aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/Meshmerizer.cs')
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs69
1 files changed, 63 insertions, 6 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index aa8df23..d56ddc8 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -76,6 +76,7 @@ namespace OpenSim.Region.Physics.Meshing
76 76
77 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 77 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
78 78
79 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
79 80
80 public Meshmerizer() 81 public Meshmerizer()
81 { 82 {
@@ -184,9 +185,62 @@ namespace OpenSim.Region.Physics.Meshing
184 185
185 } 186 }
186 187
187 public Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod) 188 private ulong GetMeshKey(PrimitiveBaseShape pbs, PhysicsVector size, float lod)
189 {
190 ulong hash = 5381;
191
192 hash = djb2(hash, pbs.PathCurve);
193 hash = djb2(hash, (byte)((byte)pbs.HollowShape | (byte)pbs.ProfileShape));
194 hash = djb2(hash, pbs.PathBegin);
195 hash = djb2(hash, pbs.PathEnd);
196 hash = djb2(hash, pbs.PathScaleX);
197 hash = djb2(hash, pbs.PathScaleY);
198 hash = djb2(hash, pbs.PathShearX);
199 hash = djb2(hash, pbs.PathShearY);
200 hash = djb2(hash, (byte)pbs.PathTwist);
201 hash = djb2(hash, (byte)pbs.PathTwistBegin);
202 hash = djb2(hash, (byte)pbs.PathRadiusOffset);
203 hash = djb2(hash, (byte)pbs.PathTaperX);
204 hash = djb2(hash, (byte)pbs.PathTaperY);
205 hash = djb2(hash, pbs.PathRevolutions);
206 hash = djb2(hash, (byte)pbs.PathSkew);
207 hash = djb2(hash, pbs.ProfileBegin);
208 hash = djb2(hash, pbs.ProfileEnd);
209 hash = djb2(hash, pbs.ProfileHollow);
210
211 // TODO: Separate scale out from the primitive shape data (after
212 // scaling is supported at the physics engine level)
213 byte[] scaleBytes = size.GetBytes();
214 for (int i = 0; i < scaleBytes.Length; i++)
215 hash = djb2(hash, scaleBytes[i]);
216
217 // Include LOD in hash, accounting for endianness
218 byte[] lodBytes = new byte[4];
219 Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4);
220 if (!BitConverter.IsLittleEndian)
221 {
222 Array.Reverse(lodBytes, 0, 4);
223 }
224 for (int i = 0; i < lodBytes.Length; i++)
225 hash = djb2(hash, lodBytes[i]);
226
227 return hash;
228 }
229
230 private ulong djb2(ulong hash, byte c)
231 {
232 return ((hash << 5) + hash) + (ulong)c;
233 }
234
235 private ulong djb2(ulong hash, ushort c)
236 {
237 hash = ((hash << 5) + hash) + (ulong)((byte)c);
238 return ((hash << 5) + hash) + (ulong)(c >> 8);
239 }
240
241
242 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod)
188 { 243 {
189 Mesh mesh = new Mesh();
190 PrimMesh primMesh; 244 PrimMesh primMesh;
191 PrimMesher.SculptMesh sculptMesh; 245 PrimMesher.SculptMesh sculptMesh;
192 246
@@ -399,8 +453,6 @@ namespace OpenSim.Region.Physics.Meshing
399 453
400 coords = primMesh.coords; 454 coords = primMesh.coords;
401 faces = primMesh.faces; 455 faces = primMesh.faces;
402
403
404 } 456 }
405 457
406 458
@@ -415,13 +467,13 @@ namespace OpenSim.Region.Physics.Meshing
415 vertices.Add(new Vertex(c.X, c.Y, c.Z)); 467 vertices.Add(new Vertex(c.X, c.Y, c.Z));
416 } 468 }
417 469
470 Mesh mesh = new Mesh();
418 // Add the corresponding triangles to the mesh 471 // Add the corresponding triangles to the mesh
419 for (int i = 0; i < numFaces; i++) 472 for (int i = 0; i < numFaces; i++)
420 { 473 {
421 Face f = faces[i]; 474 Face f = faces[i];
422 mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3])); 475 mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
423 } 476 }
424
425 return mesh; 477 return mesh;
426 } 478 }
427 479
@@ -432,7 +484,12 @@ namespace OpenSim.Region.Physics.Meshing
432 484
433 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod, bool isPhysical) 485 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod, bool isPhysical)
434 { 486 {
487 // If this mesh has been created already, return it instead of creating another copy
488 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
489 ulong key = GetMeshKey(primShape, size, lod);
435 Mesh mesh = null; 490 Mesh mesh = null;
491 if (m_uniqueMeshes.TryGetValue(key, out mesh))
492 return mesh;
436 493
437 if (size.X < 0.01f) size.X = 0.01f; 494 if (size.X < 0.01f) size.X = 0.01f;
438 if (size.Y < 0.01f) size.Y = 0.01f; 495 if (size.Y < 0.01f) size.Y = 0.01f;
@@ -455,7 +512,7 @@ namespace OpenSim.Region.Physics.Meshing
455 // trim the vertex and triangle lists to free up memory 512 // trim the vertex and triangle lists to free up memory
456 mesh.TrimExcess(); 513 mesh.TrimExcess();
457 } 514 }
458 515 m_uniqueMeshes.Add(key, mesh);
459 return mesh; 516 return mesh;
460 } 517 }
461 } 518 }