Core Scene Graph Data Structures in C++


SceneGraph

The SceneGraph class is implemented as a subclass of the Group node. An instance of the SceneGraph class is used to represent the root of each scene graph in memory. Each instance of the SceneGraph class can be associated with a file. The name of the file, as well as other global parameters, are stored as fields of the SceneGraph class.

class SceneGraph : public Group {
  public:
                        SceneGraph();
    virtual            ~SceneGraph();
    void                clear();
    string&             getUrl();
    void                setUrl(const string& url);
    Node*               find(const string& name);
    virtual bool        isSceneGraph() const;
    virtual string      getType()      const;
};

How to build a simple SceneGraph

Let us consider a file named "tetrahedron.wrl" containing the following text

 #VRML V2.0 utf8
 Shape {
   geometry IndexedFaceSet {
     coord Coordinate {
       point [
          1.633 -0.943 -0.667 # V0
          0.000  0.000  2.000 # V1
         -1.633 -0.943 -0.667 # V2
          0.000  1.886 -0.667 # V3
       ]
     }
     coordIndex [
       0 1 2 -1 # F0
       3 1 0 -1 # F1
       2 1 3 -1 # F2
       2 3 0 -1 # F3
     ]
   }
 }

The following code fragment, implemented as a method, can be used to build an instance of the SceneGraph class to represent the tetrahedron in the DGP2023 application.

void makeTetrahedronSceneGraph(SceneGraph& wrl) {
  // reference to existing SceneGraph received as argument may not be empty.
  wrl.clear();
  // this scene graph has a single Shape node as a child
  // create the Shape node
  Shape* shape = new Shape();
  // make the Shape node a child of the SceneGraph node
  // the method is inherited from Group
  wrl.addChild(shape);
  // since the file does not define an Appearance nod explicitly,
  // the default values must be added
  Appearance* appearance = new Appearance();
  shape->setAppearance(appearance);
  // add a default Material node so that the mesh is not rendered black
  Material* material = new Material();
  appearance->setMaterial(material);
  Color color(1.0f,0.0f,0.0f); // RED
  material->setDiffuseColor(color);
  // create an IndexedFaceSet node
  IndexedFaceSet* ifs = new IndexedFaceSet();
  shape->setGeometry(ifs);
  // get the coord field
  vector<float>& coord = ifs->getCoord();
  // create the vertex coordinates
  // V0
  coord.push_back( 1.633f);
  coord.push_back(-0.943f);
  coord.push_back(-0.667f);
  // V1
  coord.push_back( 0.000f);
  coord.push_back( 0.000f);
  coord.push_back( 2.000f);
  // V2
  coord.push_back(-1.633f);
  coord.push_back(-0.943f);
  coord.push_back(-0.667f);
  // V3
  coord.push_back( 0.000f);
  coord.push_back( 1.886f);
  coord.push_back(-0.667f);
  // get the coordIndex field
  vector<int>& coordIndex = ifs->getCoordIndex();
  // create the faces
  // F0
  coordIndex.push_back(0);
  coordIndex.push_back(1);
  coordIndex.push_back(2);
  coordIndex.push_back(-1);
  // F1
  coordIndex.push_back(3);
  coordIndex.push_back(1);
  coordIndex.push_back(0);
  coordIndex.push_back(-1);
  // F2
  coordIndex.push_back(2);
  coordIndex.push_back(1);
  coordIndex.push_back(3);
  coordIndex.push_back(-1);
  // F3
  coordIndex.push_back(2);
  coordIndex.push_back(3);
  coordIndex.push_back(0);
  coordIndex.push_back(-1);
}