OGRE/kody/MyApp2 1.ccp
< OGRE
#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