34 using System.Collections.Generic;
35 using System.Reflection;
36 using System.Runtime.InteropServices;
38 using OpenSim.Framework;
39 using OpenSim.Region.PhysicsModules.SharedBase;
41 namespace OpenSim.
Region.PhysicsModule.BulletS
45 #pragma warning disable 414
46 private static string LogHeader =
"[BULLETSIM VEHICLE]";
47 #pragma warning restore 414
52 private bool m_haveRegisteredForSceneEvents;
55 private float m_vehicleMass;
69 private Vector3 m_BlockingEndPoint = Vector3.Zero;
70 private Quaternion m_RollreferenceFrame = Quaternion.Identity;
71 private Quaternion m_referenceFrame = Quaternion.Identity;
75 private Vector3 m_linearMotorDirection = Vector3.Zero;
76 private Vector3 m_linearMotorOffset = Vector3.Zero;
77 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero;
78 private Vector3 m_linearFrictionTimescale = Vector3.Zero;
79 private float m_linearMotorDecayTimescale = 1;
80 private float m_linearMotorTimescale = 1;
81 private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
82 private Vector3 m_lastPositionVector = Vector3.Zero;
88 private Vector3 m_angularMotorDirection = Vector3.Zero;
90 private Vector3 m_angularMotorVelocity = Vector3.Zero;
91 private float m_angularMotorTimescale = 1;
92 private float m_angularMotorDecayTimescale = 1;
93 private Vector3 m_angularFrictionTimescale = Vector3.Zero;
94 private Vector3 m_lastAngularVelocity = Vector3.Zero;
95 private Vector3 m_lastVertAttractor = Vector3.Zero;
98 private BSVMotor m_angularDeflectionMotor =
new BSVMotor(
"AngularDeflection");
99 private float m_angularDeflectionEfficiency = 0;
100 private float m_angularDeflectionTimescale = 0;
101 private float m_linearDeflectionEfficiency = 0;
102 private float m_linearDeflectionTimescale = 0;
105 private float m_bankingEfficiency = 0;
106 private float m_bankingMix = 1;
107 private float m_bankingTimescale = 0;
111 private float m_VhoverHeight = 0f;
112 private float m_VhoverEfficiency = 0f;
113 private float m_VhoverTimescale = 0f;
114 private float m_VhoverTargetHeight = -1.0f;
116 private float m_VehicleBuoyancy = 0f;
117 private Vector3 m_VehicleGravity = Vector3.Zero;
120 private BSVMotor m_verticalAttractionMotor =
new BSVMotor(
"VerticalAttraction");
121 private float m_verticalAttractionEfficiency = 1.0f;
122 private float m_verticalAttractionCutoff = 500f;
124 private float m_verticalAttractionTimescale = 510f;
127 #pragma warning disable 414
128 static readonly
float TwoPI = ((float)Math.PI) * 2f;
129 static readonly
float FourPI = ((float)Math.PI) * 4f;
130 static readonly
float PIOverFour = ((float)Math.PI) / 4f;
131 static readonly
float PIOverTwo = ((float)Math.PI) / 2f;
132 #pragma warning restore 414
135 : base(myScene, myPrim, actorName)
137 Type = Vehicle.TYPE_NONE;
138 m_haveRegisteredForSceneEvents =
false;
141 if (ControllingPrim == null)
145 VDetailLog(
"{0},Creation", ControllingPrim.LocalID);
151 get {
return (
Type !=
Vehicle.TYPE_NONE && ControllingPrim.IsPhysicallyActive); }
155 public bool IsGroundVehicle
160 #region Vehicle parameter setting
163 VDetailLog(
"{0},ProcessFloatVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
168 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
169 m_angularDeflectionEfficiency = ClampInRange(0f, pValue, 1f);
171 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
172 m_angularDeflectionTimescale = ClampInRange(0.25f, pValue, 120);
174 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
175 m_angularMotorDecayTimescale = ClampInRange(0.25f, pValue, 120);
176 m_angularMotor.TargetValueDecayTimeScale = m_angularMotorDecayTimescale;
178 case Vehicle.ANGULAR_MOTOR_TIMESCALE:
179 m_angularMotorTimescale = ClampInRange(0.25f, pValue, 120);
180 m_angularMotor.TimeScale = m_angularMotorTimescale;
182 case Vehicle.BANKING_EFFICIENCY:
183 m_bankingEfficiency = ClampInRange(-1f, pValue, 1f);
185 case Vehicle.BANKING_MIX:
186 m_bankingMix = ClampInRange(0.01f, pValue, 1);
188 case Vehicle.BANKING_TIMESCALE:
189 m_bankingTimescale = ClampInRange(0.25f, pValue, 120);
191 case Vehicle.BUOYANCY:
192 m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f);
193 m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy);
195 case Vehicle.HOVER_EFFICIENCY:
196 m_VhoverEfficiency = ClampInRange(0.01f, pValue, 1f);
198 case Vehicle.HOVER_HEIGHT:
199 m_VhoverHeight = ClampInRange(0f, pValue, 1000000f);
201 case Vehicle.HOVER_TIMESCALE:
202 m_VhoverTimescale = ClampInRange(0.01f, pValue, 120);
204 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
205 m_linearDeflectionEfficiency = ClampInRange(0f, pValue, 1f);
207 case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
208 m_linearDeflectionTimescale = ClampInRange(0.01f, pValue, 120);
210 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
211 m_linearMotorDecayTimescale = ClampInRange(0.01f, pValue, 120);
212 m_linearMotor.TargetValueDecayTimeScale = m_linearMotorDecayTimescale;
214 case Vehicle.LINEAR_MOTOR_TIMESCALE:
215 m_linearMotorTimescale = ClampInRange(0.01f, pValue, 120);
216 m_linearMotor.TimeScale = m_linearMotorTimescale;
218 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
219 m_verticalAttractionEfficiency = ClampInRange(0.1f, pValue, 1f);
220 m_verticalAttractionMotor.Efficiency = m_verticalAttractionEfficiency;
222 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
223 m_verticalAttractionTimescale = ClampInRange(0.01f, pValue, 120);
224 m_verticalAttractionMotor.TimeScale = m_verticalAttractionTimescale;
229 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
230 clampTemp = ClampInRange(0.01f, pValue, 120);
231 m_angularFrictionTimescale =
new Vector3(clampTemp, clampTemp, clampTemp);
233 case Vehicle.ANGULAR_MOTOR_DIRECTION:
234 clampTemp = ClampInRange(-TwoPI, pValue, TwoPI);
235 m_angularMotorDirection =
new Vector3(clampTemp, clampTemp, clampTemp);
236 m_angularMotor.Zero();
237 m_angularMotor.SetTarget(m_angularMotorDirection);
239 case Vehicle.LINEAR_FRICTION_TIMESCALE:
240 clampTemp = ClampInRange(0.01f, pValue, 120);
241 m_linearFrictionTimescale =
new Vector3(clampTemp, clampTemp, clampTemp);
243 case Vehicle.LINEAR_MOTOR_DIRECTION:
244 clampTemp = ClampInRange(-BSParam.MaxLinearVelocity, pValue, BSParam.MaxLinearVelocity);
245 m_linearMotorDirection =
new Vector3(clampTemp, clampTemp, clampTemp);
246 m_linearMotorDirectionLASTSET =
new Vector3(clampTemp, clampTemp, clampTemp);
247 m_linearMotor.SetTarget(m_linearMotorDirection);
249 case Vehicle.LINEAR_MOTOR_OFFSET:
250 clampTemp = ClampInRange(-1000, pValue, 1000);
251 m_linearMotorOffset =
new Vector3(clampTemp, clampTemp, clampTemp);
257 internal void ProcessVectorVehicleParam(
Vehicle pParam, Vector3 pValue)
259 VDetailLog(
"{0},ProcessVectorVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
262 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
263 pValue.X = ClampInRange(0.25f, pValue.X, 120);
264 pValue.Y = ClampInRange(0.25f, pValue.Y, 120);
265 pValue.Z = ClampInRange(0.25f, pValue.Z, 120);
266 m_angularFrictionTimescale =
new Vector3(pValue.X, pValue.Y, pValue.Z);
268 case Vehicle.ANGULAR_MOTOR_DIRECTION:
270 pValue.X = ClampInRange(-FourPI, pValue.X, FourPI);
271 pValue.Y = ClampInRange(-FourPI, pValue.Y, FourPI);
272 pValue.Z = ClampInRange(-FourPI, pValue.Z, FourPI);
273 m_angularMotorDirection =
new Vector3(pValue.X, pValue.Y, pValue.Z);
274 m_angularMotor.Zero();
275 m_angularMotor.SetTarget(m_angularMotorDirection);
277 case Vehicle.LINEAR_FRICTION_TIMESCALE:
278 pValue.X = ClampInRange(0.25f, pValue.X, 120);
279 pValue.Y = ClampInRange(0.25f, pValue.Y, 120);
280 pValue.Z = ClampInRange(0.25f, pValue.Z, 120);
281 m_linearFrictionTimescale =
new Vector3(pValue.X, pValue.Y, pValue.Z);
283 case Vehicle.LINEAR_MOTOR_DIRECTION:
284 pValue.X = ClampInRange(-BSParam.MaxLinearVelocity, pValue.X, BSParam.MaxLinearVelocity);
285 pValue.Y = ClampInRange(-BSParam.MaxLinearVelocity, pValue.Y, BSParam.MaxLinearVelocity);
286 pValue.Z = ClampInRange(-BSParam.MaxLinearVelocity, pValue.Z, BSParam.MaxLinearVelocity);
287 m_linearMotorDirection =
new Vector3(pValue.X, pValue.Y, pValue.Z);
288 m_linearMotorDirectionLASTSET =
new Vector3(pValue.X, pValue.Y, pValue.Z);
289 m_linearMotor.SetTarget(m_linearMotorDirection);
291 case Vehicle.LINEAR_MOTOR_OFFSET:
293 pValue.X = ClampInRange(-1000, pValue.X, 1000);
294 pValue.Y = ClampInRange(-1000, pValue.Y, 1000);
295 pValue.Z = ClampInRange(-1000, pValue.Z, 1000);
296 m_linearMotorOffset =
new Vector3(pValue.X, pValue.Y, pValue.Z);
298 case Vehicle.BLOCK_EXIT:
300 pValue.X = ClampInRange(-10000, pValue.X, 10000);
301 pValue.Y = ClampInRange(-10000, pValue.Y, 10000);
302 pValue.Z = ClampInRange(-10000, pValue.Z, 10000);
303 m_BlockingEndPoint =
new Vector3(pValue.X, pValue.Y, pValue.Z);
308 internal void ProcessRotationVehicleParam(
Vehicle pParam, Quaternion pValue)
310 VDetailLog(
"{0},ProcessRotationalVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
313 case Vehicle.REFERENCE_FRAME:
314 m_referenceFrame = pValue;
316 case Vehicle.ROLL_FRAME:
317 m_RollreferenceFrame = pValue;
322 internal void ProcessVehicleFlags(
int pParam,
bool remove)
324 VDetailLog(
"{0},ProcessVehicleFlags,param={1},remove={2}", ControllingPrim.LocalID, pParam,
remove);
339 VDetailLog(
"{0},ProcessTypeChange,type={1}", ControllingPrim.LocalID, pType);
344 case Vehicle.TYPE_NONE:
345 m_linearMotorDirection = Vector3.Zero;
346 m_linearMotorTimescale = 0;
347 m_linearMotorDecayTimescale = 0;
348 m_linearFrictionTimescale =
new Vector3(0, 0, 0);
350 m_angularMotorDirection = Vector3.Zero;
351 m_angularMotorDecayTimescale = 0;
352 m_angularMotorTimescale = 0;
353 m_angularFrictionTimescale =
new Vector3(0, 0, 0);
356 m_VhoverEfficiency = 0;
357 m_VhoverTimescale = 0;
358 m_VehicleBuoyancy = 0;
360 m_linearDeflectionEfficiency = 1;
361 m_linearDeflectionTimescale = 1;
363 m_angularDeflectionEfficiency = 0;
364 m_angularDeflectionTimescale = 1000;
366 m_verticalAttractionEfficiency = 0;
367 m_verticalAttractionTimescale = 0;
369 m_bankingEfficiency = 0;
370 m_bankingTimescale = 1000;
373 m_referenceFrame = Quaternion.Identity;
378 case Vehicle.TYPE_SLED:
379 m_linearMotorDirection = Vector3.Zero;
380 m_linearMotorTimescale = 1000;
381 m_linearMotorDecayTimescale = 120;
382 m_linearFrictionTimescale =
new Vector3(30, 1, 1000);
384 m_angularMotorDirection = Vector3.Zero;
385 m_angularMotorTimescale = 1000;
386 m_angularMotorDecayTimescale = 120;
387 m_angularFrictionTimescale =
new Vector3(1000, 1000, 1000);
390 m_VhoverEfficiency = 10;
391 m_VhoverTimescale = 10;
392 m_VehicleBuoyancy = 0;
394 m_linearDeflectionEfficiency = 1;
395 m_linearDeflectionTimescale = 1;
397 m_angularDeflectionEfficiency = 1;
398 m_angularDeflectionTimescale = 1000;
400 m_verticalAttractionEfficiency = 0;
401 m_verticalAttractionTimescale = 0;
403 m_bankingEfficiency = 0;
404 m_bankingTimescale = 10;
407 m_referenceFrame = Quaternion.Identity;
408 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
409 | VehicleFlag.HOVER_TERRAIN_ONLY
410 | VehicleFlag.HOVER_GLOBAL_HEIGHT
411 | VehicleFlag.HOVER_UP_ONLY);
412 m_flags |= (VehicleFlag.NO_DEFLECTION_UP
413 | VehicleFlag.LIMIT_ROLL_ONLY
414 | VehicleFlag.LIMIT_MOTOR_UP);
417 case Vehicle.TYPE_CAR:
418 m_linearMotorDirection = Vector3.Zero;
419 m_linearMotorTimescale = 1;
420 m_linearMotorDecayTimescale = 60;
421 m_linearFrictionTimescale =
new Vector3(100, 2, 1000);
423 m_angularMotorDirection = Vector3.Zero;
424 m_angularMotorTimescale = 1;
425 m_angularMotorDecayTimescale = 0.8f;
426 m_angularFrictionTimescale =
new Vector3(1000, 1000, 1000);
429 m_VhoverEfficiency = 0;
430 m_VhoverTimescale = 1000;
431 m_VehicleBuoyancy = 0;
433 m_linearDeflectionEfficiency = 1;
434 m_linearDeflectionTimescale = 2;
436 m_angularDeflectionEfficiency = 0;
437 m_angularDeflectionTimescale = 10;
439 m_verticalAttractionEfficiency = 1f;
440 m_verticalAttractionTimescale = 10f;
442 m_bankingEfficiency = -0.2f;
444 m_bankingTimescale = 1;
446 m_referenceFrame = Quaternion.Identity;
447 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
448 | VehicleFlag.HOVER_TERRAIN_ONLY
449 | VehicleFlag.HOVER_GLOBAL_HEIGHT);
450 m_flags |= (VehicleFlag.NO_DEFLECTION_UP
451 | VehicleFlag.LIMIT_ROLL_ONLY
452 | VehicleFlag.LIMIT_MOTOR_UP
453 | VehicleFlag.HOVER_UP_ONLY);
455 case Vehicle.TYPE_BOAT:
456 m_linearMotorDirection = Vector3.Zero;
457 m_linearMotorTimescale = 5;
458 m_linearMotorDecayTimescale = 60;
459 m_linearFrictionTimescale =
new Vector3(10, 3, 2);
461 m_angularMotorDirection = Vector3.Zero;
462 m_angularMotorTimescale = 4;
463 m_angularMotorDecayTimescale = 4;
464 m_angularFrictionTimescale =
new Vector3(10,10,10);
467 m_VhoverEfficiency = 0.5f;
468 m_VhoverTimescale = 2;
469 m_VehicleBuoyancy = 1;
471 m_linearDeflectionEfficiency = 0.5f;
472 m_linearDeflectionTimescale = 3;
474 m_angularDeflectionEfficiency = 0.5f;
475 m_angularDeflectionTimescale = 5;
477 m_verticalAttractionEfficiency = 0.5f;
478 m_verticalAttractionTimescale = 5f;
480 m_bankingEfficiency = -0.3f;
482 m_bankingTimescale = 1;
484 m_referenceFrame = Quaternion.Identity;
485 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY
486 | VehicleFlag.HOVER_GLOBAL_HEIGHT
487 | VehicleFlag.LIMIT_ROLL_ONLY
488 | VehicleFlag.HOVER_UP_ONLY);
489 m_flags |= (VehicleFlag.NO_DEFLECTION_UP
490 | VehicleFlag.LIMIT_MOTOR_UP
491 | VehicleFlag.HOVER_WATER_ONLY);
493 case Vehicle.TYPE_AIRPLANE:
494 m_linearMotorDirection = Vector3.Zero;
495 m_linearMotorTimescale = 2;
496 m_linearMotorDecayTimescale = 60;
497 m_linearFrictionTimescale =
new Vector3(200, 10, 5);
499 m_angularMotorDirection = Vector3.Zero;
500 m_angularMotorTimescale = 4;
501 m_angularMotorDecayTimescale = 4;
502 m_angularFrictionTimescale =
new Vector3(20, 20, 20);
505 m_VhoverEfficiency = 0.5f;
506 m_VhoverTimescale = 1000;
507 m_VehicleBuoyancy = 0;
509 m_linearDeflectionEfficiency = 0.5f;
510 m_linearDeflectionTimescale = 3;
512 m_angularDeflectionEfficiency = 1;
513 m_angularDeflectionTimescale = 2;
515 m_verticalAttractionEfficiency = 0.9f;
516 m_verticalAttractionTimescale = 2f;
518 m_bankingEfficiency = 1;
520 m_bankingTimescale = 2;
522 m_referenceFrame = Quaternion.Identity;
523 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
524 | VehicleFlag.HOVER_TERRAIN_ONLY
525 | VehicleFlag.HOVER_GLOBAL_HEIGHT
526 | VehicleFlag.HOVER_UP_ONLY
527 | VehicleFlag.NO_DEFLECTION_UP
528 | VehicleFlag.LIMIT_MOTOR_UP);
529 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
531 case Vehicle.TYPE_BALLOON:
532 m_linearMotorDirection = Vector3.Zero;
533 m_linearMotorTimescale = 5;
534 m_linearFrictionTimescale =
new Vector3(5, 5, 5);
535 m_linearMotorDecayTimescale = 60;
537 m_angularMotorDirection = Vector3.Zero;
538 m_angularMotorTimescale = 6;
539 m_angularFrictionTimescale =
new Vector3(10, 10, 10);
540 m_angularMotorDecayTimescale = 10;
543 m_VhoverEfficiency = 0.8f;
544 m_VhoverTimescale = 10;
545 m_VehicleBuoyancy = 1;
547 m_linearDeflectionEfficiency = 0;
548 m_linearDeflectionTimescale = 5;
550 m_angularDeflectionEfficiency = 0;
551 m_angularDeflectionTimescale = 5;
553 m_verticalAttractionEfficiency = 1f;
554 m_verticalAttractionTimescale = 100f;
556 m_bankingEfficiency = 0;
558 m_bankingTimescale = 5;
560 m_referenceFrame = Quaternion.Identity;
562 m_referenceFrame = Quaternion.Identity;
563 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
564 | VehicleFlag.HOVER_TERRAIN_ONLY
565 | VehicleFlag.HOVER_UP_ONLY
566 | VehicleFlag.NO_DEFLECTION_UP
567 | VehicleFlag.LIMIT_MOTOR_UP);
568 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY
569 | VehicleFlag.HOVER_GLOBAL_HEIGHT);
573 m_linearMotor =
new BSVMotor(
"LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, 1f);
576 m_angularMotor =
new BSVMotor(
"AngularMotor", m_angularMotorTimescale, m_angularMotorDecayTimescale, 1f);
589 UnregisterForSceneEvents();
593 RegisterForSceneEvents();
599 #endregion // Vehicle parameter setting
606 m_physicsScene.PostTaintObject(
"BSDynamics.Refresh", ControllingPrim.LocalID, delegate()
608 SetPhysicalParameters();
614 private void SetPhysicalParameters()
619 m_vehicleMass = ControllingPrim.TotalMass;
624 ControllingPrim.Linkset.SetPhysicalFriction(BSParam.VehicleFriction);
625 ControllingPrim.Linkset.SetPhysicalRestitution(BSParam.VehicleRestitution);
630 m_physicsScene.PE.SetAngularDamping(ControllingPrim.PhysBody, BSParam.VehicleAngularDamping);
631 m_physicsScene.PE.SetLinearFactor(ControllingPrim.PhysBody, BSParam.VehicleLinearFactor);
632 m_physicsScene.PE.SetAngularFactorV(ControllingPrim.PhysBody, BSParam.VehicleAngularFactor);
636 ControllingPrim.Linkset.AddToPhysicalCollisionFlags(CollisionFlags.BS_VEHICLE_COLLISIONS);
642 ControllingPrim.Linkset.ComputeAndSetLocalInertia(BSParam.VehicleInertiaFactor, m_vehicleMass);
646 m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy);
649 ControllingPrim.Linkset.SetPhysicalGravity(Vector3.Zero);
651 VDetailLog(
"{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}",
652 ControllingPrim.LocalID, m_vehicleMass, ControllingPrim.Inertia, m_VehicleGravity,
653 BSParam.VehicleAngularDamping, BSParam.VehicleFriction, BSParam.VehicleRestitution,
654 BSParam.VehicleLinearFactor, BSParam.VehicleAngularFactor
659 if (ControllingPrim.PhysBody.HasPhysicalBody)
660 m_physicsScene.PE.RemoveFromCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
674 VDetailLog(
"{0},Dispose", ControllingPrim.LocalID);
675 UnregisterForSceneEvents();
676 Type = Vehicle.TYPE_NONE;
681 private void RegisterForSceneEvents()
683 if (!m_haveRegisteredForSceneEvents)
685 m_physicsScene.BeforeStep += this.Step;
686 m_physicsScene.AfterStep += this.PostStep;
687 ControllingPrim.OnPreUpdateProperty += this.PreUpdateProperty;
688 m_haveRegisteredForSceneEvents =
true;
692 private void UnregisterForSceneEvents()
694 if (m_haveRegisteredForSceneEvents)
696 m_physicsScene.BeforeStep -= this.Step;
697 m_physicsScene.AfterStep -= this.PostStep;
698 ControllingPrim.OnPreUpdateProperty -= this.PreUpdateProperty;
699 m_haveRegisteredForSceneEvents =
false;
703 private void PreUpdateProperty(ref EntityProperties entprop)
709 entprop.RotationalVelocity = Vector3.Zero;
713 #region Known vehicle value functions
720 private int m_knownChanged;
721 private int m_knownHas;
722 private float m_knownTerrainHeight;
723 private float m_knownWaterLevel;
724 private Vector3 m_knownPosition;
725 private Vector3 m_knownVelocity;
726 private Vector3 m_knownForce;
727 private Vector3 m_knownForceImpulse;
728 private Quaternion m_knownOrientation;
729 private Vector3 m_knownRotationalVelocity;
730 private Vector3 m_knownRotationalForce;
731 private Vector3 m_knownRotationalImpulse;
733 private const int m_knownChangedPosition = 1 << 0;
734 private const int m_knownChangedVelocity = 1 << 1;
735 private const int m_knownChangedForce = 1 << 2;
736 private const int m_knownChangedForceImpulse = 1 << 3;
737 private const int m_knownChangedOrientation = 1 << 4;
738 private const int m_knownChangedRotationalVelocity = 1 << 5;
739 private const int m_knownChangedRotationalForce = 1 << 6;
740 private const int m_knownChangedRotationalImpulse = 1 << 7;
741 private const int m_knownChangedTerrainHeight = 1 << 8;
742 private const int m_knownChangedWaterLevel = 1 << 9;
752 if (m_knownChanged != 0)
754 if ((m_knownChanged & m_knownChangedPosition) != 0)
755 ControllingPrim.ForcePosition = m_knownPosition;
757 if ((m_knownChanged & m_knownChangedOrientation) != 0)
758 ControllingPrim.ForceOrientation = m_knownOrientation;
760 if ((m_knownChanged & m_knownChangedVelocity) != 0)
762 ControllingPrim.ForceVelocity = m_knownVelocity;
770 if ((m_knownChanged & m_knownChangedForce) != 0)
771 ControllingPrim.AddForce(
false , (Vector3)m_knownForce);
773 if ((m_knownChanged & m_knownChangedForceImpulse) != 0)
774 ControllingPrim.AddForceImpulse((Vector3)m_knownForceImpulse,
false ,
true );
776 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
778 ControllingPrim.ForceRotationalVelocity = m_knownRotationalVelocity;
782 if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0)
783 ControllingPrim.ApplyTorqueImpulse((Vector3)m_knownRotationalImpulse,
true );
785 if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
787 ControllingPrim.AddAngularForce(
true , (Vector3)m_knownRotationalForce);
792 m_physicsScene.PE.PushUpdate(ControllingPrim.PhysBody);
799 Vector3 lastRememberedHeightPos =
new Vector3(-1, -1, -1);
800 private float GetTerrainHeight(Vector3 pos)
802 if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos)
804 lastRememberedHeightPos = pos;
805 m_knownTerrainHeight = ControllingPrim.PhysScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
806 m_knownHas |= m_knownChangedTerrainHeight;
808 return m_knownTerrainHeight;
813 Vector3 lastRememberedWaterHeightPos =
new Vector3(-1, -1, -1);
814 private float GetWaterLevel(Vector3 pos)
816 if ((m_knownHas & m_knownChangedWaterLevel) == 0 || pos != lastRememberedWaterHeightPos)
818 lastRememberedWaterHeightPos = pos;
819 m_knownWaterLevel = ControllingPrim.PhysScene.TerrainManager.GetWaterLevelAtXYZ(pos);
820 m_knownHas |= m_knownChangedWaterLevel;
822 return m_knownWaterLevel;
825 private Vector3 VehiclePosition
829 if ((m_knownHas & m_knownChangedPosition) == 0)
831 m_knownPosition = ControllingPrim.ForcePosition;
832 m_knownHas |= m_knownChangedPosition;
834 return m_knownPosition;
838 m_knownPosition = value;
839 m_knownChanged |= m_knownChangedPosition;
840 m_knownHas |= m_knownChangedPosition;
844 private Quaternion VehicleOrientation
848 if ((m_knownHas & m_knownChangedOrientation) == 0)
850 m_knownOrientation = ControllingPrim.ForceOrientation;
851 m_knownHas |= m_knownChangedOrientation;
853 return m_knownOrientation;
857 m_knownOrientation = value;
858 m_knownChanged |= m_knownChangedOrientation;
859 m_knownHas |= m_knownChangedOrientation;
863 private Vector3 VehicleVelocity
867 if ((m_knownHas & m_knownChangedVelocity) == 0)
869 m_knownVelocity = ControllingPrim.ForceVelocity;
870 m_knownHas |= m_knownChangedVelocity;
872 return m_knownVelocity;
876 m_knownVelocity = value;
877 m_knownChanged |= m_knownChangedVelocity;
878 m_knownHas |= m_knownChangedVelocity;
882 private void VehicleAddForce(Vector3 pForce)
884 if ((m_knownHas & m_knownChangedForce) == 0)
886 m_knownForce = Vector3.Zero;
887 m_knownHas |= m_knownChangedForce;
889 m_knownForce += pForce;
890 m_knownChanged |= m_knownChangedForce;
893 private void VehicleAddForceImpulse(Vector3 pImpulse)
895 if ((m_knownHas & m_knownChangedForceImpulse) == 0)
897 m_knownForceImpulse = Vector3.Zero;
898 m_knownHas |= m_knownChangedForceImpulse;
900 m_knownForceImpulse += pImpulse;
901 m_knownChanged |= m_knownChangedForceImpulse;
904 private Vector3 VehicleRotationalVelocity
908 if ((m_knownHas & m_knownChangedRotationalVelocity) == 0)
910 m_knownRotationalVelocity = ControllingPrim.ForceRotationalVelocity;
911 m_knownHas |= m_knownChangedRotationalVelocity;
913 return (Vector3)m_knownRotationalVelocity;
917 m_knownRotationalVelocity = value;
918 m_knownChanged |= m_knownChangedRotationalVelocity;
919 m_knownHas |= m_knownChangedRotationalVelocity;
922 private void VehicleAddAngularForce(Vector3 aForce)
924 if ((m_knownHas & m_knownChangedRotationalForce) == 0)
926 m_knownRotationalForce = Vector3.Zero;
928 m_knownRotationalForce += aForce;
929 m_knownChanged |= m_knownChangedRotationalForce;
930 m_knownHas |= m_knownChangedRotationalForce;
932 private void VehicleAddRotationalImpulse(Vector3 pImpulse)
934 if ((m_knownHas & m_knownChangedRotationalImpulse) == 0)
936 m_knownRotationalImpulse = Vector3.Zero;
937 m_knownHas |= m_knownChangedRotationalImpulse;
939 m_knownRotationalImpulse += pImpulse;
940 m_knownChanged |= m_knownChangedRotationalImpulse;
944 private Vector3 VehicleForwardVelocity
948 return VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleFrameOrientation));
952 private float VehicleForwardSpeed
956 return VehicleForwardVelocity.X;
959 private Quaternion VehicleFrameOrientation
963 return VehicleOrientation * m_referenceFrame;
967 #endregion // Known vehicle value functions
970 internal void Step(
float pTimestep)
972 if (!IsActive)
return;
974 ForgetKnownVehicleProperties();
976 MoveLinear(pTimestep);
977 MoveAngular(pTimestep);
979 LimitRotation(pTimestep);
982 m_lastPositionVector = VehiclePosition;
988 if (m_physicsScene.VehiclePhysicalLoggingEnabled)
989 m_physicsScene.PE.DumpRigidBody(m_physicsScene.World, ControllingPrim.PhysBody);
991 VDetailLog(
"{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}",
992 ControllingPrim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
996 internal void PostStep(
float pTimestep)
998 if (!IsActive)
return;
1000 if (m_physicsScene.VehiclePhysicalLoggingEnabled)
1001 m_physicsScene.PE.DumpRigidBody(m_physicsScene.World, ControllingPrim.PhysBody);
1005 private void MoveLinear(
float pTimestep)
1007 ComputeLinearVelocity(pTimestep);
1009 ComputeLinearDeflection(pTimestep);
1011 ComputeLinearTerrainHeightCorrection(pTimestep);
1013 ComputeLinearHover(pTimestep);
1015 ComputeLinearBlockingEndPoint(pTimestep);
1017 ComputeLinearMotorUp(pTimestep);
1019 ApplyGravity(pTimestep);
1024 Vector3 vel = VehicleVelocity;
1037 VehicleVelocity = vel;
1042 float newVelocityLengthSq = VehicleVelocity.LengthSquared();
1043 if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocitySquared)
1045 Vector3 origVelW = VehicleVelocity;
1046 VehicleVelocity /= VehicleVelocity.Length();
1047 VehicleVelocity *= BSParam.VehicleMaxLinearVelocity;
1048 VDetailLog(
"{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}",
1049 ControllingPrim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity);
1051 else if (newVelocityLengthSq < BSParam.VehicleMinLinearVelocitySquared)
1053 Vector3 origVelW = VehicleVelocity;
1054 VDetailLog(
"{0}, MoveLinear,clampMin,origVelW={1},lenSq={2}",
1055 ControllingPrim.LocalID, origVelW, newVelocityLengthSq);
1056 VehicleVelocity = Vector3.Zero;
1059 VDetailLog(
"{0}, MoveLinear,done,isColl={1},newVel={2}", ControllingPrim.LocalID, ControllingPrim.HasSomeCollision, VehicleVelocity );
1066 Vector3 origVelW = VehicleVelocity;
1067 Vector3 currentVelV = VehicleForwardVelocity;
1068 Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV);
1071 Vector3 frictionFactorV = ComputeFrictionFactor(m_linearFrictionTimescale, pTimestep);
1072 linearMotorCorrectionV -= (currentVelV * frictionFactorV);
1075 Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleFrameOrientation;
1080 if (linearMotorVelocityW.Z > 0f)
1081 linearMotorVelocityW.Z = 0f;
1085 VehicleVelocity += linearMotorVelocityW;
1087 VDetailLog(
"{0}, MoveLinear,velocity,origVelW={1},velV={2},tgt={3},correctV={4},correctW={5},newVelW={6},fricFact={7}",
1088 ControllingPrim.LocalID, origVelW, currentVelV, m_linearMotor.TargetValue, linearMotorCorrectionV,
1089 linearMotorVelocityW, VehicleVelocity, frictionFactorV);
1094 private void ComputeLinearDeflection(
float pTimestep)
1096 Vector3 linearDeflectionV = Vector3.Zero;
1097 Vector3 velocityV = VehicleForwardVelocity;
1099 if (BSParam.VehicleEnableLinearDeflection)
1103 linearDeflectionV.Y = SortedClampInRange(0, (velocityV.Y * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Y);
1104 linearDeflectionV.Z = SortedClampInRange(0, (velocityV.Z * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Z);
1107 linearDeflectionV.X += Math.Abs(linearDeflectionV.Y);
1108 linearDeflectionV.X += Math.Abs(linearDeflectionV.Z);
1111 linearDeflectionV *= pTimestep;
1114 linearDeflectionV *=
new Vector3(1, -1, -1);
1117 Vector3 linearDeflectionW = linearDeflectionV * VehicleFrameOrientation;
1120 if (BSParam.VehicleLinearDeflectionNotCollidingNoZ && !m_controllingPrim.HasSomeCollision)
1122 linearDeflectionW.Z = 0f;
1125 VehicleVelocity += linearDeflectionW;
1127 VDetailLog(
"{0}, MoveLinear,LinearDeflection,linDefEff={1},linDefTS={2},linDeflectionV={3}",
1128 ControllingPrim.LocalID, m_linearDeflectionEfficiency, m_linearDeflectionTimescale, linearDeflectionV);
1136 if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition))
1139 Vector3 newPosition = VehiclePosition;
1140 newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f;
1141 VehiclePosition = newPosition;
1142 VDetailLog(
"{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}",
1143 ControllingPrim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition);
1151 if ((m_flags & (
VehicleFlag.HOVER_WATER_ONLY |
VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0 && (m_VhoverHeight > 0) && (m_VhoverTimescale < 300))
1154 if ((m_flags &
VehicleFlag.HOVER_WATER_ONLY) != 0)
1156 m_VhoverTargetHeight = GetWaterLevel(VehiclePosition) + m_VhoverHeight;
1158 if ((m_flags &
VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
1160 m_VhoverTargetHeight = GetTerrainHeight(VehiclePosition) + m_VhoverHeight;
1162 if ((m_flags &
VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
1164 m_VhoverTargetHeight = m_VhoverHeight;
1169 if (VehiclePosition.Z > m_VhoverTargetHeight)
1171 m_VhoverTargetHeight = VehiclePosition.Z;
1177 if (m_VehicleBuoyancy != 0)
1179 Vector3 appliedGravity = ControllingPrim.ComputeGravity(ControllingPrim.Buoyancy) * m_vehicleMass;
1180 VehicleAddForce(appliedGravity);
1185 if ((m_flags &
VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
1187 if (Math.Abs(VehiclePosition.Z - m_VhoverTargetHeight) > 0.2f)
1189 Vector3 pos = VehiclePosition;
1190 pos.Z = m_VhoverTargetHeight;
1191 VehiclePosition = pos;
1193 VDetailLog(
"{0}, MoveLinear,hover,pos={1},lockHoverHeight", ControllingPrim.LocalID, pos);
1199 Vector3 hpos = VehiclePosition;
1200 float verticalError = m_VhoverTargetHeight - hpos.Z;
1201 float verticalCorrection = verticalError / m_VhoverTimescale;
1202 verticalCorrection *= m_VhoverEfficiency;
1204 hpos.Z += verticalCorrection;
1205 VehiclePosition = hpos;
1208 Vector3 vel = VehicleVelocity;
1210 VehicleVelocity = vel;
1221 VDetailLog(
"{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corr={7}",
1222 ControllingPrim.LocalID, VehiclePosition, m_VhoverEfficiency,
1223 m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight,
1224 verticalError, verticalCorrection);
1231 bool changed =
false;
1233 Vector3 pos = VehiclePosition;
1234 Vector3 posChange = pos - m_lastPositionVector;
1235 if (m_BlockingEndPoint != Vector3.Zero)
1237 if (pos.X >= (m_BlockingEndPoint.X - (
float)1))
1239 pos.X -= posChange.X + 1;
1242 if (pos.Y >= (m_BlockingEndPoint.Y - (
float)1))
1244 pos.Y -= posChange.Y + 1;
1247 if (pos.Z >= (m_BlockingEndPoint.Z - (
float)1))
1249 pos.Z -= posChange.Z + 1;
1254 pos.X += posChange.X + 1;
1259 pos.Y += posChange.Y + 1;
1264 VehiclePosition = pos;
1265 VDetailLog(
"{0}, MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
1266 ControllingPrim.LocalID, m_BlockingEndPoint, posChange, pos);
1283 if ((m_flags & (
VehicleFlag.LIMIT_MOTOR_UP)) != 0)
1306 if (!ControllingPrim.HasSomeCollision && VehicleVelocity.Z > 0.1)
1309 float upVelocity = VehicleVelocity.Z;
1310 VehicleVelocity +=
new Vector3(0, 0, -upVelocity);
1327 VDetailLog(
"{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}",
1328 ControllingPrim.LocalID, ControllingPrim.HasSomeCollision, upVelocity, VehicleVelocity);
1333 private void ApplyGravity(
float pTimeStep)
1335 Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass;
1338 if (ControllingPrim.HasSomeCollision && IsGroundVehicle)
1339 appliedGravity *= BSParam.VehicleGroundGravityFudge;
1341 VehicleAddForce(appliedGravity);
1343 VDetailLog(
"{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={5}",
1344 ControllingPrim.LocalID, m_VehicleGravity,
1345 ControllingPrim.HasSomeCollision, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity);
1354 private void MoveAngular(
float pTimestep)
1356 ComputeAngularTurning(pTimestep);
1358 ComputeAngularVerticalAttraction();
1360 ComputeAngularDeflection();
1362 ComputeAngularBanking();
1365 if (VehicleRotationalVelocity.ApproxEquals(Vector3.Zero, 0.0001f))
1368 VehicleRotationalVelocity = Vector3.Zero;
1369 VDetailLog(
"{0}, MoveAngular,done,zero", ControllingPrim.LocalID);
1373 VDetailLog(
"{0}, MoveAngular,done,nonZero,angVel={1}", ControllingPrim.LocalID, VehicleRotationalVelocity);
1378 if (m_linearMotorOffset != Vector3.Zero)
1394 Vector3 torqueFromOffset = Vector3.Zero;
1396 if (
float.IsNaN(torqueFromOffset.X))
1397 torqueFromOffset.X = 0;
1398 if (
float.IsNaN(torqueFromOffset.Y))
1399 torqueFromOffset.Y = 0;
1400 if (
float.IsNaN(torqueFromOffset.Z))
1401 torqueFromOffset.Z = 0;
1403 VehicleAddAngularForce(torqueFromOffset * m_vehicleMass);
1404 VDetailLog(
"{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", ControllingPrim.LocalID, torqueFromOffset);
1409 private void ComputeAngularTurning(
float pTimestep)
1412 Vector3 origVehicleRotationalVelocity = VehicleRotationalVelocity;
1413 Vector3 currentAngularV = VehicleRotationalVelocity * Quaternion.Inverse(VehicleFrameOrientation);
1414 Vector3 angularMotorContributionV = m_angularMotor.Step(pTimestep, currentAngularV);
1431 Vector3 frictionFactorW = ComputeFrictionFactor(m_angularFrictionTimescale, pTimestep);
1432 angularMotorContributionV -= (currentAngularV * frictionFactorW);
1434 Vector3 angularMotorContributionW = angularMotorContributionV * VehicleFrameOrientation;
1435 VehicleRotationalVelocity += angularMotorContributionW;
1437 VDetailLog(
"{0}, MoveAngular,angularTurning,curAngVelV={1},origVehRotVel={2},vehRotVel={3},frictFact={4}, angContribV={5},angContribW={6}",
1438 ControllingPrim.LocalID, currentAngularV, origVehicleRotationalVelocity, VehicleRotationalVelocity, frictionFactorW, angularMotorContributionV, angularMotorContributionW);
1453 if (BSParam.VehicleEnableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1455 Vector3 vehicleUpAxis = Vector3.UnitZ * VehicleFrameOrientation;
1456 switch (BSParam.VehicleAngularVerticalAttractionAlgorithm)
1465 float verticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f;
1469 Vector3 predictedUp = vehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
1472 Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
1476 Vector3 vehicleForwardAxis = Vector3.UnitX * VehicleFrameOrientation;
1477 torqueVector = ProjectVector(torqueVector, vehicleForwardAxis);
1481 Vector3 vertContributionV = torqueVector * verticalAttractionSpeed * verticalAttractionSpeed;
1483 VehicleRotationalVelocity += vertContributionV;
1485 VDetailLog(
"{0}, MoveAngular,verticalAttraction,vertAttrSpeed={1},upAxis={2},PredictedUp={3},torqueVector={4},contrib={5}",
1486 ControllingPrim.LocalID,
1487 verticalAttractionSpeed,
1500 Vector3 currentEulerW = Vector3.Zero;
1501 VehicleFrameOrientation.GetEulerAngles(out currentEulerW.X, out currentEulerW.Y, out currentEulerW.Z);
1502 Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEulerW.Z);
1505 Vector3 differenceAxisW = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleFrameOrientation);
1507 double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleFrameOrientation)));
1515 Quaternion correctionRotationW = Quaternion.CreateFromAxisAngle(differenceAxisW, (float)differenceAngle);
1518 Vector3 vertContributionW = Vector3.Zero;
1519 correctionRotationW.GetEulerAngles(out vertContributionW.X, out vertContributionW.Y, out vertContributionW.Z);
1520 vertContributionW *= -1f;
1521 vertContributionW /= m_verticalAttractionTimescale;
1523 VehicleRotationalVelocity += vertContributionW;
1525 VDetailLog(
"{0}, MoveAngular,verticalAttraction,upAxis={1},diffAxis={2},diffAng={3},corrRot={4},contrib={5}",
1526 ControllingPrim.LocalID,
1530 correctionRotationW,
1536 Vector3 vertContributionV = Vector3.Zero;
1537 Vector3 origRotVelW = VehicleRotationalVelocity;
1540 Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleFrameOrientation);
1552 vertContributionV.X = (float)Math.Asin(verticalError.Y);
1554 vertContributionV.Y = -(float)Math.Asin(verticalError.X);
1557 if (verticalError.Z < 0f)
1559 vertContributionV.X += Math.Sign(vertContributionV.X) * PIOverFour;
1565 Vector3 unscaledContribVerticalErrorV = vertContributionV;
1568 vertContributionV /= m_verticalAttractionTimescale;
1571 VehicleRotationalVelocity += (vertContributionV * VehicleFrameOrientation);
1573 VDetailLog(
"{0}, MoveAngular,verticalAttraction,,upAxis={1},origRotVW={2},vertError={3},unscaledV={4},eff={5},ts={6},vertContribV={7}",
1574 ControllingPrim.LocalID,
1578 unscaledContribVerticalErrorV,
1579 m_verticalAttractionEfficiency,
1580 m_verticalAttractionTimescale,
1600 if (BSParam.VehicleEnableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
1602 Vector3 deflectContributionV = Vector3.Zero;
1605 Vector3 movingDirection = VehicleVelocity;
1606 movingDirection.Normalize();
1609 movingDirection *= Math.Sign(VehicleForwardSpeed);
1612 Vector3 pointingDirection = Vector3.UnitX * VehicleFrameOrientation;
1615 Vector3 predictedPointingDirection = pointingDirection * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
1616 predictedPointingDirection.Normalize();
1620 Vector3 deflectionError = Vector3.Cross(movingDirection, predictedPointingDirection);
1626 if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = 0f;
1627 if (Math.Abs(deflectionError.Y) > PIOverFour) deflectionError.Y = 0f;
1628 if (Math.Abs(deflectionError.Z) > PIOverFour) deflectionError.Z = 0f;
1634 deflectContributionV = (-deflectionError) * ClampInRange(0, m_angularDeflectionEfficiency/m_angularDeflectionTimescale,1f);
1637 VehicleRotationalVelocity += deflectContributionV;
1638 VDetailLog(
"{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}",
1639 ControllingPrim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV);
1640 VDetailLog(
"{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3},PredictedPointingDir={4}",
1641 ControllingPrim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale, predictedPointingDirection);
1678 if (BSParam.VehicleEnableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1680 Vector3 bankingContributionV = Vector3.Zero;
1685 Vector3 rollComponents = Vector3.UnitZ * VehicleFrameOrientation;
1688 float yawAngle = m_angularMotorDirection.X * m_bankingEfficiency;
1690 float mixedYawAngle =(yawAngle * (1f - m_bankingMix)) + ((yawAngle * m_bankingMix) * VehicleForwardSpeed);
1694 mixedYawAngle = ClampInRange(-FourPI, mixedYawAngle, FourPI);
1697 bankingContributionV.Z = -mixedYawAngle;
1700 bankingContributionV /= m_bankingTimescale * BSParam.VehicleAngularBankingTimescaleFudge;
1702 VehicleRotationalVelocity += bankingContributionV;
1705 VDetailLog(
"{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}",
1706 ControllingPrim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV);
1714 internal void LimitRotation(
float timestep)
1716 Quaternion rotq = VehicleOrientation;
1717 Quaternion m_rot = rotq;
1718 if (m_RollreferenceFrame != Quaternion.Identity)
1720 if (rotq.X >= m_RollreferenceFrame.X)
1722 m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2);
1724 if (rotq.Y >= m_RollreferenceFrame.Y)
1726 m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2);
1728 if (rotq.X <= -m_RollreferenceFrame.X)
1730 m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2);
1732 if (rotq.Y <= -m_RollreferenceFrame.Y)
1734 m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2);
1744 VehicleOrientation = m_rot;
1745 VDetailLog(
"{0}, LimitRotation,done,orig={1},new={2}", ControllingPrim.LocalID, rotq, m_rot);
1752 private Vector3 ComputeFrictionFactor(Vector3 friction,
float pTimestep)
1754 Vector3 frictionFactor = Vector3.Zero;
1755 if (friction != BSMotor.InfiniteVector)
1759 frictionFactor.X = (friction.X == BSMotor.Infinite) ? 0f : (1f / friction.X);
1760 frictionFactor.Y = (friction.Y == BSMotor.Infinite) ? 0f : (1f / friction.Y);
1761 frictionFactor.Z = (friction.Z == BSMotor.Infinite) ? 0f : (1f / friction.Z);
1762 frictionFactor *= pTimestep;
1764 return frictionFactor;
1767 private float SortedClampInRange(
float clampa,
float val,
float clampb)
1769 if (clampa > clampb)
1771 float temp = clampa;
1775 return ClampInRange(clampa, val, clampb);
1780 private Vector3 ProjectVector(Vector3
vector, Vector3 onNormal)
1782 float vectorDot = Vector3.Dot(
vector, onNormal);
1783 return onNormal * vectorDot;
1787 private float ClampInRange(
float low,
float val,
float high)
1789 return Math.Max(low, Math.Min(val, high));
1794 private void VDetailLog(
string msg, params Object[] args)
1796 if (ControllingPrim.PhysScene.VehicleLoggingEnabled)
1797 ControllingPrim.PhysScene.DetailLog(msg, args);
void ComputeAngularDeflection()
BSDynamics(BSScene myScene, BSPrim myPrim, string actorName)
void ForgetKnownVehicleProperties()
void ComputeLinearHover(float pTimestep)
Each physical object can have 'actors' who are pushing the object around. This can be used for hover...
void ProcessTypeChange(Vehicle pType)
override void RemoveDependencies()
void ComputeAngularVerticalAttraction()
void ComputeLinearVelocity(float pTimestep)
bool ComputeLinearBlockingEndPoint(float pTimestep)
void ComputeLinearTerrainHeightCorrection(float pTimestep)
void ComputeAngularBanking()
void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3 vector
void ComputeLinearMotorUp(float pTimestep)