aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs110
1 files changed, 36 insertions, 74 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index 5a77e52..bbfdac6 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -51,7 +51,7 @@ public class BSShapeCollection : IDisposable
51 } 51 }
52 52
53 // Description of a hull. 53 // Description of a hull.
54 // Meshes and hulls have the same shape hash key but we only need hulls for efficient physical objects 54 // Meshes and hulls have the same shape hash key but we only need hulls for efficient collision calculations.
55 private struct HullDesc 55 private struct HullDesc
56 { 56 {
57 public IntPtr ptr; 57 public IntPtr ptr;
@@ -59,17 +59,9 @@ public class BSShapeCollection : IDisposable
59 public DateTime lastReferenced; 59 public DateTime lastReferenced;
60 } 60 }
61 61
62 private struct BodyDesc 62 // The sharable set of meshes and hulls. Indexed by their shape hash.
63 {
64 public IntPtr ptr;
65 // Bodies are only used once so reference count is always either one or zero
66 public int referenceCount;
67 public DateTime lastReferenced;
68 }
69
70 private Dictionary<System.UInt64, MeshDesc> Meshes = new Dictionary<System.UInt64, MeshDesc>(); 63 private Dictionary<System.UInt64, MeshDesc> Meshes = new Dictionary<System.UInt64, MeshDesc>();
71 private Dictionary<System.UInt64, HullDesc> Hulls = new Dictionary<System.UInt64, HullDesc>(); 64 private Dictionary<System.UInt64, HullDesc> Hulls = new Dictionary<System.UInt64, HullDesc>();
72 private Dictionary<uint, BodyDesc> Bodies = new Dictionary<uint, BodyDesc>();
73 65
74 public BSShapeCollection(BSScene physScene) 66 public BSShapeCollection(BSScene physScene)
75 { 67 {
@@ -92,6 +84,10 @@ public class BSShapeCollection : IDisposable
92 // First checks the shape and updates that if necessary then makes 84 // First checks the shape and updates that if necessary then makes
93 // sure the body is of the right type. 85 // sure the body is of the right type.
94 // Return 'true' if either the body or the shape changed. 86 // Return 'true' if either the body or the shape changed.
87 // 'shapeCallback' and 'bodyCallback' are, if non-null, functions called just before
88 // the current shape or body is destroyed. This allows the caller to remove any
89 // higher level dependencies on the shape or body. Mostly used for LinkSets to
90 // remove the physical constraints before the body is destroyed.
95 // Called at taint-time!! 91 // Called at taint-time!!
96 public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, 92 public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim,
97 ShapeData shapeData, PrimitiveBaseShape pbs, 93 ShapeData shapeData, PrimitiveBaseShape pbs,
@@ -103,7 +99,8 @@ public class BSShapeCollection : IDisposable
103 lock (m_collectionActivityLock) 99 lock (m_collectionActivityLock)
104 { 100 {
105 // Do we have the correct geometry for this type of object? 101 // Do we have the correct geometry for this type of object?
106 // Updates prim.BSShape with information/pointers to requested shape 102 // Updates prim.BSShape with information/pointers to shape.
103 // CreateGeom returns 'true' of BSShape as changed to a new shape.
107 bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs, shapeCallback); 104 bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs, shapeCallback);
108 // If we had to select a new shape geometry for the object, 105 // If we had to select a new shape geometry for the object,
109 // rebuild the body around it. 106 // rebuild the body around it.
@@ -125,35 +122,19 @@ public class BSShapeCollection : IDisposable
125 { 122 {
126 lock (m_collectionActivityLock) 123 lock (m_collectionActivityLock)
127 { 124 {
128 BodyDesc bodyDesc; 125 DetailLog("{0},BSShapeCollection.ReferenceBody,newBody", body.ID, body);
129 if (Bodies.TryGetValue(body.ID, out bodyDesc)) 126 BSScene.TaintCallback createOperation = delegate()
130 { 127 {
131 bodyDesc.referenceCount++; 128 if (!BulletSimAPI.IsInWorld2(body.ptr))
132 DetailLog("{0},BSShapeCollection.ReferenceBody,existingBody,body={1},ref={2}", body.ID, body, bodyDesc.referenceCount);
133 }
134 else
135 {
136 // New entry
137 bodyDesc.ptr = body.ptr;
138 bodyDesc.referenceCount = 1;
139 DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,ref={2}",
140 body.ID, body, bodyDesc.referenceCount);
141 BSScene.TaintCallback createOperation = delegate()
142 { 129 {
143 if (!BulletSimAPI.IsInWorld2(body.ptr)) 130 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr);
144 { 131 DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body);
145 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr); 132 }
146 DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", 133 };
147 body.ID, body); 134 if (inTaintTime)
148 } 135 createOperation();
149 }; 136 else
150 if (inTaintTime) 137 PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation);
151 createOperation();
152 else
153 PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation);
154 }
155 bodyDesc.lastReferenced = System.DateTime.Now;
156 Bodies[body.ID] = bodyDesc;
157 } 138 }
158 } 139 }
159 140
@@ -166,43 +147,25 @@ public class BSShapeCollection : IDisposable
166 147
167 lock (m_collectionActivityLock) 148 lock (m_collectionActivityLock)
168 { 149 {
169 BodyDesc bodyDesc; 150 BSScene.TaintCallback removeOperation = delegate()
170 if (Bodies.TryGetValue(body.ID, out bodyDesc))
171 { 151 {
172 bodyDesc.referenceCount--; 152 DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}",
173 bodyDesc.lastReferenced = System.DateTime.Now; 153 body.ID, body.ptr.ToString("X"), inTaintTime);
174 Bodies[body.ID] = bodyDesc; 154 // If the caller needs to know the old body is going away, pass the event up.
175 DetailLog("{0},BSShapeCollection.DereferenceBody,ref={1}", body.ID, bodyDesc.referenceCount); 155 if (bodyCallback != null) bodyCallback(body);
176 156
177 // If body is no longer being used, free it -- bodies can never be shared. 157 // It may have already been removed from the world in which case the next is a NOOP.
178 if (bodyDesc.referenceCount == 0) 158 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
179 { 159
180 Bodies.Remove(body.ID); 160 // Zero any reference to the shape so it is not freed when the body is deleted.
181 BSScene.TaintCallback removeOperation = delegate() 161 BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero);
182 { 162 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr);
183 DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}", 163 };
184 body.ID, body.ptr.ToString("X"), inTaintTime); 164 // If already in taint-time, do the operations now. Otherwise queue for later.
185 // If the caller needs to know the old body is going away, pass the event up. 165 if (inTaintTime)
186 if (bodyCallback != null) bodyCallback(body); 166 removeOperation();
187
188 // It may have already been removed from the world in which case the next is a NOOP.
189 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
190
191 // Zero any reference to the shape so it is not freed when the body is deleted.
192 BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero);
193 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr);
194 };
195 // If already in taint-time, do the operations now. Otherwise queue for later.
196 if (inTaintTime)
197 removeOperation();
198 else
199 PhysicsScene.TaintedObject("BSShapeCollection.DereferenceBody", removeOperation);
200 }
201 }
202 else 167 else
203 { 168 PhysicsScene.TaintedObject("BSShapeCollection.DereferenceBody", removeOperation);
204 DetailLog("{0},BSShapeCollection.DereferenceBody,DID NOT FIND BODY", body.ID, bodyDesc.referenceCount);
205 }
206 } 169 }
207 } 170 }
208 171
@@ -271,7 +234,6 @@ public class BSShapeCollection : IDisposable
271 } 234 }
272 235
273 // Release the usage of a shape. 236 // Release the usage of a shape.
274 // The collisionObject is released since it is a copy of the real collision shape.
275 public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback) 237 public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback)
276 { 238 {
277 if (shape.ptr == IntPtr.Zero) 239 if (shape.ptr == IntPtr.Zero)