Explosion::Explosion(const core::vector3df& position) : Effect(EXPLOSIONLENGTH), fireParticles(0), shockwave(0) { //intialize particle system sound->play3D("res/sounds/reactor_explo.wav", position); fireParticles = scenemngr->addParticleSystemSceneNode(false, 0, -1, position); IParticleEmitter *emitter = fireParticles->createSphereEmitter(vector3df(0,0,0), 20, vector3df(0,0,0), 100, 200, video::SColor(0,255,255,255), video::SColor(0,255,255,255), 2000, 4000, 0, dimension2df(75,75), dimension2df(150,150)); fireParticles->setEmitter(emitter); fireParticles->setMaterialTexture(0, vdriver->getTexture("res/textures/engine_trails.pcx")); fireParticles->setMaterialFlag(video::EMF_LIGHTING, false); fireParticles->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); IParticleAffector *af = fireParticles->createAttractionAffector(position, -100.f); fireParticles->addAffector(af); emitter->drop(); af->drop(); shockwave = scenemngr->addCubeSceneNode(5); shockwave->setScale(core::vector3df(5,0,5)); shockwave->setMaterialTexture(0,vdriver->getTexture("res/textures/fx/shockwave.png")); shockwave->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL); shockwave->setPosition(position); shockwave->setMaterialFlag(video::EMF_LIGHTING, false); }
/****************************************************************************** * Sets the rain source to the current emitter, and automatically adds fade-out * affector. * TODO: fix this to pass in values instead of an emitter pointer *****************************************************************************/ void GameInstance::setRainEmitter(IParticleEmitter *rainEmitter){ this->rainParticleSystem->setEmitter(rainEmitter); // add fade-out affector to the fire particle system IParticleAffector* rainFadeOutAffector = this->rainParticleSystem->createFadeOutParticleAffector(); this->rainParticleSystem->addAffector(rainFadeOutAffector); rainFadeOutAffector->drop(); }
// Causes this object to explode, making it vanish, and return a particle // effect node animating the explosion effect in its current position. void Soldier::createExplosionEffect(){ // add a new explosion particle systems (for the two intermixed explosions) this->explosionParticleSystem = this->smgr->addParticleSystemSceneNode(false); this->explosionParticleSystemLarge = this->smgr->addParticleSystemSceneNode(false); // add an emitter for BLOODSPLOSION!!!!!!!!!!!!!!! IParticleEmitter *explosionEmitter = this->explosionParticleSystem->createBoxEmitter( aabbox3d<f32>(-5, 0, -5, 5, 1, 5), // emitter size vector3df(0.0f,0.0f,0.1f), // direction + speed 2000, 5000, // min,max particles per second SColor(0,255,255,255), // darkest color SColor(0,255,255,255), // brightest color 200, 800, // min, max particle lifetime 360, // max angle degrees dimension2df(40.0f, 40.0f), // min start size dimension2df(200.0f, 200.0f)); // max start size this->explosionParticleSystem->setEmitter(explosionEmitter); explosionEmitter->drop(); // drop (re-created later) //add gravity affector to BLOODSPLOSION!!!!!!!!!!!! IParticleGravityAffector* pgaf = explosionParticleSystem->createGravityAffector (vector3df(0.F,-0.2F,0.0F), 200U); explosionParticleSystem->addAffector(pgaf); pgaf->drop(); // add fade-out affector to the BLOODSPLOSION!!!!!!!!!!!! IParticleAffector* explosionFadeOutAffector = explosionParticleSystem->createFadeOutParticleAffector(); this->explosionParticleSystem->addAffector(explosionFadeOutAffector); explosionFadeOutAffector->drop(); // customize the particle system positioning, etc. vector3df explosionPos = this->sceneNode->getPosition(); if(explosionPos.Y < 0) // adjust position: no explosions underground! explosionPos.Y = 0; // adjust the blood this->explosionParticleSystem->setPosition(explosionPos); this->explosionParticleSystem->setScale(vector3df(45, 45, 45)); this->explosionParticleSystem->setMaterialFlag(EMF_LIGHTING, false); this->explosionParticleSystem->setMaterialFlag(EMF_ZWRITE_ENABLE, false); this->explosionParticleSystem->setMaterialTexture(0, this->driver->getTexture("assets/textures/blood.bmp")); this->explosionParticleSystem->setMaterialType(EMT_TRANSPARENT_ADD_COLOR); }
IParticleSystemSceneNode* IrrFactory::addParticleSystemNode( const std::string& particleSystemFile ) { PropertyMap propMap; if( propMap.constructPropertyMap( SimFactory::TransformPath(particleSystemFile) ) ) { // default values const vector3df pos( 0, 0, 0 ); const vector3df rot( 0, 0, 0 ); const vector3df scale( 1, 1, 1 ); // create the particle system node IParticleSystemSceneNode* pSystem = mIrr.getSceneManager()->addParticleSystemSceneNode( false, 0, -1, pos, rot, scale ); Assert( pSystem ); // read some custom properties bool globalMovement = true; dimension2df particleSize( 5.0f, 5.0f ); propMap.getValue( globalMovement, "ParticleSystem.System.GlobalMovement" ); propMap.getValue( particleSize, "ParticleSystem.System.ParticleSize" ); pSystem->setParticlesAreGlobal(globalMovement); pSystem->setParticleSize(particleSize); /// ---- load the effectors ---- // get the gravity properties if( propMap.hasSection( "ParticleSystem.Gravity" ) ) { vector3df gravDir( 0, -1, 0 ); uint32_t affectorTimeMS(1000); // try to read params propMap.getValue( gravDir, "ParticleSystem.Gravity.Direction" ); propMap.getValue( affectorTimeMS, "ParticleSystem.Gravity.AffectorTimeMS" ); gravDir = ConvertNeroToIrrlichtPosition(gravDir); IParticleAffector* pGravity = pSystem->createGravityAffector( gravDir, affectorTimeMS ); Assert( pGravity ); pSystem->addAffector( pGravity ); pGravity->drop(); } // get the fade properties if( propMap.hasSection( "ParticleSystem.Fade" ) ) { SColor targetColor(0,0,0,0); uint32_t affectorTimeMS(1000); // try to read params propMap.getValue( targetColor, "ParticleSystem.Fade.TargetColor" ); propMap.getValue( affectorTimeMS, "ParticleSystem.Fade.AffectorTimeMS" ); IParticleAffector* pFade = pSystem->createFadeOutParticleAffector( targetColor, affectorTimeMS ); Assert( pFade ); pSystem->addAffector( pFade ); pFade->drop(); } // ---- load the emitters ---- // --- NOTE: WE ONLY DO BOX EMITTERS --- if( propMap.hasSection( "ParticleSystem.Emitter" ) ) { // default params aabbox3df box(-10, 28,-10, 10, 30, 10); vector3df dir( 0, .03f, 0 ); uint32_t minParticlesPerSecond = 5; uint32_t maxParticlesPerSecond = 10; SColor minStartColor( 255, 0, 0, 0 ); SColor maxStartColor( 255, 255, 255, 255 ); uint32_t lifeTimeMin = 2000; uint32_t lifeTimeMax = 4000; int32_t maxAngleDegrees = 0; // try to read custom params propMap.getValue( box, "ParticleSystem.Emitter.Box" ); propMap.getValue( dir, "ParticleSystem.Emitter.Direction" ); propMap.getValue( minParticlesPerSecond, "ParticleSystem.Emitter.MinParticlesPerSecond" ); propMap.getValue( maxParticlesPerSecond, "ParticleSystem.Emitter.MaxParticlesPerSecond" ); propMap.getValue( minStartColor, "ParticleSystem.Emitter.MinStartColor" ); propMap.getValue( maxStartColor, "ParticleSystem.Emitter.MaxStartColor" ); propMap.getValue( lifeTimeMin, "ParticleSystem.Emitter.LifetimeMin" ); propMap.getValue( lifeTimeMax, "ParticleSystem.Emitter.LifetimeMax" ); propMap.getValue( maxAngleDegrees, "ParticleSystem.Emitter.MaxAngleDegrees" ); // do coordinate system transformations dir = ConvertNeroToIrrlichtPosition(dir); // create the emitter IParticleEmitter* emit = pSystem->createBoxEmitter ( box, dir, minParticlesPerSecond, maxParticlesPerSecond, minStartColor, maxStartColor, lifeTimeMin, lifeTimeMax, maxAngleDegrees ); Assert( emit ); pSystem->setEmitter( emit ); emit->drop(); } else { LOG_F_WARNING( "render", "No emitter in particle system file - " << particleSystemFile ); } return pSystem; } return NULL; }
//! Reads attributes of the scene node. void CParticleSystemSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) { IParticleSystemSceneNode::deserializeAttributes(in, options); ParticlesAreGlobal = in->getAttributeAsBool("GlobalParticles"); ParticleSize.Width = in->getAttributeAsFloat("ParticleWidth"); ParticleSize.Height = in->getAttributeAsFloat("ParticleHeight"); // read emitter int emitterIdx = in->findAttribute("Emitter"); if (emitterIdx == -1) return; if (Emitter) Emitter->drop(); Emitter = 0; E_PARTICLE_EMITTER_TYPE type = (E_PARTICLE_EMITTER_TYPE) in->getAttributeAsEnumeration("Emitter", ParticleEmitterTypeNames); switch(type) { case EPET_POINT: Emitter = createPointEmitter(); break; case EPET_ANIMATED_MESH: Emitter = createAnimatedMeshSceneNodeEmitter(NULL); // we can't set the node - the user will have to do this break; case EPET_BOX: Emitter = createBoxEmitter(); break; case EPET_CYLINDER: Emitter = createCylinderEmitter(core::vector3df(0,0,0), 10.f, core::vector3df(0,1,0), 10.f); // (values here don't matter) break; case EPET_MESH: Emitter = createMeshEmitter(NULL); // we can't set the mesh - the user will have to do this break; case EPET_RING: Emitter = createRingEmitter(core::vector3df(0,0,0), 10.f, 10.f); // (values here don't matter) break; case EPET_SPHERE: Emitter = createSphereEmitter(core::vector3df(0,0,0), 10.f); // (values here don't matter) break; default: break; } u32 idx = 0; #if 0 if (Emitter) idx = Emitter->deserializeAttributes(idx, in); ++idx; #else if (Emitter) Emitter->deserializeAttributes(in); #endif // read affectors removeAllAffectors(); u32 cnt = in->getAttributeCount(); while(idx < cnt) { const char* name = in->getAttributeName(idx); if (!name || strcmp("Affector", name)) return; E_PARTICLE_AFFECTOR_TYPE atype = (E_PARTICLE_AFFECTOR_TYPE)in->getAttributeAsEnumeration(idx, ParticleAffectorTypeNames); IParticleAffector* aff = 0; switch(atype) { case EPAT_ATTRACT: aff = createAttractionAffector(core::vector3df(0,0,0)); break; case EPAT_FADE_OUT: aff = createFadeOutParticleAffector(); break; case EPAT_GRAVITY: aff = createGravityAffector(); break; case EPAT_ROTATE: aff = createRotationAffector(); break; case EPAT_SCALE: aff = createScaleParticleAffector(); break; case EPAT_NONE: default: break; } ++idx; if (aff) { #if 0 idx = aff->deserializeAttributes(idx, in, options); ++idx; #else aff->deserializeAttributes(in, options); #endif addAffector(aff); aff->drop(); } } }
//! Reads attributes of the scene node. void CParticleSystemSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) { IParticleSystemSceneNode::deserializeAttributes(in, options); ParticlesAreGlobal = in->getAttributeAsBool("GlobalParticles"); ParticleSize.Width = in->getAttributeAsFloat("ParticleWidth"); ParticleSize.Height = in->getAttributeAsFloat("ParticleHeight"); // read emitter int emitterIdx = in->findAttribute("Emitter"); if (emitterIdx == -1) return; if (Emitter) Emitter->drop(); Emitter = 0; E_PARTICLE_EMITTER_TYPE type = (E_PARTICLE_EMITTER_TYPE) in->getAttributeAsEnumeration("Emitter", ParticleEmitterTypeNames); switch(type) { case EPET_POINT: Emitter = createPointEmitter(); break; case EPET_BOX: Emitter = createBoxEmitter(); break; } s32 idx = 0; if (Emitter) idx = Emitter->deserializeAttributes(idx, in); ++idx; // read affectors removeAllAffectors(); s32 cnt = in->getAttributeCount(); while(idx < cnt) { const char* name = in->getAttributeName(idx); if (!name || strcmp("Affector", name)) return; E_PARTICLE_AFFECTOR_TYPE atype = (E_PARTICLE_AFFECTOR_TYPE)in->getAttributeAsEnumeration(idx, ParticleAffectorTypeNames); IParticleAffector* aff = 0; switch(atype) { case EPAT_FADE_OUT: aff = createFadeOutParticleAffector(); break; case EPAT_GRAVITY: aff = createGravityAffector(); break; } ++idx; if (aff) { idx = aff->deserializeAttributes(idx, in, options); ++idx; addAffector(aff); aff->drop(); } } }