| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | |
|---|
| 16 | |
|---|
| 17 | |
|---|
| 18 | |
|---|
| 19 | #include <iostream> |
|---|
| 20 | |
|---|
| 21 | #include <osg/ShapeDrawable> |
|---|
| 22 | #include <osg/MatrixTransform> |
|---|
| 23 | #include <osg/Point> |
|---|
| 24 | #include <osg/PointSprite> |
|---|
| 25 | #include <osgDB/ReadFile> |
|---|
| 26 | #include <osgDB/WriteFile> |
|---|
| 27 | #include <osgGA/TrackballManipulator> |
|---|
| 28 | #include <osgGA/StateSetManipulator> |
|---|
| 29 | #include <osgViewer/ViewerEventHandlers> |
|---|
| 30 | #include <osgViewer/Viewer> |
|---|
| 31 | |
|---|
| 32 | #include <osgParticle/ParticleSystem> |
|---|
| 33 | #include <osgParticle/ParticleSystemUpdater> |
|---|
| 34 | #include <osgParticle/ModularEmitter> |
|---|
| 35 | #include <osgParticle/ModularProgram> |
|---|
| 36 | |
|---|
| 37 | #include <osgParticle/AccelOperator> |
|---|
| 38 | #include <osgParticle/DampingOperator> |
|---|
| 39 | #include <osgParticle/BounceOperator> |
|---|
| 40 | #include <osgParticle/SinkOperator> |
|---|
| 41 | |
|---|
| 42 | void createFountainEffect( osgParticle::ModularEmitter* emitter, osgParticle::ModularProgram* program ) |
|---|
| 43 | { |
|---|
| 44 | |
|---|
| 45 | osg::ref_ptr<osgParticle::RandomRateCounter> rrc = new osgParticle::RandomRateCounter; |
|---|
| 46 | rrc->setRateRange( 500, 2000 ); |
|---|
| 47 | |
|---|
| 48 | |
|---|
| 49 | osg::ref_ptr<osgParticle::AccelOperator> accel = new osgParticle::AccelOperator; |
|---|
| 50 | accel->setToGravity(); |
|---|
| 51 | |
|---|
| 52 | |
|---|
| 53 | osg::ref_ptr<osgParticle::DampingOperator> damping = new osgParticle::DampingOperator; |
|---|
| 54 | damping->setDamping( 0.9f ); |
|---|
| 55 | |
|---|
| 56 | |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | |
|---|
| 60 | |
|---|
| 61 | osg::ref_ptr<osgParticle::BounceOperator> bounce = new osgParticle::BounceOperator; |
|---|
| 62 | bounce->setFriction( -0.05 ); |
|---|
| 63 | bounce->setResilience( 0.35 ); |
|---|
| 64 | bounce->addDiskDomain( osg::Vec3(0.0f, 0.0f, -2.0f), osg::Z_AXIS, 8.0f ); |
|---|
| 65 | bounce->addPlaneDomain( osg::Plane(osg::Z_AXIS, 5.0f) ); |
|---|
| 66 | |
|---|
| 67 | |
|---|
| 68 | osg::ref_ptr<osgParticle::SinkOperator> sink = new osgParticle::SinkOperator; |
|---|
| 69 | sink->setSinkStrategy( osgParticle::SinkOperator::SINK_OUTSIDE ); |
|---|
| 70 | sink->addSphereDomain( osg::Vec3(), 20.0f ); |
|---|
| 71 | |
|---|
| 72 | emitter->setCounter( rrc.get() ); |
|---|
| 73 | program->addOperator( accel.get() ); |
|---|
| 74 | program->addOperator( damping.get() ); |
|---|
| 75 | program->addOperator( bounce.get() ); |
|---|
| 76 | program->addOperator( sink.get() ); |
|---|
| 77 | } |
|---|
| 78 | |
|---|
| 79 | int main( int argc, char** argv ) |
|---|
| 80 | { |
|---|
| 81 | osg::ArgumentParser arguments( &argc, argv ); |
|---|
| 82 | |
|---|
| 83 | std::string textureFile("Images/smoke.rgb"); |
|---|
| 84 | while ( arguments.read("--texture", textureFile) ) {} |
|---|
| 85 | |
|---|
| 86 | float pointSize = 20.0f; |
|---|
| 87 | while ( arguments.read("--point", pointSize) ) {} |
|---|
| 88 | |
|---|
| 89 | double visibilityDistance = -1.0f; |
|---|
| 90 | while ( arguments.read("--visibility", visibilityDistance) ) {} |
|---|
| 91 | |
|---|
| 92 | bool customShape = false; |
|---|
| 93 | while ( arguments.read("--enable-custom") ) { customShape = true; } |
|---|
| 94 | |
|---|
| 95 | bool useShaders = true; |
|---|
| 96 | while ( arguments.read("--disable-shaders") ) { useShaders = false; } |
|---|
| 97 | |
|---|
| 98 | |
|---|
| 99 | |
|---|
| 100 | |
|---|
| 101 | osg::ref_ptr<osgParticle::ParticleSystem> ps = new osgParticle::ParticleSystem; |
|---|
| 102 | |
|---|
| 103 | osgParticle::Particle& ptemp = ps->getDefaultParticleTemplate(); |
|---|
| 104 | ps->getDefaultParticleTemplate().setLifeTime( 5.0f ); |
|---|
| 105 | |
|---|
| 106 | if ( customShape ) |
|---|
| 107 | { |
|---|
| 108 | |
|---|
| 109 | |
|---|
| 110 | |
|---|
| 111 | ps->getDefaultParticleTemplate().setShape( osgParticle::Particle::USER ); |
|---|
| 112 | ps->getDefaultParticleTemplate().setDrawable( new osg::ShapeDrawable(new osg::Box(osg::Vec3(), 1.0f)) ); |
|---|
| 113 | useShaders = false; |
|---|
| 114 | } |
|---|
| 115 | else |
|---|
| 116 | { |
|---|
| 117 | |
|---|
| 118 | ps->getDefaultParticleTemplate().setShape( osgParticle::Particle::POINT ); |
|---|
| 119 | } |
|---|
| 120 | |
|---|
| 121 | |
|---|
| 122 | |
|---|
| 123 | ps->setVisibilityDistance( visibilityDistance ); |
|---|
| 124 | |
|---|
| 125 | if ( useShaders ) |
|---|
| 126 | { |
|---|
| 127 | |
|---|
| 128 | |
|---|
| 129 | |
|---|
| 130 | ps->setDefaultAttributesUsingShaders( textureFile, true, 0 ); |
|---|
| 131 | } |
|---|
| 132 | else |
|---|
| 133 | { |
|---|
| 134 | |
|---|
| 135 | |
|---|
| 136 | ps->setDefaultAttributes( textureFile, true, false, 0 ); |
|---|
| 137 | |
|---|
| 138 | |
|---|
| 139 | |
|---|
| 140 | if ( visibilityDistance>0.0 ) |
|---|
| 141 | ps->setSortMode( osgParticle::ParticleSystem::SORT_BACK_TO_FRONT ); |
|---|
| 142 | } |
|---|
| 143 | |
|---|
| 144 | |
|---|
| 145 | osg::StateSet* stateset = ps->getOrCreateStateSet(); |
|---|
| 146 | stateset->setAttribute( new osg::Point(pointSize) ); |
|---|
| 147 | stateset->setTextureAttributeAndModes( 0, new osg::PointSprite, osg::StateAttribute::ON ); |
|---|
| 148 | |
|---|
| 149 | |
|---|
| 150 | |
|---|
| 151 | |
|---|
| 152 | osg::ref_ptr<osgParticle::ModularEmitter> emitter = new osgParticle::ModularEmitter; |
|---|
| 153 | emitter->setParticleSystem( ps.get() ); |
|---|
| 154 | |
|---|
| 155 | osg::ref_ptr<osgParticle::ModularProgram> program = new osgParticle::ModularProgram; |
|---|
| 156 | program->setParticleSystem( ps.get() ); |
|---|
| 157 | |
|---|
| 158 | createFountainEffect( emitter.get(), program.get() ); |
|---|
| 159 | |
|---|
| 160 | |
|---|
| 161 | |
|---|
| 162 | |
|---|
| 163 | osg::ref_ptr<osg::MatrixTransform> parent = new osg::MatrixTransform; |
|---|
| 164 | parent->addChild( emitter.get() ); |
|---|
| 165 | parent->addChild( program.get() ); |
|---|
| 166 | |
|---|
| 167 | |
|---|
| 168 | |
|---|
| 169 | osg::ref_ptr<osgParticle::ParticleSystemUpdater> updater = new osgParticle::ParticleSystemUpdater; |
|---|
| 170 | updater->addDrawable( ps.get() ); |
|---|
| 171 | |
|---|
| 172 | osg::ref_ptr<osg::Group> root = new osg::Group; |
|---|
| 173 | root->addChild( parent.get() ); |
|---|
| 174 | root->addChild( updater.get() ); |
|---|
| 175 | |
|---|
| 176 | |
|---|
| 177 | |
|---|
| 178 | |
|---|
| 179 | osgViewer::Viewer viewer; |
|---|
| 180 | viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); |
|---|
| 181 | viewer.addEventHandler( new osgViewer::StatsHandler ); |
|---|
| 182 | viewer.addEventHandler( new osgViewer::WindowSizeHandler ); |
|---|
| 183 | viewer.setSceneData( root.get() ); |
|---|
| 184 | viewer.setCameraManipulator( new osgGA::TrackballManipulator ); |
|---|
| 185 | |
|---|
| 186 | |
|---|
| 187 | |
|---|
| 188 | |
|---|
| 189 | |
|---|
| 190 | |
|---|
| 191 | |
|---|
| 192 | |
|---|
| 193 | return viewer.run(); |
|---|
| 194 | } |
|---|