Show
Ignore:
Timestamp:
03/15/06 13:26:10 (9 years ago)
Author:
robert
Message:

Added moving sphere segment intersections.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgspheresegment/osgspheresegment.cpp

    r4805 r5049  
    5353} 
    5454 
    55 osg::Node* createMovingModel(const osg::Vec3& center, float radius) 
     55 
     56 
     57class IntersectionUpdateCallback : public osg::NodeCallback 
     58{ 
     59        virtual void operator()(osg::Node* /*node*/, osg::NodeVisitor* nv) 
     60        { 
     61            if (!root_ || !terrain_ || !ss_ || !intersectionGroup_) 
     62            { 
     63                osg::notify(osg::NOTICE)<<"IntersectionUpdateCallback not set up correctly."<<std::endl; 
     64                return; 
     65            } 
     66         
     67            //traverse(node,nv); 
     68            frameCount_++; 
     69            if (frameCount_ > 200) 
     70            { 
     71                // first we need find the transformation matrix that takes 
     72                // the terrain into the coordinate frame of the sphere segment. 
     73                osg::Matrixd terrainLocalToWorld; 
     74                osg::MatrixList terrain_worldMatrices = terrain_->getWorldMatrices(root_.get()); 
     75                if (terrain_worldMatrices.empty()) terrainLocalToWorld.makeIdentity(); 
     76                else if (terrain_worldMatrices.size()==1) terrainLocalToWorld = terrain_worldMatrices.front(); 
     77                else 
     78                { 
     79                    osg::notify(osg::NOTICE)<<"IntersectionUpdateCallback: warning cannot interestect with multiple terrain instances, just uses first one."<<std::endl; 
     80                    terrainLocalToWorld = terrain_worldMatrices.front(); 
     81                } 
     82                 
     83                // sphere segment is easier as this callback is attached to the node, so the node visitor has the unique path to it already. 
     84                osg::Matrixd ssWorldToLocal = osg::computeWorldToLocal(nv->getNodePath()); 
     85                 
     86                // now we can compute the terrain to ss transform 
     87                osg::Matrixd possie = terrainLocalToWorld*ssWorldToLocal; 
     88                 
     89                osgSim::SphereSegment::LineList lines = ss_->computeIntersection(possie, terrain_.get()); 
     90                if (!lines.empty()) 
     91                { 
     92                    osg::notify(osg::NOTICE)<<"We've found intersections!!!!"<<std::endl; 
     93             
     94                    if (intersectionGroup_.valid()) 
     95                    { 
     96                        // now we need to place the intersections which are in the SphereSegmenet's coordinate frame into 
     97                        // to the final position. 
     98                        osg::MatrixTransform* mt = new osg::MatrixTransform; 
     99                        mt->setMatrix(osg::computeLocalToWorld(nv->getNodePath())); 
     100                        intersectionGroup_->addChild(mt); 
     101 
     102                        osg::Geode* geode = new osg::Geode; 
     103                        mt->addChild(geode); 
     104 
     105                        geode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF); 
     106 
     107                        for(osgSim::SphereSegment::LineList::iterator itr=lines.begin(); 
     108                           itr!=lines.end(); 
     109                           ++itr) 
     110                        { 
     111                            osg::Geometry* geom = new osg::Geometry; 
     112                            geode->addDrawable(geom); 
     113 
     114                            osg::Vec3Array* vertices = itr->get(); 
     115                            geom->setVertexArray(vertices); 
     116                            geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, vertices->getNumElements())); 
     117                        } 
     118                    } 
     119                } 
     120                else 
     121                { 
     122                       osg::notify(osg::NOTICE)<<"No intersections found"<<std::endl; 
     123                } 
     124 
     125                     
     126                frameCount_ = 0; 
     127            } 
     128        } 
     129    public: 
     130    osg::observer_ptr<osg::Group> root_; 
     131    osg::observer_ptr<osg::Geode> terrain_; 
     132    osg::observer_ptr<osgSim::SphereSegment> ss_; 
     133    osg::observer_ptr<osg::Group> intersectionGroup_; 
     134    unsigned frameCount_; 
     135}; 
     136 
     137 
     138osg::Node* createMovingModel(const osg::Vec3& center, float radius, osg::Geode * terrainGeode, osg::Group * root) 
    56139{ 
    57140    float animationLength = 10.0f; 
     
    79162        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0)); 
    80163        xform->addChild(positioned); 
    81  
     164        model->addChild(xform); 
     165    } 
     166    if (1) 
     167    { 
     168        // The IntersectionUpdateCallback has to have a safe place to put all its generated geometry into, 
     169        // and this group can't be in the parental chain of the callback otherwise we will end up invalidating 
     170        // traversal iterators. 
     171        osg::Group* intersectionGroup = new osg::Group; 
     172        root->addChild(intersectionGroup); 
     173     
     174        osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;     
     175        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0)); 
     176         
     177        osgSim::SphereSegment * ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0), 
     178                                700.0f, // radius 
     179                                osg::DegreesToRadians(135.0f), 
     180                                osg::DegreesToRadians(240.0f), 
     181                                osg::DegreesToRadians(-90.0f), 
     182                                osg::DegreesToRadians(-70.0f), 
     183                                60); 
     184                                 
     185        IntersectionUpdateCallback * iuc = new IntersectionUpdateCallback; 
     186        iuc->frameCount_ = 0; 
     187        iuc->root_ = root; 
     188        iuc->terrain_ = terrainGeode; 
     189        iuc->ss_ = ss; 
     190        iuc->intersectionGroup_ = intersectionGroup; 
     191        ss->setUpdateCallback(iuc); 
     192        ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f)); 
     193        ss->setSideColor(osg::Vec4(0.5f,1.0f,1.0f,0.1f)); 
     194        xform->addChild(ss); 
    82195        model->addChild(xform); 
    83196    } 
     
    120233        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0)); 
    121234        xform->addChild(positioned); 
    122  
    123         // add particle effects to cessna. 
    124         { 
    125             osg::PositionAttitudeTransform* positionEffects = new osg::PositionAttitudeTransform; 
    126             positionEffects->setPosition(osg::Vec3(0.0f,0.0f,0.0f)); 
    127             xform->addChild(positionEffects); 
    128  
    129             osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect; 
    130             osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect; 
    131             osgParticle::FireEffect* fire = new osgParticle::FireEffect; 
    132  
    133             positionEffects->addChild(explosion); 
    134             positionEffects->addChild(smoke); 
    135             positionEffects->addChild(fire); 
    136         } 
    137235         
    138236        model->addChild(xform); 
     
    461559    // create the moving models. 
    462560    { 
    463         root->addChild(createMovingModel(osg::Vec3(500.0f,500.0f,500.0f),100.0f)); 
     561        root->addChild(createMovingModel(osg::Vec3(500.0f,500.0f,500.0f),100.0f, terrainGeode.get(), root)); 
    464562    } 
    465563}