TransformGroup* GroundBasedComplexModelLoader::getGroundBasedComplexModels(const SCNXArchive &scnxArchive) const {
            TransformGroup *complexModels = new TransformGroup();

            // Get list of all ground based complex models.
            vector<ComplexModel*> listOfComplexModels = scnxArchive.getListOfGroundBasedComplexModels();

            // Iterate over all ground based complex models and try to build a transform group.
            vector<ComplexModel*>::iterator jt = listOfComplexModels.begin();
            while (jt != listOfComplexModels.end()) {
                ComplexModel *cm = (*jt++);
                SharedPointer<istream> in = scnxArchive.getModelData(cm->getModelFile());
                if (in.isValid()) {
                    Node *model = NULL;

                    // Check model.
                    OBJXArchive *objxArchive = NULL;
                    if (cm->getModelFile().find(".objx") != string::npos) {
                        objxArchive = OBJXArchiveFactory::getInstance().getOBJXArchive(*in);
                    } else if (cm->getModelFile().find(".obj") != string::npos) {
                        objxArchive = OBJXArchiveFactory::getInstance().getOBJXArchiveFromPlainOBJFile(*in);
                    }

                    if (objxArchive != NULL) {
                        model = objxArchive->createTransformGroup(NodeDescriptor(cm->getName()));

                        if (model != NULL) {
                            clog << "OBJ model successfully opened." << endl;
                            clog << "  Translation: " << cm->getPosition().toString() << endl;
                            clog << "  Rotation: " << cm->getRotation().toString() << endl;

                            TransformGroup *complexModel = new TransformGroup();

                            // Translation.
                            Point3 translation(cm->getPosition());
                            complexModel->setTranslation(translation);

                            // TODO: Achsenprüfung!!
                            Point3 rotation(cm->getRotation().getX(), cm->getRotation().getZ(), cm->getRotation().getY());
                            complexModel->setRotation(rotation);

                            complexModel->addChild(model);

                            complexModels->addChild(complexModel);

                        } else {
                            clog << "OBJ model could not be opened." << endl;
                        }

                        OPENDAVINCI_CORE_DELETE_POINTER(objxArchive);
                    }
                }
            }

            return complexModels;
        }
    OpenGLGrabber::OpenGLGrabber(const KeyValueConfiguration &kvc, const ImageGrabberID &imageGrabberID, const ImageGrabberCalibration &imageGrabberCalibration, hesperia::data::environment::EgoState &egoState, core::base::FIFOQueue &obstacles) :
            ImageGrabber(imageGrabberID, imageGrabberCalibration),
            m_render(OpenGLGrabber::IN_CAR),
            m_kvc(kvc),
            m_image(),
            m_sharedMemory(),
            m_root(),
            m_car(),
            m_sensors(),
            m_mapOfObstacles(),
            m_egoState(egoState),
            m_FIFO_Obstacles(obstacles) {

        const URL urlOfSCNXFile(m_kvc.getValue<string>("global.scenario"));
        const bool SHOW_GRID = (m_kvc.getValue<uint8_t>("global.showgrid") == 1);
        if (urlOfSCNXFile.isValid()) {
            m_root = core::SharedPointer<TransformGroup>(new hesperia::threeD::TransformGroup());
            m_car = core::SharedPointer<TransformGroup>(new hesperia::threeD::TransformGroup());
            m_sensors = core::SharedPointer<TransformGroup>(new hesperia::threeD::TransformGroup());

            SCNXArchive &scnxArchive = SCNXArchiveFactory::getInstance().getSCNXArchive(urlOfSCNXFile);

            // Read scnxArchive and decorate it for getting displayed in an OpenGL scene.
            const bool SHOW_LANE_CONNECTORS = false;
            m_root->addChild(DecoratorFactory::getInstance().decorate(scnxArchive, SHOW_LANE_CONNECTORS));
            if (SHOW_GRID) {
                m_root->addChild(new XYZAxes(NodeDescriptor("XYZAxes")));
                m_root->addChild(new Grid(NodeDescriptor("Grid"), 10, 2));
            }

            string objxModel(m_kvc.getValue<string>("global.car"));
            cout << "Opening file stream to car model " << objxModel << endl;
            fstream fin(objxModel.c_str(), ios::in | ios::binary);
            if (fin.good()) {
                cout << "Loading car model" << endl;
                OBJXArchive *objxArchive = OBJXArchiveFactory::getInstance().getOBJXArchive(fin);

                fin.close();
                if (objxArchive != NULL) {

                    // Decorate objxArchive for getting displayed in an OpenGL scene.
                    m_car->addChild(objxArchive->createTransformGroup(NodeDescriptor("Car")));
                }
            }

            m_sharedMemory = core::wrapper::SharedMemoryFactory::createSharedMemory("ChaseCar", 640 * 480 * 3);

            m_image = core::SharedPointer<core::wrapper::Image>(core::wrapper::ImageFactory::getInstance().getImage(640, 480, core::wrapper::Image::BGR_24BIT, static_cast<char*>(m_sharedMemory->getSharedMemory())));

            if (m_image.isValid()) {
                cerr << "OpenGLGrabber initialized." << endl;
            }
        }
    }
            void EnvironmentViewerGLWidget::createSceneGraph() {
                m_root = new TransformGroup();
                m_stationaryElements = new TransformGroup();
                m_dynamicElements = new TransformGroup();
                m_measurements = new TransformGroup();

                m_root->addChild(m_stationaryElements);
                m_root->addChild(m_dynamicElements);
                m_root->addChild(m_measurements);

                /*******************************************************************/
                /* Stationary elements.                                            */
                /*******************************************************************/
                m_stationaryElements->addChild(new hesperia::threeD::models::XYZAxes(NodeDescriptor("XYZAxes"), 1, 10));
                m_stationaryElements->addChild(new hesperia::threeD::models::Grid(NodeDescriptor("Grid"), 10, 1));

                // Setup surroundings.
                const URL urlOfSCNXFile(getPlugIn().getKeyValueConfiguration().getValue<string>("global.scenario"));
                if (urlOfSCNXFile.isValid()) {
                    SCNXArchive &scnxArchive = SCNXArchiveFactory::getInstance().getSCNXArchive(urlOfSCNXFile);

                    // Read scnxArchive and decorate it for getting displayed in an OpenGL scene.
                    Node *surroundings = DecoratorFactory::getInstance().decorate(scnxArchive);
                    if (surroundings != NULL) {
                        surroundings->setNodeDescriptor(NodeDescriptor("Surroundings"));
                        m_stationaryElements->addChild(surroundings);
                    }
                }

                /*******************************************************************/
                /* Dynamic elements.                                               */
                /*******************************************************************/
                string objxModel(getPlugIn().getKeyValueConfiguration().getValue<string>("global.car"));
                cout << "Opening file stream to car model " << objxModel << endl;
                fstream fin(objxModel.c_str(), ios::in | ios::binary);
                if (fin.good()) {
                    cout << "Loading car model" << endl;
                    OBJXArchive *objxArchive = OBJXArchiveFactory::getInstance().getOBJXArchive(fin);

                    fin.close();
                    if (objxArchive != NULL) {
                        // Decorate objxArchive for getting displayed in an OpenGL scene.
                        m_egoStateNodeDescriptor = NodeDescriptor("EgoCar");
                        m_listOfCameraAssignableNodes.push_back(m_egoStateNodeDescriptor);
                        m_egoStateNode = objxArchive->createTransformGroup(m_egoStateNodeDescriptor);
                    }

                    if (m_egoStateNode == NULL) {
                        OPENDAVINCI_CORE_THROW_EXCEPTION(InvalidArgumentException, "Could not load car model");
                    }
                    else {
                        m_dynamicElements->addChild(m_egoStateNode);

                        // EgoCar is traceable.
                        NodeDescriptor traceableNodeDescriptor = NodeDescriptor("EgoCar (Trace)");
                        TransformGroup *traceableNode = new TransformGroup(traceableNodeDescriptor);
                        m_mapOfTraceablePositions[traceableNodeDescriptor] = traceableNode;
                        m_dynamicElements->addChild(traceableNode);
                    }
                }

                m_plannedRoute = new TransformGroup(NodeDescriptor("Planned Route"));
                m_dynamicElements->addChild(m_plannedRoute);

                m_lines = new TransformGroup(NodeDescriptor("Individual Lines"));
                m_dynamicElements->addChild(m_lines);

                /*******************************************************************/
                /* Measurements.                                                   */
                /*******************************************************************/
                // Create node for showing contoured objects.
                m_contouredObjectsNode = new TransformGroup(NodeDescriptor("Contoured Objects"));
                m_measurements->addChild(m_contouredObjectsNode);

                m_obstaclesRoot = new TransformGroup(NodeDescriptor("Obstacles"));
                m_measurements->addChild(m_obstaclesRoot);
            }