OGRE/kody/MyApp2 1.ccp

Z Wikibooks, biblioteki wolnych podręczników.
#define OGRE_CHANGE1 ((1 << 16) | (1 << 8)) /* Przeznaczone do wykrywania wersji Ogre */

#include "Ogre.h"     /* Wszystkie nagłówki OGRE */
#include "ExampleApplication.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32   /* W zależności od systemu operacyjnego */
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#else
#include <iostream>
#endif

#include <deque>
using namespace std;

class MoveDemoListener : public ExampleFrameListener
{
public:

   MoveDemoListener(RenderWindow* win, Camera* cam, SceneNode *sn,
       Entity *ent, deque<Vector3> &walk)
       : ExampleFrameListener(win, cam, false, false), mNode(sn), mEntity(ent), mWalkList( walk )
   {
       // Konfiguracja animacji
       //mAnimationState = ent->getAnimationState( "Idle" );
       //mAnimationState->setLoop( true );
       //mAnimationState->setEnabled( true );

       // Ustawianie domyślnych wartości zmiennych
       mWalkSpeed = 35.0f;
       mDirection = Vector3::ZERO;

   } // MoveDemoListener

   // Funkcja ta jest wywoływana podczas przemieszczania obiektu do następnych pozycji w mWalkList.
   bool nextLocation( )
   {
       if ( mWalkList.empty() )
           return false;

       mDestination = mWalkList.front( );  // this gets the front of the deque
       mWalkList.pop_front( );             // this removes the front of the deque

       mDirection = mDestination - mNode->getPosition( );
       mDistance = mDirection.normalise( );

       return true;
   } // nextLocation( )

   bool frameStarted(const FrameEvent &evt)
   {
       if ( mDirection == Vector3::ZERO ) 
       {
           if ( nextLocation() ) 
           {
               // Set walking animation
               mAnimationState = mEntity->getAnimationState( "Walk" );
               mAnimationState->setLoop( true );
               mAnimationState->setEnabled( true );
           }
       }
       else
       {
           Real move = mWalkSpeed * evt.timeSinceLastFrame;
           mDistance -= move;
           if (mDistance <= 0.0f)
           {
              mNode->setPosition( mDestination );
              mDirection = Vector3::ZERO;
              // Ta animacja ustawiana jest jesli już dalej nie mamy gdzie iść. 
              if (! nextLocation( ) )
              {
                  // Set Idle animation                     
                  mAnimationState = mEntity->getAnimationState( "Idle" );
                  mAnimationState->setLoop( true );
                  mAnimationState->setEnabled( true );
              } 
              else
              {
                  // Tu później wstawimy kod obracjący robota
   	           //Vector3 src = mNode->getOrientation( ) * Vector3::UNIT_X;
                  //Ogre::Quaternion quat = src.getRotationTo( mDirection );
                  //mNode->rotate( quat );
                  Vector3 src = mNode->getOrientation( ) * Vector3::UNIT_X;
                  if ( (1.0f + src.dotProduct( mDirection )) < 0.0001f ) 
                  {
                    mNode->yaw( Degree(180) );
                  }
                  else
                  {
                    Ogre::Quaternion quat = src.getRotationTo( mDirection );
                    mNode->rotate( quat );
                  } // else
              }
           }
           else
           {
               mNode->translate( mDirection * move );
           } // else
       } // if

       mAnimationState->addTime( evt.timeSinceLastFrame );
       return ExampleFrameListener::frameStarted(evt);
   }
protected:
   Real mDistance;                  // Dystans który pozostał do przesunięcia
   Vector3 mDirection;              // Kierunek ruchu
   Vector3 mDestination;            // Punkt docelowy

   AnimationState *mAnimationState; // Bieżący stan animacji jednostki

   Entity *mEntity;                 // Jednostka którą animujemy
   SceneNode *mNode;                // Węzeł sceny tejże jednostki
   std::deque<Vector3> mWalkList;   // Lista zawierająca punkty ruchu

   Real mWalkSpeed;                 // Szybkość poruszającej się jednostki
};

// Dziedziczymy ExampleApplication
class MyApp : public ExampleApplication
{
 protected:
 public:
   MyApp()
   {
   }

   ~MyApp() 
   {
   }
 protected:
   Entity *mEntity;                // Jednostka którą będziemy animować
   SceneNode *mNode;               // Węzeł sceny dla poruszającej się jednostki
   std::deque<Vector3> mWalkList;  // Lista zawierająca punkty ruchu

   void createFrameListener(void)
   {
       mFrameListener= new MoveDemoListener(mWindow, mCamera, mNode, mEntity, mWalkList);
       mFrameListener->showDebugOverlay(true);
       mRoot->addFrameListener(mFrameListener);
   }

   /** createScene jest funkcją czysto wirtualną w ExampleApplication,
    *  nadpisujemy ją, aby nic nie robiła.
    *  Na początku tworzy ona pustą scenę.
    **/
   void createScene(void)
   {
       // Ustawianie domyślnego światła
       mSceneMgr->setAmbientLight( ColourValue( 1.0f, 1.0f, 1.0f ) );

       // Tworzenie jednostki
       mEntity = mSceneMgr->createEntity( "Robot", "robot.mesh" );

       // Tworzenie węzła sceny
       mNode = mSceneMgr->getRootSceneNode( )->
           createChildSceneNode( "RobotNode", Vector3( 0.0f, 0.0f, 25.0f ) );
       mNode->attachObject( mEntity );

       // Tworzenie listy punktów, po których ma się przesuwać robot
       mWalkList.push_back( Vector3( 550.0f,  0.0f,  50.0f  ) );
       mWalkList.push_back( Vector3(-100.0f,  0.0f, -200.0f ) );

       // Tworzymy węzełki, dzięki którym możemy zobaczyć ruch
       Entity *ent;
       SceneNode *node;

       ent = mSceneMgr->createEntity( "Knot1", "knot.mesh" );
       node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "Knot1Node",
           Vector3(  0.0f, -10.0f,  25.0f ) );
       node->attachObject( ent );
       node->setScale( 0.1f, 0.1f, 0.1f );

       ent = mSceneMgr->createEntity( "Knot2", "knot.mesh" );
       node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "Knot2Node",
           Vector3( 550.0f, -10.0f,  50.0f ) );
       node->attachObject( ent );
       node->setScale( 0.1f, 0.1f, 0.1f );

       ent = mSceneMgr->createEntity( "Knot3", "knot.mesh" );
       node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "Knot3Node",
           Vector3(-100.0f, -10.0f,-200.0f ) );
       node->attachObject( ent );
       node->setScale( 0.1f, 0.1f, 0.1f );

       // Ustawiamy kamerę, żeby patrzyła na naszą pracę
       mCamera->setPosition( 90.0f, 280.0f, 535.0f );
       mCamera->pitch( Degree(-30.0f) );
       mCamera->yaw( Degree(-15.0f) );
   }
};

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32   /* W zalezności od systemu operacyjnego */
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
 MyApp App;     // Tworzymy instancję naszej klasy
  try
  {
    App.go();       // ExampleApplication dostarcza metodę go, która rozpoczyna rendering
    return 0;   // Zwraca 0 w przypadku powodzenia
  }
  catch (Ogre::Exception& e)  // Przechwytuje wyjątki (błędy)
  {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32   // W zależności od systemu operacyjnego
    MessageBox( NULL, e.getFullDescription().c_str(), "Wyjątek!",
          MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
    std::cerr <<"Wyjątek:\n";
    std::cerr <<e.getFullDescription().c_str() <<"\n";
#endif
    return 1;   // Zwrócenie liczby różnej od zera oznacza niepowodzenie
  }
}

#ifdef __cplusplus
}
#endif