Skinned DTS Models Not Displaying
by Patrick Chambers · in Torque X 2D · 04/06/2008 (2:00 pm) · 8 replies
I've been hammering my way through the TorqueX 2.0 demo and source to try and get some personally created content to appear in a pretty much blank Torque 3D starter game and have been running into a problem that has really left me baffled.
I'm using 3DS Max 2008 with the current v9 max2dts exporter plugin that I downloaded from the GG resource section. If I create a static model, toss a bounding box around it and export it with the standard dummy objects, it appears in my blank test project. (I can even get a Lighting Material to attach to it and be lit by a Sun object.) However, when I go back into Max, create a simple two bone hierarchy and then skin my model, attach the bones, create a very simple sequence that rotates the head of my model, I cannot get it to appear in the game. The model exports fine, the engine lets me load it up without into compliation or runtime errors, yet the model doesn't appear.
As a reference point, I grabbed the Boombot model from the FPS demo and imported into my blank project. It would display without any effort, even if I did not try to use any of its default LightingMaterials that the FPS demo calls up.
Anyone have an idea what TorqueX is looking for when trying to load up a skinned model? I'm obviously missing something simple here and all the online resources for skinned characters have not corrected the issue.
I'm using 3DS Max 2008 with the current v9 max2dts exporter plugin that I downloaded from the GG resource section. If I create a static model, toss a bounding box around it and export it with the standard dummy objects, it appears in my blank test project. (I can even get a Lighting Material to attach to it and be lit by a Sun object.) However, when I go back into Max, create a simple two bone hierarchy and then skin my model, attach the bones, create a very simple sequence that rotates the head of my model, I cannot get it to appear in the game. The model exports fine, the engine lets me load it up without into compliation or runtime errors, yet the model doesn't appear.
As a reference point, I grabbed the Boombot model from the FPS demo and imported into my blank project. It would display without any effort, even if I did not try to use any of its default LightingMaterials that the FPS demo calls up.
Anyone have an idea what TorqueX is looking for when trying to load up a skinned model? I'm obviously missing something simple here and all the online resources for skinned characters have not corrected the issue.
#2
Apparently the Boombot DTS model that comes in the FPS demo is NOT skinned after all! It's just a collection of linked meshes to a rigged IK skeleton! That's why it works and my skinned DTS model does not! I just downloaded the TGE demo to get the Orc player model from there since I know its skinned via the ShowTool Pro documentation and tried it. No go! Of course unlike my model, the orc actually crashes with a runtime error, but nevertheless loading a skinned model in TorqueX requires something special.
On to trying to figure out what that is....
04/08/2008 (12:17 am)
It's amazing what you notice when you program late at night/early in the morning.Apparently the Boombot DTS model that comes in the FPS demo is NOT skinned after all! It's just a collection of linked meshes to a rigged IK skeleton! That's why it works and my skinned DTS model does not! I just downloaded the TGE demo to get the Orc player model from there since I know its skinned via the ShowTool Pro documentation and tried it. No go! Of course unlike my model, the orc actually crashes with a runtime error, but nevertheless loading a skinned model in TorqueX requires something special.
On to trying to figure out what that is....
#3
Also, I have the same exact problems with certain DTS shapes. I think there mught be a problem in the sape loader code. It's on my long list of things to look into.
John K.
04/08/2008 (1:45 pm)
Patrick, It's not much, but have you already seen this? www.garagegames.com/mg/forums/result.thread.php?qt=71472 Also, I have the same exact problems with certain DTS shapes. I think there mught be a problem in the sape loader code. It's on my long list of things to look into.
John K.
#4
Here's what I've found on the problem so far:
1) When I try to load up the Orc player DTS mesh (with no sequences/DSQ's to keep things simple) in a blank 3d startergame project, I get an IndexOutOfRangeException error on line 361 in tsShapeInstance.cs in the _RenderMesh() function.
2) Digging deeper in the source, I found that since a skinned mesh is always unlinked in a DTS shape export, the engine sets that NodeIndex to -1 to tell the engine this mesh is actually a tsSkinMesh. If you toss a watch on the mesh assignement a few lines above this code block, you can see that the engine does recognize this as a skinned mesh, but when it tries to call out this local matrix multiplication it craps out.
3) That_nodeTransforms array does contain all the loaded transforms (28 for the Orc player model), however I could not sift throught all those matrices to see if one of them could be used for this skin mesh call, or if an entirely different logic block needs to be added here to check for a -1 on the NodeIndex and process this local matrix mult differently.
I'm not giving up just yet. Now that I know that it is not my model that is causing the problem, I have renewed hope that I can figure out what the problem is and try and at least understand it, if not correct it.
04/08/2008 (2:25 pm)
Yes, I used that post to help me get my static DTS model to work. It's the skin modifier that is doing it. I spent most of last night/this morning tracing through the code to see what happens when you try to load up a Skinned DTS mesh. The actual file loads up and populates its values correctly as far as I can tell but when tsShapeInstance tries to render the mesh, it craps out.Here's what I've found on the problem so far:
1) When I try to load up the Orc player DTS mesh (with no sequences/DSQ's to keep things simple) in a blank 3d startergame project, I get an IndexOutOfRangeException error on line 361 in tsShapeInstance.cs in the _RenderMesh() function.
srs.World.Push(); srs.World.MultiplyMatrixLocal(_nodeTransforms[obj.Object.NodeIndex]); // IndexOutOfRange...NodeIndex is -1 mesh.Render(obj.Frame, obj.MaterialFrame, materialList, srs); srs.World.Pop();
2) Digging deeper in the source, I found that since a skinned mesh is always unlinked in a DTS shape export, the engine sets that NodeIndex to -1 to tell the engine this mesh is actually a tsSkinMesh. If you toss a watch on the mesh assignement a few lines above this code block, you can see that the engine does recognize this as a skinned mesh, but when it tries to call out this local matrix multiplication it craps out.
3) That_nodeTransforms array does contain all the loaded transforms (28 for the Orc player model), however I could not sift throught all those matrices to see if one of them could be used for this skin mesh call, or if an entirely different logic block needs to be added here to check for a -1 on the NodeIndex and process this local matrix mult differently.
I'm not giving up just yet. Now that I know that it is not my model that is causing the problem, I have renewed hope that I can figure out what the problem is and try and at least understand it, if not correct it.
#5
Since I knew I had at least one bone in the _nodeTransforms array, I just forced the -1 value to 0, which pulls out the first bone node's local matrix transform and passes that along to the renderer. The code now runs and although my poor test model is now rotated in two axis incorrectly, it does now render in the test project.
So, basically, what TorqueX needs here is the Local Matrix of the Skinned mesh. I skimmed through the tsSkinMesh.cs to see if there was a local variable for that, but there wasn't. I guess all skinned DTS models need is a way to pull out their local matrix transform for the renderer.
Continuing with my experimentation, I decided to see if perhaps the skinned mesh was already setup with it's local to world transforms during export. If that was the case, then for skinned meshes, we could skip the problem line completely. So, I changed the code to this:
Well what do you know? Running this code and my test model appears to render just fine. I'm not 100% this is a true fix for this problem, but I'm gonna try a few other test models from the TGE demo to see if it does in fact work. If it does, I'll move on to testing sequences!
04/08/2008 (3:38 pm)
Well that definitely is the problem area. Just for kicks, I went ahead and added some test code to that section I posted above to see what would happen:srs.World.Push(); // Test code to see what happens... if (obj.Object.NodeIndex == -1) srs.World.MultiplyMatrixLocal(_nodeTransforms[obj.Object.NodeIndex + 1]); else srs.World.MultiplyMatrixLocal(_nodeTransforms[obj.Object.NodeIndex]); mesh.Render(obj.Frame, obj.MaterialFrame, materialList, srs); srs.World.Pop();
Since I knew I had at least one bone in the _nodeTransforms array, I just forced the -1 value to 0, which pulls out the first bone node's local matrix transform and passes that along to the renderer. The code now runs and although my poor test model is now rotated in two axis incorrectly, it does now render in the test project.
So, basically, what TorqueX needs here is the Local Matrix of the Skinned mesh. I skimmed through the tsSkinMesh.cs to see if there was a local variable for that, but there wasn't. I guess all skinned DTS models need is a way to pull out their local matrix transform for the renderer.
Continuing with my experimentation, I decided to see if perhaps the skinned mesh was already setup with it's local to world transforms during export. If that was the case, then for skinned meshes, we could skip the problem line completely. So, I changed the code to this:
srs.World.Push(); // Test code to see what happens... if (obj.Object.NodeIndex != -1) srs.World.MultiplyMatrixLocal(_nodeTransforms[obj.Object.NodeIndex]); mesh.Render(obj.Frame, obj.MaterialFrame, materialList, srs); srs.World.Pop();
Well what do you know? Running this code and my test model appears to render just fine. I'm not 100% this is a true fix for this problem, but I'm gonna try a few other test models from the TGE demo to see if it does in fact work. If it does, I'll move on to testing sequences!
#6
I have students getting ready to export character meshes and animations into TX 3D now and was wondering if you had an further conclusions with this subject.
Thanks,
Jeff
04/14/2008 (10:49 am)
Patrick,I have students getting ready to export character meshes and animations into TX 3D now and was wondering if you had an further conclusions with this subject.
Thanks,
Jeff
#7
Yes. I've thoroughly tested all the skinned DTS models that comes with the TGE demo and they all display fine. If you are planning on using actual skinned meshes and not just separate meshes linked directly to a bones or biped hierarchy then you will need to edit the code I've listed above and add that one line to check for the NodeIndex being -1. Also, getting the model to display isn't a problem, but getting the animation stuff to play has caused me some consternation.
I have been unable to load up the animation in direct code and get it to play (despite the code compiling and tracing through fine). Currently it seems that loading models with animation only work via entering xml into your txscene, as the deserializer seems to have some mystery init code that I have been unable to locate to perform manually in code. For sanity sake, just go to the FPS demo's level's and grab the player object section. To display the model and have a test animation work, you can use the following xml (I put mine in the objects section right after the terrain object that the 3d startergame puts in by default:
Obviously you will want to change the dts model name to you model name, and put the proper sequence name of your test animation in the SequenceName section (if you like me embedded the the sequence into the DTS model). If you exported your sequence into a separate DSQ file, you will omit the SequenceName section and instead use the SequenceFilename section to point to your DSQ, (it needs to be in the same directory as your DTS and you'll need to use the standard Torque file stuff to point to it: @"data\shapes\TestModel.dsq")
Hope that helps you.
04/14/2008 (11:28 am)
Jeff,Yes. I've thoroughly tested all the skinned DTS models that comes with the TGE demo and they all display fine. If you are planning on using actual skinned meshes and not just separate meshes linked directly to a bones or biped hierarchy then you will need to edit the code I've listed above and add that one line to check for the NodeIndex being -1. Also, getting the model to display isn't a problem, but getting the animation stuff to play has caused me some consternation.
I have been unable to load up the animation in direct code and get it to play (despite the code compiling and tracing through fine). Currently it seems that loading models with animation only work via entering xml into your txscene, as the deserializer seems to have some mystery init code that I have been unable to locate to perform manually in code. For sanity sake, just go to the FPS demo's level's and grab the player object section. To display the model and have a test animation work, you can use the following xml (I put mine in the objects section right after the terrain object that the 3d startergame puts in by default:
<Player type="GarageGames.Torque.Core.TorqueObject" name="Player">
<Components>
<AnimationComponent type="GarageGames.Torque.T3D.T3DAnimationComponent">
<SceneGroupName>PlayerMesh</SceneGroupName>
<Animations>
<Animation type="GarageGames.Torque.T3D.TSAnimation">
<ThreadName>ActionThread</ThreadName>
<SequenceName>test</SequenceName>
<Name>TestAnimation</Name>
</Animation>
</Animations>
</AnimationComponent>
<RenderComponent type="GarageGames.Torque.T3D.T3DTSRenderComponent">
<SceneGroupName>PlayerMesh</SceneGroupName>
<ShapeName>data\shapes\TestModel.dts</ShapeName>
</RenderComponent>
<SceneComponent type="GarageGames.Torque.T3D.T3DSceneComponent">
<SceneGroup>PlayerMesh</SceneGroup>
<Position>
<X>1024</X>
<Y>1024</Y>
<Z>300</Z>
</Position>
</SceneComponent>
</Components>
</Player>Obviously you will want to change the dts model name to you model name, and put the proper sequence name of your test animation in the SequenceName section (if you like me embedded the the sequence into the DTS model). If you exported your sequence into a separate DSQ file, you will omit the SequenceName section and instead use the SequenceFilename section to point to your DSQ, (it needs to be in the same directory as your DTS and you'll need to use the standard Torque file stuff to point to it: @"data\shapes\TestModel.dsq")
Hope that helps you.
#8
Just thought I'd also add that when you run your app using this method, whatever animation you loaded in your txscene will automatically start playing. If you did not choose to have your animation by set to cyclic there is a chance you could miss it as the default camera location in the 3d startergame template puts you right under your model. I would recommend that you set your first test sequence to cyclic just so you have plenty of time to move your camera around to see your model. (You could also change the default position and direction of the free camera to point at your model, but that may take a little trial and error to get right and it's not 100% required to just load up a model and see it turn its head or whatever.)
04/14/2008 (11:33 am)
[Addendum:]Just thought I'd also add that when you run your app using this method, whatever animation you loaded in your txscene will automatically start playing. If you did not choose to have your animation by set to cyclic there is a chance you could miss it as the default camera location in the 3d startergame template puts you right under your model. I would recommend that you set your first test sequence to cyclic just so you have plenty of time to move your camera around to see your model. (You could also change the default position and direction of the free camera to point at your model, but that may take a little trial and error to get right and it's not 100% required to just load up a model and see it turn its head or whatever.)
Torque Owner Patrick Chambers
Gonna head back into the source to see if I can unearth the secret. :)