Game Development Community

[Bug] addMesh in 1.0 causing crash - LOGGED

by Ted Southard · in Torque 3D Professional · 11/16/2009 (1:26 pm) · 4 replies

In trying to get LODs added to objects after the fact, I'm trying to follow the example in the Official Docs. There, it's mentioned that using addMesh(filename, meshName, newMeshName) would do the trick. However, I'm running into crashes when calling addMesh during the onLoad() of my object. Here is the script that I currently use:

function BountyAgencyDAE::onLoad(%this)
{
   //TODO: Place into function, take %newLOD as parameter...
   %newLOD = ba50dae;
   
   //Dump destination object
   echo("=====Destination Object====="); 
   %this.dumpShape();
   
   //Dump new LOD
   echo("=====New LOD====="); 
   %newLOD.dumpShape();
   
   //Set new LODs size to 64
   echo("=====Resize New LOD====="); 
   %ona = %newLOD.getObjectName(0);
   echo(%newLOD SPC "object:" SPC %ona);
   %mesha = %newLOD.getMeshName(%ona, 0);
   echo(%newLOD SPC "mesh/detail:" SPC %mesha);
   %mna = strreplace(%mesha, %ona, %ona @ " ");
   echo(%newLOD SPC "meshname:" SPC %mna);
   %newLOD.setMeshSize(%mna, 64);
   
   //Set destination object's size to 128
   echo("=====Resize Destination Object====="); 
   %onb = %this.getObjectName(0);
   echo(%this.name SPC "object:" SPC %onb);
   %meshb = %this.getMeshName(%onb, 0);
   echo(%this.name SPC "mesh/detail:" SPC %meshb);
   %mnb = strreplace(%meshb, %onb, %onb @ " ");
   echo(%this.name SPC "meshname:" SPC %mnb);
   %this.setMeshSize(%mnb, 128);
   
   //Add the new LOD to the destination object
   echo("=====Adding LOD====="); 
   %ona = %newLOD.getObjectName(0);
   echo(%newLOD SPC "object:" SPC %ona);
   %mesha = %newLOD.getMeshName(%ona, 0);
   echo(%newLOD SPC "mesh/detail:" SPC %mesha);
   %mna = strreplace(%mesha, %ona, %ona @ " ");
   echo(%newLOD SPC "meshname:" SPC %mna);
   
   %newLOD.dumpShape();
   
   //Now add it, finally...
   echo("Add Function:" SPC "%this.addMesh("art/shapes/ba50.dae", "" @ %mna @ "", " " @ %mesha @ "");");
   %this.addMesh("art/shapes/ba50.dae", %mna, %mesha); //Bang! Crashes here, every time
   
   //We're done, dump destination object again to check
   echo("=====LOD Added====="); 
   %this.dumpShape();
}

The output leading up to the crash looks like this (it's pretty verbose):
=====Destination Object=====

Shape Hierarchy:

   Details:
      detail128, Subtree 0, objectDetail 0, size 128

   Subtrees:
      Subtree 0
         Cylinder04 --> Object Cylinder04 with following details:  128

   Sequences:

   Material list:
   material #0: 'orig_orig_03___Default'.
=====New LOD=====

Shape Hierarchy:

   Details:
      detail2, Subtree 0, objectDetail 0, size 2

   Subtrees:
      Subtree 0
         mesh --> Object mesh with following details:  2

   Sequences:

   Material list:
   material #0: 'material_0'.
=====Resize New LOD=====
BA50DAE object: mesh
BA50DAE mesh/detail: mesh2
BA50DAE meshname: mesh 2
=====Resize Destination Object=====
BountyAgencyDAE object: Cylinder04
BountyAgencyDAE mesh/detail: Cylinder04128
BountyAgencyDAE meshname: Cylinder04 128
=====Adding LOD=====
BA50DAE object: mesh
BA50DAE mesh/detail: mesh64
BA50DAE meshname: mesh 64

Shape Hierarchy:

   Details:
      detail64, Subtree 0, objectDetail 0, size 64

   Subtrees:
      Subtree 0
         mesh --> Object mesh with following details:  64

   Sequences:

   Material list:
   material #0: 'material_0'.
Add Function: %this.addMesh("art/shapes/ba50.dae", "mesh 64", " mesh64"); //Echo'ed

Now, right after echoing the function, the function is called as seen, and the build crashes. Debugging, I'm told:
Quote:Unhandled exception at 0x108481df (EpicFrontiers_Debug.dll) in EpicFrontiers_Debug.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd

Where it points is to Line 74 of gfxVertexFormat.cpp:
const String& GFXVertexFormat::getDescription() const
{
   if ( mDirty )
      const_cast<GFXVertexFormat*>(this)->_updateDirty();

   return mDescription;
}

Looking into the addMesh() function itself, it seems to blow up around Line 887 of tsShapeEdit.cpp:
if (mesh->getMeshType() != TSMesh::SkinMeshType)
      mesh->createVBIB(); //<---Here

And createVBIB() seems to blow up around Line 2229 of tsMesh.cpp:
// Create the vertex buffer
      if( vertsChanged || vb == NULL )
         vb.set( GFX, mVertSize, mVertexFormat, mNumVerts, mDynamic ? GFXBufferTypeDynamic : GFXBufferTypeStatic );

From there the code gets into allocations, but it's a fairly straight line to follow to this, where I have an uneducated hunch (around Line 13 of gfxVertexBuffer.cpp):
void GFXVertexBufferHandleBase::set(   GFXDevice *theDevice,
                                       U32 numVerts, 
                                       const GFXVertexFormat *vertexFormat,
                                       U32 vertexSize, 
                                       GFXBufferType type )
{
   StrongRefPtr<GFXVertexBuffer>::operator=( theDevice->allocVertexBuffer( numVerts, vertexFormat, vertexSize, type ) );
}

The only thing here is that I'm out of my depth on deep GFX stuff, so if anyone can try to replicate or tell me the correct dosage of crack I should be smoking to not make the mistake I may be making, I would be grateful :)

#1
11/16/2009 (6:09 pm)
Hi Ted,

Not sure why this is crashing, although there have been some changes to this area of tsShapeEdit since 1.0.1. Does the BA50DAE model load and display correctly in the Shape Editor (ie. as a standalone model)?

I understand if you are not able to, but usually the fastest way to resolve these sort of issues is to send me the models that are causing the problem.


Unrelated to the crash - I'm not sure I follow exactly what you're doing here? Did you want to use 'mesh2' as a lower detail mesh for the Cylinder04 object? If so, then your code should do this:

// Change destination detail size to 128
%this.setMeshSize("Cylinder04 2", 128);

// Add lower detail mesh at detail size 64
%this.addMesh("art/shapes/ba50.dae", "mesh 2", "Cylinder04 64");

Note:
1. There is no need to set the detail size in the source model (BA50DAE), since that will be done when the mesh is added to the destination model.

2. The 'newMeshName' argument "Cylinder04 64" gives the object name (Cylinder04) and the desired detail size (64). If there is not an object with that name in the destination model, then one will be created, and you will have 2 different objects at different detail levels, instead of a single object with 2 detail levels.
#2
11/16/2009 (9:12 pm)
Yeah, the object loads just fine into both the World and Shape Editors with a material and all. I emailed the models to you to look at, thanks!

Quote:Did you want to use 'mesh2' as a lower detail mesh for the Cylinder04 object?

Exactly. And I made the changes below according to your advice, and I'm still getting crashes:

//TODO: Place into function, take %newLOD as parameter...
   %newLOD = ba50dae;
   
   //Dump destination object
   echo("=====Destination Object====="); 
   %this.dumpShape();
   
   //Dump new LOD
   echo("=====New LOD====="); 
   %newLOD.dumpShape();
   
   //Set new LODs size to 64
   echo("=====Resize New LOD====="); 
   %ona = %newLOD.getObjectName(0);
   echo(%newLOD SPC "object:" SPC %ona);
   %mesha = %newLOD.getMeshName(%ona, 0);
   echo(%newLOD SPC "mesh/detail:" SPC %mesha);
   %mna = strreplace(%mesha, %ona, %ona @ " ");
   echo(%newLOD SPC "meshname:" SPC %mna);

   //Add the new LOD to the destination object
   echo("=====Adding LOD====="); 

   //Now add it, finally...
   %name = setWord(%mnb, 1, "64");
   echo("Add Function:" SPC "%this.addMesh(\"art/shapes/ba50.dae\", \"" @ %mna @ "\", \"" @ %name @ "\");");
   %this.addMesh("art/shapes/ba50.dae", %mna, %name); //Bang!
   
   //We're done, dump destination object again to check
   echo("=====LOD Added====="); 
   %this.dumpShape();
#3
11/17/2009 (10:08 pm)
To prevent the crash, add these 2 lines to TSShape::addMesh (around line 1000) in tsShapeEdit.cpp:

{
   ...
   mesh->mHasTVert2 = srcMesh->mHasTVert2;
   mesh->mNumVerts = srcMesh->mNumVerts;

   // add these 2 lines
   mesh->mVertSize = mVertSize;
   mesh->mVertexFormat = &mVertexFormat;

   if (srcMesh->mVertexData.isReady())
   {
#4
06/15/2010 (7:43 pm)
Logged: TQA-394