Jump to content
  • Advertisement
Sign in to follow this  
xynapse

3DS Max Exporting Object - Vertexes Positions And Physique

This topic is 2546 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This stuff keeps me delayed since two weeks now, and i just can't figure out what is wrong.
And this is a root cause of all problems that are related with my animation system. So if i wont' fix this, i won't finish all the other stuff that is completed and waiting for this stuff to be finally fixed.







Guys, before you skip reading - the thing i am looking for is a small help with transformation matrices - being exact : how do i get untransformed vertex positions from objects in max ( even from those, having physique applied ).




Let me say what i am currently doing.

I am writing scene exporter to my engine, if i understand it right, all vertexes should have object space coordinates, and i need transformation matrix of that object exported separately too - to multiply the vertexes by that transformation matrix later on when rendering ( in shader for example ).

So let me visualize it, this is a box that i have positioned at 50, 50, 50, the size of this box is 10,10,10




indoor21.jpg




EXPORT.

0) Object World Space Transformation Matrix at Frame 0 is achieved by:



Matrix3 mTransformationMatrix = pNode->GetObjTMAfterWSM(0);






1) Every vertex * pNode->GetObjTMAfterWSM(0) ( I suspect this will result in a Vertex Transformed to World Space (right?) )






Matrix3 matWorldSpace = pNode->GetObjTMAfterWSM(0)

for(each vertex....)
{


// calculate normals

// calculate uvs

Point3 p3VertexPosition = matWorldSpace * pMesh->verts[pMesh->faces.v[index]] ;
}




Results




+ [Box01] Processing
+ [Box01] Extracting face data [ 0 ]
+ [Box01] Face.0 Vertex.0 (UNIQUE) <55.00,55.00,55.00>
+ [Box01] Face.0 Vertex.1 (UNIQUE) <45.00,55.00,55.00>
+ [Box01] Face.0 Vertex.2 (UNIQUE) <45.00,45.00,55.00>
+ [Box01] Face.1 Vertex.0 (SHARED - indexed to Vertex.2)
+ [Box01] Face.1 Vertex.1 (UNIQUE) <55.00,45.00,55.00>
+ [Box01] Face.1 Vertex.2 (SHARED - indexed to Vertex.0)
+ [Box01] Face.2 Vertex.0 (UNIQUE) <55.00,55.00,45.00>
+ [Box01] Face.2 Vertex.1 (UNIQUE) <55.00,45.00,45.00>
+ [Box01] Face.2 Vertex.2 (UNIQUE) <45.00,45.00,45.00>
+ [Box01] Face.3 Vertex.0 (SHARED - indexed to Vertex.6)
+ [Box01] Face.3 Vertex.1 (UNIQUE) <45.00,55.00,45.00>
+ [Box01] Face.3 Vertex.2 (SHARED - indexed to Vertex.4)
+ [Box01] Face.4 Vertex.0 (UNIQUE) <55.00,45.00,45.00>
+ [Box01] Face.4 Vertex.1 (UNIQUE) <55.00,45.00,55.00>
+ [Box01] Face.4 Vertex.2 (UNIQUE) <45.00,45.00,55.00>
+ [Box01] Face.5 Vertex.0 (SHARED - indexed to Vertex.10)
+ [Box01] Face.5 Vertex.1 (UNIQUE) <45.00,45.00,45.00>
+ [Box01] Face.5 Vertex.2 (SHARED - indexed to Vertex.8)
+ [Box01] Face.6 Vertex.0 (SHARED - indexed to Vertex.4)
+ [Box01] Face.6 Vertex.1 (UNIQUE) <55.00,55.00,55.00>
+ [Box01] Face.6 Vertex.2 (SHARED - indexed to Vertex.3)
+ [Box01] Face.7 Vertex.0 (SHARED - indexed to Vertex.3)
+ [Box01] Face.7 Vertex.1 (UNIQUE) <55.00,45.00,45.00>
+ [Box01] Face.7 Vertex.2 (SHARED - indexed to Vertex.4)
+ [Box01] Face.8 Vertex.0 (UNIQUE) <45.00,55.00,45.00>
+ [Box01] Face.8 Vertex.1 (UNIQUE) <45.00,55.00,55.00>
+ [Box01] Face.8 Vertex.2 (UNIQUE) <55.00,55.00,55.00>
+ [Box01] Face.9 Vertex.0 (SHARED - indexed to Vertex.16)
+ [Box01] Face.9 Vertex.1 (UNIQUE) <55.00,55.00,45.00>
+ [Box01] Face.9 Vertex.2 (SHARED - indexed to Vertex.14)
+ [Box01] Face.10 Vertex.0 (UNIQUE) <45.00,45.00,45.00>
+ [Box01] Face.10 Vertex.1 (SHARED - indexed to Vertex.2)
+ [Box01] Face.10 Vertex.2 (UNIQUE) <45.00,55.00,55.00>
+ [Box01] Face.11 Vertex.0 (SHARED - indexed to Vertex.19)
+ [Box01] Face.11 Vertex.1 (SHARED - indexed to Vertex.7)
+ [Box01] Face.11 Vertex.2 (SHARED - indexed to Vertex.18)
+ [Box01] Writing mesh final data
+ [Box01] Overall mesh vertices: 20
+ [Box01] Overall mesh indices: 36
+ [Box01] Model Transformation Matrix: <Translation: 50.0,50.0,-55.0>.



What indicates that they are World Space transformed - this is what i expected.

Now what i want is those vertexes to be in Object Space, so i am thinking - If i remove that Multiplication, would i get them right?




2) Vertexes without any matrix multiplication



for(each vertex....)
{


// calculate normals

// calculate uvs

Point3 p3VertexPosition = pMesh->verts[pMesh->faces.v[index]] ;
}








Results






+ [Box01] Processing
+ [Box01] Extracting face data [ 0 ]
+ [Box01] Face.0 Vertex.0 (UNIQUE) <5.00,0.00,5.00>
+ [Box01] Face.0 Vertex.1 (UNIQUE) <-5.00,0.00,5.00>
+ [Box01] Face.0 Vertex.2 (UNIQUE) <-5.00,0.00,-5.00>
+ [Box01] Face.1 Vertex.0 (SHARED - indexed to Vertex.2)
+ [Box01] Face.1 Vertex.1 (UNIQUE) <5.00,0.00,-5.00>
+ [Box01] Face.1 Vertex.2 (SHARED - indexed to Vertex.0)
+ [Box01] Face.2 Vertex.0 (UNIQUE) <5.00,10.00,5.00>
+ [Box01] Face.2 Vertex.1 (UNIQUE) <5.00,10.00,-5.00>
+ [Box01] Face.2 Vertex.2 (UNIQUE) <-5.00,10.00,-5.00>
+ [Box01] Face.3 Vertex.0 (SHARED - indexed to Vertex.6)
+ [Box01] Face.3 Vertex.1 (UNIQUE) <-5.00,10.00,5.00>
+ [Box01] Face.3 Vertex.2 (SHARED - indexed to Vertex.4)
+ [Box01] Face.4 Vertex.0 (UNIQUE) <5.00,10.00,-5.00>
+ [Box01] Face.4 Vertex.1 (UNIQUE) <5.00,0.00,-5.00>
+ [Box01] Face.4 Vertex.2 (UNIQUE) <-5.00,0.00,-5.00>
+ [Box01] Face.5 Vertex.0 (SHARED - indexed to Vertex.10)
+ [Box01] Face.5 Vertex.1 (UNIQUE) <-5.00,10.00,-5.00>
+ [Box01] Face.5 Vertex.2 (SHARED - indexed to Vertex.8)
+ [Box01] Face.6 Vertex.0 (SHARED - indexed to Vertex.4)
+ [Box01] Face.6 Vertex.1 (UNIQUE) <5.00,0.00,5.00>
+ [Box01] Face.6 Vertex.2 (SHARED - indexed to Vertex.3)
+ [Box01] Face.7 Vertex.0 (SHARED - indexed to Vertex.3)
+ [Box01] Face.7 Vertex.1 (UNIQUE) <5.00,10.00,-5.00>
+ [Box01] Face.7 Vertex.2 (SHARED - indexed to Vertex.4)
+ [Box01] Face.8 Vertex.0 (UNIQUE) <-5.00,10.00,5.00>
+ [Box01] Face.8 Vertex.1 (UNIQUE) <-5.00,0.00,5.00>
+ [Box01] Face.8 Vertex.2 (UNIQUE) <5.00,0.00,5.00>
+ [Box01] Face.9 Vertex.0 (SHARED - indexed to Vertex.16)
+ [Box01] Face.9 Vertex.1 (UNIQUE) <5.00,10.00,5.00>
+ [Box01] Face.9 Vertex.2 (SHARED - indexed to Vertex.14)
+ [Box01] Face.10 Vertex.0 (UNIQUE) <-5.00,10.00,-5.00>
+ [Box01] Face.10 Vertex.1 (SHARED - indexed to Vertex.2)
+ [Box01] Face.10 Vertex.2 (UNIQUE) <-5.00,0.00,5.00>
+ [Box01] Face.11 Vertex.0 (SHARED - indexed to Vertex.19)
+ [Box01] Face.11 Vertex.1 (SHARED - indexed to Vertex.7)
+ [Box01] Face.11 Vertex.2 (SHARED - indexed to Vertex.18)
+ [Box01] Writing mesh final data
+ [Box01] Overall mesh vertices: 20
+ [Box01] Overall mesh indices: 36
+ [Box01] Model Transformation Matrix: <Translation: 50.0,50.0,-55.0>.










Success! Vertexes are in Object Space!

Well, not that fast! - Unfortunately.




This works great if there is no animation at all - and i did not say that, but i already got that working - but wanted to introduce you to the problem.

Ok so far i know i have my vertices in Object Space , so let's add a Physique Modifier to this Box and see what will happen.




Remember we are not multiplying vertices's by any matrix, just like i said - we write down their positions without any mangling.




indoor22.jpg

This is still the same box as previously, with a bone attached via Physique Modifier, let's export and see our vertexes positions.



+ [Box01] Processing
+ [Box01] Extracting face data [ 0 ]
+ [Box01] Face.0 Vertex.0 (UNIQUE) <5.00,0.00,5.00>
+ [Box01] Face.0 Vertex.1 (UNIQUE) <-5.00,0.00,5.00>
+ [Box01] Face.0 Vertex.2 (UNIQUE) <-5.00,0.00,-5.00>
+ [Box01] Face.1 Vertex.0 (SHARED - indexed to Vertex.2)
+ [Box01] Face.1 Vertex.1 (UNIQUE) <5.00,0.00,-5.00>
+ [Box01] Face.1 Vertex.2 (SHARED - indexed to Vertex.0)
+ [Box01] Face.2 Vertex.0 (UNIQUE) <5.00,10.00,5.00>
+ [Box01] Face.2 Vertex.1 (UNIQUE) <5.00,10.00,-5.00>
+ [Box01] Face.2 Vertex.2 (UNIQUE) <-5.00,10.00,-5.00>
+ [Box01] Face.3 Vertex.0 (SHARED - indexed to Vertex.6)
+ [Box01] Face.3 Vertex.1 (UNIQUE) <-5.00,10.00,5.00>
+ [Box01] Face.3 Vertex.2 (SHARED - indexed to Vertex.4)
+ [Box01] Face.4 Vertex.0 (UNIQUE) <5.00,10.00,-5.00>
+ [Box01] Face.4 Vertex.1 (UNIQUE) <5.00,0.00,-5.00>
+ [Box01] Face.4 Vertex.2 (UNIQUE) <-5.00,0.00,-5.00>
+ [Box01] Face.5 Vertex.0 (SHARED - indexed to Vertex.10)
+ [Box01] Face.5 Vertex.1 (UNIQUE) <-5.00,10.00,-5.00>
+ [Box01] Face.5 Vertex.2 (SHARED - indexed to Vertex.8)
+ [Box01] Face.6 Vertex.0 (SHARED - indexed to Vertex.4)
+ [Box01] Face.6 Vertex.1 (UNIQUE) <5.00,0.00,5.00>
+ [Box01] Face.6 Vertex.2 (SHARED - indexed to Vertex.3)
+ [Box01] Face.7 Vertex.0 (SHARED - indexed to Vertex.3)
+ [Box01] Face.7 Vertex.1 (UNIQUE) <5.00,10.00,-5.00>
+ [Box01] Face.7 Vertex.2 (SHARED - indexed to Vertex.4)
+ [Box01] Face.8 Vertex.0 (UNIQUE) <-5.00,10.00,5.00>
+ [Box01] Face.8 Vertex.1 (UNIQUE) <-5.00,0.00,5.00>
+ [Box01] Face.8 Vertex.2 (UNIQUE) <5.00,0.00,5.00>
+ [Box01] Face.9 Vertex.0 (SHARED - indexed to Vertex.16)
+ [Box01] Face.9 Vertex.1 (UNIQUE) <5.00,10.00,5.00>
+ [Box01] Face.9 Vertex.2 (SHARED - indexed to Vertex.14)
+ [Box01] Face.10 Vertex.0 (UNIQUE) <-5.00,10.00,-5.00>
+ [Box01] Face.10 Vertex.1 (SHARED - indexed to Vertex.2)
+ [Box01] Face.10 Vertex.2 (UNIQUE) <-5.00,0.00,5.00>
+ [Box01] Face.11 Vertex.0 (SHARED - indexed to Vertex.19)
+ [Box01] Face.11 Vertex.1 (SHARED - indexed to Vertex.7)
+ [Box01] Face.11 Vertex.2 (SHARED - indexed to Vertex.18)
+ [Box01] Writing mesh final data
+ [Box01] Overall mesh vertices: 20
+ [Box01] Overall mesh indices: 36
+ [Box01] Model Transformation Matrix: <Translation: 50.0,50.0,-55.0>.
+ [Box01] Physique found.







Wow, nice stuff it looks like Physique did not modify anything - again NOT SO FAST,

let's say i want to move this bone somewhere else where it should be positioned now, let's move it to 100,100,100

indoor23.jpg

Instead of moving the object i had to move the Bone as it is connected via Physique to our Box, so i translated the Bone to 100.0, 100.0, 100.0 and let's see the export dump now






+ [Box01] Processing
+ [Box01] Extracting face data [ 0 ]
+ [Box01] Face.0 Vertex.0 (UNIQUE) <55.00,-50.00,65.00> ???????????
+ [Box01] Face.0 Vertex.1 (UNIQUE) <45.00,-50.00,65.00> ???????????
+ [Box01] Face.0 Vertex.2 (UNIQUE) <45.00,-50.00,55.00> ???????????
+ [Box01] Face.1 Vertex.0 (SHARED - indexed to Vertex.2)
+ [Box01] Face.1 Vertex.1 (UNIQUE) <55.00,-50.00,55.00> ???????????
+ [Box01] Face.1 Vertex.2 (SHARED - indexed to Vertex.0)
+ [Box01] Face.2 Vertex.0 (UNIQUE) <55.00,-40.00,65.00> ???????????
+ [Box01] Face.2 Vertex.1 (UNIQUE) <55.00,-40.00,55.00>
+ [Box01] Face.2 Vertex.2 (UNIQUE) <45.00,-40.00,55.00>
+ [Box01] Face.3 Vertex.0 (SHARED - indexed to Vertex.6)
+ [Box01] Face.3 Vertex.1 (UNIQUE) <45.00,-40.00,65.00>
+ [Box01] Face.3 Vertex.2 (SHARED - indexed to Vertex.4)
+ [Box01] Face.4 Vertex.0 (UNIQUE) <55.00,-40.00,55.00>
+ [Box01] Face.4 Vertex.1 (UNIQUE) <55.00,-50.00,55.00>
+ [Box01] Face.4 Vertex.2 (UNIQUE) <45.00,-50.00,55.00>
+ [Box01] Face.5 Vertex.0 (SHARED - indexed to Vertex.10)
+ [Box01] Face.5 Vertex.1 (UNIQUE) <45.00,-40.00,55.00>
+ [Box01] Face.5 Vertex.2 (SHARED - indexed to Vertex.8)
+ [Box01] Face.6 Vertex.0 (SHARED - indexed to Vertex.4)
+ [Box01] Face.6 Vertex.1 (UNIQUE) <55.00,-50.00,65.00>
+ [Box01] Face.6 Vertex.2 (SHARED - indexed to Vertex.3)
+ [Box01] Face.7 Vertex.0 (SHARED - indexed to Vertex.3)
+ [Box01] Face.7 Vertex.1 (UNIQUE) <55.00,-40.00,55.00>
+ [Box01] Face.7 Vertex.2 (SHARED - indexed to Vertex.4)
+ [Box01] Face.8 Vertex.0 (UNIQUE) <45.00,-40.00,65.00>
+ [Box01] Face.8 Vertex.1 (UNIQUE) <45.00,-50.00,65.00>
+ [Box01] Face.8 Vertex.2 (UNIQUE) <55.00,-50.00,65.00>
+ [Box01] Face.9 Vertex.0 (SHARED - indexed to Vertex.16)
+ [Box01] Face.9 Vertex.1 (UNIQUE) <55.00,-40.00,65.00>
+ [Box01] Face.9 Vertex.2 (SHARED - indexed to Vertex.14)
+ [Box01] Face.10 Vertex.0 (UNIQUE) <45.00,-40.00,55.00>
+ [Box01] Face.10 Vertex.1 (SHARED - indexed to Vertex.2)
+ [Box01] Face.10 Vertex.2 (UNIQUE) <45.00,-50.00,65.00>
+ [Box01] Face.11 Vertex.0 (SHARED - indexed to Vertex.19)
+ [Box01] Face.11 Vertex.1 (SHARED - indexed to Vertex.7)
+ [Box01] Face.11 Vertex.2 (SHARED - indexed to Vertex.18)
+ [Box01] Writing mesh final data
+ [Box01] Overall mesh vertices: 20
+ [Box01] Overall mesh indices: 36
+ [Box01] Model Transformation Matrix: <Translation: 50.0,50.0,-55.0>.




And here is something i just DON'T UNDERSTAND and keeps me delayed - why my vertexes have changed?

The transformation matrix looks fine, but why my Raw Vertex Positions are affected, is it because of Physique and Bone translation?



How do i get the Object Space vertices positions for all objects (INodes) i am exporting no matter if they are Physique'd or not ?


The physique is to be used for Bone animation system, but it won't work if i have my Vertexes positions wrong / translated by something...




I was told to Inverse the Transformation matrix and multiply it by The vertexes, that gave some strange results and it does not work at all,

i've seen many implementations but they seem to work on World Space Coordinates - which is what i don't understand, especially when thinking of passing Vertexes later on

to the VBO and multiplying their positions when rendering with the Model Transformation Matrix exported from MAX.










Hope you guy can help me, cause i will go into trouble if i won't finish this till the eoy.
:(

Share this post


Link to post
Share on other sites
Advertisement
Guys, before you skip reading - i just want to say, that the exporter works perfectly and i don't ask for any help related to "How To Export" - the thing i am looking for is a small help with transformation matrices.[/quote]
Well, in that case I'm confused. My hunch would be that you're extracting the deformed mesh result rather than the base object. But if you say that the exporter is working fine, then I'm not sure what else to suggest really....

[color="#1C2837"]

How do i get the Object Space vertices positions for all objects (INodes) i am exporting no matter if they are Physique'd or not ?[/quote]


[color="#1C2837"]

Just grab the undeformed (original) local space values from the base object (Object::FindBaseObject) at the top of the modifier stack. But again, if you are sure there is no problem with the exporter, then it's got to be something to do with your engine I'd guess?

Share this post


Link to post
Share on other sites

Guys, before you skip reading - i just want to say, that the exporter works perfectly and i don't ask for any help related to "How To Export" - the thing i am looking for is a small help with transformation matrices.

Well, in that case I'm confused. My hunch would be that you're extracting the deformed mesh result rather than the base object. But if you say that the exporter is working fine, then I'm not sure what else to suggest really....

[color="#1C2837"]

How do i get the Object Space vertices positions for all objects (INodes) i am exporting no matter if they are Physique'd or not ?[/quote]


[color="#1C2837"]

Just grab the undeformed (original) local space values from the base object (Object::FindBaseObject) at the top of the modifier stack. But again, if you are sure there is no problem with the exporter, then it's got to be something to do with your engine I'd guess?


[/quote]
I thing i missed the spot saying 'exporter works fine' - what i was trying to say is that i don't want to ask you questions like 'how do i write the expoter' or 'how do make my game with 3ds max' - sorry, if wasn't too clear. We shall not speak about the engine yet - first things first, and i believe the first thing here is to get untransformed vertexes from objects - and this is the actual problem..



So you say to " grab the undeformed (original) local space values from the base object (Object::FindBaseObject) at the top of the modifier stack" - yeah, but how do i do this ?

I have tried multiplying pMesh->GetVert(..) like:




- pNode->GetNodeTM(0) * pMesh->getVert(pMesh->faces.v[index])

- pNode->GetObjectTM(0) * pMesh->getVert(pMesh->faces.v[index])

- pNode->GetObjectTMAfterWSM(0) * pMesh->getVert(pMesh->faces.v[index])

- pNode->GetObjectTMBeforeWSM(0) * pMesh->getVert(pMesh->faces.v[index])




And still objects having physique attached, return vertexes in non-object space ( as in first post ).
D#@mn it.


I desperately need help with this, or i am going to have really bad Christmas ;/

Share this post


Link to post
Share on other sites
Have you tried putting the entire physique portion of the model into another layer, hide the new layer then export it? This is a requirement when I export my model to X, othewise I get dummy objects and the physique model as part of the complete mesh.

Share this post


Link to post
Share on other sites
LancerSolurus - i don't get any dummy objects, i also don't get object with vertexes in it's local ( object ) space, as i stated in my first post.




And i am starting to think why the hell everybody writes exporters but nobody knows the solution?
If i get it right, when thinking of exporting something to the game engine - i think of exporting the mesh with vertexes in object space


and eventual transformation matrix if you are placing this object somewhere on the whole scene - and this is what i do,

but the first point there fails in my case. All is OK when there is no Physique.




Again, if i export the object only, with Pivot in it's center, no matter where i place it i get Object Space vertices by utilizing GetVert.

But if i apply physique and attach a bone, i get some pretty ugly vertex positions - and it seems that nobody knows why ??

I've seen people multiplying vertex positions by inverses of some matrices - but hell yeah, it works if you speak of having vertexes in world space.





Come on Guys ! I know you have something more to share !







@RobTheBloke

I have seen your previous post ( http://www.gamedev.n...a-from-3ds-max/ )

where you say:






Matrix3 local_space = node->GetNodeTM(t) * Inverse(node->GetParentTM(t));
local_space.Orthogonalize();
[/quote]


Can you please say something more about this ? I know this is per frame, but what exactly does that do ?

Share this post


Link to post
Share on other sites
Ok i think i've got it.




The Pivot is the key here, when you move the object without Physique attached, the pivot stays at the Object's Center.




But when you move the object with Physique, by dragging around the bone it is attached to, the Pivot Stays at the initial position.


On the other hand, there is another catch, you need to grab a World Space Transformation matrix with World Space modifiers



Matrix3 matObjectTransformation = pNode->GetObjTMAfterWSM(0);






Grab your current node Transformation Matrix, invert it.



Matrix3 matInverseNode = pNode->GetNodeTM(0);
matInverseNode.Invert();







Then multiply both



Matrix3 matObjectSpace= matObjectTransformation*matInverseNode;





And now multiply each vertex by this matrix



// Get the vertex position in Object Space

vVertex = pMesh->getVert(pMesh->faces.v[index])* matObjectSpace;










So to summarize,










Matrix3 matInverseNode = pNode->GetNodeTM(0);
matInverseNode.Invert();
Matrix3 matObjectTransformation = pNode->GetObjTMAfterWSM(0);

Matrix3 matObjectSpace= matObjectTransformation*matInverseNode;




// Remember to reset the Pivot !

pNode->CenterPivot(0,false);










And the dump below:









+ [BOX_WITH_BONE] Processing
+ [BOX_WITH_BONE] Extracting face data [ 0 ]
+ [BOX_WITH_BONE] Face.0 Vertex.0 (UNIQUE) <5.00,5.00,5.00>
+ [BOX_WITH_BONE] Face.0 Vertex.1 (UNIQUE) <-5.00,5.00,5.00>
+ [BOX_WITH_BONE] Face.0 Vertex.2 (UNIQUE) <-5.00,-5.00,5.00>
+ [BOX_WITH_BONE] Face.1 Vertex.0 (SHARED - indexed to Vertex.2)
+ [BOX_WITH_BONE] Face.1 Vertex.1 (UNIQUE) <5.00,-5.00,5.00>
+ [BOX_WITH_BONE] Face.1 Vertex.2 (SHARED - indexed to Vertex.0)
+ [BOX_WITH_BONE] Face.2 Vertex.0 (UNIQUE) <5.00,5.00,-5.00>
+ [BOX_WITH_BONE] Face.2 Vertex.1 (UNIQUE) <5.00,-5.00,-5.00>
+ [BOX_WITH_BONE] Face.2 Vertex.2 (UNIQUE) <-5.00,-5.00,-5.00>
+ [BOX_WITH_BONE] Face.3 Vertex.0 (SHARED - indexed to Vertex.6)
+ [BOX_WITH_BONE] Face.3 Vertex.1 (UNIQUE) <-5.00,5.00,-5.00>
+ [BOX_WITH_BONE] Face.3 Vertex.2 (SHARED - indexed to Vertex.4)
+ [BOX_WITH_BONE] Face.4 Vertex.0 (UNIQUE) <5.00,-5.00,-5.00>
+ [BOX_WITH_BONE] Face.4 Vertex.1 (UNIQUE) <5.00,-5.00,5.00>
+ [BOX_WITH_BONE] Face.4 Vertex.2 (UNIQUE) <-5.00,-5.00,5.00>
+ [BOX_WITH_BONE] Face.5 Vertex.0 (SHARED - indexed to Vertex.10)
+ [BOX_WITH_BONE] Face.5 Vertex.1 (UNIQUE) <-5.00,-5.00,-5.00>
+ [BOX_WITH_BONE] Face.5 Vertex.2 (SHARED - indexed to Vertex.8)
+ [BOX_WITH_BONE] Face.6 Vertex.0 (SHARED - indexed to Vertex.4)
+ [BOX_WITH_BONE] Face.6 Vertex.1 (UNIQUE) <5.00,5.00,5.00>
+ [BOX_WITH_BONE] Face.6 Vertex.2 (SHARED - indexed to Vertex.3)
+ [BOX_WITH_BONE] Face.7 Vertex.0 (SHARED - indexed to Vertex.3)
+ [BOX_WITH_BONE] Face.7 Vertex.1 (UNIQUE) <5.00,-5.00,-5.00>
+ [BOX_WITH_BONE] Face.7 Vertex.2 (SHARED - indexed to Vertex.4)
+ [BOX_WITH_BONE] Face.8 Vertex.0 (UNIQUE) <-5.00,5.00,-5.00>
+ [BOX_WITH_BONE] Face.8 Vertex.1 (UNIQUE) <-5.00,5.00,5.00>
+ [BOX_WITH_BONE] Face.8 Vertex.2 (UNIQUE) <5.00,5.00,5.00>
+ [BOX_WITH_BONE] Face.9 Vertex.0 (SHARED - indexed to Vertex.16)
+ [BOX_WITH_BONE] Face.9 Vertex.1 (UNIQUE) <5.00,5.00,-5.00>
+ [BOX_WITH_BONE] Face.9 Vertex.2 (SHARED - indexed to Vertex.14)
+ [BOX_WITH_BONE] Face.10 Vertex.0 (UNIQUE) <-5.00,-5.00,-5.00>
+ [BOX_WITH_BONE] Face.10 Vertex.1 (SHARED - indexed to Vertex.2)
+ [BOX_WITH_BONE] Face.10 Vertex.2 (UNIQUE) <-5.00,5.00,5.00>
+ [BOX_WITH_BONE] Face.11 Vertex.0 (SHARED - indexed to Vertex.19)
+ [BOX_WITH_BONE] Face.11 Vertex.1 (SHARED - indexed to Vertex.7)
+ [BOX_WITH_BONE] Face.11 Vertex.2 (SHARED - indexed to Vertex.18)
+ [BOX_WITH_BONE] Writing mesh final data
+ [BOX_WITH_BONE] Overall mesh vertices: 20
+ [BOX_WITH_BONE] Overall mesh indices: 36
+ [BOX_WITH_BONE] Model Transformation Matrix: <Translation: 50.0,-105.0,40.0>.


[/quote]

+ [BOX_NO_BONE] Processing
+ [BOX_NO_BONE] Extracting face data [ 0 ]
+ [BOX_NO_BONE] Face.0 Vertex.0 (UNIQUE) <5.00,-5.00,5.00>
+ [BOX_NO_BONE] Face.0 Vertex.1 (UNIQUE) <-5.00,-5.00,5.00>
+ [BOX_NO_BONE] Face.0 Vertex.2 (UNIQUE) <-5.00,-5.00,-5.00>
+ [BOX_NO_BONE] Face.1 Vertex.0 (SHARED - indexed to Vertex.2)
+ [BOX_NO_BONE] Face.1 Vertex.1 (UNIQUE) <5.00,-5.00,-5.00>
+ [BOX_NO_BONE] Face.1 Vertex.2 (SHARED - indexed to Vertex.0)
+ [BOX_NO_BONE] Face.2 Vertex.0 (UNIQUE) <5.00,5.00,5.00>
+ [BOX_NO_BONE] Face.2 Vertex.1 (UNIQUE) <5.00,5.00,-5.00>
+ [BOX_NO_BONE] Face.2 Vertex.2 (UNIQUE) <-5.00,5.00,-5.00>
+ [BOX_NO_BONE] Face.3 Vertex.0 (SHARED - indexed to Vertex.6)
+ [BOX_NO_BONE] Face.3 Vertex.1 (UNIQUE) <-5.00,5.00,5.00>
+ [BOX_NO_BONE] Face.3 Vertex.2 (SHARED - indexed to Vertex.4)
+ [BOX_NO_BONE] Face.4 Vertex.0 (UNIQUE) <5.00,5.00,-5.00>
+ [BOX_NO_BONE] Face.4 Vertex.1 (UNIQUE) <5.00,-5.00,-5.00>
+ [BOX_NO_BONE] Face.4 Vertex.2 (UNIQUE) <-5.00,-5.00,-5.00>
+ [BOX_NO_BONE] Face.5 Vertex.0 (SHARED - indexed to Vertex.10)
+ [BOX_NO_BONE] Face.5 Vertex.1 (UNIQUE) <-5.00,5.00,-5.00>
+ [BOX_NO_BONE] Face.5 Vertex.2 (SHARED - indexed to Vertex.8)
+ [BOX_NO_BONE] Face.6 Vertex.0 (SHARED - indexed to Vertex.4)
+ [BOX_NO_BONE] Face.6 Vertex.1 (UNIQUE) <5.00,-5.00,5.00>
+ [BOX_NO_BONE] Face.6 Vertex.2 (SHARED - indexed to Vertex.3)
+ [BOX_NO_BONE] Face.7 Vertex.0 (SHARED - indexed to Vertex.3)
+ [BOX_NO_BONE] Face.7 Vertex.1 (UNIQUE) <5.00,5.00,-5.00>
+ [BOX_NO_BONE] Face.7 Vertex.2 (SHARED - indexed to Vertex.4)
+ [BOX_NO_BONE] Face.8 Vertex.0 (UNIQUE) <-5.00,5.00,5.00>
+ [BOX_NO_BONE] Face.8 Vertex.1 (UNIQUE) <-5.00,-5.00,5.00>
+ [BOX_NO_BONE] Face.8 Vertex.2 (UNIQUE) <5.00,-5.00,5.00>
+ [BOX_NO_BONE] Face.9 Vertex.0 (SHARED - indexed to Vertex.16)
+ [BOX_NO_BONE] Face.9 Vertex.1 (UNIQUE) <5.00,5.00,5.00>
+ [BOX_NO_BONE] Face.9 Vertex.2 (SHARED - indexed to Vertex.14)
+ [BOX_NO_BONE] Face.10 Vertex.0 (UNIQUE) <-5.00,5.00,-5.00>
+ [BOX_NO_BONE] Face.10 Vertex.1 (SHARED - indexed to Vertex.2)
+ [BOX_NO_BONE] Face.10 Vertex.2 (UNIQUE) <-5.00,-5.00,5.00>
+ [BOX_NO_BONE] Face.11 Vertex.0 (SHARED - indexed to Vertex.19)
+ [BOX_NO_BONE] Face.11 Vertex.1 (SHARED - indexed to Vertex.7)
+ [BOX_NO_BONE] Face.11 Vertex.2 (SHARED - indexed to Vertex.18)
+ [BOX_NO_BONE] Writing mesh final data
+ [BOX_NO_BONE] Overall mesh vertices: 20
+ [BOX_NO_BONE] Overall mesh indices: 36
+ [BOX_NO_BONE] Model Transformation Matrix: <Translation: -40.0,35.0,40.0>.
+ [BOX_NO_BONE] No Physique found.







[/quote]

Share this post


Link to post
Share on other sites
<br style="color: rgb(28, 40, 55); font-size: 13px; line-height: 16px; text-align: left; background-color: rgb(250, 251, 252); ">[color=#1C2837][size=2]

And i am starting to think why the hell everybody writes exporters but nobody knows the solution?


Check out David Lanier's site. (I went on one of his extremely good SDK training courses, highly recommended!)

From what I've seen, 3ds doesn't really have the same kind of dev community behind it that something like Maya has, which makes it a bit of a faff getting the right info (most people used to respond to my questions with "use IGame". frustrating!). The Skin modifiers are a little bit easier to use, so most people just seem to use that from what I've seen.

So you say to " grab the undeformed (original) local space values from the base object (Object::FindBaseObject) at the top of the modifier stack" - yeah, but how do i do this ?


You're looking for the base object essentially. (thankfully on holiday, and no 3ds max in sight at the moment!). From memory, you eval the Inode, it returns the object state (which has the world space object result contained within it). From (os.obj rings a bell?) you should be able to call FindBaseObject to find the original geometry. Normally you'd expect this to be a tri or poly mesh (although in your test scene, it could be a polycube instead). I think it's something like this:

ObjectState* state = inode->Eval(0)
state->obj //< this is the result in world space

Which gets you the output of the modifier stack. I think the base object is something like this:
Object* baseobj = state->obj->FindBaseObject()


The local space data should then match up with the bind pose transforms stored on the physique nodes. Or something like that!


And still objects having physique attached, return vertexes in non-object space ( as in first post ).
D#@mn it.[/quote]

Are you converting the object-state object directly to a mesh? (the one returned by eval?). Try getting its base object, or....


Don't bother. Grabbing the local space data involves a little bit more work iirc.There are also some cases where grabbing the local space data will fail, and some cases where grabbing the world space data will fail. They are fairly rare edge cases though (almost always as a result of data from a 3rd party importer, which hasn't set things up in *quite* the same way as max). I've actually ended up support both methods, and have an export flag to choose between them. Just thought I'd better mention that before you went hacking apart your working code! If I were you, I'd just leave it as it is ;)

Share this post


Link to post
Share on other sites

Check out David Lanier's site. (I went on one of his extremely good SDK training courses, highly recommended!)

From what I've seen, 3ds doesn't really have the same kind of dev community behind it that something like Maya has, which makes it a bit of a faff getting the right info (most people used to respond to my questions with "use IGame". frustrating!). The Skin modifiers are a little bit easier to use, so most people just seem to use that from what I've seen.

So you say to " grab the undeformed (original) local space values from the base object (Object::FindBaseObject) at the top of the modifier stack" - yeah, but how do i do this ?
[/quote]








Might be that you're right, but i was almost sure that gamedev community was very up-to-date with Max plug in development, well it looks like i was wrong unfortunately.

Well, as i am doing a game project for my client, there are no 'changes' that can be made - they want Max plugin, and i need to code it - no matter what..

So here i am, coding this stuff already delayed 2 weeks on my Christmas holidays break..





You're looking for the base object essentially. (thankfully on holiday, and no 3ds max in sight at the moment!). From memory, you eval the Inode, it returns the object state (which has the world space object result contained within it). From (os.obj rings a bell?) you should be able to call FindBaseObject to find the original geometry. Normally you'd expect this to be a tri or poly mesh (although in your test scene, it could be a polycube instead). I think it's something like this:

ObjectState* state = inode->Eval(0)
state->obj //< this is the result in world space

Which gets you the output of the modifier stack. I think the base object is something like this:
Object* baseobj = state->obj->FindBaseObject()


The local space data should then match up with the bind pose transforms stored on the physique nodes. Or something like that!

[/quote]





I get what you mean, will check it in a moment and see what will happen...




Are you converting the object-state object directly to a mesh? (the one returned by eval?). Try getting its base object, or....

Don't bother. Grabbing the local space data involves a little bit more work iirc.There are also some cases where grabbing the local space data will fail, and some cases where grabbing the world space data will fail. They are fairly rare edge cases though (almost always as a result of data from a 3rd party importer, which hasn't set things up in *quite* the same way as max). I've actually ended up support both methods, and have an export flag to choose between them. Just thought I'd better mention that before you went hacking apart your working code! If I were you, I'd just leave it as it is ;)
[/quote]

Yeah can't just 'leave it as it is' . They want Level Editing to be done completely with max, and all was fine at the beginning due to the fact i was exporting everything in World Space ( GetObjTMAfterWSM ) and all stuff was up there in the engine showing correctly. This was Easy, i created one .MAX file which was the level, and it was pivoted in 0,0,0, then another object as separate .MAX , and merged all in engine loader class..

But when they have updated the project requirements asking for Levels to be completely made in Max, so when they create a "Lamp" object, they create it in Max, and merge it to the level also in Max, move it to the correct position, rotate, add animation and export.

Then it became a pain in the a$, as i wasn't prepared to have such a big problems with such a 'simple' thing we all might think.




So as you see, they want the level to be prepared in Max with all the objects already there - this is why i have to grab their Local Object Space vertex positions, so that i can manage their positions later on in OpenGL by translating within object Model Transformation Matrix. If I'll get them with wrong Vertex Positions ( not object ones ) from Max, i won't be able to manage properly their Location in the engine.. not mentioning rotation etc..


Btw, thanks for sharing your thoughts with me during that special time of year, Merry Christmas btw. and thanks again.

Time to get to work again,

will come back with the results.

Share this post


Link to post
Share on other sites
Update:




Unfortunately, FindBaseObject - method was not much of a help, well no help at all, so the only solution I've found - works ( i have posted it above, the one with pivots ).

Now my objects vertices's are exported in Object Space ( they are in relation with the pivot ).





Next thing, it's time to export the bone transformation matrices properly... ( i also did that in WSpace previously and it worked ) .
Having in mind, i have already exported (1) vertices in object space, i have exported the (2) model transformation matrix ( the object position / rotation )

I shall export bone matrices with respect to the model transformation matrix (2) i believe..

So that final position would be:

Model Vertex (1) * Model Transformation Matrix (2) * mvp [/quote]




Adding animation will result in:




//Pseudocode!!

// Grab per frame matrix for this bone

CMatrix4x4 BoneTransformationMatrix = GetBoneMatrixAtFrame(iFrame)

// Get original vertex position

Vector3 v3NewVertexPosition = Model Vertex(1) ;

// Rotate with bone quaternion

v3NewVertexPosition = BoneTransformationMatrix.GetRotationQuaternion() * vNewVertexPosition ;

// add translation of the bone

v3NewVertexPosition += Vector3(BoneTransformationMatrix.GetTranslation());




// At this point, vertex should be rotated and translated as per bone position.

// That would be ideal solution







So i need to get that Bone Transformation Matrix per frame, it can't be done with



for(eachFrame)
{
Matrix3 matBoneTransformationMatrix = m_vBones[iBone]->GetObjTMAfterWSM(iFrame * GetTicksPerFrame());

fwrite(...)


}


as i'll get it in World Space and when multiplied by Model Transformation Matrix(2) it will fall far away from it's position.

So i need to somehow Get that Bone Transformation Matrix and substract it from Model Transformation Matrix (2).. hush!







Let's try.

Share this post


Link to post
Share on other sites
Ok, another update - everything before dint not work.

Here's what is actually happening.

indoor30.jpg

In order to display this scene in GL, i export the data as per below:

1) All object's vertices are exported in their local space and converted to Right Handed


Box dimensions: 50,50,50

+ [Box01] Face.0 Vertex.0 (UNIQUE) <25.00,-25.00,-25.00>
+ [Box01] Face.0 Vertex.1 (UNIQUE) <-25.00,-25.00,-25.00>
+ [Box01] Face.0 Vertex.2 (UNIQUE) <-25.00,-25.00,25.00>
...






2) All object's initial transformations are exported in World Space and converted to RightHanded


OpenGLMatrix:
1.000000 0.000000 0.000000 0.000000
0.000000 0.000000 -1.000000 -0.000001
-0.000000 1.000000 0.000000 -105.000000
0.000000 0.000000 0.000000 1.000000




3) All bone transformation matrices per frames are exported in their local space and converted to Right Handed


BONE DATA + [Box01] Physique.Frame.0.Bone.0.Bone01. Frame
LocalMatrix:
1.000000 0.000000 0.000000
0.000000 0.999972 0.007439
0.000000 -0.007439 0.999972
0.000000 0.000000 0.000000
OpenGLMatrix:
1.000000 0.000000 0.000000 0.000000
0.000000 0.999972 -0.007439 0.000000
0.000000 0.007439 0.999972 0.000000
0.000000 0.000000 0.000000 1.000000

BONE DATA + [Box01] Physique.Frame.1.Bone.0.Bone01. Frame
LocalMatrix:
1.000000 0.000000 0.000000
0.000000 0.999569 0.029351
0.000000 -0.029351 0.999569
0.000000 0.000000 0.000000
OpenGLMatrix:
1.000000 0.000000 0.000000 0.000000
0.000000 0.999569 -0.029351 0.000000
0.000000 0.029351 0.999569 0.000000
0.000000 0.000000 0.000000 1.000000




Everything then is summed up and displayed via shader as per below:



-- Engine --
vertex.position = bone.rotation[frame] * original.vertex.position
vertex.position += bone.translation[frame]
update vbo

--- Shader ---


mat4 modelViewMatrix = mat4_View * mat4_Model;
mat4 mvpMatrix = mat4_Projection * modelViewMatrix;

gl_Position = mvpMatrix * vec4(in_VertexPosition, 1.0);




Now, can somebody tell me if this is the right export approach?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!