| 23 | | using namespace osgSim; |
| 24 | | |
| 25 | | class MyNodeCallback: public osg::NodeCallback |
| 26 | | { |
| 27 | | void operator()(osg::Node*,osg::NodeVisitor*); |
| 28 | | }; |
| 29 | | |
| 30 | | // void MyNodeCallback::operator()(osg::Node* n,osg::NodeVisitor* nv) |
| 31 | | // { |
| 32 | | // if(osgSim::SphereSegment* ss=dynamic_cast<osgSim::SphereSegment*>(n)) |
| 33 | | // { |
| 34 | | // osg::Vec3 vec; |
| 35 | | // float azRange, elevRange; |
| 36 | | // ss->getArea(vec,azRange,elevRange); |
| 37 | | // |
| 38 | | // float azRangeDeg = osg::RadiansToDegrees(azRange); |
| 39 | | // |
| 40 | | // static bool azAscending = false; |
| 41 | | // |
| 42 | | // if(azAscending){ |
| 43 | | // azRangeDeg += 1.0f; |
| 44 | | // if(azRangeDeg>89.0f) azAscending = false; |
| 45 | | // }else{ |
| 46 | | // azRangeDeg -= 1.0f; |
| 47 | | // if(azRangeDeg<2.0f) azAscending = true; |
| 48 | | // } |
| 49 | | // |
| 50 | | // ss->setArea(vec,osg::DegreesToRadians(azRangeDeg),elevRange); |
| 51 | | // |
| 52 | | // } |
| 53 | | // traverse(n,nv); |
| 54 | | // } |
| 55 | | |
| 56 | | void MyNodeCallback::operator()(osg::Node* n,osg::NodeVisitor* nv) |
| 57 | | { |
| 58 | | if(osgSim::SphereSegment* ss=dynamic_cast<osgSim::SphereSegment*>(n)) |
| 59 | | { |
| 60 | | osg::Vec3 vec; |
| 61 | | float azRange, elevRange; |
| 62 | | ss->getArea(vec,azRange,elevRange); |
| 63 | | |
| 64 | | static float angle = 0.0f; |
| 65 | | if(++angle > 359.0f) angle = 0.0f; |
| 66 | | vec.set(sin(osg::DegreesToRadians(angle)),cos(osg::DegreesToRadians(angle)),0.0f); |
| 67 | | |
| 68 | | std::cout<<"angle "<<angle<<" degrees, vec is "<<vec |
| 69 | | <<", azRange is "<<osg::RadiansToDegrees(azRange) |
| 70 | | <<", elevRange is "<<osg::RadiansToDegrees(elevRange) |
| 71 | | <<std::endl; |
| 72 | | |
| 73 | | ss->setArea(vec,azRange,elevRange); |
| 74 | | } |
| 75 | | traverse(n,nv); |
| 76 | | } |
| 77 | | |
| 78 | | osg::Node* createSphereSegment() |
| 79 | | { |
| 80 | | SphereSegment* ss = new SphereSegment(osg::Vec3(0.0f,0.0f,0.0f), 1.0f, |
| 81 | | osg::Vec3(0.0f,1.0f,0.0f), |
| 82 | | osg::DegreesToRadians(90.0f), |
| 83 | | osg::DegreesToRadians(45.0f), |
| 84 | | 60); |
| 85 | | ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f)); |
| 86 | | ss->setSideColor(osg::Vec4(0.0f,0.0f,1.0f,0.5f)); |
| 87 | | //ss->setDrawMask(SphereSegment::DrawMask(SphereSegment::SPOKES | SphereSegment::EDGELINE)); |
| 88 | | |
| 89 | | //ss->setUpdateCallback(new MyNodeCallback); |
| 90 | | |
| 91 | | return ss; |
| 92 | | } |
| 93 | | |
| 94 | | int main( int argc, char **argv ) |
| | 16 | #include <osgParticle/ExplosionEffect> |
| | 17 | #include <osgParticle/SmokeEffect> |
| | 18 | #include <osgParticle/FireEffect> |
| | 19 | #include <osgParticle/ParticleSystemUpdater> |
| | 20 | |
| | 21 | // for the grid data.. |
| | 22 | #include "../osghangglide/terrain_coords.h" |
| | 23 | |
| | 24 | osg::AnimationPath* createAnimationPath(const osg::Vec3& center,float radius,double looptime) |
| | 25 | { |
| | 26 | // set up the animation path |
| | 27 | osg::AnimationPath* animationPath = new osg::AnimationPath; |
| | 28 | animationPath->setLoopMode(osg::AnimationPath::LOOP); |
| | 29 | |
| | 30 | int numSamples = 40; |
| | 31 | float yaw = 0.0f; |
| | 32 | float yaw_delta = 2.0f*osg::PI/((float)numSamples-1.0f); |
| | 33 | float roll = osg::inDegrees(30.0f); |
| | 34 | |
| | 35 | double time=0.0f; |
| | 36 | double time_delta = looptime/(double)numSamples; |
| | 37 | for(int i=0;i<numSamples;++i) |
| | 38 | { |
| | 39 | osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f)); |
| | 40 | osg::Quat rotation(osg::Quat(roll,osg::Vec3(0.0,1.0,0.0))*osg::Quat(-(yaw+osg::inDegrees(90.0f)),osg::Vec3(0.0,0.0,1.0))); |
| | 41 | |
| | 42 | animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation)); |
| | 43 | |
| | 44 | yaw += yaw_delta; |
| | 45 | time += time_delta; |
| | 46 | |
| | 47 | } |
| | 48 | return animationPath; |
| | 49 | } |
| | 50 | |
| | 51 | osg::Node* createMovingModel(const osg::Vec3& center, float radius) |
| | 52 | { |
| | 53 | float animationLength = 10.0f; |
| | 54 | |
| | 55 | osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength); |
| | 56 | |
| | 57 | osg::Group* model = new osg::Group; |
| | 58 | |
| | 59 | osg::Node* glider = osgDB::readNodeFile("glider.osg"); |
| | 60 | if (glider) |
| | 61 | { |
| | 62 | const osg::BoundingSphere& bs = glider->getBound(); |
| | 63 | |
| | 64 | float size = radius/bs.radius()*0.3f; |
| | 65 | osg::MatrixTransform* positioned = new osg::MatrixTransform; |
| | 66 | positioned->setDataVariance(osg::Object::STATIC); |
| | 67 | positioned->setMatrix(osg::Matrix::translate(-bs.center())* |
| | 68 | osg::Matrix::scale(size,size,size)* |
| | 69 | osg::Matrix::rotate(osg::inDegrees(-90.0f),0.0f,0.0f,1.0f)); |
| | 70 | |
| | 71 | positioned->addChild(glider); |
| | 72 | |
| | 73 | osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform; |
| | 74 | xform->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); |
| | 75 | xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0)); |
| | 76 | xform->addChild(positioned); |
| | 77 | |
| | 78 | model->addChild(xform); |
| | 79 | } |
| | 80 | |
| | 81 | osg::Node* cessna = osgDB::readNodeFile("cessna.osg"); |
| | 82 | if (cessna) |
| | 83 | { |
| | 84 | const osg::BoundingSphere& bs = cessna->getBound(); |
| | 85 | |
| | 86 | osgText::Text* text = new osgText::Text; |
| | 87 | float size = radius/bs.radius()*0.3f; |
| | 88 | |
| | 89 | text->setPosition(bs.center()); |
| | 90 | text->setText("Cessna"); |
| | 91 | text->setAlignment(osgText::Text::CENTER_CENTER); |
| | 92 | text->setAxisAlignment(osgText::Text::SCREEN); |
| | 93 | text->setCharacterSize(40.0f); |
| | 94 | text->setCharacterSizeMode(osgText::Text::SCREEN_COORDS); |
| | 95 | |
| | 96 | osg::Geode* geode = new osg::Geode; |
| | 97 | geode->addDrawable(text); |
| | 98 | |
| | 99 | osg::LOD* lod = new osg::LOD; |
| | 100 | lod->setRangeMode(osg::LOD::PIXEL_SIZE_ON_SCREEN); |
| | 101 | lod->addChild(geode,0.0f,100.0f); |
| | 102 | lod->addChild(cessna,100.0f,10000.0f); |
| | 103 | |
| | 104 | |
| | 105 | osg::MatrixTransform* positioned = new osg::MatrixTransform; |
| | 106 | positioned->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); |
| | 107 | positioned->setDataVariance(osg::Object::STATIC); |
| | 108 | positioned->setMatrix(osg::Matrix::translate(-bs.center())* |
| | 109 | osg::Matrix::scale(size,size,size)* |
| | 110 | osg::Matrix::rotate(osg::inDegrees(180.0f),0.0f,0.0f,1.0f)); |
| | 111 | |
| | 112 | //positioned->addChild(cessna); |
| | 113 | positioned->addChild(lod); |
| | 114 | |
| | 115 | osg::MatrixTransform* xform = new osg::MatrixTransform; |
| | 116 | xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0)); |
| | 117 | xform->addChild(positioned); |
| | 118 | |
| | 119 | model->addChild(xform); |
| | 120 | } |
| | 121 | |
| | 122 | return model; |
| | 123 | } |
| | 124 | |
| | 125 | |
| | 126 | osg::Vec3 computeTerrainIntersection(osg::Node* subgraph,float x,float y) |
| | 127 | { |
| | 128 | osgUtil::IntersectVisitor iv; |
| | 129 | osg::ref_ptr<osg::LineSegment> segDown = new osg::LineSegment; |
| | 130 | |
| | 131 | const osg::BoundingSphere& bs = subgraph->getBound(); |
| | 132 | float zMax = bs.center().z()+bs.radius(); |
| | 133 | float zMin = bs.center().z()-bs.radius(); |
| | 134 | |
| | 135 | segDown->set(osg::Vec3(x,y,zMin),osg::Vec3(x,y,zMax)); |
| | 136 | iv.addLineSegment(segDown.get()); |
| | 137 | |
| | 138 | subgraph->accept(iv); |
| | 139 | |
| | 140 | if (iv.hits()) |
| | 141 | { |
| | 142 | osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segDown.get()); |
| | 143 | if (!hitList.empty()) |
| | 144 | { |
| | 145 | osg::Vec3 ip = hitList.front().getWorldIntersectPoint(); |
| | 146 | return ip; |
| | 147 | } |
| | 148 | } |
| | 149 | |
| | 150 | return osg::Vec3(x,y,0.0f); |
| | 151 | } |
| | 152 | |
| | 153 | |
| | 154 | ////////////////////////////////////////////////////////////////////////////// |
| | 155 | // MAIN SCENE GRAPH BUILDING FUNCTION |
| | 156 | ////////////////////////////////////////////////////////////////////////////// |
| | 157 | |
| | 158 | void build_world(osg::Group *root) |
| | 159 | { |
| | 160 | |
| | 161 | osg::Geode* terrainGeode = new osg::Geode; |
| | 162 | // create terrain |
| | 163 | { |
| | 164 | osg::StateSet* stateset = new osg::StateSet(); |
| | 165 | osg::Image* image = osgDB::readImageFile("Images/lz.rgb"); |
| | 166 | if (image) |
| | 167 | { |
| | 168 | osg::Texture2D* texture = new osg::Texture2D; |
| | 169 | texture->setImage(image); |
| | 170 | stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON); |
| | 171 | } |
| | 172 | |
| | 173 | terrainGeode->setStateSet( stateset ); |
| | 174 | |
| | 175 | float size = 1000; // 10km; |
| | 176 | float scale = size/39.0f; // 10km; |
| | 177 | float z_scale = scale*3.0f; |
| | 178 | |
| | 179 | osg::HeightField* grid = new osg::HeightField; |
| | 180 | grid->allocateGrid(38,39); |
| | 181 | grid->setXInterval(scale); |
| | 182 | grid->setYInterval(scale); |
| | 183 | |
| | 184 | for(unsigned int r=0;r<39;++r) |
| | 185 | { |
| | 186 | for(unsigned int c=0;c<38;++c) |
| | 187 | { |
| | 188 | grid->setHeight(c,r,z_scale*vertex[r+c*39][2]); |
| | 189 | } |
| | 190 | } |
| | 191 | terrainGeode->addDrawable(new osg::ShapeDrawable(grid)); |
| | 192 | |
| | 193 | root->addChild(terrainGeode); |
| | 194 | } |
| | 195 | |
| | 196 | // create sphere segment |
| | 197 | { |
| | 198 | osgSim::SphereSegment* ss = new osgSim::SphereSegment( |
| | 199 | computeTerrainIntersection(terrainGeode,550.0f,780.0f), // center |
| | 200 | 500.0f, // radius |
| | 201 | osg::DegreesToRadians(135.0f), |
| | 202 | osg::DegreesToRadians(245.0f), |
| | 203 | osg::DegreesToRadians(-10.0f), |
| | 204 | osg::DegreesToRadians(30.0f), |
| | 205 | 60); |
| | 206 | ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f)); |
| | 207 | ss->setSideColor(osg::Vec4(0.0f,1.0f,1.0f,0.1f)); |
| | 208 | |
| | 209 | root->addChild(ss); |
| | 210 | } |
| | 211 | |
| | 212 | |
| | 213 | // create particle effects |
| | 214 | { |
| | 215 | osg::PositionAttitudeTransform* positionEffects = new osg::PositionAttitudeTransform; |
| | 216 | positionEffects->setPosition(computeTerrainIntersection(terrainGeode,100.0f,100.0f)); |
| | 217 | root->addChild(positionEffects); |
| | 218 | |
| | 219 | osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect; |
| | 220 | osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect; |
| | 221 | osgParticle::FireEffect* fire = new osgParticle::FireEffect; |
| | 222 | |
| | 223 | osg::Geode* geode = new osg::Geode; |
| | 224 | geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),10.0f))); |
| | 225 | positionEffects->addChild(geode); |
| | 226 | |
| | 227 | positionEffects->addChild(explosion); |
| | 228 | positionEffects->addChild(smoke); |
| | 229 | positionEffects->addChild(fire); |
| | 230 | |
| | 231 | osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater; |
| | 232 | |
| | 233 | psu->addParticleSystem(explosion->getParticleSystem()); |
| | 234 | psu->addParticleSystem(smoke->getParticleSystem()); |
| | 235 | psu->addParticleSystem(fire->getParticleSystem()); |
| | 236 | |
| | 237 | // add the updater node to the scene graph |
| | 238 | root->addChild(psu); |
| | 239 | } |
| | 240 | |
| | 241 | |
| | 242 | // create the moving models. |
| | 243 | { |
| | 244 | root->addChild(createMovingModel(osg::Vec3(500.0f,500.0f,500.0f),100.0f)); |
| | 245 | } |
| | 246 | } |
| | 247 | |
| | 248 | |
| | 249 | ////////////////////////////////////////////////////////////////////////////// |
| | 250 | // main() |
| | 251 | ////////////////////////////////////////////////////////////////////////////// |
| | 252 | |
| | 253 | |
| | 254 | int main(int argc, char **argv) |