From 80a2b81d52de3c053ce00f1f54751c7a931dad23 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 26 Aug 2011 21:26:26 -0700 Subject: Add level of detail specification to optionally reduce the number of vertices in generated prim meshes Signed-off-by: BlueWall --- OpenSim/Region/Physics/Manager/IMesher.cs | 11 ++++++++ OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 36 +++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/Physics') 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 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); } + // Values for level of detail to be passed to the mesher. + // Values origionally chosen for the LOD of sculpties (the sqrt(width*heigth) of sculpt texture) + // Lower level of detail reduces the number of vertices used to represent the meshed shape. + public enum LevelOfDetail + { + High = 32, + Medium = 16, + Low = 8, + VeryLow = 4 + } + public interface IVertex { } diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index e81b982..faecce4 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -336,7 +336,7 @@ namespace OpenSim.Region.Physics.Meshing } else { - if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, out coords, out faces)) + if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces)) return null; } @@ -616,7 +616,7 @@ namespace OpenSim.Region.Physics.Meshing /// Faces are added to this list by the method. /// true if coords and faces were successfully generated, false if not private bool GenerateCoordsAndFacesFromPrimShapeData( - string primName, PrimitiveBaseShape primShape, Vector3 size, out List coords, out List faces) + string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List coords, out List faces) { PrimMesh primMesh; coords = new List(); @@ -636,13 +636,30 @@ namespace OpenSim.Region.Physics.Meshing profileHollow = 0.95f; int sides = 4; + LevelOfDetail iLOD = (LevelOfDetail)lod; if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) sides = 3; else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) - sides = 24; + { + switch (iLOD) + { + case LevelOfDetail.High: sides = 24; break; + case LevelOfDetail.Medium: sides = 12; break; + case LevelOfDetail.Low: sides = 6; break; + case LevelOfDetail.VeryLow: sides = 3; break; + default: sides = 24; break; + } + } else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) { // half circle, prim is a sphere - sides = 24; + switch (iLOD) + { + case LevelOfDetail.High: sides = 24; break; + case LevelOfDetail.Medium: sides = 12; break; + case LevelOfDetail.Low: sides = 6; break; + case LevelOfDetail.VeryLow: sides = 3; break; + default: sides = 24; break; + } profileBegin = 0.5f * profileBegin + 0.5f; profileEnd = 0.5f * profileEnd + 0.5f; @@ -650,7 +667,16 @@ namespace OpenSim.Region.Physics.Meshing int hollowSides = sides; if (primShape.HollowShape == HollowShape.Circle) - hollowSides = 24; + { + switch (iLOD) + { + case LevelOfDetail.High: hollowSides = 24; break; + case LevelOfDetail.Medium: hollowSides = 12; break; + case LevelOfDetail.Low: hollowSides = 6; break; + case LevelOfDetail.VeryLow: hollowSides = 3; break; + default: hollowSides = 24; break; + } + } else if (primShape.HollowShape == HollowShape.Square) hollowSides = 4; else if (primShape.HollowShape == HollowShape.Triangle) -- cgit v1.1 From 18037d41c45b7a00170a7badddd3ef1d8ad2a25c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 26 Aug 2011 20:51:05 -0700 Subject: Move GetMeshKey from buried inside Meshmerizer to a public method on PrimitiveBaseShape Signed-off-by: BlueWall --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 63 +-------------------------- 1 file changed, 1 insertion(+), 62 deletions(-) (limited to 'OpenSim/Region/Physics') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index faecce4..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 m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString()); } - private ulong GetMeshKey(PrimitiveBaseShape pbs, Vector3 size, float lod) - { - ulong hash = 5381; - - hash = djb2(hash, pbs.PathCurve); - hash = djb2(hash, (byte)((byte)pbs.HollowShape | (byte)pbs.ProfileShape)); - hash = djb2(hash, pbs.PathBegin); - hash = djb2(hash, pbs.PathEnd); - hash = djb2(hash, pbs.PathScaleX); - hash = djb2(hash, pbs.PathScaleY); - hash = djb2(hash, pbs.PathShearX); - hash = djb2(hash, pbs.PathShearY); - hash = djb2(hash, (byte)pbs.PathTwist); - hash = djb2(hash, (byte)pbs.PathTwistBegin); - hash = djb2(hash, (byte)pbs.PathRadiusOffset); - hash = djb2(hash, (byte)pbs.PathTaperX); - hash = djb2(hash, (byte)pbs.PathTaperY); - hash = djb2(hash, pbs.PathRevolutions); - hash = djb2(hash, (byte)pbs.PathSkew); - hash = djb2(hash, pbs.ProfileBegin); - hash = djb2(hash, pbs.ProfileEnd); - hash = djb2(hash, pbs.ProfileHollow); - - // TODO: Separate scale out from the primitive shape data (after - // scaling is supported at the physics engine level) - byte[] scaleBytes = size.GetBytes(); - for (int i = 0; i < scaleBytes.Length; i++) - hash = djb2(hash, scaleBytes[i]); - - // Include LOD in hash, accounting for endianness - byte[] lodBytes = new byte[4]; - Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4); - if (!BitConverter.IsLittleEndian) - { - Array.Reverse(lodBytes, 0, 4); - } - for (int i = 0; i < lodBytes.Length; i++) - hash = djb2(hash, lodBytes[i]); - - // include sculpt UUID - if (pbs.SculptEntry) - { - scaleBytes = pbs.SculptTexture.GetBytes(); - for (int i = 0; i < scaleBytes.Length; i++) - hash = djb2(hash, scaleBytes[i]); - } - - return hash; - } - - private ulong djb2(ulong hash, byte c) - { - return ((hash << 5) + hash) + (ulong)c; - } - - private ulong djb2(ulong hash, ushort c) - { - hash = ((hash << 5) + hash) + (ulong)((byte)c); - return ((hash << 5) + hash) + (ulong)(c >> 8); - } - /// /// Add a submesh to an existing list of coords and faces. /// @@ -777,7 +716,7 @@ namespace OpenSim.Region.Physics.Meshing // If this mesh has been created already, return it instead of creating another copy // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory - key = GetMeshKey(primShape, size, lod); + key = primShape.GetMeshKey(size, lod); if (m_uniqueMeshes.TryGetValue(key, out mesh)) return mesh; -- cgit v1.1