diff options
author | Robert Adams | 2013-07-06 08:22:59 -0700 |
---|---|---|
committer | Robert Adams | 2013-07-06 08:25:15 -0700 |
commit | a65cec3986431f5a2f4f9eb2424157def0d035c8 (patch) | |
tree | 5e8ea300f4d9042c52f0cc89367cb0e9dc7e3dee /OpenSim/Region/Physics/BulletSPlugin | |
parent | BulletSim: More tweaking on center-of-mass. Almost there. Changes have no eff... (diff) | |
download | opensim-SC-a65cec3986431f5a2f4f9eb2424157def0d035c8.zip opensim-SC-a65cec3986431f5a2f4f9eb2424157def0d035c8.tar.gz opensim-SC-a65cec3986431f5a2f4f9eb2424157def0d035c8.tar.bz2 opensim-SC-a65cec3986431f5a2f4f9eb2424157def0d035c8.tar.xz |
BulletSim: implementation of linkset center-of-mass.
Default off, for the moment, until more testing.
Add separate thread and center-of-mass flags to OpenSimDefaults.ini.
Clean up comments in OpenSimDefaults.ini.
Diffstat (limited to '')
5 files changed, 70 insertions, 29 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 96626ca..1d94142 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -271,6 +271,8 @@ public sealed class BSLinksetCompound : BSLinkset | |||
271 | // to what they should be as if the root was not in a linkset. | 271 | // to what they should be as if the root was not in a linkset. |
272 | // Not that bad since we only get into this routine if there are children in the linkset and | 272 | // Not that bad since we only get into this routine if there are children in the linkset and |
273 | // something has been updated/changed. | 273 | // something has been updated/changed. |
274 | // Have to do the rebuild before checking for physical because this might be a linkset | ||
275 | // being destructed and going non-physical. | ||
274 | LinksetRoot.ForceBodyShapeRebuild(true); | 276 | LinksetRoot.ForceBodyShapeRebuild(true); |
275 | 277 | ||
276 | // There is no reason to build all this physical stuff for a non-physical linkset. | 278 | // There is no reason to build all this physical stuff for a non-physical linkset. |
@@ -283,28 +285,29 @@ public sealed class BSLinksetCompound : BSLinkset | |||
283 | // Get a new compound shape to build the linkset shape in. | 285 | // Get a new compound shape to build the linkset shape in. |
284 | BSShape linksetShape = BSShapeCompound.GetReference(m_physicsScene); | 286 | BSShape linksetShape = BSShapeCompound.GetReference(m_physicsScene); |
285 | 287 | ||
286 | // The center of mass for the linkset is the geometric center of the group. | ||
287 | // Compute a displacement for each component so it is relative to the center-of-mass. | 288 | // Compute a displacement for each component so it is relative to the center-of-mass. |
288 | // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass | 289 | // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass |
289 | OMV.Vector3 centerOfMassW = ComputeLinksetCenterOfMass(); | 290 | OMV.Vector3 centerOfMassW = ComputeLinksetCenterOfMass(); |
290 | 291 | ||
291 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Normalize(OMV.Quaternion.Inverse(LinksetRoot.RawOrientation)); | 292 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Normalize(OMV.Quaternion.Inverse(LinksetRoot.RawOrientation)); |
293 | OMV.Vector3 origRootPosition = LinksetRoot.RawPosition; | ||
292 | 294 | ||
293 | // 'centerDisplacementV' is the value to subtract from children to give physical offset position | 295 | // 'centerDisplacementV' is the vehicle relative distance from the simulator root position to the center-of-mass |
294 | OMV.Vector3 centerDisplacementV = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation; | 296 | OMV.Vector3 centerDisplacementV = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation; |
295 | if (UseBulletSimRootOffsetHack || !BSParam.LinksetOffsetCenterOfMass) | 297 | if (UseBulletSimRootOffsetHack || !BSParam.LinksetOffsetCenterOfMass) |
296 | { | 298 | { |
299 | // Zero everything if center-of-mass displacement is not being done. | ||
297 | centerDisplacementV = OMV.Vector3.Zero; | 300 | centerDisplacementV = OMV.Vector3.Zero; |
298 | LinksetRoot.ClearDisplacement(); | 301 | LinksetRoot.ClearDisplacement(); |
299 | } | 302 | } |
300 | else | 303 | else |
301 | { | 304 | { |
302 | LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacementV); | ||
303 | // The actual center-of-mass could have been set by the user. | 305 | // The actual center-of-mass could have been set by the user. |
304 | centerDisplacementV = LinksetRoot.PositionDisplacement; | 306 | centerDisplacementV = LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacementV); |
305 | } | 307 | } |
308 | |||
306 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,rootPos={1},com={2},comDisp={3}", | 309 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,rootPos={1},com={2},comDisp={3}", |
307 | LinksetRoot.LocalID, LinksetRoot.RawPosition, centerOfMassW, centerDisplacementV); | 310 | LinksetRoot.LocalID, origRootPosition, centerOfMassW, centerDisplacementV); |
308 | 311 | ||
309 | // Add the shapes of all the components of the linkset | 312 | // Add the shapes of all the components of the linkset |
310 | int memberIndex = 1; | 313 | int memberIndex = 1; |
@@ -321,11 +324,11 @@ public sealed class BSLinksetCompound : BSLinkset | |||
321 | memberIndex++; | 324 | memberIndex++; |
322 | } | 325 | } |
323 | 326 | ||
324 | // Get a reference to the shape of the child and add that shape to the linkset compound shape | 327 | // Get a reference to the shape of the child for adding of that shape to the linkset compound shape |
325 | BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim); | 328 | BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim); |
326 | 329 | ||
327 | // Offset the child shape from the center-of-mass and rotate it to vehicle relative | 330 | // Offset the child shape from the center-of-mass and rotate it to vehicle relative. |
328 | OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacementV; | 331 | OMV.Vector3 offsetPos = (cPrim.RawPosition - origRootPosition) * invRootOrientation - centerDisplacementV; |
329 | OMV.Quaternion offsetRot = OMV.Quaternion.Normalize(cPrim.RawOrientation) * invRootOrientation; | 332 | OMV.Quaternion offsetRot = OMV.Quaternion.Normalize(cPrim.RawOrientation) * invRootOrientation; |
330 | 333 | ||
331 | // Add the child shape to the compound shape being built | 334 | // Add the child shape to the compound shape being built |
@@ -366,6 +369,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
366 | // This enables a feature in the C++ code to return the world coordinates of the first shape in the | 369 | // This enables a feature in the C++ code to return the world coordinates of the first shape in the |
367 | // compound shape. This aleviates the need to offset the returned physical position by the | 370 | // compound shape. This aleviates the need to offset the returned physical position by the |
368 | // center-of-mass offset. | 371 | // center-of-mass offset. |
372 | // TODO: either debug this feature or remove it. | ||
369 | m_physicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE); | 373 | m_physicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE); |
370 | } | 374 | } |
371 | } | 375 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index a0d5c42..738e2d0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -90,6 +90,8 @@ public abstract class BSPhysObject : PhysicsActor | |||
90 | PhysBody = new BulletBody(localID); | 90 | PhysBody = new BulletBody(localID); |
91 | PhysShape = new BSShapeNull(); | 91 | PhysShape = new BSShapeNull(); |
92 | 92 | ||
93 | UserSetCenterOfMassDisplacement = null; | ||
94 | |||
93 | PrimAssetState = PrimAssetCondition.Unknown; | 95 | PrimAssetState = PrimAssetCondition.Unknown; |
94 | 96 | ||
95 | // Default material type. Also sets Friction, Restitution and Density. | 97 | // Default material type. Also sets Friction, Restitution and Density. |
@@ -180,6 +182,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
180 | Material = (MaterialAttributes.Material)material; | 182 | Material = (MaterialAttributes.Material)material; |
181 | 183 | ||
182 | // Setting the material sets the material attributes also. | 184 | // Setting the material sets the material attributes also. |
185 | // TODO: decide if this is necessary -- the simulator does this. | ||
183 | MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); | 186 | MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); |
184 | Friction = matAttrib.friction; | 187 | Friction = matAttrib.friction; |
185 | Restitution = matAttrib.restitution; | 188 | Restitution = matAttrib.restitution; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index f0858ca..ce4c3da 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -802,6 +802,7 @@ public class BSPrim : BSPhysObject | |||
802 | // isSolid: other objects bounce off of this object | 802 | // isSolid: other objects bounce off of this object |
803 | // isVolumeDetect: other objects pass through but can generate collisions | 803 | // isVolumeDetect: other objects pass through but can generate collisions |
804 | // collisionEvents: whether this object returns collision events | 804 | // collisionEvents: whether this object returns collision events |
805 | // NOTE: overloaded by BSPrimLinkable to also update linkset physical parameters. | ||
805 | public virtual void UpdatePhysicalParameters() | 806 | public virtual void UpdatePhysicalParameters() |
806 | { | 807 | { |
807 | if (!PhysBody.HasPhysicalBody) | 808 | if (!PhysBody.HasPhysicalBody) |
@@ -1532,6 +1533,8 @@ public class BSPrim : BSPhysObject | |||
1532 | 1533 | ||
1533 | // The physics engine says that properties have updated. Update same and inform | 1534 | // The physics engine says that properties have updated. Update same and inform |
1534 | // the world that things have changed. | 1535 | // the world that things have changed. |
1536 | // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims. | ||
1537 | // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimDisplaced which handles mapping physical position to simulator position. | ||
1535 | public override void UpdateProperties(EntityProperties entprop) | 1538 | public override void UpdateProperties(EntityProperties entprop) |
1536 | { | 1539 | { |
1537 | // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator. | 1540 | // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator. |
@@ -1567,8 +1570,6 @@ public class BSPrim : BSPhysObject | |||
1567 | LastEntityProperties = CurrentEntityProperties; | 1570 | LastEntityProperties = CurrentEntityProperties; |
1568 | CurrentEntityProperties = entprop; | 1571 | CurrentEntityProperties = entprop; |
1569 | 1572 | ||
1570 | // Note that BSPrim can be overloaded by BSPrimLinkable which controls updates from root and children prims. | ||
1571 | |||
1572 | PhysScene.PostUpdate(this); | 1573 | PhysScene.PostUpdate(this); |
1573 | } | 1574 | } |
1574 | } | 1575 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs index a11bca0..35d5a08 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs | |||
@@ -59,6 +59,7 @@ public class BSPrimDisplaced : BSPrim | |||
59 | // are converted into simulator origin values before being passed to the base | 59 | // are converted into simulator origin values before being passed to the base |
60 | // class. | 60 | // class. |
61 | 61 | ||
62 | // PositionDisplacement is the vehicle relative distance from the root prim position to the center-of-mass. | ||
62 | public virtual OMV.Vector3 PositionDisplacement { get; set; } | 63 | public virtual OMV.Vector3 PositionDisplacement { get; set; } |
63 | 64 | ||
64 | public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, | 65 | public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, |
@@ -72,49 +73,77 @@ public class BSPrimDisplaced : BSPrim | |||
72 | // Does not clear the displacement set by the user. | 73 | // Does not clear the displacement set by the user. |
73 | public void ClearDisplacement() | 74 | public void ClearDisplacement() |
74 | { | 75 | { |
75 | SetEffectiveCenterOfMassDisplacement(OMV.Vector3.Zero); | 76 | if (UserSetCenterOfMassDisplacement.HasValue) |
77 | PositionDisplacement = (OMV.Vector3)UserSetCenterOfMassDisplacement; | ||
78 | else | ||
79 | PositionDisplacement = OMV.Vector3.Zero; | ||
76 | } | 80 | } |
77 | 81 | ||
78 | // Set this sets and computes the displacement from the passed prim to the center-of-mass. | 82 | // Set this sets and computes the displacement from the passed prim to the center-of-mass. |
79 | // A user set value for center-of-mass overrides whatever might be passed in here. | 83 | // A user set value for center-of-mass overrides whatever might be passed in here. |
80 | // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates). | 84 | // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates). |
85 | // Returns the relative offset from the root position to the center-of-mass. | ||
81 | // Called at taint time. | 86 | // Called at taint time. |
82 | public virtual void SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement) | 87 | public virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement) |
83 | { | 88 | { |
89 | PhysScene.AssertInTaintTime("BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement"); | ||
84 | Vector3 comDisp; | 90 | Vector3 comDisp; |
85 | if (UserSetCenterOfMassDisplacement.HasValue) | 91 | if (UserSetCenterOfMassDisplacement.HasValue) |
86 | comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement; | 92 | comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement; |
87 | else | 93 | else |
88 | comDisp = centerOfMassDisplacement; | 94 | comDisp = centerOfMassDisplacement; |
89 | 95 | ||
96 | // Eliminate any jitter caused be very slight differences in masses and positions | ||
90 | if (comDisp.ApproxEquals(Vector3.Zero, 0.01f) ) | 97 | if (comDisp.ApproxEquals(Vector3.Zero, 0.01f) ) |
91 | comDisp = Vector3.Zero; | 98 | comDisp = Vector3.Zero; |
92 | 99 | ||
93 | DetailLog("{0},BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement,userSet={1},comDisp={2}", | 100 | DetailLog("{0},BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement,userSet={1},comDisp={2}", |
94 | LocalID, UserSetCenterOfMassDisplacement.HasValue, comDisp); | 101 | LocalID, UserSetCenterOfMassDisplacement.HasValue, comDisp); |
95 | if ( comDisp != PositionDisplacement ) | 102 | if ( !comDisp.ApproxEquals(PositionDisplacement, 0.01f) ) |
96 | { | 103 | { |
97 | // Displacement setting is changing. | 104 | // Displacement setting is changing. |
98 | // The relationship between the physical object and simulated object must be aligned. | 105 | // The relationship between the physical object and simulated object must be aligned. |
99 | PositionDisplacement = comDisp; | 106 | PositionDisplacement = comDisp; |
100 | this.ForcePosition = RawPosition; | 107 | this.ForcePosition = RawPosition; |
101 | } | 108 | } |
109 | |||
110 | return PositionDisplacement; | ||
102 | } | 111 | } |
103 | 112 | ||
113 | // 'ForcePosition' is the one way to set the physical position of the body in the physics engine. | ||
114 | // Displace the simulator idea of position (center of root prim) to the physical position. | ||
104 | public override Vector3 ForcePosition | 115 | public override Vector3 ForcePosition |
105 | { | 116 | { |
106 | get { return base.ForcePosition; } | 117 | get { |
118 | OMV.Vector3 physPosition = base.ForcePosition; | ||
119 | if (PositionDisplacement != OMV.Vector3.Zero) | ||
120 | { | ||
121 | // If there is some displacement, return the physical position (center-of-mass) | ||
122 | // location minus the displacement to give the center of the root prim. | ||
123 | OMV.Vector3 displacement = PositionDisplacement * ForceOrientation; | ||
124 | DetailLog("{0},BSPrimDisplaced.ForcePosition,get,physPos={1},disp={2},simPos={3}", | ||
125 | LocalID, physPosition, displacement, physPosition - displacement); | ||
126 | physPosition -= displacement; | ||
127 | } | ||
128 | return physPosition; | ||
129 | } | ||
107 | set | 130 | set |
108 | { | 131 | { |
109 | if (PositionDisplacement != OMV.Vector3.Zero) | 132 | if (PositionDisplacement != OMV.Vector3.Zero) |
110 | { | 133 | { |
111 | // The displacement is always relative to the vehicle so, when setting position, | 134 | // This value is the simulator's idea of where the prim is: the center of the root prim |
112 | // the caller means to set the position of the root prim. | 135 | RawPosition = value; |
113 | // This offsets the setting value to the center-of-mass and sends that to the | 136 | |
114 | // physics engine. | 137 | // Move the passed root prim postion to the center-of-mass position and set in the physics engine. |
115 | OMV.Vector3 displacedPos = value - (PositionDisplacement * RawOrientation); | 138 | OMV.Vector3 displacement = PositionDisplacement * RawOrientation; |
116 | DetailLog("{0},BSPrimDisplaced.ForcePosition,val={1},disp={2},newPos={3}", LocalID, value, PositionDisplacement, displacedPos); | 139 | OMV.Vector3 displacedPos = RawPosition + displacement; |
117 | base.ForcePosition = displacedPos; | 140 | DetailLog("{0},BSPrimDisplaced.ForcePosition,set,simPos={1},disp={2},physPos={3}", |
141 | LocalID, RawPosition, displacement, displacedPos); | ||
142 | if (PhysBody.HasPhysicalBody) | ||
143 | { | ||
144 | PhysScene.PE.SetTranslation(PhysBody, displacedPos, RawOrientation); | ||
145 | ActivateIfPhysical(false); | ||
146 | } | ||
118 | } | 147 | } |
119 | else | 148 | else |
120 | { | 149 | { |
@@ -143,10 +172,11 @@ public class BSPrimDisplaced : BSPrim | |||
143 | // These physical location must be back converted to be centered around the displaced | 172 | // These physical location must be back converted to be centered around the displaced |
144 | // root shape. | 173 | // root shape. |
145 | 174 | ||
146 | // The root position is the reported position displaced by the rotated displacement. | 175 | // Move the returned center-of-mass location to the root prim location. |
147 | OMV.Vector3 displacedPos = entprop.Position + (PositionDisplacement * entprop.Rotation); | 176 | OMV.Vector3 displacement = PositionDisplacement * entprop.Rotation; |
148 | DetailLog("{0},BSPrimDisplaced.UpdateProperties,physPos={1},disp={2},newPos={3}", | 177 | OMV.Vector3 displacedPos = entprop.Position - displacement; |
149 | LocalID, entprop.Position, PositionDisplacement, displacedPos); | 178 | DetailLog("{0},BSPrimDisplaced.UpdateProperties,physPos={1},disp={2},simPos={3}", |
179 | LocalID, entprop.Position, displacement, displacedPos); | ||
150 | entprop.Position = displacedPos; | 180 | entprop.Position = displacedPos; |
151 | } | 181 | } |
152 | 182 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index 7058646..1fbcfcc 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs | |||
@@ -160,10 +160,13 @@ public class BSPrimLinkable : BSPrimDisplaced | |||
160 | protected override void MakeDynamic(bool makeStatic) | 160 | protected override void MakeDynamic(bool makeStatic) |
161 | { | 161 | { |
162 | base.MakeDynamic(makeStatic); | 162 | base.MakeDynamic(makeStatic); |
163 | if (makeStatic) | 163 | if (Linkset != null) // null can happen during initialization |
164 | Linkset.MakeStatic(this); | 164 | { |
165 | else | 165 | if (makeStatic) |
166 | Linkset.MakeDynamic(this); | 166 | Linkset.MakeStatic(this); |
167 | else | ||
168 | Linkset.MakeDynamic(this); | ||
169 | } | ||
167 | } | 170 | } |
168 | 171 | ||
169 | // Body is being taken apart. Remove physical dependencies and schedule a rebuild. | 172 | // Body is being taken apart. Remove physical dependencies and schedule a rebuild. |