Steve_Yorkshire Posted May 22, 2017 Share Posted May 22, 2017 I've got a little confused with particleEmitters - especially the usefulness of phiVariance and phiReferenceVel.What I want is to create a ring on the vertical, but only seem to be able to do this on the horizontal.Here is what I've got. A ring on the horizontal when creating an emitter with ThetaMin/Max set to 90. When spawning it via an explosion it aligns to the impact vector (as expected).http://i.imgur.com/bLrQcq7.jpgWhat I want is the opposite, so that the emitter particle is a vertical ring (and thus a horizontal ring when it hits a vertical surface in an 90 degree angled explosion).Setting thetaMin/Max to 0-180 gives a full sphere, and there seems no way to "flatten" it or limit vertical angle of discharge.I did some playing around with phiVariance (aka DEPTH in the particle Editor) and phiReferenceVel (which is not in the particle Editor but is an emitter value but god knows what it does) but that just cuts off some of the particle spawning. So setting depth/phiVariance to 180 gives half a circle on one side.http://i.imgur.com/GSXgOG5.jpgPhi not terribly helpful here ...So, any thoughts, insights or ideas would be appreciated. I'm thinking I might have to add a new value in particleEmitter.cpp/h to limit the thetaMin/Max over X (Y? Z?) ejection.Here's my particle data if anyone is interested. datablock ParticleData(aTestBits) { textureName = "art/particles/firefly.png"; inheritedVelFactor = "0"; constantAcceleration = "0"; lifetimeMS = "2000"; lifetimeVarianceMS = "0"; useInvAlpha = true; spinSpeed = "0"; spinRandomMin = "0"; spinRandomMax = "1"; colors[0] = "1 0 1 1"; colors[1] = "1 0 1 0.5"; colors[2] = "1 0 1 0"; sizes[0] = "1"; sizes[1] = "1"; sizes[2] = "1"; times[0] = 0; times[1] = "0.5"; times[2] = 1; animTexName = "art/particles/firefly.png"; dragCoefficient = "2"; }; datablock ParticleEmitterData(aTestBitsEmitter) { ejectionPeriodMS = "1"; periodVarianceMS = "0"; ejectionVelocity = "5"; velocityVariance = "0"; ejectionOffset = "1"; thetaMin = "90"; thetaMax = "90"; phiReferenceVel = 0; phiVariance = "360"; overrideAdvances = 0; orientParticles = "0"; lifetimeMS = "200"; particles = "aTestBits"; blendStyle = "ADDITIVE"; glow = "0"; lifetimeVarianceMS = "0"; ejectionOffsetVariance = "0"; alignDirection = "0 0 1"; }; Quote Link to comment Share on other sites More sharing options...
Duion Posted May 22, 2017 Share Posted May 22, 2017 Rotate the particle effect, for example the default grenade explosion does a ring and when it explodes on a wall the ring is vertical, but may be just a stupid workaround. Quote Link to comment Share on other sites More sharing options...
Steve_Yorkshire Posted May 22, 2017 Author Share Posted May 22, 2017 So I added a flag in ParticleEmitterData to check for rotation around the Y(?) axis and then use that for aligning the normal at (0, 1, 0) on the ParticleEmitterNodeData.Fine for particleEmitters ... except it turns out explosionData particles don't use the ParticleEmitterNodeData object ... (fuuuu-). Quote Link to comment Share on other sites More sharing options...
Steve_Yorkshire Posted May 22, 2017 Author Share Posted May 22, 2017 @Duion Exact same problem. Stock grenade explodes when it stops and is thus pointing upwards, so the smoke ring is ALWAYS horizontal to Z. So using it as a normal impact projectile gives the vertical orientated explosion against a vertical surface. Quote Link to comment Share on other sites More sharing options...
Steve_Yorkshire Posted May 22, 2017 Author Share Posted May 22, 2017 Okay, after much sniffing up the wrong tree I eventually got what I wanted.Initially I managed to make particleEmitterNode rotate on the Z axis.So then it turns out explosionData particles do not use particleEmitterNodes --- and I didn't have much success rotating the axis of the emitter for ejecting particles in ParticleEmitter.cpp.So I had to make my changes inside explosion.cpp itself, with a reference to particleEmitterData to check whether the spawned particle should be flat (eg: face upwards).First up, the flag to check for flat particles the emitter.In particleEmitter.h//***************************************************************************** // Particle Emitter Data //***************************************************************************** class ParticleEmitterData : public GameBaseData { typedef GameBaseData Parent; //... bool glow; ///< Renders this emitter into the glow buffer. bool reload(); F32 RotateY;//yorks in new! }; In particleEmitter.cpp//----------------------------------------------------------------------------- // ParticleEmitterData //----------------------------------------------------------------------------- ParticleEmitterData::ParticleEmitterData() { VECTOR_SET_ASSOCIATION(particleDataBlocks); VECTOR_SET_ASSOCIATION(dataBlockIds); //... alignParticles = false; alignDirection = Point3F(0.0f, 1.0f, 0.0f); RotateY = 0.0f;//yorks in new! } //... //----------------------------------------------------------------------------- // initPersistFields //----------------------------------------------------------------------------- void ParticleEmitterData::initPersistFields() { addGroup( "ParticleEmitterData" ); addFieldV("ejectionPeriodMS", TYPEID< S32 >(), Offset(ejectionPeriodMS, ParticleEmitterData), &ejectPeriodIValidator, "Time (in milliseconds) between each particle ejection." ); //... addField("glow", TYPEID< bool >(), Offset(glow, ParticleEmitterData), "If true, the particles are rendered to the glow buffer as well."); //yorks addField("RotateY", TYPEID< F32 >(), Offset(RotateY, ParticleEmitterData), "If >0.0f, the first particle spawns on Y axis not Z."); //@} endGroup( "ParticleEmitterData" ); Parent::initPersistFields(); } And the particleEmitter datablock in Torquescript:datablock ParticleEmitterData(aTestBitsEmitter) { ejectionPeriodMS = "1"; periodVarianceMS = "0"; ejectionVelocity = "5"; velocityVariance = "0"; ejectionOffset = "1"; thetaMin = "90"; thetaMax = "90"; phiReferenceVel = 0; phiVariance = "360"; overrideAdvances = 0; orientParticles = "0"; lifetimeMS = "200"; particles = "aTestBits"; blendStyle = "ADDITIVE"; glow = "0"; lifetimeVarianceMS = "0"; ejectionOffsetVariance = "0"; alignDirection = "0 0 1"; RotateY = "1"; }; And finally in explosion.cpp://---------------------------------------------------------------------------- // Update emitters //---------------------------------------------------------------------------- void Explosion::updateEmitters( F32 dt ) { Point3F pos = getPosition(); for( S32 i=0; i { if( mEmitterList ) { //yorks start F32 mRotate = mEmitterList->getDataBlock()->RotateY; //Con::printf("mRotate = %g", mRotate); if (mRotate > 0.0f) { //Con::printf("YES = %g", mRotate); mInitialNormal = Point3F(0, 0, 1); }//yorks end mEmitterList->emitParticles( pos, pos, mInitialNormal, Point3F( 0.0f, 0.0f, 0.0f ), (U32)(dt * 1000)); } } }And hey-presto it works. Currently the F32 RotateY is only acting as a bool, and this could be expanded to merge the math of the original mInitialNormal to give a true relative position, or a cut-off angle could be used: eg; if mInitialNormal.z < RotateY (say 0.8) use RotateY instead, etc, etc.http://i.imgur.com/1Z6PPJA.jpg Quote Link to comment Share on other sites More sharing options...
Steve_Yorkshire Posted May 22, 2017 Author Share Posted May 22, 2017 Okay, found a problem.All the particles in the explosion get the modification passed to them because mInitiialNormal gets reset. So here's the fix. Leave Britney/mInitialNormal Alone!!!! ;) explosion.cpp//---------------------------------------------------------------------------- // Update emitters //---------------------------------------------------------------------------- void Explosion::updateEmitters( F32 dt ) { Point3F pos = getPosition(); for( S32 i=0; i { if( mEmitterList ) { F32 mRotate = mEmitterList->getDataBlock()->RotateY; //Con::printf("mRotate = %g", mRotate); if (mRotate > 0.0f) { //mInitialNormal = Point3F(0.0f, 0.0f, 1.0f);//yorks no no no! mEmitterList->emitParticles(pos, pos, Point3F(0.0f, 0.0f, 1.0f), Point3F(0.0f, 0.0f, 0.0f), (U32)(dt * 1000)); } else mEmitterList->emitParticles( pos, pos, mInitialNormal, Point3F( 0.0f, 0.0f, 0.0f ), (U32)(dt * 1000)); } } }Behold 2 emitters, 1 using RotateY and the other without!http://i.imgur.com/sLKrmPQ.jpg :mrgreen: Quote Link to comment Share on other sites More sharing options...
JeffR Posted May 23, 2017 Share Posted May 23, 2017 Very slick :D 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.