diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 72 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 24 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 85 |
3 files changed, 120 insertions, 61 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 8b97ebb..adf4aff 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -34,7 +34,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
34 | { | 34 | { |
35 | public sealed class BSLinksetCompound : BSLinkset | 35 | public sealed class BSLinksetCompound : BSLinkset |
36 | { | 36 | { |
37 | // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; | 37 | private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; |
38 | 38 | ||
39 | public BSLinksetCompound(BSScene scene, BSPhysObject parent) | 39 | public BSLinksetCompound(BSScene scene, BSPhysObject parent) |
40 | { | 40 | { |
@@ -59,6 +59,12 @@ public sealed class BSLinksetCompound : BSLinkset | |||
59 | // refresh will happen once after all the other taints are applied. | 59 | // refresh will happen once after all the other taints are applied. |
60 | public override void Refresh(BSPhysObject requestor) | 60 | public override void Refresh(BSPhysObject requestor) |
61 | { | 61 | { |
62 | // External request for Refresh (from BSPrim) is not necessary | ||
63 | // InternalRefresh(requestor); | ||
64 | } | ||
65 | |||
66 | private void InternalRefresh(BSPhysObject requestor) | ||
67 | { | ||
62 | DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1}", LinksetRoot.LocalID, requestor.LocalID); | 68 | DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1}", LinksetRoot.LocalID, requestor.LocalID); |
63 | // Queue to happen after all the other taint processing | 69 | // Queue to happen after all the other taint processing |
64 | PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() | 70 | PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() |
@@ -135,13 +141,13 @@ public sealed class BSLinksetCompound : BSLinkset | |||
135 | { | 141 | { |
136 | bool ret = false; | 142 | bool ret = false; |
137 | 143 | ||
138 | DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2},isRoot={3}", | 144 | DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", |
139 | child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), IsRoot(child)); | 145 | child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), IsRoot(child)); |
140 | 146 | ||
141 | if (!IsRoot(child)) | 147 | if (!IsRoot(child)) |
142 | { | 148 | { |
143 | // Cause the current shape to be freed and the new one to be built. | 149 | // Cause the current shape to be freed and the new one to be built. |
144 | Refresh(LinksetRoot); | 150 | InternalRefresh(LinksetRoot); |
145 | ret = true; | 151 | ret = true; |
146 | } | 152 | } |
147 | 153 | ||
@@ -169,7 +175,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
169 | DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); | 175 | DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); |
170 | 176 | ||
171 | // Cause constraints and assorted properties to be recomputed before the next simulation step. | 177 | // Cause constraints and assorted properties to be recomputed before the next simulation step. |
172 | Refresh(LinksetRoot); | 178 | InternalRefresh(LinksetRoot); |
173 | } | 179 | } |
174 | return; | 180 | return; |
175 | } | 181 | } |
@@ -196,34 +202,68 @@ public sealed class BSLinksetCompound : BSLinkset | |||
196 | else | 202 | else |
197 | { | 203 | { |
198 | // Schedule a rebuild of the linkset before the next simulation tick. | 204 | // Schedule a rebuild of the linkset before the next simulation tick. |
199 | Refresh(LinksetRoot); | 205 | InternalRefresh(LinksetRoot); |
200 | } | 206 | } |
201 | } | 207 | } |
202 | return; | 208 | return; |
203 | } | 209 | } |
204 | 210 | ||
205 | 211 | // Called before the simulation step to make sure the compound based linkset | |
206 | // Call each of the constraints that make up this linkset and recompute the | ||
207 | // various transforms and variables. Create constraints of not created yet. | ||
208 | // Called before the simulation step to make sure the constraint based linkset | ||
209 | // is all initialized. | 212 | // is all initialized. |
213 | // Constraint linksets are rebuilt every time. | ||
214 | // Note that this works for rebuilding just the root after a linkset is taken apart. | ||
210 | // Called at taint time!! | 215 | // Called at taint time!! |
211 | private void RecomputeLinksetCompound() | 216 | private void RecomputeLinksetCompound() |
212 | { | 217 | { |
213 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},numChildren={2}", | 218 | // Cause the root shape to be rebuilt as a compound object with just the root in it |
214 | LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), NumberOfChildren); | ||
215 | |||
216 | LinksetRoot.ForceBodyShapeRebuild(true); | 219 | LinksetRoot.ForceBodyShapeRebuild(true); |
217 | 220 | ||
221 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", | ||
222 | LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); | ||
223 | |||
224 | ForEachMember(delegate(BSPhysObject cPrim) | ||
225 | { | ||
226 | if (!IsRoot(cPrim)) | ||
227 | { | ||
228 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); | ||
229 | OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; | ||
230 | OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; | ||
231 | |||
232 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", | ||
233 | LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, displacementPos, displacementRot); | ||
234 | |||
235 | if (cPrim.PhysShape.isNativeShape) | ||
236 | { | ||
237 | // Native shapes are not shared so we need to create a new one. | ||
238 | // A mesh or hull is created because scale is not available on a native shape. | ||
239 | // (TODO: Bullet does have a btScaledCollisionShape. Can that be used?) | ||
240 | BulletShape saveShape = cPrim.PhysShape; | ||
241 | PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); | ||
242 | BulletShape newShape = cPrim.PhysShape; | ||
243 | cPrim.PhysShape = saveShape; | ||
244 | BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot); | ||
245 | } | ||
246 | else | ||
247 | { | ||
248 | // For the shared shapes (meshes and hulls) just use the shape in the child | ||
249 | if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape)) | ||
250 | { | ||
251 | PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", | ||
252 | LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); | ||
253 | } | ||
254 | BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, displacementPos, displacementRot); | ||
255 | } | ||
256 | } | ||
257 | return false; | ||
258 | }); | ||
259 | |||
260 | |||
218 | float linksetMass = LinksetMass; | 261 | float linksetMass = LinksetMass; |
219 | LinksetRoot.UpdatePhysicalMassProperties(linksetMass); | 262 | LinksetRoot.UpdatePhysicalMassProperties(linksetMass); |
220 | 263 | ||
221 | // DEBUG: see of inter-linkset collisions are causing problems | 264 | // DEBUG: see of inter-linkset collisions are causing problems |
222 | // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, | 265 | // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, |
223 | // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); | 266 | // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); |
224 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,end,rBody={1},linksetMass={2}", | ||
225 | LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass); | ||
226 | |||
227 | 267 | ||
228 | } | 268 | } |
229 | } | 269 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 13aa860..de35359 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -116,6 +116,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
116 | // True if initialized and ready to do simulation steps | 116 | // True if initialized and ready to do simulation steps |
117 | private bool m_initialized = false; | 117 | private bool m_initialized = false; |
118 | 118 | ||
119 | // Flag which is true when processing taints. | ||
120 | // Not guaranteed to be correct all the time (don't depend on this) but good for debugging. | ||
121 | public bool InTaintTime { get; private set; } | ||
122 | |||
119 | // Pinned memory used to pass step information between managed and unmanaged | 123 | // Pinned memory used to pass step information between managed and unmanaged |
120 | private int m_maxCollisionsPerFrame; | 124 | private int m_maxCollisionsPerFrame; |
121 | private CollisionDesc[] m_collisionArray; | 125 | private CollisionDesc[] m_collisionArray; |
@@ -270,6 +274,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
270 | TerrainManager = new BSTerrainManager(this); | 274 | TerrainManager = new BSTerrainManager(this); |
271 | TerrainManager.CreateInitialGroundPlaneAndTerrain(); | 275 | TerrainManager.CreateInitialGroundPlaneAndTerrain(); |
272 | 276 | ||
277 | m_log.WarnFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)Params.linksetImplementation); | ||
278 | |||
279 | InTaintTime = false; | ||
273 | m_initialized = true; | 280 | m_initialized = true; |
274 | } | 281 | } |
275 | 282 | ||
@@ -707,8 +714,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
707 | // here just before the physics engine is called to step the simulation. | 714 | // here just before the physics engine is called to step the simulation. |
708 | public void ProcessTaints() | 715 | public void ProcessTaints() |
709 | { | 716 | { |
717 | InTaintTime = true; | ||
710 | ProcessRegularTaints(); | 718 | ProcessRegularTaints(); |
711 | ProcessPostTaintTaints(); | 719 | ProcessPostTaintTaints(); |
720 | InTaintTime = false; | ||
712 | } | 721 | } |
713 | 722 | ||
714 | private void ProcessRegularTaints() | 723 | private void ProcessRegularTaints() |
@@ -851,6 +860,17 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
851 | } | 860 | } |
852 | } | 861 | } |
853 | 862 | ||
863 | public bool AssertInTaintTime(string whereFrom) | ||
864 | { | ||
865 | if (!InTaintTime) | ||
866 | { | ||
867 | DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); | ||
868 | m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); | ||
869 | Util.PrintCallStack(); | ||
870 | } | ||
871 | return InTaintTime; | ||
872 | } | ||
873 | |||
854 | #endregion // Taints | 874 | #endregion // Taints |
855 | 875 | ||
856 | #region Vehicles | 876 | #region Vehicles |
@@ -1214,8 +1234,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
1214 | (s) => { return s.m_params[0].numberOfSolverIterations; }, | 1234 | (s) => { return s.m_params[0].numberOfSolverIterations; }, |
1215 | (s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ), | 1235 | (s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ), |
1216 | 1236 | ||
1217 | new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound)", | 1237 | new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", |
1218 | (float)BSLinkset.LinksetImplementation.Constraint, | 1238 | (float)BSLinkset.LinksetImplementation.Compound, |
1219 | (s,cf,p,v) => { s.m_params[0].linksetImplementation = cf.GetFloat(p,v); }, | 1239 | (s,cf,p,v) => { s.m_params[0].linksetImplementation = cf.GetFloat(p,v); }, |
1220 | (s) => { return s.m_params[0].linksetImplementation; }, | 1240 | (s) => { return s.m_params[0].linksetImplementation; }, |
1221 | (s,p,l,v) => { s.m_params[0].linksetImplementation = v; } ), | 1241 | (s,p,l,v) => { s.m_params[0].linksetImplementation = v; } ), |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 107befe..662b19d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -92,6 +92,8 @@ public sealed class BSShapeCollection : IDisposable | |||
92 | public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, | 92 | public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, |
93 | ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) | 93 | ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) |
94 | { | 94 | { |
95 | PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape"); | ||
96 | |||
95 | bool ret = false; | 97 | bool ret = false; |
96 | 98 | ||
97 | // This lock could probably be pushed down lower but building shouldn't take long | 99 | // This lock could probably be pushed down lower but building shouldn't take long |
@@ -121,7 +123,7 @@ public sealed class BSShapeCollection : IDisposable | |||
121 | { | 123 | { |
122 | lock (m_collectionActivityLock) | 124 | lock (m_collectionActivityLock) |
123 | { | 125 | { |
124 | DetailLog("{0},BSShapeCollection.ReferenceBody,newBody", body.ID, body); | 126 | DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); |
125 | PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() | 127 | PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() |
126 | { | 128 | { |
127 | if (!BulletSimAPI.IsInWorld2(body.ptr)) | 129 | if (!BulletSimAPI.IsInWorld2(body.ptr)) |
@@ -165,7 +167,7 @@ public sealed class BSShapeCollection : IDisposable | |||
165 | // Meshes and hulls for the same shape have the same hash key. | 167 | // Meshes and hulls for the same shape have the same hash key. |
166 | // NOTE that native shapes are not added to the mesh list or removed. | 168 | // NOTE that native shapes are not added to the mesh list or removed. |
167 | // Returns 'true' if this is the initial reference to the shape. Otherwise reused. | 169 | // Returns 'true' if this is the initial reference to the shape. Otherwise reused. |
168 | private bool ReferenceShape(BulletShape shape) | 170 | public bool ReferenceShape(BulletShape shape) |
169 | { | 171 | { |
170 | bool ret = false; | 172 | bool ret = false; |
171 | switch (shape.type) | 173 | switch (shape.type) |
@@ -276,8 +278,8 @@ public sealed class BSShapeCollection : IDisposable | |||
276 | if (shapeCallback != null) shapeCallback(shape); | 278 | if (shapeCallback != null) shapeCallback(shape); |
277 | meshDesc.lastReferenced = System.DateTime.Now; | 279 | meshDesc.lastReferenced = System.DateTime.Now; |
278 | Meshes[shape.shapeKey] = meshDesc; | 280 | Meshes[shape.shapeKey] = meshDesc; |
279 | DetailLog("{0},BSShapeCollection.DereferenceMesh,key={1},refCnt={2}", | 281 | DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}", |
280 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); | 282 | BSScene.DetailLogZero, shape, meshDesc.referenceCount); |
281 | 283 | ||
282 | } | 284 | } |
283 | } | 285 | } |
@@ -297,8 +299,8 @@ public sealed class BSShapeCollection : IDisposable | |||
297 | 299 | ||
298 | hullDesc.lastReferenced = System.DateTime.Now; | 300 | hullDesc.lastReferenced = System.DateTime.Now; |
299 | Hulls[shape.shapeKey] = hullDesc; | 301 | Hulls[shape.shapeKey] = hullDesc; |
300 | DetailLog("{0},BSShapeCollection.DereferenceHull,key={1},refCnt={2}", | 302 | DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}", |
301 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); | 303 | BSScene.DetailLogZero, shape, hullDesc.referenceCount); |
302 | } | 304 | } |
303 | } | 305 | } |
304 | 306 | ||
@@ -319,8 +321,11 @@ public sealed class BSShapeCollection : IDisposable | |||
319 | BSScene.DetailLogZero, shape.type, shape.ptr.ToString("X")); | 321 | BSScene.DetailLogZero, shape.type, shape.ptr.ToString("X")); |
320 | return; | 322 | return; |
321 | } | 323 | } |
324 | |||
322 | int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr); | 325 | int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr); |
323 | for (int ii = 0; ii < numChildren; ii++) | 326 | DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren); |
327 | |||
328 | for (int ii = numChildren - 1; ii >= 0; ii--) | ||
324 | { | 329 | { |
325 | IntPtr childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii); | 330 | IntPtr childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii); |
326 | DereferenceAnonCollisionShape(childShape); | 331 | DereferenceAnonCollisionShape(childShape); |
@@ -343,6 +348,7 @@ public sealed class BSShapeCollection : IDisposable | |||
343 | shapeInfo.isNativeShape = true; | 348 | shapeInfo.isNativeShape = true; |
344 | shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) | 349 | shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) |
345 | } | 350 | } |
351 | DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo); | ||
346 | 352 | ||
347 | DereferenceShape(shapeInfo, true, null); | 353 | DereferenceShape(shapeInfo, true, null); |
348 | } | 354 | } |
@@ -440,23 +446,32 @@ public sealed class BSShapeCollection : IDisposable | |||
440 | } | 446 | } |
441 | 447 | ||
442 | // If a simple shape is not happening, create a mesh and possibly a hull. | 448 | // If a simple shape is not happening, create a mesh and possibly a hull. |
449 | if (!haveShape && pbs != null) | ||
450 | { | ||
451 | ret = CreateGeomMeshOrHull(prim, shapeCallback); | ||
452 | } | ||
453 | |||
454 | return ret; | ||
455 | } | ||
456 | |||
457 | public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) | ||
458 | { | ||
459 | |||
460 | bool ret = false; | ||
443 | // Note that if it's a native shape, the check for physical/non-physical is not | 461 | // Note that if it's a native shape, the check for physical/non-physical is not |
444 | // made. Native shapes work in either case. | 462 | // made. Native shapes work in either case. |
445 | if (!haveShape && pbs != null) | 463 | if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) |
446 | { | 464 | { |
447 | if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) | 465 | // Update prim.BSShape to reference a hull of this shape. |
448 | { | 466 | ret = GetReferenceToHull(prim,shapeCallback); |
449 | // Update prim.BSShape to reference a hull of this shape. | 467 | DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", |
450 | ret = GetReferenceToHull(prim,shapeCallback); | 468 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); |
451 | DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", | 469 | } |
452 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); | 470 | else |
453 | } | 471 | { |
454 | else | 472 | ret = GetReferenceToMesh(prim, shapeCallback); |
455 | { | 473 | DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", |
456 | ret = GetReferenceToMesh(prim, shapeCallback); | 474 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); |
457 | DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", | ||
458 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); | ||
459 | } | ||
460 | } | 475 | } |
461 | return ret; | 476 | return ret; |
462 | } | 477 | } |
@@ -743,32 +758,16 @@ public sealed class BSShapeCollection : IDisposable | |||
743 | // This shouldn't be to bad since most of the parts will be meshes that had been built previously. | 758 | // This shouldn't be to bad since most of the parts will be meshes that had been built previously. |
744 | private bool GetReferenceToCompoundShape(BSPhysObject prim, ShapeDestructionCallback shapeCallback) | 759 | private bool GetReferenceToCompoundShape(BSPhysObject prim, ShapeDestructionCallback shapeCallback) |
745 | { | 760 | { |
761 | // Remove reference to the old shape | ||
762 | // Don't need to do this as the shape is freed when we create the new root shape below. | ||
763 | // DereferenceShape(prim.PhysShape, true, shapeCallback); | ||
764 | |||
746 | BulletShape cShape = new BulletShape( | 765 | BulletShape cShape = new BulletShape( |
747 | BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr), ShapeData.PhysicsShapeType.SHAPE_COMPOUND); | 766 | BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr), ShapeData.PhysicsShapeType.SHAPE_COMPOUND); |
748 | 767 | ||
749 | // The prim's linkset is the source of the children. | 768 | // Create the shape for the root prim and add it to the compound shape |
750 | // TODO: there is too much knowledge here about the internals of linksets and too much | ||
751 | // dependency on the relationship of compound shapes and linksets (what if we want to use | ||
752 | // compound shapes for something else?). Think through this and clean up so the | ||
753 | // appropriate knowledge is used at the correct software levels. | ||
754 | |||
755 | // Recreate the geometry of the root prim (might have been a linkset root in the past) | ||
756 | CreateGeomNonSpecial(true, prim, null); | 769 | CreateGeomNonSpecial(true, prim, null); |
757 | 770 | BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity); | |
758 | BSPhysObject rootPrim = prim.Linkset.LinksetRoot; | ||
759 | |||
760 | prim.Linkset.ForEachMember(delegate(BSPhysObject cPrim) | ||
761 | { | ||
762 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(rootPrim.RawOrientation); | ||
763 | OMV.Vector3 displacementPos = (cPrim.RawPosition - rootPrim.RawPosition) * invRootOrientation; | ||
764 | OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; | ||
765 | |||
766 | DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", | ||
767 | prim.LocalID, cPrim.LocalID, cPrim.PhysShape.ptr.ToString("X"), displacementPos, displacementRot); | ||
768 | |||
769 | BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, cPrim.PhysShape.ptr, displacementPos, displacementRot); | ||
770 | return false; | ||
771 | }); | ||
772 | 771 | ||
773 | prim.PhysShape = cShape; | 772 | prim.PhysShape = cShape; |
774 | 773 | ||