Game Development Community

when i break shape ,crash

by Zhangruquan · in Torque 3D Professional · 11/26/2009 (9:11 am) · 8 replies

I change the rocketLauncher.cs like this:
//[add the rocketLauncherDebris
datablock DebrisData(rocketLauncherDebris)
{
explodeOnMaxBounce = false;

elasticity = 0.15;
friction = 0.5;

lifetime = 2.0;
lifetimeVariance = 0.0;

minSpinSpeed = 40;
maxSpinSpeed = 200;

numBounces = 5;
bounceVariance = 0;

staticOnMaxBounce = true;
gravModifier = 1.0;

useRadiusMass = true;
baseRadius = 1;

velocity = 30.0;
velocityVariance = 12.0;
};
//]

datablock ItemData(RocketLauncher)
{
// Mission editor category
category = "Weapon";

// Hook into Item Weapon class hierarchy. The weapon namespace
// provides common weapon handling functions in addition to hooks
// into the inventory system.
className = "Weapon";

// Basic Item properties
shapefile = "art/shapes/weapons/SwarmGun/swarmgun.dts";
//[add this
debrisShapeName = "art/shapes/weapons/SwarmGun/swarmgun.dts";
debris = rocketLauncherDebris;
//]
mass = 5;
elasticity = 0.2;
friction = 0.6;
emap = true;

// Dynamic properties defined by the scripts
pickUpName = "SwarmGun";
description = "RocketLauncher";
image = RocketLauncherImage;

// weaponHUD
previewImage = 'swarmer.png';
reticle = 'reticle_rocketlauncher';
};

then i creat a item in the mission like this
%item = new Item() {
collideable = "0";
static = "1";
rotate = "1";
rotate2 = "0";
dataBlock = "RocketLauncher";
position = "316.922 -146.512 244.404";
rotation = "1 0 0 0";
scale = "1 1 1";
canSaveDynamicFields = "1";
};


then i call this %item.setDamageState(Destroyed);


so it crash ,i use the debug mode,follow this,
it crash in TSShapeInstance::setDetailFromDistance 's
if ( mShape->mSmallestVisibleDL >= 0 &&
mShape->details.first().maxError >= 0)

I don't know the reason ,so i need help of you ,please

About the author

Recent Threads


#1
11/27/2009 (4:28 am)
haha,i know the reason ,it is really a bug of Torque 3D 2009 SDK 1.0,
now let's look the c++ code
d:\Torque\Engine\source\T3D\debris.cpp

bool Debris::prepRenderImage(SceneState *state, const U32 stateKey,
const U32 /*startZone*/, const bool /*modifyBaseState*/)
{
if (isLastState(state, stateKey))
return false;
setLastState(state, stateKey);

// This should be sufficient for most objects that don't manage zones, and
// don't need to return a specialized RenderImage...
if( state->isObjectRendered(this) && (mPart || mShape) )
{
Point3F cameraOffset;
mObjToWorld.getColumn(3,&cameraOffset);
cameraOffset -= state->getDiffuseCameraPosition();
F32 dist = cameraOffset.len();
F32 invScale = (1.0f/getMax(getMax(mObjScale.x,mObjScale.y),mObjScale.z));

if( mShape )
{
mShape->setDetailFromDistance( state, dist * invScale );
if( mShape->getCurrentDetail() < 0 )
return false;
}

if( mPart )
mShape->setDetailFromDistance( state, dist * invScale );

prepBatchRender( state );
}

return false;
}


look this "mPart || mShape",but then it call
if( mPart )
mShape->setDetailFromDistance( state, dist * invScale );

if mShape is null ,it will crash ,so you must change this.
#2
02/26/2010 (12:26 pm)
actually the problem lies deeper in the source

in debris.cpp

change
if( mPart )
mShape->setDetailFromDistance( state, dist * invScale );
to
// > pg debris
      // this failed when mShape is null...
      if( mPart && mShape)
         mShape->setDetailFromDistance( state, dist * invScale );
      // > pg debris

and in
tsPartInstance.cpp
in
TSPartInstance::breakShape

change the content of this loop
for (S32 i=0; i<partList.size(); i++)
to
// > pg debris
      int size = partList[i]->mMeshObjects.size();
      bool hasMesh = false;
      for (S32 j=0; j<size; j++)
      {
         if (partList[i]->mMeshObjects[j]->getMesh(0))
         {
            hasMesh = true;
            break;
         }
      }
      if (hasMesh)
         partList[i]->updateBounds();
      else
      {
         partList.erase(i);
         i--;
      }
      // > pg debris

Big thanks to the Code Guru Paul Dana for the Fix!
#3
02/26/2010 (1:22 pm)
@Zhangruquan
Please check your email inbox, I just sent you a message.

Thread hidden until the issue of licensing is sorted out.
#4
02/28/2010 (5:59 pm)
i change the code like this:

bool Debris::prepRenderImage(SceneState *state, const U32 stateKey,
const U32 /*startZone*/, const bool /*modifyBaseState*/)
{
if (isLastState(state, stateKey))
return false;
setLastState(state, stateKey);

// This should be sufficient for most objects that don't manage zones, and
// don't need to return a specialized RenderImage...
if( state->isObjectRendered(this) && (mPart || mShape) )
{
Point3F cameraOffset;
mObjToWorld.getColumn(3,&cameraOffset);
cameraOffset -= state->getDiffuseCameraPosition();
F32 dist = cameraOffset.len();
F32 invScale = (1.0f/getMax(getMax(mObjScale.x,mObjScale.y),mObjScale.z));

if( mShape )
{
mShape->setDetailFromDistance( state, dist * invScale );
if( mShape->getCurrentDetail() < 0 )
return false;
}
//[code changed by zrq
if( mPart )
mPart->getSourceShapeInstance()->setDetailFromDistance( state, dist * invScale );
//]
prepBatchRender( state );

prepBatchRender( state );
}

return false;
}

#5
02/28/2010 (6:05 pm)
@Scott Burns ,my email inbox is :zhang_ru_quan@yahoo.cn,welcome your message,thanks
#6
03/02/2010 (10:08 am)
As this thread contains a fix that others may find useful or need in the future I'm moving it here to the Private forums.
#7
03/02/2010 (1:24 pm)
thx scott, any chance this will be flagged to go in the trunk ?
#8
03/02/2010 (1:54 pm)
I'll be letting the team know about it, but beyond that I have no control over what goes into the trunk.