aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/Manager/IMesher.cs11
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs99
2 files changed, 43 insertions, 67 deletions
diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs
index 1181b8d..3a9ca1b 100644
--- a/OpenSim/Region/Physics/Manager/IMesher.cs
+++ b/OpenSim/Region/Physics/Manager/IMesher.cs
@@ -38,6 +38,17 @@ namespace OpenSim.Region.Physics.Manager
38 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); 38 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical);
39 } 39 }
40 40
41 // Values for level of detail to be passed to the mesher.
42 // Values origionally chosen for the LOD of sculpties (the sqrt(width*heigth) of sculpt texture)
43 // Lower level of detail reduces the number of vertices used to represent the meshed shape.
44 public enum LevelOfDetail
45 {
46 High = 32,
47 Medium = 16,
48 Low = 8,
49 VeryLow = 4
50 }
51
41 public interface IVertex 52 public interface IVertex
42 { 53 {
43 } 54 }
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index e81b982..53d5e4c 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -193,67 +193,6 @@ namespace OpenSim.Region.Physics.Meshing
193 m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString()); 193 m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString());
194 } 194 }
195 195
196 private ulong GetMeshKey(PrimitiveBaseShape pbs, Vector3 size, float lod)
197 {
198 ulong hash = 5381;
199
200 hash = djb2(hash, pbs.PathCurve);
201 hash = djb2(hash, (byte)((byte)pbs.HollowShape | (byte)pbs.ProfileShape));
202 hash = djb2(hash, pbs.PathBegin);
203 hash = djb2(hash, pbs.PathEnd);
204 hash = djb2(hash, pbs.PathScaleX);
205 hash = djb2(hash, pbs.PathScaleY);
206 hash = djb2(hash, pbs.PathShearX);
207 hash = djb2(hash, pbs.PathShearY);
208 hash = djb2(hash, (byte)pbs.PathTwist);
209 hash = djb2(hash, (byte)pbs.PathTwistBegin);
210 hash = djb2(hash, (byte)pbs.PathRadiusOffset);
211 hash = djb2(hash, (byte)pbs.PathTaperX);
212 hash = djb2(hash, (byte)pbs.PathTaperY);
213 hash = djb2(hash, pbs.PathRevolutions);
214 hash = djb2(hash, (byte)pbs.PathSkew);
215 hash = djb2(hash, pbs.ProfileBegin);
216 hash = djb2(hash, pbs.ProfileEnd);
217 hash = djb2(hash, pbs.ProfileHollow);
218
219 // TODO: Separate scale out from the primitive shape data (after
220 // scaling is supported at the physics engine level)
221 byte[] scaleBytes = size.GetBytes();
222 for (int i = 0; i < scaleBytes.Length; i++)
223 hash = djb2(hash, scaleBytes[i]);
224
225 // Include LOD in hash, accounting for endianness
226 byte[] lodBytes = new byte[4];
227 Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4);
228 if (!BitConverter.IsLittleEndian)
229 {
230 Array.Reverse(lodBytes, 0, 4);
231 }
232 for (int i = 0; i < lodBytes.Length; i++)
233 hash = djb2(hash, lodBytes[i]);
234
235 // include sculpt UUID
236 if (pbs.SculptEntry)
237 {
238 scaleBytes = pbs.SculptTexture.GetBytes();
239 for (int i = 0; i < scaleBytes.Length; i++)
240 hash = djb2(hash, scaleBytes[i]);
241 }
242
243 return hash;
244 }
245
246 private ulong djb2(ulong hash, byte c)
247 {
248 return ((hash << 5) + hash) + (ulong)c;
249 }
250
251 private ulong djb2(ulong hash, ushort c)
252 {
253 hash = ((hash << 5) + hash) + (ulong)((byte)c);
254 return ((hash << 5) + hash) + (ulong)(c >> 8);
255 }
256
257 /// <summary> 196 /// <summary>
258 /// Add a submesh to an existing list of coords and faces. 197 /// Add a submesh to an existing list of coords and faces.
259 /// </summary> 198 /// </summary>
@@ -336,7 +275,7 @@ namespace OpenSim.Region.Physics.Meshing
336 } 275 }
337 else 276 else
338 { 277 {
339 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, out coords, out faces)) 278 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
340 return null; 279 return null;
341 } 280 }
342 281
@@ -616,7 +555,7 @@ namespace OpenSim.Region.Physics.Meshing
616 /// <param name="faces">Faces are added to this list by the method.</param> 555 /// <param name="faces">Faces are added to this list by the method.</param>
617 /// <returns>true if coords and faces were successfully generated, false if not</returns> 556 /// <returns>true if coords and faces were successfully generated, false if not</returns>
618 private bool GenerateCoordsAndFacesFromPrimShapeData( 557 private bool GenerateCoordsAndFacesFromPrimShapeData(
619 string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces) 558 string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List<Coord> coords, out List<Face> faces)
620 { 559 {
621 PrimMesh primMesh; 560 PrimMesh primMesh;
622 coords = new List<Coord>(); 561 coords = new List<Coord>();
@@ -636,13 +575,30 @@ namespace OpenSim.Region.Physics.Meshing
636 profileHollow = 0.95f; 575 profileHollow = 0.95f;
637 576
638 int sides = 4; 577 int sides = 4;
578 LevelOfDetail iLOD = (LevelOfDetail)lod;
639 if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) 579 if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
640 sides = 3; 580 sides = 3;
641 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) 581 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
642 sides = 24; 582 {
583 switch (iLOD)
584 {
585 case LevelOfDetail.High: sides = 24; break;
586 case LevelOfDetail.Medium: sides = 12; break;
587 case LevelOfDetail.Low: sides = 6; break;
588 case LevelOfDetail.VeryLow: sides = 3; break;
589 default: sides = 24; break;
590 }
591 }
643 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) 592 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
644 { // half circle, prim is a sphere 593 { // half circle, prim is a sphere
645 sides = 24; 594 switch (iLOD)
595 {
596 case LevelOfDetail.High: sides = 24; break;
597 case LevelOfDetail.Medium: sides = 12; break;
598 case LevelOfDetail.Low: sides = 6; break;
599 case LevelOfDetail.VeryLow: sides = 3; break;
600 default: sides = 24; break;
601 }
646 602
647 profileBegin = 0.5f * profileBegin + 0.5f; 603 profileBegin = 0.5f * profileBegin + 0.5f;
648 profileEnd = 0.5f * profileEnd + 0.5f; 604 profileEnd = 0.5f * profileEnd + 0.5f;
@@ -650,7 +606,16 @@ namespace OpenSim.Region.Physics.Meshing
650 606
651 int hollowSides = sides; 607 int hollowSides = sides;
652 if (primShape.HollowShape == HollowShape.Circle) 608 if (primShape.HollowShape == HollowShape.Circle)
653 hollowSides = 24; 609 {
610 switch (iLOD)
611 {
612 case LevelOfDetail.High: hollowSides = 24; break;
613 case LevelOfDetail.Medium: hollowSides = 12; break;
614 case LevelOfDetail.Low: hollowSides = 6; break;
615 case LevelOfDetail.VeryLow: hollowSides = 3; break;
616 default: hollowSides = 24; break;
617 }
618 }
654 else if (primShape.HollowShape == HollowShape.Square) 619 else if (primShape.HollowShape == HollowShape.Square)
655 hollowSides = 4; 620 hollowSides = 4;
656 else if (primShape.HollowShape == HollowShape.Triangle) 621 else if (primShape.HollowShape == HollowShape.Triangle)
@@ -751,7 +716,7 @@ namespace OpenSim.Region.Physics.Meshing
751 716
752 // If this mesh has been created already, return it instead of creating another copy 717 // If this mesh has been created already, return it instead of creating another copy
753 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory 718 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
754 key = GetMeshKey(primShape, size, lod); 719 key = primShape.GetMeshKey(size, lod);
755 if (m_uniqueMeshes.TryGetValue(key, out mesh)) 720 if (m_uniqueMeshes.TryGetValue(key, out mesh))
756 return mesh; 721 return mesh;
757 722