diff options
author | Justin Clark-Casey (justincc) | 2013-01-15 00:24:51 +0000 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2013-01-15 00:24:51 +0000 |
commit | c846cefda97bd59b7707147d7ae1a520c9121127 (patch) | |
tree | ee23e4b451087874a8149348e010a905817121f7 /OpenSim/Region/Physics/BulletSPlugin | |
parent | refactor: Simplify ScriptInstance by retaining reference to SceneObjectPart i... (diff) | |
parent | BulletSim: fix not moving physical objects below terrain to over terrain. (diff) | |
download | opensim-SC-c846cefda97bd59b7707147d7ae1a520c9121127.zip opensim-SC-c846cefda97bd59b7707147d7ae1a520c9121127.tar.gz opensim-SC-c846cefda97bd59b7707147d7ae1a520c9121127.tar.bz2 opensim-SC-c846cefda97bd59b7707147d7ae1a520c9121127.tar.xz |
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to '')
14 files changed, 466 insertions, 223 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 14de2eb..9ff7084 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | |||
@@ -202,7 +202,7 @@ private void BulletLoggerPhysLog(string msg) | |||
202 | } | 202 | } |
203 | 203 | ||
204 | public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, | 204 | public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, |
205 | out int updatedEntityCount, out int collidersCount) | 205 | out int updatedEntityCount, out int collidersCount) |
206 | { | 206 | { |
207 | BulletWorldUnman worldu = world as BulletWorldUnman; | 207 | BulletWorldUnman worldu = world as BulletWorldUnman; |
208 | return BSAPICPP.PhysicsStep2(worldu.ptr, timeStep, maxSubSteps, fixedTimeStep, out updatedEntityCount, out collidersCount); | 208 | return BSAPICPP.PhysicsStep2(worldu.ptr, timeStep, maxSubSteps, fixedTimeStep, out updatedEntityCount, out collidersCount); |
@@ -327,6 +327,12 @@ public override void RemoveChildShapeFromCompoundShape(BulletShape shape, Bullet | |||
327 | BSAPICPP.RemoveChildShapeFromCompoundShape2(shapeu.ptr, removeShapeu.ptr); | 327 | BSAPICPP.RemoveChildShapeFromCompoundShape2(shapeu.ptr, removeShapeu.ptr); |
328 | } | 328 | } |
329 | 329 | ||
330 | public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) | ||
331 | { | ||
332 | BulletShapeUnman shapeu = pShape as BulletShapeUnman; | ||
333 | BSAPICPP.UpdateChildTransform2(shapeu.ptr, childIndex, pos, rot, shouldRecalculateLocalAabb); | ||
334 | } | ||
335 | |||
330 | public override void RecalculateCompoundShapeLocalAabb(BulletShape shape) | 336 | public override void RecalculateCompoundShapeLocalAabb(BulletShape shape) |
331 | { | 337 | { |
332 | BulletShapeUnman shapeu = shape as BulletShapeUnman; | 338 | BulletShapeUnman shapeu = shape as BulletShapeUnman; |
@@ -1357,6 +1363,9 @@ public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShap | |||
1357 | public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); | 1363 | public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); |
1358 | 1364 | ||
1359 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 1365 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
1366 | public static extern void UpdateChildTransform2(IntPtr pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb); | ||
1367 | |||
1368 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
1360 | public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); | 1369 | public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); |
1361 | 1370 | ||
1362 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 1371 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 0c7f315..b6ff52b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | |||
@@ -1212,6 +1212,7 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1212 | 1212 | ||
1213 | public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { /* TODO */ return null; } | 1213 | public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { /* TODO */ return null; } |
1214 | public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ } | 1214 | public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ } |
1215 | public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) { /* TODO */ } | ||
1215 | 1216 | ||
1216 | public override BulletShape CreateGroundPlaneShape(uint pLocalId, float pheight, float pcollisionMargin) | 1217 | public override BulletShape CreateGroundPlaneShape(uint pLocalId, float pheight, float pcollisionMargin) |
1217 | { | 1218 | { |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 794ee17..bc163eb 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | |||
@@ -342,6 +342,8 @@ public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape c | |||
342 | 342 | ||
343 | public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape); | 343 | public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape); |
344 | 344 | ||
345 | public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb); | ||
346 | |||
345 | public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); | 347 | public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); |
346 | 348 | ||
347 | public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); | 349 | public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 939d38a..a5fec87 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -126,9 +126,9 @@ public sealed class BSCharacter : BSPhysObject | |||
126 | DetailLog("{0},BSCharacter.Destroy", LocalID); | 126 | DetailLog("{0},BSCharacter.Destroy", LocalID); |
127 | PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() | 127 | PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() |
128 | { | 128 | { |
129 | PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); | 129 | PhysicsScene.Shapes.DereferenceBody(PhysBody, true /* inTaintTime */, null /* bodyCallback */); |
130 | PhysBody.Clear(); | 130 | PhysBody.Clear(); |
131 | PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); | 131 | PhysicsScene.Shapes.DereferenceShape(PhysShape, true /* inTaintTime */, null /* bodyCallback */); |
132 | PhysShape.Clear(); | 132 | PhysShape.Clear(); |
133 | }); | 133 | }); |
134 | } | 134 | } |
@@ -328,6 +328,10 @@ public sealed class BSCharacter : BSPhysObject | |||
328 | public override bool Selected { | 328 | public override bool Selected { |
329 | set { _selected = value; } | 329 | set { _selected = value; } |
330 | } | 330 | } |
331 | public override bool IsSelected | ||
332 | { | ||
333 | get { return _selected; } | ||
334 | } | ||
331 | public override void CrossingFailure() { return; } | 335 | public override void CrossingFailure() { return; } |
332 | public override void link(PhysicsActor obj) { return; } | 336 | public override void link(PhysicsActor obj) { return; } |
333 | public override void delink() { return; } | 337 | public override void delink() { return; } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index c34c05a..bcebaec 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -108,10 +108,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
108 | private float m_VhoverEfficiency = 0f; | 108 | private float m_VhoverEfficiency = 0f; |
109 | private float m_VhoverTimescale = 0f; | 109 | private float m_VhoverTimescale = 0f; |
110 | private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height | 110 | private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height |
111 | private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. | 111 | // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) |
112 | // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) | 112 | private float m_VehicleBuoyancy = 0f; |
113 | // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. | 113 | private Vector3 m_VehicleGravity = Vector3.Zero; // Gravity computed when buoyancy set |
114 | // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. | ||
115 | 114 | ||
116 | //Attractor properties | 115 | //Attractor properties |
117 | private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); | 116 | private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); |
@@ -124,17 +123,38 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
124 | static readonly float PIOverFour = ((float)Math.PI) / 4f; | 123 | static readonly float PIOverFour = ((float)Math.PI) / 4f; |
125 | static readonly float PIOverTwo = ((float)Math.PI) / 2f; | 124 | static readonly float PIOverTwo = ((float)Math.PI) / 2f; |
126 | 125 | ||
126 | // For debugging, flags to turn on and off individual corrections. | ||
127 | private bool enableAngularVerticalAttraction = true; | ||
128 | private bool enableAngularDeflection = true; | ||
129 | private bool enableAngularBanking = true; | ||
130 | |||
127 | public BSDynamics(BSScene myScene, BSPrim myPrim) | 131 | public BSDynamics(BSScene myScene, BSPrim myPrim) |
128 | { | 132 | { |
129 | PhysicsScene = myScene; | 133 | PhysicsScene = myScene; |
130 | Prim = myPrim; | 134 | Prim = myPrim; |
131 | Type = Vehicle.TYPE_NONE; | 135 | Type = Vehicle.TYPE_NONE; |
136 | SetupVehicleDebugging(); | ||
137 | } | ||
138 | |||
139 | // Stopgap debugging enablement. Allows source level debugging but still checking | ||
140 | // in changes by making enablement of debugging flags from INI file. | ||
141 | public void SetupVehicleDebugging() | ||
142 | { | ||
143 | enableAngularVerticalAttraction = true; | ||
144 | enableAngularDeflection = true; | ||
145 | enableAngularBanking = true; | ||
146 | if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse) | ||
147 | { | ||
148 | enableAngularVerticalAttraction = false; | ||
149 | enableAngularDeflection = false; | ||
150 | enableAngularBanking = false; | ||
151 | } | ||
132 | } | 152 | } |
133 | 153 | ||
134 | // Return 'true' if this vehicle is doing vehicle things | 154 | // Return 'true' if this vehicle is doing vehicle things |
135 | public bool IsActive | 155 | public bool IsActive |
136 | { | 156 | { |
137 | get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; } | 157 | get { return (Type != Vehicle.TYPE_NONE && !Prim.IsStatic); } |
138 | } | 158 | } |
139 | 159 | ||
140 | #region Vehicle parameter setting | 160 | #region Vehicle parameter setting |
@@ -168,6 +188,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
168 | break; | 188 | break; |
169 | case Vehicle.BUOYANCY: | 189 | case Vehicle.BUOYANCY: |
170 | m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); | 190 | m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); |
191 | m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy); | ||
171 | break; | 192 | break; |
172 | case Vehicle.HOVER_EFFICIENCY: | 193 | case Vehicle.HOVER_EFFICIENCY: |
173 | m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); | 194 | m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); |
@@ -540,12 +561,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
540 | 1f); | 561 | 1f); |
541 | m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | 562 | m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) |
542 | 563 | ||
564 | /* Not implemented | ||
543 | m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, | 565 | m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, |
544 | BSMotor.Infinite, BSMotor.InfiniteVector, | 566 | BSMotor.Infinite, BSMotor.InfiniteVector, |
545 | m_verticalAttractionEfficiency); | 567 | m_verticalAttractionEfficiency); |
546 | // Z goes away and we keep X and Y | 568 | // Z goes away and we keep X and Y |
547 | m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); | 569 | m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); |
548 | m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | 570 | m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) |
571 | */ | ||
549 | } | 572 | } |
550 | #endregion // Vehicle parameter setting | 573 | #endregion // Vehicle parameter setting |
551 | 574 | ||
@@ -571,15 +594,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
571 | // Vehicles report collision events so we know when it's on the ground | 594 | // Vehicles report collision events so we know when it's on the ground |
572 | PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); | 595 | PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); |
573 | 596 | ||
574 | Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass); | 597 | Prim.Inertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass); |
575 | PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, localInertia); | 598 | PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, Prim.Inertia); |
576 | PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody); | 599 | PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody); |
577 | 600 | ||
578 | Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy); | 601 | // Set the gravity for the vehicle depending on the buoyancy |
579 | PhysicsScene.PE.SetGravity(Prim.PhysBody, grav); | 602 | // TODO: what should be done if prim and vehicle buoyancy differ? |
603 | m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy); | ||
604 | // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. | ||
605 | PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero); | ||
580 | 606 | ||
581 | VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}", | 607 | VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", |
582 | Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); | 608 | Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, m_VehicleGravity); |
583 | } | 609 | } |
584 | else | 610 | else |
585 | { | 611 | { |
@@ -619,6 +645,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
619 | private Vector3 m_knownPosition; | 645 | private Vector3 m_knownPosition; |
620 | private Vector3 m_knownVelocity; | 646 | private Vector3 m_knownVelocity; |
621 | private Vector3 m_knownForce; | 647 | private Vector3 m_knownForce; |
648 | private Vector3 m_knownForceImpulse; | ||
622 | private Quaternion m_knownOrientation; | 649 | private Quaternion m_knownOrientation; |
623 | private Vector3 m_knownRotationalVelocity; | 650 | private Vector3 m_knownRotationalVelocity; |
624 | private Vector3 m_knownRotationalForce; | 651 | private Vector3 m_knownRotationalForce; |
@@ -627,12 +654,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
627 | private const int m_knownChangedPosition = 1 << 0; | 654 | private const int m_knownChangedPosition = 1 << 0; |
628 | private const int m_knownChangedVelocity = 1 << 1; | 655 | private const int m_knownChangedVelocity = 1 << 1; |
629 | private const int m_knownChangedForce = 1 << 2; | 656 | private const int m_knownChangedForce = 1 << 2; |
630 | private const int m_knownChangedOrientation = 1 << 3; | 657 | private const int m_knownChangedForceImpulse = 1 << 3; |
631 | private const int m_knownChangedRotationalVelocity = 1 << 4; | 658 | private const int m_knownChangedOrientation = 1 << 4; |
632 | private const int m_knownChangedRotationalForce = 1 << 5; | 659 | private const int m_knownChangedRotationalVelocity = 1 << 5; |
633 | private const int m_knownChangedTerrainHeight = 1 << 6; | 660 | private const int m_knownChangedRotationalForce = 1 << 6; |
634 | private const int m_knownChangedWaterLevel = 1 << 7; | 661 | private const int m_knownChangedTerrainHeight = 1 << 7; |
635 | private const int m_knownChangedForwardVelocity = 1 << 8; | 662 | private const int m_knownChangedWaterLevel = 1 << 8; |
663 | private const int m_knownChangedForwardVelocity = 1 << 9; | ||
636 | 664 | ||
637 | private void ForgetKnownVehicleProperties() | 665 | private void ForgetKnownVehicleProperties() |
638 | { | 666 | { |
@@ -653,21 +681,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
653 | if ((m_knownChanged & m_knownChangedVelocity) != 0) | 681 | if ((m_knownChanged & m_knownChangedVelocity) != 0) |
654 | { | 682 | { |
655 | Prim.ForceVelocity = m_knownVelocity; | 683 | Prim.ForceVelocity = m_knownVelocity; |
656 | PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, VehicleVelocity); | 684 | // Fake out Bullet by making it think the velocity is the same as last time. |
685 | // Bullet does a bunch of smoothing for changing parameters. | ||
686 | // Since the vehicle is demanding this setting, we override Bullet's smoothing | ||
687 | // by telling Bullet the value was the same last time. | ||
688 | PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity); | ||
657 | } | 689 | } |
658 | 690 | ||
659 | if ((m_knownChanged & m_knownChangedForce) != 0) | 691 | if ((m_knownChanged & m_knownChangedForce) != 0) |
660 | Prim.AddForce((Vector3)m_knownForce, false, true); | 692 | Prim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/); |
693 | |||
694 | if ((m_knownChanged & m_knownChangedForceImpulse) != 0) | ||
695 | Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/); | ||
661 | 696 | ||
662 | if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) | 697 | if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) |
663 | { | 698 | { |
664 | Prim.ForceRotationalVelocity = m_knownRotationalVelocity; | 699 | Prim.ForceRotationalVelocity = m_knownRotationalVelocity; |
665 | // Fake out Bullet by making it think the velocity is the same as last time. | ||
666 | PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); | 700 | PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); |
667 | } | 701 | } |
668 | 702 | ||
669 | if ((m_knownChanged & m_knownChangedRotationalForce) != 0) | 703 | if ((m_knownChanged & m_knownChangedRotationalForce) != 0) |
670 | Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); | 704 | { |
705 | Prim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/); | ||
706 | } | ||
671 | 707 | ||
672 | // If we set one of the values (ie, the physics engine didn't do it) we must force | 708 | // If we set one of the values (ie, the physics engine didn't do it) we must force |
673 | // an UpdateProperties event to send the changes up to the simulator. | 709 | // an UpdateProperties event to send the changes up to the simulator. |
@@ -757,15 +793,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
757 | } | 793 | } |
758 | } | 794 | } |
759 | 795 | ||
760 | private void VehicleAddForce(Vector3 aForce) | 796 | private void VehicleAddForce(Vector3 pForce) |
761 | { | 797 | { |
762 | if ((m_knownHas & m_knownChangedForce) == 0) | 798 | if ((m_knownHas & m_knownChangedForce) == 0) |
763 | { | 799 | { |
764 | m_knownForce = Vector3.Zero; | 800 | m_knownForce = Vector3.Zero; |
801 | m_knownHas |= m_knownChangedForce; | ||
765 | } | 802 | } |
766 | m_knownForce += aForce; | 803 | m_knownForce += pForce; |
767 | m_knownChanged |= m_knownChangedForce; | 804 | m_knownChanged |= m_knownChangedForce; |
768 | m_knownHas |= m_knownChangedForce; | 805 | } |
806 | |||
807 | private void VehicleAddForceImpulse(Vector3 pImpulse) | ||
808 | { | ||
809 | if ((m_knownHas & m_knownChangedForceImpulse) == 0) | ||
810 | { | ||
811 | m_knownForceImpulse = Vector3.Zero; | ||
812 | m_knownHas |= m_knownChangedForceImpulse; | ||
813 | } | ||
814 | m_knownForceImpulse += pImpulse; | ||
815 | m_knownChanged |= m_knownChangedForceImpulse; | ||
769 | } | 816 | } |
770 | 817 | ||
771 | private Vector3 VehicleRotationalVelocity | 818 | private Vector3 VehicleRotationalVelocity |
@@ -844,86 +891,92 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
844 | if (PhysicsScene.VehiclePhysicalLoggingEnabled) | 891 | if (PhysicsScene.VehiclePhysicalLoggingEnabled) |
845 | PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); | 892 | PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); |
846 | 893 | ||
847 | VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", | 894 | VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}", |
848 | Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); | 895 | Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity); |
849 | } | 896 | } |
850 | 897 | ||
851 | // Apply the effect of the linear motor and other linear motions (like hover and float). | 898 | // Apply the effect of the linear motor and other linear motions (like hover and float). |
852 | private void MoveLinear(float pTimestep) | 899 | private void MoveLinear(float pTimestep) |
853 | { | 900 | { |
854 | Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); | 901 | ComputeLinearVelocity(pTimestep); |
855 | 902 | ||
856 | // The movement computed in the linear motor is relative to the vehicle | 903 | ComputeLinearTerrainHeightCorrection(pTimestep); |
857 | // coordinates. Rotate the movement to world coordinates. | ||
858 | linearMotorContribution *= VehicleOrientation; | ||
859 | // All the contributions after this are world relative (mostly Z modifications) | ||
860 | |||
861 | // ================================================================== | ||
862 | // Buoyancy: force to overcome gravity. | ||
863 | // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; | ||
864 | // So, if zero, don't change anything (let gravity happen). If one, negate the effect of gravity. | ||
865 | Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * m_VehicleBuoyancy; | ||
866 | |||
867 | Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); | ||
868 | 904 | ||
869 | Vector3 hoverContribution = ComputeLinearHover(pTimestep); | 905 | ComputeLinearHover(pTimestep); |
870 | 906 | ||
871 | ComputeLinearBlockingEndPoint(pTimestep); | 907 | ComputeLinearBlockingEndPoint(pTimestep); |
872 | 908 | ||
873 | Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); | 909 | ComputeLinearMotorUp(pTimestep); |
874 | 910 | ||
875 | // ================================================================== | 911 | ApplyGravity(pTimestep); |
876 | Vector3 newVelocity = linearMotorContribution | ||
877 | + terrainHeightContribution | ||
878 | + hoverContribution | ||
879 | + limitMotorUpContribution; | ||
880 | |||
881 | Vector3 newForce = buoyancyContribution; | ||
882 | 912 | ||
883 | // If not changing some axis, reduce out velocity | 913 | // If not changing some axis, reduce out velocity |
884 | if ((m_flags & (VehicleFlag.NO_X)) != 0) | 914 | if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0) |
885 | newVelocity.X = 0; | 915 | { |
886 | if ((m_flags & (VehicleFlag.NO_Y)) != 0) | 916 | Vector3 vel = VehicleVelocity; |
887 | newVelocity.Y = 0; | 917 | if ((m_flags & (VehicleFlag.NO_X)) != 0) |
888 | if ((m_flags & (VehicleFlag.NO_Z)) != 0) | 918 | vel.X = 0; |
889 | newVelocity.Z = 0; | 919 | if ((m_flags & (VehicleFlag.NO_Y)) != 0) |
920 | vel.Y = 0; | ||
921 | if ((m_flags & (VehicleFlag.NO_Z)) != 0) | ||
922 | vel.Z = 0; | ||
923 | VehicleVelocity = vel; | ||
924 | } | ||
890 | 925 | ||
891 | // ================================================================== | 926 | // ================================================================== |
892 | // Clamp high or low velocities | 927 | // Clamp high or low velocities |
893 | float newVelocityLengthSq = newVelocity.LengthSquared(); | 928 | float newVelocityLengthSq = VehicleVelocity.LengthSquared(); |
894 | if (newVelocityLengthSq > 1000f) | 929 | if (newVelocityLengthSq > 1000f) |
895 | { | 930 | { |
896 | newVelocity /= newVelocity.Length(); | 931 | VehicleVelocity /= VehicleVelocity.Length(); |
897 | newVelocity *= 1000f; | 932 | VehicleVelocity *= 1000f; |
898 | } | 933 | } |
899 | else if (newVelocityLengthSq < 0.001f) | 934 | else if (newVelocityLengthSq < 0.001f) |
900 | newVelocity = Vector3.Zero; | 935 | VehicleVelocity = Vector3.Zero; |
901 | 936 | ||
902 | // ================================================================== | 937 | VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", Prim.LocalID, Prim.IsColliding, VehicleVelocity ); |
903 | // Stuff new linear velocity into the vehicle. | 938 | |
904 | // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. | 939 | } // end MoveLinear() |
905 | VehicleVelocity = newVelocity; | 940 | |
941 | public void ComputeLinearVelocity(float pTimestep) | ||
942 | { | ||
943 | Vector3 linearMotorStep = m_linearMotor.Step(pTimestep); | ||
944 | |||
945 | // The movement computed in the linear motor is relative to the vehicle | ||
946 | // coordinates. Rotate the movement to world coordinates. | ||
947 | Vector3 linearMotorVelocity = linearMotorStep * VehicleOrientation; | ||
906 | 948 | ||
907 | // Other linear forces are applied as forces. | 949 | // If we're a ground vehicle, don't loose any Z action (like gravity acceleration). |
908 | Vector3 totalDownForce = newForce * m_vehicleMass; | 950 | float mixFactor = 1f; // 1 means use all linear motor Z value, 0 means use all existing Z |
909 | if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) | 951 | if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0) |
910 | { | 952 | { |
911 | VehicleAddForce(totalDownForce); | 953 | if (!Prim.IsColliding) |
954 | { | ||
955 | // If a ground vehicle and not on the ground, I want gravity effect | ||
956 | mixFactor = 0.2f; | ||
957 | } | ||
912 | } | 958 | } |
959 | else | ||
960 | { | ||
961 | // I'm not a ground vehicle but don't totally loose the effect of the environment | ||
962 | mixFactor = 0.8f; | ||
963 | } | ||
964 | linearMotorVelocity.Z = mixFactor * linearMotorVelocity.Z + (1f - mixFactor) * VehicleVelocity.Z; | ||
913 | 965 | ||
914 | VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}", | 966 | // What we want to contribute to the vehicle's existing velocity |
915 | Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding); | 967 | Vector3 linearMotorForce = linearMotorVelocity - VehicleVelocity; |
916 | VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},buoyContrib={5}", | ||
917 | Prim.LocalID, | ||
918 | linearMotorContribution, terrainHeightContribution, hoverContribution, | ||
919 | limitMotorUpContribution, buoyancyContribution | ||
920 | ); | ||
921 | 968 | ||
922 | } // end MoveLinear() | 969 | // Act against the inertia of the vehicle |
970 | linearMotorForce *= m_vehicleMass; | ||
923 | 971 | ||
924 | public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep) | 972 | VehicleAddForceImpulse(linearMotorForce * pTimestep); |
973 | |||
974 | VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}", | ||
975 | Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce); | ||
976 | } | ||
977 | |||
978 | public void ComputeLinearTerrainHeightCorrection(float pTimestep) | ||
925 | { | 979 | { |
926 | Vector3 ret = Vector3.Zero; | ||
927 | // If below the terrain, move us above the ground a little. | 980 | // If below the terrain, move us above the ground a little. |
928 | // TODO: Consider taking the rotated size of the object or possibly casting a ray. | 981 | // TODO: Consider taking the rotated size of the object or possibly casting a ray. |
929 | if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) | 982 | if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) |
@@ -935,13 +988,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
935 | VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", | 988 | VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", |
936 | Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); | 989 | Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); |
937 | } | 990 | } |
938 | return ret; | ||
939 | } | 991 | } |
940 | 992 | ||
941 | public Vector3 ComputeLinearHover(float pTimestep) | 993 | public void ComputeLinearHover(float pTimestep) |
942 | { | 994 | { |
943 | Vector3 ret = Vector3.Zero; | ||
944 | |||
945 | // m_VhoverEfficiency: 0=bouncy, 1=totally damped | 995 | // m_VhoverEfficiency: 0=bouncy, 1=totally damped |
946 | // m_VhoverTimescale: time to achieve height | 996 | // m_VhoverTimescale: time to achieve height |
947 | if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) | 997 | if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) |
@@ -974,23 +1024,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
974 | Vector3 pos = VehiclePosition; | 1024 | Vector3 pos = VehiclePosition; |
975 | pos.Z = m_VhoverTargetHeight; | 1025 | pos.Z = m_VhoverTargetHeight; |
976 | VehiclePosition = pos; | 1026 | VehiclePosition = pos; |
1027 | |||
1028 | VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", Prim.LocalID, pos); | ||
977 | } | 1029 | } |
978 | } | 1030 | } |
979 | else | 1031 | else |
980 | { | 1032 | { |
981 | // Error is positive if below the target and negative if above. | 1033 | // Error is positive if below the target and negative if above. |
982 | float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; | 1034 | float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; |
983 | float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; | 1035 | float verticalCorrectionVelocity = verticalError / m_VhoverTimescale * pTimestep; |
984 | 1036 | ||
985 | // TODO: implement m_VhoverEfficiency correctly | 1037 | // TODO: implement m_VhoverEfficiency correctly |
986 | ret = new Vector3(0f, 0f, verticalCorrectionVelocity); | 1038 | VehicleAddForceImpulse(new Vector3(0f, 0f, verticalCorrectionVelocity)); |
1039 | |||
1040 | VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corrVel={7}", | ||
1041 | Prim.LocalID, VehiclePosition, m_VhoverEfficiency, | ||
1042 | m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, | ||
1043 | verticalError, verticalCorrectionVelocity); | ||
987 | } | 1044 | } |
988 | 1045 | ||
989 | VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},ret={6}", | ||
990 | Prim.LocalID, VehiclePosition, m_VhoverEfficiency, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, ret); | ||
991 | } | 1046 | } |
992 | |||
993 | return ret; | ||
994 | } | 1047 | } |
995 | 1048 | ||
996 | public bool ComputeLinearBlockingEndPoint(float pTimestep) | 1049 | public bool ComputeLinearBlockingEndPoint(float pTimestep) |
@@ -1045,30 +1098,67 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1045 | // TODO: this code is wrong. Also, what should it do for boats (height from water)? | 1098 | // TODO: this code is wrong. Also, what should it do for boats (height from water)? |
1046 | // This is just using the ground and a general collision check. Should really be using | 1099 | // This is just using the ground and a general collision check. Should really be using |
1047 | // a downward raycast to find what is below. | 1100 | // a downward raycast to find what is below. |
1048 | public Vector3 ComputeLinearMotorUp(float pTimestep) | 1101 | public void ComputeLinearMotorUp(float pTimestep) |
1049 | { | 1102 | { |
1050 | Vector3 ret = Vector3.Zero; | 1103 | Vector3 ret = Vector3.Zero; |
1051 | float distanceAboveGround = 0f; | ||
1052 | 1104 | ||
1053 | if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) | 1105 | if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) |
1054 | { | 1106 | { |
1107 | // This code tries to decide if the object is not on the ground and then pushing down | ||
1108 | /* | ||
1055 | float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); | 1109 | float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); |
1056 | distanceAboveGround = VehiclePosition.Z - targetHeight; | 1110 | distanceAboveGround = VehiclePosition.Z - targetHeight; |
1057 | // Not colliding if the vehicle is off the ground | 1111 | // Not colliding if the vehicle is off the ground |
1058 | if (!Prim.IsColliding) | 1112 | if (!Prim.IsColliding) |
1059 | { | 1113 | { |
1060 | // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); | 1114 | // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); |
1061 | ret = new Vector3(0, 0, -distanceAboveGround); | 1115 | VehicleVelocity += new Vector3(0, 0, -distanceAboveGround); |
1062 | } | 1116 | } |
1063 | // TODO: this calculation is wrong. From the description at | 1117 | // TODO: this calculation is wrong. From the description at |
1064 | // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce | 1118 | // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce |
1065 | // has a decay factor. This says this force should | 1119 | // has a decay factor. This says this force should |
1066 | // be computed with a motor. | 1120 | // be computed with a motor. |
1067 | // TODO: add interaction with banking. | 1121 | // TODO: add interaction with banking. |
1068 | } | 1122 | VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", |
1069 | VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", | ||
1070 | Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); | 1123 | Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); |
1071 | return ret; | 1124 | */ |
1125 | |||
1126 | // Another approach is to measure if we're going up. If going up and not colliding, | ||
1127 | // the vehicle is in the air. Fix that by pushing down. | ||
1128 | if (!Prim.IsColliding && VehicleVelocity.Z > 0.1) | ||
1129 | { | ||
1130 | // Get rid of any of the velocity vector that is pushing us up. | ||
1131 | VehicleVelocity += new Vector3(0, 0, -VehicleVelocity.Z); | ||
1132 | |||
1133 | // If we're pointed up into the air, we should nose down | ||
1134 | Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; | ||
1135 | // The rotation around the Y axis is pitch up or down | ||
1136 | if (pointingDirection.Y > 0.01f) | ||
1137 | { | ||
1138 | float angularCorrectionForce = -(float)Math.Asin(pointingDirection.Y); | ||
1139 | Vector3 angularCorrectionVector = new Vector3(0f, angularCorrectionForce, 0f); | ||
1140 | // Rotate into world coordinates and apply to vehicle | ||
1141 | angularCorrectionVector *= VehicleOrientation; | ||
1142 | VehicleAddAngularForce(angularCorrectionVector); | ||
1143 | VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2},corrFrc={3},aCorr={4}", | ||
1144 | Prim.LocalID, VehicleVelocity, pointingDirection, angularCorrectionForce, angularCorrectionVector); | ||
1145 | } | ||
1146 | else | ||
1147 | { | ||
1148 | VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2}", | ||
1149 | Prim.LocalID, VehicleVelocity, pointingDirection); | ||
1150 | } | ||
1151 | } | ||
1152 | } | ||
1153 | } | ||
1154 | |||
1155 | private void ApplyGravity(float pTimeStep) | ||
1156 | { | ||
1157 | Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass; | ||
1158 | VehicleAddForce(appliedGravity); | ||
1159 | |||
1160 | VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}", | ||
1161 | Prim.LocalID, m_VehicleGravity, appliedGravity); | ||
1072 | } | 1162 | } |
1073 | 1163 | ||
1074 | // ======================================================================= | 1164 | // ======================================================================= |
@@ -1088,6 +1178,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1088 | // for preventing ground vehicles with large linear deflection, like bumper cars, | 1178 | // for preventing ground vehicles with large linear deflection, like bumper cars, |
1089 | // from climbing their linear deflection into the sky. | 1179 | // from climbing their linear deflection into the sky. |
1090 | // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement | 1180 | // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement |
1181 | // TODO: This is here because this is where ODE put it but documentation says it | ||
1182 | // is a linear effect. Where should this check go? | ||
1091 | if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) | 1183 | if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) |
1092 | { | 1184 | { |
1093 | angularMotorContribution.X = 0f; | 1185 | angularMotorContribution.X = 0f; |
@@ -1179,7 +1271,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1179 | Vector3 ret = Vector3.Zero; | 1271 | Vector3 ret = Vector3.Zero; |
1180 | 1272 | ||
1181 | // If vertical attaction timescale is reasonable | 1273 | // If vertical attaction timescale is reasonable |
1182 | if (m_verticalAttractionTimescale < m_verticalAttractionCutoff) | 1274 | if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) |
1183 | { | 1275 | { |
1184 | // Take a vector pointing up and convert it from world to vehicle relative coords. | 1276 | // Take a vector pointing up and convert it from world to vehicle relative coords. |
1185 | Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; | 1277 | Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; |
@@ -1230,7 +1322,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1230 | // this creates an over-correction and then wabbling as the target is overshot. | 1322 | // this creates an over-correction and then wabbling as the target is overshot. |
1231 | // TODO: rethink how the different correction computations inter-relate. | 1323 | // TODO: rethink how the different correction computations inter-relate. |
1232 | 1324 | ||
1233 | if (m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) | 1325 | if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) |
1234 | { | 1326 | { |
1235 | // The direction the vehicle is moving | 1327 | // The direction the vehicle is moving |
1236 | Vector3 movingDirection = VehicleVelocity; | 1328 | Vector3 movingDirection = VehicleVelocity; |
@@ -1303,7 +1395,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1303 | { | 1395 | { |
1304 | Vector3 ret = Vector3.Zero; | 1396 | Vector3 ret = Vector3.Zero; |
1305 | 1397 | ||
1306 | if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) | 1398 | if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) |
1307 | { | 1399 | { |
1308 | // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. | 1400 | // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. |
1309 | // As the vehicle rolls to the right or left, the Y value will increase from | 1401 | // As the vehicle rolls to the right or left, the Y value will increase from |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 756faed..cbd160f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | |||
@@ -152,6 +152,7 @@ public abstract class BSLinkset | |||
152 | if (IsRoot(child)) | 152 | if (IsRoot(child)) |
153 | { | 153 | { |
154 | // Cannot remove the root from a linkset. | 154 | // Cannot remove the root from a linkset. |
155 | child.PositionDisplacement = OMV.Vector3.Zero; | ||
155 | return this; | 156 | return this; |
156 | } | 157 | } |
157 | RemoveChildFromLinkset(child); | 158 | RemoveChildFromLinkset(child); |
@@ -159,6 +160,7 @@ public abstract class BSLinkset | |||
159 | } | 160 | } |
160 | 161 | ||
161 | // The child is down to a linkset of just itself | 162 | // The child is down to a linkset of just itself |
163 | child.PositionDisplacement = OMV.Vector3.Zero; | ||
162 | return BSLinkset.Factory(PhysicsScene, child); | 164 | return BSLinkset.Factory(PhysicsScene, child); |
163 | } | 165 | } |
164 | 166 | ||
@@ -310,7 +312,7 @@ public abstract class BSLinkset | |||
310 | 312 | ||
311 | foreach (BSPhysObject bp in m_children) | 313 | foreach (BSPhysObject bp in m_children) |
312 | { | 314 | { |
313 | com += bp.Position * bp.RawMass; | 315 | com += bp.Position; |
314 | } | 316 | } |
315 | com /= (m_children.Count + 1); | 317 | com /= (m_children.Count + 1); |
316 | } | 318 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index bd03d31..5a1b5c7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -40,23 +40,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
40 | // removed from the linkset. | 40 | // removed from the linkset. |
41 | sealed class BSLinksetCompoundInfo : BSLinksetInfo | 41 | sealed class BSLinksetCompoundInfo : BSLinksetInfo |
42 | { | 42 | { |
43 | public OMV.Vector3 OffsetPos; | 43 | public int Index; |
44 | public OMV.Vector3 OffsetFromRoot; | ||
45 | public OMV.Vector3 OffsetFromCenterOfMass; | ||
44 | public OMV.Quaternion OffsetRot; | 46 | public OMV.Quaternion OffsetRot; |
45 | public BSLinksetCompoundInfo(OMV.Vector3 p, OMV.Quaternion r) | 47 | public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r) |
46 | { | 48 | { |
47 | OffsetPos = p; | 49 | Index = indx; |
50 | OffsetFromRoot = p; | ||
51 | OffsetFromCenterOfMass = p; | ||
48 | OffsetRot = r; | 52 | OffsetRot = r; |
49 | } | 53 | } |
50 | public override void Clear() | 54 | public override void Clear() |
51 | { | 55 | { |
52 | OffsetPos = OMV.Vector3.Zero; | 56 | Index = 0; |
57 | OffsetFromRoot = OMV.Vector3.Zero; | ||
58 | OffsetFromCenterOfMass = OMV.Vector3.Zero; | ||
53 | OffsetRot = OMV.Quaternion.Identity; | 59 | OffsetRot = OMV.Quaternion.Identity; |
54 | } | 60 | } |
55 | public override string ToString() | 61 | public override string ToString() |
56 | { | 62 | { |
57 | StringBuilder buff = new StringBuilder(); | 63 | StringBuilder buff = new StringBuilder(); |
58 | buff.Append("<p="); | 64 | buff.Append("<i="); |
59 | buff.Append(OffsetPos.ToString()); | 65 | buff.Append(Index.ToString()); |
66 | buff.Append(",p="); | ||
67 | buff.Append(OffsetFromRoot.ToString()); | ||
68 | buff.Append(",m="); | ||
69 | buff.Append(OffsetFromCenterOfMass.ToString()); | ||
60 | buff.Append(",r="); | 70 | buff.Append(",r="); |
61 | buff.Append(OffsetRot.ToString()); | 71 | buff.Append(OffsetRot.ToString()); |
62 | buff.Append(">"); | 72 | buff.Append(">"); |
@@ -170,6 +180,8 @@ public sealed class BSLinksetCompound : BSLinkset | |||
170 | return ret; | 180 | return ret; |
171 | } | 181 | } |
172 | 182 | ||
183 | // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then. | ||
184 | // Called at taint-time. | ||
173 | public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) | 185 | public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) |
174 | { | 186 | { |
175 | // The user moving a child around requires the rebuilding of the linkset compound shape | 187 | // The user moving a child around requires the rebuilding of the linkset compound shape |
@@ -182,6 +194,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
182 | && !physicalUpdate | 194 | && !physicalUpdate |
183 | && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) | 195 | && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) |
184 | { | 196 | { |
197 | // TODO: replace this with are calculation of the child prim's orientation and pos. | ||
185 | updated.LinksetInfo = null; | 198 | updated.LinksetInfo = null; |
186 | ScheduleRebuild(updated); | 199 | ScheduleRebuild(updated); |
187 | } | 200 | } |
@@ -230,7 +243,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
230 | if (inTaintTime) | 243 | if (inTaintTime) |
231 | { | 244 | { |
232 | OMV.Vector3 oldPos = child.RawPosition; | 245 | OMV.Vector3 oldPos = child.RawPosition; |
233 | child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos; | 246 | child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetFromRoot; |
234 | child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; | 247 | child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; |
235 | DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", | 248 | DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", |
236 | child.LocalID, oldPos, lci, child.RawPosition); | 249 | child.LocalID, oldPos, lci, child.RawPosition); |
@@ -238,7 +251,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
238 | else | 251 | else |
239 | { | 252 | { |
240 | // TaintedObject is not used here so the raw position is set now and not at taint-time. | 253 | // TaintedObject is not used here so the raw position is set now and not at taint-time. |
241 | child.Position = LinksetRoot.RawPosition + lci.OffsetPos; | 254 | child.Position = LinksetRoot.RawPosition + lci.OffsetFromRoot; |
242 | child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; | 255 | child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; |
243 | } | 256 | } |
244 | } | 257 | } |
@@ -306,6 +319,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
306 | // Constraint linksets are rebuilt every time. | 319 | // Constraint linksets are rebuilt every time. |
307 | // Note that this works for rebuilding just the root after a linkset is taken apart. | 320 | // Note that this works for rebuilding just the root after a linkset is taken apart. |
308 | // Called at taint time!! | 321 | // Called at taint time!! |
322 | private bool disableCOM = true; // disable until we get this debugged | ||
309 | private void RecomputeLinksetCompound() | 323 | private void RecomputeLinksetCompound() |
310 | { | 324 | { |
311 | try | 325 | try |
@@ -316,10 +330,34 @@ public sealed class BSLinksetCompound : BSLinkset | |||
316 | // Cause the root shape to be rebuilt as a compound object with just the root in it | 330 | // Cause the root shape to be rebuilt as a compound object with just the root in it |
317 | LinksetRoot.ForceBodyShapeRebuild(true); | 331 | LinksetRoot.ForceBodyShapeRebuild(true); |
318 | 332 | ||
333 | // The center of mass for the linkset is the geometric center of the group. | ||
334 | // Compute a displacement for each component so it is relative to the center-of-mass. | ||
335 | // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass | ||
336 | OMV.Vector3 centerOfMass; | ||
337 | OMV.Vector3 centerDisplacement = OMV.Vector3.Zero; | ||
338 | if (disableCOM) // DEBUG DEBUG | ||
339 | { // DEBUG DEBUG | ||
340 | centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG | ||
341 | LinksetRoot.PositionDisplacement = OMV.Vector3.Zero; | ||
342 | } // DEBUG DEBUG | ||
343 | else | ||
344 | { | ||
345 | centerOfMass = ComputeLinksetGeometricCenter(); | ||
346 | centerDisplacement = centerOfMass - LinksetRoot.RawPosition; | ||
347 | |||
348 | // Since we're displacing the center of the shape, we need to move the body in the world | ||
349 | LinksetRoot.PositionDisplacement = centerDisplacement; | ||
350 | |||
351 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); | ||
352 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", | ||
353 | LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); | ||
354 | } | ||
355 | |||
319 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", | 356 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", |
320 | LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); | 357 | LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); |
321 | 358 | ||
322 | // Add a shape for each of the other children in the linkset | 359 | // Add a shape for each of the other children in the linkset |
360 | int memberIndex = 1; | ||
323 | ForEachMember(delegate(BSPhysObject cPrim) | 361 | ForEachMember(delegate(BSPhysObject cPrim) |
324 | { | 362 | { |
325 | if (!IsRoot(cPrim)) | 363 | if (!IsRoot(cPrim)) |
@@ -331,19 +369,21 @@ public sealed class BSLinksetCompound : BSLinkset | |||
331 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; | 369 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; |
332 | if (lci == null) | 370 | if (lci == null) |
333 | { | 371 | { |
334 | // Each child position and rotation is given relative to the root. | 372 | // Each child position and rotation is given relative to the center-of-mass. |
335 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); | 373 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); |
336 | OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; | 374 | OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; |
375 | OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement; | ||
337 | OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; | 376 | OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; |
338 | 377 | ||
339 | // Save relative position for recomputing child's world position after moving linkset. | 378 | // Save relative position for recomputing child's world position after moving linkset. |
340 | lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); | 379 | lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot); |
380 | lci.OffsetFromRoot = displacementFromRoot; | ||
341 | cPrim.LinksetInfo = lci; | 381 | cPrim.LinksetInfo = lci; |
342 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); | 382 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); |
343 | } | 383 | } |
344 | 384 | ||
345 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", | 385 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}", |
346 | LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); | 386 | LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci); |
347 | 387 | ||
348 | if (cPrim.PhysShape.isNativeShape) | 388 | if (cPrim.PhysShape.isNativeShape) |
349 | { | 389 | { |
@@ -359,7 +399,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
359 | PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); | 399 | PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); |
360 | BulletShape newShape = cPrim.PhysShape; | 400 | BulletShape newShape = cPrim.PhysShape; |
361 | cPrim.PhysShape = saveShape; | 401 | cPrim.PhysShape = saveShape; |
362 | PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot); | 402 | PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot); |
363 | } | 403 | } |
364 | else | 404 | else |
365 | { | 405 | { |
@@ -371,8 +411,10 @@ public sealed class BSLinksetCompound : BSLinkset | |||
371 | PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", | 411 | PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", |
372 | LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); | 412 | LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); |
373 | } | 413 | } |
374 | PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); | 414 | PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetFromCenterOfMass, lci.OffsetRot); |
375 | } | 415 | } |
416 | lci.Index = memberIndex; | ||
417 | memberIndex++; | ||
376 | } | 418 | } |
377 | return false; // 'false' says to move onto the next child in the list | 419 | return false; // 'false' says to move onto the next child in the list |
378 | }); | 420 | }); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 23d573f..27ff047 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -80,6 +80,7 @@ public static class BSParam | |||
80 | public static float AvatarStepForceFactor { get; private set; } | 80 | public static float AvatarStepForceFactor { get; private set; } |
81 | 81 | ||
82 | public static float VehicleAngularDamping { get; private set; } | 82 | public static float VehicleAngularDamping { get; private set; } |
83 | public static float VehicleDebuggingEnabled { get; private set; } | ||
83 | 84 | ||
84 | public static float LinksetImplementation { get; private set; } | 85 | public static float LinksetImplementation { get; private set; } |
85 | public static float LinkConstraintUseFrameOffset { get; private set; } | 86 | public static float LinkConstraintUseFrameOffset { get; private set; } |
@@ -427,6 +428,11 @@ public static class BSParam | |||
427 | (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, | 428 | (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, |
428 | (s) => { return VehicleAngularDamping; }, | 429 | (s) => { return VehicleAngularDamping; }, |
429 | (s,p,l,v) => { VehicleAngularDamping = v; } ), | 430 | (s,p,l,v) => { VehicleAngularDamping = v; } ), |
431 | new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging", | ||
432 | ConfigurationParameters.numericFalse, | ||
433 | (s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, | ||
434 | (s) => { return VehicleDebuggingEnabled; }, | ||
435 | (s,p,l,v) => { VehicleDebuggingEnabled = v; } ), | ||
430 | 436 | ||
431 | new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", | 437 | new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", |
432 | 0f, | 438 | 0f, |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index e8575f6..821f470 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -73,6 +73,8 @@ public abstract class BSPhysObject : PhysicsActor | |||
73 | 73 | ||
74 | // A linkset of just me | 74 | // A linkset of just me |
75 | Linkset = BSLinkset.Factory(PhysicsScene, this); | 75 | Linkset = BSLinkset.Factory(PhysicsScene, this); |
76 | PositionDisplacement = OMV.Vector3.Zero; | ||
77 | |||
76 | LastAssetBuildFailed = false; | 78 | LastAssetBuildFailed = false; |
77 | 79 | ||
78 | // Default material type | 80 | // Default material type |
@@ -135,6 +137,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
135 | public virtual OMV.Vector3 Scale { get; set; } | 137 | public virtual OMV.Vector3 Scale { get; set; } |
136 | public abstract bool IsSolid { get; } | 138 | public abstract bool IsSolid { get; } |
137 | public abstract bool IsStatic { get; } | 139 | public abstract bool IsStatic { get; } |
140 | public abstract bool IsSelected { get; } | ||
138 | 141 | ||
139 | // Materialness | 142 | // Materialness |
140 | public MaterialAttributes.Material Material { get; private set; } | 143 | public MaterialAttributes.Material Material { get; private set; } |
@@ -156,6 +159,14 @@ public abstract class BSPhysObject : PhysicsActor | |||
156 | public abstract OMV.Vector3 RawPosition { get; set; } | 159 | public abstract OMV.Vector3 RawPosition { get; set; } |
157 | public abstract OMV.Vector3 ForcePosition { get; set; } | 160 | public abstract OMV.Vector3 ForcePosition { get; set; } |
158 | 161 | ||
162 | // Position is what the simulator thinks the positions of the prim is. | ||
163 | // Because Bullet needs the zero coordinate to be the center of mass of the linkset, | ||
164 | // sometimes it is necessary to displace the position the physics engine thinks | ||
165 | // the position is. PositionDisplacement must be added and removed from the | ||
166 | // position as the simulator position is stored and fetched from the physics | ||
167 | // engine. | ||
168 | public virtual OMV.Vector3 PositionDisplacement { get; set; } | ||
169 | |||
159 | public abstract OMV.Quaternion RawOrientation { get; set; } | 170 | public abstract OMV.Quaternion RawOrientation { get; set; } |
160 | public abstract OMV.Quaternion ForceOrientation { get; set; } | 171 | public abstract OMV.Quaternion ForceOrientation { get; set; } |
161 | 172 | ||
@@ -371,10 +382,13 @@ public abstract class BSPhysObject : PhysicsActor | |||
371 | { | 382 | { |
372 | string identifier = op + "-" + id.ToString(); | 383 | string identifier = op + "-" + id.ToString(); |
373 | 384 | ||
374 | // Clean out any existing action | 385 | lock (RegisteredActions) |
375 | UnRegisterPreStepAction(op, id); | 386 | { |
387 | // Clean out any existing action | ||
388 | UnRegisterPreStepAction(op, id); | ||
376 | 389 | ||
377 | RegisteredActions[identifier] = actn; | 390 | RegisteredActions[identifier] = actn; |
391 | } | ||
378 | PhysicsScene.BeforeStep += actn; | 392 | PhysicsScene.BeforeStep += actn; |
379 | DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); | 393 | DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); |
380 | } | 394 | } |
@@ -384,22 +398,28 @@ public abstract class BSPhysObject : PhysicsActor | |||
384 | { | 398 | { |
385 | string identifier = op + "-" + id.ToString(); | 399 | string identifier = op + "-" + id.ToString(); |
386 | bool removed = false; | 400 | bool removed = false; |
387 | if (RegisteredActions.ContainsKey(identifier)) | 401 | lock (RegisteredActions) |
388 | { | 402 | { |
389 | PhysicsScene.BeforeStep -= RegisteredActions[identifier]; | 403 | if (RegisteredActions.ContainsKey(identifier)) |
390 | RegisteredActions.Remove(identifier); | 404 | { |
391 | removed = true; | 405 | PhysicsScene.BeforeStep -= RegisteredActions[identifier]; |
406 | RegisteredActions.Remove(identifier); | ||
407 | removed = true; | ||
408 | } | ||
392 | } | 409 | } |
393 | DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed); | 410 | DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed); |
394 | } | 411 | } |
395 | 412 | ||
396 | protected void UnRegisterAllPreStepActions() | 413 | protected void UnRegisterAllPreStepActions() |
397 | { | 414 | { |
398 | foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredActions) | 415 | lock (RegisteredActions) |
399 | { | 416 | { |
400 | PhysicsScene.BeforeStep -= kvp.Value; | 417 | foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredActions) |
418 | { | ||
419 | PhysicsScene.BeforeStep -= kvp.Value; | ||
420 | } | ||
421 | RegisteredActions.Clear(); | ||
401 | } | 422 | } |
402 | RegisteredActions.Clear(); | ||
403 | DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID); | 423 | DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID); |
404 | } | 424 | } |
405 | 425 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs index 65be52a..9442854 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs | |||
@@ -59,7 +59,7 @@ public class BSPlugin : IPhysicsPlugin | |||
59 | { | 59 | { |
60 | if (_mScene == null) | 60 | if (_mScene == null) |
61 | { | 61 | { |
62 | _mScene = new BSScene(sceneIdentifier); | 62 | _mScene = new BSScene(GetName(), sceneIdentifier); |
63 | } | 63 | } |
64 | return (_mScene); | 64 | return (_mScene); |
65 | } | 65 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 400d5d6..79fe632 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -50,7 +50,10 @@ public sealed class BSPrim : BSPhysObject | |||
50 | private bool _grabbed; | 50 | private bool _grabbed; |
51 | private bool _isSelected; | 51 | private bool _isSelected; |
52 | private bool _isVolumeDetect; | 52 | private bool _isVolumeDetect; |
53 | |||
54 | // _position is what the simulator thinks the positions of the prim is. | ||
53 | private OMV.Vector3 _position; | 55 | private OMV.Vector3 _position; |
56 | |||
54 | private float _mass; // the mass of this object | 57 | private float _mass; // the mass of this object |
55 | private float _density; | 58 | private float _density; |
56 | private OMV.Vector3 _force; | 59 | private OMV.Vector3 _force; |
@@ -169,6 +172,7 @@ public sealed class BSPrim : BSPhysObject | |||
169 | public override PrimitiveBaseShape Shape { | 172 | public override PrimitiveBaseShape Shape { |
170 | set { | 173 | set { |
171 | BaseShape = value; | 174 | BaseShape = value; |
175 | LastAssetBuildFailed = false; | ||
172 | ForceBodyShapeRebuild(false); | 176 | ForceBodyShapeRebuild(false); |
173 | } | 177 | } |
174 | } | 178 | } |
@@ -178,7 +182,6 @@ public sealed class BSPrim : BSPhysObject | |||
178 | 182 | ||
179 | public override bool ForceBodyShapeRebuild(bool inTaintTime) | 183 | public override bool ForceBodyShapeRebuild(bool inTaintTime) |
180 | { | 184 | { |
181 | LastAssetBuildFailed = false; | ||
182 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate() | 185 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate() |
183 | { | 186 | { |
184 | _mass = CalculateMass(); // changing the shape changes the mass | 187 | _mass = CalculateMass(); // changing the shape changes the mass |
@@ -204,6 +207,10 @@ public sealed class BSPrim : BSPhysObject | |||
204 | } | 207 | } |
205 | } | 208 | } |
206 | } | 209 | } |
210 | public override bool IsSelected | ||
211 | { | ||
212 | get { return _isSelected; } | ||
213 | } | ||
207 | public override void CrossingFailure() { return; } | 214 | public override void CrossingFailure() { return; } |
208 | 215 | ||
209 | // link me to the specified parent | 216 | // link me to the specified parent |
@@ -290,7 +297,7 @@ public sealed class BSPrim : BSPhysObject | |||
290 | */ | 297 | */ |
291 | 298 | ||
292 | // don't do the GetObjectPosition for root elements because this function is called a zillion times. | 299 | // don't do the GetObjectPosition for root elements because this function is called a zillion times. |
293 | // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody); | 300 | // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement; |
294 | return _position; | 301 | return _position; |
295 | } | 302 | } |
296 | set { | 303 | set { |
@@ -316,18 +323,37 @@ public sealed class BSPrim : BSPhysObject | |||
316 | } | 323 | } |
317 | public override OMV.Vector3 ForcePosition { | 324 | public override OMV.Vector3 ForcePosition { |
318 | get { | 325 | get { |
319 | _position = PhysicsScene.PE.GetPosition(PhysBody); | 326 | _position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement; |
320 | return _position; | 327 | return _position; |
321 | } | 328 | } |
322 | set { | 329 | set { |
323 | _position = value; | 330 | _position = value; |
324 | if (PhysBody.HasPhysicalBody) | 331 | if (PhysBody.HasPhysicalBody) |
325 | { | 332 | { |
326 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | 333 | PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); |
327 | ActivateIfPhysical(false); | 334 | ActivateIfPhysical(false); |
328 | } | 335 | } |
329 | } | 336 | } |
330 | } | 337 | } |
338 | // Override to have position displacement immediately update the physical position. | ||
339 | // A feeble attempt to keep the sim and physical positions in sync | ||
340 | // Must be called at taint time. | ||
341 | public override OMV.Vector3 PositionDisplacement | ||
342 | { | ||
343 | get | ||
344 | { | ||
345 | return base.PositionDisplacement; | ||
346 | } | ||
347 | set | ||
348 | { | ||
349 | base.PositionDisplacement = value; | ||
350 | PhysicsScene.TaintedObject(PhysicsScene.InTaintTime, "BSPrim.setPosition", delegate() | ||
351 | { | ||
352 | if (PhysBody.HasPhysicalBody) | ||
353 | PhysicsScene.PE.SetTranslation(PhysBody, _position + base.PositionDisplacement, _orientation); | ||
354 | }); | ||
355 | } | ||
356 | } | ||
331 | 357 | ||
332 | // Check that the current position is sane and, if not, modify the position to make it so. | 358 | // Check that the current position is sane and, if not, modify the position to make it so. |
333 | // Check for being below terrain and being out of bounds. | 359 | // Check for being below terrain and being out of bounds. |
@@ -336,7 +362,7 @@ public sealed class BSPrim : BSPhysObject | |||
336 | { | 362 | { |
337 | bool ret = false; | 363 | bool ret = false; |
338 | 364 | ||
339 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) | 365 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) |
340 | { | 366 | { |
341 | // The physical object is out of the known/simulated area. | 367 | // The physical object is out of the known/simulated area. |
342 | // Upper levels of code will handle the transition to other areas so, for | 368 | // Upper levels of code will handle the transition to other areas so, for |
@@ -350,8 +376,11 @@ public sealed class BSPrim : BSPhysObject | |||
350 | { | 376 | { |
351 | DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); | 377 | DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); |
352 | float targetHeight = terrainHeight + (Size.Z / 2f); | 378 | float targetHeight = terrainHeight + (Size.Z / 2f); |
353 | // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. | 379 | // If the object is below ground it just has to be moved up because pushing will |
354 | upForce.Z = (terrainHeight - RawPosition.Z) * 1f; | 380 | // not get it through the terrain |
381 | _position.Z = targetHeight; | ||
382 | if (inTaintTime) | ||
383 | ForcePosition = _position; | ||
355 | ret = true; | 384 | ret = true; |
356 | } | 385 | } |
357 | 386 | ||
@@ -363,20 +392,15 @@ public sealed class BSPrim : BSPhysObject | |||
363 | { | 392 | { |
364 | // Upforce proportional to the distance away from the water. Correct the error in 1 sec. | 393 | // Upforce proportional to the distance away from the water. Correct the error in 1 sec. |
365 | upForce.Z = (waterHeight - RawPosition.Z) * 1f; | 394 | upForce.Z = (waterHeight - RawPosition.Z) * 1f; |
395 | |||
396 | // Apply upforce and overcome gravity. | ||
397 | OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; | ||
398 | DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); | ||
399 | AddForce(correctionForce, false, inTaintTime); | ||
366 | ret = true; | 400 | ret = true; |
367 | } | 401 | } |
368 | } | 402 | } |
369 | 403 | ||
370 | // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. | ||
371 | // TODO: This should be intergrated with a geneal physics action mechanism. | ||
372 | // TODO: This should be moderated with PID'ness. | ||
373 | if (ret) | ||
374 | { | ||
375 | // Apply upforce and overcome gravity. | ||
376 | OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; | ||
377 | DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); | ||
378 | AddForce(correctionForce, false, inTaintTime); | ||
379 | } | ||
380 | return ret; | 404 | return ret; |
381 | } | 405 | } |
382 | 406 | ||
@@ -410,7 +434,7 @@ public sealed class BSPrim : BSPhysObject | |||
410 | } | 434 | } |
411 | else | 435 | else |
412 | { | 436 | { |
413 | OMV.Vector3 grav = ComputeGravity(); | 437 | OMV.Vector3 grav = ComputeGravity(Buoyancy); |
414 | 438 | ||
415 | if (inWorld) | 439 | if (inWorld) |
416 | { | 440 | { |
@@ -445,12 +469,12 @@ public sealed class BSPrim : BSPhysObject | |||
445 | } | 469 | } |
446 | 470 | ||
447 | // Return what gravity should be set to this very moment | 471 | // Return what gravity should be set to this very moment |
448 | private OMV.Vector3 ComputeGravity() | 472 | public OMV.Vector3 ComputeGravity(float buoyancy) |
449 | { | 473 | { |
450 | OMV.Vector3 ret = PhysicsScene.DefaultGravity; | 474 | OMV.Vector3 ret = PhysicsScene.DefaultGravity; |
451 | 475 | ||
452 | if (!IsStatic) | 476 | if (!IsStatic) |
453 | ret *= (1f - Buoyancy); | 477 | ret *= (1f - buoyancy); |
454 | 478 | ||
455 | return ret; | 479 | return ret; |
456 | } | 480 | } |
@@ -586,6 +610,7 @@ public sealed class BSPrim : BSPhysObject | |||
586 | _velocity = value; | 610 | _velocity = value; |
587 | if (PhysBody.HasPhysicalBody) | 611 | if (PhysBody.HasPhysicalBody) |
588 | { | 612 | { |
613 | DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, _velocity); | ||
589 | PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); | 614 | PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); |
590 | ActivateIfPhysical(false); | 615 | ActivateIfPhysical(false); |
591 | } | 616 | } |
@@ -650,12 +675,7 @@ public sealed class BSPrim : BSPhysObject | |||
650 | 675 | ||
651 | PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() | 676 | PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() |
652 | { | 677 | { |
653 | if (PhysBody.HasPhysicalBody) | 678 | ForceOrientation = _orientation; |
654 | { | ||
655 | // _position = PhysicsScene.PE.GetObjectPosition(PhysicsScene.World, BSBody); | ||
656 | // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); | ||
657 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | ||
658 | } | ||
659 | }); | 679 | }); |
660 | } | 680 | } |
661 | } | 681 | } |
@@ -670,7 +690,8 @@ public sealed class BSPrim : BSPhysObject | |||
670 | set | 690 | set |
671 | { | 691 | { |
672 | _orientation = value; | 692 | _orientation = value; |
673 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | 693 | if (PhysBody.HasPhysicalBody) |
694 | PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); | ||
674 | } | 695 | } |
675 | } | 696 | } |
676 | public override int PhysicsActorType { | 697 | public override int PhysicsActorType { |
@@ -809,7 +830,7 @@ public sealed class BSPrim : BSPhysObject | |||
809 | // PhysicsScene.PE.ClearAllForces(BSBody); | 830 | // PhysicsScene.PE.ClearAllForces(BSBody); |
810 | 831 | ||
811 | // For good measure, make sure the transform is set through to the motion state | 832 | // For good measure, make sure the transform is set through to the motion state |
812 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | 833 | PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); |
813 | 834 | ||
814 | // Center of mass is at the center of the object | 835 | // Center of mass is at the center of the object |
815 | // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation); | 836 | // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation); |
@@ -1153,33 +1174,70 @@ public sealed class BSPrim : BSPhysObject | |||
1153 | // This added force will only last the next simulation tick. | 1174 | // This added force will only last the next simulation tick. |
1154 | public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { | 1175 | public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { |
1155 | // for an object, doesn't matter if force is a pushforce or not | 1176 | // for an object, doesn't matter if force is a pushforce or not |
1156 | if (!IsStatic && force.IsFinite()) | 1177 | if (!IsStatic) |
1157 | { | 1178 | { |
1158 | float magnitude = force.Length(); | 1179 | if (force.IsFinite()) |
1159 | if (magnitude > BSParam.MaxAddForceMagnitude) | ||
1160 | { | 1180 | { |
1161 | // Force has a limit | 1181 | float magnitude = force.Length(); |
1162 | force = force / magnitude * BSParam.MaxAddForceMagnitude; | 1182 | if (magnitude > BSParam.MaxAddForceMagnitude) |
1163 | } | 1183 | { |
1184 | // Force has a limit | ||
1185 | force = force / magnitude * BSParam.MaxAddForceMagnitude; | ||
1186 | } | ||
1164 | 1187 | ||
1165 | OMV.Vector3 addForce = force; | 1188 | OMV.Vector3 addForce = force; |
1166 | // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); | 1189 | // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); |
1167 | 1190 | ||
1168 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() | 1191 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() |
1169 | { | ||
1170 | // Bullet adds this central force to the total force for this tick | ||
1171 | DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); | ||
1172 | if (PhysBody.HasPhysicalBody) | ||
1173 | { | 1192 | { |
1174 | PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); | 1193 | // Bullet adds this central force to the total force for this tick |
1175 | ActivateIfPhysical(false); | 1194 | DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); |
1176 | } | 1195 | if (PhysBody.HasPhysicalBody) |
1177 | }); | 1196 | { |
1197 | PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); | ||
1198 | ActivateIfPhysical(false); | ||
1199 | } | ||
1200 | }); | ||
1201 | } | ||
1202 | else | ||
1203 | { | ||
1204 | m_log.WarnFormat("{0}: AddForce: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); | ||
1205 | return; | ||
1206 | } | ||
1178 | } | 1207 | } |
1179 | else | 1208 | } |
1209 | |||
1210 | public void AddForceImpulse(OMV.Vector3 impulse, bool pushforce, bool inTaintTime) { | ||
1211 | // for an object, doesn't matter if force is a pushforce or not | ||
1212 | if (!IsStatic) | ||
1180 | { | 1213 | { |
1181 | m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); | 1214 | if (impulse.IsFinite()) |
1182 | return; | 1215 | { |
1216 | float magnitude = impulse.Length(); | ||
1217 | if (magnitude > BSParam.MaxAddForceMagnitude) | ||
1218 | { | ||
1219 | // Force has a limit | ||
1220 | impulse = impulse / magnitude * BSParam.MaxAddForceMagnitude; | ||
1221 | } | ||
1222 | |||
1223 | // DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse); | ||
1224 | OMV.Vector3 addImpulse = impulse; | ||
1225 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate() | ||
1226 | { | ||
1227 | // Bullet adds this impulse immediately to the velocity | ||
1228 | DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse); | ||
1229 | if (PhysBody.HasPhysicalBody) | ||
1230 | { | ||
1231 | PhysicsScene.PE.ApplyCentralImpulse(PhysBody, addImpulse); | ||
1232 | ActivateIfPhysical(false); | ||
1233 | } | ||
1234 | }); | ||
1235 | } | ||
1236 | else | ||
1237 | { | ||
1238 | m_log.WarnFormat("{0}: AddForceImpulse: Got a NaN impulse applied to a prim. LocalID={1}", LogHeader, LocalID); | ||
1239 | return; | ||
1240 | } | ||
1183 | } | 1241 | } |
1184 | } | 1242 | } |
1185 | 1243 | ||
@@ -1561,21 +1619,6 @@ public sealed class BSPrim : BSPhysObject | |||
1561 | 1619 | ||
1562 | // The physics engine says that properties have updated. Update same and inform | 1620 | // The physics engine says that properties have updated. Update same and inform |
1563 | // the world that things have changed. | 1621 | // the world that things have changed. |
1564 | // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate() | ||
1565 | enum UpdatedProperties { | ||
1566 | Position = 1 << 0, | ||
1567 | Rotation = 1 << 1, | ||
1568 | Velocity = 1 << 2, | ||
1569 | Acceleration = 1 << 3, | ||
1570 | RotationalVel = 1 << 4 | ||
1571 | } | ||
1572 | |||
1573 | const float ROTATION_TOLERANCE = 0.01f; | ||
1574 | const float VELOCITY_TOLERANCE = 0.001f; | ||
1575 | const float POSITION_TOLERANCE = 0.05f; | ||
1576 | const float ACCELERATION_TOLERANCE = 0.01f; | ||
1577 | const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; | ||
1578 | |||
1579 | public override void UpdateProperties(EntityProperties entprop) | 1622 | public override void UpdateProperties(EntityProperties entprop) |
1580 | { | 1623 | { |
1581 | // Updates only for individual prims and for the root object of a linkset. | 1624 | // Updates only for individual prims and for the root object of a linkset. |
@@ -1588,7 +1631,8 @@ public sealed class BSPrim : BSPhysObject | |||
1588 | entprop.RotationalVelocity = OMV.Vector3.Zero; | 1631 | entprop.RotationalVelocity = OMV.Vector3.Zero; |
1589 | } | 1632 | } |
1590 | 1633 | ||
1591 | // Assign directly to the local variables so the normal set action does not happen | 1634 | // Assign directly to the local variables so the normal set actions do not happen |
1635 | entprop.Position -= PositionDisplacement; | ||
1592 | _position = entprop.Position; | 1636 | _position = entprop.Position; |
1593 | _orientation = entprop.Rotation; | 1637 | _orientation = entprop.Rotation; |
1594 | _velocity = entprop.Velocity; | 1638 | _velocity = entprop.Velocity; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 7017194..e0b4992 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -167,11 +167,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
167 | public bool VehiclePhysicalLoggingEnabled { get; private set; } | 167 | public bool VehiclePhysicalLoggingEnabled { get; private set; } |
168 | 168 | ||
169 | #region Construction and Initialization | 169 | #region Construction and Initialization |
170 | public BSScene(string identifier) | 170 | public BSScene(string engineType, string identifier) |
171 | { | 171 | { |
172 | m_initialized = false; | 172 | m_initialized = false; |
173 | // we are passed the name of the region we're working for. | 173 | |
174 | // The name of the region we're working for is passed to us. Keep for identification. | ||
174 | RegionName = identifier; | 175 | RegionName = identifier; |
176 | |||
177 | // Set identifying variables in the PhysicsScene interface. | ||
178 | EngineType = engineType; | ||
179 | Name = EngineType + "/" + RegionName; | ||
175 | } | 180 | } |
176 | 181 | ||
177 | public override void Initialise(IMesher meshmerizer, IConfigSource config) | 182 | public override void Initialise(IMesher meshmerizer, IConfigSource config) |
@@ -382,12 +387,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
382 | if (!m_initialized) return null; | 387 | if (!m_initialized) return null; |
383 | 388 | ||
384 | BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); | 389 | BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); |
385 | lock (PhysObjects) PhysObjects.Add(localID, actor); | 390 | lock (PhysObjects) |
391 | PhysObjects.Add(localID, actor); | ||
386 | 392 | ||
387 | // TODO: Remove kludge someday. | 393 | // TODO: Remove kludge someday. |
388 | // We must generate a collision for avatars whether they collide or not. | 394 | // We must generate a collision for avatars whether they collide or not. |
389 | // This is required by OpenSim to update avatar animations, etc. | 395 | // This is required by OpenSim to update avatar animations, etc. |
390 | lock (m_avatars) m_avatars.Add(actor); | 396 | lock (m_avatars) |
397 | m_avatars.Add(actor); | ||
391 | 398 | ||
392 | return actor; | 399 | return actor; |
393 | } | 400 | } |
@@ -403,9 +410,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
403 | { | 410 | { |
404 | try | 411 | try |
405 | { | 412 | { |
406 | lock (PhysObjects) PhysObjects.Remove(actor.LocalID); | 413 | lock (PhysObjects) |
414 | PhysObjects.Remove(bsactor.LocalID); | ||
407 | // Remove kludge someday | 415 | // Remove kludge someday |
408 | lock (m_avatars) m_avatars.Remove(bsactor); | 416 | lock (m_avatars) |
417 | m_avatars.Remove(bsactor); | ||
409 | } | 418 | } |
410 | catch (Exception e) | 419 | catch (Exception e) |
411 | { | 420 | { |
@@ -414,6 +423,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
414 | bsactor.Destroy(); | 423 | bsactor.Destroy(); |
415 | // bsactor.dispose(); | 424 | // bsactor.dispose(); |
416 | } | 425 | } |
426 | else | ||
427 | { | ||
428 | m_log.ErrorFormat("{0}: Requested to remove avatar that is not a BSCharacter. ID={1}, type={2}", | ||
429 | LogHeader, actor.LocalID, actor.GetType().Name); | ||
430 | } | ||
417 | } | 431 | } |
418 | 432 | ||
419 | public override void RemovePrim(PhysicsActor prim) | 433 | public override void RemovePrim(PhysicsActor prim) |
@@ -486,6 +500,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
486 | ProcessTaints(); | 500 | ProcessTaints(); |
487 | 501 | ||
488 | // Some of the physical objects requre individual, pre-step calls | 502 | // Some of the physical objects requre individual, pre-step calls |
503 | // (vehicles and avatar movement, in particular) | ||
489 | TriggerPreStepEvent(timeStep); | 504 | TriggerPreStepEvent(timeStep); |
490 | 505 | ||
491 | // the prestep actions might have added taints | 506 | // the prestep actions might have added taints |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index f0c6b99..addab29 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -906,7 +906,7 @@ public sealed class BSShapeCollection : IDisposable | |||
906 | } | 906 | } |
907 | } | 907 | } |
908 | 908 | ||
909 | // While we figure out the real problem, stick a simple native shape on the object. | 909 | // While we figure out the real problem, stick in a simple box for the object. |
910 | BulletShape fillinShape = | 910 | BulletShape fillinShape = |
911 | BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); | 911 | BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); |
912 | 912 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 29bd4e4..59cbab9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | |||
@@ -1,12 +1,17 @@ | |||
1 | CURRENT PRIORITIES | 1 | CURRENT PRIORITIES |
2 | ================================================= | 2 | ================================================= |
3 | Nebadon vehicles turning funny in arena | ||
4 | limitMotorUp calibration (more down?) | ||
5 | Vehicle angular vertical attraction | ||
6 | Vehicle angular deflection | ||
7 | Preferred orientation angular correction fix | ||
8 | vehicle angular banking | ||
3 | Avatars walking up stairs (HALF DONE) | 9 | Avatars walking up stairs (HALF DONE) |
10 | Radius of the capsule affects ability to climb edges. | ||
4 | Vehicle movement on terrain smoothness | 11 | Vehicle movement on terrain smoothness |
5 | limitMotorUp calibration (more down?) | ||
6 | Preferred orientation angular correction fix | ||
7 | Surfboard go wonky when turning | 12 | Surfboard go wonky when turning |
8 | Angular motor direction is global coordinates rather than local coordinates? | 13 | Angular motor direction is global coordinates rather than local coordinates? |
9 | Boats float low in the water | 14 | Boats float low in the water (DONE) |
10 | Avatar movement | 15 | Avatar movement |
11 | flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE) | 16 | flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE) |
12 | walking up stairs is not calibrated correctly (stairs out of Kepler cabin) | 17 | walking up stairs is not calibrated correctly (stairs out of Kepler cabin) |
@@ -33,19 +38,15 @@ CRASHES | |||
33 | 38 | ||
34 | VEHICLES TODO LIST: | 39 | VEHICLES TODO LIST: |
35 | ================================================= | 40 | ================================================= |
36 | Angular motor direction is global coordinates rather than local coordinates | ||
37 | Border crossing with linked vehicle causes crash | 41 | Border crossing with linked vehicle causes crash |
38 | Vehicles (Move smoothly) | 42 | Vehicles (Move smoothly) |
39 | Add vehicle collisions so IsColliding is properly reported. | ||
40 | Needed for banking, limitMotorUp, movementLimiting, ... | ||
41 | VehicleAddForce is not scaled by the simulation step but it is only | ||
42 | applied for one step. Should it be scaled? | ||
43 | Some vehicles should not be able to turn if no speed or off ground. | 43 | Some vehicles should not be able to turn if no speed or off ground. |
44 | Cannot edit/move a vehicle being ridden: it jumps back to the origional position. | 44 | Cannot edit/move a vehicle being ridden: it jumps back to the origional position. |
45 | Neb car jiggling left and right | 45 | Neb car jiggling left and right |
46 | Happens on terrain and any other mesh object. Flat cubes are much smoother. | 46 | Happens on terrain and any other mesh object. Flat cubes are much smoother. |
47 | This has been reduced but not eliminated. | 47 | This has been reduced but not eliminated. |
48 | Implement referenceFrame for all the motion routines. | 48 | Implement referenceFrame for all the motion routines. |
49 | For limitMotorUp, use raycast down to find if vehicle is in the air. | ||
49 | Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. | 50 | Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. |
50 | Verify that angular motion specified around Z moves in the vehicle coordinates. | 51 | Verify that angular motion specified around Z moves in the vehicle coordinates. |
51 | Verify llGetVel() is returning a smooth and good value for vehicle movement. | 52 | Verify llGetVel() is returning a smooth and good value for vehicle movement. |
@@ -54,14 +55,13 @@ Implement function efficiency for lineaar and angular motion. | |||
54 | After getting off a vehicle, the root prim is phantom (can be walked through) | 55 | After getting off a vehicle, the root prim is phantom (can be walked through) |
55 | Need to force a position update for the root prim after compound shape destruction | 56 | Need to force a position update for the root prim after compound shape destruction |
56 | Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) | 57 | Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) |
57 | For limitMotorUp, use raycast down to find if vehicle is in the air. | ||
58 | Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties(). | 58 | Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties(). |
59 | A kludge that isn't fixing the real problem of Bullet adding extra motion. | 59 | A kludge that isn't fixing the real problem of Bullet adding extra motion. |
60 | Incorporate inter-relationship of angular corrections. For instance, angularDeflection | 60 | Incorporate inter-relationship of angular corrections. For instance, angularDeflection |
61 | and angularMotorUp will compute same X or Y correction. When added together | 61 | and angularMotorUp will compute same X or Y correction. When added together |
62 | creates over-correction and over-shoot and wabbling. | 62 | creates over-correction and over-shoot and wabbling. |
63 | 63 | ||
64 | BULLETSIM TODO LIST: | 64 | GENERAL TODO LIST: |
65 | ================================================= | 65 | ================================================= |
66 | Implement an avatar mesh shape. The Bullet capsule is way too limited. | 66 | Implement an avatar mesh shape. The Bullet capsule is way too limited. |
67 | Consider just hand creating a vertex/index array in a new BSShapeAvatar. | 67 | Consider just hand creating a vertex/index array in a new BSShapeAvatar. |
@@ -121,11 +121,9 @@ LinksetCompound: when one of the children changes orientation (like tires | |||
121 | Verify/think through scripts in children of linksets. What do they reference | 121 | Verify/think through scripts in children of linksets. What do they reference |
122 | and return when getting position, velocity, ... | 122 | and return when getting position, velocity, ... |
123 | Confirm constraint linksets still work after making all the changes for compound linksets. | 123 | Confirm constraint linksets still work after making all the changes for compound linksets. |
124 | Use PostTaint callback to do rebuilds for constraint linksets to reduce rebuilding | ||
124 | Add 'changed' flag or similar to reduce the number of times a linkset is rebuilt. | 125 | Add 'changed' flag or similar to reduce the number of times a linkset is rebuilt. |
125 | For compound linksets, add ability to remove or reposition individual child shapes. | 126 | For compound linksets, add ability to remove or reposition individual child shapes. |
126 | Disable activity of passive linkset children. | ||
127 | Since the linkset is a compound object, the old prims are left lying | ||
128 | around and need to be phantomized so they don't collide, ... | ||
129 | Speed up creation of large physical linksets | 127 | Speed up creation of large physical linksets |
130 | For instance, sitting in Neb's car (130 prims) takes several seconds to become physical. | 128 | For instance, sitting in Neb's car (130 prims) takes several seconds to become physical. |
131 | REALLY bad for very large physical linksets (freezes the sim for many seconds). | 129 | REALLY bad for very large physical linksets (freezes the sim for many seconds). |
@@ -138,25 +136,21 @@ MORE | |||
138 | Use the HACD convex hull routine in Bullet rather than the C# version. | 136 | Use the HACD convex hull routine in Bullet rather than the C# version. |
139 | Do we need to do convex hulls all the time? Can complex meshes be left meshes? | 137 | Do we need to do convex hulls all the time? Can complex meshes be left meshes? |
140 | There is some problem with meshes and collisions | 138 | There is some problem with meshes and collisions |
141 | Test avatar walking up stairs. How does compare with SL. | 139 | Hulls are not as detailed as meshes. Hulled vehicles insides are different shape. |
142 | Radius of the capsule affects ability to climb edges. | ||
143 | Debounce avatar contact so legs don't keep folding up when standing. | 140 | Debounce avatar contact so legs don't keep folding up when standing. |
144 | Implement LSL physics controls. Like STATUS_ROTATE_X. | 141 | Implement LSL physics controls. Like STATUS_ROTATE_X. |
145 | Add border extensions to terrain to help region crossings and objects leaving region. | 142 | Add border extensions to terrain to help region crossings and objects leaving region. |
146 | Use a different capsule shape for avatar when sitting | 143 | Use a different capsule shape for avatar when sitting |
147 | LL uses a pyrimidal shape scaled by the avatar's bounding box | 144 | LL uses a pyrimidal shape scaled by the avatar's bounding box |
148 | http://wiki.secondlife.com/wiki/File:Avmeshforms.png | 145 | http://wiki.secondlife.com/wiki/File:Avmeshforms.png |
149 | |||
150 | Performance test with lots of avatars. Can BulletSim support a thousand? | 146 | Performance test with lots of avatars. Can BulletSim support a thousand? |
151 | Optimize collisions in C++: only send up to the object subscribed to collisions. | 147 | Optimize collisions in C++: only send up to the object subscribed to collisions. |
152 | Use collision subscription and remove the collsion(A,B) and collision(B,A) | 148 | Use collision subscription and remove the collsion(A,B) and collision(B,A) |
153 | Check whether SimMotionState needs large if statement (see TODO). | 149 | Check whether SimMotionState needs large if statement (see TODO). |
154 | |||
155 | Implement 'top colliders' info. | 150 | Implement 'top colliders' info. |
156 | Avatar jump | 151 | Avatar jump |
157 | Performance measurement and changes to make quicker. | 152 | Performance measurement and changes to make quicker. |
158 | Implement detailed physics stats (GetStats()). | 153 | Implement detailed physics stats (GetStats()). |
159 | |||
160 | Measure performance improvement from hulls | 154 | Measure performance improvement from hulls |
161 | Test not using ghost objects for volume detect implementation. | 155 | Test not using ghost objects for volume detect implementation. |
162 | Performance of closures and delegates for taint processing | 156 | Performance of closures and delegates for taint processing |
@@ -164,9 +158,7 @@ Performance of closures and delegates for taint processing | |||
164 | Is any slowdown introduced by the existing implementation significant? | 158 | Is any slowdown introduced by the existing implementation significant? |
165 | Is there are more efficient method of implementing pre and post step actions? | 159 | Is there are more efficient method of implementing pre and post step actions? |
166 | See http://www.codeproject.com/Articles/29922/Weak-Events-in-C | 160 | See http://www.codeproject.com/Articles/29922/Weak-Events-in-C |
167 | |||
168 | Physics Arena central pyramid: why is one side permiable? | 161 | Physics Arena central pyramid: why is one side permiable? |
169 | |||
170 | In SL, perfect spheres don't seem to have rolling friction. Add special case. | 162 | In SL, perfect spheres don't seem to have rolling friction. Add special case. |
171 | Enforce physical parameter min/max: | 163 | Enforce physical parameter min/max: |
172 | Gravity: [-1, 28] | 164 | Gravity: [-1, 28] |
@@ -178,6 +170,8 @@ Avatar attachments have no mass? http://forums-archive.secondlife.com/54/f0/3179 | |||
178 | 170 | ||
179 | INTERNAL IMPROVEMENT/CLEANUP | 171 | INTERNAL IMPROVEMENT/CLEANUP |
180 | ================================================= | 172 | ================================================= |
173 | Can the 'inTaintTime' flag be cleaned up and used? For instance, a call to | ||
174 | BSScene.TaintedObject() could immediately execute the callback if already in taint time. | ||
181 | Create the physical wrapper classes (BulletBody, BulletShape) by methods on | 175 | Create the physical wrapper classes (BulletBody, BulletShape) by methods on |
182 | BSAPITemplate and make their actual implementation Bullet engine specific. | 176 | BSAPITemplate and make their actual implementation Bullet engine specific. |
183 | For the short term, just call the existing functions in ShapeCollection. | 177 | For the short term, just call the existing functions in ShapeCollection. |
@@ -197,22 +191,19 @@ Generalize Dynamics and PID with standardized motors. | |||
197 | Generalize Linkset and vehicles into PropertyManagers | 191 | Generalize Linkset and vehicles into PropertyManagers |
198 | Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies | 192 | Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies |
199 | Potentially add events for shape destruction, etc. | 193 | Potentially add events for shape destruction, etc. |
200 | Complete implemention of preStepActions | 194 | Better mechanism for resetting linkset set and vehicle parameters when body rebuilt. |
201 | Replace vehicle step call with prestep event. | 195 | BSPrim.CreateGeomAndObject is kludgy with the callbacks, etc. |
202 | Is there a need for postStepActions? postStepTaints? | ||
203 | Implement linkset by setting position of children when root updated. (LinksetManual) | 196 | Implement linkset by setting position of children when root updated. (LinksetManual) |
204 | Linkset implementation using manual prim movement. | 197 | Linkset implementation using manual prim movement. |
205 | LinkablePrim class? Would that simplify/centralize the linkset logic? | 198 | LinkablePrim class? Would that simplify/centralize the linkset logic? |
206 | BSScene.UpdateParameterSet() is broken. How to set params on objects? | 199 | BSScene.UpdateParameterSet() is broken. How to set params on objects? |
207 | Remove HeightmapInfo from terrain specification | ||
208 | Since C++ code does not need terrain height, this structure et al are not needed. | ||
209 | Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will | 200 | Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will |
210 | bob at the water level. BSPrim.PositionSanityCheck(). | 201 | bob at the water level. BSPrim.PositionSanityCheck() |
211 | Should taints check for existance or activeness of target? | 202 | Should taints check for existance or activeness of target? |
212 | When destroying linksets/etc, taints can be generated for objects that are | 203 | When destroying linksets/etc, taints can be generated for objects that are |
213 | actually gone when the taint happens. Crashes don't happen because the taint closure | 204 | actually gone when the taint happens. Crashes don't happen because the taint closure |
214 | keeps the object from being freed, but that is just an accident. | 205 | keeps the object from being freed, but that is just an accident. |
215 | Possibly have and 'active' flag that is checked by the taint processor? | 206 | Possibly have an 'active' flag that is checked by the taint processor? |
216 | Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones) | 207 | Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones) |
217 | Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'? | 208 | Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'? |
218 | There are TOO MANY interfaces from BulletSim core to Bullet itself | 209 | There are TOO MANY interfaces from BulletSim core to Bullet itself |
@@ -282,3 +273,18 @@ Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE) | |||
282 | Meshes rendering as bounding boxes (DONE) | 273 | Meshes rendering as bounding boxes (DONE) |
283 | (Resolution: Added test for mesh/sculpties in native shapes so it didn't think it was a box) | 274 | (Resolution: Added test for mesh/sculpties in native shapes so it didn't think it was a box) |
284 | llMoveToTarget (Resolution: added simple motor to update the position.) | 275 | llMoveToTarget (Resolution: added simple motor to update the position.) |
276 | Angular motor direction is global coordinates rather than local coordinates (DONE) | ||
277 | Add vehicle collisions so IsColliding is properly reported. (DONE) | ||
278 | Needed for banking, limitMotorUp, movementLimiting, ... | ||
279 | (Resolution: added CollisionFlags.BS_VEHICLE_COLLISION and code to use it) | ||
280 | VehicleAddForce is not scaled by the simulation step but it is only | ||
281 | applied for one step. Should it be scaled? (DONE) | ||
282 | (Resolution: use force for timed things, Impulse for immediate, non-timed things) | ||
283 | Complete implemention of preStepActions (DONE) | ||
284 | Replace vehicle step call with prestep event. | ||
285 | Is there a need for postStepActions? postStepTaints? | ||
286 | Disable activity of passive linkset children. (DONE) | ||
287 | Since the linkset is a compound object, the old prims are left lying | ||
288 | around and need to be phantomized so they don't collide, ... | ||
289 | Remove HeightmapInfo from terrain specification (DONE) | ||
290 | Since C++ code does not need terrain height, this structure et al are not needed. \ No newline at end of file | ||