Steve_Yorkshire Posted January 18, 2017 Share Posted January 18, 2017 filename ExplosionData::explosionShape Optional DTS or DAE shape to place at the center of the explosion. The ambient animation of this model will be played automatically at the start of the explosion. bool ExplosionData::faceViewer Controls whether the visual effects of the explosion always face the camera. I've been using explosionShape for a while and have come up with an improvement. :idea: In stock T3D the model for an explosionShape spawns in game with the rotation of it's impact. This is fine for vertical collision but means that striking a horizontal contact flips the model 90 degrees. If you wanted to spawn an explosion by script - without an impact vector/rotation you would have to export the animated model facing the Y-axis for it's "up" - but then it would be bent 90 degrees if it was used for a standard collision impact.But wait! There's more!Using faceViewer=bool; was also funky as it would billboard it's rotation towards the camera, half the model would end up buried beneath the terrain and faceViewer had a random Y rotation in it's code.Non of this is helpful if you want your animated mesh explosion to align upwards (Z axis) - for instance a nuclear mushroom cloud or a shockwave along the ground.What would be useful is a faceZ(bool) variable which works like particleEmitter's alignDirection = "0 0 1"; and make the model always stand up along the z-axis. And here it is! :Psource/T3D/fx/explosion.h class ExplosionData : public GameBaseData { //... public: StringTableEntry dtsFileName; bool faceViewer; bool faceZ;//yorks in ~line 62 S32 particleDensity; //... source/T3D/fx/explosion.cppExplosionData::ExplosionData() { //... faceViewer = false; faceZ = false;//yorks in ~line 226 soundProfile = NULL; //... void ExplosionData::initPersistFields() { //... "Non-looping sound effect that will be played at the start of the explosion." ); addField( "faceViewer", TypeBool, Offset(faceViewer, ExplosionData), "Controls whether the visual effects of the explosion always face the camera." ); //yorks in ~line 300 addField("faceZ", TypeBool, Offset(faceZ, ExplosionData), "Controls whether the visual effects of the explosion always face Z axis/up axis.\n\n" "Does not work with faceViewer as faceViewer takes precedent."); //yorks in end ~line 304 addField( "particleEmitter", TYPEID< ParticleEmitterData >(), Offset(particleEmitter, ExplosionData), //... void ExplosionData::packData(BitStream* stream) { //... stream->write(particleRadius); stream->writeFlag(faceViewer); stream->writeFlag(faceZ);//yorks in ~line 559 if(stream->writeFlag(explosionScale.x != 1 || explosionScale.y != 1 || explosionScale.z != 1)) //... void ExplosionData::unpackData(BitStream* stream) { //... particleDensity = stream->readInt(14); stream->read(&particleRadius); faceViewer = stream->readFlag(); faceZ = stream->readFlag();//yorks in ~line 666 MAIDEN MAIDEN :P if(stream->readFlag()) //... //-------------------------------------------------------------------------- // Make the explosion face the viewer (if desired) //-------------------------------------------------------------------------- void Explosion::prepModelView(SceneRenderState* state) { MatrixF rotMatrix( true ); Point3F targetVector; if( mDataBlock->faceViewer ) { targetVector = getPosition() - state->getCameraPosition(); targetVector.normalize(); // rotate explosion each time so it's a little different rotMatrix.set( EulerF( 0.0f, mRandAngle, 0.0f ) ); } /* //yorks out ~line 1039 else { targetVector = mInitialNormal;//yorks out end } */ //yorks out end else if (mDataBlock->faceZ)//yorks new in ~line 1045 { targetVector = state->getCameraPosition() - getPosition(); targetVector.z = 0.0f; targetVector.normalize(); } else targetVector = mInitialNormal;//yorks new end ~line 1052 MatrixF explOrient = MathUtils::createOrientFromDir( targetVector ); explOrient.mul( rotMatrix ); explOrient.setPosition( getPosition() ); setCurrentScale(); explOrient.scale( mObjScale ); GFX->setWorldMatrix( explOrient ); } Note: In the above code faceZ is overriden if faceViewer is set to true.And in your explosion datablock add faceZ = true; to enable it. datablock ExplosionData(smallExplosion) { explosionShape = "art/shapes/yorks/mesh_explosions/distort_explo500.dts";//your animated mesh with z-axis for up faceZ = true;//no tilting! lifeTimeMS = 500; // Remember explosionShape Ambient animation length overrides this!!! lifetimeVariance = 0; // Point emission emitter[0] = smallDarkExpEmitter; emitter[1] = smallExpSparksEmitter; emitter[2] = smallExpDustEmitter; }; Now if you want animated explosions to always face upright regardless of impact vector rotation - they will! :mrgreen: Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.