aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs315
1 files changed, 211 insertions, 104 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 65df741..311cf4f 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -40,13 +40,14 @@ using OpenSim.Region.Physics.Manager;
40 40
41namespace OpenSim.Region.Physics.BulletSPlugin 41namespace OpenSim.Region.Physics.BulletSPlugin
42{ 42{
43 public sealed class BSDynamics 43 public sealed class BSDynamics : BSActor
44 { 44 {
45 private static string LogHeader = "[BULLETSIM VEHICLE]"; 45 private static string LogHeader = "[BULLETSIM VEHICLE]";
46 46
47 private BSScene PhysicsScene { get; set; }
48 // the prim this dynamic controller belongs to 47 // the prim this dynamic controller belongs to
49 private BSPrim Prim { get; set; } 48 private BSPrim ControllingPrim { get; set; }
49
50 private bool m_haveRegisteredForSceneEvents;
50 51
51 // mass of the vehicle fetched each time we're calles 52 // mass of the vehicle fetched each time we're calles
52 private float m_vehicleMass; 53 private float m_vehicleMass;
@@ -129,11 +130,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
129 public bool enableAngularDeflection; 130 public bool enableAngularDeflection;
130 public bool enableAngularBanking; 131 public bool enableAngularBanking;
131 132
132 public BSDynamics(BSScene myScene, BSPrim myPrim) 133 public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName)
134 : base(myScene, myPrim, actorName)
133 { 135 {
134 PhysicsScene = myScene; 136 ControllingPrim = myPrim;
135 Prim = myPrim;
136 Type = Vehicle.TYPE_NONE; 137 Type = Vehicle.TYPE_NONE;
138 m_haveRegisteredForSceneEvents = false;
137 SetupVehicleDebugging(); 139 SetupVehicleDebugging();
138 } 140 }
139 141
@@ -144,7 +146,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
144 enableAngularVerticalAttraction = true; 146 enableAngularVerticalAttraction = true;
145 enableAngularDeflection = false; 147 enableAngularDeflection = false;
146 enableAngularBanking = true; 148 enableAngularBanking = true;
147 if (BSParam.VehicleDebuggingEnabled) 149 if (BSParam.VehicleDebuggingEnable)
148 { 150 {
149 enableAngularVerticalAttraction = true; 151 enableAngularVerticalAttraction = true;
150 enableAngularDeflection = false; 152 enableAngularDeflection = false;
@@ -155,7 +157,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
155 // Return 'true' if this vehicle is doing vehicle things 157 // Return 'true' if this vehicle is doing vehicle things
156 public bool IsActive 158 public bool IsActive
157 { 159 {
158 get { return (Type != Vehicle.TYPE_NONE && Prim.IsPhysicallyActive); } 160 get { return (Type != Vehicle.TYPE_NONE && ControllingPrim.IsPhysicallyActive); }
159 } 161 }
160 162
161 // Return 'true' if this a vehicle that should be sitting on the ground 163 // Return 'true' if this a vehicle that should be sitting on the ground
@@ -167,7 +169,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
167 #region Vehicle parameter setting 169 #region Vehicle parameter setting
168 public void ProcessFloatVehicleParam(Vehicle pParam, float pValue) 170 public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
169 { 171 {
170 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); 172 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
171 switch (pParam) 173 switch (pParam)
172 { 174 {
173 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: 175 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
@@ -195,7 +197,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
195 break; 197 break;
196 case Vehicle.BUOYANCY: 198 case Vehicle.BUOYANCY:
197 m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); 199 m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f);
198 m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy); 200 m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy);
199 break; 201 break;
200 case Vehicle.HOVER_EFFICIENCY: 202 case Vehicle.HOVER_EFFICIENCY:
201 m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); 203 m_VhoverEfficiency = ClampInRange(0f, pValue, 1f);
@@ -233,7 +235,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
233 // set all of the components to the same value 235 // set all of the components to the same value
234 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 236 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
235 m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); 237 m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
236 m_angularMotor.FrictionTimescale = m_angularFrictionTimescale;
237 break; 238 break;
238 case Vehicle.ANGULAR_MOTOR_DIRECTION: 239 case Vehicle.ANGULAR_MOTOR_DIRECTION:
239 m_angularMotorDirection = new Vector3(pValue, pValue, pValue); 240 m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
@@ -242,7 +243,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
242 break; 243 break;
243 case Vehicle.LINEAR_FRICTION_TIMESCALE: 244 case Vehicle.LINEAR_FRICTION_TIMESCALE:
244 m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); 245 m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
245 m_linearMotor.FrictionTimescale = m_linearFrictionTimescale;
246 break; 246 break;
247 case Vehicle.LINEAR_MOTOR_DIRECTION: 247 case Vehicle.LINEAR_MOTOR_DIRECTION:
248 m_linearMotorDirection = new Vector3(pValue, pValue, pValue); 248 m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
@@ -258,12 +258,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
258 258
259 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) 259 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
260 { 260 {
261 VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); 261 VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
262 switch (pParam) 262 switch (pParam)
263 { 263 {
264 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 264 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
265 m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); 265 m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
266 m_angularMotor.FrictionTimescale = m_angularFrictionTimescale;
267 break; 266 break;
268 case Vehicle.ANGULAR_MOTOR_DIRECTION: 267 case Vehicle.ANGULAR_MOTOR_DIRECTION:
269 // Limit requested angular speed to 2 rps= 4 pi rads/sec 268 // Limit requested angular speed to 2 rps= 4 pi rads/sec
@@ -276,7 +275,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
276 break; 275 break;
277 case Vehicle.LINEAR_FRICTION_TIMESCALE: 276 case Vehicle.LINEAR_FRICTION_TIMESCALE:
278 m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); 277 m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
279 m_linearMotor.FrictionTimescale = m_linearFrictionTimescale;
280 break; 278 break;
281 case Vehicle.LINEAR_MOTOR_DIRECTION: 279 case Vehicle.LINEAR_MOTOR_DIRECTION:
282 m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); 280 m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
@@ -294,7 +292,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
294 292
295 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) 293 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
296 { 294 {
297 VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); 295 VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
298 switch (pParam) 296 switch (pParam)
299 { 297 {
300 case Vehicle.REFERENCE_FRAME: 298 case Vehicle.REFERENCE_FRAME:
@@ -308,7 +306,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
308 306
309 internal void ProcessVehicleFlags(int pParam, bool remove) 307 internal void ProcessVehicleFlags(int pParam, bool remove)
310 { 308 {
311 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", Prim.LocalID, pParam, remove); 309 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", ControllingPrim.LocalID, pParam, remove);
312 VehicleFlag parm = (VehicleFlag)pParam; 310 VehicleFlag parm = (VehicleFlag)pParam;
313 if (pParam == -1) 311 if (pParam == -1)
314 m_flags = (VehicleFlag)0; 312 m_flags = (VehicleFlag)0;
@@ -323,7 +321,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
323 321
324 public void ProcessTypeChange(Vehicle pType) 322 public void ProcessTypeChange(Vehicle pType)
325 { 323 {
326 VDetailLog("{0},ProcessTypeChange,type={1}", Prim.LocalID, pType); 324 VDetailLog("{0},ProcessTypeChange,type={1}", ControllingPrim.LocalID, pType);
327 // Set Defaults For Type 325 // Set Defaults For Type
328 Type = pType; 326 Type = pType;
329 switch (pType) 327 switch (pType)
@@ -557,34 +555,40 @@ namespace OpenSim.Region.Physics.BulletSPlugin
557 break; 555 break;
558 } 556 }
559 557
560 // Update any physical parameters based on this type. 558 m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, 1f);
561 Refresh(); 559 m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
562
563 m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale,
564 m_linearMotorDecayTimescale, m_linearFrictionTimescale,
565 1f);
566 m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
567 560
568 m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, 561 m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, m_angularMotorDecayTimescale, 1f);
569 m_angularMotorDecayTimescale, m_angularFrictionTimescale, 562 m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
570 1f);
571 m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
572 563
573 /* Not implemented 564 /* Not implemented
574 m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, 565 m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
575 BSMotor.Infinite, BSMotor.InfiniteVector, 566 BSMotor.Infinite, BSMotor.InfiniteVector,
576 m_verticalAttractionEfficiency); 567 m_verticalAttractionEfficiency);
577 // Z goes away and we keep X and Y 568 // Z goes away and we keep X and Y
578 m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
579 m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) 569 m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
580 */ 570 */
571
572 if (this.Type == Vehicle.TYPE_NONE)
573 {
574 UnregisterForSceneEvents();
575 }
576 else
577 {
578 RegisterForSceneEvents();
579 }
580
581 // Update any physical parameters based on this type.
582 Refresh();
581 } 583 }
582 #endregion // Vehicle parameter setting 584 #endregion // Vehicle parameter setting
583 585
584 public void Refresh() 586 // BSActor.Refresh()
587 public override void Refresh()
585 { 588 {
586 // If asking for a refresh, reset the physical parameters before the next simulation step. 589 // If asking for a refresh, reset the physical parameters before the next simulation step.
587 PhysicsScene.PostTaintObject("BSDynamics.Refresh", Prim.LocalID, delegate() 590 // Called whether active or not since the active state may be updated before the next step.
591 m_physicsScene.PostTaintObject("BSDynamics.Refresh", ControllingPrim.LocalID, delegate()
588 { 592 {
589 SetPhysicalParameters(); 593 SetPhysicalParameters();
590 }); 594 });
@@ -597,49 +601,91 @@ namespace OpenSim.Region.Physics.BulletSPlugin
597 if (IsActive) 601 if (IsActive)
598 { 602 {
599 // Remember the mass so we don't have to fetch it every step 603 // Remember the mass so we don't have to fetch it every step
600 m_vehicleMass = Prim.TotalMass; 604 m_vehicleMass = ControllingPrim.TotalMass;
601 605
602 // Friction affects are handled by this vehicle code 606 // Friction affects are handled by this vehicle code
603 PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction); 607 m_physicsScene.PE.SetFriction(ControllingPrim.PhysBody, BSParam.VehicleFriction);
604 PhysicsScene.PE.SetRestitution(Prim.PhysBody, BSParam.VehicleRestitution); 608 m_physicsScene.PE.SetRestitution(ControllingPrim.PhysBody, BSParam.VehicleRestitution);
605 609
606 // Moderate angular movement introduced by Bullet. 610 // Moderate angular movement introduced by Bullet.
607 // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. 611 // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
608 // Maybe compute linear and angular factor and damping from params. 612 // Maybe compute linear and angular factor and damping from params.
609 PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, BSParam.VehicleAngularDamping); 613 m_physicsScene.PE.SetAngularDamping(ControllingPrim.PhysBody, BSParam.VehicleAngularDamping);
610 PhysicsScene.PE.SetLinearFactor(Prim.PhysBody, BSParam.VehicleLinearFactor); 614 m_physicsScene.PE.SetLinearFactor(ControllingPrim.PhysBody, BSParam.VehicleLinearFactor);
611 PhysicsScene.PE.SetAngularFactorV(Prim.PhysBody, BSParam.VehicleAngularFactor); 615 m_physicsScene.PE.SetAngularFactorV(ControllingPrim.PhysBody, BSParam.VehicleAngularFactor);
612 616
613 // Vehicles report collision events so we know when it's on the ground 617 // Vehicles report collision events so we know when it's on the ground
614 PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); 618 m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
615 619
616 Prim.Inertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass); 620 Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass);
617 PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, Prim.Inertia); 621 ControllingPrim.Inertia = inertia * BSParam.VehicleInertiaFactor;
618 PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody); 622 m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia);
623 m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody);
619 624
620 // Set the gravity for the vehicle depending on the buoyancy 625 // Set the gravity for the vehicle depending on the buoyancy
621 // TODO: what should be done if prim and vehicle buoyancy differ? 626 // TODO: what should be done if prim and vehicle buoyancy differ?
622 m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy); 627 m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy);
623 // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. 628 // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
624 PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero); 629 m_physicsScene.PE.SetGravity(ControllingPrim.PhysBody, Vector3.Zero);
625 630
626 VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}", 631 VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}",
627 Prim.LocalID, m_vehicleMass, Prim.Inertia, m_VehicleGravity, 632 ControllingPrim.LocalID, m_vehicleMass, ControllingPrim.Inertia, m_VehicleGravity,
628 BSParam.VehicleAngularDamping, BSParam.VehicleFriction, BSParam.VehicleRestitution, 633 BSParam.VehicleAngularDamping, BSParam.VehicleFriction, BSParam.VehicleRestitution,
629 BSParam.VehicleLinearFactor, BSParam.VehicleAngularFactor 634 BSParam.VehicleLinearFactor, BSParam.VehicleAngularFactor
630 ); 635 );
631 } 636 }
632 else 637 else
633 { 638 {
634 if (Prim.PhysBody.HasPhysicalBody) 639 if (ControllingPrim.PhysBody.HasPhysicalBody)
635 PhysicsScene.PE.RemoveFromCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); 640 m_physicsScene.PE.RemoveFromCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
636 } 641 }
637 } 642 }
638 643
639 public bool RemoveBodyDependencies(BSPhysObject prim) 644 // BSActor.RemoveBodyDependencies
645 public override void RemoveDependencies()
640 { 646 {
641 Refresh(); 647 Refresh();
642 return IsActive; 648 }
649
650 // BSActor.Release()
651 public override void Dispose()
652 {
653 UnregisterForSceneEvents();
654 Type = Vehicle.TYPE_NONE;
655 Enabled = false;
656 return;
657 }
658
659 private void RegisterForSceneEvents()
660 {
661 if (!m_haveRegisteredForSceneEvents)
662 {
663 m_physicsScene.BeforeStep += this.Step;
664 m_physicsScene.AfterStep += this.PostStep;
665 ControllingPrim.OnPreUpdateProperty += this.PreUpdateProperty;
666 m_haveRegisteredForSceneEvents = true;
667 }
668 }
669
670 private void UnregisterForSceneEvents()
671 {
672 if (m_haveRegisteredForSceneEvents)
673 {
674 m_physicsScene.BeforeStep -= this.Step;
675 m_physicsScene.AfterStep -= this.PostStep;
676 ControllingPrim.OnPreUpdateProperty -= this.PreUpdateProperty;
677 m_haveRegisteredForSceneEvents = false;
678 }
679 }
680
681 private void PreUpdateProperty(ref EntityProperties entprop)
682 {
683 // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
684 // TODO: handle physics introduced by Bullet with computed vehicle physics.
685 if (IsActive)
686 {
687 entprop.RotationalVelocity = Vector3.Zero;
688 }
643 } 689 }
644 690
645 #region Known vehicle value functions 691 #region Known vehicle value functions
@@ -686,14 +732,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
686 if (m_knownChanged != 0) 732 if (m_knownChanged != 0)
687 { 733 {
688 if ((m_knownChanged & m_knownChangedPosition) != 0) 734 if ((m_knownChanged & m_knownChangedPosition) != 0)
689 Prim.ForcePosition = m_knownPosition; 735 ControllingPrim.ForcePosition = m_knownPosition;
690 736
691 if ((m_knownChanged & m_knownChangedOrientation) != 0) 737 if ((m_knownChanged & m_knownChangedOrientation) != 0)
692 Prim.ForceOrientation = m_knownOrientation; 738 ControllingPrim.ForceOrientation = m_knownOrientation;
693 739
694 if ((m_knownChanged & m_knownChangedVelocity) != 0) 740 if ((m_knownChanged & m_knownChangedVelocity) != 0)
695 { 741 {
696 Prim.ForceVelocity = m_knownVelocity; 742 ControllingPrim.ForceVelocity = m_knownVelocity;
697 // Fake out Bullet by making it think the velocity is the same as last time. 743 // Fake out Bullet by making it think the velocity is the same as last time.
698 // Bullet does a bunch of smoothing for changing parameters. 744 // Bullet does a bunch of smoothing for changing parameters.
699 // Since the vehicle is demanding this setting, we override Bullet's smoothing 745 // Since the vehicle is demanding this setting, we override Bullet's smoothing
@@ -702,28 +748,28 @@ namespace OpenSim.Region.Physics.BulletSPlugin
702 } 748 }
703 749
704 if ((m_knownChanged & m_knownChangedForce) != 0) 750 if ((m_knownChanged & m_knownChangedForce) != 0)
705 Prim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/); 751 ControllingPrim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/);
706 752
707 if ((m_knownChanged & m_knownChangedForceImpulse) != 0) 753 if ((m_knownChanged & m_knownChangedForceImpulse) != 0)
708 Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/); 754 ControllingPrim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/);
709 755
710 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) 756 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
711 { 757 {
712 Prim.ForceRotationalVelocity = m_knownRotationalVelocity; 758 ControllingPrim.ForceRotationalVelocity = m_knownRotationalVelocity;
713 // PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); 759 // PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity);
714 } 760 }
715 761
716 if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0) 762 if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0)
717 Prim.ApplyTorqueImpulse((Vector3)m_knownRotationalImpulse, true /*inTaintTime*/); 763 ControllingPrim.ApplyTorqueImpulse((Vector3)m_knownRotationalImpulse, true /*inTaintTime*/);
718 764
719 if ((m_knownChanged & m_knownChangedRotationalForce) != 0) 765 if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
720 { 766 {
721 Prim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/); 767 ControllingPrim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/);
722 } 768 }
723 769
724 // If we set one of the values (ie, the physics engine didn't do it) we must force 770 // If we set one of the values (ie, the physics engine didn't do it) we must force
725 // an UpdateProperties event to send the changes up to the simulator. 771 // an UpdateProperties event to send the changes up to the simulator.
726 PhysicsScene.PE.PushUpdate(Prim.PhysBody); 772 m_physicsScene.PE.PushUpdate(ControllingPrim.PhysBody);
727 } 773 }
728 m_knownChanged = 0; 774 m_knownChanged = 0;
729 } 775 }
@@ -736,7 +782,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
736 if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos) 782 if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos)
737 { 783 {
738 lastRememberedHeightPos = pos; 784 lastRememberedHeightPos = pos;
739 m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); 785 m_knownTerrainHeight = ControllingPrim.PhysScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
740 m_knownHas |= m_knownChangedTerrainHeight; 786 m_knownHas |= m_knownChangedTerrainHeight;
741 } 787 }
742 return m_knownTerrainHeight; 788 return m_knownTerrainHeight;
@@ -748,7 +794,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
748 { 794 {
749 if ((m_knownHas & m_knownChangedWaterLevel) == 0) 795 if ((m_knownHas & m_knownChangedWaterLevel) == 0)
750 { 796 {
751 m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); 797 m_knownWaterLevel = ControllingPrim.PhysScene.TerrainManager.GetWaterLevelAtXYZ(pos);
752 m_knownHas |= m_knownChangedWaterLevel; 798 m_knownHas |= m_knownChangedWaterLevel;
753 } 799 }
754 return (float)m_knownWaterLevel; 800 return (float)m_knownWaterLevel;
@@ -760,7 +806,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
760 { 806 {
761 if ((m_knownHas & m_knownChangedPosition) == 0) 807 if ((m_knownHas & m_knownChangedPosition) == 0)
762 { 808 {
763 m_knownPosition = Prim.ForcePosition; 809 m_knownPosition = ControllingPrim.ForcePosition;
764 m_knownHas |= m_knownChangedPosition; 810 m_knownHas |= m_knownChangedPosition;
765 } 811 }
766 return m_knownPosition; 812 return m_knownPosition;
@@ -779,7 +825,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
779 { 825 {
780 if ((m_knownHas & m_knownChangedOrientation) == 0) 826 if ((m_knownHas & m_knownChangedOrientation) == 0)
781 { 827 {
782 m_knownOrientation = Prim.ForceOrientation; 828 m_knownOrientation = ControllingPrim.ForceOrientation;
783 m_knownHas |= m_knownChangedOrientation; 829 m_knownHas |= m_knownChangedOrientation;
784 } 830 }
785 return m_knownOrientation; 831 return m_knownOrientation;
@@ -798,7 +844,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
798 { 844 {
799 if ((m_knownHas & m_knownChangedVelocity) == 0) 845 if ((m_knownHas & m_knownChangedVelocity) == 0)
800 { 846 {
801 m_knownVelocity = Prim.ForceVelocity; 847 m_knownVelocity = ControllingPrim.ForceVelocity;
802 m_knownHas |= m_knownChangedVelocity; 848 m_knownHas |= m_knownChangedVelocity;
803 } 849 }
804 return m_knownVelocity; 850 return m_knownVelocity;
@@ -839,7 +885,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
839 { 885 {
840 if ((m_knownHas & m_knownChangedRotationalVelocity) == 0) 886 if ((m_knownHas & m_knownChangedRotationalVelocity) == 0)
841 { 887 {
842 m_knownRotationalVelocity = Prim.ForceRotationalVelocity; 888 m_knownRotationalVelocity = ControllingPrim.ForceRotationalVelocity;
843 m_knownHas |= m_knownChangedRotationalVelocity; 889 m_knownHas |= m_knownChangedRotationalVelocity;
844 } 890 }
845 return (Vector3)m_knownRotationalVelocity; 891 return (Vector3)m_knownRotationalVelocity;
@@ -914,11 +960,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
914 // for the physics engine to note the changes so an UpdateProperties event will happen. 960 // for the physics engine to note the changes so an UpdateProperties event will happen.
915 PushKnownChanged(); 961 PushKnownChanged();
916 962
917 if (PhysicsScene.VehiclePhysicalLoggingEnabled) 963 if (m_physicsScene.VehiclePhysicalLoggingEnabled)
918 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); 964 m_physicsScene.PE.DumpRigidBody(m_physicsScene.World, ControllingPrim.PhysBody);
919 965
920 VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}", 966 VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}",
921 Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity); 967 ControllingPrim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
922 } 968 }
923 969
924 // Called after the simulation step 970 // Called after the simulation step
@@ -926,8 +972,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
926 { 972 {
927 if (!IsActive) return; 973 if (!IsActive) return;
928 974
929 if (PhysicsScene.VehiclePhysicalLoggingEnabled) 975 if (m_physicsScene.VehiclePhysicalLoggingEnabled)
930 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); 976 m_physicsScene.PE.DumpRigidBody(m_physicsScene.World, ControllingPrim.PhysBody);
931 } 977 }
932 978
933 // Apply the effect of the linear motor and other linear motions (like hover and float). 979 // Apply the effect of the linear motor and other linear motions (like hover and float).
@@ -966,13 +1012,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
966 Vector3 origVelW = VehicleVelocity; // DEBUG DEBUG 1012 Vector3 origVelW = VehicleVelocity; // DEBUG DEBUG
967 VehicleVelocity /= VehicleVelocity.Length(); 1013 VehicleVelocity /= VehicleVelocity.Length();
968 VehicleVelocity *= BSParam.VehicleMaxLinearVelocity; 1014 VehicleVelocity *= BSParam.VehicleMaxLinearVelocity;
969 VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}", 1015 VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}",
970 Prim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity); 1016 ControllingPrim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity);
971 } 1017 }
972 else if (newVelocityLengthSq < 0.001f) 1018 else if (newVelocityLengthSq < 0.001f)
973 VehicleVelocity = Vector3.Zero; 1019 VehicleVelocity = Vector3.Zero;
974 1020
975 VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", Prim.LocalID, Prim.IsColliding, VehicleVelocity ); 1021 VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", ControllingPrim.LocalID, ControllingPrim.IsColliding, VehicleVelocity );
976 1022
977 } // end MoveLinear() 1023 } // end MoveLinear()
978 1024
@@ -983,6 +1029,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
983 Vector3 currentVelV = VehicleVelocity * Quaternion.Inverse(VehicleOrientation); 1029 Vector3 currentVelV = VehicleVelocity * Quaternion.Inverse(VehicleOrientation);
984 Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV); 1030 Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV);
985 1031
1032 // Friction reduces vehicle motion
1033 Vector3 frictionFactorW = ComputeFrictionFactor(m_linearFrictionTimescale, pTimestep);
1034 linearMotorCorrectionV -= (currentVelV * frictionFactorW);
1035
986 // Motor is vehicle coordinates. Rotate it to world coordinates 1036 // Motor is vehicle coordinates. Rotate it to world coordinates
987 Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation; 1037 Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation;
988 1038
@@ -996,8 +1046,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
996 // Add this correction to the velocity to make it faster/slower. 1046 // Add this correction to the velocity to make it faster/slower.
997 VehicleVelocity += linearMotorVelocityW; 1047 VehicleVelocity += linearMotorVelocityW;
998 1048
999 VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5}", 1049
1000 Prim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, linearMotorVelocityW, VehicleVelocity); 1050
1051 VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5},fricFact={6}",
1052 ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV,
1053 linearMotorVelocityW, VehicleVelocity, frictionFactorW);
1001 } 1054 }
1002 1055
1003 public void ComputeLinearTerrainHeightCorrection(float pTimestep) 1056 public void ComputeLinearTerrainHeightCorrection(float pTimestep)
@@ -1011,7 +1064,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1011 newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f; 1064 newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f;
1012 VehiclePosition = newPosition; 1065 VehiclePosition = newPosition;
1013 VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", 1066 VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}",
1014 Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); 1067 ControllingPrim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition);
1015 } 1068 }
1016 } 1069 }
1017 1070
@@ -1041,7 +1094,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1041 if (VehiclePosition.Z > m_VhoverTargetHeight) 1094 if (VehiclePosition.Z > m_VhoverTargetHeight)
1042 m_VhoverTargetHeight = VehiclePosition.Z; 1095 m_VhoverTargetHeight = VehiclePosition.Z;
1043 } 1096 }
1044 1097
1045 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) 1098 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
1046 { 1099 {
1047 if (Math.Abs(VehiclePosition.Z - m_VhoverTargetHeight) > 0.2f) 1100 if (Math.Abs(VehiclePosition.Z - m_VhoverTargetHeight) > 0.2f)
@@ -1050,7 +1103,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1050 pos.Z = m_VhoverTargetHeight; 1103 pos.Z = m_VhoverTargetHeight;
1051 VehiclePosition = pos; 1104 VehiclePosition = pos;
1052 1105
1053 VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", Prim.LocalID, pos); 1106 VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", ControllingPrim.LocalID, pos);
1054 } 1107 }
1055 } 1108 }
1056 else 1109 else
@@ -1079,7 +1132,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1079 */ 1132 */
1080 1133
1081 VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corr={7}", 1134 VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corr={7}",
1082 Prim.LocalID, VehiclePosition, m_VhoverEfficiency, 1135 ControllingPrim.LocalID, VehiclePosition, m_VhoverEfficiency,
1083 m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, 1136 m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight,
1084 verticalError, verticalCorrection); 1137 verticalError, verticalCorrection);
1085 } 1138 }
@@ -1124,7 +1177,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1124 { 1177 {
1125 VehiclePosition = pos; 1178 VehiclePosition = pos;
1126 VDetailLog("{0}, MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", 1179 VDetailLog("{0}, MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
1127 Prim.LocalID, m_BlockingEndPoint, posChange, pos); 1180 ControllingPrim.LocalID, m_BlockingEndPoint, posChange, pos);
1128 } 1181 }
1129 } 1182 }
1130 return changed; 1183 return changed;
@@ -1135,7 +1188,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1135 // used with conjunction with banking: the strength of the banking will decay when the 1188 // used with conjunction with banking: the strength of the banking will decay when the
1136 // vehicle no longer experiences collisions. The decay timescale is the same as 1189 // vehicle no longer experiences collisions. The decay timescale is the same as
1137 // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering 1190 // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering
1138 // when they are in mid jump. 1191 // when they are in mid jump.
1139 // TODO: this code is wrong. Also, what should it do for boats (height from water)? 1192 // TODO: this code is wrong. Also, what should it do for boats (height from water)?
1140 // This is just using the ground and a general collision check. Should really be using 1193 // This is just using the ground and a general collision check. Should really be using
1141 // a downward raycast to find what is below. 1194 // a downward raycast to find what is below.
@@ -1164,7 +1217,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1164 1217
1165 // Another approach is to measure if we're going up. If going up and not colliding, 1218 // Another approach is to measure if we're going up. If going up and not colliding,
1166 // the vehicle is in the air. Fix that by pushing down. 1219 // the vehicle is in the air. Fix that by pushing down.
1167 if (!Prim.IsColliding && VehicleVelocity.Z > 0.1) 1220 if (!ControllingPrim.IsColliding && VehicleVelocity.Z > 0.1)
1168 { 1221 {
1169 // Get rid of any of the velocity vector that is pushing us up. 1222 // Get rid of any of the velocity vector that is pushing us up.
1170 float upVelocity = VehicleVelocity.Z; 1223 float upVelocity = VehicleVelocity.Z;
@@ -1186,7 +1239,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1186 } 1239 }
1187 */ 1240 */
1188 VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}", 1241 VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}",
1189 Prim.LocalID, Prim.IsColliding, upVelocity, VehicleVelocity); 1242 ControllingPrim.LocalID, ControllingPrim.IsColliding, upVelocity, VehicleVelocity);
1190 } 1243 }
1191 } 1244 }
1192 } 1245 }
@@ -1196,14 +1249,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1196 Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass; 1249 Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass;
1197 1250
1198 // Hack to reduce downward force if the vehicle is probably sitting on the ground 1251 // Hack to reduce downward force if the vehicle is probably sitting on the ground
1199 if (Prim.IsColliding && IsGroundVehicle) 1252 if (ControllingPrim.IsColliding && IsGroundVehicle)
1200 appliedGravity *= BSParam.VehicleGroundGravityFudge; 1253 appliedGravity *= BSParam.VehicleGroundGravityFudge;
1201 1254
1202 VehicleAddForce(appliedGravity); 1255 VehicleAddForce(appliedGravity);
1203 1256
1204 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={3}", 1257 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={3}",
1205 Prim.LocalID, m_VehicleGravity, 1258 ControllingPrim.LocalID, m_VehicleGravity,
1206 Prim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity); 1259 ControllingPrim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity);
1207 } 1260 }
1208 1261
1209 // ======================================================================= 1262 // =======================================================================
@@ -1227,11 +1280,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1227 { 1280 {
1228 // The vehicle is not adding anything angular wise. 1281 // The vehicle is not adding anything angular wise.
1229 VehicleRotationalVelocity = Vector3.Zero; 1282 VehicleRotationalVelocity = Vector3.Zero;
1230 VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); 1283 VDetailLog("{0}, MoveAngular,done,zero", ControllingPrim.LocalID);
1231 } 1284 }
1232 else 1285 else
1233 { 1286 {
1234 VDetailLog("{0}, MoveAngular,done,nonZero,angVel={1}", Prim.LocalID, VehicleRotationalVelocity); 1287 VDetailLog("{0}, MoveAngular,done,nonZero,angVel={1}", ControllingPrim.LocalID, VehicleRotationalVelocity);
1235 } 1288 }
1236 1289
1237 // ================================================================== 1290 // ==================================================================
@@ -1262,7 +1315,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1262 torqueFromOffset.Z = 0; 1315 torqueFromOffset.Z = 0;
1263 1316
1264 VehicleAddAngularForce(torqueFromOffset * m_vehicleMass); 1317 VehicleAddAngularForce(torqueFromOffset * m_vehicleMass);
1265 VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); 1318 VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", ControllingPrim.LocalID, torqueFromOffset);
1266 } 1319 }
1267 1320
1268 } 1321 }
@@ -1277,7 +1330,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1277 // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : 1330 // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags :
1278 // This flag prevents linear deflection parallel to world z-axis. This is useful 1331 // This flag prevents linear deflection parallel to world z-axis. This is useful
1279 // for preventing ground vehicles with large linear deflection, like bumper cars, 1332 // for preventing ground vehicles with large linear deflection, like bumper cars,
1280 // from climbing their linear deflection into the sky. 1333 // from climbing their linear deflection into the sky.
1281 // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement 1334 // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
1282 // TODO: This is here because this is where ODE put it but documentation says it 1335 // TODO: This is here because this is where ODE put it but documentation says it
1283 // is a linear effect. Where should this check go? 1336 // is a linear effect. Where should this check go?
@@ -1287,8 +1340,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1287 // angularMotorContributionV.Y = 0f; 1340 // angularMotorContributionV.Y = 0f;
1288 // } 1341 // }
1289 1342
1343 // Reduce any velocity by friction.
1344 Vector3 frictionFactorW = ComputeFrictionFactor(m_angularFrictionTimescale, pTimestep);
1345 angularMotorContributionV -= (currentAngularV * frictionFactorW);
1346
1290 VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation; 1347 VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation;
1291 VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContributionV); 1348
1349
1350
1351 VDetailLog("{0}, MoveAngular,angularTurning,angContribV={1}", ControllingPrim.LocalID, angularMotorContributionV);
1292 } 1352 }
1293 1353
1294 // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: 1354 // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial:
@@ -1305,6 +1365,35 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1305 // If vertical attaction timescale is reasonable 1365 // If vertical attaction timescale is reasonable
1306 if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1366 if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1307 { 1367 {
1368 //Another formula to try got from :
1369 //http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html
1370
1371 Vector3 VehicleUpAxis = Vector3.UnitZ * VehicleOrientation;
1372
1373 // Flipping what was originally a timescale into a speed variable and then multiplying it by 2
1374 // since only computing half the distance between the angles.
1375 float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f;
1376
1377 // Make a prediction of where the up axis will be when this is applied rather then where it is now as
1378 // this makes for a smoother adjustment and less fighting between the various forces.
1379 Vector3 predictedUp = VehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
1380
1381 // This is only half the distance to the target so it will take 2 seconds to complete the turn.
1382 Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
1383
1384 // Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared
1385 Vector3 vertContributionV = torqueVector * VerticalAttractionSpeed * VerticalAttractionSpeed;
1386
1387 VehicleRotationalVelocity += vertContributionV;
1388
1389 VDetailLog("{0}, MoveAngular,verticalAttraction,UpAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
1390 ControllingPrim.LocalID,
1391 VehicleUpAxis,
1392 predictedUp,
1393 torqueVector,
1394 vertContributionV);
1395 //=====================================================================
1396 /*
1308 // Possible solution derived from a discussion at: 1397 // Possible solution derived from a discussion at:
1309 // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no 1398 // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no
1310 1399
@@ -1334,11 +1423,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1334 VehicleRotationalVelocity += vertContributionV; 1423 VehicleRotationalVelocity += vertContributionV;
1335 1424
1336 VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}", 1425 VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}",
1337 Prim.LocalID, 1426 ControllingPrim.LocalID,
1338 differenceAxis, 1427 differenceAxis,
1339 differenceAngle, 1428 differenceAngle,
1340 correctionRotation, 1429 correctionRotation,
1341 vertContributionV); 1430 vertContributionV);
1431 */
1342 1432
1343 // =================================================================== 1433 // ===================================================================
1344 /* 1434 /*
@@ -1380,7 +1470,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1380 VehicleRotationalVelocity += (vertContributionV * VehicleOrientation); 1470 VehicleRotationalVelocity += (vertContributionV * VehicleOrientation);
1381 1471
1382 VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}", 1472 VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}",
1383 Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV, 1473 Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV,
1384 m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV); 1474 m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV);
1385 */ 1475 */
1386 } 1476 }
@@ -1433,9 +1523,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1433 VehicleRotationalVelocity += deflectContributionV * VehicleOrientation; 1523 VehicleRotationalVelocity += deflectContributionV * VehicleOrientation;
1434 1524
1435 VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", 1525 VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}",
1436 Prim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV); 1526 ControllingPrim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV);
1437 VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", 1527 VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}",
1438 Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); 1528 ControllingPrim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale);
1439 } 1529 }
1440 } 1530 }
1441 1531
@@ -1447,13 +1537,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1447 // produce a angular velocity around the yaw-axis, causing the vehicle to turn. The magnitude 1537 // produce a angular velocity around the yaw-axis, causing the vehicle to turn. The magnitude
1448 // of the yaw effect will be proportional to the 1538 // of the yaw effect will be proportional to the
1449 // VEHICLE_BANKING_EFFICIENCY, the angle of the roll rotation, and sometimes the vehicle's 1539 // VEHICLE_BANKING_EFFICIENCY, the angle of the roll rotation, and sometimes the vehicle's
1450 // velocity along its preferred axis of motion. 1540 // velocity along its preferred axis of motion.
1451 // The VEHICLE_BANKING_EFFICIENCY can vary between -1 and +1. When it is positive then any 1541 // The VEHICLE_BANKING_EFFICIENCY can vary between -1 and +1. When it is positive then any
1452 // positive rotation (by the right-hand rule) about the roll-axis will effect a 1542 // positive rotation (by the right-hand rule) about the roll-axis will effect a
1453 // (negative) torque around the yaw-axis, making it turn to the right--that is the 1543 // (negative) torque around the yaw-axis, making it turn to the right--that is the
1454 // vehicle will lean into the turn, which is how real airplanes and motorcycle's work. 1544 // vehicle will lean into the turn, which is how real airplanes and motorcycle's work.
1455 // Negating the banking coefficient will make it so that the vehicle leans to the 1545 // Negating the banking coefficient will make it so that the vehicle leans to the
1456 // outside of the turn (not very "physical" but might allow interesting vehicles so why not?). 1546 // outside of the turn (not very "physical" but might allow interesting vehicles so why not?).
1457 // The VEHICLE_BANKING_MIX is a fake (i.e. non-physical) parameter that is useful for making 1547 // The VEHICLE_BANKING_MIX is a fake (i.e. non-physical) parameter that is useful for making
1458 // banking vehicles do what you want rather than what the laws of physics allow. 1548 // banking vehicles do what you want rather than what the laws of physics allow.
1459 // For example, consider a real motorcycle...it must be moving forward in order for 1549 // For example, consider a real motorcycle...it must be moving forward in order for
@@ -1465,11 +1555,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1465 // totally static (0.0) and totally dynamic (1.0). By "static" we mean that the 1555 // totally static (0.0) and totally dynamic (1.0). By "static" we mean that the
1466 // banking effect depends only on the vehicle's rotation about its roll-axis compared 1556 // banking effect depends only on the vehicle's rotation about its roll-axis compared
1467 // to "dynamic" where the banking is also proportional to its velocity along its 1557 // to "dynamic" where the banking is also proportional to its velocity along its
1468 // roll-axis. Finding the best value of the "mixture" will probably require trial and error. 1558 // roll-axis. Finding the best value of the "mixture" will probably require trial and error.
1469 // The time it takes for the banking behavior to defeat a preexisting angular velocity about the 1559 // The time it takes for the banking behavior to defeat a preexisting angular velocity about the
1470 // world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to 1560 // world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to
1471 // bank quickly then give it a banking timescale of about a second or less, otherwise you can 1561 // bank quickly then give it a banking timescale of about a second or less, otherwise you can
1472 // make a sluggish vehicle by giving it a timescale of several seconds. 1562 // make a sluggish vehicle by giving it a timescale of several seconds.
1473 public void ComputeAngularBanking() 1563 public void ComputeAngularBanking()
1474 { 1564 {
1475 if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1565 if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
@@ -1498,10 +1588,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1498 1588
1499 //VehicleRotationalVelocity += bankingContributionV * VehicleOrientation; 1589 //VehicleRotationalVelocity += bankingContributionV * VehicleOrientation;
1500 VehicleRotationalVelocity += bankingContributionV; 1590 VehicleRotationalVelocity += bankingContributionV;
1501 1591
1502 1592
1503 VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", 1593 VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}",
1504 Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV); 1594 ControllingPrim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV);
1505 } 1595 }
1506 } 1596 }
1507 1597
@@ -1540,11 +1630,28 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1540 if (rotq != m_rot) 1630 if (rotq != m_rot)
1541 { 1631 {
1542 VehicleOrientation = m_rot; 1632 VehicleOrientation = m_rot;
1543 VDetailLog("{0}, LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); 1633 VDetailLog("{0}, LimitRotation,done,orig={1},new={2}", ControllingPrim.LocalID, rotq, m_rot);
1544 } 1634 }
1545 1635
1546 } 1636 }
1547 1637
1638 // Given a friction vector (reduction in seconds) and a timestep, return the factor to reduce
1639 // some value by to apply this friction.
1640 private Vector3 ComputeFrictionFactor(Vector3 friction, float pTimestep)
1641 {
1642 Vector3 frictionFactor = Vector3.Zero;
1643 if (friction != BSMotor.InfiniteVector)
1644 {
1645 // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep;
1646 // Individual friction components can be 'infinite' so compute each separately.
1647 frictionFactor.X = (friction.X == BSMotor.Infinite) ? 0f : (1f / friction.X);
1648 frictionFactor.Y = (friction.Y == BSMotor.Infinite) ? 0f : (1f / friction.Y);
1649 frictionFactor.Z = (friction.Z == BSMotor.Infinite) ? 0f : (1f / friction.Z);
1650 frictionFactor *= pTimestep;
1651 }
1652 return frictionFactor;
1653 }
1654
1548 private float ClampInRange(float low, float val, float high) 1655 private float ClampInRange(float low, float val, float high)
1549 { 1656 {
1550 return Math.Max(low, Math.Min(val, high)); 1657 return Math.Max(low, Math.Min(val, high));
@@ -1554,8 +1661,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1554 // Invoke the detailed logger and output something if it's enabled. 1661 // Invoke the detailed logger and output something if it's enabled.
1555 private void VDetailLog(string msg, params Object[] args) 1662 private void VDetailLog(string msg, params Object[] args)
1556 { 1663 {
1557 if (Prim.PhysicsScene.VehicleLoggingEnabled) 1664 if (ControllingPrim.PhysScene.VehicleLoggingEnabled)
1558 Prim.PhysicsScene.DetailLog(msg, args); 1665 ControllingPrim.PhysScene.DetailLog(msg, args);
1559 } 1666 }
1560 } 1667 }
1561} 1668}