diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 315 |
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 | ||
41 | namespace OpenSim.Region.Physics.BulletSPlugin | 41 | namespace 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 | } |