//--------------------- AccumulateForce ---------------------------------- // // This function calculates how much of its max steering force the // vehicle has left to apply and then applies that amount of the // force to add. //------------------------------------------------------------------------ bool SteeringBehaviors::AccumulateForce(Vector3 &RunningTot, Vector3 ForceToAdd) { //calculate how much steering force the vehicle has used so far double MagnitudeSoFar = vectorMag(RunningTot); //calculate how much steering force remains to be used by this vehicle double MagnitudeRemaining = _vehicle->MaxForce() - MagnitudeSoFar; //return false if there is no more force left to use if (MagnitudeRemaining <= 0.0) return false; //calculate the magnitude of the force we want to add double MagnitudeToAdd = vectorMag(ForceToAdd); //if the magnitude of the sum of ForceToAdd and the running total //does not exceed the maximum force available to this vehicle, just //add together. Otherwise add as much of the ForceToAdd vector is //possible without going over the max. if (MagnitudeToAdd < MagnitudeRemaining) { RunningTot += ForceToAdd; } else { Vector3 forceNormal = Vector3(ForceToAdd); forceNormal.normalize(); //add it to the steering force RunningTot += (forceNormal * MagnitudeRemaining); } return true; };
Vector3 SteeringBehaviors::Evade(const BaseEntity *pursuer) { Vector3 toPursuer = pursuer->position - this->_vehicle->position; double lookAheadTime = vectorMag(toPursuer) / (this->_vehicle->MaxSpeed() + pursuer->Speed()); lookAheadTime += this->LookAheadTime(this->_vehicle, pursuer->position); return Flee(pursuer->position + pursuer->Velocity() * lookAheadTime); };
void Quaternion::setToRotateAboutAxis(const Vector3& axis, float theta) { assert(fabs(vectorMag(axis) - 1.0f) < 0.01f); float alpha = theta*0.5f; float sinAlpha = sin(alpha); w = cos(alpha); x = axis.x*sinAlpha; y = axis.y*sinAlpha; y = axis.z*sinAlpha; }
void Quaternion::setToRotateAboutAxis(const Vector3& axis, float theta) { assert(fabs(vectorMag(axis) - 1.0f) < 0.01f); float thetaOver2 = theta * 0.5f; float sinThetaOver2 = sin(thetaOver2); float cosThetaOver2 = cos(thetaOver2); w = cosThetaOver2; x = axis.x*sinThetaOver2; y = axis.y*sinThetaOver2; z = axis.z*sinThetaOver2; }
Vector3 SteeringBehaviors::Pursue(const BaseEntity *evador) { Vector3 toEvador = evador->position - this->_vehicle->position; double relativeHeader = (this->_vehicle->Heading() * evador->Heading()); if((toEvador * this->_vehicle->Heading()) > 0) { return Seek(evador->position); } double lookAheadTime = vectorMag(toEvador) / (this->_vehicle->MaxSpeed() + evador->Speed()); lookAheadTime += this->LookAheadTime(this->_vehicle, evador->position); return Seek(evador->position + evador->Velocity() * lookAheadTime); };
Vector3 SteeringBehaviors::Arrive(const Vector3 target, Deceleration deceleration) { Vector3 toTarget = target - _vehicle->position; double dist = vectorMag(toTarget); if(dist > 0) { const double decelerationTween = 0.3; double speed = dist * ((double)deceleration * decelerationTween); speed = std::min(speed, _vehicle->MaxSpeed()); Vector3 desiredVelocity = toTarget * (speed / dist); return desiredVelocity - _vehicle->Velocity(); } return Vector3(); };
void Quaternion::setToRotateAboutAxis(const Vector3& axis, float theta) { // The axis of rotation must be normalized _ASSERTE(fabs(vectorMag(axis) - 1.0f) < .01f); // Compute the half angle and its sin float thetaOver2 = theta * .5f; float sinThetaOver2 = sin(thetaOver2); // Set the values w = cos(thetaOver2); x = axis.x * sinThetaOver2; y = axis.y * sinThetaOver2; z = axis.z * sinThetaOver2; }
double Speed()const { return vectorMag(this->_velocity); }