aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs215
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;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Text; 30using System.Text;
31 31
32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager;
34
32using OMV = OpenMetaverse; 35using OMV = OpenMetaverse;
33 36
34namespace OpenSim.Region.Physics.BulletSPlugin 37namespace 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// ============================================================================================================
115public class BSShapeNull : BSShape 136public 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// ============================================================================================================
124public class BSShapeNative : BSShape 146public 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// ============================================================================================================
182public class BSShapeMesh : BSShape 209public 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// ============================================================================================================
194public class BSShapeHull : BSShape 326public 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// ============================================================================================================
206public class BSShapeCompound : BSShape 344public 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// ============================================================================================================
219public class BSShapeAvatar : BSShape 358public class BSShapeAvatar : BSShape
220{ 359{
221 private static string LogHeader = "[BULLETSIM SHAPE AVATAR]"; 360 private static string LogHeader = "[BULLETSIM SHAPE AVATAR]";