bool SplitGraphOp::traverse(Node *root)
{
    // If the root node is not a Group, make it one
    if(isLeaf(root))
    {
        NodeUnrecPtr n = makeNodeFor(root->getCore());
        
        root->setCore(Group::create());
        root->addChild(n);
    }  

    return GraphOp::traverse(root);
}
/*! Add a transform node to the OpenSG tree representing
    this <node>. Also finalizes transform animations.
 */
void
ColladaNode::appendStackedXForm(TransformationElement *transformElement, domNodeRef node)
{
    OSG_ASSERT(getGlobal()->getOptions()->getFlattenNodeXForms());

    StackedTransformUnrecPtr bottomTrans(NULL);

    if(_bottomN != NULL)
    {
        if(_bottomN->getCore()->getType().isDerivedFrom(StackedTransform::getClassType()))
        {
            bottomTrans = dynamic_cast<StackedTransform*>(_bottomN->getCore());
        }
        else
        {
            bottomTrans = StackedTransform::create();

            NodeUnrecPtr      xformN = makeNodeFor(bottomTrans);

            setName(xformN, node->getName());

            _bottomN->addChild(xformN);
        }
    }
    else
    {
        bottomTrans = StackedTransform::create();

        _bottomN =  makeNodeFor(bottomTrans);

        setName(_bottomN, node->getName());
    }
    bottomTrans->pushToTransformElements(transformElement);
    
    if(_topN == NULL)
    {
        _topN = _bottomN;
    }
}
void
ColladaNode::handleSkew(domSkew *skew)
{
    if(skew == NULL)
        return;
	
    domNodeRef        node   = getDOMElementAs<domNode>();
    Vec3f rotationAxis(skew->getValue()[1],skew->getValue()[2],skew->getValue()[3]), 
          translationAxis(skew->getValue()[4],skew->getValue()[5],skew->getValue()[6]);
    Real32 angle(skew->getValue()[0]);

    if(getGlobal()->getOptions()->getFlattenNodeXForms())
    {
        SkewTransformationElementUnrecPtr SkewElement = SkewTransformationElement::create();
        SkewElement->setRotationAxis(rotationAxis);
        SkewElement->setTranslationAxis(translationAxis);
        SkewElement->setAngle(angle);
        setName(SkewElement, skew->getSid());

        appendStackedXForm(SkewElement, node);
    }
    else
    {

        TransformUnrecPtr xform = Transform::create();
	    NodeUnrecPtr      xformN = makeNodeFor(xform);

        Matrix skewMatrix;
        MatrixSkew(skewMatrix,rotationAxis, translationAxis, angle);

	    xform->setMatrix(skewMatrix);

	     if(getGlobal()->getOptions()->getCreateNameAttachments() == true && 
           node->getName()                                       != NULL   )
        {
            std::string nodeName = node->getName();

            if(skew->getSid() != NULL && 
			    getGlobal()->getOptions()->getFlattenNodeXForms() == false)
            {
                nodeName.append("."                );
                nodeName.append(skew->getSid());
            }

            setName(xformN, nodeName);
        }

        appendXForm(xformN);
    }

}
void
ColladaNode::handleRotate(domRotate *rotate)
{
    if(rotate == NULL)
        return;

    domNodeRef        node   = getDOMElementAs<domNode>();

    Vec3f axis(rotate->getValue()[0], rotate->getValue()[1], rotate->getValue()[2]);
    Real32 angle(rotate->getValue()[3]);

    if(getGlobal()->getOptions()->getFlattenNodeXForms())
    {
        RotationTransformationElementUnrecPtr RotationElement = RotationTransformationElement::create();
        RotationElement->setAxis(axis);
        RotationElement->setAngle(angle);
        setName(RotationElement, rotate->getSid());

        appendStackedXForm(RotationElement, node);

	    if(getGlobal()->editAnimationMap()[rotate] != NULL) 
	    {
            SLOG << "Found Rotation Animation" << std::endl;
		    getGlobal()->editAnimationMap()[rotate]->getAnimation()->setAnimatedField(RotationElement,std::string("Angle"));
	    }
    }
    else
    {
        TransformUnrecPtr xform = Transform::create();
        NodeUnrecPtr      xformN = makeNodeFor(xform);
        
        xform->editMatrix().setRotate(Quaternion(axis, osgDegree2Rad(angle)));

        if(getGlobal()->getOptions()->getCreateNameAttachments() == true && 
           node->getName()                                       != NULL   )
        {
            std::string nodeName = node->getName();

            if(rotate->getSid() != NULL&& 
			    getGlobal()->getOptions()->getFlattenNodeXForms() == false)
            {
                nodeName.append("."             );
                nodeName.append(rotate->getSid());
            }

            setName(xformN, nodeName);
        }

        appendXForm(xformN);
    }
}
void
ColladaNode::handleLookAt(domLookat *lookat)
{
    if(lookat == NULL)
        return;
	
    domNodeRef        node   = getDOMElementAs<domNode>();
    Pnt3f eyePosition(lookat->getValue()[0],lookat->getValue()[1],lookat->getValue()[2]), 
          lookAtPoint(lookat->getValue()[3],lookat->getValue()[4],lookat->getValue()[5]);
    Vec3f upDirection(lookat->getValue()[7],lookat->getValue()[8],lookat->getValue()[9]);

    if(getGlobal()->getOptions()->getFlattenNodeXForms())
    {
        LookAtTransformationElementUnrecPtr LookAtElement = LookAtTransformationElement::create();
        LookAtElement->setEyePosition(eyePosition);
        LookAtElement->setLookAtPosition(lookAtPoint);
        LookAtElement->setUpDirection(upDirection);
        setName(LookAtElement, lookat->getSid());

        appendStackedXForm(LookAtElement, node);
    }
    else
    {

        TransformUnrecPtr xform = Transform::create();
	    NodeUnrecPtr      xformN = makeNodeFor(xform);

        Matrix lookAtMatrix;
        MatrixLookAt(lookAtMatrix,eyePosition, lookAtPoint, upDirection);

	    xform->setMatrix(lookAtMatrix);

	     if(getGlobal()->getOptions()->getCreateNameAttachments() == true && 
           node->getName()                                       != NULL   )
        {
            std::string nodeName = node->getName();

            if(lookat->getSid() != NULL && 
			    getGlobal()->getOptions()->getFlattenNodeXForms() == false)
            {
                nodeName.append("."                );
                nodeName.append(lookat->getSid());
            }

            setName(xformN, nodeName);
        }

        appendXForm(xformN);
    }
}
void
ColladaNode::handleTranslate(domTranslate *translate)
{
    if(translate == NULL)
        return;

    domNodeRef        node   = getDOMElementAs<domNode>();
    Vec3f translation(translate->getValue()[0], translate->getValue()[1], translate->getValue()[2]);

    if(getGlobal()->getOptions()->getFlattenNodeXForms())
    {
        TranslationTransformationElementUnrecPtr TranslateElement = TranslationTransformationElement::create();
        TranslateElement->setTranslation(translation);
        setName(TranslateElement, translate->getSid());

        appendStackedXForm(TranslateElement, node);

	    if(getGlobal()->editAnimationMap()[translate] != NULL) 
	    {
				SLOG << "Found Translation Animation" << std::endl;
				getGlobal()->editAnimationMap()[translate]->getAnimation()->setAnimatedField(TranslateElement,std::string("Translation")) ;
	    }
    }
    else
    {

        TransformUnrecPtr xform = Transform::create();
        NodeUnrecPtr      xformN = makeNodeFor(xform);

        xform->editMatrix().setTranslate(translation);

        if(getGlobal()->getOptions()->getCreateNameAttachments() == true && 
           node->getName()                                       != NULL   )
        {
            std::string nodeName = node->getName();

            if(translate->getSid() != NULL && 
			    getGlobal()->getOptions()->getFlattenNodeXForms() == false)
            {
                nodeName.append("."                );
                nodeName.append(translate->getSid());
            }

            setName(xformN, nodeName);
        }

        appendXForm(xformN);
    }
}
/* virtual */
NodeTransitPtr OFMatrixRecord::convert(Node *pNode)
{
    NodeUnrecPtr returnValue(NULL);

    if(pNode != NULL)
    {
        TransformUnrecPtr pXform = Transform::create();
        pXform->setMatrix(matrix);

        returnValue = makeNodeFor(pXform);
        returnValue->addChild(pNode);
    }

    return NodeTransitPtr(returnValue);
}
void
ColladaNode::handleMatrix(domMatrix *matrix)
{
    if(matrix == NULL)
        return;

    domNodeRef        node   = getDOMElementAs<domNode>();

    TransformUnrecPtr xform  = Transform::create();
    NodeUnrecPtr      xformN = makeNodeFor(xform);

    Matrix m(matrix->getValue()[0],      // rVal00
             matrix->getValue()[1],      // rVal10
             matrix->getValue()[2],      // rVal20
             matrix->getValue()[3],      // rVal30
             matrix->getValue()[4],      // rVal01
             matrix->getValue()[5],      // rVal11
             matrix->getValue()[6],      // rVal21
             matrix->getValue()[7],      // rVal31
             matrix->getValue()[8],      // rVal02
             matrix->getValue()[9],      // rVal12
             matrix->getValue()[10],     // rVal22
             matrix->getValue()[11],     // rVal32
             matrix->getValue()[12],     // rVal03
             matrix->getValue()[13],     // rVal13
             matrix->getValue()[14],     // rVal23
             matrix->getValue()[15] );   // rVal33
    
    xform->setMatrix(m);

    if(getGlobal()->getOptions()->getCreateNameAttachments() == true && 
       node->getName()                                       != NULL   )
    {
        std::string nodeName = node->getName();

        if(matrix->getSid() != NULL)
        {
            nodeName.append("."             );
            nodeName.append(matrix->getSid());
        }

        setName(xformN, nodeName);
    }

    appendXForm(xformN);
}
Exemple #9
0
//
// create an arbitrarly complex render scene
//
static NodeTransitPtr createStaticScene()
{
    NodeUnrecPtr root = makeCoredNode<Group>();

    typedef boost::mt19937 base_generator_type;
    static base_generator_type generator(0);
    static boost::uniform_01<float> value;
    static boost::variate_generator< base_generator_type, boost::uniform_01<float> > die(generator, value);

    for (int i = 0; i < max_tori; ++i) {
        NodeUnrecPtr scene = makeTorus(.5, 2, 32, 32);

        TransformUnrecPtr transformCore = Transform::create();
        Matrix mat;

        mat.setIdentity();

        float x = 500.f * die();
        float y = 500.f * die();
        float z = 500.f * die();

        float e1 = die();
        float e2 = die();
        float e3 = die();

        Vec3f v(e1,e2,e3);
        v.normalize();

        float a = TwoPi * die();

        Quaternion q(v, a);

        mat.setTranslate(x,y,z);
        mat.setRotate(q);

        transformCore->setMatrix(mat);

        NodeUnrecPtr trafo = makeNodeFor(transformCore);

        trafo->addChild(scene);

        root->addChild(trafo);
    }
    
    return NodeTransitPtr(root);
}
NodeTransitPtr buildScene(void)
{
    NodeUnrecPtr geoN = makeBox(1.f, 1.f, 1.f, 1, 1, 1);

    ComponentTransformUnrecPtr xform  = ComponentTransform::create();
    NodeUnrecPtr               xformN = makeNodeFor(xform);
    
    setTargetId(xform, "xform0");

    gXForm = xform;

    NodeUnrecPtr      groupN = makeCoredNode<Group>();

    xformN->addChild(geoN  );
    groupN->addChild(xformN);

    return NodeTransitPtr(groupN);
}
NodeTransitPtr OctreeVisualization::createNodeDistanceLOD(OctreePtr,
                                                          const Octree::OTNodePtr node,
                                                          Material* GeoMaterial,
                                                          const Node* BaseGeo,
                                                          Real32 Range
                                                         )
{
    NodeRecPtr box = deepCloneTree(BaseGeo);
    dynamic_cast<Geometry*>(box->getCore())->setMaterial(GeoMaterial);

    //DistanceLOD node
    DistanceLODRecPtr LOD = DistanceLOD::create();
    LOD->editMFRange()->push_back(10.0);

    NodeRecPtr LODNode = makeNodeFor(LOD);
    LODNode->addChild(box);
    LODNode->addChild(makeCoredNode<Group>());

    Matrix m;
    TransformRecPtr box_trans;
    NodeRecPtr trans_node = makeCoredNode<Transform>(&box_trans);
    Pnt3f Center;
    node->getVolume().getCenter(Center);
    m.setTranslate(Center.x(),
                   Center.y(),
                   Center.z());

    const Real32 Offset(0.0f);
    Vec3f Size;
    node->getVolume().getSize(Size);
    m.setScale(Size.x()-(Size.x()*Offset),
               Size.y()-(Size.y()*Offset),
               Size.z()-(Size.z()*Offset));
    box_trans->setMatrix(m);
    trans_node->addChild(LODNode);

    return NodeTransitPtr(trans_node);
}
OSG_BEGIN_NAMESPACE

NodeTransitPtr OctreeVisualization::createOctreeVisualization(OctreePtr tree,
                                                              Int32 MaxDepth,
                                                              bool filledGeometry,
                                                              bool onlyLeaf)
{
    OTNodeGeometryCreateFunc GeoCreateFunc;
    OTNodeMaterialCreateFunc MatCreateFunc;    
    OTNodeIsVisibleFunc IsVisibleFunc;

    IsVisibleFunc = boost::bind(&OctreeVisualization::isNodeLeaf,_1, _2,
                                false);

    NodeRecPtr VisRootNode = makeCoredNode<Group>();

    if(filledGeometry)
    {
        NodeRecPtr BaseBox = makeBox(1.0f,1.0f,1.0f,
                                     1,   1,   1);

        GeoCreateFunc = boost::bind(&OctreeVisualization::createNodeDistanceLOD,_1, _2, _3, BaseBox.get(), 10.0f);

        BlendChunkRecPtr DefaultBlendChunk = BlendChunk::create();
        DefaultBlendChunk->setSrcFactor(GL_SRC_ALPHA);
        DefaultBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);

        PolygonChunkRecPtr    DefaultPolygonChunk = PolygonChunk::create();
        DefaultPolygonChunk->setCullFace(GL_BACK);
        
        MatCreateFunc = boost::bind(&OctreeVisualization::createMatFilled,_1, _2,
                                    Color3f(0.0f,1.0f,0.0f),
                                    Color3f(1.0f,0.0f,0.0f),
                                    0.15f,
                                    DefaultBlendChunk.get(),
                                    DefaultPolygonChunk.get());

        createOctreeVisualizationRec(tree,
                                     tree->getRoot(),
                                     VisRootNode,
                                     osgMin<UInt32>(tree->getDepth(),MaxDepth),
                                     GeoCreateFunc,
                                     MatCreateFunc,
                                     IsVisibleFunc);
    }
    else
    {
        //*******************Create the Geometry for the box
        GeoUInt8PropertyRecPtr type = GeoUInt8Property::create();
        //Volume bound box
        type->push_back(GL_LINE_STRIP);
        type->push_back(GL_LINES);

        GeoUInt32PropertyRefPtr lens = GeoUInt32Property::create();
        //Volume bound box
        lens->push_back(10);
        lens->push_back(6);

        GeoUInt32PropertyRefPtr index = GeoUInt32Property::create();

        //Volume bound box
        index->push_back(0);
        index->push_back(1);
        index->push_back(3);
        index->push_back(2);
        index->push_back(0);
        index->push_back(4);
        index->push_back(5);
        index->push_back(7);
        index->push_back(6);
        index->push_back(4);

        index->push_back(1);
        index->push_back(5);
        index->push_back(2);
        index->push_back(6);
        index->push_back(3);
        index->push_back(7);

        GeoPnt3fPropertyRefPtr highlightPoints = GeoPnt3fProperty::create();
        //Volume bound box
        highlightPoints->push_back(Pnt3f(-1, -1, -1));
        highlightPoints->push_back(Pnt3f( 1, -1, -1));
        highlightPoints->push_back(Pnt3f(-1,  1, -1));
        highlightPoints->push_back(Pnt3f( 1,  1, -1));
        highlightPoints->push_back(Pnt3f(-1, -1,  1));
        highlightPoints->push_back(Pnt3f( 1, -1,  1));
        highlightPoints->push_back(Pnt3f(-1,  1,  1));
        highlightPoints->push_back(Pnt3f( 1,  1,  1));

        //Colors
        Color4f BoundBoxColor(1.0f,1.0f,1.0,1.00f);

        GeoVec4fPropertyRefPtr highlightColors = GeoVec4fProperty::create();
        //Volume bound box
        highlightColors->push_back(BoundBoxColor);
        highlightColors->push_back(BoundBoxColor);
        highlightColors->push_back(BoundBoxColor);
        highlightColors->push_back(BoundBoxColor);
        highlightColors->push_back(BoundBoxColor);
        highlightColors->push_back(BoundBoxColor);
        highlightColors->push_back(BoundBoxColor);
        highlightColors->push_back(BoundBoxColor);

        GeometryRecPtr BoxGeo =Geometry::create();
        BoxGeo->setTypes     (type);
        BoxGeo->setLengths   (lens);
        BoxGeo->setIndices   (index);
        BoxGeo->setPositions (highlightPoints);
        BoxGeo->setColors    (highlightColors);

        //Highlight Bound Box Node
        NodeRecPtr BaseBox = makeNodeFor(BoxGeo);
        GeoCreateFunc =
            boost::bind(&OctreeVisualization::createNodeDistanceLOD,_1, _2, _3,
                        BaseBox.get(), 10.0f);

        //*******************Create the Geometry for the highlight


        BlendChunkRecPtr DefaultBlendChunk = BlendChunk::create();
        DefaultBlendChunk->setSrcFactor(GL_SRC_ALPHA);
        DefaultBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);

        LineChunkRecPtr    DefaultLineChunk = LineChunk::create();
        DefaultLineChunk->setSmooth(true);

        MatCreateFunc = boost::bind(&OctreeVisualization::createMatLine,_1, _2,
                                    Color3f(1.0f,0.0f,0.0f),
                                    Color3f(0.0f,0.0f,1.0f),
                                    0.55f,
                                    DefaultBlendChunk.get(),
                                    DefaultLineChunk.get());

        createOctreeVisualizationRec(tree,
                                     tree->getRoot(),
                                     VisRootNode,
                                     osgMin<UInt32>(tree->getDepth(),MaxDepth),
                                     GeoCreateFunc,
                                     MatCreateFunc,
                                     IsVisibleFunc);
    }


    return NodeTransitPtr(VisRootNode);
}
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

    // Set up Window
    TutorialWindow = createNativeWindow();
    TutorialWindow->initWindow();

    TutorialWindow->setDisplayCallback(display);
    TutorialWindow->setReshapeCallback(reshape);

    //Add Window Listener
    TutorialKeyListener TheKeyListener;
    TutorialWindow->addKeyListener(&TheKeyListener);
    TutorialMouseListener TheTutorialMouseListener;
    TutorialMouseMotionListener TheTutorialMouseMotionListener;
    TutorialWindow->addMouseListener(&TheTutorialMouseListener);
    TutorialWindow->addMouseMotionListener(&TheTutorialMouseMotionListener);

    // Create the SimpleSceneManager helper
    mgr = new SimpleSceneManager;

    // Tell the Manager what to manage
    mgr->setWindow(TutorialWindow);
	
	//SkeletonDrawer System Material
	LineChunkUnrecPtr ExampleLineChunk = LineChunk::create();
    ExampleLineChunk->setWidth(4.0f);
    ExampleLineChunk->setSmooth(true);

	BlendChunkUnrecPtr ExampleBlendChunk = BlendChunk::create();
    ExampleBlendChunk->setSrcFactor(GL_SRC_ALPHA);
    ExampleBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);

	MaterialChunkUnrecPtr ExampleMaterialChunk = MaterialChunk::create();
    ExampleMaterialChunk->setAmbient(Color4f(1.0f,1.0f,1.0f,1.0f));
    ExampleMaterialChunk->setDiffuse(Color4f(0.0f,0.0f,0.0f,1.0f));
    ExampleMaterialChunk->setSpecular(Color4f(0.0f,0.0f,0.0f,1.0f));

	ChunkMaterialUnrecPtr ExampleMaterial = ChunkMaterial::create();
    ExampleMaterial->addChunk(ExampleLineChunk);
    ExampleMaterial->addChunk(ExampleMaterialChunk);
    ExampleMaterial->addChunk(ExampleBlendChunk);

    GeometryRefPtr SphereGeometry = makeSphereGeo(2, 0.25f);
    GeometryRefPtr BoxGeometry = makeBoxGeo(0.5f,0.5f,0.5f,1,1,1);

    //Skeleton
    SkeletonBlendedGeometryUnrecPtr ExampleSkeleton = SkeletonBlendedGeometry::create();

    //Joint
	TransformRecPtr ExampleRootJoint = Transform::create();

    NodeRecPtr ExampleRootJointNode = makeNodeFor(ExampleRootJoint);

    //Add this joint to the skeleton
    ExampleSkeleton->pushToJoints(ExampleRootJointNode, Matrix());

    NodeRecPtr TempRootJointNode = ExampleRootJointNode;
    NodeRefPtr GeoNode = makeNodeFor(BoxGeometry);
    TempRootJointNode->addChild(GeoNode);

	Matrix TempMat;
	//Create a set of randomly placed child joints
	for (Real32 i = 0.0f; i < 5.0f; ++i)
	{
		TransformRecPtr ExampleChildJoint = Transform::create();
		NodeRecPtr ExampleChildJointNode = makeNodeFor(ExampleChildJoint);

        GeoNode = makeNodeFor(SphereGeometry);
        ExampleChildJointNode->addChild(GeoNode);

		//TempMat.setTranslate(RandomPoolManager::getRandomReal32(0.0, 10.0f), RandomPoolManager::getRandomReal32(0.0f, 10.0f), RandomPoolManager::getRandomReal32(0.0f, 10.0f));
        switch((static_cast<UInt32>(i) % 3))
        {
            case 0:
                TempMat.setTranslate(2.0f,0.0f,0.0f);
                break;
            case 1:
                TempMat.setTranslate(0.0f,2.0f,0.0f);
                break;
            case 2:
                TempMat.setTranslate(0.0f,0.0f,2.0f);
                break;
        }
		
		//Set bind and current transformations to TempMat (calculated above)
        ExampleChildJoint->setMatrix(TempMat);

		//Add ExampleChildJoint as a child to the previous joint	
        TempRootJointNode->addChild(ExampleChildJointNode);//add a Child to the root joint

		//ExampleChildJoint will be the next parent joint
		TempRootJointNode = ExampleChildJointNode;
        
        //Add this joint to the skeleton
        Matrix InvBind(TempRootJointNode->getToWorld());
        InvBind.invert();
        ExampleSkeleton->pushToJoints(ExampleChildJointNode, InvBind);
	}


    //SkeletonDrawer
    SkeletonDrawableUnrecPtr ExampleSkeletonDrawable = SkeletonDrawable::create();
    ExampleSkeletonDrawable->setSkeleton(ExampleSkeleton);
    ExampleSkeletonDrawable->setMaterial(ExampleMaterial);
	
	//Skeleton Particle System Node
	NodeUnrecPtr SkeletonNode = Node::create();
    SkeletonNode->setCore(ExampleSkeletonDrawable);


    // Make Main Scene Node and add the Torus
    NodeUnrecPtr scene = Node::create();
    scene->setCore(Group::create());
    scene->addChild(SkeletonNode);
    scene->addChild(ExampleRootJointNode);

    mgr->setRoot(scene);

    // Show the whole Scene
    mgr->showAll();


    //Open Window
    Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f);
    Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5);
    TutorialWindow->openWindow(WinPos,
            WinSize,
            "10SkeletonDrawer");

    //Main Loop
    TutorialWindow->mainLoop();

    osgExit();

    return 0;
}
Exemple #14
0
//
// FBO solution
//
static void writeHiResScreenShotFBO(const char* name, UInt32 width, UInt32 height)
{
    size_t num_ports = win->getMFPort()->size();
    if (num_ports == 0)
        return;
    //
    // calc image dimensions
    //
    UInt32 winWidth  = win->getWidth();
    UInt32 winHeight = win->getHeight();

    if (width  < winWidth ) width  = winWidth;
    if (height < winHeight) height = winHeight;

    Real32 a = Real32(winWidth) / Real32(winHeight);
    width = UInt32(a*height);

    //
    // output stream for writing the final image
    //
    std::ofstream stream(name, std::ios::binary);
    if (stream.good() == false)
        return;

    //
    // Setup the FBO
    //
    FrameBufferObjectUnrecPtr fbo = FrameBufferObject::create();
    //
    // We use two render buffers. One for the color buffer and one for the depth and
    // stencil buffer. This example does not take credit of the stencil buffer. There-
    // fore a depth buffer would suffice. However, the use of the combined depth and
    // stencil buffer is useful in other contextes and hence used.
    //
    RenderBufferUnrecPtr colBuf = RenderBuffer::create();
    RenderBufferUnrecPtr  dsBuf = RenderBuffer::create();
    //
    // As we would like to read back the FBO color buffer, we must provide a fitting
    // image.
    //
    ImageUnrecPtr buffer_image = Image::create();
    buffer_image->set(Image::OSG_RGBA_PF, winWidth, winHeight);
    colBuf->setImage(buffer_image);
    //
    // We must setup the internal image formats of the two render buffers accordingly.
    //
    colBuf->setInternalFormat(GL_RGBA);
    dsBuf ->setInternalFormat(GL_DEPTH24_STENCIL8_EXT);
    //
    // we must inform the FBO about the actual used color render buffers.
    //
    fbo->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);
    //
    // The FBO takes responsibility of the render buffers. Notice, that the shared
    // depth/stencil buffer is provided twice. As the depth render buffer and as the
    // stencil render buffer.
    //
    fbo->setColorAttachment  (colBuf, 0);
    fbo->setDepthAttachment  (dsBuf);
    fbo->setStencilAttachment(dsBuf);
    //
    // Also the FBO must be sized correctly.
    //
    fbo->setWidth (winWidth );
    fbo->setHeight(winHeight);
    //
    // In order to read the color buffer back next two statements are necessary.
    //
    fbo->setPostProcessOnDeactivate(true);
    fbo->getColorAttachments(0)->setReadBack(true);

    //
    // We tile the final image and render each tile with the screen resolution
    // into the FBO. The more tiles we use the bigger the resolution of the
    // final image gets with respect to a provided measure of length.
    //
    typedef boost::tuple<TileCameraDecoratorUnrecPtr, bool, SimpleStageUnrecPtr, ViewportUnrecPtr> TupleT;
    std::vector<TupleT> decorators;
    decorators.resize(num_ports);

    //
    // Remember the stage viewports for later cleanup
    //
    std::stack<ViewportUnrecPtr> stage_viewports;

    //
    // Setup the tile camera decorators for each viewport of the window and
    // disable the tile property of tileable viewport backgrounds.
    //
    for (size_t i = 0; i < num_ports; ++i) {
        Viewport* vp = win->getPort(i);

        TileCameraDecoratorUnrecPtr decorator = TileCameraDecorator::create();

        decorator->setFullSize (width, height);
        decorator->setDecoratee(vp->getCamera());

        vp->setCamera(decorator);

        bool bTiled = false;
        TileableBackground* tbg = dynamic_cast<TileableBackground*>(vp->getBackground());
        if (tbg) {
            bTiled = tbg->getTile();
            tbg->setTile(false);
        }

        //
        // The scene manager root node does not provide the illumination of the
        // scene. This is governed internally by the manager. However, to take
        // credit of the illumination we scan to the final parent of the scene
        // graph.
        //
        Node* internalRoot = rootNode(mgr->getRoot());
        //
        // We would like to render the scene but won't detach it from its parent.
        // The VisitSubTree allows just that.
        //
        VisitSubTreeUnrecPtr visitor = VisitSubTree::create();
        visitor->setSubTreeRoot(internalRoot);
        NodeUnrecPtr visit_node = makeNodeFor(visitor);
        //
        // We clone the camera of the first viewport and do not swap the buffer on later
        // rendering. This way the image generation process is not noticable in the
        // window.
        //
        CameraUnrecPtr camera = dynamic_pointer_cast<Camera>(vp->getCamera()->shallowCopy());
        //
        // The stage object does provide a render target for the frame buffer attachment.
        // SimpleStage has a camera, a background and the left, right, top, bottom
        // fields to let you restrict rendering to a sub-rectangle of your FBO, i.e.
        // they give you a viewport.
        //
        SimpleStageUnrecPtr stage = SimpleStage::create();
        stage->setRenderTarget(fbo);
        stage->setCamera      (decorator);
        stage->setBackground  (vp->getBackground());
        //
        // Give the stage core a place to live
        //
        NodeUnrecPtr stage_node = makeNodeFor(stage);
        stage_node->addChild(visit_node);
        //
        //   root
        //    |
        //    +- SimpleStage
        //            |
        //            +- VisitSubTree -> ApplicationScene
        //
        NodeUnrecPtr root = makeCoredNode<Group>();
        root->addChild(stage_node);
        //
        // Give the root node a place to live, i.e. create a passive
        // viewport and add it to the window.
        //
        ViewportUnrecPtr stage_viewport = PassiveViewport::create();
        stage_viewport->setRoot      (root);
        stage_viewport->setBackground(vp->getBackground());
        stage_viewport->setCamera    (camera);

        win->addPort(stage_viewport);

        //
        // remember the decorator, the background tile prop setting and the stage setup
        //
        decorators[i] = boost::make_tuple(decorator, bTiled, stage, stage_viewport);
    }

    //
    // We write the image in simple ppm format. This one starts with a description
    // header which we output once on first write.
    //
    bool write_header = true;

    //
    // Calc the max y start position (width). We process the tiles from bottom
    // up and from left tp right as determined by the image format.
    //
    UInt32 yPosLast = 0;
    for (; yPosLast < height-winHeight; yPosLast += winHeight);

    //
    // Process from bottom to top
    //
    for (Int32 yPos = yPosLast; yPos >= 0; yPos -= winHeight)
    {
        UInt32 ySize = std::min(winHeight, height - yPos);

        //
        // Collect the tile images for each row, i.e. we write the
        // image in row manner to disk. This way the main memory is
        // only moderately stressed.
        //
        std::vector<ImageUnrecPtr> vecColImages;

        //
        // Process from left to right
        //
        for (UInt32 xPos = 0; xPos < width; xPos += winWidth)
        {
            UInt32 xSize = std::min(winWidth, width - xPos);
            //
            // The current tile image
            //
            ImageUnrecPtr col_image = Image::create();
            col_image->set(Image::OSG_RGBA_PF, xSize, ySize);
            //
            // Adapt the tile camera decorator boxes to the current tile
            //
            for (size_t i = 0; i < num_ports; ++i)
            {
                //
                // this tile does not fill the whole FBO - adjust to only render
                // to a part of it
                //
                decorators[i].get<2>()->setLeft  (0.f);
                decorators[i].get<2>()->setRight (xSize / float(winWidth));
                decorators[i].get<2>()->setBottom(0.f);
                decorators[i].get<2>()->setTop   (ySize / float(winHeight));

                TileCameraDecorator* decorator = decorators[i].get<0>();

                decorator->setSize( xPos / float(width),
                                    yPos / float(height),
                          (xPos + xSize) / float(width),
                          (yPos + ySize) / float(height) );

            }
            //
            // render the tile
            //
            mgr->update();
            win->renderNoFinish(mgr->getRenderAction());
            win->frameExit();
            win->deactivate ();

            //
            // Copy the image into the tile image stored for later processing
            //
            if(fbo)
            {
                RenderBuffer* grabber = dynamic_cast<RenderBuffer*>(fbo->getColorAttachments(0));

                if(grabber)
                {
                    grabber->getImage()->subImage(0, 0, 0, xSize, ySize, 1, col_image);
                }
            }

            vecColImages.push_back(col_image);
        }

        //
        // Write the image format header once
        //
        if (write_header) {
            write_header = false;
            if (!writePNMImagesHeader(vecColImages, width, height, stream)) break;
        }
        //
        // Write the current column
        //
        if (!writePNMImagesData(vecColImages, stream)) break;
        //
        // Forget the current column images
        //
        vecColImages.clear();
    }

    //
    // restore window and cleanup
    //
    for (size_t i = 0; i < num_ports; ++i) {
        win->subPortByObj(decorators[i].get<3>());

        Viewport* vp = win->getPort(i);
        vp->setCamera(decorators[i].get<0>()->getDecoratee());
        vp->setSize(0, 0, 1, 1);

        TileableBackground* tbg = dynamic_cast<TileableBackground*>(vp->getBackground());
        if (tbg)
            tbg->setTile(decorators[i].get<1>());
    }
}
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);
    
    {
        // Set up Window
        WindowEventProducerRecPtr TutorialWindow = createNativeWindow();
        TutorialWindow->initWindow();

        // Create the SimpleSceneManager helper
        SimpleSceneManager sceneManager;
        TutorialWindow->setDisplayCallback(boost::bind(display, &sceneManager));
        TutorialWindow->setReshapeCallback(boost::bind(reshape, _1, &sceneManager));

        // Tell the Manager what to manage
        sceneManager.setWindow(TutorialWindow);

        TutorialWindow->connectKeyTyped(boost::bind(keyTyped, _1));
        TutorialWindow->connectMousePressed(boost::bind(mousePressed, _1, &sceneManager));
        TutorialWindow->connectMouseReleased(boost::bind(mouseReleased, _1, &sceneManager));
        TutorialWindow->connectMouseDragged(boost::bind(mouseDragged, _1, &sceneManager));
        TutorialWindow->connectMouseWheelMoved(boost::bind(mouseWheelMoved, _1, &sceneManager));

        BoostPath EffectFilePath("./Data/goochyPt.cgfx");
        if(argc >= 2)
        {
            EffectFilePath = BoostPath(argv[1]);
            if(!boost::filesystem::exists(EffectFilePath))
            {
                std::cerr << "Could not load file: "<< EffectFilePath.string()
                          << ", because no such files exists."<< std::endl;
                EffectFilePath = BoostPath("./Data/goochyPt.cgfx");
            }
        }

        //Make the CgFX Material
        CgFXMaterialRecPtr ExampleMaterial = CgFXMaterial::create();
        ExampleMaterial->setEffectFile(EffectFilePath.string());

        // Make Torus Node (creates Torus in background of scene)
        GeometryRefPtr TorusGeometry = makeTorusGeo(.5, 2, 16, 16);
        //GeometryRefPtr TorusGeometry = makeBoxGeo(1.0,1.0,1.0,1,1,1);
        TorusGeometry->setMaterial(ExampleMaterial);
        TorusGeometry->setDlistCache(false);

        NodeRefPtr TorusGeometryNode = makeNodeFor(TorusGeometry);

        // Make Main Scene Node and add the Torus
        NodeRefPtr scene = OSG::Node::create();
        scene->setCore(OSG::Group::create());
        scene->addChild(TorusGeometryNode);

        sceneManager.setRoot(scene);

        //Create the Documentation Foreground and add it to the viewport
        SimpleScreenDoc TheSimpleScreenDoc(&sceneManager, TutorialWindow);

        // Show the whole Scene
        sceneManager.showAll();

        //Open Window
        Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f);
        Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5);
        TutorialWindow->openWindow(WinPos,
                                   WinSize,
                                   "04CgFXMaterial");

        commitChanges();

        //Enter main Loop
        TutorialWindow->mainLoop();
    }

    osgExit();

    return 0;
}
OSG_USING_NAMESPACE

void renderSceneToTexture(Scene* const TheScene,
                          TextureObjChunk* const ColorTexture,
                          Window* const TheWindow,
                          RenderAction* TheRenderAction)
{
    //Create an FBO to render the Scene's Viewport(s) into

    FrameBufferObjectRecPtr SceneFBO         = FrameBufferObject::create();
    TextureBufferRecPtr     FBOTextureBuffer = TextureBuffer    ::create();
    RenderBufferRecPtr      FBODepthBuffer   = RenderBuffer     ::create();


    //Attache the Texture to the TexureBuffer
    FBOTextureBuffer->setTexture(ColorTexture);

    // add a depth attachment, otherwise there is no depth buffer when
    // rendering to the FBO
    FBODepthBuffer->setInternalFormat(GL_DEPTH_COMPONENT24);

    // make the fbo render to the texture
    SceneFBO->setColorAttachment(FBOTextureBuffer,   0);
    SceneFBO->setDepthAttachment(FBODepthBuffer   );
    SceneFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);
    SceneFBO->setWidth (FBOTextureBuffer->getTexture()->getImage()->getWidth() );
    SceneFBO->setHeight(FBOTextureBuffer->getTexture()->getImage()->getHeight());


    /*
        Next we set up a Stage, which renders the subtree below it to its
        render target (the FBO from above).
    */

    SimpleStageRefPtr SceneStage     = SimpleStage::create();
    NodeRefPtr        SceneStageNode = makeNodeFor(SceneStage);

    ViewportRecPtr SceneViewport(TheScene->getPrimaryViewport());
    SceneStage->setRenderTarget(SceneFBO);
    SceneStage->setLeft(SceneViewport->getLeft());
    SceneStage->setRight(SceneViewport->getRight());
    SceneStage->setTop(SceneViewport->getTop());
    SceneStage->setBottom(SceneViewport->getBottom());
    SceneStage->setCamera(SceneViewport->getCamera());
    SceneStage->setBackground(SceneViewport->getBackground());

    for(UInt32 i(0) ; i<SceneViewport->getMFForegrounds()->size() ; ++i)
    {
        SceneStage->pushToForegrounds(SceneViewport->getForegrounds(i));
    }

    SceneStageNode->addChild(SceneViewport->getRoot());

    NodeRecPtr ThumbRootNode = makeCoredNode<Group>();
    ThumbRootNode->addChild(SceneStageNode);

    CameraRecPtr ThumbCamera = MatrixCamera::create();
    ThumbCamera->setBeacon(ThumbRootNode);

    BackgroundRecPtr ThumbBackground = PassiveBackground::create();

    //Create a dummy Viewport for attaching to the window
    ViewportRecPtr ThumbViewport = Viewport::create();
    ThumbViewport->setBackground(ThumbBackground);
    ThumbViewport->setRoot(ThumbRootNode);
    ThumbViewport->setCamera(ThumbCamera);

    //Get all of the original TravMasks of the Viewports on the window
    //Set all of the TravMasks of the Viewports on the window to 0
    std::vector<UInt32> OrigTravMasks;
    OrigTravMasks.reserve(TheWindow->getMFPort()->size());
    for(UInt32 i(0) ; i<TheWindow->getMFPort()->size() ; ++i)
    {
        OrigTravMasks.push_back(TheWindow->getPort(i)->getTravMask());

        TheWindow->getPort(i)->setTravMask(0);
    }

    //Attach the Viewport to the Window
    TheWindow->addPort(ThumbViewport);

    //Draw the window
    TheWindow->render(TheRenderAction);

    //Detach the Viewport from the Window
    TheWindow->subPortByObj(ThumbViewport);

    //Reset all of the original TravMasks of the Viewports on the window
    for(UInt32 i(0) ; i<TheWindow->getMFPort()->size() ; ++i)
    {
        TheWindow->getPort(i)->setTravMask(OrigTravMasks[i]);
    }
}
Node *
ColladaNode::createInstanceJoint(ColladaInstInfo *colInstInfo, domNode *node)
{
    NodeUnrecPtr retVal    = NULL;
    bool         startSkel = false;

    // if there is a ColladaInstanceElement someone tried to use <instance_node>
    // with this joint as target - this is currently not supported
    if(colInstInfo->getColInst() != NULL)
    {
        SWARNING << "ColladaNode::createInstanceJoint: <instance_node> with "
                 << "target <node> of type JOINT not supported." << std::endl;
        return retVal;
    }

    NodeLoaderState *state =
        getGlobal()->getLoaderStateAs<NodeLoaderState>(_loaderStateName);
    OSG_ASSERT(state != NULL);

    state->pushNodePath(node->getId() != NULL ? node->getId() : "");
    state->dumpNodePath();

    InstData instData;
    instData._nodePath = state->getNodePath();
    instData._skel     = state->getSkeleton();

    if(instData._skel == NULL)
    {
        startSkel      = true;
        instData._skel = Skeleton::create();

        state->setSkeleton(instData._skel);
        state->setJointId (0             );

        OSG_COLLADA_LOG(("ColladaNode::createInstanceJoint: id [%s] "
                         "root joint\n", node->getId()));
    }
    else
    {
        state->setJointId(state->getJointId() + 1);

        OSG_COLLADA_LOG(("ColladaNode::createInstanceJoint: id [%s] "
                         "joint [%d]\n", node->getId(), state->getJointId()));
    }

    const daeElementRefArray &contents = node->getContents();

    for(UInt32 i = 0; i < contents.getCount(); ++i)
    {
        switch(contents[i]->getElementType())
        {
        case COLLADA_TYPE::LOOKAT:
            handleLookAt(daeSafeCast<domLookat>(contents[i]), instData);
            break;

        case COLLADA_TYPE::MATRIX:
            handleMatrix(daeSafeCast<domMatrix>(contents[i]), instData);
            break;

        case COLLADA_TYPE::ROTATE:
            handleRotate(daeSafeCast<domRotate>(contents[i]), instData);
            break;

        case COLLADA_TYPE::SCALE:
            handleScale(daeSafeCast<domScale>(contents[i]), instData);
            break;

        case COLLADA_TYPE::SKEW:
            handleSkew(daeSafeCast<domSkew>(contents[i]), instData);
            break;

        case COLLADA_TYPE::TRANSLATE:
            handleTranslate(daeSafeCast<domTranslate>(contents[i]), instData);
            break;
        }
    }

    // assert top and bottom are both set or both unset
    OSG_ASSERT((instData._topN != NULL && instData._bottomN != NULL) ||
               (instData._topN == NULL && instData._bottomN == NULL)   );

    if(instData._topN == NULL && instData._bottomN == NULL)
    {
        // no xforms were created, make a SkeletonJoint for this <node>

        SkeletonJointUnrecPtr joint = SkeletonJoint::create();

        joint->setJointId(state->getJointId());

        instData._topN    = makeNodeFor(joint);
        instData._bottomN = instData._topN;

        if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
           node->getName()                                       != NULL   )
        {
            setName(instData._topN, node->getName());
        }
    }
    else if(getGlobal()->getOptions()->getMergeTransforms() == false)
    {
        // when not merging transforms add SkeletonJoint core now

        SkeletonJointUnrecPtr joint  = SkeletonJoint::create();
        NodeUnrecPtr          jointN = makeNodeFor(joint);

        joint->setJointId(state->getJointId());

        instData._bottomN->addChild(jointN);
        instData._bottomN = jointN;
    }

    if(startSkel == true)
    {
        // add a transform for the world matrix up to this node to put
        // the Skeleton in the correct coordinate system

        TransformUnrecPtr xform  = Transform::create();
        NodeUnrecPtr      xformN = makeNodeFor(xform);

        xform->setMatrix(state->getWorldMatrix());

        xformN->addChild(instData._topN);
        instData._topN = xformN;

        if(getGlobal()->getOptions()->getCreateNameAttachments() == true)
            setName(xformN, "SkeletonWorldMatrix");
    }

    // update world matrix before we instantiate child nodes, etc.
    state->pushMatrix(instData._localMatrix);

    // add <node> child elements
    const domNode_Array &nodes = node->getNode_array();

    for(UInt32 i = 0; i < nodes.getCount(); ++i)
        handleNode(nodes[i], instData);

    // add <instance_node> child elements
    const domInstance_node_Array &instNodes =
        node->getInstance_node_array();

    for(UInt32 i = 0; i < instNodes.getCount(); ++i)
        handleInstanceNode(instNodes[i], instData);

    // we don't handle other <instance_*> tags here, it does not
    // make sense to have them inside a skeleton

    editInstStore().push_back(instData._topN);
    _instDataStore .push_back(instData      );
    retVal = instData._topN;

    if(startSkel == true)
    {
        instData._skel->pushToRoots(instData._topN);

        state->setSkeleton(NULL);
        state->setJointId (SkeletonJoint::INVALID_JOINT_ID);
    }

    state->popMatrix  ();
    state->popNodePath();

    return retVal;
}
Exemple #18
0
//
// setup of the image generation stage
//
static void createAcquisitionStage()
{
    size_t num_ports = win->getMFPort()->size();
    if (num_ports == 0)
        return;

    UInt32 width  = win->getWidth();
    UInt32 height = win->getHeight();

    Real32 a = Real32(width) / Real32(height);
    width = UInt32(a*height);

    Viewport* vp = staticVp;

    Node* internalRoot = rootNode(mgr->getRoot());

    //
    // Setup the FBO
    //
    spSimpleFBO.reset(new SimpleFBO(width, height, true, true, true, false));
    
    //spSimpleFBO->fbo()->setPostProcessOnDeactivate(true);
    //spSimpleFBO->colorBuffer(0)->setReadBack(true);

    //
    // We would like to render the scene but won't detach it from its parent.
    // The VisitSubTree allows just that.
    //
    VisitSubTreeUnrecPtr visitor = VisitSubTree::create();
    visitor->setSubTreeRoot(internalRoot);
    NodeUnrecPtr visit_node = makeNodeFor(visitor);

    //
    // The stage object does provide a render target for the frame buffer attachment.
    // SimpleStage has a camera, a background and the left, right, top, bottom
    // fields to let you restrict rendering to a sub-rectangle of your FBO, i.e.
    // they give you a viewport.
    //
    SimpleStageUnrecPtr stage = SimpleStage::create();
    stage->setRenderTarget(spSimpleFBO->fbo());
    stage->setCamera      (vp->getCamera());
    stage->setBackground  (vp->getBackground());
    //
    // Give the stage core a place to live
    //
    NodeUnrecPtr stage_node = makeNodeFor(stage);
    stage_node->addChild(visit_node);

    //
    //   root
    //    |
    //    +- SimpleStage
    //            |
    //            +- VisitSubTree -> ApplicationScene
    //
    NodeUnrecPtr root = makeCoredNode<Group>();
    root->addChild(stage_node);

    //
    // Give the root node a place to live, i.e. create a passive
    // viewport and add it to the window.
    //
    ViewportUnrecPtr stage_viewport = PassiveViewport::create();
    stage_viewport->setRoot      (stage_node);
    stage_viewport->setBackground(vp->getBackground());
    stage_viewport->setCamera    (vp->getCamera());

    win->addPort(stage_viewport);

    mgr->update();
    win->renderNoFinish(mgr->getRenderAction());
    win->frameExit();
    win->deactivate ();

    //ImageUnrecPtr col_image = Image::create();
    //col_image->set(Image::OSG_RGBA_PF, width, height);
        
    //TextureObjChunk* texObj = spSimpleFBO->colorTexObj(0);
    //texObj->getImage()->subImage(0, 0, 0, width, height, 1, col_image);
    //col_image->write("d:/my_Test_opensg.png");

    win->subPortByObj(stage_viewport);
}
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

    {
        // Set up Window
        WindowEventProducerRecPtr TutorialWindow = createNativeWindow();
        TutorialWindow->initWindow();

        // Create the SimpleSceneManager helper
        SimpleSceneManager sceneManager;
        TutorialWindow->setDisplayCallback(boost::bind(display, &sceneManager));
        TutorialWindow->setReshapeCallback(boost::bind(reshape, _1, &sceneManager));

        // Tell the Manager what to manage
        sceneManager.setWindow(TutorialWindow);

        TutorialWindow->connectKeyTyped(boost::bind(keyPressed, _1));

        // Make Torus Node (creates Torus in background of scene)
        NodeRecPtr TorusGeometryNode = makeTorus(.5, 2, 16, 16);

        // Make Main Scene Node and add the Torus
        NodeRecPtr scene = Node::create();
        scene->setCore(Group::create());
        scene->addChild(TorusGeometryNode);

        // Create the Graphics
        GraphicsRecPtr TutorialGraphics = Graphics2D::create();

        // Initialize the LookAndFeelManager to enable default settings
        LookAndFeelManager::the()->getLookAndFeel()->init();

        //Create the nessicary parts for a viewport
        Matrix TransformMatrix;
        TransformMatrix.setTranslate(0.0f,0.0f, 0.0f);
        TransformRecPtr CameraBeaconTransform = Transform::create();
        CameraBeaconTransform->setMatrix(TransformMatrix);

        NodeRecPtr CameraBeaconNode = Node::create();
        CameraBeaconNode->setCore(CameraBeaconTransform);

        // Make Torus Node (creates Torus in background of scene)
        NodeRecPtr GeometryNode = makeTorus(.5, 2, 32, 32);

        //Make a light Node
        NodeRecPtr LightBeaconNode = makeCoredNode<Transform>();

        DirectionalLightRecPtr SceneLight = DirectionalLight::create();
        SceneLight->setAmbient(Color4f(0.3f,0.3f,0.3f,1.0f));
        SceneLight->setDiffuse(Color4f(0.8f,0.8f,0.8f,1.0f));
        SceneLight->setSpecular(Color4f(1.0f,1.0f,1.0f,1.0f));
        SceneLight->setOn(true);
        SceneLight->setBeacon(LightBeaconNode);

        NodeRecPtr LightNode = makeNodeFor(SceneLight);
        LightNode->addChild(GeometryNode);

        // Make Main Scene Node and add the Torus
        NodeRecPtr DefaultRootNode = Node::create();
        DefaultRootNode->setCore(Group::create());
        DefaultRootNode->addChild(LightNode);
        DefaultRootNode->addChild(LightBeaconNode);
        DefaultRootNode->addChild(CameraBeaconNode);

        //Camera
        PerspectiveCameraRecPtr DefaultCamera = PerspectiveCamera::create();
        DefaultCamera->setBeacon(CameraBeaconNode);
        DefaultCamera->setFov   (osgDegree2Rad(60.f));
        DefaultCamera->setNear  (0.1f);
        DefaultCamera->setFar   (100.f);

        //Background
        GradientBackgroundRecPtr DefaultBackground = GradientBackground::create();
        DefaultBackground->addLine(Color3f(0.0f,0.0f,0.0f), 0.0f);
        DefaultBackground->addLine(Color3f(0.0f,0.0f,1.0f), 1.0f);

        //Viewport
        ViewportRecPtr DefaultViewport = Viewport::create();
        DefaultViewport->setCamera                  (DefaultCamera);
        DefaultViewport->setRoot                    (DefaultRootNode);
        DefaultViewport->setSize                    (0.0f,0.0f, 1.0f,1.0f);
        DefaultViewport->setBackground              (DefaultBackground);

        //GL Viewport Component
        LineBorderRecPtr TheGLViewportBorder = LineBorder::create();
        TheGLViewportBorder->setColor(Color4f(1.0,0.0,0.0,1.0));
        TheGLViewportBorder->setWidth(3.0);

        GLViewportRecPtr TheGLViewport = GLViewport::create();
        TheGLViewport->setPort(DefaultViewport);
        TheGLViewport->setPreferredSize(Vec2f(400.0f,400.0f));
        TheGLViewport->setBorders(TheGLViewportBorder);
        TheGLViewport->lookAt(Pnt3f(0.0f,0.0f,10.0f), //From
                              Pnt3f(0.0f,0.0f,0.0f), //At
                              Vec3f(0.0f,1.0f,0.0f)); //Up

        ButtonRecPtr ExampleButton = Button::create();

        ExampleButton->setText("Example");

        // Create The Main InternalWindow
        // Create Background to be used with the Main InternalWindow
        ColorLayerRecPtr MainInternalWindowBackground = ColorLayer::create();
        MainInternalWindowBackground->setColor(Color4f(1.0,1.0,1.0,0.5));

        InternalWindowRecPtr MainInternalWindow = InternalWindow::create();
        LayoutRecPtr MainInternalWindowLayout = FlowLayout::create();
        MainInternalWindow->pushToChildren(TheGLViewport);
        MainInternalWindow->pushToChildren(ExampleButton);
        MainInternalWindow->setLayout(MainInternalWindowLayout);
        MainInternalWindow->setBackgrounds(MainInternalWindowBackground);
        MainInternalWindow->setAlignmentInDrawingSurface(Vec2f(0.5f,0.5f));
        MainInternalWindow->setScalingInDrawingSurface(Vec2f(0.95f,0.95f));
        MainInternalWindow->setDrawTitlebar(false);
        MainInternalWindow->setResizable(false);

        // Create the Drawing Surface
        UIDrawingSurfaceRecPtr TutorialDrawingSurface = UIDrawingSurface::create();
        TutorialDrawingSurface->setGraphics(TutorialGraphics);
        TutorialDrawingSurface->setEventProducer(TutorialWindow);

        TutorialDrawingSurface->openWindow(MainInternalWindow);

        // Create the UI Foreground Object
        UIForegroundRecPtr TutorialUIForeground = UIForeground::create();

        TutorialUIForeground->setDrawingSurface(TutorialDrawingSurface);


        // Tell the Manager what to manage
        sceneManager.setRoot(scene);

        // Add the UI Foreground Object to the Scene
        ViewportRecPtr TutorialViewport = sceneManager.getWindow()->getPort(0);
        TutorialViewport->addForeground(TutorialUIForeground);

        //Create the Documentation Foreground and add it to the viewport
        SimpleScreenDoc TheSimpleScreenDoc(&sceneManager, TutorialWindow);

        // Show the whole Scene
        sceneManager.showAll();


        //Open Window
        Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f);
        Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5);
        TutorialWindow->openWindow(WinPos,
                                   WinSize,
                                   "41GLViewportComponent");

        //Enter main Loop
        TutorialWindow->mainLoop();
    }

    osgExit();

    return 0;
}
Node *
ColladaLight::createInstanceCommon(
    ColladaLightInstInfo *colInstInfo, domLight::domTechnique_common *tech)
{
    domLightRef light = getDOMElementAs<domLight>();

    OSG_COLLADA_LOG(("ColladaLight::createInstanceCommon id [%s]\n",
                     light->getId()));

    NodeUnrecPtr                                     lightN      = NULL;

    domLight::domTechnique_common::domAmbientRef     ambient     =
        tech->getAmbient();
    domLight::domTechnique_common::domDirectionalRef directional =
        tech->getDirectional();
    domLight::domTechnique_common::domPointRef       point       =
        tech->getPoint();
    domLight::domTechnique_common::domSpotRef        spot        =
        tech->getSpot();

    if(ambient != NULL)
    {
        Color4f lightColor(ambient->getColor()->getValue()[0],
                           ambient->getColor()->getValue()[1],
                           ambient->getColor()->getValue()[2], 1.f);

        LightLoaderState *state =
            getGlobal()->getLoaderStateAs<LightLoaderState>(_loaderStateName);
        OSG_ASSERT(state != NULL);

        LightModelChunkUnrecPtr lmChunk = state->getLightModelChunk();

        if(state->getLightModelChunk() == NULL)
        {
            lmChunk = LightModelChunk::create();
            lmChunk->setAmbient(Color4f(0.f, 0.f, 0.f, 1.f));

            state->setLightModelChunk(lmChunk);

            // only place one instance into the inst queue, it will
            // add the LightModelChunk with the accumulated ambient
            // for the scene
            ColladaInstInfoRefPtr ambientInstInfo =
                ColladaLightAmbientInstInfo::create(
                    colInstInfo->getColInstParent(),
                    dynamic_cast<ColladaInstanceLight *>(
                        colInstInfo->getColInst())        );

            getGlobal()->editInstQueue().push_back(ambientInstInfo);
        }

        lightColor[0] = 
            osgClamp(0.f, lmChunk->getAmbient()[0] + lightColor[0], 1.f);
        lightColor[1] =
            osgClamp(0.f, lmChunk->getAmbient()[1] + lightColor[1], 1.f);
        lightColor[2] =
            osgClamp(0.f, lmChunk->getAmbient()[2] + lightColor[0], 1.f);

        lmChunk->setAmbient(lightColor);
    }

    if(directional != NULL)
    {
        Color4f lightColor(directional->getColor()->getValue()[0],
                           directional->getColor()->getValue()[1],
                           directional->getColor()->getValue()[2], 1.f);

        DirectionalLightUnrecPtr dl = DirectionalLight::create();
        lightN                      = makeNodeFor(dl);

        dl->setBeacon  (colInstInfo->getBeacon());
        dl->setDiffuse (lightColor              );
        dl->setSpecular(lightColor              );
    }

    if(point != NULL)
    {
        Color4f lightColor(point->getColor()->getValue()[0],
                           point->getColor()->getValue()[1],
                           point->getColor()->getValue()[2], 1.f);

        PointLightUnrecPtr pl = PointLight::create();
        lightN                = makeNodeFor(pl);

        Real32 constAtt = 1.f;
        Real32 linAtt   = 0.f;
        Real32 quadAtt  = 0.f;

        if(point->getConstant_attenuation() != NULL)
            constAtt = point->getConstant_attenuation()->getValue();

        if(point->getLinear_attenuation() != NULL)
            linAtt   = point->getLinear_attenuation()->getValue();

        if(point->getQuadratic_attenuation() != NULL)
            quadAtt  = point->getQuadratic_attenuation()->getValue();

        pl->setBeacon              (colInstInfo->getBeacon());
        pl->setDiffuse             (lightColor              );
        pl->setSpecular            (lightColor              );
        pl->setConstantAttenuation (constAtt                );
        pl->setLinearAttenuation   (linAtt                  );
        pl->setQuadraticAttenuation(quadAtt                 );
    }

    if(spot != NULL)
    {
        Color4f lightColor(spot->getColor()->getValue()[0],
                           spot->getColor()->getValue()[1],
                           spot->getColor()->getValue()[2], 1.f);

        SpotLightUnrecPtr sl = SpotLight::create();
        lightN               = makeNodeFor(sl);

        Real32 constAtt =   1.f;
        Real32 linAtt   =   0.f;
        Real32 quadAtt  =   0.f;
        Real32 cutOff   = 180.f;
        Real32 exponent =   0.f;

        if(spot->getConstant_attenuation() != NULL)
            constAtt = spot->getConstant_attenuation()->getValue();

        if(spot->getLinear_attenuation() != NULL)
            linAtt   = spot->getLinear_attenuation()->getValue();

        if(spot->getQuadratic_attenuation() != NULL)
            quadAtt  = spot->getQuadratic_attenuation()->getValue();

        if(spot->getFalloff_angle() != NULL)
            cutOff   = spot->getFalloff_angle()->getValue();

        if(spot->getFalloff_exponent() != NULL)
            exponent = spot->getFalloff_exponent()->getValue();

        sl->setBeacon              (colInstInfo->getBeacon());
        sl->setDiffuse             (lightColor              );
        sl->setSpecular            (lightColor              );
        sl->setConstantAttenuation (constAtt                );
        sl->setLinearAttenuation   (linAtt                  );
        sl->setQuadraticAttenuation(quadAtt                 );
        sl->setSpotCutOff          (osgDegree2Rad(cutOff)   );
        sl->setSpotExponent        (exponent                );
    }

    if(lightN != NULL)
    {
        editInstStore().push_back(lightN);

        if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
           light->getName()                                      != NULL   )
        {
            setName(lightN, light->getName());
        }
    }

    return lightN;
}
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

    // Set up Window
    TutorialWindow = createNativeWindow();
    TutorialWindow->initWindow();

    TutorialWindow->setDisplayCallback(display);
    TutorialWindow->setReshapeCallback(reshape);

    //Add Window Listener
    TutorialKeyListener TheKeyListener;
    TutorialWindow->addKeyListener(&TheKeyListener);
    TutorialMouseListener TheTutorialMouseListener;
    TutorialMouseMotionListener TheTutorialMouseMotionListener;
    TutorialWindow->addMouseListener(&TheTutorialMouseListener);
    TutorialWindow->addMouseMotionListener(&TheTutorialMouseMotionListener);

    // Create the SimpleSceneManager helper
    mgr = new SimpleSceneManager;

    // Tell the Manager what to manage
    mgr->setWindow(TutorialWindow);

    //Print key command info
    std::cout << "\n\nKEY COMMANDS:" << std::endl;
    std::cout << "space   Play/Pause the animation" << std::endl;
    std::cout << "B       Show/Hide the bind pose skeleton" << std::endl;
    std::cout << "SHIFT-B Show/Hide the bind pose mesh" << std::endl;
    std::cout << "P       Show/Hide the current pose skeleton" << std::endl;
    std::cout << "SHIFT-P Show/Hide the current pose mesh" << std::endl;
    std::cout << "CTRL-Q  Exit\n\n" << std::endl;


    //SkeletonDrawer System Material
    LineChunkUnrecPtr ExampleLineChunk = LineChunk::create();
    ExampleLineChunk->setWidth(2.0f);
    ExampleLineChunk->setSmooth(true);

    BlendChunkUnrecPtr ExampleBlendChunk = BlendChunk::create();
    ExampleBlendChunk->setSrcFactor(GL_SRC_ALPHA);
    ExampleBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);

    MaterialChunkUnrecPtr ExampleMaterialChunk = MaterialChunk::create();
    ExampleMaterialChunk->setAmbient(Color4f(1.0f,1.0f,1.0f,1.0f));
    ExampleMaterialChunk->setDiffuse(Color4f(0.0f,0.0f,0.0f,1.0f));
    ExampleMaterialChunk->setSpecular(Color4f(0.0f,0.0f,0.0f,1.0f));

    ChunkMaterialUnrecPtr ExampleMaterial = ChunkMaterial::create();
    ExampleMaterial->addChunk(ExampleLineChunk);
    ExampleMaterial->addChunk(ExampleMaterialChunk);
    ExampleMaterial->addChunk(ExampleBlendChunk);


    //Skeleton
    ExampleSkeleton = SkeletonBlendedGeometry::create();

    //===========================================Joints==================================================================
    Matrix TempMat;
    Matrix InvBind;

    /*================================================================================================*/
    /*                                       Pelvis                                                   */
    Pelvis = Joint::create(); //create a joint called Pelvis 
    TempMat.setTranslate(0.0,7.0,0.0);
    Pelvis->setJointTransformation(TempMat);

    NodeRecPtr PelvisNode = makeNodeFor(Pelvis);

    InvBind = PelvisNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(Pelvis, InvBind);
    setName(Pelvis, "Pelvis Joint");
    setName(PelvisNode, "Pelvis Node");
    
    /*================================================================================================*/
    /*                                       Clavicle                                                   */
    Clavicle = Joint::create(); //create a joint called Clavicle 
    TempMat.setTranslate(0.0,5.0,0.0);
    Clavicle->setJointTransformation(TempMat);

    NodeRecPtr ClavicleNode = makeNodeFor(Clavicle);
    PelvisNode->addChild(ClavicleNode);

    InvBind = ClavicleNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(Clavicle, InvBind);
    setName(Clavicle, "Clavicle Joint");
    setName(ClavicleNode, "Clavicle Node");

    /*================================================================================================*/
    /*                                       Left Shoulder                                                 */
    LeftShoulder = Joint::create(); //create a joint called LeftShoulder 
    TempMat.setTranslate(1.0,-0.5,0.0);
    LeftShoulder->setJointTransformation(TempMat);

    NodeRecPtr LeftShoulderNode = makeNodeFor(LeftShoulder);
    ClavicleNode->addChild(LeftShoulderNode);

    InvBind = LeftShoulderNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(LeftShoulder, InvBind);
    setName(LeftShoulder, "Left Shoulder Joint");
    setName(LeftShoulderNode, "Left Shoulder Node");

    /*================================================================================================*/
    /*                                       Left Elbow                                                 */
    LeftElbow = Joint::create(); //create a joint called LeftElbow 
    TempMat.setTranslate(2.0,0.0,0.0);
    LeftElbow->setJointTransformation(TempMat);

    NodeRecPtr LeftElbowNode = makeNodeFor(LeftElbow);
    LeftShoulderNode->addChild(LeftElbowNode);

    InvBind = LeftElbowNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(LeftElbow, InvBind);
    setName(LeftElbow, "Left Elbow Joint");
    setName(LeftElbowNode, "Left Elbow Node");

    /*================================================================================================*/
    /*                                       Left Hand                                                 */
    LeftHand = Joint::create(); //create a joint called LeftHand 
    TempMat.setTranslate(2.0,0.0,0.0);
    LeftHand->setJointTransformation(TempMat);

    NodeRecPtr LeftHandNode = makeNodeFor(LeftHand);
    LeftElbowNode->addChild(LeftHandNode);

    InvBind = LeftHandNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(LeftHand, InvBind);
    setName(LeftHand, "Left Hand Joint");
    setName(LeftHandNode, "Left Hand Node");
    /*================================================================================================*/
    /*                                       Left Fingers                                                 */
    LeftFingers = Joint::create(); //create a joint called LeftFingers 
    TempMat.setTranslate(1.0,0.0,0.0);
    LeftFingers->setJointTransformation(TempMat);

    NodeRecPtr LeftFingersNode = makeNodeFor(LeftFingers);
    LeftHandNode->addChild(LeftFingersNode);

    InvBind = LeftFingersNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(LeftFingers, InvBind);
    setName(LeftFingers, "Left Fingers Joint");
    setName(LeftFingersNode, "Left Fingers Node");

    /*================================================================================================*/
    /*                                       Right Shoulder                                                 */
    RightShoulder = Joint::create(); //create a joint called RightShoulder 
    TempMat.setTranslate(-1.0,-0.5,0.0);
    RightShoulder->setJointTransformation(TempMat);

    NodeRecPtr RightShoulderNode = makeNodeFor(RightShoulder);
    ClavicleNode->addChild(RightShoulderNode);

    InvBind = RightShoulderNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(RightShoulder, InvBind);
    setName(RightShoulder, "Right Shoulder Joint");
    setName(RightShoulderNode, "Right Shoulder Node");

    /*================================================================================================*/
    /*                                       Right Elbow                                                 */
    RightElbow = Joint::create(); //create a joint called RightElbow 
    TempMat.setTranslate(-2.0,0.0,0.0);
    RightElbow->setJointTransformation(TempMat);

    NodeRecPtr RightElbowNode = makeNodeFor(RightElbow);
    RightShoulderNode->addChild(RightElbowNode);

    InvBind = RightElbowNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(RightElbow, InvBind);
    setName(RightElbow, "Right Elbow Joint");
    setName(RightElbowNode, "Right Elbow Node");

    /*================================================================================================*/
    /*                                       Right Hand                                                 */
    RightHand = Joint::create(); //create a joint called RightHand 
    TempMat.setTranslate(-2.0,0.0,0.0);
    RightHand->setJointTransformation(TempMat);

    NodeRecPtr RightHandNode = makeNodeFor(RightHand);
    RightElbowNode->addChild(RightHandNode);

    InvBind = RightHandNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(RightHand, InvBind);
    setName(RightHand, "Right Hand Joint");
    setName(RightHandNode, "Right Hand Node");

    /*================================================================================================*/
    /*                                       Right Fingers                                                 */
    RightFingers = Joint::create(); //create a joint called RightFingers 
    TempMat.setTranslate(-1.0,0.0,0.0);
    RightFingers->setJointTransformation(TempMat);

    NodeRecPtr RightFingersNode = makeNodeFor(RightFingers);
    RightHandNode->addChild(RightFingersNode);

    InvBind = RightFingersNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(RightFingers, InvBind);
    setName(RightFingers, "Right Fingers Joint");
    setName(RightFingersNode, "Right Fingers Node");

    /*================================================================================================*/
    /*                                       Head                                                 */
    Head = Joint::create(); //create a joint called Head 
    TempMat.setTranslate(0.0,1.0,0.0);
    Head->setJointTransformation(TempMat);

    NodeRecPtr HeadNode = makeNodeFor(Head);
    ClavicleNode->addChild(HeadNode);

    InvBind = HeadNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(Head, InvBind);
    setName(Head, "Head Joint");
    setName(HeadNode, "Head Node");

    /*================================================================================================*/
    /*                                       Left Hip                                                 */
    LeftHip = Joint::create(); //create a joint called LeftHip 
    TempMat.setTranslate(1.0,-1.0,0.0);
    LeftHip->setJointTransformation(TempMat);

    NodeRecPtr LeftHipNode = makeNodeFor(LeftHip);
    PelvisNode->addChild(LeftHipNode);

    InvBind = LeftHipNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(LeftHip, InvBind);
    setName(LeftHip, "Left Hip Joint");
    setName(LeftHipNode, "Left Hip Node");

    /*================================================================================================*/
    /*                                       Left Knee                                                 */
    LeftKnee = Joint::create(); //create a joint called LeftKnee 
    TempMat.setTranslate(0.0,-3.0,0.0);
    LeftKnee->setJointTransformation(TempMat);

    NodeRecPtr LeftKneeNode = makeNodeFor(LeftKnee);
    LeftHipNode->addChild(LeftKneeNode);

    InvBind = LeftKneeNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(LeftKnee, InvBind);
    setName(LeftKnee, "Left Knee Joint");
    setName(LeftKneeNode, "Left Knee Node");

    /*================================================================================================*/
    /*                                       Left Foot                                                 */
    LeftFoot = Joint::create(); //create a joint called LeftFoot 
    TempMat.setTranslate(0.0,-3.0,0.0);
    LeftFoot->setJointTransformation(TempMat);

    NodeRecPtr LeftFootNode = makeNodeFor(LeftFoot);
    LeftKneeNode->addChild(LeftFootNode);

    InvBind = LeftFootNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(LeftFoot, InvBind);
    setName(LeftFoot, "Left Foot Joint");
    setName(LeftFootNode, "Left Foot Node");

    /*================================================================================================*/
    /*                                       Left Toes                                                 */
    LeftToes = Joint::create(); //create a bone called ExampleChildbone
    TempMat.setTranslate(0.0,0.0,1.0);
    LeftToes->setJointTransformation(TempMat);

    NodeRecPtr LeftToesNode = makeNodeFor(LeftToes);
    LeftFootNode->addChild(LeftToesNode);

    InvBind = LeftToesNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(LeftToes, InvBind);
    setName(LeftToes, "Left Toes Joint");
    setName(LeftToesNode, "Left Toes Node");

    /*================================================================================================*/
    /*                                       Right Hip                                                 */
    RightHip = Joint::create(); //create a joint called RightHip 
    TempMat.setTranslate(-1.0,-1.0,0.0);
    RightHip->setJointTransformation(TempMat);

    NodeRecPtr RightHipNode = makeNodeFor(RightHip);
    PelvisNode->addChild(RightHipNode);

    InvBind = RightHipNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(RightHip, InvBind);
    setName(RightHip, "Right Hip Joint");
    setName(RightHipNode, "Right Hip Node");

    /*================================================================================================*/
    /*                                       Right Knee                                                 */
    RightKnee = Joint::create(); //create a joint called RightKnee 
    TempMat.setTranslate(0.0,-3.0,0.0);
    RightKnee->setJointTransformation(TempMat);

    NodeRecPtr RightKneeNode = makeNodeFor(RightKnee);
    RightHipNode->addChild(RightKneeNode);

    InvBind = RightKneeNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(RightKnee, InvBind);
    setName(RightKnee, "Right Knee Joint");
    setName(RightKneeNode, "Right Knee Node");

    /*================================================================================================*/
    /*                                       Right Foot                                                 */
    RightFoot = Joint::create(); //create a joint called RightFoot 
    TempMat.setTranslate(0.0,-3.0,0.0);
    RightFoot->setJointTransformation(TempMat);

    NodeRecPtr RightFootNode = makeNodeFor(RightFoot);
    RightKneeNode->addChild(RightFootNode);

    InvBind = RightFootNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(RightFoot, InvBind);
    setName(RightFoot, "Right Foot Joint");
    setName(RightFootNode, "Right Foot Node");
    
    /*================================================================================================*/
    /*                                       Right Toes                                                 */
    RightToes = Joint::create(); //create a joint called RightToes 
    TempMat.setTranslate(0.0,0.0,1.0);
    RightToes->setJointTransformation(TempMat);

    NodeRecPtr RightToesNode = makeNodeFor(RightToes);
    RightFootNode->addChild(RightToesNode);

    InvBind = RightToesNode->getToWorld();
    InvBind.invert();
    ExampleSkeleton->pushToJoints(RightToes, InvBind);
    setName(RightToes, "Right Toes Joint");
    setName(RightToesNode, "Right Toes Node");


    //Create a geometry to attach to the skeleton (i.e-> skin)
    GeoUInt8PropertyUnrecPtr type = GeoUInt8Property::create();        
        type->push_back(GL_QUADS);

    GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property::create();    
        lens->push_back(72);
    GeoPnt3fPropertyUnrecPtr  pnts  = GeoPnt3fProperty ::create();
        // the points of the Quads

        //Back
        pnts->push_back(Pnt3f(-0.5,  6.0,  0));
        pnts->push_back(Pnt3f( 0.5,  6.0,  0));
        pnts->push_back(Pnt3f( 0.5,  12.0,  0));
        pnts->push_back(Pnt3f(-0.5,  12.0,  0));

        //Head
        pnts->push_back(Pnt3f(-0.5,  12,  0));
        pnts->push_back(Pnt3f( 0.5,  12,  0));
        pnts->push_back(Pnt3f( 0.5,  13,  0));
        pnts->push_back(Pnt3f(-0.5,  13,  0));

        //Left Shoulder
        pnts->push_back(Pnt3f(0.0,  11.5,  0));
        pnts->push_back(Pnt3f(0.0,  12.5,  0));
        pnts->push_back(Pnt3f(1.0,  12.0,  0));
        pnts->push_back(Pnt3f(1.0,  11.0,  0));

        //Left Humerus
        pnts->push_back(Pnt3f(1.0,  11.0,  0));
        pnts->push_back(Pnt3f(1.0,  12.0,  0));
        pnts->push_back(Pnt3f(3.0,  12.0,  0));
        pnts->push_back(Pnt3f(3.0,  11.0,  0));

        //Left Radius
        pnts->push_back(Pnt3f(3.0,  11.0,  0));
        pnts->push_back(Pnt3f(3.0,  12.0,  0));
        pnts->push_back(Pnt3f(5.0,  12.0,  0));
        pnts->push_back(Pnt3f(5.0,  11.0,  0));

        //Left Hand
        pnts->push_back(Pnt3f(5.0,  11.0,  0));
        pnts->push_back(Pnt3f(5.0,  12.0,  0));
        pnts->push_back(Pnt3f(6.0,  12.0,  0));
        pnts->push_back(Pnt3f(6.0,  11.0,  0));

        //Right Shoulder
        pnts->push_back(Pnt3f(0.0,  11.5,  0));
        pnts->push_back(Pnt3f(0.0,  12.5,  0));
        pnts->push_back(Pnt3f(-1.0,  12.0,  0));
        pnts->push_back(Pnt3f(-1.0,  11.0,  0));

        //Right Humerus
        pnts->push_back(Pnt3f(-1.0,  11.0,  0));
        pnts->push_back(Pnt3f(-1.0,  12.0,  0));
        pnts->push_back(Pnt3f(-3.0,  12.0,  0));
        pnts->push_back(Pnt3f(-3.0,  11.0,  0));

        //Right Radius
        pnts->push_back(Pnt3f(-3.0,  11.0,  0));
        pnts->push_back(Pnt3f(-3.0,  12.0,  0));
        pnts->push_back(Pnt3f(-5.0,  12.0,  0));
        pnts->push_back(Pnt3f(-5.0,  11.0,  0));

        //Right Hand
        pnts->push_back(Pnt3f(-5.0,  11.0,  0));
        pnts->push_back(Pnt3f(-5.0,  12.0,  0));
        pnts->push_back(Pnt3f(-6.0,  12.0,  0));
        pnts->push_back(Pnt3f(-6.0,  11.0,  0));

        //Left Hip
        pnts->push_back(Pnt3f(0.0, 6.5,  0));
        pnts->push_back(Pnt3f(0.5, 7.5,  0));
        pnts->push_back(Pnt3f( 1.5,  6.0,  0));
        pnts->push_back(Pnt3f(0.5,  6.0,  0));

        //Left Femur
        pnts->push_back(Pnt3f(0.5,  6.0,  0));
        pnts->push_back(Pnt3f( 1.5,  6.0,  0));
        pnts->push_back(Pnt3f( 1.5,  3.0,  0));
        pnts->push_back(Pnt3f(0.5,  3.0,  0));

        //Left Tibia
        pnts->push_back(Pnt3f(0.5,  3.0,  0));
        pnts->push_back(Pnt3f( 1.5,  3.0,  0));
        pnts->push_back(Pnt3f( 1.5,  0.0,  0));
        pnts->push_back(Pnt3f(0.5,  0.0,  0));

        //Left Foot
        pnts->push_back(Pnt3f(0.5,  0.0,  0));
        pnts->push_back(Pnt3f( 1.5,  0.0,  0));
        pnts->push_back(Pnt3f( 1.5,  0.0,  1.0));
        pnts->push_back(Pnt3f(0.5,  0.0,  1.0));


        //Right Hip
        pnts->push_back(Pnt3f(0.0, 6.5,  0));
        pnts->push_back(Pnt3f(-0.5, 7.5,  0));
        pnts->push_back(Pnt3f( -1.5,  6.0,  0));
        pnts->push_back(Pnt3f(-0.5,  6.0,  0));

        //Right Femur
        pnts->push_back(Pnt3f(-0.5,  6.0,  0));
        pnts->push_back(Pnt3f( -1.5,  6.0,  0));
        pnts->push_back(Pnt3f( -1.5,  3.0,  0));
        pnts->push_back(Pnt3f(-0.5,  3.0,  0));

        //Right Tibia
        pnts->push_back(Pnt3f(-0.5,  3.0,  0));
        pnts->push_back(Pnt3f( -1.5,  3.0,  0));
        pnts->push_back(Pnt3f( -1.5,  0.0,  0));
        pnts->push_back(Pnt3f(-0.5,  0.0,  0));

        //Right Foot
        pnts->push_back(Pnt3f(-0.5,  0.0,  0));
        pnts->push_back(Pnt3f( -1.5,  0.0,  0));
        pnts->push_back(Pnt3f( -1.5,  0.0,  1.0));
        pnts->push_back(Pnt3f(-0.5,  0.0,  1.0));

    //Normals
    GeoVec3fPropertyUnrecPtr  norms = GeoVec3fProperty ::create();
    geo=Geometry::create();
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    //Left Hip
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    //Left Femur
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    //Left Tibia
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    //Left Foot
    norms->push_back(Vec3f( 0.0,1.0,0.0));
    norms->push_back(Vec3f( 0.0,1.0,0.0));
    norms->push_back(Vec3f( 0.0,1.0,0.0));
    norms->push_back(Vec3f( 0.0,1.0,0.0));

    //Right Hip
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    //Right Femur
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    //Right Tibia
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));
    norms->push_back(Vec3f( 0.0,0.0,1.0));

    //Right Foot
    norms->push_back(Vec3f( 0.0,1.0,0.0));
    norms->push_back(Vec3f( 0.0,1.0,0.0));
    norms->push_back(Vec3f( 0.0,1.0,0.0));
    norms->push_back(Vec3f( 0.0,1.0,0.0));

    //Tell the geometry (geo) to use the points and normals we just defined
    geo->setTypes    (type);
    geo->setLengths  (lens);
    geo->setPositions(pnts);
    geo->setNormals(norms);

    // assign a material to the geometry to make it visible. The details
    // of materials are defined later.
    geo->setMaterial(getDefaultMaterial());   

    //Create unbound geometry node (for displaying mesh in its bind pose)
    UnboundGeometry = Node::create();
    UnboundGeometry->setCore(geo);
    UnboundGeometry->setTravMask(0);  //By default, we won't show the mesh's bind pose




    //SkeletonDrawer
    SkeletonDrawableUnrecPtr ExampleSkeletonDrawable = SkeletonDrawable::create();
    ExampleSkeletonDrawable->setSkeleton(ExampleSkeleton);
    ExampleSkeletonDrawable->setMaterial(ExampleMaterial);
    ExampleSkeletonDrawable->setDrawBindPose(false);  //By default, we don't draw the skeleton's bind pose
    ExampleSkeletonDrawable->setBindPoseColor(Color4f(0.0, 1.0, 0.0, 1.0));  //When drawn, the skeleton's bind pose renders green
    ExampleSkeletonDrawable->setDrawPose(true);  //By default, we do draw the skeleton's current pose
    ExampleSkeletonDrawable->setPoseColor(Color4f(0.0, 0.0, 1.0, 1.0));  //The skeleton's current pose renders blue

    //Skeleton Node
    SkeletonNode = Node::create();
    SkeletonNode->setCore(ExampleSkeletonDrawable);




    // Skeleton Blended Geometry
    // Here we are attaching the "skin" to the skeleton so that when the skeleton is animated, the skin moves with it
    ExampleSkeleton->setBaseGeometry(geo);
    //Back
    ExampleSkeleton->addJointBlending(0,Pelvis,1.0f);
    ExampleSkeleton->addJointBlending(1,Pelvis,1.0f);
    ExampleSkeleton->addJointBlending(2,Clavicle,1.0f);
    ExampleSkeleton->addJointBlending(3,Clavicle,1.0f);

    //Head
    ExampleSkeleton->addJointBlending(4,Clavicle,1.0f);
    ExampleSkeleton->addJointBlending(5,Clavicle,1.0f);
    ExampleSkeleton->addJointBlending(6,Head,1.0f);
    ExampleSkeleton->addJointBlending(7,Head,1.0f);

    //Left Shoulder
    ExampleSkeleton->addJointBlending(8,Clavicle,1.0f);
    ExampleSkeleton->addJointBlending(9,Clavicle,1.0f);
    ExampleSkeleton->addJointBlending(10,LeftShoulder,1.0f);
    ExampleSkeleton->addJointBlending(11,LeftShoulder,1.0f);

    //Left Humerus
    ExampleSkeleton->addJointBlending(12,LeftShoulder,1.0f);
    ExampleSkeleton->addJointBlending(13,LeftShoulder,1.0f);
    ExampleSkeleton->addJointBlending(14,LeftElbow,0.8f);
    ExampleSkeleton->addJointBlending(15,LeftElbow,0.8f);
    ExampleSkeleton->addJointBlending(14,LeftHand,0.2f);
    ExampleSkeleton->addJointBlending(15,LeftHand,0.2f);

    //Left Radius
    ExampleSkeleton->addJointBlending(16,LeftElbow,1.0f);
    ExampleSkeleton->addJointBlending(17,LeftElbow,1.0f);
    ExampleSkeleton->addJointBlending(18,LeftHand,1.0f);
    ExampleSkeleton->addJointBlending(19,LeftHand,1.0f);

    //Left Hand
    ExampleSkeleton->addJointBlending(20,LeftHand,1.0f);
    ExampleSkeleton->addJointBlending(21,LeftHand,1.0f);
    ExampleSkeleton->addJointBlending(22,LeftFingers,1.0f);
    ExampleSkeleton->addJointBlending(23,LeftFingers,1.0f);

    //Right Shoulder
    ExampleSkeleton->addJointBlending(24,Clavicle,1.0f);
    ExampleSkeleton->addJointBlending(25,Clavicle,1.0f);
    ExampleSkeleton->addJointBlending(26,RightShoulder,1.0f);
    ExampleSkeleton->addJointBlending(27,RightShoulder,1.0f);

    //Right Humerus
    ExampleSkeleton->addJointBlending(28,RightShoulder,1.0f);
    ExampleSkeleton->addJointBlending(29,RightShoulder,1.0f);
    ExampleSkeleton->addJointBlending(30,RightElbow,1.0f);
    ExampleSkeleton->addJointBlending(31,RightElbow,1.0f);

    //Right Radius
    ExampleSkeleton->addJointBlending(32,RightElbow,1.0f);
    ExampleSkeleton->addJointBlending(33,RightElbow,1.0f);
    ExampleSkeleton->addJointBlending(34,RightHand,1.0f);
    ExampleSkeleton->addJointBlending(35,RightHand,1.0f);

    //Right Hand
    ExampleSkeleton->addJointBlending(36,RightHand,1.0f);
    ExampleSkeleton->addJointBlending(37,RightHand,1.0f);
    ExampleSkeleton->addJointBlending(38,RightFingers,1.0f);
    ExampleSkeleton->addJointBlending(39,RightFingers,1.0f);

    //Left Hip
    ExampleSkeleton->addJointBlending(40,Pelvis,1.0f);
    ExampleSkeleton->addJointBlending(41,Pelvis,1.0f);
    ExampleSkeleton->addJointBlending(42,LeftHip,1.0f);
    ExampleSkeleton->addJointBlending(43,LeftHip,1.0f);

    //Left Femur
    ExampleSkeleton->addJointBlending(44,LeftHip,1.0f);
    ExampleSkeleton->addJointBlending(45,LeftHip,1.0f);
    ExampleSkeleton->addJointBlending(46,LeftKnee,1.0f);
    ExampleSkeleton->addJointBlending(47,LeftKnee,1.0f);

    //Left Tibia
    ExampleSkeleton->addJointBlending(48,LeftKnee,1.0f);
    ExampleSkeleton->addJointBlending(49,LeftKnee,1.0f);
    ExampleSkeleton->addJointBlending(50,LeftFoot,1.0f);
    ExampleSkeleton->addJointBlending(51,LeftFoot,1.0f);

    //Left Foot
    ExampleSkeleton->addJointBlending(52,LeftFoot,1.0f);
    ExampleSkeleton->addJointBlending(53,LeftFoot,1.0f);
    ExampleSkeleton->addJointBlending(54,LeftToes,1.0f);
    ExampleSkeleton->addJointBlending(55,LeftToes,1.0f);

    //Right Hip
    ExampleSkeleton->addJointBlending(56,Pelvis,1.0f);
    ExampleSkeleton->addJointBlending(57,Pelvis,1.0f);
    ExampleSkeleton->addJointBlending(58,RightHip,1.0f);
    ExampleSkeleton->addJointBlending(59,RightHip,1.0f);

    //Right Femur
    ExampleSkeleton->addJointBlending(60,RightHip,1.0f);
    ExampleSkeleton->addJointBlending(61,RightHip,1.0f);
    ExampleSkeleton->addJointBlending(62,RightKnee,1.0f);
    ExampleSkeleton->addJointBlending(63,RightKnee,1.0f);

    //Right Tibia
    ExampleSkeleton->addJointBlending(64,RightKnee,1.0f);
    ExampleSkeleton->addJointBlending(65,RightKnee,1.0f);
    ExampleSkeleton->addJointBlending(66,RightFoot,1.0f);
    ExampleSkeleton->addJointBlending(67,RightFoot,1.0f);

    //Right Foot
    ExampleSkeleton->addJointBlending(68,RightFoot,1.0f);
    ExampleSkeleton->addJointBlending(69,RightFoot,1.0f);
    ExampleSkeleton->addJointBlending(70,RightToes,1.0f);
    ExampleSkeleton->addJointBlending(71,RightToes,1.0f);

    MeshNode = Node::create();
    MeshNode->setCore(ExampleSkeleton);

    //Create scene node 
    NodeUnrecPtr scene = Node::create();
    scene->setCore(Group::create());
    scene->addChild(UnboundGeometry);
    scene->addChild(SkeletonNode);
    scene->addChild(MeshNode);

    mgr->setRoot(scene);

    //Setup the Animation
    setupAnimation();

    //Save to an xml file
    FCFileType::FCPtrStore Containers;
    Containers.insert(ExampleSkeleton);
    Containers.insert(PelvisNode);
    Containers.insert(TheSkeletonAnimation);

    //Use an empty Ignore types vector
    FCFileType::FCTypeVector IgnoreTypes;
    //IgnoreTypes.push_back(Node::getClassType().getId());
    
    //Write the Field Containers to a xml file
    FCFileHandler::the()->write(Containers,BoostPath("./13Output.xml"),IgnoreTypes);

    // Show the whole Scene
    mgr->showAll();


    //Open Window
    Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f);
    Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5);
    TutorialWindow->openWindow(WinPos,
            WinSize,
            "13MeshBlending");

    //Main Loop
    TutorialWindow->mainLoop();


    osgExit();

    return 0;
}
void
OgreMeshReader::constructSubMesh(SubMeshInfo        &smInfo,
                                 VertexElementStore &vertexElements)
{
    OSG_OGRE_LOG(("OgreMeshReader::constructSubMesh: meshName '%s'"
                  "matName '%s'\n",
                  smInfo.name.c_str(), smInfo.matName.c_str()));

    if(smInfo.skelAnim == true)
    {
        smInfo.mesh = SkinnedGeometry::create();
    }
    else
    {
        smInfo.mesh = Geometry::create();
    }

    smInfo.meshN = makeNodeFor(smInfo.mesh);
    smInfo.meshN->editSFVolume()->setValue(_rootN->getVolume());

    setName(smInfo.meshN, smInfo.name);

    UInt16 nextIdx = Geometry::TexCoordsIndex;

    for(UInt32 i = 0; i < vertexElements.size(); ++i)
    {
        Int32 usage   = -1;
        Int16 propSlot = -1;

        switch(vertexElements[i].semantic)
        {
        case VES_POSITION:
            usage    = GeoProperty::UsageObjectSpace;
            propSlot = Geometry::PositionsIndex;
            break;

        case VES_BLEND_WEIGHTS:
        case VES_BLEND_INDICES:
        case VES_TEXTURE_COORDINATES:
            usage    = GeoProperty::UsageParameterSpace;
            propSlot = nextIdx++;
            break;

        case VES_BINORMAL:
        case VES_TANGENT:
            usage    = GeoProperty::UsageTangentSpace;
            propSlot = nextIdx++;
            break;

        case VES_NORMAL:
            usage    = GeoProperty::UsageTangentSpace;
            propSlot = Geometry::NormalsIndex;
            break;

        case VES_DIFFUSE:
            usage    = GeoProperty::UsageColorSpace;
            propSlot = Geometry::ColorsIndex;
            break;

        case VES_SPECULAR:
            usage    = GeoProperty::UsageColorSpace;
            propSlot = Geometry::SecondaryColorsIndex;
            break;
        }

        if(usage >= 0)
        {
            vertexElements[i].prop->setUsage(usage);
        }

        if(propSlot >= 0)
        {
            OSG_OGRE_LOG(("OgreMeshReader::constructSubMesh: vertex elem semantic '%s'"
                          " using property '%u'\n",
                          getVertexElementSemanticString(vertexElements[i].semantic).c_str(),
                          propSlot));

            smInfo.mesh->setProperty(vertexElements[i].prop, propSlot);
            smInfo.mesh->setIndex   (smInfo.propIdx,         propSlot);
        }
        else
        {
            SWARNING << "OgreMeshReader::constructSubMesh: no property slot found for "
                     << "vertex elem semantic '"
                     << getVertexElementSemanticString(vertexElements[i].semantic)
                     << "'. Skipping." << std::endl;
        }

        if(vertexElements[i].semantic == VES_BLEND_INDICES)
        {
            SkinnedGeometry* skin =
                dynamic_pointer_cast<SkinnedGeometry>(smInfo.mesh);

            skin->setJointIndexProperty(propSlot);
        }

        if(vertexElements[i].semantic == VES_BLEND_WEIGHTS)
        {
            SkinnedGeometry* skin =
                dynamic_pointer_cast<SkinnedGeometry>(smInfo.mesh);

            skin->setJointWeightProperty(propSlot);
        }
    }

    GeoUInt8PropertyUnrecPtr types = GeoUInt8Property::create();
    switch(smInfo.meshOp)
    {
    case SMO_POINT_LIST:
        types->addValue(GL_POINTS);
        break;

    case SMO_LINE_LIST:
        types->addValue(GL_LINES);
        break;

    case SMO_LINE_STRIP:
        types->addValue(GL_LINE_STRIP);
        break;

    case SMO_TRIANGLE_LIST:
        types->addValue(GL_TRIANGLES);
        break;

    case SMO_TRIANGLE_STRIP:
        types->addValue(GL_TRIANGLE_STRIP);
        break;

    case SMO_TRIANGLE_FAN:
        types->addValue(GL_TRIANGLE_FAN);
        break;
    }

    GeoUInt32PropertyUnrecPtr lengths = GeoUInt32Property::create();
    lengths->addValue(smInfo.propIdx->size());

    smInfo.mesh->setTypes  (types);
    smInfo.mesh->setLengths(lengths);

    constructMaterial(smInfo);

    if(smInfo.skelAnim == true && _skel != NULL)
    {
        SkinnedGeometry* skin = dynamic_pointer_cast<SkinnedGeometry>(smInfo.mesh);

        if(skin != NULL)
        {
            skin->setSkeleton  (_skel);
            skin->setRenderMode(SkinnedGeometry::RMSkeleton);
        }
    }

    _rootN->addChild(smInfo.meshN);
}
Node *
ColladaGeometry::createInstance(ColladaInstInfo *colInstInfo)
{
    typedef ColladaInstanceGeometry::MaterialMap        MaterialMap;
    typedef ColladaInstanceGeometry::MaterialMapConstIt MaterialMapConstIt;

    domGeometryRef geometry = getDOMElementAs<domGeometry>();
    NodeUnrecPtr   groupN   = makeCoredNode<Group>();

    OSG_COLLADA_LOG(("ColladaGeometry::createInstance id [%s]\n",
                     geometry->getId()));

    if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
       geometry->getName()                                   != NULL   )
    {
        setName(groupN, geometry->getName());
    }

    ColladaInstanceGeometryRefPtr  colInstGeo =
        dynamic_cast<ColladaInstanceGeometry *>(colInstInfo->getColInst());
    const MaterialMap             &matMap     =
        colInstGeo->getMaterialMap();

    // iterate over all parts of geometry
    GeoStoreIt gsIt   = _geoStore.begin();
    GeoStoreIt gsEnd  = _geoStore.end  ();

    for(; gsIt != gsEnd; ++gsIt)
    {
        OSG_ASSERT(gsIt->_propStore.size() == gsIt->_indexStore.size());

        // find the material associated with the geometry's material symbol
        MaterialMapConstIt mmIt       = matMap.find(gsIt->_matSymbol);
        std::string        matTarget;

        if(mmIt != matMap.end())
        {
            matTarget = mmIt->second->getTarget();
        }

        // check if the geometry was already used with that material

        GeometryUnrecPtr   geo      = NULL;
        InstanceMapConstIt instIt   = gsIt->_instMap.find(matTarget);

        if(instIt != gsIt->_instMap.end())
        {
            // reuse geometry

            geo = dynamic_pointer_cast<Geometry>(
                getInstStore()[instIt->second]);

            getGlobal()->getStatCollector()->getElem(
                ColladaGlobal::statNGeometryUsed)->inc();
        }
        else
        {
            // create new geometry

            geo = Geometry::create();

            getGlobal()->getStatCollector()->getElem(
                ColladaGlobal::statNGeometryCreated)->inc();

            geo->setLengths(gsIt->_lengths);
            geo->setTypes  (gsIt->_types  );

            handleBindMaterial(*gsIt, geo, colInstGeo);

            // record the instantiation of the geometry with the
            // material for reuse
            gsIt->_instMap.insert(
                InstanceMap::value_type(matTarget, getInstStore().size()));

            editInstStore().push_back(geo);
        }

        NodeUnrecPtr geoN = makeNodeFor(geo);

        groupN->addChild(geoN);
    }

    // store the generated group node
    editInstStore().push_back(groupN);

    return groupN;
}
void
ColladaNode::appendXForm(const Matrix      &m,
                         const std::string &xformSID,
                         InstData          &instData   )
{
    domNodeRef       node  = getDOMElementAs<domNode>();
    NodeLoaderState *state =
        getGlobal()->getLoaderStateAs<NodeLoaderState>(_loaderStateName);
    OSG_ASSERT(state != NULL);

    if(getGlobal()->getOptions()->getMergeTransforms() == true)
    {
        if(instData._bottomN == NULL)
        {
            if(node->getType() == NODETYPE_JOINT)
            {
                SkeletonJointUnrecPtr joint = SkeletonJoint::create();
                instData._bottomN           = makeNodeFor(joint);

                joint->setMatrix(m);
                joint->setJointId(state->getJointId());
            }
            else
            {
                TransformUnrecPtr xform = Transform::create();
                instData._bottomN       = makeNodeFor(xform);

                xform->setMatrix(m);
            }

            instData._localMatrix = m;
        }
        else
        {
            if(node->getType() == NODETYPE_JOINT)
            {
                SkeletonJoint *joint =
                    dynamic_cast<SkeletonJoint *>(instData._bottomN->getCore());
                OSG_ASSERT(joint != NULL);

                joint->editMatrix().mult(m);
            }
            else
            {
                Transform *xform =
                    dynamic_cast<Transform *>(instData._bottomN->getCore());
                OSG_ASSERT(xform != NULL);

                xform->editMatrix().mult(m);
            }

            instData._localMatrix.mult(m);
        }

        if(instData._topN == NULL)
            instData._topN = instData._bottomN;

        if(xformSID.empty() == false)
            instData._sidMap[xformSID] = instData._bottomN;

        if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
           node->getName()                                       != NULL &&
           getName(instData._bottomN)                            == NULL   )
        {
            std::string nodeName = node->getName();

            setName(instData._bottomN, nodeName);
        }
    }
    else
    {
        TransformUnrecPtr xform  = Transform::create();
        NodeUnrecPtr      xformN = makeNodeFor(xform);

        if(instData._bottomN != NULL)
            instData._bottomN->addChild(xformN);

        xform->setMatrix(m);
        instData._localMatrix.mult(m);

        instData._bottomN = xformN;

        if(instData._topN == NULL)
            instData._topN = instData._bottomN;

        if(xformSID.empty() == false)
            instData._sidMap[xformSID] = xformN;

        if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
           node->getName()                                       != NULL   )
        {
            std::string nodeName = node->getName();

            if(xformSID.empty() == false)
            {
                nodeName.append("."     );
                nodeName.append(xformSID);
            }

            setName(instData._bottomN, nodeName);
        }
    }
}
// Initialize GLUT & OpenSG and set up the rootNode
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

    {
        // Set up Window
        WindowEventProducerRecPtr TutorialWindow = createNativeWindow();
        TutorialWindow->initWindow();

        SimpleSceneManager sceneManager;
        TutorialWindow->setDisplayCallback(boost::bind(display, &sceneManager));
        TutorialWindow->setReshapeCallback(boost::bind(reshape, _1, &sceneManager));

        //Attach to events
        TutorialWindow->connectMousePressed(boost::bind(mousePressed, _1, &sceneManager));
        TutorialWindow->connectMouseReleased(boost::bind(mouseReleased, _1, &sceneManager));
        TutorialWindow->connectMouseMoved(boost::bind(mouseMoved, _1, &sceneManager));
        TutorialWindow->connectMouseDragged(boost::bind(mouseDragged, _1, &sceneManager));

        // Tell the Manager what to manage
        sceneManager.setWindow(TutorialWindow);

        UInt32 SceneMask(1),
               NanobotMask(2),
               PathMask(4);

        BoostPath SceneFilePath(".//Data//CellParts.osb");

        if(argc >= 2)
        {
            SceneFilePath = BoostPath(argv[1]);
            if(!boost::filesystem::exists(SceneFilePath))
            {
                SceneFilePath = BoostPath(".//Data//CellParts.osb");
            }
        }

        //Make Base Geometry Node
        NodeRecPtr SceneGeometryNode =
            SceneFileHandler::the()->read(SceneFilePath.string().c_str());
        SceneGeometryNode->setTravMask(SceneMask);
        if(SceneGeometryNode == NULL)
        {
            SceneGeometryNode = makeTorus(1.0, 10.0, 24, 24);
        }
        //Construct the Root Node
        NodeRecPtr RootNode = makeCoredNode<Group>();
        RootNode->addChild(SceneGeometryNode);

        commitChanges();

        //Create the Octree

        SLOG << "Started Building Octree" << std::endl;
        SLOG << "This may take some time ..." << std::endl;
        Time StartTime;
        StartTime = getSystemTime();
		OctreePtr TheOctree =
            Octree::buildTree(RootNode,SceneMask,6,0.5,true);

        SLOG << "Building Octree: " << getSystemTime() - StartTime << " s" << std::endl;
        Pnt3f Min,Max;
        TheOctree->getRoot()->getVolume();
        SLOG << "Octree: "<< std::endl
             << "    Depth: " << TheOctree->getDepth() << std::endl
             << "    Bounds: " << TheOctree->getRoot()->getVolume().getMin() << "  :  " << TheOctree->getRoot()->getVolume().getMax() << std::endl
             << "    NodeCount: " << TheOctree->getNodeCount() << std::endl
             << "    LeafNodeCount: " << TheOctree->getLeafNodeCount() << std::endl
             << "    BranchNodeCount: " << TheOctree->getBranchNodeCount() << std::endl
             << "    IntersectingNodeCount: " << TheOctree->getIntersectingNodeCount() << std::endl
             << "    IntersectingLeafNodeCount: " << TheOctree->getIntersectingLeafNodeCount() << std::endl;

        //Make the Nanobot Nodes
        BoostPath NanobotFilePath(".//Data//Nanobot.osb");
        NodeRecPtr NanobotGeoNode =
            SceneFileHandler::the()->read(NanobotFilePath.string().c_str());

        NanobotVector Nanobots;

        UInt32 NumNanobots(3);
        for(UInt32 i(0) ; i<NumNanobots ; ++i)
        {
            NanobotDetails TheDetails;

            //Get the Transform node for the Nanobot
            TheDetails._Transform = Transform::create();
            Matrix NanobotMatrix;
            
            Pnt3f Min,Max;
            SceneGeometryNode->getVolume().getBounds(Min,Max);
            Min = Min + ShrinkFactor;
            Max = Max - ShrinkFactor;
            NanobotMatrix.setTranslate(randomOpenPosition(Min,Max,TheOctree).subZero());
            NanobotMatrix.setScale(0.06f);
            TheDetails._Transform->setMatrix(NanobotMatrix);

            TheDetails._Node = makeNodeFor(TheDetails._Transform);
            TheDetails._Node->addChild(cloneTree(NanobotGeoNode));
            TheDetails._Node->setTravMask(NanobotMask);
            
            TheDetails._PathVisNode = Node::create();

            Nanobots.push_back(TheDetails);

            makeNanobotPath(Nanobots.back(), TheOctree, TutorialWindow, Min,Max);
        }

        for(UInt32 i(0) ; i<Nanobots.size() ; ++i)
        {
            RootNode->addChild(Nanobots[i]._Node);
            RootNode->addChild(Nanobots[i]._PathVisNode);
        }
        commitChanges();


        //NodeRecPtr StartNode = makeSphere(1.0, 2);
        //TransformRecPtr StartNodeTransform = Transform::create();
        //Matrix StartNodeMatrix;
        //StartNodeMatrix.setTranslate(Start);
        //StartNodeMatrix.setScale(0.1f);
        //StartNodeTransform->setMatrix(StartNodeMatrix);
        //NodeRecPtr StartNodeTransformNode = makeNodeFor(StartNodeTransform);
        //StartNodeTransformNode->addChild(StartNode);
        //StartNodeTransformNode->setTravMask(PathMask);
        //RootNode->addChild(StartNodeTransformNode);

        //NodeRecPtr GoalNode = makeSphere(1.0, 2);
        //TransformRecPtr GoalNodeTransform = Transform::create();
        //Matrix GoalNodeMatrix;
        //GoalNodeMatrix.setScale(0.1f);
        //GoalNodeMatrix.setTranslate(Goal);
        //GoalNodeTransform->setMatrix(GoalNodeMatrix);
        //NodeRecPtr GoalNodeTransformNode = makeNodeFor(GoalNodeTransform);
        //GoalNodeTransformNode->addChild(GoalNode);
        //GoalNodeTransformNode->setTravMask(PathMask);
        //RootNode->addChild(GoalNodeTransformNode);

        TutorialWindow->connectKeyPressed(boost::bind(keyPressed, _1,
                                                      TutorialWindow.get(),
                                                      SceneGeometryNode.get(),
                                                      TheOctree,
                                                      Nanobots));


        //Set the background
        SolidBackgroundRecPtr TheBackground = SolidBackground::create();
        TheBackground->setColor(Color3f(0.0f,0.0f,0.0f));

        // tell the manager what to manage
        sceneManager.setRoot  (RootNode);
        sceneManager.getWindow()->getPort(0)->setBackground(TheBackground);

        // show the whole RootNode
        sceneManager.showAll();

        Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f);
        Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5);
        TutorialWindow->openWindow(WinPos,
                                   WinSize,
                                   "01AStarPathing");

        //Enter main Loop
        TutorialWindow->mainLoop();
    }

    osgExit();

    return 0;
}
void PlaneMoveManipulator::onCreate(const PlaneMoveManipulator* source)
{
    // Skip direct parent, don't want the default geometry creation
    Transform::onCreate(source);

    SimpleMaterialUnrecPtr pMat = SimpleMaterial::create();
    pMat->setDiffuse(Color3f(.5, .5, .5));
    pMat->setLit    (false              );
    setMaterialX(pMat);

    pMat = SimpleMaterial::create();
    pMat->setDiffuse(Color3f(0, 1, 0));
    pMat->setLit    (false           );
    LineChunkUnrecPtr lc = LineChunk::create();
    lc->setWidth(3);
    pMat->addChunk(lc);
    setMaterialY(pMat);

    pMat = SimpleMaterial::create();
    pMat->setDiffuse(Color3f(0., 0., 1.));
    pMat->setLit    (true               );
    setMaterialZ(pMat);

//    SimpleMaterial *simpleMat;
//    Geometry       *geo;

    setExternalUpdateHandler(NULL);

    // add a name attachment
    NameUnrecPtr nameN = Name::create();
    nameN->editFieldPtr()->setValue("XYManipulator");
    addAttachment(nameN);

    // make the axis line. Not really a handle, but easier to manage this way.
       
    GeoBuilder b;
    
    b.vertex(Pnt3f(0,0,0));
    b.vertex(Pnt3f(0,getLength()[1],0));
    
    b.line(0, 1);
    
    GeometryUnrecPtr g = b.getGeometry();
    
    g->setMaterial(getMaterialY());
    
    NodeUnrecPtr pNode = makeNodeFor(g);
    setTransYNode(pNode);

    // make the plane handle

    pNode = Node::create();
    setTransXNode(pNode);

    g = makePlaneGeo(getLength()[0] / 2.f, getLength()[2] / 2.f, 1, 1);
    g->setMaterial(getMaterialX());   
    pNode = makeNodeFor(g);
    
    OSG::ComponentTransformUnrecPtr transHandleXC = ComponentTransform::create();

    setHandleXNode(pNode);

    getTransXNode()->setCore (transHandleXC   );
    getTransXNode()->addChild(getHandleXNode());

    transHandleXC->setTranslation(Vec3f(0, getLength()[1], 0));
    transHandleXC->setRotation   (Quaternion(Vec3f(1, 0, 0), osgDegree2Rad(90)));

    //
    // make the rotate handle

    pNode = Node::create();
    setTransZNode(pNode);

    g = makeCylinderGeo(0.05f, 0.1f, 16, true, true, true);
    g->setMaterial(getMaterialZ());   
    pNode = makeNodeFor(g);
    
    OSG::ComponentTransformUnrecPtr transHandleZC = ComponentTransform::create();

    setHandleZNode(pNode);

    getTransZNode()->setCore (transHandleZC   );
    getTransZNode()->addChild(getHandleZNode());

    transHandleZC->setTranslation(Vec3f(0, getLength()[1], 0));

    commitChanges();
}
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

    // Set up Window
    TutorialWindow = createNativeWindow();
    TutorialWindow->initWindow();

    TutorialWindow->setDisplayCallback(display);
    TutorialWindow->setReshapeCallback(reshape);

    //Add Window Listener
    TutorialKeyListener TheKeyListener;
    TutorialWindow->addKeyListener(&TheKeyListener);
    TutorialMouseListener TheTutorialMouseListener;
    TutorialMouseMotionListener TheTutorialMouseMotionListener;
    TutorialWindow->addMouseListener(&TheTutorialMouseListener);
    TutorialWindow->addMouseMotionListener(&TheTutorialMouseMotionListener);

    // Create the SimpleSceneManager helper
    mgr = new SimpleSceneManager;

    // Tell the Manager what to manage
    mgr->setWindow(TutorialWindow);
	
	//Print key command info
	std::cout << "\n\nKEY COMMANDS:" << std::endl;
	std::cout << "space   Play/Pause the animation" << std::endl;
	std::cout << "B       Show/Hide the bind pose skeleton" << std::endl;
	std::cout << "P       Show/Hide the current pose skeleton" << std::endl;
	std::cout << "1       Play first example animation" << std::endl;
	std::cout << "2       Play second example animation" << std::endl;
	std::cout << "CTRL-Q  Exit\n\n" << std::endl;
										

	//SkeletonDrawer System Material
	LineChunkUnrecPtr ExampleLineChunk = LineChunk::create();
    ExampleLineChunk->setWidth(2.0f);
    ExampleLineChunk->setSmooth(true);

	BlendChunkUnrecPtr ExampleBlendChunk = BlendChunk::create();
    ExampleBlendChunk->setSrcFactor(GL_SRC_ALPHA);
    ExampleBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);

	MaterialChunkUnrecPtr ExampleMaterialChunk = MaterialChunk::create();
    ExampleMaterialChunk->setAmbient(Color4f(1.0f,1.0f,1.0f,1.0f));
    ExampleMaterialChunk->setDiffuse(Color4f(0.0f,0.0f,0.0f,1.0f));
    ExampleMaterialChunk->setSpecular(Color4f(0.0f,0.0f,0.0f,1.0f));

	ChunkMaterialUnrecPtr ExampleMaterial = ChunkMaterial::create();
    ExampleMaterial->addChunk(ExampleLineChunk);
    ExampleMaterial->addChunk(ExampleMaterialChunk);
    ExampleMaterial->addChunk(ExampleBlendChunk);

    GeometryRefPtr SphereGeometry = makeSphereGeo(2, 0.25f);
    GeometryRefPtr BoxGeometry = makeBoxGeo(0.5f,0.5f,0.5f,1,1,1);

    //Skeleton
    SkeletonBlendedGeometryUnrecPtr ExampleSkeleton = SkeletonBlendedGeometry::create();

    //Joint
	JointRecPtr ExampleRootJoint = Joint::create();

    //Add this joint to the skeleton
    ExampleSkeleton->pushToJoints(ExampleRootJoint, Matrix());

    NodeRecPtr ExampleRootJointNode = makeNodeFor(ExampleRootJoint);

    NodeRecPtr TempRootJointNode = ExampleRootJointNode;
    NodeRefPtr GeoNode = makeNodeFor(BoxGeometry);
    TempRootJointNode->addChild(GeoNode);

	Matrix TempMat;
	//Create a set of randomly placed child joints
	for (Real32 i = 0.0f; i < 5.0f; ++i)
	{
		JointRecPtr ExampleChildJoint = Joint::create();
		NodeRecPtr ExampleChildJointNode = makeNodeFor(ExampleChildJoint);

        GeoNode = makeNodeFor(SphereGeometry);
        ExampleChildJointNode->addChild(GeoNode);

		//TempMat.setTranslate(RandomPoolManager::getRandomReal32(0.0, 10.0f), RandomPoolManager::getRandomReal32(0.0f, 10.0f), RandomPoolManager::getRandomReal32(0.0f, 10.0f));
        switch((static_cast<UInt32>(i) % 3))
        {
            case 0:
                TempMat.setTranslate(2.0f,0.0f,0.0f);
                break;
            case 1:
                TempMat.setTranslate(0.0f,2.0f,0.0f);
                break;
            case 2:
                TempMat.setTranslate(0.0f,0.0f,2.0f);
                break;
        }
		
		//Set bind and current transformations to TempMat (calculated above)
        ExampleChildJoint->setJointTransformation(TempMat);

		//Add ExampleChildJoint as a child to the previous joint	
        TempRootJointNode->addChild(ExampleChildJointNode);//add a Child to the root joint

		//ExampleChildJoint will be the next parent joint
		TempRootJointNode = ExampleChildJointNode;
        
        //Add this joint to the skeleton
        Matrix InvBind(TempRootJointNode->getToWorld());
        InvBind.invert();
        ExampleSkeleton->pushToJoints(ExampleChildJoint, InvBind);
	}

    //SkeletonDrawer
    SkeletonDrawableUnrecPtr ExampleSkeletonDrawable = SkeletonDrawable::create();
    ExampleSkeletonDrawable->setSkeleton(ExampleSkeleton);
    ExampleSkeletonDrawable->setMaterial(ExampleMaterial);
    ExampleSkeletonDrawable->setDrawBindPose(false);  //By default, we won't draw the skeleton's bind pose
    ExampleSkeletonDrawable->setBindPoseColor(Color4f(0.0, 1.0, 0.0, 1.0));  //When the skeleton's bind pose is rendered, it will be green
    ExampleSkeletonDrawable->setDrawPose(true);  //By default, we do draw the skeleton's current pose
    ExampleSkeletonDrawable->setPoseColor(Color4f(0.0, 0.0, 1.0, 1.0));  //The skeleton's current pose is rendered in blue
	
	//Skeleton Node
	SkeletonNode = Node::create();
    SkeletonNode->setCore(ExampleSkeletonDrawable);

    //Create scene
    NodeUnrecPtr scene = Node::create();
    scene->setCore(Group::create());
    scene->addChild(SkeletonNode);
    scene->addChild(ExampleRootJointNode);

    mgr->setRoot(scene);

	//Setup the Animation
	setupAnimation(ExampleRootJoint,
                   dynamic_cast<Joint*>(ExampleRootJointNode->getChild(1)->getCore()));

	//Set the currently playing animation to TheJointAnimation (can be switched at runtime via a key command)
	TheCurrentAnimation = TheJointAnimation;


    // Show the whole Scene
    mgr->showAll();


    //Open Window
    Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f);
    Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5);
    TutorialWindow->openWindow(WinPos,
                        WinSize,
                                        "11BoneAnimation");

    //Main Loop
    TutorialWindow->mainLoop();

    osgExit();

    return 0;
}
// Initialize GLUT & OpenSG and set up the scene
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

    {
        // Set up Window
        WindowEventProducerRecPtr TutorialWindow = createNativeWindow();

        //Initialize Window
        TutorialWindow->initWindow();

        SimpleSceneManager sceneManager;
        TutorialWindow->setDisplayCallback(boost::bind(display, &sceneManager));
        TutorialWindow->setReshapeCallback(boost::bind(reshape, _1, &sceneManager));

        // Tell the Manager what to manage
        sceneManager.setWindow(TutorialWindow);

        //Attach to events
        TutorialWindow->connectMousePressed(boost::bind(mousePressed, _1, &sceneManager));
        TutorialWindow->connectMouseReleased(boost::bind(mouseReleased, _1, &sceneManager));
        TutorialWindow->connectMouseDragged(boost::bind(mouseDragged, _1, &sceneManager));
        TutorialWindow->connectMouseWheelMoved(boost::bind(mouseWheelMoved, _1, &sceneManager));

        BoostPath FilePath("../Animation/Data/Nanobot.dae");
        if(argc >= 2)
        {
            FilePath = BoostPath(argv[1]);
            if(!boost::filesystem::exists(FilePath))
            {
                std::cerr << "Could not load file: "<< FilePath.string()
                          << ", because no such files exists."<< std::endl;
                FilePath = BoostPath("../Animation/Data/Nanobot.dae");
            }
        }

        NodeRefPtr LoadedRoot;
        std::vector<AnimationRecPtr> LoadedAnimations;

        FCFileType::FCPtrStore ObjStore;
        try
        {
            ObjStore = FCFileHandler::the()->read(FilePath);
        }
        catch(std::exception &ex)
        {
            std::cerr << "Failed to load file: " << FilePath.string() << ", error:"
                     << ex.what()                        << std::endl;
            return -1;
        }
        for(FCFileType::FCPtrStore::iterator StorItor(ObjStore.begin());
            StorItor != ObjStore.end();
            ++StorItor)
        {
            //Animations
            if((*StorItor)->getType().isDerivedFrom(Animation::getClassType()))
            {
                LoadedAnimations.push_back(dynamic_pointer_cast<Animation>(*StorItor));
                LoadedAnimations.back()->attachUpdateProducer(TutorialWindow);
                LoadedAnimations.back()->start();
            }
            //Root Node
            if((*StorItor)->getType() == Node::getClassType() &&
                    dynamic_pointer_cast<Node>(*StorItor)->getParent() == NULL)
            {
                LoadedRoot = dynamic_pointer_cast<Node>(*StorItor);
            }
        }

        if(LoadedRoot == NULL)
        {
            LoadedRoot = SceneFileHandler::the()->read(FilePath.string().c_str());
        }

        if(LoadedRoot == NULL)
        {
            LoadedRoot= makeTorus(.5, 2, 32, 32);
        }

        //Make the fog node
        PostShaderStageRecPtr PostShaderStageCore = PostShaderStage::create();
        PostShaderStageCore->clearPasses();
        PostShaderStageCore->addPass("", generateNoEffectProg());


        DirectionalLightRecPtr SceneLightCore = DirectionalLight::create();
        SceneLightCore->setAmbient(Color4f(0.2f, 0.2f, 0.2f, 1.0f));
        SceneLightCore->setDiffuse(Color4f(0.8f, 0.8f, 0.8f, 1.0f));
        SceneLightCore->setSpecular(Color4f(1.0f, 1.0f, 1.0f, 1.0f));

        NodeRefPtr SceneLight = makeNodeFor(SceneLightCore);
        SceneLight->addChild(LoadedRoot);

        NodeRefPtr PostShaderStageNode = makeNodeFor(PostShaderStageCore);
        PostShaderStageNode->addChild(SceneLight);

        //Make Main Scene Node
        NodeRefPtr scene = makeCoredNode<Group>();

        scene->addChild(PostShaderStageNode);

        // tell the manager what to manage
        sceneManager.setRoot  (scene);
        SceneLightCore->setBeacon(sceneManager.getCamera()->getBeacon());

        //Create the Documentation Foreground and add it to the viewport
        SimpleScreenDoc TheSimpleScreenDoc(&sceneManager, TutorialWindow);

        // show the whole scene
        sceneManager.showAll();

        sceneManager.getWindow()->getPort(0)->setTravMask(1);
        RenderOptionsRecPtr ViewportRenderOptions = RenderOptions::create();
        ViewportRenderOptions->setRenderProperties(0x0);
        ViewportRenderOptions->setRenderProperties(RenderPropertiesPool::the()->getFrom1("Default"));
        ViewportRenderOptions->setRenderProperties(0x01);

        sceneManager.getWindow()->getPort(0)->setRenderOptions(ViewportRenderOptions);

        Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f);
        Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5);
        TutorialWindow->openWindow(WinPos,
                                   WinSize,
                                   "Collada Loader");

        TutorialWindow->connectKeyPressed(boost::bind(keyPressed, _1,
                                                      TutorialWindow.get(),
                                                      PostShaderStageCore.get()));

        //Enter main Loop
        TutorialWindow->mainLoop();

    }

    osgExit();

    return 0;
}
// Initialize GLUT & OpenSG and set up the rootNode
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

    {
        // Set up Window
        WindowEventProducerRecPtr TutorialWindow = createNativeWindow();
        TutorialWindow->initWindow();

        SimpleSceneManager sceneManager;
        TutorialWindow->setDisplayCallback(boost::bind(display, &sceneManager));
        TutorialWindow->setReshapeCallback(boost::bind(reshape, _1, &sceneManager));

        //Attach to events
        TutorialWindow->connectMousePressed(boost::bind(mousePressed, _1, &sceneManager));
        TutorialWindow->connectMouseReleased(boost::bind(mouseReleased, _1, &sceneManager));
        TutorialWindow->connectMouseMoved(boost::bind(mouseMoved, _1, &sceneManager));
        TutorialWindow->connectMouseDragged(boost::bind(mouseDragged, _1, &sceneManager));
        TutorialWindow->connectKeyPressed(boost::bind(keyPressed,_1));

        // Tell the Manager what to manage
        sceneManager.setWindow(TutorialWindow);

        UInt32 SceneMask(1),
               PathMask(4);

        BoostPath SceneFilePath(".//Data//CellParts.osb");

        if(argc >= 2)
        {
            SceneFilePath = BoostPath(argv[1]);
            if(!boost::filesystem::exists(SceneFilePath))
            {
                SceneFilePath = BoostPath(".//Data//CellParts.osb");
            }
        }

        //Make Base Geometry Node
        NodeRecPtr SceneGeometryNode =
            SceneFileHandler::the()->read(SceneFilePath.string().c_str());
        SceneGeometryNode->setTravMask(SceneMask);
        if(SceneGeometryNode == NULL)
        {
            SceneGeometryNode = makeTorus(1.0, 10.0, 24, 24);
        }

        //Construct the Root Node
        NodeRecPtr RootNode = makeCoredNode<Group>();
        RootNode->addChild(SceneGeometryNode);
        commitChanges();

        //Create the Octree

        SLOG << "Started Building Octree" << std::endl;
        SLOG << "This may take some time ..." << std::endl;
        Time StartTime;
        StartTime = getSystemTime();
		OctreePtr TheOctree =
            Octree::buildTree(RootNode,SceneMask,6,1.5,true);

        SLOG << "Building Octree: " << getSystemTime() - StartTime << " s" << std::endl;
        Pnt3f Min,Max;
        TheOctree->getRoot()->getVolume();
        SLOG << "Octree: "<< std::endl
             << "    Depth: " << TheOctree->getDepth() << std::endl
             << "    Bounds: " << TheOctree->getRoot()->getVolume().getMin() << "  :  " << TheOctree->getRoot()->getVolume().getMax() << std::endl
             << "    NodeCount: " << TheOctree->getNodeCount() << std::endl
             << "    LeafNodeCount: " << TheOctree->getLeafNodeCount() << std::endl
             << "    BranchNodeCount: " << TheOctree->getBranchNodeCount() << std::endl
             << "    IntersectingNodeCount: " << TheOctree->getIntersectingNodeCount() << std::endl
             << "    IntersectingLeafNodeCount: " << TheOctree->getIntersectingLeafNodeCount() << std::endl;

        //Create the Path Geometry
        //Generate the Path
        OctreeAStarAlgorithm AlgorithmObj;
        SLOG << "Started AStar Search" << std::endl;
        StartTime = getSystemTime();
        Pnt3f Start(-4.01f,1.01f,10.01f),Goal(-4.01f,-0.01f,-7.01f);
        std::vector<Pnt3f> Path =
            AlgorithmObj.search(TheOctree,Start,Goal);
        Path.front() = Start;
        Path.back() = Goal;
        SLOG << "Finished AStar Search: " << getSystemTime() - StartTime << " s" << std::endl;

        NodeRecPtr PathNode = createPathGeometry(Path);
        PathNode->setTravMask(PathMask);
        RootNode->addChild(PathNode);

        NodeRecPtr StartNode = makeSphere(1.0, 2);
        TransformRecPtr StartNodeTransform = Transform::create();
        Matrix StartNodeMatrix;
        StartNodeMatrix.setTranslate(Start);
        StartNodeMatrix.setScale(0.1f);
        StartNodeTransform->setMatrix(StartNodeMatrix);
        NodeRecPtr StartNodeTransformNode = makeNodeFor(StartNodeTransform);
        StartNodeTransformNode->addChild(StartNode);
        StartNodeTransformNode->setTravMask(PathMask);
        RootNode->addChild(StartNodeTransformNode);

        NodeRecPtr GoalNode = makeSphere(1.0, 2);
        TransformRecPtr GoalNodeTransform = Transform::create();
        Matrix GoalNodeMatrix;
        GoalNodeMatrix.setScale(0.1f);
        GoalNodeMatrix.setTranslate(Goal);
        GoalNodeTransform->setMatrix(GoalNodeMatrix);
        NodeRecPtr GoalNodeTransformNode = makeNodeFor(GoalNodeTransform);
        GoalNodeTransformNode->addChild(GoalNode);
        GoalNodeTransformNode->setTravMask(PathMask);
        RootNode->addChild(GoalNodeTransformNode);


        //Set the background
        SolidBackgroundRecPtr TheBackground = SolidBackground::create();
        TheBackground->setColor(Color3f(0.0f,0.0f,0.0f));

        // tell the manager what to manage
        sceneManager.setRoot  (RootNode);
        sceneManager.getWindow()->getPort(0)->setBackground(TheBackground);

        // show the whole RootNode
        sceneManager.showAll();

        Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f);
        Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5);
        TutorialWindow->openWindow(WinPos,
                                   WinSize,
                                   "01AStarPathing");

        //Enter main Loop
        TutorialWindow->mainLoop();
    }

    osgExit();

    return 0;
}