int main(int argc, char **argv) { preloadSharedObject("OSGImageFileIO"); // OSG init osgInit(argc,argv); { // Set up Window WindowEventProducerRecPtr TutorialWindow = createNativeWindow(); TutorialWindow->initWindow(); // Create the SimpleSceneManager helper SimpleSceneManager sceneManager; TutorialWindow->setDisplayCallback(boost::bind(display, &sceneManager)); TutorialWindow->setReshapeCallback(boost::bind(reshape, _1, &sceneManager)); // Tell the Manager what to manage sceneManager.setWindow(TutorialWindow); //Attach to events TutorialWindow->connectMousePressed(boost::bind(mousePressed, _1, &sceneManager)); TutorialWindow->connectMouseReleased(boost::bind(mouseReleased, _1, &sceneManager)); TutorialWindow->connectMouseMoved(boost::bind(mouseMoved, _1, &sceneManager)); TutorialWindow->connectMouseDragged(boost::bind(mouseDragged, _1, &sceneManager)); TutorialWindow->connectMouseWheelMoved(boost::bind(mouseWheelMoved, _1, &sceneManager)); // Creating the Particle System Material // Here, the image is loaded. The entire image sequence is conatined in one image, // which reduces texture memory overhead and runs faster. TextureObjChunkRefPtr QuadTextureChunk = TextureObjChunk::create(); ImageRefPtr LoadedImage = ImageFileHandler::the()->read("Data/Explosion.png"); QuadTextureChunk->setImage(LoadedImage); TextureEnvChunkRefPtr QuadTextureEnvChunk = TextureEnvChunk::create(); QuadTextureEnvChunk->setEnvMode(GL_MODULATE); BlendChunkRefPtr PSBlendChunk = BlendChunk::create(); PSBlendChunk->setSrcFactor(GL_SRC_ALPHA); PSBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA); MaterialChunkRefPtr PSMaterialChunk = MaterialChunk::create(); PSMaterialChunk->setLit(false); ChunkMaterialRefPtr PSMaterial = ChunkMaterial::create(); PSMaterial->addChunk(QuadTextureChunk); PSMaterial->addChunk(QuadTextureEnvChunk); PSMaterial->addChunk(PSMaterialChunk); PSMaterial->addChunk(PSBlendChunk); //Particle System ParticleSystemRecPtr ExplosionParticleSystem = ParticleSystem::create(); ExplosionParticleSystem->attachUpdateProducer(TutorialWindow); //Age Particle Function. Controls which image is shown when, based on the age of a particle. AgeParticleFunctionRecPtr AgeFunc = AgeParticleFunction::create(); AgeFunc->setSequenceTime(0.07f); // image changes every 0.1 seconds. AgeFunc->setSequenceOrder(AgeParticleFunction::CUSTOM); // using the custom sequence below. /* Here, a custom sequence for the image ordering is assembled. The image sequence will be shown in the order specified here. Once the end of the sequence is reached, the sequence repeats. */ UInt32 NumImages(25); for(UInt32 i(0) ; i<NumImages ; ++i) { AgeFunc->editMFCustomSequence()->push_back(i); } //Particle System Drawer - QuadSequenceParticleSystemDrawerRecPtr ExplosionParticleSystemDrawer = QuadSequenceParticleSystemDrawer::create(); // image dimensions (in pixels) are required if there is a border on the images. ExplosionParticleSystemDrawer->setImageDimensions(Vec2us(320,320)); // The "dimensions" of the sequence contained in the image. For this image, // there are 3 images in the "x" direction, and two in the "y" direction, for a // total of 6. ExplosionParticleSystemDrawer->setSequenceDimensions(Vec2b(5,5)); // width of the border on each side of the image, in pixels. ExplosionParticleSystemDrawer->setBorderOffsets(Vec2b(0,0)); // this is the age function we just created above. ExplosionParticleSystemDrawer->setSequenceFunction(AgeFunc); RateParticleGeneratorRecPtr ExplosionParticleGenerator = RateParticleGenerator::create(); //Attach the function objects to the Generator ExplosionParticleGenerator->setPositionDistribution(createPositionDistribution()); ExplosionParticleGenerator->setLifespanDistribution(createLifespanDistribution()); ExplosionParticleGenerator->setVelocityDistribution(createVelocityDistribution()); ExplosionParticleGenerator->setAccelerationDistribution(createAccelerationDistribution()); ExplosionParticleGenerator->setSizeDistribution(createSizeDistribution()); ExplosionParticleGenerator->setGenerationRate(100.0f); //Particle System Node ParticleSystemCoreRefPtr ExplosionParticleCore = ParticleSystemCore::create(); ExplosionParticleCore->setSystem(ExplosionParticleSystem); ExplosionParticleCore->setDrawer(ExplosionParticleSystemDrawer); ExplosionParticleCore->setMaterial(PSMaterial); ExplosionParticleCore->setSortingMode(ParticleSystemCore::BACK_TO_FRONT); NodeRefPtr ExplosionParticleNode = Node::create(); ExplosionParticleNode->setCore(ExplosionParticleCore); ExplosionParticleSystem->addParticle(Pnt3f(10.0,0.0,0.0), Vec3f(0.0,1.0,0.0), Color4f(1.0,1.0,1.0,1.0), Vec3f(1.0,1.0,1.0), 0.01, Vec3f(0.0,0.0,0.0), Vec3f(0.0,0.0,0.0)); ExplosionParticleSystem->addParticle(Pnt3f(-10.0,0.0,0.0), Vec3f(0.0,1.0,0.0), Color4f(1.0,1.0,1.0,1.0), Vec3f(1.0,1.0,1.0), 0.01, Vec3f(0.0,0.0,0.0), Vec3f(0.0,0.0,0.0)); ExplosionParticleSystem->pushToGenerators(ExplosionParticleGenerator); AgeSizeParticleAffectorRecPtr ExampleAgeSizeParticleAffector = AgeSizeParticleAffector::create(); //Age and size ExampleAgeSizeParticleAffector->editMFAges()->push_back(0.0); ExampleAgeSizeParticleAffector->editMFSizes()->push_back(Vec3f(0.2,0.2,0.2)); ExampleAgeSizeParticleAffector->editMFAges()->push_back(1.0); ExampleAgeSizeParticleAffector->editMFSizes()->push_back(Vec3f(4.0,4.0,4.0)); ExampleAgeSizeParticleAffector->editMFAges()->push_back(1.8); ExampleAgeSizeParticleAffector->editMFSizes()->push_back(Vec3f(2.2,2.2,0.1)); //Age Fade Affector AgeFadeParticleAffectorRecPtr ExampleAgeFadeParticleAffector = AgeFadeParticleAffector::create(); //Age and size ExampleAgeFadeParticleAffector->setStartAlpha(0.0f); ExampleAgeFadeParticleAffector->setFadeInTime(0.5f); ExampleAgeFadeParticleAffector->setFadeToAlpha(1.0f); ExampleAgeFadeParticleAffector->setFadeOutTime(0.5f); ExampleAgeFadeParticleAffector->setEndAlpha(0.0f); ExplosionParticleSystem->pushToAffectors(ExampleAgeFadeParticleAffector); //Smoke Particle System VortexParticleAffectorRecPtr SmokeVortexAffector = VortexParticleAffector::create(); SmokeVortexAffector->setMagnitude(0.2); SmokeVortexAffector->setVortexAxis(Vec3f(0.0,1.0,0.0)); // field rotates around y axis NodeRefPtr VortexBeacon = makeCoredNode<Group>(); SmokeVortexAffector->setBeacon(VortexBeacon); // set to 'emulate' from (0,0,0) SmokeVortexAffector->setMaxDistance(-1.0); // particles affected regardless of distance SmokeVortexAffector->setAttenuation(0.25); // strength of uniform field dimishes by dist^attenuation AgeFadeParticleAffectorRecPtr SmokeAgeFadeParticleAffector = AgeFadeParticleAffector::create(); //Age and size SmokeAgeFadeParticleAffector->setStartAlpha(0.0f); SmokeAgeFadeParticleAffector->setFadeInTime(0.2f); SmokeAgeFadeParticleAffector->setFadeToAlpha(1.0f); SmokeAgeFadeParticleAffector->setFadeOutTime(3.5f); SmokeAgeFadeParticleAffector->setEndAlpha(0.0f); RateParticleGeneratorRecPtr SmokeParticleGenerator = RateParticleGenerator::create(); SmokeParticleGenerator->setSizeDistribution(createSmokeSizeDistribution()); SmokeParticleGenerator->setPositionDistribution(createSmokePositionDistribution()); SmokeParticleGenerator->setLifespanDistribution(createSmokeLifespanDistribution()); SmokeParticleGenerator->setVelocityDistribution(createSmokeVelocityDistribution()); SmokeParticleGenerator->setColorDistribution(createSmokeColorDistribution()); SmokeParticleGenerator->setGenerationRate(80.0f); ParticleSystemRecPtr SmokeParticleSystem = ParticleSystem::create(); SmokeParticleSystem->pushToGenerators(SmokeParticleGenerator); SmokeParticleSystem->attachUpdateProducer(TutorialWindow); SmokeParticleSystem->pushToAffectors(SmokeAgeFadeParticleAffector); SmokeParticleSystem->pushToAffectors(SmokeVortexAffector); TextureObjChunkRefPtr SmokeTextureObjChunk = TextureObjChunk::create(); ImageRefPtr SmokeImage = ImageFileHandler::the()->read("Data/Smoke.png"); SmokeTextureObjChunk->setImage(SmokeImage); ChunkMaterialRefPtr SmokeMaterial = ChunkMaterial::create(); SmokeMaterial->addChunk(SmokeTextureObjChunk); SmokeMaterial->addChunk(QuadTextureEnvChunk); SmokeMaterial->addChunk(PSMaterialChunk); SmokeMaterial->addChunk(PSBlendChunk); SmokeMaterial->setSortKey(-1.0f); QuadParticleSystemDrawerRecPtr SmokeParticleSystemDrawer = QuadParticleSystemDrawer::create(); ParticleSystemCoreRefPtr SmokeParticleCore = ParticleSystemCore::create(); SmokeParticleCore->setSystem(SmokeParticleSystem); SmokeParticleCore->setDrawer(SmokeParticleSystemDrawer); SmokeParticleCore->setMaterial(SmokeMaterial); SmokeParticleCore->setSortingMode(ParticleSystemCore::BACK_TO_FRONT); NodeRefPtr SmokeParticleNode = Node::create(); SmokeParticleNode->setCore(SmokeParticleCore); // Make Main Scene Node and add the Torus NodeRefPtr scene = makeCoredNode<Group>(); scene->addChild(ExplosionParticleNode); scene->addChild(SmokeParticleNode); scene->addChild(VortexBeacon); TutorialWindow->connectKeyTyped(boost::bind(keyTyped, _1, &sceneManager, AgeFunc.get())); sceneManager.setRoot(scene); // Show the whole Scene sceneManager.showAll(); //Open Window Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f); Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5); TutorialWindow->openWindow(WinPos, WinSize, "06Explosion"); //Enter main Loop TutorialWindow->mainLoop(); } osgExit(); return 0; }
int main(int argc, char **argv) { // OSG init osgInit(argc,argv); { // Set up Window WindowEventProducerRecPtr TutorialWindow = createNativeWindow(); TutorialWindow->initWindow(); // Create the SimpleSceneManager helper SimpleSceneManager sceneManager; TutorialWindow->setDisplayCallback(boost::bind(display, &sceneManager)); TutorialWindow->setReshapeCallback(boost::bind(reshape, _1, &sceneManager)); // Tell the Manager what to manage sceneManager.setWindow(TutorialWindow); //Attach to events TutorialWindow->connectMousePressed(boost::bind(mousePressed, _1, &sceneManager)); TutorialWindow->connectMouseReleased(boost::bind(mouseReleased, _1, &sceneManager)); TutorialWindow->connectMouseDragged(boost::bind(mouseDragged, _1, &sceneManager)); TutorialWindow->connectMouseWheelMoved(boost::bind(mouseWheelMoved, _1, &sceneManager)); //Particle System Material PointChunkRefPtr PSPointChunk = PointChunk::create(); PSPointChunk->setSize(5.0f); PSPointChunk->setSmooth(true); BlendChunkRefPtr PSBlendChunk = BlendChunk::create(); PSBlendChunk->setSrcFactor(GL_SRC_ALPHA); PSBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA); MaterialChunkRefPtr PSMaterialChunkChunk = MaterialChunk::create(); PSMaterialChunkChunk->setAmbient(Color4f(1.0f,1.0f,1.0f,1.0f)); PSMaterialChunkChunk->setDiffuse(Color4f(0.7f,0.7f,0.7f,1.0f)); PSMaterialChunkChunk->setSpecular(Color4f(0.9f,0.9f,0.9f,1.0f)); PSMaterialChunkChunk->setColorMaterial(GL_AMBIENT_AND_DIFFUSE); ChunkMaterialRefPtr PSMaterial = ChunkMaterial::create(); PSMaterial->addChunk(PSPointChunk); PSMaterial->addChunk(PSMaterialChunkChunk); PSMaterial->addChunk(PSBlendChunk); //Particle System ParticleSystemRefPtr ExampleParticleSystem = ParticleSystem::create(); ExampleParticleSystem->addParticle(Pnt3f(0,-100,0), Vec3f(0.0,0.0f,1.0f), Color4f(1.0,1.0,1.0,1.0), Vec3f(1.0,1.0,1.0), 0.1, Vec3f(0.0f,0.0f,0.0f), //Velocity Vec3f(0.0f,0.0f,0.0f) ); ExampleParticleSystem->addParticle(Pnt3f(0,100,0), Vec3f(0.0,0.0f,1.0f), Color4f(1.0,1.0,1.0,1.0), Vec3f(1.0,1.0,1.0), 0.1, Vec3f(0.0f,0.0f,0.0f), //Velocity Vec3f(0.0f,0.0f,0.0f) ); ExampleParticleSystem->attachUpdateProducer(TutorialWindow); //Particle System Drawer (Point) PointParticleSystemDrawerRecPtr ExamplePointParticleSystemDrawer = PointParticleSystemDrawer::create(); //Particle System Drawer (line) LineParticleSystemDrawerRecPtr ExampleLineParticleSystemDrawer = LineParticleSystemDrawer::create(); ExampleLineParticleSystemDrawer->setLineDirectionSource(LineParticleSystemDrawer::DIRECTION_VELOCITY); ExampleLineParticleSystemDrawer->setLineLengthSource(LineParticleSystemDrawer::LENGTH_SIZE_X); ExampleLineParticleSystemDrawer->setLineLength(2.0f); ExampleLineParticleSystemDrawer->setEndPointFading(Vec2f(0.0f,1.0f)); //Create a Rate Particle Generator RateParticleGeneratorRefPtr ExampleGenerator = RateParticleGenerator::create(); //Attach the function objects to the Generator ExampleGenerator->setPositionDistribution(createPositionDistribution()); ExampleGenerator->setLifespanDistribution(createLifespanDistribution()); ExampleGenerator->setGenerationRate(60.0); ExampleGenerator->setVelocityDistribution(createVelocityDistribution()); VortexParticleAffectorRecPtr ExampleVortexAffector = VortexParticleAffector::create(); ExampleVortexAffector->setMagnitude(20.0); ExampleVortexAffector->setVortexAxis(Vec3f(0.0,0.0,1.0)); // field rotates around z axis NodeRefPtr VortexBeacon = Node::create(); ExampleVortexAffector->setBeacon(VortexBeacon); // set to 'emulate' from (0,0,0) ExampleVortexAffector->setMaxDistance(-1.0); // particles affected regardless of distance ExampleVortexAffector->setAttenuation(0.25); // strength of uniform field dimishes by dist^attenuation //Attach the Generator and Affector to the Particle System ExampleParticleSystem->pushToGenerators(ExampleGenerator); ExampleParticleSystem->pushToAffectors(ExampleVortexAffector); ExampleParticleSystem->setMaxParticles(800); //Particle System Node ParticleSystemCoreRecPtr ParticleNodeCore = ParticleSystemCore::create(); ParticleNodeCore->setSystem(ExampleParticleSystem); ParticleNodeCore->setDrawer(ExamplePointParticleSystemDrawer); ParticleNodeCore->setMaterial(PSMaterial); NodeRefPtr ParticleNode = Node::create(); ParticleNode->setCore(ParticleNodeCore); // Make Main Scene Node and add the Torus NodeRefPtr scene = Node::create(); scene->setCore(Group::create()); scene->addChild(ParticleNode); TutorialWindow->connectKeyTyped(boost::bind(keyTyped, _1, &sceneManager, ParticleNodeCore.get(), ExamplePointParticleSystemDrawer.get(), ExampleLineParticleSystemDrawer.get(), ExampleVortexAffector.get())); sceneManager.setRoot(scene); //Create the Documentation SimpleScreenDoc TheSimpleScreenDoc(&sceneManager, TutorialWindow); // Show the whole Scene sceneManager.showAll(); sceneManager.getCamera()->setFar(1000.0); //Open Window Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f); Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5); TutorialWindow->openWindow(WinPos, WinSize, "22VortexParticleAffector"); //Enter main Loop TutorialWindow->mainLoop(); } osgExit(); return 0; }