void Character::clipToTerrainHeight() { // Setup the scene query Ogre::Ray queryRay(getNode()->getPosition(), Ogre::Vector3::NEGATIVE_UNIT_Y); // Perform the scene query Ogre::TerrainGroup::RayResult result = mClipTo->rayIntersects(queryRay); if(result.hit) { Ogre::Real terrainHeight = result.position.y; Ogre::Vector3 pos = getNode()->getPosition(); pos.y = terrainHeight; getNode()->setPosition(pos); } else { // Try querying terrain above character queryRay.setOrigin(getNode()->getPosition()); queryRay.setDirection(Ogre::Vector3::UNIT_Y); // Perform scene query again result = mClipTo->rayIntersects(queryRay); if(result.hit) { Ogre::Real terrainHeight = result.position.y; Ogre::Vector3 pos = getNode()->getPosition(); pos.y = terrainHeight; getNode()->setPosition(pos); } } }
void PlayerCharacter::update(Ogre::Real elapsedTime, OIS::Keyboard *input) { processKeyboardInput(elapsedTime); processMouseInput(elapsedTime); //Get the position of the ground below the player Ogre::TerrainGroup* terrain = RenderManager::getSingletonPtr()->getTerrainManager()->getTerrainGroup(); //Store the position to increase it, to guarantuee a hit on the terrain Ogre::Vector3 main_position = mMainNode_->getPosition(); Ogre::Vector3 ray_cast_position = main_position; ray_cast_position.y += 1000.0f; // Setup the query ray Ogre::Ray queryRay(ray_cast_position, Ogre::Vector3::NEGATIVE_UNIT_Y); // Perform the scene query Ogre::TerrainGroup::RayResult result = terrain->rayIntersects(queryRay); if(result.hit) { mCurrentGroundPosition = result.position.y; } //Process jumping if(isJumping_) { // if we're jumping, add a vertical offset too, and apply gravity mMainNode_->translate(0, mCurrentDropVelocity * elapsedTime, 0, Ogre::Node::TS_LOCAL); mCurrentDropVelocity -= mDropVelocityIncrement * elapsedTime; Ogre::Vector3 pos = mMainNode_->getPosition(); if (pos.y <= mCurrentGroundPosition) { // if we've hit the ground, change to landing state pos.y = mCurrentGroundPosition; mMainNode_->setPosition(pos); isJumping_ = false; mCurrentDropVelocity = 0.0f; } } //Upate the player height to the world if not jumping if(!isJumping_) { if(main_position.y <= mCurrentGroundPosition) { main_position.y = mCurrentGroundPosition; mMainNode_->setPosition(main_position); mCurrentDropVelocity = 0.0f; } else { mCurrentDropVelocity += mDropVelocityIncrement * elapsedTime; main_position.y = main_position.y - mCurrentDropVelocity; //Check if we are already below the ground if(main_position.y < mCurrentGroundPosition) main_position.y = mCurrentGroundPosition; mMainNode_->setPosition(main_position); } } if (isRunning_ && mBaseAnimID == ANIM_IDLE_BASE) { // start running if not already moving and the player wants to move setBaseAnimation(ANIM_WALK, true); } if(!isRunning_ && mBaseAnimID == ANIM_WALK) { setBaseAnimation(ANIM_IDLE_BASE); } updateAnimations(elapsedTime); }