void Agent::updateLocomote(Ogre::Real deltaTime) { //This is the update locomotion from the previous assignment // Set idle animation if (mDirection == Ogre::Vector3::ZERO) { if (nextLocation()) { Ogre::Vector3 src = mBodyNode->getOrientation() * Ogre::Vector3::UNIT_Z; if ((1.0f + src.dotProduct(mDirection)) < 0.0001f) { mBodyNode->yaw(Ogre::Degree(180)); } else { Ogre::Quaternion quat = src.getRotationTo(mDirection); mBodyNode->rotate(quat); } setBaseAnimation(ANIM_RUN_BASE); setTopAnimation(ANIM_RUN_TOP); } } else { Ogre::Real move = mWalkSpeed * deltaTime; mDistance -= move; if (mDistance <= 0.0f) { mBodyNode->setPosition(mDestination); mDirection = Ogre::Vector3::ZERO; if (!nextLocation()) { setBaseAnimation(ANIM_IDLE_BASE); setTopAnimation(ANIM_IDLE_TOP); } else { Ogre::Vector3 src = mBodyNode->getOrientation() * Ogre::Vector3::UNIT_Z; if ((1.0f + src.dotProduct(mDirection)) < 0.0001f) { mBodyNode->yaw(Ogre::Degree(180)); } else { Ogre::Quaternion quat = src.getRotationTo(mDirection); mBodyNode->rotate(quat); } } } else { mBodyNode->translate(mDirection * move); } } }
void EnemyController::approach(void) { EnemyPlane* enemy = static_cast<EnemyPlane*>(IDManager::getPointer(_enemyName, ACTOR)); Ogre::Vector3 temp = FCKnowledge::getSingleton().getPlayerPosition() - enemy->getPosition(); Ogre::Vector3 direction = temp * enemy->getAxis(); //std::cout<<direction.x<<" "<<direction.y<<" "<<direction.z<<std::endl; if(direction.angleBetween(Ogre::Vector3::NEGATIVE_UNIT_Z) >= Ogre::Radian(Ogre::Degree(1))) { Ogre::Quaternion test = direction.getRotationTo(Ogre::Vector3::NEGATIVE_UNIT_Z); Ogre::Degree angle = enemy->getRotateLimit(); double yawNum = test.getYaw().valueDegrees()/(angle*WORLD_UPDATE_INTERVAL).valueDegrees(); yawNum = Ogre::Math::Clamp(yawNum, -1.0, 1.0); enemy->yaw(yawNum); double pitchNum = test.getPitch().valueDegrees()/(angle*WORLD_UPDATE_INTERVAL).valueDegrees(); pitchNum = Ogre::Math::Clamp(pitchNum, -1.0, 1.0); enemy->pitch(pitchNum); double rollNum = test.getRoll().valueDegrees()/(angle*WORLD_UPDATE_INTERVAL).valueDegrees(); rollNum = Ogre::Math::Clamp(rollNum, -1.0, 1.0); enemy->roll(rollNum); } else { enemy->yaw(0); enemy->pitch(0); enemy->roll(0); } }
void AnimateableCharacter::update(Ogre::Real timeSinceLastFrame) { updatePosition(timeSinceLastFrame); if (mClipTo) clipToTerrainHeight(); Ogre::Vector3 velocity = getVelocity(); // Current velocity of agent Ogre::Real speed = velocity.length(); if(speed > 0.15) { //mAnimState->setEnabled(true); //mAnimState->addTime(mAnimSpeedScale * speed * timeSinceLastFrame); if(speed > 0/*0.8*/) { // Avoid jitter (TODO keep this?) // Rotate to look in walking direction Ogre::Vector3 src = getLookingDirection(); src.y = 0; // Ignore y direction velocity.y = 0; velocity.normalise(); mNode->rotate(src.getRotationTo(velocity)); } } else { // Assume character has stopped mAnimState->setEnabled(false); mAnimState->setTimePosition(0); } }
//----------------------------------------------------------------------------- bool IntermediateTutorial1::frameRenderingQueued(const Ogre::FrameEvent &evt) { if (mDirection == Ogre::Vector3::ZERO) { if (nextLocation()) { // Set walking animation mAnimationState = mEntity->getAnimationState("Walk"); mAnimationState->setLoop(true); mAnimationState->setEnabled(true); rotateRobotToDirection(); } } else { Ogre::Real move = mWalkSpeed * evt.timeSinceLastFrame; mDistance -= move; if (mDistance <= 0.0f) { mNode->setPosition(mDestination); mDirection = Ogre::Vector3::ZERO; // Set animation based on if the robot has another point to walk to. if (!nextLocation()) { // Set Idle animation mAnimationState = mEntity->getAnimationState("Idle"); mAnimationState->setLoop(true); mAnimationState->setEnabled(true); } else { // Rotation Code will go here later Ogre::Vector3 src = mNode->getOrientation() * Ogre::Vector3::UNIT_X; if ((1.0f + src.dotProduct(mDirection)) < 0.0001f) { mNode->yaw(Ogre::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 BaseApplication::frameRenderingQueued(evt); }
void PlayerObject::rotatePlayer() { Ogre::Vector3 src = objectNode->getOrientation() * Ogre::Vector3::UNIT_X; src.y = 0; mDirection.y = 0; src.normalise(); Ogre::Real mDistance = mDirection.normalise(); Ogre::Quaternion quat = src.getRotationTo(mDirection); objectNode->rotate(quat); objectNode->yaw(Ogre::Degree(-90)); } // rotatePlayer
//----------------------------------------------------------------------------- void IntermediateTutorial1::rotateRobotToDirection(void) { Ogre::Vector3 src = mNode->getOrientation() * Ogre::Vector3::UNIT_X; // Orientation from initial direction src.y = 0; // Ignore pitch difference angle mDirection.y = 0; src.normalise(); Ogre::Real mDistance = mDirection.normalise( ); // Both vectors modified so renormalize them Ogre::Quaternion quat = src.getRotationTo(mDirection); mNode->rotate(quat); }
void Tank::rotateTank(void){ Ogre::Vector3 src = mTankBodyNode->getOrientation() * Ogre::Vector3::NEGATIVE_UNIT_X; if ((1.0 + src.dotProduct(mDirection)) < 0.0001) { mTankBodyNode->yaw(Ogre::Degree(180)); } else { Ogre::Quaternion quat = src.getRotationTo(mDirection); mTankBodyNode->rotate(quat); } }
//----------------------------------------------------------------------------------------- bool CCameraEditor::_setViewMode(OgitorsPropertyBase* property, const int& value) { if(value) { if(mAutoTrackTarget->get() != "None") _setAutoTrackTarget(mAutoTrackTarget, "None"); //Set it to CVM_FREE so we can set to new orientation mViewMode->init(0); Ogre::Vector3 normal = Ogre::Vector3::UNIT_Z; switch(value) { case CVM_GLOBAL_LEFT: setDerivedOrientation(normal.getRotationTo(Ogre::Vector3::NEGATIVE_UNIT_X));break; case CVM_GLOBAL_RIGHT: setDerivedOrientation(normal.getRotationTo(Ogre::Vector3::UNIT_X));break; case CVM_GLOBAL_FRONT: setDerivedOrientation(normal.getRotationTo(Ogre::Vector3::NEGATIVE_UNIT_Z));break; case CVM_GLOBAL_BACK: setDerivedOrientation(Ogre::Quaternion::IDENTITY);break; case CVM_GLOBAL_TOP: setDerivedOrientation(normal.getRotationTo(Ogre::Vector3::UNIT_Y));break; case CVM_GLOBAL_BOTTOM: setDerivedOrientation(normal.getRotationTo(Ogre::Vector3::NEGATIVE_UNIT_Y));break; case CVM_LOCAL_LEFT: mOrientation->set(normal.getRotationTo(Ogre::Vector3::NEGATIVE_UNIT_X));break; case CVM_LOCAL_RIGHT: mOrientation->set(normal.getRotationTo(Ogre::Vector3::UNIT_X));break; case CVM_LOCAL_FRONT: mOrientation->set(normal.getRotationTo(Ogre::Vector3::NEGATIVE_UNIT_Z));break; case CVM_LOCAL_BACK: mOrientation->set(Ogre::Quaternion::IDENTITY);break; case CVM_LOCAL_TOP: mOrientation->set(normal.getRotationTo(Ogre::Vector3::UNIT_Y));break; case CVM_LOCAL_BOTTOM: mOrientation->set(normal.getRotationTo(Ogre::Vector3::NEGATIVE_UNIT_Y));break; } //Restore the value mViewMode->init(value); } else { if(mAutoTrackTarget->get() != "None") _setAutoTrackTarget(mAutoTrackTarget, mAutoTrackTarget->get()); } return true; }
void PlayerCharacter::updateCharDirMoving(Ogre::Vector3* moveDir, unsigned long timeSinceLastFrame, Ogre::Radian &moveDirRotAngle) { // TODO: Running backwards goes crazy, turn too fast // http://www.ogre3d.org/tikiwiki/Intermediate+Tutorial+1&structure=Tutorials // http://www.ogre3d.org/tikiwiki/Quaternion+and+Rotation+Primer#Q._How_can_I_make_my_objects_rotate_smoothly_You_mentioned_slerp_etc_ if(!moveDir->isZeroLength()) { Ogre::Vector3 src = this->node->getOrientation() * Ogre::Vector3::UNIT_Z; if ((1.0f + src.dotProduct(*moveDir)) < 0.0001f) { this->node->yaw(Ogre::Degree(180)); } else { Ogre::Quaternion quat = src.getRotationTo(*moveDir); this->node->rotate(quat); } } /*if(!moveDir->isZeroLength()) { //Ogre::Vector3 targetDirection = Quaternion(moveDirRotAngle, Vector3::UNIT_Y) * (*moveDir); Ogre::Vector3 targetDirection = this->node->getOrientation() * *moveDir; Ogre::Radian rotationDifferenceToLastValue = m_lastTargetDirection.angleBetween(targetDirection); Radian targetRotation; if(rotationDifferenceToLastValue > Ogre::Radian(Ogre::Real(0.001))) { Quaternion rotationQuat = (Vector3::UNIT_X).getRotationTo(targetDirection, Vector3::UNIT_Y); Radian targetRotation = rotationQuat.getYaw(); //m_moveRotation.setTargetValueWithAdjustedSmoothtime(targetRotation, true); m_moveRotation = targetRotation; } //m_moveRotation.smoothValue(timeSinceLastFrame); this->node->setDirection(0,0,-1, Node::TS_WORLD); this->node->yaw(m_moveRotation); m_lastTargetDirection = targetDirection; }*/ }
void Robot::updateLocomote(Ogre::Real deltaTime) { if (mDirection == Ogre::Vector3::ZERO) { if (this->nextLocation()) // a check to see if there is another destination { // Set walking animation this->setBaseAnimation(ANIM_WALK, true); this->setTopAnimation(ANIM_WALK, true); } } else { Ogre::Real move = mWalkSpeed * deltaTime; mDistance -= move; if (mDistance <= 0.0f) // over shooting target { this->mBodyNode->setPosition(mDestination); mDirection = Ogre::Vector3::ZERO; if (!this->nextLocation()) // a check to see if there is another destination { this->setBaseAnimation(ANIM_IDLE, true); this->setTopAnimation(ANIM_IDLE, true); } else { Ogre::Vector3 src = this->mBodyNode->getOrientation() * Ogre::Vector3::UNIT_X; if ((1.0f + src.dotProduct(mDirection)) < 0.0001f) { this->mBodyNode->yaw(Ogre::Degree(180)); } else { Ogre::Quaternion quat = src.getRotationTo(mDirection); this->mBodyNode->rotate(quat); this->mBodyNode->yaw(Ogre::Degree(angleOffset)); // To correct for models facing different directions } } } else { this->mBodyNode->translate(mDirection * move); } } }
void PlayerObject::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { if (dead || attacking) { return; } // if int x = evt.state.X.abs; int y = evt.state.Y.abs; Ogre::Ray mouseRay = camera->getCameraToViewportRay(x/float(evt.state.width), y/float(evt.state.height)); Ogre::Vector3 point = World::getInstance().getCurrentZone()->getIntersectingPlane(mouseRay); point.y = objectNode->getPosition().y; if (id == OIS::MB_Left) { walkTo = point; } // if else if (id == OIS::MB_Right) { int ran = rand() % 3; attacking = true; walkTo = objectNode->getPosition(); // Rotate player Ogre::Vector3 dir = point - walkTo; Ogre::Vector3 src = objectNode->getOrientation() * Ogre::Vector3::UNIT_X; src.y = 0; dir.y = 0; src.normalise(); Ogre::Real mDistance = dir.normalise(); Ogre::Quaternion quat = src.getRotationTo(dir); objectNode->rotate(quat); objectNode->yaw(Ogre::Degree(-90)); switch (ran) { case 0: mAnimationState = objectEntity->getAnimationState("Attack1"); break; case 1: mAnimationState = objectEntity->getAnimationState("Attack2"); break; default: mAnimationState = objectEntity->getAnimationState("Attack3"); } // switch-case mAnimationState->setTimePosition(0); mAnimationState->setLoop(false); mAnimationState->setEnabled(true); SoundManager::getInstance().ATTACK_MISS_1_SOUND->play(); } // else if } // mousePresesd
void Utility::rotateToTarget(Ogre::SceneNode* node, const Ogre::Vector3& target, bool ignoreY, Ogre::Vector3 originalDirection) { Ogre::Vector3 source = node->getOrientation() * originalDirection; if(ignoreY) { source.y = 0; } node->rotate(source.getRotationTo(target)); return; }
void BaseTower::update(float time) { if(die) return; fireCD -= time; if(fireCD < 0 && !enemyFactory->enemyList.empty()) { /* if(enemyFactory->enemyList.size() == 1) { Enemy *e= *enemyFactory->enemyList.begin(); if(e->nearlyDie) return; } */ enemy = *enemyFactory->enemyList.begin(); if(!ifInRange(enemy->getSceneNode()->getPosition(),sceneNode->getPosition(), range)) { return; } fireCD = 2.0f; Ogre::Vector3 src = sceneNode->getOrientation() * Ogre::Vector3::UNIT_X; src.y = 0; Ogre::Vector3 direction = enemy->getSceneNode()->getPosition() - sceneNode->getPosition(); direction.y = 0; Ogre::Quaternion quat = src.getRotationTo(direction); //direction sceneNode->rotate(quat); //sceneNode->yaw(Ogre::Degree(90)); Bullet *b = bulletFactory->generate(sceneNode->getPosition(), sceneNode->getOrientation(), BULLET_NORMAL); Vector3 v = b->getSceneNode()->getPosition(); v.y = 160; b->getSceneNode()->setPosition(v); } }
//------------------------------------------------------------------------------------- bool PlayersManager::moving(zappy::Player *p, int i) { OPlayer *OPlayer = this->mOPlayers.at(i); this->speed = Constants::SquareSize / ((Constants::timeUnit / static_cast<Ogre::Real>(time))); Ogre::SceneNode *node = OPlayer->getSceneNode(); Ogre::Vector3 &direction = OPlayer->getDirection(); Ogre::Real &distance = OPlayer->getDistance(); Ogre::Real move = this->speed * this->tslf; Ogre::Vector3 destination(p->getX() * Constants::SquareSize, 0, p->getY() * Constants::SquareSize); Ogre::AnimationState *anim = OPlayer->getEntity()-> getAnimationState(distance <= 0.0f ? "Idle" : "Walk"); anim->setLoop(true); anim->setEnabled(true); if (direction == Ogre::Vector3::ZERO) { Ogre::Vector3 src = node->getOrientation() * Ogre::Vector3::UNIT_X; direction = destination - node->getPosition(); distance = direction.normalise(); if ((1.0f + src.dotProduct(direction)) < 0.0001f) node->yaw(Ogre::Degree(180)); else node->rotate(src.getRotationTo(direction)); if (distance > Constants::SquareSize) distance = 0.0f; } else { distance -= move; if (distance <= 0.0f) { node->setPosition(destination); direction = Ogre::Vector3::ZERO; } else node->translate(direction * move); } if (OPlayer->stateHasChanged()) OPlayer->detachAnim(); anim->addTime(this->tslf); return true; }
void Tank::wanderMovement(const float & deltaTime) { if(wanderPathCreated) { if (mWanderDirection == Ogre::Vector3::ZERO) { wanderNextLocation(); } else { Ogre::Real move = mMoveSpd * (deltaTime); mWanderDistance -= move; Ogre::Vector3 src = mTankBodyNode->getOrientation() * Ogre::Vector3::NEGATIVE_UNIT_X; //http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Quaternion+and+Rotation+Primer //this is used for rotation of the tank if ((1.0 + src.dotProduct(mWanderDirection)) < 0.0001) { mTankBodyNode->yaw(Ogre::Degree(180)); } else { mWanderDirection.y = 0; Ogre::Quaternion quat = src.getRotationTo(mWanderDirection); Ogre::Quaternion mOrientSrc = mTankBodyNode->getOrientation(); Ogre::Quaternion mOrientDest = quat * mOrientSrc; Ogre::Quaternion delta = Ogre::Quaternion::nlerp(deltaTime * 2.0, mOrientSrc, mOrientDest, true); mTankBodyNode->setOrientation(delta); } //for movement if (mWanderDistance <= 0) { mTankBodyNode->setPosition(mWanderDestination); mWanderDirection = Ogre::Vector3::ZERO; } else { mTankBodyNode->translate(move * mWanderDirection); } } } }
void Fighter::update(Ogre::Real deltaTime) { Ogre::Vector3 curPos = mNode->getPosition(); Ogre::Vector3 direction = curPos - mCursorPos; Ogre::Vector3 src = mNode->getOrientation() * -Ogre::Vector3::UNIT_Z; src.y = 0; direction.y = 0; src.normalise(); direction.normalise(); mNode->setPosition(mNode->getPosition()+mCurrentMoveVector); Ogre::Quaternion quat = src.getRotationTo(direction); mNode->rotate(quat); /* * Update all shots */ for(std::vector<Shot*>::iterator it = mShots.begin(); it != mShots.end();) { (*it)->update(deltaTime); /** @see http://www.ogre3d.org/forums/viewtopic.php?t=2519 http://de.wikipedia.org/wiki/Projektionsmatrix */ Ogre::Vector3 hcpPos = (*mCameraPtr)->getProjectionMatrix()*(*mCameraPtr)->getViewMatrix()*mNode->getPosition(); if ((hcpPos.x < -1.0f) || (hcpPos.x > 1.0f) || (hcpPos.y < -1.0f) || (hcpPos.y > 1.0f)) { (*it)->die(); delete (*it); it = mShots.erase(it); } else { ++it; } } //Update positon for enemies mCurrentPosition = mNode->getPosition(); }
void NPCCharacter::_behaviorIdle() { stop(); //still want to point the character in the direction last traveled. Ogre::Vector3 vel = getVelocity(); float speed = vel.length(); Ogre::Vector3 src = _node->getOrientation() * Ogre::Vector3::NEGATIVE_UNIT_Z; src.y = 0; vel.y = 0; vel.normalise(); _node->rotate(src.getRotationTo(vel)); _isBhvFinished = true; //transition to idle animation _animHandler.blend("Idle",AnimationBlender::BlendWhileAnimating,.2f,true); }
void BaseNpc::update(double timeSinceLastFrame) { mAnimationState->addTime(timeSinceLastFrame); if (m_pCurrentState) { m_pCurrentState->Execute(this); } if (isMoving == false) { if (nextLocation(m_pNpcNode)) { // Set walking animation mAnimationState = m_pNPC->getAnimationState("Walk"); mAnimationState->setLoop(true); mAnimationState->setEnabled(true); isMoving = true; } else { // Not moving and no locations in list } } else { Ogre::Real move = mWalkSpeed * timeSinceLastFrame; mDistance -= move; if (mDistance <= 0.0f) { m_pNpcNode->setPosition(mDestination); mDirection = Ogre::Vector3::ZERO; // Set animation based on if the robot has another point to walk to. if (! nextLocation(m_pNpcNode)) { // Set Idle animation mAnimationState = m_pNPC->getAnimationState("Idle"); mAnimationState->setLoop(true); mAnimationState->setEnabled(true); } else { Ogre::Vector3 src = m_pNpcNode->getOrientation() * Ogre::Vector3::UNIT_X; if ((1.0f + src.dotProduct(mDirection)) < 0.0001f) { m_pNpcNode->yaw(Ogre::Degree(180)); } else { Ogre::Quaternion quat = src.getRotationTo(mDirection); m_pNpcNode->rotate(quat); } } } else { m_pNpcNode->translate(mDirection * move); } } }
void CharacterMovement::rotate() { if( !_rotating ) { return; } // linear interpolate _rotationValue += _rotationInc; if( _rotationValue > 1.0 ) { _rotating = false; } else { // Update player's orientation Ogre::Vector3 facingVector = _node->getOrientation() * Ogre::Vector3::UNIT_Z; Ogre::Vector3 direction = UtilFunctions::qVector3dToOgreVector3( _direction ); // Work around 180 degree quaternion rotation quirk // avoid divide by zero // this works our only in case we are walking on non-regular terrain.. // its irrelevant on plane ground if( (1.0f + facingVector.dotProduct( direction )) < 0.0001f ) { _node->yaw( Ogre::Degree(180) ); } else { Ogre::Quaternion delta; Ogre::Quaternion orientationSrc = _node->getOrientation(); Ogre::Quaternion orientationDest = facingVector.getRotationTo( direction ) * orientationSrc; // Slerp delta = Ogre::Quaternion::Slerp( _rotationInc, orientationSrc, orientationDest ); _node->setOrientation( delta ); } } }
// Returns volume for the right ear. // If the sound is directly to the right, that channel gets 254 of intensity. // If the sound is directly in front of us, each channel gets 254/2 of intensity. int SoundManager::calcPanning(Ogre::Camera* mCamera, Ogre::Vector3 soundPosition) { Ogre::Vector3 camDirection = mCamera->getOrientation() * Ogre::Vector3::NEGATIVE_UNIT_Z; Ogre::Vector3 soundDir = soundPosition - mCamera->getPosition(); soundDir.normalise(); // Retrieve the angle made between the sound position and the camera's direction, // which should be pointing forwards. Ogre::Quaternion q = camDirection.getRotationTo(soundDir); Ogre::Radian radians = q.getYaw(); // anything left of the camera returns positive degrees float degrees = radians.valueDegrees(); int leftIntensity; int rightIntensity; // from 0 to -179 it's the right ear. if(degrees <= 0) { //std::cout << "degrees " << degrees << std::endl; degrees *= -1; if(degrees > 90) degrees = 90 - (degrees - 90); // if 91, we subtract 1 and go back to 89 // Intensity can never be 255 because then the effect cancels out. int intensity = (degrees / 90.0) * 254/2 + 254/2; //std::cout << "intensity " << intensity << std::endl; rightIntensity = intensity; leftIntensity = 255 - (rightIntensity); } // from 0 to 179 it's the left ear. else { if(degrees > 90) degrees = 90 - (degrees - 90); int intensity = (degrees / 90) * 254/2 + 254/2; //std::cout << "intensity " << intensity << std::endl; leftIntensity = intensity; rightIntensity = 254 - (leftIntensity); } return rightIntensity; }
void Monster::go(float timeSinceLastFrame) { /// 给动画增加时间 addTimeToAnimation(timeSinceLastFrame); if(!mIsDead) { if(mDistance < 0.0f || mDistance == 0.0f) { int size = ogrePath.size(); mNode->setPosition(ogrePath[mNextPosIndex]); if(ogrePath[ogrePath.size()-1] != mNode->getPosition()) { mBeginPosIndex++; mNextPosIndex++; mDistance = distance(ogrePath[mNextPosIndex], ogrePath[mBeginPosIndex]); /// 面向,方向向量 mFace = (ogrePath[mNextPosIndex] - ogrePath[mBeginPosIndex]); mFace.normalise(); /// 旋转面向角度 Ogre::Vector3 src = mNode->getOrientation() * Vector3::UNIT_X; Ogre::Quaternion quat = src.getRotationTo(mFace); mNode->rotate(quat); } else { setBlood(0); mIsGetUFO = true; } } /// 平移所需要走的路 float moveDistance = timeSinceLastFrame * mSpeedCurrent; mNode->translate(mFace * moveDistance); mDistance -= moveDistance; } }
//code taken and adapted from http://natureofcode.com/book/chapter-6-autonomous-agents/ //written by Michael Kong void Tank::seek(const Ogre::Vector3& target, const float& deltaTime){ Ogre::Vector3 seekTarget = target; seekTarget.y = 0.f; Ogre::Quaternion tankOrientation = mTankBodyNode->getOrientation(); Ogre::Vector3 currentDirection = tankOrientation * Ogre::Vector3::NEGATIVE_UNIT_X; currentDirection.normalise(); Ogre::Vector3 desired = seekTarget - mTankBodyNode->getPosition(); desired.normalise(); //get unit vector desired *= ms; Ogre::Vector3 src = tankOrientation * Ogre::Vector3::NEGATIVE_UNIT_X; Ogre::Quaternion quat = src.getRotationTo(seekTarget); /* Ogre::Quaternion mOrientSrc = mTankBodyNode->getOrientation(); Ogre::Quaternion mOrientDest = quat * mOrientSrc; */ mTankBodyNode->setOrientation(quat * deltaTime); mTankBodyNode->translate(desired * deltaTime); }
//Probably the most involved behavior so far. void NPCCharacter::_behaviorTalk(const std::string& targetName) { //have to start moving to the target entity until the distance is acceptable LevelData::BaseEntity* targetEnt = LuaManager::getSingleton().getEntity(targetName); //Can't talk to a trigger zone or door(though I *could* do the door, it would be an easter egg). if(targetEnt->getType() != LevelData::NPC && targetEnt->getType() != LevelData::ENEMY) { _isBhvFinished = true; return; } if(targetEnt->getType() == LevelData::NPC) { NPCCharacter* targetNpc = static_cast<NPCCharacter*>(targetEnt); //choosing to ignore the y-value to get a true 4 unit distance horizontally from the target. //might remove if it doesn't make a difference. Ogre::Vector3 tgtNpc = targetNpc->getPosition(); tgtNpc.y = 0; Ogre::Vector3 pos = getPosition(); pos.y = 0; //position has to be less than 16 units to talk to the entity. //chose to use 18 instead due to float inaccuracies(might have a value like 16.0178) if(tgtNpc.squaredDistance(pos) > 18) { //move towards the entity(not using the _behaviorMove function though) //or can I?? //yes I can actually. *does a jig* //generate a more correct position Ogre::Vector3 target,tmp; tmp = targetNpc->getPosition() - getPosition(); //distance and direction to the target tmp.y = 0; Ogre::Real len = tmp.normalise(); //original + (unit direction vector * desired distance from target[non-squared]) target = getPosition() + (tmp * ( len - 1)); _behaviorMove(target); if(_isBhvFinished) { //reached the destination, but behavior isn't done yet. _isBhvFinished = false; } } else { //rotate to face the target Ogre::Vector3 dir = tgtNpc - pos; dir.normalise(); Ogre::Vector3 src = _node->getOrientation() * Ogre::Vector3::NEGATIVE_UNIT_Z; src.y = 0; _node->rotate(src.getRotationTo(dir)); //make sure any other blends are finished first. if(_animHandler.getTarget() == nullptr) { //this ends the behavior until the talk animation or sound file is implemented _isBhvFinished = true; //this would be the actual way to finish the behavior(or even with the end of a sound file) if(_animHandler.getSource()->getAnimationName() == "Talk") { _isBhvFinished = true; } else { //start the blend to the talk animation. //_animHandler.blend([animation],[blend technique],.2,true); } } } return; } if(targetEnt->getType() == LevelData::ENEMY) { //nothing for now. return; } return; }
void EnemyDragon::update(float time) { if(fireLastingTime > 0) { fireLastingTime -= time; ps->setVisible(true); }else ps->setVisible(false); if(frostLastingTime <=0) frostCoefficient = 1; else frostLastingTime -= time; if(attackToHome) { attackToHome = false; userGUI->resetHealthBar(50); //mWorld->homeHealth -= 100; //mWorld->homeText->setCaption(convertInt(mWorld->homeHealth)); } if(die){ mtext->setCaption("0"); mtext->setVisible(false); return; } if(saveBody < 0){ die = true; mtext->setCaption("0"); return; } if(!nearlyDie && !die) { mtext->setCaption(convertInt(lifeValue)); }else{ mtext->setCaption("0"); mtext->setVisible(false); } if(nearlyDie) { mAnimationState= entity->getAnimationState("Death"); mAnimationState->setLoop(false); mAnimationState->setEnabled(true); nearlyDieTime -= time; if(nearlyDieTime < 0) { saveBody -= time; mAnimationState= entity->getAnimationState("Death"); //die = true; //cleanBody = true; } mAnimationState->addTime(time * frostCoefficient); return; } if(caught) return; if (mDirection == Ogre::Vector3::ZERO) { if (nextLocation()) { // Set walking animation mAnimationState = entity->getAnimationState("Run"); mAnimationState->setLoop(true); mAnimationState->setEnabled(true); }//if }else{ Ogre::Real move = mWalkSpeed * time * frostCoefficient; mDistance -= move * frostCoefficient; if (mDistance <= 0.0f){ sceneNode->setPosition(mDestination); mDirection = Ogre::Vector3::ZERO; // Set animation based on if the robot has another point to walk to. if (!nextLocation()){ // Set Jump animation mAnimationState = entity->getAnimationState("BattleRoar"); mAnimationState->setLoop(true); mAnimationState->setEnabled(true); nearlyDie = true; attackToHome = true; mtext->setCaption("0"); }else{ // Rotation Code will go here later Ogre::Vector3 src = sceneNode->getOrientation() *(- Ogre::Vector3::UNIT_Z); if ((1.0f + src.dotProduct(mDirection)) < 0.0001f) { sceneNode->yaw(Ogre::Degree(180)); }else{ Ogre::Quaternion quat = src.getRotationTo(mDirection); sceneNode->rotate(quat); sceneNode->yaw(Ogre::Degree(90)); } // else }//else }else{ sceneNode->translate(mDirection * move * frostCoefficient); } // else } // if mAnimationState->addTime(time * frostCoefficient); if(reachHome) { ps->setVisible(true); happy2Dead -= time; if(happy2Dead < 0) { die = true; } } }
void Ninja::updateLocomote(Ogre::Real deltaTime) { int xOffset = ((this->grid->getRows() * this->grid->getHeight()) - this->grid->getHeight())/2; int yOffset = ((this->grid->getCols() * this->grid->getHeight()) - this->grid->getHeight())/2; int x = (xOffset + mDestination.x)/grid->getHeight(); int y = (yOffset + mDestination.z)/grid->getHeight(); if (mDirection == Ogre::Vector3::ZERO) { if (nextLocation()) // a check to see if there is another destination { // Set walking animation this->setBaseAnimation(ANIM_WALK, true); //this->setTopAnimation(ANIM_WALK, true); } } else { Ogre::Real move = mWalkSpeed * deltaTime; mDistance -= move; if (mDistance <= 0.0f) // over shooting target { this->mBodyNode->setPosition(mDestination); this->setCurrentNode(grid->getNode(x, y)); while(this->getCurrentNode()->getItemList()->size() > 0) { Ogre::Entity* ent = this->getCurrentNode()->getItemList()->front(); this->inventory->push_back(ent); this->getCurrentNode()->getItemList()->pop(); ent->detachFromParent(); this->getmBodyEntity()->attachObjectToBone("Joint13", ent); ent->getParentNode()->scale(1.15f,1.15f,1.15f); ent->setVisible(true); } mDirection = Ogre::Vector3::ZERO; if (!nextLocation()) // a check to see if there is another destination { this->setCurrentNode(grid->getNode(x, y)); this->setBaseAnimation(ANIM_IDLE_1, true); //this->setTopAnimation(ANIM_IDLE_1, true); } else { Ogre::Vector3 src = this->mBodyNode->getOrientation() * Ogre::Vector3::UNIT_X; if ((1.0f + src.dotProduct(mDirection)) < 0.0001f) { this->mBodyNode->yaw(Ogre::Degree(180)); } else { Ogre::Quaternion quat = src.getRotationTo(mDirection); this->mBodyNode->rotate(quat); this->mBodyNode->yaw(Ogre::Degree(angleOffset)); // To correct for models facing different directions } } } else { this->mBodyNode->translate(mDirection * move); } } }
void Game::createCallbacks() { App::createCallbacks(); // Quit on Xbox remote BACK. OnFrameRenderingQueued.Subscribe([&](const FrameEventArgs* args) { playing = !xboxCtrl.p1.getState().buttons[XboxController::BACK]; }); #pragma region Helpers // Update an animation pair. static const auto updateAnimPair = [&](int i, Ogre::Real dt) { animStates[i]->addTime(dt); animStates[i + 1]->addTime(dt); }; // Toggle enabled for an animation pair. static const auto setEnabledAnimPair = [&](int i, bool enabled) { animStates[i]->setEnabled(enabled); animStates[i + 1]->setEnabled(enabled); }; #pragma endregion // Toggle animations. OnFrameRenderingQueued.Subscribe([&](const FrameEventArgs* args) { if (sinbad->getAcceleration().isZeroLength()) { setEnabledAnimPair(0, true); setEnabledAnimPair(2, false); updateAnimPair(0, args->evt->timeSinceLastFrame); } else { setEnabledAnimPair(0, false); setEnabledAnimPair(2, true); updateAnimPair(2, args->evt->timeSinceLastFrame); } }); // Control Sinbad. OnFrameRenderingQueued.Subscribe([&](const FrameEventArgs* args) { const auto& leftStick = xboxCtrl.p1.getState().leftStick; const auto& rightStick = xboxCtrl.p1.getState().rightStick; // Invert the y so stick up goes into screen. sinbad->setAcceleration(Ogre::Vector3(leftStick.x, 0, -leftStick.y).normalisedCopy()); // Keep him facing the move direction. Ogre::Vector3 dir = sinbad->getAcceleration().normalisedCopy(); Ogre::Vector3 src = sinbad->getNode()->getOrientation() * Ogre::Vector3::UNIT_Z; // Ignore pitch. dir.y = 0; dir.normalise(); src.y = 0; src.normalise(); sinbad->getNode()->rotate(src.getRotationTo(dir)); sinbad->update(args->evt); cameraMan->setYawPitchDist(Ogre::Degree(rightStick.x), Ogre::Degree(rightStick.y), 45.0f); }); }
//----------------------------------------------------------------------------------------- void CLightEditor::_calculateOrientation() { Ogre::Vector3 direction = mHandle->getDerivedDirection(); Ogre::Vector3 normal = Ogre::Vector3::UNIT_Z; mOrientation->initAndSignal( normal.getRotationTo(direction) ); }
//---------------------------------------------------------------------------- int CDotSceneSerializer::ReadLight(TiXmlElement *element, CBaseEditor *parent, CBaseEditor **ret) { OgitorsPropertyValueMap params; OgitorsPropertyValue propValue; propValue.propType = PROP_STRING; Ogre::String name = ValidAttr(element->Attribute("name")); if(Ogitors::OgitorsRoot::getSingletonPtr()->FindObject(name)) propValue.val = Ogre::Any(Ogre::String("Light") + Ogitors::OgitorsRoot::getSingletonPtr()->CreateUniqueID("Light","")); else propValue.val = Ogre::Any(name); params["name"] = propValue; int ltype = Ogre::Light::LT_POINT; Ogre::String lighttype = ValidAttr(element->Attribute("type"),"point"); if(lighttype == "directional") ltype = Ogre::Light::LT_DIRECTIONAL; else if(lighttype == "spot") ltype = Ogre::Light::LT_SPOTLIGHT; propValue.propType = PROP_INT; propValue.val = Ogre::Any(ltype); params["lighttype"] = propValue; propValue.propType = PROP_BOOL; propValue.val = Ogre::Any(Ogre::StringConverter::parseBool(ValidAttr(element->Attribute("castShadows")))); params["castshadows"] = propValue; propValue.propType = PROP_REAL; propValue.val = Ogre::Any(Ogre::StringConverter::parseReal(ValidAttr(element->Attribute("power"), "1"))); params["power"] = propValue; TiXmlElement* subs = 0; Ogre::String eType; subs = element->FirstChildElement(); if(!subs) return SCF_OK; do { eType = subs->Value(); if(eType == "colourDiffuse") { params["diffuse"] = parseColourValue(subs); } else if(eType == "colourSpecular") { params["specular"] = parseColourValue(subs); } else if(eType == "lightAttenuation") { Ogre::Vector4 att; att.x = Ogre::StringConverter::parseReal(ValidAttr(subs->Attribute("range"))); att.y = Ogre::StringConverter::parseReal(ValidAttr(subs->Attribute("constant"))); att.z = Ogre::StringConverter::parseReal(ValidAttr(subs->Attribute("linear"))); att.w = Ogre::StringConverter::parseReal(ValidAttr(subs->Attribute("quadric"))); propValue.propType = PROP_VECTOR4; propValue.val = Ogre::Any(att); params["attenuation"] = propValue; } else if(eType == "lightRange") { Ogre::Vector3 range; range.x = Ogre::StringConverter::parseReal(ValidAttr(subs->Attribute("inner"),"15")); range.y = Ogre::StringConverter::parseReal(ValidAttr(subs->Attribute("outer"),"30")); range.z = Ogre::StringConverter::parseReal(ValidAttr(subs->Attribute("falloff"),"1")); propValue.propType = PROP_VECTOR3; propValue.val = Ogre::Any(range); params["lightrange"] = propValue; } else if(eType == "position") { params["position"] = parseVector3(subs); } else if(eType == "directionVector") { params["direction"] = parseVector3(subs); /* Orientation is not stored for lights in the .scene files. If we don't set orientation for the spotlights/directional lights they will face to the default direction */ Ogre::Vector3 normal = Ogre::Vector3::UNIT_Z; Ogitors::OgitorsPropertyValue pOrient; pOrient.propType = PROP_QUATERNION; pOrient.val = normal.getRotationTo(Ogre::any_cast<Ogre::Vector3>(parseVector3(subs).val)); params["orientation"] = pOrient; } } while(subs = subs->NextSiblingElement()); *ret = Ogitors::OgitorsRoot::getSingletonPtr()->CreateEditorObject(parent, "Light Object", params, false, false); return SCF_OK; }
void Node::setDirection(Ogre::Vector3 direction, Ogre::Vector3 front_vector) { setRotation(front_vector.getRotationTo(direction, Ogre::Vector3::UNIT_X)); }
bool Character::update(const Ogre::FrameEvent& evt) { if(mState == ST_DEAD) // если мертвый, оставляем только текущую анимацию и выходим { mGraphicBody->update(evt); return 0; } // посчитаем не спал ли статус if(mStatus.lockTime >0) { mStatus.lockTime -= evt.timeSinceLastFrame; } else //if (mStatus.status != STATUS_NORMAL) { addStatus(STATUS_NORMAL, "", 0); StatusMoveVec = Ogre::Vector3::ZERO; //перемещаеть этим вектором можно только под статусом } // повернем лицом к противнику Ogre::Vector3 direction = mTargetNode->getPosition() - mNode->getPosition(); direction.y = 0; Ogre::Real distance = direction.normalise(); if(distance > 0.2) { Ogre::Vector3 src = mNode->getOrientation() * Ogre::Vector3::UNIT_X; src.y = 0; if ((1.0f + src.dotProduct(direction)) < 0.0001f) { mNode->yaw(Ogre::Degree(180)); } else { Ogre::Quaternion quat = src.getRotationTo(direction); mNode->rotate(quat); } // else mPhysicsBody->setOrientation(cvt(mNode->getOrientation())); } //------------------------------------------------------------------ if(mState == ST_ATACK && !mPhysicsBody->isLock()) // если атака закончилась { mState = ST_NOTHING; } if(mState != ST_WALK && mState != ST_RUN) MoveVec = Ogre::Vector3::ZERO; // занулим если не передвигаемся Ogre::Vector3 newPosition = mNode->getPosition() + (MoveVec + StatusMoveVec + pushVec + JumpVec)*evt.timeSinceLastFrame; mNode->setPosition(newPosition); pushVec = Ogre::Vector3::ZERO; // занулим, если вдруг возникнет персечение объектов то этот вектор опять пропишеться if(mPose == POSE_JUMP) // считаем прыжек { if(newPosition.y >= 0) { Ogre::Real newY = JumpVec.y - 10 * evt.timeSinceLastFrame; //учтем гравитацию JumpVec = Ogre::Vector3(JumpVec.x, newY, JumpVec.z); // } else //приземление после прыжка { mPose = POSE_STAND; JumpVec = Ogre::Vector3::ZERO; mGraphicBody->a_stance(); mGraphicBody->setAnimationRate(1); mPhysicsBody->setBaseBodiesTransforms(); mMoveDir = MV_NULL; mPhysicsBody->break_atack(1); } } mPhysicsBody->setPosition(cvt(newPosition)); if(mGraphicBody->isAnimationComplete()) //на всякий случай - чтобы при отсутствии анимаций стоял в стойке { mGraphicBody->a_stance(); mGraphicBody->setAnimationRate(1); } mPhysicsBody->update(evt); mGraphicBody->update(evt); }