Documentation


mainScene.cpp

Go to the documentation of this file.
00001 
00002 //                            mainScene.cpp                                   //
00004 
00005 #include <X3DTK/memreleaser.h>
00006 #include <X3DTK/X3D/scenegraph.h>
00007 #include <X3DTK/X3D/glbuilder.h>
00008 #include <X3DTK/X3D/scenesaver.h>
00009 #include <X3DTK/X3D/bboxupdater.h>
00010 //debug
00011 //#include <X3DTK/graphtester.h>
00012 
00013 //#include <animal/X3DTK/X3D/engine/engineRemover.h>
00014 #include <animal/X3DTK/X3D/engine/engineWalker.h>
00015 #include <animal/X3DTK/X3D/engine/engineLoaderVisitor.h>
00016 #include <animal/X3DTK/X3D/engine/engineLoader.h>
00017 #include <animal/X3DTK/X3D/engine/glBuilderEngineNodeVisitor.h>
00018 #include <animal/X3DTK/Qt/mainControllerGUI/MainController.h>
00019 #include <animal/engine/engine.h>
00020 #include <animal/event/keyEvent.h>
00021 #include <animal/event/mouseEvent.h>
00022 #include <animal/X3DTK/X3D/massSpringNode/massSpringNode.h>
00023 
00024 #include "mainScene.h"
00025 #include <iostream>
00026 using std::cout;
00027 using std::endl;
00028 using std::cerr;
00029 
00030 
00031 namespace X3DTK
00032 {
00033 
00035 MainScene::MainScene()
00036         : x3dscene(NULL)
00037         , glscene(NULL)
00038         , x3dloader(NULL)
00039         , mainController(NULL)
00040         , m_selectedNode(NULL)
00041 {
00042     // Init all the processors
00043     engineLoader = new X3D::EngineLoader(&allEngineNodes, &kinematicEngines, &dynamicEngines, &collisionEngines);
00044     //bboxupdater = new X3D::BBoxUpdater();
00045 /*    builder = new  X3D::GLBuilder();
00046     builder->setComponentVisitor(new X3D::GLBuilderEngineNodeVisitor());*/
00047 //    renderer = new  GL::MyRenderer();
00048 //    releaser = new  MemReleaser();
00049 //    x3dGLMapBuilder = new  GL::X3DGLMapBuilder();
00050 
00051     // Create the x3d scene, the root x3d node
00052     x3dscene = new X3D::Scene();
00053     bbupdater = new X3D::BBoxUpdater();
00054     buildGL();
00055 
00056 }
00057 
00059 MainScene:: ~MainScene()
00060 {
00061     releaseNode(x3dscene);
00062     releaseNode(glscene);
00063     x3dscene = NULL;
00064     glscene = NULL;
00065 
00066     if (x3dloader)
00067     {
00068         //delete x3dloader;
00069         x3dloader = NULL;
00070     }
00071 /*    if (bboxupdater)
00072     {
00073         delete bboxupdater;
00074         bboxupdater = NULL;
00075     }*/
00076 /*    if (builder)
00077     {
00078         delete builder;
00079         builder = NULL;
00080     }*/
00081 /*    if (renderer)
00082     {
00083         delete renderer;
00084         renderer = NULL;
00085     }*/
00086 /*    if (releaser)
00087     {
00088         delete releaser;
00089         releaser = NULL;
00090     }*/
00091 /*    if (engineLoaderVisitor)
00092     {
00093         delete engineLoaderVisitor;
00094         engineLoaderVisitor = NULL;
00095     }*/
00096 //     if (engineLoader)
00097 //     {
00098 //         delete engineLoader;
00099 //         engineLoader = NULL;
00100 //     }
00101 
00102 }
00103 
00104 
00106 void MainScene::load(const char *file, bool fileValidation)
00107 {
00108     // Load the x3d scene file
00109     if (!x3dloader)
00110     {
00111         std::cerr<<"Warning MainScene::load(): impossible to load because the x3dloader is NULL."<<std::endl;
00112         return;
00113     }
00114     releaseNode(x3dscene);
00115     x3dscene = NULL;
00116     x3dscene = x3dloader->load(file, fileValidation);
00117 
00118     // Create the list of engines
00119     engineLoader->initialize(x3dscene);
00120 
00121     // Reload the gl graph
00122     buildGL();
00123 
00124 }
00125 
00127 void MainScene::load(const char *file, X3D::X3DNode * node, bool fileValidation)
00128 {
00129     if (!node)
00130     {
00131         std::cerr<< "Warning: impossible to insert. The node from where you want to insert new nodes is NULL."<< std::endl;
00132         return;
00133     }
00134 
00135     if (node && dynamic_cast<X3D::X3DGroupingNode *>(node) == NULL)
00136     {
00137         std::cerr<< "Warning: impossible to insert. The node from where you want to insert new nodes is not an X3D::X3DGroupingNode."<< std::endl;
00138         return;
00139     }
00140 
00141     // Load the x3d scene file
00142     if (!x3dloader)
00143     {
00144         std::cerr<<"Warning MainScene::load(): impossible to load because the x3dloader is NULL."<<std::endl;
00145         return;
00146     }
00147     X3D::Scene * sceneTmp = x3dloader->load(file, fileValidation);
00148 
00149     // Get all the children of the sceneTmp
00150     MFNode childrenList = sceneTmp->getChildren();
00151     for(MFNode::iterator it = childrenList.begin(); it != childrenList.end();++it)
00152     {
00153         engineLoader->initialize(*it);
00154         pastNode((*it), node);
00155     }
00156 
00157     delete  sceneTmp;
00158 }
00159 
00161 bool MainScene::pastNode(X3DAbstractNode* node, X3DAbstractNode* parentNode)
00162 {
00163     if (!node)
00164     {
00165         std::cerr<< "Warning MainScene::pastNode(): impossible to past. The node you want to past is NULL."<< std::endl;
00166         return false;
00167     }
00168 
00169     if (!parentNode)
00170     {
00171         std::cerr<< "Warning MainScene::pastNode(): impossible to past. The parent node where you want to past a node is NULL."<< std::endl;
00172         return false;
00173     }
00174 
00175     if (isADescendant(parentNode, node))
00176     {
00177         std::cerr<< "Warning MainScene::pastNode(): impossible to past. The parentNode is a descendant of the node you want to past."<< std::endl;
00178         return false;
00179     }
00180 
00181     if (parentNode && dynamic_cast<X3D::X3DGroupingNode *>(parentNode) == NULL)
00182     {
00183         std::cerr<< "Warning MainScene::pastNode(): impossible to past. The node from where you want to past new nodes is not an X3D::X3DGroupingNode."<< std::endl;
00184         return false;
00185     }
00186 
00187     parentNode->setChild(node);
00188 
00189     // Add the name of the node in the DEFDic
00190     SFString s = node->getName();//X3DAbstractNode::DEFDict.getNameOfNode(node);
00191     if (s=="")
00192     {
00193         node->setName(node->getType()->getName());
00194     }
00195 
00196     // Load the new engines contain in the x3d node
00197     engineLoader->initialize(node);
00198 
00199     // Reload the gl graph
00200     buildGL();
00201 
00202     return true;
00203 }
00204 
00209 bool MainScene::cutNode(X3DAbstractNode* node, X3DAbstractNode* parentNode)
00210 {
00211     if (!node)
00212     {
00213         std::cerr<< "Warning MainScene::cutNode(): impossible to cut. The node you want to cut is NULL."<< std::endl;
00214         return false;
00215     }
00216 
00217     if (dynamic_cast<X3D::X3DChildNode *>(node) == NULL)
00218     {
00219         std::cerr<< "Warning MainScene::cutNode(): impossible to cut. The node you want to cut is not an X3D::X3DChildNode."<< std::endl;
00220         return false;
00221     }
00222 
00223     engineLoader->release(node);
00224     if (parentNode)
00225     {
00226         // Remove the link
00227         parentNode->removeChild(node);
00228 
00229         //         MFNode parentList = node->getParentList();
00230         //         // Get the engines contain in the x3d node and remove them
00231         //         if(parentList.size()== 0)
00232         //         {
00233         //             engineLoader->release(node);
00234         //         }
00235 
00236     }
00237     else if (x3dscene==node)
00238     {
00239         // Get all the children of the scene and delete it
00240         MFNode childrenList = x3dscene->getChildren();
00241         for(MFNode::iterator it = childrenList.begin(); it != childrenList.end();++it)
00242         {
00243             // Delete the node
00244             deleteNode(*it, x3dscene);
00245         }
00246     }
00247 
00248     // Reload the gl graph
00249     buildGL();
00250 
00251     return true;
00252 
00253 }
00254 
00260 void MainScene::deleteNode(X3DAbstractNode* node, X3DAbstractNode* parentNode)
00261 {
00262     if(cutNode(node, parentNode))
00263     {
00264         // Get all the children of the x3d node
00265         // and remove the link between the x3d node
00266         // and its corresponding QWidget in
00267         // the main GUI and delete the QWidget
00268         if (mainController && !isADescendant(node, x3dscene))
00269         {
00270             MFNode childrenList = node->getChildList();
00271             for(MFNode::iterator it = childrenList.begin(); it != childrenList.end();++it)
00272                 mainController->removeX3DQtMap(dynamic_cast<X3D::X3DNode *>(*it));
00273             mainController->removeX3DQtMap(node);
00274         }
00275 
00276         // release the x3d node
00277         releaseNode(node);
00278     }
00279 }
00280 
00284 void MainScene::releaseNode(X3DAbstractNode* node)
00285 {
00286     if (node==x3dscene)
00287     {
00288         // Get all the children of the scene and delete them
00289         MFNode childrenList = x3dscene->getChildren();
00290         for(MFNode::iterator it = childrenList.begin(); it != childrenList.end();++it)
00291             deleteNode(*it, x3dscene);
00292     }
00293     else
00294     {
00295         if( X3D::EngineNode* e=dynamic_cast<X3D::EngineNode*>(node) )
00296         {
00297             glUpdates.erase(e);
00298         }
00299         MemReleaser releaser;
00300         releaser.release(node);
00301     }
00302 }
00303 
00305 void MainScene::draw()
00306 {
00307     //std::cerr<< " MainScene::draw()" <<std::endl;
00308 
00309     // Draw the engines which doesn't have a corresponding x3d node
00310     for( AnimalEngines::iterator i=animalEngines.begin(); i!=animalEngines.end(); ++i )
00311     {
00312         if((*i)->drawEngine)
00313             (*i)->draw();
00314         if((*i)->drawBBox)
00315             (*i)->drawBoundingBox();
00316     }
00317     
00318     if (glscene)
00319     {
00320         // Draw the gl scene
00321         glPushAttrib(GL_ALL_ATTRIB_BITS);
00322         //GL::MyRenderer renderer;
00323         renderer.render(glscene);
00324         glPopAttrib();
00325     }
00326 }
00327 
00329 void MainScene::save(const char *file)
00330 {
00331     //Close the engine nodes
00332     for( X3D::EngineNodes::iterator i= allEngineNodes.begin(); i!=allEngineNodes.end(); ++i )
00333         (*i)->close();
00334       
00335     for( X3D::EngineNodes::reverse_iterator i= allEngineNodes.rbegin(); i!=allEngineNodes.rend(); ++i )
00336         (*i)->postClose();
00337     
00338     X3D::SceneSaver sceneSaver;
00339     sceneSaver.saveAs(x3dscene, file);
00340 }
00341 
00343 void MainScene::reset()
00344 {
00345     //Init the animalEngines
00346     for( AnimalEngines::iterator i= animalEngines.begin(); i!=animalEngines.end(); ++i )
00347         if((*i)->resetEngine)
00348             (*i)->reset();
00349 
00350     //Init the engine nodes
00351     for( X3D::EngineNodes::iterator i= allEngineNodes.begin(); i!=allEngineNodes.end(); ++i )
00352         (*i)->reset();
00353       
00354     for( X3D::EngineNodes::reverse_iterator i= allEngineNodes.rbegin(); i!=allEngineNodes.rend(); ++i )
00355         (*i)->postReset();
00356 
00357     updateGL();
00358 }
00359 
00361 void MainScene::move(double dt)
00362 {
00363     //std::cerr<< "MainScene::move()" << std::endl;
00364 
00365     // Move the animal::engines
00366     for( AnimalEngines::iterator i= animalEngines.begin(); i!=animalEngines.end(); ++i )
00367         if ((*i)->moveEngine)
00368             (*i)->move(dt);
00369     // Move the engine nodes
00370     for( X3D::EngineNodes::iterator i= allEngineNodes.begin(); i!=allEngineNodes.end(); ++i )
00371     {
00372         if( (*i)->m_animate ) 
00373             (*i)->animate(dt);
00374     }
00375     for( X3D::EngineNodes::reverse_iterator i= allEngineNodes.rbegin(); i!=allEngineNodes.rend(); ++i )
00376     {
00377         if( (*i)->m_animate ) 
00378             (*i)->postAnimate(dt);
00379     }
00380     
00381     updateGL();
00382 }
00383 
00386 bool MainScene::computeBbox()
00387 {
00388 
00389     //std::cerr<<"MainScene::computeBbox()"<<std::endl;
00390 
00391     for( X3D::EngineNodes::iterator i= allEngineNodes.begin(); i!=allEngineNodes.end(); ++i )
00392     {
00393         (*i)->updateBoundingBox();
00394         //std::cerr<<"update bounding box of engine "<<(*i)->getName() << endl;
00395     }
00396     
00397     // Bounding box of the x3d scene
00398     bbupdater->update(x3dscene);
00399     SFVec3f center = x3dscene->getBBoxCenter();
00400     SFVec3f size = x3dscene->getBBoxSize();
00401 
00402     SFVec3f A = center + 0.5f*size;
00403     SFVec3f B = center - 0.5f*size;
00404 
00405     if (A.x < B.x)
00406     {
00407         min.x = A.x;
00408         max.x = B.x;
00409     }
00410     else
00411     {
00412         min.x = B.x;
00413         max.x = A.x;
00414     }
00415 
00416     if (A.y < B.y)
00417     {
00418         min.y = A.y;
00419         max.y = B.y;
00420     }
00421     else
00422     {
00423         min.y = B.y;
00424         max.y = A.y;
00425     }
00426 
00427     if (A.z < B.z)
00428     {
00429         min.z = A.z;
00430         max.z = B.z;
00431     }
00432     else
00433     {
00434         min.z = B.z;
00435         max.z = A.z;
00436     }
00437     //cerr<<"MainScene::computeBbox graph "<< min.x <<", "<< min.y <<", "<<min.z<<", "<<max.x<<", "<<max.y<<", "<<max.z<<endl;;
00438 
00439     float minX, minY, minZ, maxX, maxY, maxZ;
00440     // Bounding box of all the engines
00441     for( AnimalEngines::iterator i= animalEngines.begin(); i!=animalEngines.end(); ++i )
00442     {
00443         (*i)->getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
00444         if (minX < min.x)
00445             min.x = minX;
00446         if (minY < min.y)
00447             min.y = minY;
00448         if (minZ < min.z)
00449             min.z = minZ;
00450         if (max.x < maxX)
00451             max.x = maxX;
00452         if (max.y < maxY)
00453             max.y = maxY;
00454         if (max.z < maxZ)
00455             max.z = maxZ;
00456     }
00457 
00458     //cout<<"MainScene::computeBbox total "<< min.x <<", "<< min.y <<", "<<min.z<<", "<<max.x<<", "<<max.y<<", "<<max.z<<endl;;
00459     return true;
00460 }
00461 
00462 //====================== Manage engines
00464 void MainScene::addEngine( animal::Engine * engine)
00465 {
00466     animalEngines.push_back(engine);
00467     engine->init();
00468     computeBbox();
00469 }
00470 
00472 void MainScene::removeEngine(animal::Engine* engine)
00473 {
00474     animalEngines.remove(engine);
00475     computeBbox();
00476 }
00477 
00479 void MainScene::clearEngines()
00480 {
00481     animalEngines.clear();
00482     computeBbox();
00483 }
00484 
00486 void MainScene::updateGL()
00487 {
00488     for( GLUpdates::iterator u=glUpdates.begin(); u!=glUpdates.end(); ++u )
00489     {
00490         for( GLNodeList::iterator g=(*u).second.begin(); g!=(*u).second.end(); ++g )
00491         {
00492             (*g)->update();
00493         }
00494     }
00495     computeBbox();
00496     //  std::cerr<<"MainScene::updateGL() - end -------------------------------------------------"<<std::endl;
00497 }
00498 
00502 void MainScene::buildGL()
00503 {
00504     //std::cout<<"MainScene::buildGL start " << std::endl;
00505     // Build the glscene from the x3dscene
00506     releaseNode(glscene);
00507     glscene = NULL;
00508     X3D::GLBuilder builder;
00509     builder.setComponentVisitor(new X3D::GLBuilderEngineNodeVisitor());
00510     glscene = builder.build(x3dscene);
00511 
00512     // Update the list glNodeToUpdate
00513     GL::X3DGLMapBuilder x3dGLMapBuilder;
00514     x3dGLMap = *x3dGLMapBuilder.build(glscene);
00515     glUpdates.clear();
00516 
00517     // Find the nodes modified by the engines
00518     for( X3DGLMap::iterator i= x3dGLMap.begin(); i!=x3dGLMap.end(); ++i )
00519     {
00520        //std::cout<<"MainScene::buildGL found node named "<<(*i).first->getName() << std::endl;
00521        X3DTK::X3D::EngineNode* engineNode = dynamic_cast<X3DTK::X3D::EngineNode*>((*i).first);
00522         if(engineNode)
00523         {
00524             //std::cout<<"MainScene::buildGL found engine node named "<<engineNode->getName() << std::endl;
00525             typedef X3DTK::X3D::X3D_X3DNodeList NodeList;
00526             NodeList outputs;
00527             outputs.clear();
00528             engineNode->declareOutputs(outputs);
00529             //std::cout<<"this node has "<<outputs.size()<<" outputs"<< std::endl;
00530             for(NodeList::iterator n=outputs.begin(); n!=outputs.end(); ++n )
00531             {
00532                 if( X3DTK::X3D::Coordinate* c = dynamic_cast<X3DTK::X3D::Coordinate*>(*n) )
00533                 {
00534                     // find the Geometry nodes linked to this Coordinate node
00535                     MFNode parents = c->getParentList();
00536                     for( MFNode::iterator p=parents.begin(); p!=parents.end(); ++p)
00537                     {
00538                         if( X3DTK::X3D::X3DGeometryNode* g = dynamic_cast<X3DTK::X3D::X3DGeometryNode*>(*p) )
00539                         {
00540                             // add its corresponding gl nodes to the list glNodeToUpdate
00541                             for (std::list<GL::X3DNode *>::iterator i= x3dGLMap[g].begin(); i!=x3dGLMap[g].end(); ++i)
00542                             {
00543                                 //std::cout<<"MainScene::buildGL, geometry node named "<<(*i)->getX3DReference()->getName() <<" to update"<<std::endl;
00544                                 glUpdates[engineNode].push_back(*i);
00545                             }
00546                         }
00547                     }
00548                 }
00549                 else if( X3DTK::X3D::Transform* t = dynamic_cast<X3DTK::X3D::Transform*>(*n) )
00550                 {
00551                     // add its corresponding gl nodes to the list glNodeToUpdate
00552                     for (std::list<GL::X3DNode *>::iterator i= x3dGLMap[t].begin(); i!=x3dGLMap[t].end(); ++i)
00553                     {
00554                         //std::cout<<"MainScene::buildGL, transform node named "<<(*i)->getX3DReference()->getName() <<" to update"<<std::endl;
00555                         glUpdates[engineNode].push_back(*i);
00556                     }
00557                 }
00558                 else if( dynamic_cast<X3DTK::X3D::MassSpringNode*>(*n) )
00559                 {
00560                     // nothing to do
00561                 }
00562                 else
00563                 {
00564 /*                    std::cout<<"MainScene::buildGL, engine "<< engineNode->getName();
00565                     std::cout <<", can not find gl update to perform for output "<< (*n)->getName() << std::endl;*/
00566                     std::cout<<"MainScene::buildGL, can not find gl update to perform for output "<< (*n)->getName() << std::endl;
00567                 }
00568             }
00569 
00570         }
00571         else
00572         {
00573             /*            std::cout<<"MainScene::buildGL found non-engine node named "<<(*i).first->getName() << std::endl;*/
00574         }
00575     }
00576 
00577 }
00578 
00579 
00581 bool MainScene::isADescendant(X3DAbstractNode* node1, X3DAbstractNode* node2)
00582 {
00583     if (node1 == node2)
00584         return true;
00585 
00586     if (!node2 || !node1)
00587         return false;
00588 
00589     MFNode childrenList = node2->getChildList();
00590     for(MFNode::iterator it = childrenList.begin(); it != childrenList.end();++it)
00591         if(isADescendant(node1,static_cast<X3DTK::X3D::X3DNode*>(*it)))
00592             return true;
00593     return false;
00594 }
00595 
00596 //-----------Mouse and key board events-------------
00597 void MainScene::keyPressEvent(animal::KeyEvent *e)
00598 {
00599     for( AnimalEngines::iterator i= animalEngines.begin(); i!=animalEngines.end(); ++i )
00600         (*i)->keyPressEvent(e);
00601 }
00602 
00603 void MainScene::mouseDoubleClickEvent(animal::MouseEvent * e)
00604 {
00605     for( AnimalEngines::iterator i= animalEngines.begin(); i!=animalEngines.end(); ++i )
00606         (*i)->mouseDoubleClickEvent(e);
00607 }
00608 
00609 void MainScene::mouseMoveEvent(animal::MouseEvent * e)
00610 {
00611     for( AnimalEngines::iterator i= animalEngines.begin(); i!=animalEngines.end(); ++i )
00612         (*i)->mouseMoveEvent(e);
00613 }
00614 
00615 void MainScene::mousePressEvent(animal::MouseEvent * e)
00616 {
00617     for( AnimalEngines::iterator i= animalEngines.begin(); i!=animalEngines.end(); ++i )
00618         (*i)->mousePressEvent(e);
00619 }
00620 
00621 void MainScene::mouseReleaseEvent(animal::MouseEvent * e)
00622 {
00623     for( AnimalEngines::iterator i= animalEngines.begin(); i!=animalEngines.end(); ++i )
00624         (*i)->mouseReleaseEvent(e);
00625 }
00626 //-----------End of mouse and key board events-------------
00627 
00628 // ----------  FF: picking -----------------------------
00629 animal::ConstrainedItem* MainScene::pickPoint(float origin[3], float direction[3],
00630         float threshold )
00631 {
00632     animal::ConstrainedItem* item = 0;
00633 
00634     //std::cout<<"MainScene::pickPoint"<<std::endl;
00635     AnimalEngines::iterator e=animalEngines.begin(), eend=animalEngines.end();
00636     while( e != eend && item==0 )
00637     {
00638         //std::cout<<"MainScene::pickPoint engine" << std::endl;
00639         item = (*e)->pickPoint( origin, direction, threshold );
00640         ++e;
00641     }
00642 
00643     X3D::EngineNodes::iterator en=allEngineNodes.begin(), enend=allEngineNodes.end();
00644     while( en != enend && item==0 )
00645     {
00646         //std::cout<<"MainScene::pickPoint engine" << std::endl;
00647         item = (*en)->pickPoint( origin, direction, threshold );
00648         ++en;
00649     }
00650 /*    if(item) cout<<"MainScene::pickPoint, found !!"<<endl;
00651     else cout<<"MainScene::pickPoint, nothing !!"<<endl;*/
00652     return item;
00653 }
00654 // ----------  end FF: picking -----------------------------
00655 
00656    void MainScene::setSelectedNode( X3D::X3DBoundedObject * n )
00657    {
00658        m_selectedNode = n;
00659         renderer.setBoundedObject(m_selectedNode);
00660    }
00661 
00662 
00663 }// X3DTK

Generated on Thu Dec 23 13:52:25 2004 by doxygen 1.3.6