bool LightingDemo2::init()
{
    if (RenderCore::init() == false)
    {
        return false;
    }

    mWaves.Init(160, 160, 1.0f, 0.03f, 5.0f, 0.3f);

    // Must init Effects first since InputLayouts depend on shader signatures.
    EffectMgr::initAll(md3dDevice);
    InputLayoutMgr::initAll(md3dDevice);
    RenderStateMgr::initAll(md3dDevice);

    HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice, L"../Textures/grass.dds", 0, 0, &mGrassMapSRV, 0 ));
    HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice, L"../Textures/water2.dds", 0, 0, &mWavesMapSRV, 0 ));
    HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice, L"../Textures/WireFence.dds", 0, 0, &mBoxMapSRV, 0 ));
    HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice, L"../Textures/cig_texture2.dds", 0, 0, &mCigMapSRV, 0 ));

    //buildSceneBuffers();
    buildSkull();
    buildCigar();
    buildBox();
    buildLand();
    buildWave();

    return true;
}
 virtual void keyPressed(const KeyEventPtr e)
 {
     if(e->getKey() == KeyEvent::KEY_Q && e->getModifiers() & KeyEvent::KEY_MODIFIER_COMMAND)
     {
          TutorialWindowEventProducer->closeWindow();
     }
     switch(e->getKey())
     {
     case KeyEvent::KEY_S:
          {
              buildSphere();
          }
          break;
     case KeyEvent::KEY_B:
          {
              buildBox();
          }
          break;
     case KeyEvent::KEY_Z:
          {
              //SceneFileHandler::the().write(rootNode, "scene.osb");
          }
          break;
     case KeyEvent::KEY_T:
          {
              buildTriMesh();
          }
          break;
     }
 }
void keyPressed(KeyEventDetails* const details,
                Node* const spaceGroupNode,
                PhysicsWorld* const physicsWorld,
                PhysicsHashSpace* const physicsSpace)
{
    if(details->getKey() == KeyEventDetails::KEY_Q &&
       details->getModifiers() & KeyEventDetails::KEY_MODIFIER_COMMAND)
    {
        dynamic_cast<WindowEventProducer*>(details->getSource())->closeWindow();
    }
    switch(details->getKey())
    {
        case KeyEventDetails::KEY_B:
            buildBox(Pnt3f((Real32)(rand()%100)-50.0,(Real32)(rand()%100)-50.0,55.0),
                     Vec3f(10.0,10.0,10.0),
                     Color3f(0.0f,1.0f,0.0f),
                     spaceGroupNode,
                     physicsWorld,
                     physicsSpace);
            break;
        case KeyEventDetails::KEY_UP:
            _IsUpKeyDown = true;
            break;
        case KeyEventDetails::KEY_DOWN:
            _IsDownKeyDown = true;
            break;
        case KeyEventDetails::KEY_LEFT:
            _IsLeftKeyDown = true;
            break;
        case KeyEventDetails::KEY_RIGHT:
            _IsRightKeyDown = true;
            break;
        case KeyEventDetails::KEY_A:
            _IsAKeyDown = true;
            break;
        case KeyEventDetails::KEY_D:
            _IsDKeyDown = true;
            break;
        case KeyEventDetails::KEY_SPACE:
            _ShouldJump = true;
            break;
    }
}
void keyPressed(KeyEventDetails* const details,
                Node* const TriGeometryBase,
                Node* const spaceGroupNode,
                Node* const PhysDrawableNode,
                PhysicsWorld* const physicsWorld,
                PhysicsHashSpace* const physicsSpace)
{
    if(details->getKey() == KeyEventDetails::KEY_Q &&
       details->getModifiers() & KeyEventDetails::KEY_MODIFIER_COMMAND)
    {
        dynamic_cast<WindowEventProducer*>(details->getSource())->closeWindow();
    }
    switch(details->getKey())
    {
        case KeyEventDetails::KEY_S:
            {
                buildSphere(spaceGroupNode, physicsWorld, physicsSpace);
            }
            break;
        case KeyEventDetails::KEY_B:
            {
                buildBox(spaceGroupNode, physicsWorld, physicsSpace);
            }
            break;
        case KeyEventDetails::KEY_T:
            {
                buildTriMesh(TriGeometryBase, spaceGroupNode, physicsWorld, physicsSpace);
            }
            break;
        case KeyEventDetails::KEY_D:
            {
                if(PhysDrawableNode->getTravMask())
                {
                    PhysDrawableNode->setTravMask(TypeTraits<UInt32>::getMin());
                }
                else
                {
                    PhysDrawableNode->setTravMask(TypeTraits<UInt32>::getMax());
                }
            }
            break;
    }
}
 virtual void keyPressed(const KeyEventUnrecPtr e)
 {
     if(e->getKey() == KeyEvent::KEY_Q && e->getModifiers() & KeyEvent::KEY_MODIFIER_COMMAND)
     {
         TutorialWindow->closeWindow();
     }
     switch(e->getKey())
     {
     case KeyEvent::KEY_S:
          {
              allPhysicsBodies.push_back(buildSphere());
          }
          break;
     case KeyEvent::KEY_B:
          {
              allPhysicsBodies.push_back(buildBox());
          }
          break;
     case KeyEvent::KEY_E:
         makeExplosion(Pnt3f(0.0f,0.0f,-5.0f), 1280.0f);
         break;
     case KeyEvent::KEY_1:
         makeExplosion(Pnt3f(0.0f,0.0f,-5.0f), 20.0f);
         break;
     case KeyEvent::KEY_2:
         makeExplosion(Pnt3f(0.0f,0.0f,-5.0f), 80.0f);
         break;
     case KeyEvent::KEY_3:
         makeExplosion(Pnt3f(0.0f,0.0f,-5.0f), 320.0f);
         break;
     case KeyEvent::KEY_4:
         makeExplosion(Pnt3f(0.0f,0.0f,-5.0f), 1280.0f);
         break;
     case KeyEvent::KEY_5:
         makeExplosion(Pnt3f(0.0f,0.0f,-5.0f), 5120.0f);
         break;
     case KeyEvent::KEY_6:
         makeExplosion(Pnt3f(0.0f,0.0f,-5.0f), 20480.0f);
         break;
     }
 }
   virtual void keyPressed(const KeyEventUnrecPtr e)
   {
       if(e->getKey() == KeyEvent::KEY_Q && e->getModifiers() & KeyEvent::KEY_MODIFIER_CONTROL)
       {
           TutorialWindow->closeWindow();
       }
       switch(e->getKey())
       {
       case KeyEvent::KEY_B:
           buildBox(Vec3f(10.0,10.0,10.0), Pnt3f((Real32)(rand()%100)-50.0,(Real32)(rand()%100)-50.0,25.0));
           break;
	   case KeyEvent::KEY_UP:
           _IsUpKeyDown = true;
		   break;
	   case KeyEvent::KEY_DOWN:
           _IsDownKeyDown = true;
		   break;
	   case KeyEvent::KEY_LEFT:
           _IsLeftKeyDown = true;
		   break;
	   case KeyEvent::KEY_RIGHT:
           _IsRightKeyDown = true;
           break;
       case KeyEvent::KEY_D:
            {
                if(PhysDrawableNode->getTravMask())
                {
                    PhysDrawableNode->setTravMask(TypeTraits<UInt32>::getMin());
                }
                else
                {
                    PhysDrawableNode->setTravMask(TypeTraits<UInt32>::getMax());
                }
            }
            break;
       }
   }
 virtual void keyPressed(const KeyEventUnrecPtr e)
 {
     if(e->getKey() == KeyEvent::KEY_Q && e->getModifiers() & KeyEvent::KEY_MODIFIER_COMMAND)
     {
         TutorialWindow->closeWindow();
     }
     switch(e->getKey())
     {
         case KeyEvent::KEY_S:
             {
                 buildSphere();
             }
             break;
         case KeyEvent::KEY_B:
             {
                 buildBox();
             }
             break;
         case KeyEvent::KEY_T:
             {
                 buildTriMesh();
             }
             break;
         case KeyEvent::KEY_D:
             {
                 if(PhysDrawableNode->getTravMask())
                 {
                     PhysDrawableNode->setTravMask(TypeTraits<UInt32>::getMin());
                 }
                 else
                 {
                     PhysDrawableNode->setTravMask(TypeTraits<UInt32>::getMax());
                 }
             }
             break;
     }
 }
// Initialize GLUT & OpenSG and set up the rootNode
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

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

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

    TutorialKeyListener TheKeyListener;
    TutorialWindow->addKeyListener(&TheKeyListener);
    TutorialMouseListener TheTutorialMouseListener;
    TutorialMouseMotionListener TheTutorialMouseMotionListener;
    TutorialWindow->addMouseListener(&TheTutorialMouseListener);
    TutorialWindow->addMouseMotionListener(&TheTutorialMouseMotionListener);
	TutorialUpdateListener TheTutorialUpdateListener;
    TutorialWindow->addUpdateListener(&TheTutorialUpdateListener);


    // Create the SimpleSceneManager helper
    mgr = new SimpleSceneManager;

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

    //Make Main Scene Node
	NodeRefPtr scene = makeCoredNode<Group>();
    setName(scene, "scene");
    rootNode = Node::create();
    setName(rootNode, "rootNode");
    ComponentTransformRefPtr Trans;
    Trans = ComponentTransform::create();
    {
        rootNode->setCore(Trans);
 
        // add the torus as a child
        rootNode->addChild(scene);
    }

    //Make The Physics Characteristics Node
    PhysicsCharacteristicsDrawableUnrecPtr PhysDrawable = PhysicsCharacteristicsDrawable::create();
        PhysDrawable->setRoot(rootNode);

	PhysDrawableNode = Node::create();
    PhysDrawableNode->setCore(PhysDrawable);
    PhysDrawableNode->setTravMask(TypeTraits<UInt32>::getMin());

    rootNode->addChild(PhysDrawableNode);

    //Light Beacon
    NodeRefPtr TutorialLightBeacon = makeCoredNode<Transform>();

    //Light Node
    DirectionalLightRefPtr TutorialLight = DirectionalLight::create();
    TutorialLight->setDirection(0.0,0.0,-1.0);
    TutorialLight->setBeacon(TutorialLightBeacon);

    NodeRefPtr TutorialLightNode = Node::create();
    TutorialLightNode->setCore(TutorialLight);

    scene->addChild(TutorialLightNode);
    scene->addChild(TutorialLightBeacon);


    //Setup Physics Scene
    physicsWorld = PhysicsWorld::create();
        physicsWorld->setWorldContactSurfaceLayer(0.01);
        physicsWorld->setAutoDisableFlag(1);
        physicsWorld->setAutoDisableTime(0.75);
        physicsWorld->setWorldContactMaxCorrectingVel(1.0);
        //physicsWorld->setGravity(Vec3f(0.0, 0.0, -9.81));
        //physicsWorld->setCfm(0.001);
        //physicsWorld->setErp(0.2);

    hashSpace = PhysicsHashSpace::create();

    physHandler = PhysicsHandler::create();
        physHandler->setWorld(physicsWorld);
        physHandler->pushToSpaces(hashSpace);
        physHandler->setUpdateNode(rootNode);
    physHandler->attachUpdateProducer(TutorialWindow->editEventProducer());
    

        rootNode->addAttachment(physHandler);    
        rootNode->addAttachment(physicsWorld);
        rootNode->addAttachment(hashSpace);


	/************************************************************************/
	/* create spaces, geoms and bodys                                                                     */
	/************************************************************************/
    //create a group for our space
    GroupRefPtr spaceGroup;
	spaceGroupNode = makeCoredNode<Group>(&spaceGroup);
	//add Attachments to nodes...
	    spaceGroupNode->addAttachment(hashSpace);

	    TutorialLightNode->addChild(spaceGroupNode);

    //Create Character
    ShipBody = buildShip(Vec3f(3.0,3.0,10.0), Pnt3f((Real32)(rand()%100)-50.0,(Real32)(rand()%100)-50.0,25.0));
    ShipMotor = buildMotor(ShipBody);

    for(UInt32 i(0) ; i<5 ; ++i)
    {
        buildBox(Vec3f(10.0,10.0,10.0), Pnt3f((Real32)(rand()%100)-50.0,(Real32)(rand()%100)-50.0,25.0));
    }

    // tell the manager what to manage
    mgr->setRoot  (rootNode);

    // show the whole rootNode
    mgr->showAll();
    
    Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f);
    Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5);
    TutorialWindow->openWindow(WinPos,
            WinSize,
            "04ZeroGravityShip");

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

    osgExit();

    return 0;
}