| 53 | | osg::Node* createMovingModel(const osg::Vec3& center, float radius) |
| 54 | | { |
| 55 | | float animationLength = 10.0f; |
| 56 | | |
| 57 | | osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength); |
| 58 | | |
| 59 | | osg::Group* model = new osg::Group; |
| 60 | | |
| 61 | | osg::Node* glider = osgDB::readNodeFile("glider.osg"); |
| 62 | | if (glider) |
| 63 | | { |
| 64 | | glider->setName("glider"); |
| 65 | | |
| 66 | | const osg::BoundingSphere& bs = glider->getBound(); |
| 67 | | |
| 68 | | float size = radius/bs.radius()*0.3f; |
| 69 | | osg::MatrixTransform* positioned = new osg::MatrixTransform; |
| 70 | | positioned->setDataVariance(osg::Object::STATIC); |
| 71 | | positioned->setMatrix(osg::Matrix::translate(-bs.center())* |
| 72 | | osg::Matrix::scale(size,size,size)* |
| 73 | | osg::Matrix::rotate(osg::inDegrees(-90.0f),0.0f,0.0f,1.0f)); |
| 74 | | |
| 75 | | positioned->addChild(glider); |
| 76 | | |
| 77 | | osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform; |
| 78 | | xform->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); |
| 79 | | xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0)); |
| 80 | | xform->addChild(positioned); |
| 81 | | |
| 82 | | model->addChild(xform); |
| 83 | | } |
| 84 | | |
| 85 | | osg::Node* cessna = osgDB::readNodeFile("cessna.osg"); |
| 86 | | if (cessna) |
| 87 | | { |
| 88 | | cessna->setName("cessna"); |
| 89 | | |
| 90 | | const osg::BoundingSphere& bs = cessna->getBound(); |
| 91 | | |
| 92 | | osgText::Text* text = new osgText::Text; |
| 93 | | float size = radius/bs.radius()*0.3f; |
| 94 | | |
| 95 | | text->setPosition(bs.center()); |
| 96 | | text->setText("Cessna"); |
| 97 | | text->setAlignment(osgText::Text::CENTER_CENTER); |
| 98 | | text->setAxisAlignment(osgText::Text::SCREEN); |
| 99 | | text->setCharacterSize(40.0f); |
| 100 | | text->setCharacterSizeMode(osgText::Text::SCREEN_COORDS); |
| 101 | | |
| 102 | | osg::Geode* geode = new osg::Geode; |
| 103 | | geode->addDrawable(text); |
| 104 | | |
| 105 | | osg::LOD* lod = new osg::LOD; |
| 106 | | lod->setRangeMode(osg::LOD::PIXEL_SIZE_ON_SCREEN); |
| 107 | | lod->addChild(geode,0.0f,100.0f); |
| 108 | | lod->addChild(cessna,100.0f,10000.0f); |
| 109 | | |
| 110 | | |
| 111 | | osg::MatrixTransform* positioned = new osg::MatrixTransform; |
| 112 | | positioned->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); |
| 113 | | positioned->setDataVariance(osg::Object::STATIC); |
| 114 | | positioned->setMatrix(osg::Matrix::translate(-bs.center())* |
| 115 | | osg::Matrix::scale(size,size,size)* |
| 116 | | osg::Matrix::rotate(osg::inDegrees(180.0f),0.0f,0.0f,1.0f)); |
| 117 | | |
| 118 | | //positioned->addChild(cessna); |
| 119 | | positioned->addChild(lod); |
| 120 | | |
| 121 | | osg::MatrixTransform* xform = new osg::MatrixTransform; |
| 122 | | xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0)); |
| 123 | | xform->addChild(positioned); |
| 124 | | |
| 125 | | model->addChild(xform); |
| 126 | | } |
| 127 | | |
| 128 | | return model; |
| 129 | | } |
| 130 | | |
| 131 | | |
| 132 | | osg::Vec3 computeTerrainIntersection(osg::Node* subgraph,float x,float y) |
| 133 | | { |
| 134 | | osgUtil::IntersectVisitor iv; |
| 135 | | osg::ref_ptr<osg::LineSegment> segDown = new osg::LineSegment; |
| 136 | | |
| 137 | | const osg::BoundingSphere& bs = subgraph->getBound(); |
| 138 | | float zMax = bs.center().z()+bs.radius(); |
| 139 | | float zMin = bs.center().z()-bs.radius(); |
| 140 | | |
| 141 | | segDown->set(osg::Vec3(x,y,zMin),osg::Vec3(x,y,zMax)); |
| 142 | | iv.addLineSegment(segDown.get()); |
| 143 | | |
| 144 | | subgraph->accept(iv); |
| 145 | | |
| 146 | | if (iv.hits()) |
| 147 | | { |
| 148 | | osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segDown.get()); |
| 149 | | if (!hitList.empty()) |
| 150 | | { |
| 151 | | osg::Vec3 ip = hitList.front().getWorldIntersectPoint(); |
| 152 | | return ip; |
| 153 | | } |
| 154 | | } |
| 155 | | |
| 156 | | return osg::Vec3(x,y,0.0f); |
| 157 | | } |
| 158 | | |
| 159 | | |
| 160 | | ////////////////////////////////////////////////////////////////////////////// |
| 161 | | // MAIN SCENE GRAPH BUILDING FUNCTION |
| 162 | | ////////////////////////////////////////////////////////////////////////////// |
| 163 | | |
| 164 | | void build_world(osg::Group *root) |
| 165 | | { |
| 166 | | |
| 167 | | osg::Geode* terrainGeode = new osg::Geode; |
| 168 | | // create terrain |
| 169 | | { |
| 170 | | osg::StateSet* stateset = new osg::StateSet(); |
| 171 | | osg::Image* image = osgDB::readImageFile("Images/lz.rgb"); |
| 172 | | if (image) |
| 173 | | { |
| 174 | | osg::Texture2D* texture = new osg::Texture2D; |
| 175 | | texture->setImage(image); |
| 176 | | stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON); |
| 177 | | } |
| 178 | | |
| 179 | | terrainGeode->setStateSet( stateset ); |
| 180 | | |
| 181 | | float size = 1000; // 10km; |
| 182 | | float scale = size/39.0f; // 10km; |
| 183 | | float z_scale = scale*3.0f; |
| 184 | | |
| 185 | | osg::HeightField* grid = new osg::HeightField; |
| 186 | | grid->allocateGrid(38,39); |
| 187 | | grid->setXInterval(scale); |
| 188 | | grid->setYInterval(scale); |
| 189 | | |
| 190 | | for(unsigned int r=0;r<39;++r) |
| 191 | | { |
| 192 | | for(unsigned int c=0;c<38;++c) |
| 193 | | { |
| 194 | | grid->setHeight(c,r,z_scale*vertex[r+c*39][2]); |
| 195 | | } |
| 196 | | } |
| 197 | | terrainGeode->addDrawable(new osg::ShapeDrawable(grid)); |
| 198 | | |
| 199 | | root->addChild(terrainGeode); |
| 200 | | } |
| 201 | | |
| 202 | | // create sphere segment |
| 203 | | { |
| 204 | | osgSim::SphereSegment* ss = new osgSim::SphereSegment( |
| 205 | | computeTerrainIntersection(terrainGeode,550.0f,780.0f), // center |
| 206 | | 500.0f, // radius |
| 207 | | osg::DegreesToRadians(135.0f), |
| 208 | | osg::DegreesToRadians(245.0f), |
| 209 | | osg::DegreesToRadians(-10.0f), |
| 210 | | osg::DegreesToRadians(30.0f), |
| 211 | | 60); |
| 212 | | ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f)); |
| 213 | | ss->setSideColor(osg::Vec4(0.0f,1.0f,1.0f,0.1f)); |
| 214 | | |
| 215 | | root->addChild(ss); |
| 216 | | } |
| 217 | | |
| 218 | | |
| 219 | | // create particle effects |
| 220 | | { |
| 221 | | osg::PositionAttitudeTransform* positionEffects = new osg::PositionAttitudeTransform; |
| 222 | | positionEffects->setPosition(computeTerrainIntersection(terrainGeode,100.0f,100.0f)); |
| 223 | | root->addChild(positionEffects); |
| 224 | | |
| 225 | | osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect; |
| 226 | | osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect; |
| 227 | | osgParticle::FireEffect* fire = new osgParticle::FireEffect; |
| 228 | | |
| 229 | | osg::Geode* geode = new osg::Geode; |
| 230 | | geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),10.0f))); |
| 231 | | positionEffects->addChild(geode); |
| 232 | | |
| 233 | | positionEffects->addChild(explosion); |
| 234 | | positionEffects->addChild(smoke); |
| 235 | | positionEffects->addChild(fire); |
| 236 | | |
| 237 | | osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater; |
| 238 | | |
| 239 | | psu->addParticleSystem(explosion->getParticleSystem()); |
| 240 | | psu->addParticleSystem(smoke->getParticleSystem()); |
| 241 | | psu->addParticleSystem(fire->getParticleSystem()); |
| 242 | | |
| 243 | | // add the updater node to the scene graph |
| 244 | | root->addChild(psu); |
| 245 | | } |
| 246 | | |
| 247 | | |
| 248 | | // create the moving models. |
| 249 | | { |
| 250 | | root->addChild(createMovingModel(osg::Vec3(500.0f,500.0f,500.0f),100.0f)); |
| 251 | | } |
| 252 | | } |