Game Development Community

T3D 1.1 Preview - Use of TsShapeConstructor Causes Crash - RESOLVED (THREED-1569)

by Steve Acaster · in Torque 3D Professional · 04/08/2011 (3:35 am) · 12 replies

T3D 1.1 Preview

Win7 32bit

Target:
TsShapeConstructor cs files, ShapeEditor

Issues:
Any use of a TsShapeConstructor onLoad function (created via ShapeEditor) will cause a crash on restart.

Steps to repeat:
Select a model in ShapeEditor and attach another object on a new node.
Alternatively change the detail node number.
Save the new cs file.
Exit T3D and restart.
Attempt to place object in world and watch crash.

Example script:
Using FPS Example - Create a file named small_rock_01.cs FPS Examplegameartshapesvegetationdesertrockssmall_rock_01.cs. This adds a new LOD with small_rock_02.cached.dts and then changes the LOD to 600 so it's easy to spot the difference in-game.

singleton TSShapeConstructor(Small_rock_01DAE)
{
   baseShape = "./small_rock_01.DAE";
};

function Small_rock_01DAE::onLoad(%this)
{
   %this.addMesh("smallrocktwo 2", "art/shapes/vegetation/desertrocks/small_rock_02.cached.dts", "smallrocktwo 400");
   %this.addMesh("col 2", "art/shapes/vegetation/desertrocks/small_rock_02.cached.dts", "col -1");
   %this.setDetailLevelSize("2", "600");
}

This works when you do it first time in the ShapeEditor, but crashes on every subsequent restart when you attempt to put the small_rock_01 object in-game.

Suggest:
FIX IT!

[edit]
The last bug I submitted for a troublesome TsShapeConstructor -> linky

#1
04/08/2011 (6:55 am)
Logged as THREED-1569.
#2
04/23/2011 (3:10 pm)
I am experiencing more or less the same problem here :(

The difference is that it happens when using addMesh... and not, I repeat NOT when I am changing LODS.

My TSShapeConstructor file:

singleton TSShapeConstructor(MaleDts)
{
   baseShape = "./male.dts";
};

function MaleDts::onLoad(%this)
{
   %this.addSequence("art/shapes/actors/anims_ACK/player_root.dsq", "root", "0", "-1");
...
   %this.addSequence("art/shapes/actors/anims_ACK/player_lookSword.dsq", "lookSword", "0", "-1");
   %this.addTrigger("run", "16", "1");
...
   %this.addTrigger("walk", "9", "2");
   %this.setSequencePriority("Root", "1");
...
   %this.setSequencePriority("lKick1", "5");
   %this.setDetailLevelSize("48", "550");
   %this.setDetailLevelSize("16", "350");
   %this.setDetailLevelSize("8", "200");
   %this.setDetailLevelSize("2", "30");
   %this.addNode("cam", "head", "0 -0.506858 2.639 1 0 0 0", "1");
   %this.renameNode("facialHair", "mount9");
   %this.addMesh("base_hair6_one 550", "art/shapes/actors/player/hair6.dts", "base_hair6_one 0");
   %this.addMesh("base_hair6_one 350", "art/shapes/actors/player/hair6.dts", "base_hair6_one 0");
   %this.addMesh("base_hair6_one 200", "art/shapes/actors/player/hair6.dts", "base_hair6_one 0");
   %this.addMesh("base_hair6_one 30", "art/shapes/actors/player/hair6.dts", "base_hair6_one 0");
}

It runs fine when I comment the last four lines out (the addMesh).

@Steve:
Is it possible for you to confirm this?

David:

For GG info the crash report.

Crash report:

Unhandled exception at 0x108299b8 (CleanScript_DEBUG.dll) in CleanScript_DEBUG.exe: 0xC0000005: Access violation reading location 0x00000000.

in tsignal.h:
template<class A>
class Signal<void(A)> : public SignalBaseT<void(A)>
{
   public:

      void trigger( A a )
      {
         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
         {
            this->mTriggerNext = ptr->next; // Here is the crash!!!!
            this->getDelegate( ptr )( a );
            ptr = this->mTriggerNext;
         }
         this->mTriggerNext = NULL;
      }
};

Call Stack:

> CleanScript_DEBUG.dll!Signal<void __cdecl(Resource<TSShape> &)>::trigger(Resource<TSShape> & a={...}) Line 460 + 0x6 bytes C++
CleanScript_DEBUG.dll!Resource<TSShape>::_triggerPostLoadSignal() Line 248 + 0x1c bytes C++
CleanScript_DEBUG.dll!ResourceBase::assign(const ResourceBase & inResource={...}, void * resource=0x04c6b530) Line 84 C++
CleanScript_DEBUG.dll!Resource<TSShape>::operator=(const ResourceBase & base={...}) Line 197 + 0x1a bytes C++
CleanScript_DEBUG.dll!ShapeBaseData::preload(bool server=true, String & errorStr={...}) Line 282 + 0x61 bytes C++
CleanScript_DEBUG.dll!PlayerData::preload(bool server=true, String & errorStr={...}) Line 346 + 0x11 bytes C++
CleanScript_DEBUG.dll!CodeBlock::exec(unsigned int ip=4705, const char * functionName=0x04c7694c, Namespace * thisNamespace=0x00000000, unsigned int argc=0, const char * * argv=0x00000000, bool noCalls=false, const char * packageName=0x00000000, int setFrame=0) Line 864 + 0x26 bytes C++
CleanScript_DEBUG.dll!CodeBlock::compileExec(const char * fileName=0x04c7694c, const char * inString=0x04d37f38, bool noCalls=false, int setFrame=0) Line 648 C++

edit:
Forgot the \code tag.
#3
04/24/2011 (5:21 am)
Yeah, it really don't like addMesh.

Obviously all of my crashes with new LODs also have a new mesh added to the new LOD.

As a quick test I used stock rock1 and rock2 in the same LOD node.
singleton TSShapeConstructor(Rock1Dts)
{
   baseShape = "./rock1.dts";
};

function Rock1Dts::onLoad(%this)
{
   %this.setDetailLevelSize("2", "20");
   %this.addMesh("rock_a 20", "art/shapes/rocks/rock2.dts", "rock_a 2");
   %this.addMesh("Col 20", "art/shapes/rocks/rock2.dts", "Col -1");
   %this.setBounds("-8.99177 -6.76777 -0.833022 8.36053 8.25775 6.57893");
}

And the result was that ALL of my mission/levels CRASHED when trying to load, even though none of them had the rock1 object in them.
#4
04/24/2011 (8:13 am)
Here is a fix (or a change back to beta 3 if you like)

in core/util/tsignal.h around line 456 change this (make sure you have the right one, cause this function is around this file for a few times).

void trigger( A a )
      {
         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
         {
            this->mTriggerNext = ptr->next;
            this->getDelegate( ptr )( a );
            ptr = this->mTriggerNext;
         }
         this->mTriggerNext = NULL;
    }
};

into this

void trigger( A a )
      {
	     for( SignalBase::DelegateLink* ptr = this->mList.next;ptr != &this->mList; )
	     {
	         SignalBase::DelegateLink* next = ptr->next;
	         this->getDelegate(ptr)(a);
	         ptr = next;
	     }
      }
};

It is not thoroughly tested, but it is the beta3 code.
Now addMesh works again, but I don't know if this introduce other things... Maybe a dev could answer it.
#5
04/24/2011 (8:32 am)
It almost looks like the new version is attempting to address a memory leak, but I'm not seeing a leak from the old version. Maybe deleting next at the end of each loop ... but I think the re-definition should overwrite the same location in memory - maybe I'm not understanding this. Guess I should look at the rest of that file.
#6
04/24/2011 (8:54 am)
Yeah, that code rollback works, meshes now appear fine and everything in TsShapeConstructor LODs nicely - rather than dividing by zero like before.

Treat yourself to a nice Boerenkoolstamppot, you lovely Orange person.
:)
#7
04/24/2011 (9:42 am)
@Richard (Ranft):
The code there is somewhat difficult to understand, but I did compare beta 3 against the preview, and the only changes were in tsignal, so I guessed that this one was causing the problems.

@Steve:
Thanks, but I pass the Boerenkoolstamppot. Besides the fact that I don't like this dish, it is a winter dish and right now it is 23 degrees Celcius, not really winter ;). I think I am going to enjoy a nice white Zinfandel and a light dish (that rules out the Stamppot).
#8
04/24/2011 (10:44 am)
The picture of it on Wikipedia looked nice. :)

And I then spent the next hour looking for things to do with sausage and mashed potato ... enjoy your zinfandel
#9
05/06/2011 (5:14 pm)
Fixed in 1.1 Final.
#10
05/07/2011 (5:45 am)
I see the 'fix'...some Rex observations on 'addMeshing'

I wonder if not having the mesh 'object' defined[in the DTS shape] as well was doing some oddities...I found this in earlier 'betas'. Or adding a mesh to a shape with no corresponding Node.

In earlier betas...I had to addNodes and objects to get meshes 'merging' as I'd expect. If the node ain't there...meshes don't arrive or arrive at World Origin[0,0,0]

TSShapeConstructor is the coolest....had a great time experimenting with it...;) Added an entire 'army' outfit from a modern male avatar to a 'elvin' female ranger avatar....with TSShapeConstructor.

Oh, BTW; how are 'smoothing group' data being parsed in Preview? I was getting visible 'seams' at mesh boundaries when 'merging' subMeshes from another DTS file in earlier betas?? If this issue can be resolved...T3D can be used for nearly anything! An 'easy' check is to take a sphere DTS shape[smoothed/no seams/multiple subMesh groups], copy it, rename it, then remove part of the destination DTS. Now, 'addMesh' the same subMesh grouping from the target DTS file...and see if there are 'seams' between the objects...?!? In earlier betas, I found visible seams at the boundaries. To me, there shouldn't be any seam...same nodes, same transforms....normals should be the same? And no seam visible...

addMesh is so helpful....didn't expect the vertex weighting to parse[as long as namingConvention is same and transforms too]...meshes merge flawlessly!

Some working Tutorials would be superLicious! The scripting documents help a lot, takes some experimenting to assemble the DTS satisfactorily.

Have fun with TSShapeConstructor!

...and I seem to remember some difference between 'rigid' mesh objects and 'skinned' mesh objects....;), being added I'll have to dig thru the art tree to find the two DTS shapes I used to see exactly what I did. OH, and I never used the Editor...always 'hand rolled'.
#11
05/07/2011 (8:06 am)
Quote:
Added an entire 'army' outfit from a modern male avatar to a 'elvin' female ranger avatar....with TSShapeConstructor.

If you read that back, Rex - it sounds like some sort of transgender operation ...
#12
05/18/2011 (3:14 am)
...no, just crossDressing, she's still a female, ;)!