Crash when setting new datablock (animation related)
by Nathan Bowhay - ESAL · in Torque 3D Professional · 06/19/2009 (3:20 pm) · 4 replies
I ran into a crash if I have an object that has a datablock with an animation and the animation is playing and then I set a new datablock with art that doesn't have an animation it crashes, I am guessing cause:
setThreadSequence is called and st.thread is null so it calls mShapeInstance->addThread() and mShape->sequences.empty() is true so it returns null again so st.thread is still null.
setThreadSequence is called and st.thread is null so it calls mShapeInstance->addThread() and mShape->sequences.empty() is true so it returns null again so st.thread is still null.
#2
In ShapeBase.cpp, new ShapeBase::onNewDataBlock method below.
I also fixed something else, noticed that calling ShapeBase.playThread with the same slot/sequence more than once only would play it the first time. This should fix that issue:
Inside void ShapeBase::updateThread(Thread& st),
Insert this at line 2131 (including lines from previous fix)
08/24/2009 (6:53 pm)
Hey Nathan, try this fix out for me.In ShapeBase.cpp, new ShapeBase::onNewDataBlock method below.
bool ShapeBase::onNewDataBlock( GameBaseData *dptr )
{
ShapeBaseData *prevDB = dynamic_cast<ShapeBaseData*>( mDataBlock );
bool isInitialDataBlock = ( mDataBlock == 0 );
if (Parent::onNewDataBlock(dptr) == false)
return false;
mDataBlock = dynamic_cast<ShapeBaseData*>(dptr);
if (!mDataBlock)
return false;
setMaskBits(DamageMask);
mDamageThread = 0;
mHulkThread = 0;
// Even if loadShape succeeds, there may not actually be
// a shape assigned to this object.
if (bool(mDataBlock->mShape)) {
delete mShapeInstance;
mShapeInstance = new TSShapeInstance(mDataBlock->mShape, isClientObject());
if (isClientObject())
mShapeInstance->cloneMaterialList();
mObjBox = mDataBlock->mShape->bounds;
resetWorldBox();
// Set the initial mesh hidden state.
mMeshHidden.setSize( mDataBlock->mShape->objects.size() );
mMeshHidden.clear();
// Initialize the threads
for (U32 i = 0; i < MaxScriptThreads; i++) {
Thread& st = mScriptThread[i];
if (st.sequence != -1) {
// TG: Need to see about suppressing non-cyclic sounds
// if the sequences were activated before the object was
// ghosted.
// TG: Cyclic animations need to have a random pos if
// they were started before the object was ghosted.
// If there was something running on the old shape, the thread
// needs to be reset. Otherwise we assume that it's been
// initialized either by the constructor or from the server.
bool reset = st.thread != 0;
st.thread = 0;
// New datablock/shape may not actually HAVE this sequence.
// In that case stop playing it.
AssertFatal( prevDB != NULL, "ShapeBase::onNewDataBlock - how did you have a sequence playing without a prior datablock?" );
const TSShape *prevShape = prevDB->mShape;
const TSShape::Sequence &prevSeq = prevShape->sequences[st.sequence];
const String &prevSeqName = prevShape->names[prevSeq.nameIndex];
st.sequence = mDataBlock->mShape->findSequence( prevSeqName );
if ( st.sequence != -1 )
{
setThreadSequence( i, st.sequence, reset );
}
}
}
if (mDataBlock->damageSequence != -1) {
mDamageThread = mShapeInstance->addThread();
mShapeInstance->setSequence(mDamageThread,
mDataBlock->damageSequence,0);
}
if (mDataBlock->hulkSequence != -1) {
mHulkThread = mShapeInstance->addThread();
mShapeInstance->setSequence(mHulkThread,
mDataBlock->hulkSequence,0);
}
}
if( isGhost() )
reSkin();
//
mEnergy = 0;
mDamage = 0;
mDamageState = Enabled;
mRepairReserve = 0;
updateMass();
updateDamageLevel();
updateDamageState();
mDrag = mDataBlock->drag;
mCameraFov = mDataBlock->cameraDefaultFov;
updateMass();
if( !isInitialDataBlock && mLightPlugin )
mLightPlugin->reset();
if ( isClientObject() )
{
mCubeReflector.unregisterReflector();
if ( mDataBlock->reflectorDesc )
mCubeReflector.registerReflector( this, mDataBlock->reflectorDesc );
}
return true;
}I also fixed something else, noticed that calling ShapeBase.playThread with the same slot/sequence more than once only would play it the first time. This should fix that issue:
Inside void ShapeBase::updateThread(Thread& st),
Insert this at line 2131 (including lines from previous fix)
st.state = Thread::Stop;
#3
I may end up checking these fixes out anyway, but figured i would check if it was necessary or not first. Thanks a ton for the fixes by the way :)
12/16/2009 (2:49 pm)
Hey James sorry for not responding or trying this out, work has been busy and this was low priority. It appears to be fixed in T3D 1.1 Alpha, where these changes updated in one of the builds past T3D Beta 3? or should I still check them out and update the code?I may end up checking these fixes out anyway, but figured i would check if it was necessary or not first. Thanks a ton for the fixes by the way :)
#4
12/16/2009 (5:55 pm)
Yes the fix I posted is rolled into the current codebase.
Associate Rene Damm
Logged as THREED-491.