DefaultFrameListener.cpp
//==========================================================================// // Ogre A* Example - December 2009 // // // // Author: Daniel Soltyka // // E-Mail: dsoltyka [at] gmail [dot] com // // // // This example demonstrates the A* pathfinding algorithm in a 3D // // environment. // // // // Modified A* routines based off of A* Algorithm Implementation using STL // // by Justin Heyes-Jones. // // // // Original Routines can be found at http://www.heyes-jones.com/astar.html // //==========================================================================// #include "DefaultFrameListener.h" using namespace std; DefaultFrameListener::DefaultFrameListener(RenderWindow* win, Camera* cam, SceneManager* sm, SceneNode *sn, Entity *ent, WorldMap* map, PathFinder* pathFinder) : ExampleFrameListener(win, cam, false, false), mSceneMgr(sm), mNode(sn), mEntity(ent), mMap(map), mPathFinder(pathFinder) { // set default variables mWalkSpeed = 150.0f; mDirection = Vector3::ZERO; // find our path findPath(); mStartPoint = mWalkList.front(); // get the vector from the front mEndPoint = mWalkList.back(); // get the vector from the back mWalkList.pop_front(); // remove waypoint from the front // position start and end markers setStartEnd(); mNode->setPosition(mStartPoint); } // This function is called to start the object moving to the next position in mWalkList. bool DefaultFrameListener::nextLocation() { if (mWalkList.empty()) return false; mDestination = mWalkList.front(); // get the vector from the front mWalkList.pop_front(); // remove from the front mDirection = mDestination - mNode->getPosition(); mDistance = mDirection.normalise(); return true; } // nextLocation() // Per frame logic. Called before each frame is rendered bool DefaultFrameListener::frameStarted(const FrameEvent &evt) { if (mEntity) { if (mDirection == Vector3::ZERO) { if (nextLocation()) { // set walking anim mAnimationState = mEntity->getAnimationState("Walk"); mAnimationState->setLoop(true); mAnimationState->setEnabled(true); // set initial rotation 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 { Real move = mWalkSpeed * evt.timeSinceLastFrame; mDistance -= move; if (mDistance <= 0.0f) { mNode->setPosition(mDestination); mDirection = Vector3::ZERO; //set animation based on if the robot has another point to walk to if (!nextLocation()) { // set idle anim mAnimationState = mEntity->getAnimationState("Idle"); mAnimationState->setLoop(true); mAnimationState->setEnabled(true); // find a new path findPath(&mEndPoint); mStartPoint = mWalkList.front(); // get the vector from the front mEndPoint = mWalkList.back(); // get the vector from the back mWalkList.pop_front(); // remove waypoint from the front // position start and end markers setStartEnd(); } else { // rotation code 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); } } mAnimationState->addTime(evt.timeSinceLastFrame); } return ExampleFrameListener::frameStarted(evt); } // Generate a new path in our maze void DefaultFrameListener::findPath() { // create pathfinder mPathFinder = new PathFinder(mMap); // generate path mPathFinder->Run(); // get path mPathFinder->GetResults(&mWalkList); } // Generate a new path in our maze using a specified starting point void DefaultFrameListener::findPath(Vector3 *startingPoint) { // create pathfinder mPathFinder = new PathFinder(mMap, startingPoint); // generate path mPathFinder->Run(); // get path mPathFinder->GetResults(&mWalkList); } // Positions the start/end markers at their respective positions void DefaultFrameListener::setStartEnd() { SceneNode* node; node = mSceneMgr->getSceneNode("StartNode"); node->setPosition(mStartPoint); node = mSceneMgr->getSceneNode("EndNode"); node->setPosition(mEndPoint); }