public MeshingResult CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, OpenMetaverse.Vector3 size, float lod, ShapeType desiredShape, bool preScale) { Vector3 szvec = new Vector3(size.X, size.Y, size.Z); ulong meshKey = primShape.GetMeshKey(szvec, lod); try { if (primShape.SculptEntry && ((primShape.SculptData == null) || (primShape.SculptData.Length == 0))) { //preload the sculpt/mesh data AssetBase asset = _assetCache.GetAsset(primShape.SculptTexture, AssetRequestInfo.InternalRequest()); if (asset == null) { return(null); } primShape.SculptData = asset.Data; } if (primShape.SculptEntry == false || (primShape.SculptEntry == true && (SculptType)primShape.SculptType != SculptType.Mesh)) { return(ExtractTrimeshFromPrimOrSculpt(primName, primShape, ref size, lod, preScale, meshKey)); } else //mesh { return(ExtractMeshingResultFromMesh(primName, primShape, ref size, lod, preScale, desiredShape, meshKey)); } } finally { //we dont need the sculpt data around anymore primShape.SculptData = null; } }
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) { Mesh mesh = null; ulong key = primShape.GetMeshKey(size, lod); if (size.X < 0.01f) { size.X = 0.01f; } if (size.Y < 0.01f) { size.Y = 0.01f; } if (size.Z < 0.01f) { size.Z = 0.01f; } if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh) { mesh = CreateBoundingBoxMesh(size, key); } else { mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod, key); } return(mesh); }
// Main mesh creation entry point public IMesh CreateMesh(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) { #if SPAM MainConsole.Instance.DebugFormat("[Mesh]: Creating mesh for {0}", primName); #endif Mesh mesh; ulong key = 0; // If caching and this mesh has been created already, return it instead of creating another copy if (shouldCache) { key = primShape.GetMeshKey(size, lod); lock (m_uniqueMeshes) { if (m_uniqueMeshes.TryGetValue(key, out mesh)) { return(mesh); } } } // set miniumm sizes if (size.X < 0.01f) { size.X = 0.01f; } if (size.Y < 0.01f) { size.Y = 0.01f; } if (size.Z < 0.01f) { size.Z = 0.01f; } mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod, key); if (mesh != null) { if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh) { mesh = CreateBoundingBoxMesh(size, key); } #if SPAM MainConsole.Instance.Debug("Meshmerizer: prim " + primName + " has a size of " + size.ToString() + " which is below threshold of " + minSizeForComplexMesh.ToString() + " - creating simple bounding box"); //mesh.DumpRaw(baseDir, primName, "Z extruded"); #endif // cache newly created mesh? if (shouldCache) { lock (m_uniqueMeshes) { m_uniqueMeshes.Add(key, mesh); } } } return(mesh); }
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) { #if SPAM m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName); #endif Mesh mesh = null; ulong key = 0; // 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 if (shouldCache) { key = primShape.GetMeshKey(size, lod); if (m_uniqueMeshes.TryGetValue(key, out mesh)) { return(mesh); } } if (size.X < 0.01f) { size.X = 0.01f; } if (size.Y < 0.01f) { size.Y = 0.01f; } if (size.Z < 0.01f) { size.Z = 0.01f; } mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod); if (mesh != null) { if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh) { #if SPAM m_log.Debug("Meshmerizer: prim " + primName + " has a size of " + size.ToString() + " which is below threshold of " + minSizeForComplexMesh.ToString() + " - creating simple bounding box"); #endif mesh = CreateBoundingBoxMesh(mesh); mesh.DumpRaw(baseDir, primName, "Z extruded"); } // trim the vertex and triangle lists to free up memory mesh.TrimExcess(); if (shouldCache) { m_uniqueMeshes.Add(key, mesh); } } return(mesh); }
private HacdConvexHull[] DecomposeWithRatcliff(PrimitiveBaseShape shape, float LOD, IMesh mesh) { List <int> indexes = mesh.getIndexListAsIntList(); List <float3> verts = mesh.getVertexListAsFloat3(); RatcliffACD rcAcd = new RatcliffACD(); HacdConvexHull[] hulls = rcAcd.DecomposeToConvexHulls(shape.GetMeshKey(OpenMetaverse.Vector3.One, LOD), true, verts, indexes); return(hulls); }
// Main mesh creation entry point public IMesh CreateMesh(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) { #if SPAM MainConsole.Instance.DebugFormat("[Mesh]: Creating mesh for {0}", primName); #endif Mesh mesh; ulong key = primShape.GetMeshKey(size, lod); // If caching and this mesh has been created already, return it instead of creating another copy if (shouldCache) { lock (m_uniqueMeshes) { if (m_uniqueMeshes.TryGetValue(key, out mesh)) { return(mesh); } } } // set miniumm sizes if (size.X < 0.01f) { size.X = 0.01f; } if (size.Y < 0.01f) { size.Y = 0.01f; } if (size.Z < 0.01f) { size.Z = 0.01f; } if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh) { mesh = CreateBoundingBoxMesh(size, key); } else { mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod, key); } // cache newly created mesh? if (shouldCache) { lock (m_uniqueMeshes) { m_uniqueMeshes.Add(key, mesh); } } return(mesh); }
// Create a hash of all the shape parameters to be used as a key // for this particular shape. private ulong ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod) { // level of detail based on size and type of the object float lod = PhysicsScene.MeshLOD; if (pbs.SculptEntry) { lod = PhysicsScene.SculptLOD; } float maxAxis = Math.Max(shapeData.Size.X, Math.Max(shapeData.Size.Y, shapeData.Size.Z)); if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) { lod = PhysicsScene.MeshMegaPrimLOD; } retLod = lod; return((ulong)pbs.GetMeshKey(shapeData.Size, lod)); }
// Create a hash of all the shape parameters to be used as a key // for this particular shape. private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) { // level of detail based on size and type of the object float lod = BSParam.MeshLOD; if (pbs.SculptEntry) { lod = BSParam.SculptLOD; } // Mega prims usually get more detail because one can interact with shape approximations at this size. float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z)); if (maxAxis > BSParam.MeshMegaPrimThreshold) { lod = BSParam.MeshMegaPrimLOD; } retLod = lod; return(pbs.GetMeshKey(size, lod)); }
private static HacdConvexHull[] DecomposeWithHACD(PrimitiveBaseShape shape, float LOD, IMesh mesh) { int[] indexes = mesh.getIndexListAsInt(); float[] verts = mesh.getVertexListAsFloat(); mesh.ReleaseSourceMeshData(); HacdPreset preset; if (shape.SculptEntry) { preset = Hacd.SculptDefaultPreset; } else { preset = Hacd.PrimDefaultPreset; } //we cant use the hash we have here, as Hacd needs the mesh hash prescaled HacdConvexHull[] hulls = Hacd.DecomposeToConvexHulls(shape.GetMeshKey(OpenMetaverse.Vector3.One, LOD), shape.SculptEntry == false, preset, verts, indexes); return(hulls); }
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) { Mesh mesh = null; ulong key = primShape.GetMeshKey(size, lod); if (size.X < 0.01f) size.X = 0.01f; if (size.Y < 0.01f) size.Y = 0.01f; if (size.Z < 0.01f) size.Z = 0.01f; if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh) mesh = CreateBoundingBoxMesh(size, key); else mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod, key); return mesh; }
// Create a hash of all the shape parameters to be used as a key for this particular shape. public static System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) { // level of detail based on size and type of the object float lod = BSParam.MeshLOD; if (pbs.SculptEntry) lod = BSParam.SculptLOD; // Mega prims usually get more detail because one can interact with shape approximations at this size. float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z)); if (maxAxis > BSParam.MeshMegaPrimThreshold) lod = BSParam.MeshMegaPrimLOD; retLod = lod; return pbs.GetMeshKey(size, lod); }
// Main mesh creation entry point public IMesh CreateMesh (string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) { #if SPAM MainConsole.Instance.DebugFormat("[Mesh]: Creating mesh for {0}", primName); #endif Mesh mesh; ulong key = 0; // If caching and this mesh has been created already, return it instead of creating another copy if (shouldCache) { key = primShape.GetMeshKey (size, lod); lock (m_uniqueMeshes) { if (m_uniqueMeshes.TryGetValue (key, out mesh)) return mesh; } } // set miniumm sizes if (size.X < 0.01f) size.X = 0.01f; if (size.Y < 0.01f) size.Y = 0.01f; if (size.Z < 0.01f) size.Z = 0.01f; mesh = CreateMeshFromPrimMesher (primName, primShape, size, lod, key); if (mesh != null) { if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh) mesh = CreateBoundingBoxMesh (size, key); #if SPAM MainConsole.Instance.Debug("Meshmerizer: prim " + primName + " has a size of " + size.ToString() + " which is below threshold of " + minSizeForComplexMesh.ToString() + " - creating simple bounding box"); //mesh.DumpRaw(baseDir, primName, "Z extruded"); #endif // cache newly created mesh? if (shouldCache) { lock (m_uniqueMeshes) { m_uniqueMeshes.Add (key, mesh); } } } return mesh; }
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) { Mesh mesh; ulong key = primShape.GetMeshKey(size, lod); // If this mesh has been created already, return it instead of creating another copy lock (m_uniqueMeshes) { if (m_uniqueMeshes.TryGetValue(key, out mesh)) return mesh; } // set miniumm sizes if (size.X < 0.01f) size.X = 0.01f; if (size.Y < 0.01f) size.Y = 0.01f; if (size.Z < 0.01f) size.Z = 0.01f; if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh) mesh = CreateBoundingBoxMesh(size, key); else mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod, key); // cache newly created mesh's lock (m_uniqueMeshes) { m_uniqueMeshes.Add(key, mesh); } return mesh; }
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, out List <List <Vector3> > hulls, out List <Vector3> boundingHull) { #if SPAM m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName); #endif Mesh mesh = null; ulong key = 0; // 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 m_uniqueMeshesRwLock.AcquireReaderLock(-1); try { if (shouldCache) { key = primShape.GetMeshKey(size, lod); if (m_uniqueMeshes.TryGetValue(key, out mesh)) { m_uniqueMeshesBoundingHulls.TryGetValue(key, out boundingHull); m_uniqueMeshesHulls.TryGetValue(key, out hulls); return(mesh); } } LockCookie lc = m_uniqueMeshesRwLock.UpgradeToWriterLock(-1); try { /* recheck since we allow a lot of threading here */ if (shouldCache) { if (m_uniqueMeshes.TryGetValue(key, out mesh)) { m_uniqueMeshesBoundingHulls.TryGetValue(key, out boundingHull); m_uniqueMeshesHulls.TryGetValue(key, out hulls); return(mesh); } } if (size.X < 0.01f) { size.X = 0.01f; } if (size.Y < 0.01f) { size.Y = 0.01f; } if (size.Z < 0.01f) { size.Z = 0.01f; } List <List <Vector3> > inhulls; List <Vector3> inboundingHull; mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod, out inhulls, out inboundingHull); if (inhulls != null) { hulls = new List <List <Vector3> >(); foreach (var hull in inhulls) { List <Vector3> verts = new List <Vector3>(); foreach (var vert in hull) { verts.Add(vert * size); } hulls.Add(verts); } } else { hulls = null; } if (inboundingHull != null) { boundingHull = new List <Vector3>(); foreach (var vert in inboundingHull) { boundingHull.Add(vert * size); } } else { boundingHull = null; } if (mesh != null) { if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh) { #if SPAM m_log.Debug("Meshmerizer: prim " + primName + " has a size of " + size.ToString() + " which is below threshold of " + minSizeForComplexMesh.ToString() + " - creating simple bounding box"); #endif mesh = CreateBoundingBoxMesh(mesh); mesh.DumpRaw(baseDir, primName, "Z extruded"); } // trim the vertex and triangle lists to free up memory mesh.TrimExcess(); if (shouldCache) { m_uniqueMeshes.Add(key, mesh); m_uniqueMeshesHulls.Add(key, hulls); m_uniqueMeshesBoundingHulls.Add(key, boundingHull); } } } finally { m_uniqueMeshesRwLock.DowngradeFromWriterLock(ref lc); } } finally { m_uniqueMeshesRwLock.ReleaseReaderLock(); } return(mesh); }
// Main mesh creation entry point public IMesh CreateMesh(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) { #if SPAM MainConsole.Instance.DebugFormat("[Mesh]: Creating mesh for {0}", primName); #endif Mesh mesh; ulong key = primShape.GetMeshKey(size, lod); // If caching and this mesh has been created already, return it instead of creating another copy if (shouldCache) { lock (m_uniqueMeshes) { if (m_uniqueMeshes.TryGetValue(key, out mesh)) return mesh; } } // set miniumm sizes if (size.X < 0.01f) size.X = 0.01f; if (size.Y < 0.01f) size.Y = 0.01f; if (size.Z < 0.01f) size.Z = 0.01f; if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh) mesh = CreateBoundingBoxMesh(size, key); else mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod, key); // cache newly created mesh? if (shouldCache) { lock (m_uniqueMeshes) { m_uniqueMeshes.Add(key, mesh); } } return mesh; }