bool OgreMesh::intersectTri(const Ogre::Ray &ray, IntersectResult &rtn, Triangle*itr, bool isplane) { std::pair<bool, Real> hit = isplane ? Ogre::Math::intersects(ray, Ogre::Plane(itr->v1.coord, itr->v2.coord,itr->v3.coord)) : Ogre::Math::intersects(ray, itr->v1.coord, itr->v2.coord,itr->v3.coord, true, false); rtn.u = 0; rtn.v = 0; if (hit.first && hit.second < rtn.distance) { rtn.intersected = hit.first; rtn.distance = hit.second; Ogre::Vector3 nml=(itr->v1.coord-itr->v2.coord). crossProduct(itr->v3.coord-itr->v2.coord); rtn.normal.x=nml.x; rtn.normal.y=nml.y; rtn.normal.z=nml.z; rtn.tri = *itr; Ogre::Vector3 intersect = ray.getPoint(hit.second) - rtn.tri.v2.coord; Ogre::Vector3 aVec = (rtn.tri.v1.coord - rtn.tri.v2.coord); Ogre::Vector3 bVec = (rtn.tri.v3.coord - rtn.tri.v2.coord); if (aVec.length() > 1.0e-10 && bVec.length() > 1.0e-10) { rtn.u = rtn.tri.v2.u + (rtn.tri.v1.u - rtn.tri.v2.u)*cos(aVec.angleBetween(intersect).valueRadians())*intersect.length()/aVec.length(); rtn.v = rtn.tri.v2.v + (rtn.tri.v3.v - rtn.tri.v2.v)*cos(bVec.angleBetween(intersect).valueRadians())*intersect.length()/bVec.length(); } } return rtn.intersected; }
void BotControlComponent::OnUpdate(double time_diff) { if(IsEnabled()) { if(mAircraftComponentName == "") { dt::Logger::Get().Error("Cannot control aircraft: no aircraft component set."); return; } Ogre::Vector3 diff = mTarget - GetNode()->GetPosition(dt::Node::SCENE); if(diff.length() < 1) { mTarget = Ogre::Vector3(dt::Random::Get(-15.f, 15.f), dt::Random::Get(-10.f, 10.f), 0); diff = mTarget - GetNode()->GetPosition(dt::Node::SCENE); } diff.normalise(); AircraftComponent* aircraft = GetNode()->FindComponent<AircraftComponent>(mAircraftComponentName); aircraft->GetPhysicsBody()->SetCentralForce(btVector3(diff.x, diff.y, 0) * 14); dt::Node* player = GetNode()->GetScene()->FindChildNode("player_aircraft"); //target player diff = player->GetPosition(dt::Node::SCENE) - GetNode()->GetPosition(dt::Node::SCENE); aircraft->SetTargetAngle(Ogre::Vector3::UNIT_X.getRotationTo(diff, Ogre::Vector3::UNIT_Z).getRoll()); if(diff.length() < 15) aircraft->Shoot(); } }
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 DeferredLight::isCameraInsideLight(Ogre::Camera* camera) { switch (parentLight->getType()) { case Ogre::Light::LT_DIRECTIONAL: return false; case Ogre::Light::LT_POINT: { Ogre::Real distanceFromLight = camera->getDerivedPosition().distance(parentLight->getDerivedPosition()); // Small epsilon fix to account for the fact that we aren't a true sphere. return distanceFromLight <= radius + camera->getNearClipDistance() + 0.1; } case Ogre::Light::LT_SPOTLIGHT: { Ogre::Vector3 lightPos = parentLight->getDerivedPosition(); Ogre::Vector3 lightDir = parentLight->getDerivedDirection(); Ogre::Radian attAngle = parentLight->getSpotlightOuterAngle(); // Extend the analytic cone's radius by the near clip range by moving its tip accordingly. Ogre::Vector3 clipRangeFix = -lightDir * (camera->getNearClipDistance() / Ogre::Math::Tan(attAngle/2)); lightPos = lightPos + clipRangeFix; Ogre::Vector3 lightToCamDir = camera->getDerivedPosition() - lightPos; Ogre::Real distanceFromLight = lightToCamDir.normalise(); Ogre::Real cosAngle = lightToCamDir.dotProduct(lightDir); Ogre::Radian angle = Ogre::Math::ACos(cosAngle); // Check whether we will see the cone from our current POV. return (distanceFromLight <= (parentLight->getAttenuationRange() + clipRangeFix.length())) && (angle <= attAngle); } default: return false; } }
/*---------------------------------------------------------------------------------*/ void CameraHandler::Zoom(const OIS::MouseEvent &arg) { bool okToZoom = false; //Direction from imaginary camera position to character Ogre::Vector3 directionToCharacter = mvpCharNode->_getDerivedPosition() - mvpCamNoCollisionNode->_getDerivedPosition(); //No direction in Y direction. directionToCharacter.y = 0; //To check if we're too close or too far Ogre::Real lengthToCharacter = directionToCharacter.length(); //If zoom is positive, we only have to worry about going too close if (lengthToCharacter > *mvpCamDistanceMin && arg.state.Z.rel > 0) { okToZoom = true; } //If zoom is negative, we only have to worry about going too far else if (lengthToCharacter < *mvpCamDistanceMax && arg.state.Z.rel < 0) { okToZoom = true; } if (okToZoom) { //Always the same speed, not dependent of the distance directionToCharacter.normalise(); //At the startup, the camera was translated @ Z axis. mvpCamNoCollisionNode->translate(Ogre::Vector3::NEGATIVE_UNIT_Z * (*mvpZoom) * arg.state.Z.rel, Ogre::Node::TS_LOCAL); } }
void CombatCamera::MouseWheel(const GG::Pt& pt, int move, GG::Flags<GG::ModKey> mod_keys) { Ogre::Real total_move = TotalMove(move, mod_keys, DistanceToLookAtPoint()); if (0 < move) { const unsigned int TICKS = GG::GUI::GetGUI()->Ticks(); const unsigned int ZOOM_IN_TIMEOUT = 750u; if (m_initial_zoom_in_position == INVALID_MAP_LOCATION || ZOOM_IN_TIMEOUT < TICKS - m_previous_zoom_in_time) { std::pair<bool, Ogre::Vector3> intersection = IntersectMouseWithEcliptic(pt); m_initial_zoom_in_position = intersection.first ? intersection.second : INVALID_MAP_LOCATION; } if (m_initial_zoom_in_position != INVALID_MAP_LOCATION) { const double CLOSE_FACTOR = move * 0.333 * ZoomFactor(mod_keys); Ogre::Vector3 start = Moving() ? m_look_at_point_target : LookAtPoint(); Ogre::Vector3 delta = m_initial_zoom_in_position - start; double delta_length = delta.length(); double distance = std::min(std::max(1.0, delta_length * CLOSE_FACTOR), delta_length); delta.normalise(); Ogre::Vector3 new_center = start + delta * distance; if (new_center.length() < SystemRadius()) LookAtPositionAndZoom(new_center, ZoomResult(total_move)); } m_previous_zoom_in_time = TICKS; } else if (move < 0) { ZoomImpl(total_move); } }
Ogre::Vector3 separate(const Vehicle& agent, const std::set<Vehicle*>& neighbours, const float simulation_time) { Ogre::Vector3 result(Ogre::Vector3::ZERO) ; for(std::set<Vehicle*>::const_iterator neighbour = neighbours.begin() ; neighbour != neighbours.end() ; ++neighbour) { // test proximity const float sumOfRadii = agent.getRadius() + (*neighbour)->getRadius() ; const float minCenterToCenter = sumOfRadii; Ogre::Vector3 offset = (*neighbour)->predictFuturePosition(simulation_time)- agent.predictFuturePosition(simulation_time) ; const float futureDistance = offset.length() ; InternalMessage("SteeringBehaviour","SteeringBehaviour::separate offset=" + Kernel::toString(offset.x) + "," + Kernel::toString(offset.y) + "," + Kernel::toString(offset.z)) ; if (futureDistance < minCenterToCenter) { result += offset / (futureDistance*futureDistance) ; } InternalMessage("SteeringBehaviour","SteeringBehaviour::futureDistance =" + Kernel::toString(futureDistance)) ; } InternalMessage("SteeringBehaviour","SteeringBehaviour::separate =" + Kernel::toString(result.x) + "," + Kernel::toString(result.y) + "," + Kernel::toString(result.z)) ; return result ; }
void CharacterController::UpdateAI(float dt) { _CurrentPathAge += dt; //std::cerr << _CurrentPathIndex << " / " << _CurrentPath.size() << "\n"; if (_CurrentPathIndex + 2 <= _CurrentPath.size()) { Ogre::Vector3 const & a = _CurrentPath[_CurrentPathIndex]; Ogre::Vector3 const & b = _CurrentPath[_CurrentPathIndex+1]; Ogre::Vector3 const & m = GetPosition(); Ogre::Vector3 const ab = b - a; Ogre::Vector3 const am = m - a; Ogre::Vector3 const mb = b - m; Ogre::Vector3 const mb_unit = mb.normalisedCopy(); float remaining = mb.length(); for(size_t i = _CurrentPathIndex + 1; i + 2 <= _CurrentPath.size(); ++i) { remaining += _CurrentPath[i].distance(_CurrentPath[i+1]); } //std::cerr << "Remaining distance: " << remaining << " m\n"; float lambda = am.dotProduct(ab) / ab.squaredLength(); //const float tau = 0.1; SetVelocity(_CurrentVelocity * mb_unit); if (lambda > 1) _CurrentPathIndex++; /*if (_CurrentPathIndex + 1 == _CurrentPath.size()) SetVelocity(Ogre::Vector3(0.));*/ } }
void CEntity::UpdateMovement(Ogre::Real ElapsedTime) { //Also update walk/idle animation? if( IsMoving() ){ Ogre::Real LenghtLeftToGo = (GetDestination() - GetPosition()).length(); Ogre::Vector3 Movement = GetMovement(); Ogre::Vector3 CorrectedMovement = ( Movement * ElapsedTime ); //Set the right angle for the entity mNode->lookAt( GetDestination(), Ogre::Node::TS_WORLD ); if( CorrectedMovement.length() < LenghtLeftToGo ){ //Not at destination yet, just move mNode->translate( CorrectedMovement ); }else{ //Arrived at destination mNode->setPosition( GetDestination() ); ReachedDestination(); //TODO: If there is a next destination then go there with the frametime left of this movement. //(Loop till all frametime is used for movement) //Example: if there are 3 destinations left, and the first 2 will be reached //in 2 seconds. //If the user has a slow computer that updates the frame every 2,5 seconds, //then it should first use x seconds to reach destination one, then check //for how many seconds left, and use those to go to the next node and so on. } } }
void AnimalThirdPersonControler::orient(int i_xRel, int i_yRel, double i_timeSinceLastFrame) { if (!(m_pAnimal != nullptr && m_pCamera != nullptr)) return; Ogre::Vector3 camPos = m_pCamera->getPosition(); Ogre::Radian angleX(i_xRel * -m_camAngularSpeed); Ogre::Radian angleY(i_yRel * -m_camAngularSpeed); Ogre::Vector3 avatarToCamera = m_pCamera->getPosition() - m_pAnimal->m_pNode->getPosition(); // restore lenght if (avatarToCamera.length() != m_camDistance) avatarToCamera = avatarToCamera.normalisedCopy() * m_camDistance; // Do not go to the poles Ogre::Radian latitude = m_pAnimal->m_pNode->getOrientation().zAxis().angleBetween(avatarToCamera); if (latitude < Ogre::Radian(Ogre::Math::DegreesToRadians(10.f)) && angleY < Ogre::Radian(0.f)) angleY = Ogre::Radian(0.f); else if (latitude > Ogre::Radian(Ogre::Math::DegreesToRadians(170.f)) && angleY > Ogre::Radian(0.f)) angleY = Ogre::Radian(0.f); Ogre::Quaternion orient = Ogre::Quaternion(angleY, m_pCamera->getOrientation().xAxis()) * Ogre::Quaternion(angleX, m_pCamera->getOrientation().yAxis()); Ogre::Vector3 newAvatarToCamera = orient * avatarToCamera; // Move camera closer if collides with terrain m_collideCamWithTerrain(newAvatarToCamera); }
Ogre::Vector3 evade(const Vehicle& agent,const Vehicle& target) { // a parameter const float maxPredictionTime = 2 ; Ogre::Vector3 offset = target.getPosition()-agent.getPosition() ; const float distance = offset.length() ; // may be equal to zero when target has reached agent const float roughTime = distance / target.getSpeed().length() ; const float predictionTime = ((roughTime > maxPredictionTime) ? maxPredictionTime : roughTime); const Ogre::Vector3 menace_position = target.predictFuturePosition(predictionTime) ; Ogre::Vector3 desiredVelocity = agent.getPosition() - menace_position ; const float desiredSpeed = desiredVelocity.normalise() ; if (desiredSpeed == 0) { desiredVelocity = agent.getForward() ; desiredVelocity.normalise() ; } // we should evade with maximum speed desiredVelocity = desiredVelocity*agent.getMaxSpeed() ; agent.normalizeSpeed(desiredVelocity) ; return desiredVelocity-agent.getSpeed() ; }
/* distance(target_positon+t*target_speed) = t*interceptor_speed formal solver gives : delta = (-target_positon.y^2-target_positon.x^2)*target_speed.z^2 +(2*target_positon.y*target_positon.z*target_speed.y+2*target_positon.x*target_positon.z*target_speed.x)*target_speed.z +(-target_positon.z^2-target_positon.x^2)*target_speed.y^2 +2*target_positon.x*target_positon.y*target_speed.x*target_speed.y +(-target_positon.z^2-target_positon.y^2)*target_speed.x^2 +interceptor_speed^2*target_positon.z^2 +interceptor_speed^2*target_positon.y^2 +interceptor_speed^2*target_positon.x^2 if delta > 0 t = (sqrt(delta) -target_positon.z*target_speed.z-target_positon.y*target_speed.y-target_positon.x*target_speed.x) /(target_speed.z^2+target_speed.y^2+target_speed.x^2-laser_speed^2) special case for delta=0 when equation becomes linear */ std::pair<bool,float> calculateInterceptionTime( const Ogre::Vector3& target_position, const Ogre::Vector3& target_speed, const float& interceptor_speed) { // result ; float time = 0 ; if (target_speed.length() != 0) { float delta = (-pow(target_position.y,2)-pow(target_position.x,2))*pow(target_speed.z,2) +(2*target_position.y*target_position.z*target_speed.y+2*target_position.x*target_position.z*target_speed.x)*target_speed.z +(-pow(target_position.z,2)-pow(target_position.x,2))*pow(target_speed.y,2) +2*target_position.x*target_position.y*target_speed.x*target_speed.y +(-pow(target_position.z,2)-pow(target_position.y,2))*pow(target_speed.x,2) +pow(interceptor_speed,2)*pow(target_position.z,2) +pow(interceptor_speed,2)*pow(target_position.y,2) +pow(interceptor_speed,2)*pow(target_position.x,2) ; float divisor = target_speed.squaredLength()-pow(interceptor_speed,2) ; if (delta > 0 && fabs(divisor) > 1e-10) { float b = -target_position.z*target_speed.z-target_position.y*target_speed.y-target_position.x*target_speed.x ; time = (sqrt(delta)+b)/divisor ; if (time < 0) time = (-sqrt(delta)+b)/divisor ; } else { /// no real solution : target is unreachable by interceptor return std::pair<bool,float>(false,0) ; } } else { time = target_position.length()/interceptor_speed ; } return std::pair<bool,float>(true,time) ; }
//----------------------------------------------------------------------- void LineEmitter::_notifyRescaled(const Ogre::Vector3& scale) { // Scale the internal attributes and use them, otherwise this results in too many calculations per particle ParticleEmitter::_notifyRescaled(scale); Ogre::Real scaleLength = scale.length(); _mScaledEnd = mEnd * scale; _mScaledMaxDeviation = mMaxDeviation * scaleLength; _mScaledMinIncrement = mMinIncrement * scaleLength; _mScaledMaxIncrement = (mMaxIncrement - mMinIncrement) * scaleLength; _mScaledLength = _mScaledEnd.length(); }
void Bomber::move(Ogre::Vector3 distance) { if(warpTimer <= 0.0 && distance.length() <= 10000){ m_pNode->translate(m_pNode->getOrientation() * -50 * Ogre::Vector3::UNIT_Y); m_pNode->needUpdate(); warpTimer = 60.0f; }else{ warpTimer -= 0.1f; } }
//------------------------------------------------------------------------- void ManualObject::position( const Ogre::Vector3 &position ) { if( m_position == nullptr ) { createPositionBuffer(); } *(m_position++) = position; m_bbox.merge( position ); m_radius = std::max( m_radius, position.length() ); }
void Robot::update(Ogre::Real dt) { switch(state) { case STAND: animationState->addTime(0.0001f*speed*dt); if (foundTarget()) setState(SEEK); else if (rand() % 400 == 1) setState(WANDER); break; case WANDER: { Ogre::Real dist = targetLocation.distance(this->getPosition()); if (dist < speed * dt) { setPosition(targetLocation); if (rand() % 5 != 1) setState(STAND); else setState(WANDER); } else { Ogre::Vector3 dir = (targetLocation - getPosition()).normalisedCopy(); this->translate(dir * speed * dt); animationState->addTime(0.0001f*dt); } if (foundTarget()) setState(SEEK); break; } case SEEK: { Ogre::Vector3 targetDiff = target->getPosition() - this->getPosition(); if (targetDiff.length() > 20) { setState(WANDER); } else if (targetDiff.length() > 5) { setVelocity(Ogre::Vector3::ZERO); } break; } } }
void RotateControlet::injectMouseMove(int _absx, int _absy, int _absz){ if( mPick && (_absx!=mMouseX || _absy!=mMouseY) ){ /*上一个鼠标位置和眼睛组成的射线A,新的鼠标位置和眼睛组成的射线B 它们和旋转盘相交,交点和旋转盘中心组成的矢量的角度,既是旋转角 */ Game& game = Game::getSingleton(); int sx = game.getScreenWidth(); int sy = game.getScreenHeight(); Ogre::Vector3 eye = game.getCamera()->getPosition(); Ogre::Ray A = game.getCamera()->getCameraToViewportRay( (Ogre::Real)mMouseX/(Ogre::Real)sx, (Ogre::Real)mMouseY/(Ogre::Real)sy ); Ogre::Ray B = game.getCamera()->getCameraToViewportRay( (Ogre::Real)_absx/(Ogre::Real)sx, (Ogre::Real)_absy/(Ogre::Real)sy ); //计算和旋转盘的交点,旋转盘是一个平面 //平面的法向量是Local Z轴,平面通过Local原点 Ogre::Matrix3 m3 = mNode->getLocalAxes(); Ogre::Vector3 v3 = mNode->getPosition(); Ogre::Vector3 axis(m3[0][2],m3[1][2],m3[2][2]); Ogre::Plane P(axis,v3 ); //旋转盘平面 Math3d::CalcResult result1 = Math3d::CalcRayPlanePoint( A,P ); Math3d::CalcResult result2 = Math3d::CalcRayPlanePoint( B,P ); if( result1.first && result2.first ){ //方程都有解 Ogre::Vector3 a,b; a = result1.second; b = result2.second; a -= v3;b -= v3; a.normalise(); b.normalise(); Ogre::Vector3 c = b.crossProduct(a); Ogre::Real sinv = c.length(); Ogre::Real ang = asinf(sinv); if( axis.dotProduct( c ) > 0 ) ang = -ang; mNode->rotate( axis,Ogre::Radian(ang),Ogre::Node::TS_WORLD ); mNotify( mName,axis,ang ); } mMouseX = _absx; mMouseY = _absy; } mouseFocus( _absx,_absy ); }
void RacketPhysics::testCollisionWithBall() { if (timeSinceLastHit < 0.5f) return; Ogre::Vector3 racketNormal = Ogre::Vector3::UNIT_Y; racketNormal = ori * racketNormal; Ogre::Vector3 ballPos = ball->getPosition(); Ogre::Plane racketPlane(racketNormal, pos); float distanceFromPlane = racketPlane.getDistance(ballPos); if (distanceFromPlane < 0.0f) { racketNormal = -racketNormal; distanceFromPlane = -distanceFromPlane; } //if (distanceFromPlane < g_RacketThickness + g_BallRadius) if (distanceFromPlane < 0.03f) { Ogre::Vector3 distanceVector = racketNormal * distanceFromPlane; Ogre::Vector3 nearestPointOnPlane = ballPos - distanceVector; Ogre::Vector3 distanceOnPlane = nearestPointOnPlane - pos; //odprintf("dist before: %f, %f, %f", distanceOnPlane.x, distanceOnPlane.y, distanceOnPlane.z); distanceOnPlane.z *= 0.5f; distanceOnPlane.y *= 0.5f; //odprintf("dist after: %f, %f, %f", distanceOnPlane.x, distanceOnPlane.y, distanceOnPlane.z); float projectedDistance = distanceOnPlane.length(); //odprintf("dist sum: %f", projectedDistance); //if (projectedDistance < g_RacketRadiusB) if (projectedDistance < 0.3f) { odprintf("HIT, time sinc last hit: %f", timeSinceLastHit); timeSinceLastHit = 0; // Collision ballPos += distanceVector * (0.03f/abs(distanceFromPlane)); ball->setPosition(ballPos); Ogre::Vector3 ballSpeed = ball->getSpeed(); ballSpeed = ballSpeed.reflect(racketNormal); // Perpendicular element, used for spin Ogre::Vector3 speedPerp = racketPlane.projectVector(speed); ball->setSpin(speedPerp.crossProduct(racketNormal)); // Parallel element, used for speed Ogre::Vector3 speedPara = speed - speedPerp; ballSpeed += speedPara * g_HitStrength; ball->setSpeed(ballSpeed); gameLogic->onTouchRacket(playerId); } else { //odprintf("no hit, time sinc last hit: %f", timeSinceLastHit); } } }
void NPCCharacter::_behaviorMove(const Ogre::Vector3& target) { //Check for duplicate move calls and update lua function call with that info //std::cout << target << std::endl; if(_destination.squaredDistance(target) >= 5) { updateDestination(target,false); _destination = target; } if(destinationReached()) { _isBhvFinished = true; } else { _isBhvFinished = false; } //point the character in the direction it's traveling Ogre::Vector3 vel = getVelocity(); float speed = vel.length(); vel.y = 0; vel.normalise(); if(speed > .2f) { Ogre::Vector3 src = _node->getOrientation() * Ogre::Vector3::NEGATIVE_UNIT_Z; src.y = 0; //moving sufficiently fast, change to moving animation and point character Utility::rotateToTarget(_node,vel,true); //change animation if needed. if(_animHandler.getSource() != nullptr) { Ogre::AnimationState* target = _animHandler.getTarget(); //this relies on the properties of the '&&' construct used by C++(if the first is false, //then the if-statement is false. It DOESN'T check both fields. if((target == nullptr && _animHandler.getSource()->getAnimationName() != "Walk") || (target != nullptr && target->getAnimationName() != "Walk")) { _animHandler.blend("Walk",AnimationBlender::BlendWhileAnimating,.2f,true); } } } //also have to reset the head, since I'm manually controlling it. Ogre::Skeleton* skel = static_cast<Ogre::Entity*>(_movableObject)->getSkeleton(); Ogre::Bone* headBone = skel->getBone("Bip01_Head"); //not sure how to do this. }
void AgentVehicle::onInit() { InternalMessage("AI","entering AgentVehicle::onInit") ; Ogre::Vector3 speed = getSpeed() ; m_vehicle.reset(new Vehicle(getPosition(), getOrientation(), speed, speed.length(), getSize())) ; getViewPoint()->setVehicle(m_vehicle.get()) ; InternalMessage("AI","leaving AgentVehicle::onInit") ; }
void SlideCollisionResponse::Response(PhysObjDescriptor* object, CollisionModel3D *CollisionModel, bool ismodelowner) { // при коллизии определяется треугольник и объект движется параллельно плоскости тругольника float t1[9], t2[9], p[3], *t; CollisionModel->getCollisionPoint(p,false); Ogre::Vector3 normal, IntersectionPoint(p[0],p[1],p[2]); CollisionModel->getCollidingTriangles(t1, t2, false); if (ismodelowner) t=t1; else t=t2; Ogre::Plane collidplane(Ogre::Vector3(t[0],t[1],t[2]), Ogre::Vector3(t[3],t[4],t[5]), Ogre::Vector3(t[6],t[7],t[8])); Ogre::Vector3 proj = collidplane.projectVector(object->LinVelocity); proj.normalise(); Ogre::Vector3 Normal = collidplane.normal; Ogre::Vector3 linvel = object->LinVelocity; Ogre::Vector3 throttle = object->Throttle; Ogre::Vector3 dir=proj+Normal/2; dir.normalise(); object->Object->SetForces(Ogre::Vector3::ZERO); object->VelocityVector = dir*(linvel.length()+1); object->LinVelocity = dir*(linvel.length()+1); object->Object->SetReplacingDirection(dir*(linvel.length()+1)); object->Object->AddForce(IntersectionPoint, dir*(linvel.length()+1)*Owner->GetMass()/object->Object->GetMass()); }
//------------------------------------------------------------------------------------- void EntitySimple::addTime(Real deltaTime) { if(blocktime_ <= 0.f) { Ogre::Vector3 currpos = getLastPosition(); if(kbe_playerID() != mID) { Ogre::Vector3 movement = destPos_ - currpos; float speed = mMoveSpeed * deltaTime; movement.y = 0.f; Real mlen = movement.length(); if(mlen < speed || (mLastAnimName != "Run" && mlen <= 1.0f)) { if (mLastAnimName == "Run") { float y = currpos.y; currpos = destPos_; currpos.y = y; playAnimation("Idle"); } } else { movement.normalise(); // Òƶ¯Î»Öà movement *= speed; currpos += movement; playAnimation("Run"); } } blocktime_ = 0.f; setPosition(currpos.x, currpos.y, currpos.z); KBEntity::addTime(deltaTime); } else { blocktime_ -= deltaTime; playAnimation("Block"); } if(mLastAnims) mLastAnims->addTime(deltaTime); }
void OrientationControlet::injectMouseMove(int _absx, int _absy, int _absz){ if( mPick && (_absx!=mMouseX || _absy!=mMouseY) ){ /*计算和摇杆球面的交点 */ Game& game = Game::getSingleton(); int sx = game.getScreenWidth(); int sy = game.getScreenHeight(); Ogre::Vector3 eye = game.getCamera()->getPosition(); Ogre::Ray A = game.getCamera()->getCameraToViewportRay( (Ogre::Real)mMouseX/(Ogre::Real)sx, (Ogre::Real)mMouseY/(Ogre::Real)sy ); Ogre::Ray B = game.getCamera()->getCameraToViewportRay( (Ogre::Real)_absx/(Ogre::Real)sx, (Ogre::Real)_absy/(Ogre::Real)sy ); //计算和旋转盘的交点,旋转盘是一个平面 //平面的法向量是Local Z轴,平面通过Local原点 Ogre::Matrix3 m3 = mNode->getLocalAxes(); Ogre::Vector3 v3 = mNode->getPosition(); Ogre::Vector3 axis = m3.GetColumn(2); Ogre::Sphere S(v3,mRaduis); Math3d::CalcResult result1 = Math3d::CalcRaySphereNearFarPoint(A,S,mNearFar); Math3d::CalcResult result2 = Math3d::CalcRaySphereNearFarPoint(B,S,mNearFar); if( result1.first && result2.first ){//都相交 //然后使用直线的参数方程计算出具体的焦点 Ogre::Vector3 a = result1.second; Ogre::Vector3 b = result2.second; a -= v3;b -= v3; a.normalise(); b.normalise(); Ogre::Vector3 c = b.crossProduct(a); Ogre::Real sinv = c.length(); Ogre::Real ang = -asinf(sinv); c.normalise(); mNode->rotate( c,Ogre::Radian(ang),Ogre::Node::TS_WORLD ); mNotify( mName,c,ang ); } mMouseX = _absx; mMouseY = _absy; } mouseFocus( _absx,_absy ); }
void LuaScriptUtilities::SetLineStartEnd( Ogre::SceneNode* line, const Ogre::Vector3& start, const Ogre::Vector3& end) { Ogre::Vector3 lineVector = end - start; Ogre::Quaternion lineRotation = Ogre::Vector3::UNIT_Z.getRotationTo(lineVector.normalisedCopy()); line->setOrientation(lineRotation * Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3::UNIT_X)); line->setPosition(start); line->setScale(0.01f, lineVector.length(), 0.01f); }
void ChangeDisplay::addArrow(Ogre::Vector3 from, Ogre::Vector3 to, int r, int g, int b) { Ogre::SceneNode* frame_node = scene_node_->createChildSceneNode(); ArrowPtr arrow(new Arrow(context_->getSceneManager(), frame_node)); arrow->setColor(255.0, 0, 0, 1.0); arrow->setPosition(from); Ogre::Vector3 direct = to - from; float length = direct.length(); arrow->setDirection(direct); arrow->setScale(Ogre::Vector3(length*0.8, length, length)); frame_node->setPosition(position); frame_node->setOrientation(orientation); arrows.push_back(arrow); }
void OrientationControlet::setOrient( const Ogre::Vector3& o, const Ogre::Vector3& ax, const Ogre::Real s ) { if( mScale != s || !mNode ){ //重新调整外观 mScale = s; rebuildEntity(); } mRaduis = ax.length() + 2*s; mNode->setPosition( o ); mNode->setDirection( ax,Ogre::Node::TS_WORLD ); mNodeLocal->setPosition( Ogre::Vector3(0,0,mRaduis) ); }
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); }
Ogre::Vector3 SteeringBehaviors::Pursuit(Character* evader) { Ogre::Vector3 ToEvader = evader->GetSceneNode()->getPosition() - mCharacter->GetSceneNode()->getPosition(); double RelativeHeading = mCharacter->GetHeading().dotProduct(evader->GetHeading()); //if evader is in front and moving forward if((ToEvader.dotProduct(mCharacter->GetHeading())) > 0 && (RelativeHeading < -0.95)) return Seek(evader->GetSceneNode()->getPosition()); //not ahead so look forward double LookAheadTime = ToEvader.length() / (mCharacter->GetMaxSpeed() + evader->GetMaxSpeed()); Ogre::Vector3 currentVelocity = evader->GetVelocity(); Ogre::Real currentSpeed = currentVelocity.normalise(); Ogre::Vector3 desiredVelocity = Seek(evader->GetSceneNode()->getPosition() + evader->GetHeading() * currentSpeed * LookAheadTime); desiredVelocity.y = 0; return desiredVelocity; }
bool SceneEntity::notifyMoved(const OIS::MouseEvent &evt, const Ogre::Ray &ray) { if(evt.state.buttonDown(OIS::MB_Left)) { Ogre::Vector3 position = ray.getPoint(mCollsionDepth) + mPickedNodeOffset; Ogre::Vector3 pos = position - mSceneNode->getPosition(); float dis = pos.length(); if(dis < 500) { if(mIsXFixed) position.x = mSceneNode->getPosition().x; if(mIsYFixed) position.y = mSceneNode->getPosition().y; if(mIsZFixed) position.z = mSceneNode->getPosition().z; mSceneNode->setPosition(position); AxisEntity::getSingletonPtr()->setPosition(position); AxisEntity::getSingletonPtr()->setVisible(true); } } return true; }
void BoneCollisionManager::checkMesh(Ogre::String outFileName, Ogre::SceneNode* node) { std::ofstream file(outFileName.c_str()); if (file) { Ogre::Entity* ent = (Ogre::Entity*)node->getAttachedObject(0); Ogre::SkeletonInstance* skeletonInst = ent->getSkeleton(); Ogre::Skeleton::BoneIterator boneI=skeletonInst->getBoneIterator(); //file<<"Creating bone length information from:\n"; file<<"Mesh name: "<<ent->getMesh()->getName()<<"\n"; file<<"Skeleton name: "<<skeletonInst->getName()<<"\n\n"; while(boneI.hasMoreElements()) { Ogre::Bone* bone=boneI.getNext(); Ogre::String bName=bone->getName(); if (bone->getChild(0)) { Ogre::Vector3 curr = bone->_getDerivedPosition(); Ogre::Vector3 next = bone->getChild(0)->_getDerivedPosition(); Ogre::Vector3 difference = next-curr; //length of bone Ogre::Real lenght = difference.length(); file<<bName<<":\nLength\t\t\t=\t"<<Ogre::StringConverter::toString(lenght,3)<<"\n"<< "Position"<<"\t\t=\t"<<Ogre::StringConverter::toString(curr.x,1)<<", "<< Ogre::StringConverter::toString(curr.y,1)<<", "<< Ogre::StringConverter::toString(curr.z,1)<<"\n"; if (!bone->getParent()) file<<bName<<" is a Root Bone!\n\n"; else file<<"\n\n"; } } } }