ShapeInstance Data Corruption with high values - LOGGED
by Ivan Mandzhukov · in Torque 3D Professional · 11/10/2010 (7:25 pm) · 5 replies
Hi,
I spent 2-3 days to track e serious bug in a loaded scene.The problem turned out to be a ShapeInstance data curruption.
Some of the transforms as mNodeTransforms usually work well,but suddently on a high load become broken (values are infinit).
Currently I can not locate why this happens,because the bug is hard to be reproduced.
I catch the bug this way:
This is a stock T3D code.
This bug replicates to Player::calcClassRenderData() and the ray cast there results to a bad bin range.
If I workaround the problem,the crash will not happen, but this corrupts the rendering of the shape instances (missing heads,missing bone data,etc..)
Any ideas will be appreciated.
I spent 2-3 days to track e serious bug in a loaded scene.The problem turned out to be a ShapeInstance data curruption.
Some of the transforms as mNodeTransforms usually work well,but suddently on a high load become broken (values are infinit).
Currently I can not locate why this happens,because the bug is hard to be reproduced.
I catch the bug this way:
MatrixF mountTransform = mShapeInstance->mNodeTransforms[ni]; Point3F position. mountTransform.getColumn( 3, &position ); if( mIsNaN( position )) position.set(0,0,0);
This is a stock T3D code.
This bug replicates to Player::calcClassRenderData() and the ray cast there results to a bad bin range.
If I workaround the problem,the crash will not happen, but this corrupts the rendering of the shape instances (missing heads,missing bone data,etc..)
Any ideas will be appreciated.
#2
Currently I found what is causing the issue - when I have two animation threads at the same time on a single player.
This should be not a problem,because T3D is using many threads to control the character's animation.
I will update this forum thread when I find the solution.
11/12/2010 (8:57 am)
thanks ,David.Currently I found what is causing the issue - when I have two animation threads at the same time on a single player.
This should be not a problem,because T3D is using many threads to control the character's animation.
I will update this forum thread when I find the solution.
#3
In tsTransform.cpp,at the bottom of the file I see this:
All looks good,but if you pass an identity transform,after inversing I get a non identity transform - ouch!
In mMatrix.h ,locate this:
Currently this does not solve my problem,but it seems the bug is a combination of several small transformation bugs.
11/12/2010 (1:36 pm)
I find some interesting bugs.In tsTransform.cpp,at the bottom of the file I see this:
void TSTransform::applyScale(const TSScale & scale, MatrixF * mat)
{
MatrixF mat2;
TSTransform::setMatrix(scale.mRotate,&mat2);
MatrixF mat3(mat2);
mat3.inverse();
mat2.scale(scale.mScale);
mat2.mul(mat3);
mat->mul(mat2);
}All looks good,but if you pass an identity transform,after inversing I get a non identity transform - ouch!
In mMatrix.h ,locate this:
inline MatrixF& MatrixF::inverse()
{
m_matF_inverse(m);
return (*this);
}and replace with this:inline MatrixF& MatrixF::inverse()
{
if(isIdentity()) return (*this);
m_matF_inverse(m);
return (*this);
}Currently this does not solve my problem,but it seems the bug is a combination of several small transformation bugs.
#4
11/13/2010 (5:20 am)
Was there more to your post that's now missing?
#5
Using multiple threads with complex animations may crash the time duration (transitiondata.duration),this bug then replicates to the delta.
This is just a workaround,I will provide the full fix but I need some time to track several things.
EDIT:
OK,guys,here is the full fix.When we have a real load (1-2 fps),the transition code sometimes gets confused at this frame,so:
tsThread.cpp
locate TSShapeInstance::updateTransitions()
at the bottom of this method find this:
and replace with:
Also locate this:
and replace with this:
This is good for animations without transitions to have zero durations instead of random numbers.
Locate advancePos().
At the beginning of this method paste this:
Now when delta is ranged, this prevents the shape instance from being animated with wrong values.
11/13/2010 (6:47 am)
@KenUsing multiple threads with complex animations may crash the time duration (transitiondata.duration),this bug then replicates to the delta.
This is just a workaround,I will provide the full fix but I need some time to track several things.
EDIT:
OK,guys,here is the full fix.When we have a real load (1-2 fps),the transition code sometimes gets confused at this frame,so:
tsThread.cpp
locate TSShapeInstance::updateTransitions()
at the bottom of this method find this:
// reset transition durations to account for new reference transforms
for (i=0; i<mTransitionThreads.size(); i++)
{
TSThread * th = mTransitionThreads[i];
if (th->transitionData.inTransition)
{
th->transitionData.duration *= 1.0f - th->transitionData.pos;
th->transitionData.pos = 0.0f;
}
if(th->transitionData.duration>1)
th->transitionData.pos = 0.0f;
}and replace with:
// reset transition durations to account for new reference transforms
for (i=0; i<mTransitionThreads.size(); i++)
{
TSThread * th = mTransitionThreads[i];
if (th->transitionData.inTransition)
{
if((th->transitionData.duration<0.0001) || (th->transitionData.duration>1))
th->transitionData.duration = th->getSequence()->duration;
th->transitionData.duration *= 1.0f - th->transitionData.pos;
th->transitionData.pos = 0.0f;
}
if(th->transitionData.duration>1)
th->transitionData.pos = 0.0f;
}Also locate this:
TSThread::TSThread(TSShapeInstance * _shapeInst)
{
timeScale = 1.0f;
mShapeInstance = _shapeInst;
transitionData.inTransition = false;
blendDisabled = false;
setSequence(0,0.0f);
}and replace with this:
TSThread::TSThread(TSShapeInstance * _shapeInst)
{
timeScale = 1.0f;
mShapeInstance = _shapeInst;
transitionData.inTransition = false;
blendDisabled = false;
setSequence(0,0.0f);
transitionData.duration = 0.0f;
}This is good for animations without transitions to have zero durations instead of random numbers.
Locate advancePos().
At the beginning of this method paste this:
void TSThread::advancePos(F32 delta)
{ if (mFabs(delta)>0.0f && mFabs(delta)<0.00001f)
delta = 0.00002f;
if (mFabs(delta)>1000)
delta = 0.0f;
...Now when delta is ranged, this prevents the shape instance from being animated with wrong values.
Associate David Montgomery-Blake
David MontgomeryBlake