// ---------------------------------------------------------------------------- // alternate version: keep FORWARD parallel to velocity, adjust UP according // to a no-basis-in-reality "banking" behavior, something like what birds and // airplanes do // XXX experimental cwr 6-5-03 public void regenerateLocalSpaceForBanking(Vector3 newVelocity, float elapsedTime) { // the length of this global-upward-pointing vector controls the vehicle's // tendency to right itself as it is rolled over from turning acceleration Vector3 globalUp = new Vector3(0, 0.2f, 0); // acceleration points toward the center of local path curvature, the // length determines how much the vehicle will roll while turning Vector3 accelUp = _smoothedAcceleration * 0.05f; // combined banking, sum of UP due to turning and global UP Vector3 bankUp = accelUp + globalUp; // blend bankUp into vehicle's UP basis vector float smoothRate = elapsedTime * 3; Vector3 tempUp = up(); tempUp = OpenSteerUtility.blendIntoAccumulator(smoothRate, bankUp, tempUp); tempUp.Normalise(); setUp(tempUp); // annotationLine (position(), position() + (globalUp * 4), gWhite); // XXX // annotationLine (position(), position() + (bankUp * 4), gOrange); // XXX // annotationLine (position(), position() + (accelUp * 4), gRed); // XXX // annotationLine (position(), position() + (up () * 1), gYellow); // XXX // adjust orthonormal basis vectors to be aligned with new velocity if (speed() > 0) { regenerateOrthonormalBasisUF(newVelocity / speed()); } }
// ---------------------------------------------------------------------------- // apply a given steering force to our momentum, // adjusting our orientation to maintain velocity-alignment. public void applySteeringForce(Vector3 force, float elapsedTime) { Vector3 adjustedForce = adjustRawSteeringForce(force); //, elapsedTime); // enforce limit on magnitude of steering force //Vector3 clippedForce = adjustedForce.truncateLength (maxForce ()); //Vector3 clippedForce = adjustedForce.truncateLength(maxForce()); Vector3 clippedForce = truncateLength(adjustedForce, maxForce()); // compute acceleration and velocity Vector3 newAcceleration = (clippedForce / mass()); Vector3 newVelocity = velocity(); // damp out abrupt changes and oscillations in steering acceleration // (rate is proportional to time step, then clipped into useful range) if (elapsedTime > 0) { float smoothRate = OpenSteerUtility.clip(9 * elapsedTime, 0.15f, 0.4f); _smoothedAcceleration = OpenSteerUtility.blendIntoAccumulator(smoothRate, newAcceleration, _smoothedAcceleration); } // Euler integrate (per frame) acceleration into velocity newVelocity += _smoothedAcceleration * elapsedTime; // enforce speed limit //newVelocity = newVelocity.truncateLength (maxSpeed ()); newVelocity = truncateLength(newVelocity, maxSpeed()); // update Speed setSpeed(newVelocity.Length); // Euler integrate (per frame) velocity into position setPosition(Position + (newVelocity * elapsedTime)); // regenerate local space (by default: align vehicle's forward axis with // new velocity, but this behavior may be overridden by derived classes.) regenerateLocalSpace(newVelocity); //, elapsedTime); // maintain path curvature information measurePathCurvature(elapsedTime); // running average of recent positions _smoothedPosition = OpenSteerUtility.blendIntoAccumulator(elapsedTime * 0.06f, // QQQ Position, _smoothedPosition); }
// ---------------------------------------------------------------------------- // measure path curvature (1/turning-radius), maintain smoothed version void measurePathCurvature(float elapsedTime) { if (elapsedTime > 0) { Vector3 dP = _lastPosition - Position; Vector3 dF = (_lastForward - forward()) / dP.Length; //SI - BIT OF A WEIRD FIX HERE . NOT SURE IF ITS CORRECT //Vector3 lateral = dF.perpendicularComponent (forward ()); Vector3 lateral = OpenSteerUtility.perpendicularComponent(dF, forward()); float sign = (lateral.DotProduct(side()) < 0) ? 1.0f : -1.0f; _curvature = lateral.Length * sign; //OpenSteerUtility.blendIntoAccumulator(elapsedTime * 4.0f, _curvature,_smoothedCurvature); _smoothedCurvature = OpenSteerUtility.blendIntoAccumulator(elapsedTime * 4.0f, _curvature, _smoothedCurvature); _lastForward = forward(); _lastPosition = Position; } }