原文参考:http://wiki.ogrecn.com/wiki/index.php?title=%E6%96%87%E6%A1%A3:%E6%95%99%E7%A8%8B:%E4%B8%AD%E7%BA%A7%E6%95%99%E7%A8%8B:%E4%B8%AD%E7%BA%A7%E6%95%99%E7%A8%8B%E4%B8%80
这次主要是实现Ogre里的动画,以及结合之前的四元数的使用。具体代码如下:
001 | #include "ExampleApplication.h" |
002 | |
003 | #include |
004 | |
005 | using namespace std; |
006 | |
007 | class MoveDemoListener : public ExampleFrameListener |
008 | { |
009 | public : |
010 | |
011 | MoveDemoListener(RenderWindow* win, Camera* cam, SceneNode *sn, |
012 | Entity *ent, std::deque &walk) |
013 | : ExampleFrameListener(win, cam, false , false ), mNode(sn), mEntity(ent), mWalkList( walk ) |
014 | { |
015 | //mAnimationState = ent->getAnimationState("Idle"); |
016 | //mAnimationState->setLoop(true); |
017 | //mAnimationState->setEnabled(true); |
018 | mWalkSpeed = 35.0f; |
019 | mDirection = Vector3::ZERO; |
020 | |
021 | } // MoveDemoListener |
022 | |
023 | bool nextLocation( ) |
024 | { |
025 | if (mWalkList.empty()) |
026 | return false ; |
027 | |
028 | mDestination = mWalkList.front(); // this gets the front of the deque |
029 | mWalkList.pop_front(); // this removes the front of the deque |
030 | |
031 | mDirection = mDestination - mNode->getPosition(); |
032 | mDistance = mDirection.normalise(); |
033 | |
034 | return true ; |
035 | } // nextLocation( ) |
036 | |
037 | bool frameStarted( const FrameEvent &evt) |
038 | { |
039 | if (mDirection == Vector3::ZERO) |
040 | { |
041 | if (nextLocation()) |
042 | { |
043 | // Set walking animation |
044 | mAnimationState = mEntity->getAnimationState( "Walk" ); |
045 | mAnimationState->setLoop( true ); |
046 | mAnimationState->setEnabled( true ); |
047 | } |
048 | } |
049 | else |
050 | { |
051 | Real move = mWalkSpeed * evt.timeSinceLastFrame; |
052 | mDistance -= move; |
053 | if (mDistance <= 0.0f) { mNode->setPosition(mDestination); |
054 | mDirection=Vector3::ZERO; |
055 | if (!nextLocation()) |
056 | { |
057 | // Set Idle animation |
058 | mAnimationState = mEntity->getAnimationState( "Idle" ); |
059 | mAnimationState->setLoop( true ); |
060 | mAnimationState->setEnabled( true ); |
061 | } |
062 | else //next Direction |
063 | { |
064 | Vector3 src = mNode->getOrientation() * Vector3::UNIT_X; |
065 | if ((1.0f + src.dotProduct(mDirection)) < 0.0001f) { mNode->yaw(Degree(180)); |
066 | } |
067 | else |
068 | { |
069 | Ogre::Quaternion quat = src.getRotationTo(mDirection); |
070 | mNode->rotate(quat); |
071 | } // else |
072 | |
073 | } |
074 | } |
075 | else //Distance>0.0f |
076 | { |
077 | mNode->translate(mDirection*move); |
078 | } |
079 | } |
080 | |
081 | mAnimationState->addTime(evt.timeSinceLastFrame); |
082 | |
083 | return ExampleFrameListener::frameStarted(evt); |
084 | } |
085 | protected : |
086 | Real mDistance; // The distance the object has left to travel |
087 | Vector3 mDirection; // The direction the object is moving |
088 | Vector3 mDestination; // The destination the object is moving towards |
089 | Real mWalkSpeed; // The speed at which the object is moving |
090 | |
091 | AnimationState *mAnimationState; // The current animation state of the object |
092 | |
093 | Entity *mEntity; // The Entity we are animating |
094 | SceneNode *mNode; // The SceneNode that the Entity is attached to |
095 | std::deque mWalkList; // The list of points we are walking to |
096 | |
097 | }; |
098 | |
099 | class MoveDemoApplication : public ExampleApplication |
100 | { |
101 | protected : |
102 | public : |
103 | MoveDemoApplication() |
104 | { |
105 | // Set idle animation |
106 | |
107 | } |
108 | |
109 | ~MoveDemoApplication() |
110 | { |
111 | } |
112 | protected : |
113 | Entity *mEntity; // The entity of the object we are animating |
114 | SceneNode *mNode; // The SceneNode of the object we are moving |
115 | std::deque mWalkList; // A deque containing the waypoints |
116 | |
117 | void createScene( void ) |
118 | { |
119 | mSceneMgr->setAmbientLight( ColourValue( 1.0f, 1.0f, 1.0f ) ); |
120 | |
121 | // Create the entity |
122 | mEntity = mSceneMgr->createEntity( "Robot" , "robot.mesh" ); |
123 | |
124 | // Create the scene node |
125 | mNode = mSceneMgr->getRootSceneNode( )-> |
126 | createChildSceneNode( "RobotNode" , Vector3( 0.0f, 0.0f, 25.0f ) ); |
127 | mNode->attachObject( mEntity ); |
128 | |
129 | // Create the walking list |
130 | mWalkList.push_back( Vector3( 550.0f, 0.0f, 50.0f ) ); |
131 | mWalkList.push_back( Vector3(-100.0f, 0.0f, -200.0f ) ); |
132 | |
133 | // Create objects so we can see movement |
134 | Entity *ent; |
135 | SceneNode *node; |
136 | |
137 | ent = mSceneMgr->createEntity( "Knot1" , "knot.mesh" ); |
138 | node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "Knot1Node" , |
139 | Vector3( 0.0f, -10.0f, 25.0f ) ); |
140 | node->attachObject( ent ); |
141 | node->setScale( 0.1f, 0.1f, 0.1f ); |
142 | |
143 | ent = mSceneMgr->createEntity( "Knot2" , "knot.mesh" ); |
144 | node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "Knot2Node" , |
145 | Vector3( 550.0f, -10.0f, 50.0f ) ); |
146 | node->attachObject( ent ); |
147 | node->setScale( 0.1f, 0.1f, 0.1f ); |
148 | |
149 | ent = mSceneMgr->createEntity( "Knot3" , "knot.mesh" ); |
150 | node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "Knot3Node" , |
151 | Vector3(-100.0f, -10.0f,-200.0f ) ); |
152 | node->attachObject( ent ); |
153 | node->setScale( 0.1f, 0.1f, 0.1f ); |
154 | |
155 | // Set the camera to look at our handywork |
156 | mCamera->setPosition( 90.0f, 280.0f, 535.0f ); |
157 | mCamera->pitch( Degree(-30.0f) ); |
158 | mCamera->yaw( Degree(-15.0f) ); |
159 | |
160 | } |
161 | |
162 | void createFrameListener( void ) |
163 | { |
164 | mFrameListener= new MoveDemoListener(mWindow, mCamera, mNode, mEntity, mWalkList); |
165 | mFrameListener->showDebugOverlay( true ); |
166 | mRoot->addFrameListener(mFrameListener); |
167 | } |
168 | |
169 | }; |
170 | |
171 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 |
172 | #define WIN32_LEAN_AND_MEAN |
173 | #include "windows.h" |
174 | |
175 | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE , LPSTR strCmdLine, INT ) |
176 | #else |
177 | int main( int argc, char **argv) |
178 | #endif |
179 | { |
180 | // Create application object |
181 | MoveDemoApplication app; |
182 | |
183 | try { |
184 | app.go(); |
185 | } catch ( Exception& e ) { |
186 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 |
187 | MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!" , |
188 | MB_OK | MB_ICONERROR | MB_TASKMODAL); |
189 | #else |
190 | fprintf (stderr, "An exception has occured: %s/n" , |
191 | e.getFullDescription().c_str()); |
192 | #endif |
193 | } |
194 | |
195 | return 0; |
196 | } |