diff options
Diffstat (limited to '')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 110 |
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) |