diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 215 |
1 files changed, 177 insertions, 38 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index ee18379..dd5ae1a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | |||
@@ -29,6 +29,9 @@ using System; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Text; | 30 | using System.Text; |
31 | 31 | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Physics.Manager; | ||
34 | |||
32 | using OMV = OpenMetaverse; | 35 | using OMV = OpenMetaverse; |
33 | 36 | ||
34 | namespace OpenSim.Region.Physics.BulletSPlugin | 37 | namespace OpenSim.Region.Physics.BulletSPlugin |
@@ -37,11 +40,19 @@ public abstract class BSShape | |||
37 | { | 40 | { |
38 | public int referenceCount { get; set; } | 41 | public int referenceCount { get; set; } |
39 | public DateTime lastReferenced { get; set; } | 42 | public DateTime lastReferenced { get; set; } |
43 | public BulletShape physShapeInfo { get; set; } | ||
40 | 44 | ||
41 | public BSShape() | 45 | public BSShape() |
42 | { | 46 | { |
43 | referenceCount = 0; | 47 | referenceCount = 0; |
44 | lastReferenced = DateTime.Now; | 48 | lastReferenced = DateTime.Now; |
49 | physShapeInfo = new BulletShape(); | ||
50 | } | ||
51 | public BSShape(BulletShape pShape) | ||
52 | { | ||
53 | referenceCount = 0; | ||
54 | lastReferenced = DateTime.Now; | ||
55 | physShapeInfo = pShape; | ||
45 | } | 56 | } |
46 | 57 | ||
47 | // Get a reference to a physical shape. Create if it doesn't exist | 58 | // Get a reference to a physical shape. Create if it doesn't exist |
@@ -79,21 +90,30 @@ public abstract class BSShape | |||
79 | 90 | ||
80 | return ret; | 91 | return ret; |
81 | } | 92 | } |
82 | public static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | 93 | private static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) |
83 | { | 94 | { |
95 | BSShapeMesh.GetReference(physicsScene, forceRebuild, prim); | ||
96 | BSShapeHull.GetReference(physicsScene, forceRebuild, prim); | ||
84 | return null; | 97 | return null; |
85 | } | 98 | } |
86 | public static BSShape GetShapeReferenceNonNative(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | 99 | |
100 | // Called when this shape is being used again. | ||
101 | public virtual void IncrementReference() | ||
87 | { | 102 | { |
88 | return null; | 103 | referenceCount++; |
104 | lastReferenced = DateTime.Now; | ||
105 | } | ||
106 | |||
107 | // Called when this shape is being used again. | ||
108 | public virtual void DecrementReference() | ||
109 | { | ||
110 | referenceCount--; | ||
111 | lastReferenced = DateTime.Now; | ||
89 | } | 112 | } |
90 | 113 | ||
91 | // Release the use of a physical shape. | 114 | // Release the use of a physical shape. |
92 | public abstract void Dereference(BSScene physicsScene); | 115 | public abstract void Dereference(BSScene physicsScene); |
93 | 116 | ||
94 | // All shapes have a static call to get a reference to the physical shape | ||
95 | // protected abstract static BSShape GetReference(); | ||
96 | |||
97 | // Returns a string for debugging that uniquily identifies the memory used by this instance | 117 | // Returns a string for debugging that uniquily identifies the memory used by this instance |
98 | public virtual string AddrString | 118 | public virtual string AddrString |
99 | { | 119 | { |
@@ -112,6 +132,7 @@ public abstract class BSShape | |||
112 | } | 132 | } |
113 | } | 133 | } |
114 | 134 | ||
135 | // ============================================================================================================ | ||
115 | public class BSShapeNull : BSShape | 136 | public class BSShapeNull : BSShape |
116 | { | 137 | { |
117 | public BSShapeNull() : base() | 138 | public BSShapeNull() : base() |
@@ -121,23 +142,39 @@ public class BSShapeNull : BSShape | |||
121 | public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ } | 142 | public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ } |
122 | } | 143 | } |
123 | 144 | ||
145 | // ============================================================================================================ | ||
124 | public class BSShapeNative : BSShape | 146 | public class BSShapeNative : BSShape |
125 | { | 147 | { |
126 | private static string LogHeader = "[BULLETSIM SHAPE NATIVE]"; | 148 | private static string LogHeader = "[BULLETSIM SHAPE NATIVE]"; |
127 | public BSShapeNative() : base() | 149 | public BSShapeNative(BulletShape pShape) : base(pShape) |
128 | { | 150 | { |
129 | } | 151 | } |
152 | |||
130 | public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim, | 153 | public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim, |
131 | BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) | 154 | BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) |
132 | { | 155 | { |
133 | // Native shapes are not shared and are always built anew. | 156 | // Native shapes are not shared and are always built anew. |
134 | //return new BSShapeNative(physicsScene, prim, shapeType, shapeKey); | 157 | return new BSShapeNative(CreatePhysicalNativeShape(physicsScene, prim, shapeType, shapeKey)); |
135 | return null; | ||
136 | } | 158 | } |
137 | 159 | ||
138 | private BSShapeNative(BSScene physicsScene, BSPhysObject prim, | 160 | // Make this reference to the physical shape go away since native shapes are not shared. |
139 | BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) | 161 | public override void Dereference(BSScene physicsScene) |
162 | { | ||
163 | // Native shapes are not tracked and are released immediately | ||
164 | if (physShapeInfo.HasPhysicalShape) | ||
165 | { | ||
166 | physicsScene.DetailLog("{0},BSShapeNative.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); | ||
167 | physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo); | ||
168 | } | ||
169 | physShapeInfo.Clear(); | ||
170 | // Garbage collection will free up this instance. | ||
171 | } | ||
172 | |||
173 | private static BulletShape CreatePhysicalNativeShape(BSScene physicsScene, BSPhysObject prim, | ||
174 | BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) | ||
140 | { | 175 | { |
176 | BulletShape newShape; | ||
177 | |||
141 | ShapeData nativeShapeData = new ShapeData(); | 178 | ShapeData nativeShapeData = new ShapeData(); |
142 | nativeShapeData.Type = shapeType; | 179 | nativeShapeData.Type = shapeType; |
143 | nativeShapeData.ID = prim.LocalID; | 180 | nativeShapeData.ID = prim.LocalID; |
@@ -146,63 +183,164 @@ public class BSShapeNative : BSShape | |||
146 | nativeShapeData.MeshKey = (ulong)shapeKey; | 183 | nativeShapeData.MeshKey = (ulong)shapeKey; |
147 | nativeShapeData.HullKey = (ulong)shapeKey; | 184 | nativeShapeData.HullKey = (ulong)shapeKey; |
148 | 185 | ||
149 | |||
150 | /* | ||
151 | if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) | 186 | if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) |
152 | { | 187 | { |
153 | ptr = PhysicsScene.PE.BuildCapsuleShape(physicsScene.World, 1f, 1f, prim.Scale); | 188 | newShape = physicsScene.PE.BuildCapsuleShape(physicsScene.World, 1f, 1f, prim.Scale); |
154 | physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); | 189 | physicsScene.DetailLog("{0},BSShapeNative,capsule,scale={1}", prim.LocalID, prim.Scale); |
155 | } | 190 | } |
156 | else | 191 | else |
157 | { | 192 | { |
158 | ptr = PhysicsScene.PE.BuildNativeShape(physicsScene.World, nativeShapeData); | 193 | newShape = physicsScene.PE.BuildNativeShape(physicsScene.World, nativeShapeData); |
159 | } | 194 | } |
160 | if (ptr == IntPtr.Zero) | 195 | if (!newShape.HasPhysicalShape) |
161 | { | 196 | { |
162 | physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", | 197 | physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", |
163 | LogHeader, prim.LocalID, shapeType); | 198 | LogHeader, prim.LocalID, shapeType); |
164 | } | 199 | } |
165 | type = shapeType; | 200 | newShape.type = shapeType; |
166 | key = (UInt64)shapeKey; | 201 | newShape.isNativeShape = true; |
167 | */ | 202 | newShape.shapeKey = (UInt64)shapeKey; |
168 | } | 203 | return newShape; |
169 | // Make this reference to the physical shape go away since native shapes are not shared. | ||
170 | public override void Dereference(BSScene physicsScene) | ||
171 | { | ||
172 | /* | ||
173 | // Native shapes are not tracked and are released immediately | ||
174 | physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); | ||
175 | PhysicsScene.PE.DeleteCollisionShape(physicsScene.World, this); | ||
176 | ptr = IntPtr.Zero; | ||
177 | // Garbage collection will free up this instance. | ||
178 | */ | ||
179 | } | 204 | } |
205 | |||
180 | } | 206 | } |
181 | 207 | ||
208 | // ============================================================================================================ | ||
182 | public class BSShapeMesh : BSShape | 209 | public class BSShapeMesh : BSShape |
183 | { | 210 | { |
184 | private static string LogHeader = "[BULLETSIM SHAPE MESH]"; | 211 | private static string LogHeader = "[BULLETSIM SHAPE MESH]"; |
185 | private static Dictionary<System.UInt64, BSShapeMesh> Meshes = new Dictionary<System.UInt64, BSShapeMesh>(); | 212 | private static Dictionary<System.UInt64, BSShapeMesh> Meshes = new Dictionary<System.UInt64, BSShapeMesh>(); |
186 | 213 | ||
187 | public BSShapeMesh() : base() | 214 | public BSShapeMesh(BulletShape pShape) : base(pShape) |
188 | { | 215 | { |
189 | } | 216 | } |
190 | public static BSShape GetReference() { return new BSShapeNull(); } | 217 | public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) |
191 | public override void Dereference(BSScene physicsScene) { } | 218 | { |
219 | float lod; | ||
220 | System.UInt64 newMeshKey = BSShapeCollection.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | ||
221 | |||
222 | physicsScene.DetailLog("{0},BSShapeMesh,create,oldKey={1},newKey={2},size={3},lod={4}", | ||
223 | prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"), prim.Size, lod); | ||
224 | |||
225 | BSShapeMesh retMesh; | ||
226 | lock (Meshes) | ||
227 | { | ||
228 | if (Meshes.TryGetValue(newMeshKey, out retMesh)) | ||
229 | { | ||
230 | // The mesh has already been created. Return a new reference to same. | ||
231 | retMesh.IncrementReference(); | ||
232 | } | ||
233 | else | ||
234 | { | ||
235 | // An instance of this mesh has not been created. Build and remember same. | ||
236 | BulletShape newShape = CreatePhysicalMesh(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod); | ||
237 | // Take evasive action if the mesh was not constructed. | ||
238 | newShape = BSShapeCollection.VerifyMeshCreated(physicsScene, newShape, prim); | ||
239 | |||
240 | retMesh = new BSShapeMesh(newShape); | ||
241 | |||
242 | Meshes.Add(newMeshKey, retMesh); | ||
243 | } | ||
244 | } | ||
245 | return retMesh; | ||
246 | } | ||
247 | public override void Dereference(BSScene physicsScene) | ||
248 | { | ||
249 | lock (Meshes) | ||
250 | { | ||
251 | this.DecrementReference(); | ||
252 | // TODO: schedule aging and destruction of unused meshes. | ||
253 | } | ||
254 | } | ||
255 | |||
256 | private static BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
257 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | ||
258 | { | ||
259 | BulletShape newShape = null; | ||
260 | |||
261 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, | ||
262 | false, // say it is not physical so a bounding box is not built | ||
263 | false // do not cache the mesh and do not use previously built versions | ||
264 | ); | ||
265 | |||
266 | if (meshData != null) | ||
267 | { | ||
268 | |||
269 | int[] indices = meshData.getIndexListAsInt(); | ||
270 | int realIndicesIndex = indices.Length; | ||
271 | float[] verticesAsFloats = meshData.getVertexListAsFloat(); | ||
272 | |||
273 | if (BSParam.ShouldRemoveZeroWidthTriangles) | ||
274 | { | ||
275 | // Remove degenerate triangles. These are triangles with two of the vertices | ||
276 | // are the same. This is complicated by the problem that vertices are not | ||
277 | // made unique in sculpties so we have to compare the values in the vertex. | ||
278 | realIndicesIndex = 0; | ||
279 | for (int tri = 0; tri < indices.Length; tri += 3) | ||
280 | { | ||
281 | // Compute displacements into vertex array for each vertex of the triangle | ||
282 | int v1 = indices[tri + 0] * 3; | ||
283 | int v2 = indices[tri + 1] * 3; | ||
284 | int v3 = indices[tri + 2] * 3; | ||
285 | // Check to see if any two of the vertices are the same | ||
286 | if (!( ( verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0] | ||
287 | && verticesAsFloats[v1 + 1] == verticesAsFloats[v2 + 1] | ||
288 | && verticesAsFloats[v1 + 2] == verticesAsFloats[v2 + 2]) | ||
289 | || ( verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0] | ||
290 | && verticesAsFloats[v2 + 1] == verticesAsFloats[v3 + 1] | ||
291 | && verticesAsFloats[v2 + 2] == verticesAsFloats[v3 + 2]) | ||
292 | || ( verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0] | ||
293 | && verticesAsFloats[v1 + 1] == verticesAsFloats[v3 + 1] | ||
294 | && verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2]) ) | ||
295 | ) | ||
296 | { | ||
297 | // None of the vertices of the triangles are the same. This is a good triangle; | ||
298 | indices[realIndicesIndex + 0] = indices[tri + 0]; | ||
299 | indices[realIndicesIndex + 1] = indices[tri + 1]; | ||
300 | indices[realIndicesIndex + 2] = indices[tri + 2]; | ||
301 | realIndicesIndex += 3; | ||
302 | } | ||
303 | } | ||
304 | } | ||
305 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,origTri={1},realTri={2},numVerts={3}", | ||
306 | BSScene.DetailLogZero, indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3); | ||
307 | |||
308 | if (realIndicesIndex != 0) | ||
309 | { | ||
310 | newShape = physicsScene.PE.CreateMeshShape(physicsScene.World, | ||
311 | realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); | ||
312 | } | ||
313 | else | ||
314 | { | ||
315 | physicsScene.Logger.DebugFormat("{0} All mesh triangles degenerate. Prim {1} at {2} in {3}", | ||
316 | LogHeader, prim.PhysObjectName, prim.RawPosition, physicsScene.Name); | ||
317 | } | ||
318 | } | ||
319 | newShape.shapeKey = newMeshKey; | ||
320 | |||
321 | return newShape; | ||
322 | } | ||
192 | } | 323 | } |
193 | 324 | ||
325 | // ============================================================================================================ | ||
194 | public class BSShapeHull : BSShape | 326 | public class BSShapeHull : BSShape |
195 | { | 327 | { |
196 | private static string LogHeader = "[BULLETSIM SHAPE HULL]"; | 328 | private static string LogHeader = "[BULLETSIM SHAPE HULL]"; |
197 | private static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>(); | 329 | private static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>(); |
198 | 330 | ||
199 | public BSShapeHull() : base() | 331 | public BSShapeHull(BulletShape pShape) : base(pShape) |
332 | { | ||
333 | } | ||
334 | public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | ||
335 | { | ||
336 | return new BSShapeNull(); | ||
337 | } | ||
338 | public override void Dereference(BSScene physicsScene) | ||
200 | { | 339 | { |
201 | } | 340 | } |
202 | public static BSShape GetReference() { return new BSShapeNull(); } | ||
203 | public override void Dereference(BSScene physicsScene) { } | ||
204 | } | 341 | } |
205 | 342 | ||
343 | // ============================================================================================================ | ||
206 | public class BSShapeCompound : BSShape | 344 | public class BSShapeCompound : BSShape |
207 | { | 345 | { |
208 | private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; | 346 | private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; |
@@ -216,6 +354,7 @@ public class BSShapeCompound : BSShape | |||
216 | public override void Dereference(BSScene physicsScene) { } | 354 | public override void Dereference(BSScene physicsScene) { } |
217 | } | 355 | } |
218 | 356 | ||
357 | // ============================================================================================================ | ||
219 | public class BSShapeAvatar : BSShape | 358 | public class BSShapeAvatar : BSShape |
220 | { | 359 | { |
221 | private static string LogHeader = "[BULLETSIM SHAPE AVATAR]"; | 360 | private static string LogHeader = "[BULLETSIM SHAPE AVATAR]"; |