Example #1
0
        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;
        }
Example #2
0
    // 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);
    }
Example #3
0
    // 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);
    }
Example #4
0
        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);
                lock (m_uniqueMeshes)
                {
                    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)
                {
                    lock (m_uniqueMeshes)
                    {
                        m_uniqueMeshes.Add(key, mesh);
                    }
                }
            }

            return mesh;
        }
Example #5
0
        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;
            }
        }
Example #6
0
    // Create a hash of all the shape parameters to be used as a key
    //    for this particular shape.
    private System.UInt64 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;

        // Mega prims usually get more detail because one can interact with shape approximations at this size.
        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 pbs.GetMeshKey(shapeData.Size, lod);
    }
Example #7
0
        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;
        }
Example #8
0
        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;
        }