Aller au contenu

Photo

Nevercheetah3d (WIP)


  • Veuillez vous connecter pour répondre
26 réponses à ce sujet

#1
henesua

henesua
  • Members
  • 3 855 messages

I'm working on scripts for importing and exporting MDL (models) in ASCII format for my favorite modelling software, Cheetah3d. So far so good. Its a nice little exercise. I'll be posting questions throughout the thread as I work on this. This first post will eventually have a link to the scripts if I ever get to a public release.

 

FEATURES (2015 mar 16)

  • export an ASCII mdl file from Cheetah3D
  • nodes exported (so far): root dummy/mdl base, dummy, trimesh

 

  • import an ASCII mdl file into Cheetah3d
  • nodes imported (so far): root dummy/mdl base, dummy, trimesh
  • creates Aurora Property parameters: mdl base, trimesh
  • create Cheetah materials to represent NWN's shading in game (partial success)

  • Rolo Kipp aime ceci

#2
henesua

henesua
  • Members
  • 3 855 messages

Question 1:

 

I'm looking at the orientation aspect of a node, and wondering what each of the four floats represent. Anyone have a clue?

 

My expectation is for rotation at X Y and Z axes but this looks like something else. What is it? Quaternions?

 

EDIT --------------

Just found this:

 

 

I decoded the ASCII MDL format for my engine testing.
It''s and Angle Axis.

First 3 values are axis, last is the angle.

I think it''s Radians, don''t remember, well it works in my engine.

 

is this correct?

 

EDIT 2 --------

yup, its an axis angle and the last one is the rotation around the vector defined by the first three floats. and the last appears to be radians. But its definitely X Y Z - W.



#3
henesua

henesua
  • Members
  • 3 855 messages

Question 2:

 

Related to the above, what are the orientations of the 3 axes? And that of the rotations?

 

example

A MDL file has a position sequence like this in its file:

position 1.05201 0.00333741 0.00335884

My assumption based on how the toolset works is that these are X, Y, Z in order. Using the color coding of the following picture my assumption is that X is red, Y is blue and Z is green, and all the arrows are pointing in the correct direction, although it is theoretically possible I guess for Y to point in the opposite direction. Someone please let me know.

axes.png

 

Now for rotation I am confused entirely and need help.

orientation 1.0 0.0 0.0 0.0 

My assumption is that that the first three define a vector with X Y Z, and the last is the rotation around the vector. I assume that the XYZ are the same for this as for position, and that the last figure is in radians. If anyone knows please fill me in.



#4
henesua

henesua
  • Members
  • 3 855 messages

Question 3:

 

wirecolor: is wirecolor actually used at all?

wirecolor 0.423529 0.0313726 0.533333

Seems to me to be an RGB value with each number ranging from 0 - 1. For the time being I am assuming this is not used and I am just going to plug in 0.01 1.0 0.01 and just leave it.

 

But if anyone knows please speak up.



#5
henesua

henesua
  • Members
  • 3 855 messages

Question 4:

center. what is this? 

center 10.1702 0.0 97.9209

I was looking in Torlack's rundown on the binary file and found this

 

0x00A0

FLOAT [3]

Average of all points in the mesh, defaults to (0, 0, 0), computed

 

Is this the center property?

 

Observation:

Its interesting that there are many mesh properties in there that I have not seen in the MDL examples I am looking at. Things like radius and bounding box, additional textures and so on.

 

-- after this one i'm in the midst of the crunchy bits - the mesh's actual data. woohoo. real stuff.



#6
henesua

henesua
  • Members
  • 3 855 messages

Question 5:
 
faces. I need some clues as to how to decode the string of 8 integers. The first 3 are pretty clearly indexes of vertices of the face (since NWN only uses tris). Getting the order right will be important, but I can probably figure that out. After that however I am having trouble decoding a pattern.

  faces 16
    0 1 5  1  20 21 23  1
    5 4 0  1  23 22 20  1
    1 2 6  8  1 2 6  1
    6 5 1  8  6 5 1  1
    2 3 7  1  16 17 19  1
    7 6 2  1  19 18 16  1
    3 0 4  8  3 0 4  1
    4 7 3  8  4 7 3  1
    8 9 13  1  24 25 27  1
    13 12 8  1  27 26 24  1
    9 10 14  8  9 13 29  1
    14 13 9  8  29 28 9  1
    10 11 15  1  10 14 31  1
    15 14 10  1  31 30 10  1
    11 8 12  8  11 8 12  1
    12 15 11  8  12 15 11  1

Torlack has this for the face structure:

| Offset | Type | Description |
| 0x0000 | FLOAT [3] | Plane normal |
| 0x000C | FLOAT | Plane distance |
| 0x0010 | INT32 | Surface ID |
| 0x0014 | INT16 [3] | Adjacent face number or -1 |
| 0x001A | INT16 [3] | Vertex indices |
| 0x0020 | | Total length of structure |

 
I'm not making much out of that yet.

 

-- EDIT --

I found this in neverblender:

ascii_geometry.append('    ' + str(face[0]) + ' '  + # Vertex index
                               str(face[1]) + ' '  + # Vertex index
                               str(face[2]) + '  ' + # Vertex index
                               str(face[3]) + '  ' + # Smoth group/Shading group (whatever)
                               str(face[4]) + ' '  + # Texture vertex index
                               str(face[5]) + ' '  + # Texture vertex index
                               str(face[6]) + '  ' + # Texture vertex index
                               str(face[7]) )        # Misc

so that is my clue. not sure what misc is. will need to investigate that. shading groups will take some investigation to extract, not clear on how to do that yet.



#7
Michael DarkAngel

Michael DarkAngel
  • Members
  • 366 messages

Q1: Correct

 

orientation [X-Axis] [Y-Axis] [Z-Axis] [rotation_amount] - the node is rotated around the axis given in x,y,z

 

rotation_amount is in radians

 

Q2: Correct.

 

In some 3D programs y-axis is up, and you would need to adjust for that.

 

Q3: I believe this was only used internally, I don't think it has any bearing on the model in-game.  However, nwMax does have a button on the trimesh modifier that will allow you to set the selfiilumcolor value based on the wire color.

 

Q4: Can't say I have ever seen this, and nwMax makes no reference to it.

 

center [x] [y] [z] - This may be the center of the node. This could possibly affect rotations.

 

Q5: Correct, misc is/should be material

 

[v1] [v2] [v3] [s] [t1] [t2] [t3] [m]

 

v = vertex

s = smoothing group

t = texture vertex

m = material

 

HTH

 

icon_zdevil.gif

MDA


  • OldTimeRadio, henesua, Rolo Kipp et 1 autre aiment ceci

#8
OldTimeRadio

OldTimeRadio
  • Members
  • 1 400 messages

First, wanted to back up what MDA said in his response to Q3.

 

Second, in hopes of suggesting something which may cut down the time required for you to achieve your goal, and on the assumption that you're familiar with whatever the scripting/programming language is that one writes Cheetah3D (and whatever paradigms they follow for reconstructing objects), I think you can fast track a ton of your work by:

1. Acquiring a copy of GMax and a copy of the GMax help, which includes MaxScript help- if you don't already have these aready.

2. Use this import/export script, Wayland's latest GMax import/export script as updated by NWC Snake as the cheatsheet you use for importing/exporting routines.

3. Refer to that in building the framework your model import/export script, in conjunction with the GMax help file(s) to interpret between MaxScript and whatever functions are available in Cheetah3D.  The reason being is NWMax is architected in a certain way which is not all that easy to reverse engineer or, at times, understand IMO.  Wayland's is one script. 

 

Symmetric's Neverblender might also yield some helpful ideas, though I haven't used it myself.

 

Autodesk has a more comprehensive set of MaxScript help files if you need really granular answers.

 

Observation:

Its interesting that there are many mesh properties in there that I have not seen in the MDL examples I am looking at. Things like radius and bounding box, additional textures and so on.

 

Some values are computed at model compile time by the model compiler.  Other properties you may encounter looking at Torlack's material are binary data fields which no one knows how to access/understand or fields for which there are commands (e.g. "lightmapped") which have a clear parity between ASCII files and the binary data format but whose functional parameters haven't been cracked yet- or that the engine may not support.


  • Michael DarkAngel, henesua et Rolo Kipp aiment ceci

#9
Asymmetric

Asymmetric
  • Members
  • 165 messages

Q3: wirecolor

No idead what it does and there is no property in blender which matches it. In Neverblender you can select the wirecolor and it will get imported/exported, but it is unused.

 

 

Q4:  center x y z

As far as I can tell it doesn't affect anything. It's not used for rotation, animations or anything. Neverblender parses it, puts it in a custom property/variable for the object and then forgets about it.


  • henesua et Rolo Kipp aiment ceci

#10
henesua

henesua
  • Members
  • 3 855 messages

Thanks for the responses, all. I really really appreciate it.

 

I've got verts and tverts worked out now, and am still finishing off faces by looking at smoothing groups and material. I suspect that material is not used by the engine since we only use one bitmap per mesh.

 

 

As far as means and methods, OldTimeRadio, I am trying to do this on my own from scratch in order to build up my javascript skills, and practice processing data. I do admittedly cheat sometimes and look at neverblender's python scripts in order to have a clue as to what the data is. I haven't bothered with gmax but might eventually take a look. That script by wayland however will be made use of. I've got it loaded right now into my text editor here, thanks!


  • OldTimeRadio aime ceci

#11
henesua

henesua
  • Members
  • 3 855 messages

Question 6:
 
Smoothing groups. How are these applied in Max? (I don't have a copy) Do you select a bunch of polygons, and then choose a number between 1 and 32?
 
In Cheetah3D I am considering allowing a user to select polygons, and apply a smoothing group to them. This could enable however the ability to add polygons to shading groups which do not share edges (unless I decide to check for this and prevent it). Alternatively I could generate smoothing groups procedurally, but I am worried that if I do this I will be unable to achieve 1 to 1 parity with the original MDL I import. It seems much easier to create a data matrix which links faces to smoothing groups and develop a way to link this to a customized interface in the application.
 
I found this reading at the Harvest Moon Consortium to help me sort out what smoothing groups are in an MDL.
 
--- EDIT ----
ramble follows
some nwn modellers in various threads I have googled mention that they simply set the angle threshold between normals to define whether smoothing should occur. Most apps have this setting as does cheetah. I should probably enable the same and apply smoothing groups procedurally on export although it would be interesting to define smoothing explicitly. Perhaps I could use seams for explicitly defining a hard break between smoothing groups.
 
and then I found this:


SMOOTHING GROUPS

Smoothing groups define whether a surface is rendered with sharp edges or smooth surfaces. You create smoothing groups by assigning group numbers to the faces of an object. If two faces share an edge and share the same smoothing group, they render as a smooth surface. If they don’t share the same smoothing group, the edge between them renders as a corner.



#12
Michael DarkAngel

Michael DarkAngel
  • Members
  • 366 messages


 

I've got verts and tverts worked out now, and am still finishing off faces by looking at smoothing groups and material. I suspect that material is not used by the engine since we only use one bitmap per mesh.

 

As far as I can tell material is ignored on normal meshes and is only referenced for the walkmeshes.

 

For walkmeshes you have the following:

 

1 -- Dirt

2 -- Obscuring

3 -- Grass

4 -- Stone

5 -- Wood

6 -- Water

7 -- Nonwalk

8 -- Transparent

9 -- Carpet

10 -- Metal

11 -- Puddles

12 -- Swamp

13 -- Mud

14 -- Leaves

15 -- Lava

16 -- BottomlessPit

17 -- DeepWater

18 -- Door

19 -- Snow

20 -- Sand

21 -- BareBones

22 -- StoneBridge

23 -- Temp1

24 -- Temp2

25 -- Temp3

26 -- Temp4

27 -- Temp5

28 -- Temp6

29 -- Temp7

30 -- Trigger

 

icon_zdevil.gif

MDA


  • OldTimeRadio, henesua et Rolo Kipp aiment ceci

#13
Michael DarkAngel

Michael DarkAngel
  • Members
  • 366 messages

Q6:  Not sure if this will answer your question, but this is what happens in gMax/3DSMax:

 

SG_001s.png

click image for full size

 

Select an object, and then select the face sub-object level.  Scroll down the right-side nav panel until you see Smoothing Groups.

 

SG_002s.png

click image for full size

 

Select your face(s), in this case I selected all.  The numbered buttons should change to reflect what smoothing group(s) the selected face(s) are associated with.  Because I did not want any sharp edges on this section of the tower, all faces are part of the same smoothing group.

 

SG_003s.png

click image for full size

 

Because the crenellations should have sharp edges, you can see all the selected faces are part of four different smoothing groups.

 

If you wanted to pick faces by the smoothing group associated with them, you would use the Select By SG button.

 

You can clear associated smoothing groups, by selecting the face(s) you wish to clear and then press the Clear All button.

 

Auto Smooth is used along with the angle next to it, to perform automated smoothing.  45 degrees is the default that has been set since nwMax released.  For the most part, it does a pretty good job.  If this doesn't give you the desired effect, your mesh should probably be split into more than a single mesh.

 

You can also manually assign smoothing groups by selecting faces and selecting one of the smoothing group buttons.

 

icon_zdevil.gif

MDA


  • OldTimeRadio, henesua et Rolo Kipp aiment ceci

#14
henesua

henesua
  • Members
  • 3 855 messages

Thanks, M_DA. That is exactly what I wanted to know, and is the assumption I've been proceeding under.



#15
henesua

henesua
  • Members
  • 3 855 messages

I have very rudimentary tools in place, but I am able to export from Cheetah3d a model that is visible in game.

My first test was a cylinder textured with _six's wildwood's leaves.

1test_success.jpg

 

here's a snapshot of the mdl

 

and a snapshot of my messy javascript


  • Michael DarkAngel, OldTimeRadio et Rolo Kipp aiment ceci

#16
henesua

henesua
  • Members
  • 3 855 messages

Question 7:

Do nodes always have unique names? And are they always recorded after their parents in the mdl file?

node trimesh Cylinder
  parent 1test

I am working on my importer script, and decided to perform operations (creation and modification of actual objects in Cheetah3d) according to each line of the file as I read it in.

 

As you can see I'm currently dealing with setting the parent of a node. Given the mdl data above when I reach the "parent" declaration, I look through all existing objects named "1test" that I've created in my Cheetah3d scene. The first match I find gets returned and becomes the proud new parent of the node I last created.

 

If the answer to either of my questions above is "no", I will need to put some serious thought into how I handle this (perhaps read the entire mdl file in all at once, and use various string parsing functions on that data rather than execute the code of the mdl immediately).

 

___

My find Node by name code

function getNodeByName(name,mdl_base)
{
  // create a check list of nodes to check
  // start with the mdl_base
  var check_list  = [mdl_base];

  while(check_list.length>0)
  {
    // start with the last index of the array of nodes to check
    var node = check_list.pop();
    // check its name
    if(node.getParameter('name')==name)
      return node;
    // add its children to the array of nodes to check
    for(i=0;i<node.childCount();i++)
      check_list.push(node.childAtIndex(i));
  }

  return null;
}


#17
MerricksDad

MerricksDad
  • Members
  • 1 608 messages

node names are not always unique. While I shouldn't, I commonly have multiple generic meshes or dummies named the same in some models. It doesn't seem to cause any issues.

 

nodes listed in the file should always come after their parent node details, just like c# headers should always appear somewhere above actual function definitions.

 

If the javascript you can use in that program is the full kit, as used in browsers, and specifically has prototype modifiers, feel free to peek and poke at my javascript libraries online. Use anything you like.

 

https://greasyfork.o...on-library/code


  • Michael DarkAngel, OldTimeRadio, henesua et 1 autre aiment ceci

#18
henesua

henesua
  • Members
  • 3 855 messages

Hmmmm..... *musing* if a MDL will accept nodes of the same name, then I suspect that the nearest node above the current with the parent name is the parent node. I should be able to work with that, and I'll double check my export code to ensure that that is how I generate the MDL file.

 

As far as the javascript in this modeller, yes, it is using javascript from webkit. I haven't found anything missing yet. Only changes that I have found involve the API for the modeller. Thanks for sharing your code. I'll see if I can make use of it.



#19
Michael DarkAngel

Michael DarkAngel
  • Members
  • 366 messages

While having non-unique names for child nodes doesn't seem to cause an issue, having non-unique names for parent nodes in the same model may or may not cause some issues in-game (not sure, never tested it).  In an importer it would definitely create some havoc.  I can't recall ever seeing this happen.  We should test it and see what happens :blink:

 

I do remember that in NWN2 if every object in a scene was not uniquely named it would cause problems.  [EDIT]Actually, that's not the correct way to state that.  Multiples of the same model will have objects that are named alike.  So, it might be better to say that no two models could have objects named alike.[/EDIT]

 

icon_zdevil.gif

MDA


  • henesua aime ceci

#20
henesua

henesua
  • Members
  • 3 855 messages

I've hit a wall with this because Cheetah's API has some limitations with regards to materials. The material node system does not have an API for me to access via scripts. The developer is working on this though and so once I have access to the materials I shoul dbe back in business with my importer script. (I need to be able to create materials and apply them to the objects I am importing.)


  • PracticalKat aime ceci

#21
OldTimeRadio

OldTimeRadio
  • Members
  • 1 400 messages

If you're looking for something to tinker with, Java-wise, might I suggest the NWN 3D Java Model viewer as fodder?  That came with the source code and I'd uploaded both the program and the source code to the old Vault.  Not sure where it is at the new one but I assume it made it there. (?)

 

The reason I bring it up is, after all these years, NWN still doesn't have a good emitter creation program where you edit how they look, real-time.  The model viewer does a good job displaying most types of emitters, already.  I have no idea what kind of work would be involved in adding that extra functionality (sliders and checkboxes to tweak emitters and be able to export them) but it would be so much nicer than doing it by hand.  Barring those specific changes, any functionality you saw fit to add would almost certainly be appreciated.

 

Anyway, just a thought.  Cheers!


  • MerricksDad aime ceci

#22
Michael DarkAngel

Michael DarkAngel
  • Members
  • 366 messages

I've hit a wall with this because Cheetah's API has some limitations with regards to materials. The material node system does not have an API for me to access via scripts. The developer is working on this though and so once I have access to the materials I shoul dbe back in business with my importer script. (I need to be able to create materials and apply them to the objects I am importing.)

 

You're right.  Without the ability to create and apply a material via scripting it does limit how complete your importer will be.  Having said that, however, should not stop you from making your importer as complete as it can be.  You can leave yourself a couple of comments in the code where you want the material creation to take place and then move on to the next step of what you want the importer to accomplish.

 

Never stop working on something because you hit a wall, hurdle that wall and continue on so that you can come back later and knock it down with ease.

 

If by some chance it takes the developer longer than anticipated, you may lose the desire to pick up where you left off.

 

icon_zdevil.gif

MDA


  • OldTimeRadio, henesua et MerricksDad aiment ceci

#23
henesua

henesua
  • Members
  • 3 855 messages

I didn't stop actually because i have a hard time letting go of a project. But that said, the awesome dev of Cheetah just gave me the documentation on the API I needed so… its already coded, just undocumented. :)

 

I'm doubling back to materials now, after I finish my bit on mesh import. Implementing the file one piece at a time with each line in the file turns out not to be a great method since I want to gnerate all of the faces after I create all of the verts and tverts….. working on that fix now.

 

that said, once this is done, and i have had my fill with blender. i'll look at that java thing. :)


  • Michael DarkAngel, OldTimeRadio et CaveGnome aiment ceci

#24
henesua

henesua
  • Members
  • 3 855 messages

Made slow progress this week, but figured out materials, and am working on refactoring my code so that this tool can work in all ways I want it to: import, export, setup any new file in cheetah to work as a NWN mdl. and then other little tools/helpers.

 

doing this required that I figure out how to reuse my code in WebKit's JavaScript environment which disallows "require", a kind of include. I am basically executing my include script (eval() ) as a work around.

// name space for MDL functions
var MDL = {};

// load and execute external code
function loadLibrary(prepath,libraryName)
{
	var file = new File(prepath+"Library/Application Support/Cheetah3D/Scripts/Library/" + libraryName);
	file.open(READ_MODE);
	var funcstring = file.read(file.size());
	file.close();
	eval(funcstring);
}

function loadIncludes(caller)
{
  var prepath = caller.scriptPath().match(/(\/Users\/[-\w^&'@{}[\],$=!#().%+~ ]*\/)/g);
	loadLibrary(prepath,"math_extension.js");
	loadLibrary(prepath,"mdl.js");
}



#25
Zwerkules

Zwerkules
  • Members
  • 1 318 messages

While having non-unique names for child nodes doesn't seem to cause an issue, having non-unique names for parent nodes in the same model may or may not cause some issues in-game (not sure, never tested it).  In an importer it would definitely create some havoc.  I can't recall ever seeing this happen.  We should test it and see what happens :blink:

Child nodes with the same name are okay, but parent nodes (especially dummies) cause problems when you import more than one model. For example Clean Models 3 creates a dummy called cm3repair if the animation node of a tile is not at 0,0,0. If you load two models which have this cm3repair dummy the children linked to cm3repair of the second model will be linked to cm3repair of the first one.


  • henesua aime ceci