Exemplo n.º 1
0
        public Mesh Clone()
        {
            Mesh result = new Mesh();

            foreach (Vertex v in vertices)
            {
                if (v == null)
                    result.vertices.Add(null);
                else
                    result.vertices.Add(v.Clone());
            }

            foreach (Triangle t in triangles)
            {
                int iV1, iV2, iV3;
                iV1 = vertices.IndexOf(t.v1);
                iV2 = vertices.IndexOf(t.v2);
                iV3 = vertices.IndexOf(t.v3);

                Triangle newT = new Triangle(result.vertices[iV1], result.vertices[iV2], result.vertices[iV3]);
                result.Add(newT);
            }

            return result;
        }
Exemplo n.º 2
0
        public Mesh Clone()
        {
            Mesh result = new Mesh(_meshHash, _meshData.VertexCount, _meshData.TriangleCount);

            foreach (Triangle t in _meshData.Triangles)
            {
                result.Add(t.v1.Clone(), t.v2.Clone(), t.v3.Clone());
            }

            return result;
        }
Exemplo n.º 3
0
        public Mesh Clone()
        {
            Mesh result = new Mesh();

            foreach (Triangle t in m_triangles)
            {
                result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
            }

            return result;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Create a physics mesh from data that comes with the prim.  The actual data used depends on the prim type.
        /// </summary>
        /// <param name="primName"></param>
        /// <param name="primShape"></param>
        /// <param name="size"></param>
        /// <param name="lod"></param>
        /// <returns></returns>
        private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List<List<Vector3>> hulls, out List<Vector3> boundingHull)
        {
//            m_log.DebugFormat(
//                "[MESH]: Creating physics proxy for {0}, shape {1}",
//                primName, (OpenMetaverse.SculptType)primShape.SculptType);

            List<Coord> coords;
            List<Face> faces;
            hulls = null;
            boundingHull = null;

            if (primShape.SculptEntry)
            {
                if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh)
                {
                    if (!useMeshiesPhysicsMesh)
                        return null;

                    if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces, out hulls, out boundingHull))
                        return null;
                }
                else
                {
                    if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces))
                        return null;
                }
            }
            else
            {
                if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
                    return null;
            }

            // Remove the reference to any JPEG2000 sculpt data so it can be GCed
            primShape.SculptData = Utils.EmptyBytes;

            int numCoords = coords.Count;
            int numFaces = faces.Count;

            // Create the list of vertices
            List<Vertex> vertices = new List<Vertex>();
            for (int i = 0; i < numCoords; i++)
            {
                Coord c = coords[i];
                vertices.Add(new Vertex(c.X, c.Y, c.Z));
            }

            Mesh mesh = new Mesh();
            // Add the corresponding triangles to the mesh
            for (int i = 0; i < numFaces; i++)
            {
                Face f = faces[i];
                mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
            }

            return mesh;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Creates a simple bounding box mesh for a complex input mesh
        /// </summary>
        /// <param name="meshIn"></param>
        /// <returns></returns>
        private static Mesh CreateBoundingBoxMesh(Mesh meshIn)
        {
            float minX = float.MaxValue;
            float maxX = float.MinValue;
            float minY = float.MaxValue;
            float maxY = float.MinValue;
            float minZ = float.MaxValue;
            float maxZ = float.MinValue;

            foreach (Vector3 v in meshIn.getVertexList())
            {
                if (v.X < minX) minX = v.X;
                if (v.Y < minY) minY = v.Y;
                if (v.Z < minZ) minZ = v.Z;

                if (v.X > maxX) maxX = v.X;
                if (v.Y > maxY) maxY = v.Y;
                if (v.Z > maxZ) maxZ = v.Z;
            }

            return CreateSimpleBoxMesh(minX, maxX, minY, maxY, minZ, maxZ);
        }
Exemplo n.º 6
0
        /// <summary>
        /// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may
        /// be useful as a backup proxy when level of detail is not needed or when more complex meshes fail
        /// for some reason
        /// </summary>
        /// <param name="minX"></param>
        /// <param name="maxX"></param>
        /// <param name="minY"></param>
        /// <param name="maxY"></param>
        /// <param name="minZ"></param>
        /// <param name="maxZ"></param>
        /// <returns></returns>
        private static Mesh CreateSimpleBoxMesh(float minX, float maxX, float minY, float maxY, float minZ, float maxZ)
        {
            Mesh box = new Mesh();
            List<Vertex> vertices = new List<Vertex>();
            // bottom

            vertices.Add(new Vertex(minX, maxY, minZ));
            vertices.Add(new Vertex(maxX, maxY, minZ));
            vertices.Add(new Vertex(maxX, minY, minZ));
            vertices.Add(new Vertex(minX, minY, minZ));

            box.Add(new Triangle(vertices[0], vertices[1], vertices[2]));
            box.Add(new Triangle(vertices[0], vertices[2], vertices[3]));

            // top

            vertices.Add(new Vertex(maxX, maxY, maxZ));
            vertices.Add(new Vertex(minX, maxY, maxZ));
            vertices.Add(new Vertex(minX, minY, maxZ));
            vertices.Add(new Vertex(maxX, minY, maxZ));

            box.Add(new Triangle(vertices[4], vertices[5], vertices[6]));
            box.Add(new Triangle(vertices[4], vertices[6], vertices[7]));

            // sides

            box.Add(new Triangle(vertices[5], vertices[0], vertices[3]));
            box.Add(new Triangle(vertices[5], vertices[3], vertices[6]));

            box.Add(new Triangle(vertices[1], vertices[0], vertices[5]));
            box.Add(new Triangle(vertices[1], vertices[5], vertices[4]));

            box.Add(new Triangle(vertices[7], vertices[1], vertices[4]));
            box.Add(new Triangle(vertices[7], vertices[2], vertices[1]));

            box.Add(new Triangle(vertices[3], vertices[2], vertices[7]));
            box.Add(new Triangle(vertices[3], vertices[7], vertices[6]));

            return box;
        }
Exemplo n.º 7
0
        private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
        {
//            m_log.DebugFormat(
//                "[MESH]: Creating physics proxy for {0}, shape {1}",
//                primName, (OpenMetaverse.SculptType)primShape.SculptType);

            PrimMesh primMesh;
            PrimMesher.SculptMesh sculptMesh;

            List<Coord> coords = new List<Coord>();
            List<Face> faces = new List<Face>();

            Image idata = null;
            string decodedSculptFileName = "";

            if (primShape.SculptEntry)
            {
                if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh)
                {
                    if (!useMeshiesPhysicsMesh)
                        return null;

                    m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);

                    OSD meshOsd = null;

                    if (primShape.SculptData.Length <= 0)
                    {
                        m_log.Error("[MESH]: asset data is zero length");
                        return null;
                    }

                    long start = 0;
                    using (MemoryStream data = new MemoryStream(primShape.SculptData))
                    {
                        try
                        {
                            OSD osd = OSDParser.DeserializeLLSDBinary(data);
                            if (osd is OSDMap)
                                meshOsd = (OSDMap)osd;
                            else
                            {
                                m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap");
                                return null;
                            }
                        }
                        catch (Exception e)
                        {
                            m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString());
                        }

                        start = data.Position;
                    }

                    if (meshOsd is OSDMap)
                    {
                        OSDMap physicsParms = null;
                        OSDMap map = (OSDMap)meshOsd;
                        if (map.ContainsKey("physics_shape"))
                            physicsParms = (OSDMap)map["physics_shape"]; // old asset format
                        else if (map.ContainsKey("physics_mesh"))
                            physicsParms = (OSDMap)map["physics_mesh"]; // new asset format

                        if (physicsParms == null)
                        {
                            m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset");
                            return null;
                        }

                        int physOffset = physicsParms["offset"].AsInteger() + (int)start;
                        int physSize = physicsParms["size"].AsInteger();

                        if (physOffset < 0 || physSize == 0)
                            return null; // no mesh data in asset

                        OSD decodedMeshOsd = new OSD();
                        byte[] meshBytes = new byte[physSize];
                        System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
//                        byte[] decompressed = new byte[physSize * 5];
                        try
                        {
                            using (MemoryStream inMs = new MemoryStream(meshBytes))
                            {
                                using (MemoryStream outMs = new MemoryStream())
                                {
                                    using (ZOutputStream zOut = new ZOutputStream(outMs))
                                    {
                                        byte[] readBuffer = new byte[2048];
                                        int readLen = 0;
                                        while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
                                        {
                                            zOut.Write(readBuffer, 0, readLen);
                                        }
                                        zOut.Flush();
                                        outMs.Seek(0, SeekOrigin.Begin);

                                        byte[] decompressedBuf = outMs.GetBuffer();

                                        decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString());
                            return null;
                        }

                        OSDArray decodedMeshOsdArray = null;

                        // physics_shape is an array of OSDMaps, one for each submesh
                        if (decodedMeshOsd is OSDArray)
                        {
//                            Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));

                            decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
                            foreach (OSD subMeshOsd in decodedMeshOsdArray)
                            {
                                if (subMeshOsd is OSDMap)
                                    AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
                            }
                        }
                    }
                }
                else
                {
                    if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
                    {
                        decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString());
                        try
                        {
                            if (File.Exists(decodedSculptFileName))
                            {
                                idata = Image.FromFile(decodedSculptFileName);
                            }
                        }
                        catch (Exception e)
                        {
                            m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message);

                        }
                        //if (idata != null)
                        //    m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
                    }

                    if (idata == null)
                    {
                        if (primShape.SculptData == null || primShape.SculptData.Length == 0)
                            return null;

                        try
                        {
                            OpenMetaverse.Imaging.ManagedImage unusedData;
                            OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
                            unusedData = null;

                            //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);

                            if (cacheSculptMaps && idata != null)
                            {
                                try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
                                catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
                            }
                        }
                        catch (DllNotFoundException)
                        {
                            m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed.  Often times this is because of an old version of GLIBC.  You must have version 2.4 or above!");
                            return null;
                        }
                        catch (IndexOutOfRangeException)
                        {
                            m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
                            return null;
                        }
                        catch (Exception ex)
                        {
                            m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message);
                            return null;
                        }
                    }

                    PrimMesher.SculptMesh.SculptType sculptType;
                    switch ((OpenMetaverse.SculptType)primShape.SculptType)
                    {
                        case OpenMetaverse.SculptType.Cylinder:
                            sculptType = PrimMesher.SculptMesh.SculptType.cylinder;
                            break;
                        case OpenMetaverse.SculptType.Plane:
                            sculptType = PrimMesher.SculptMesh.SculptType.plane;
                            break;
                        case OpenMetaverse.SculptType.Torus:
                            sculptType = PrimMesher.SculptMesh.SculptType.torus;
                            break;
                        case OpenMetaverse.SculptType.Sphere:
                            sculptType = PrimMesher.SculptMesh.SculptType.sphere;
                            break;
                        default:
                            sculptType = PrimMesher.SculptMesh.SculptType.plane;
                            break;
                    }

                    bool mirror = ((primShape.SculptType & 128) != 0);
                    bool invert = ((primShape.SculptType & 64) != 0);

                    sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert);
                    
                    idata.Dispose();

                    sculptMesh.DumpRaw(baseDir, primName, "primMesh");

                    sculptMesh.Scale(size.X, size.Y, size.Z);

                    coords = sculptMesh.coords;
                    faces = sculptMesh.faces;
                }
            }
            else
            {
                float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f;
                float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f;
                float pathBegin = (float)primShape.PathBegin * 2.0e-5f;
                float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f;
                float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f;
                float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f;

                float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f;
                float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f;
                float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f;
                if (profileHollow > 0.95f)
                    profileHollow = 0.95f;

                int sides = 4;
                if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
                    sides = 3;
                else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
                    sides = 24;
                else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
                { // half circle, prim is a sphere
                    sides = 24;

                    profileBegin = 0.5f * profileBegin + 0.5f;
                    profileEnd = 0.5f * profileEnd + 0.5f;
                }

                int hollowSides = sides;
                if (primShape.HollowShape == HollowShape.Circle)
                    hollowSides = 24;
                else if (primShape.HollowShape == HollowShape.Square)
                    hollowSides = 4;
                else if (primShape.HollowShape == HollowShape.Triangle)
                    hollowSides = 3;

                primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides);

                if (primMesh.errorMessage != null)
                    if (primMesh.errorMessage.Length > 0)
                        m_log.Error("[ERROR] " + primMesh.errorMessage);

                primMesh.topShearX = pathShearX;
                primMesh.topShearY = pathShearY;
                primMesh.pathCutBegin = pathBegin;
                primMesh.pathCutEnd = pathEnd;

                if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible)
                {
                    primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10;
                    primMesh.twistEnd = primShape.PathTwist * 18 / 10;
                    primMesh.taperX = pathScaleX;
                    primMesh.taperY = pathScaleY;

                    if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
                    {
                        ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
                        if (profileBegin < 0.0f) profileBegin = 0.0f;
                        if (profileEnd > 1.0f) profileEnd = 1.0f;
                    }
#if SPAM
                m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
#endif
                    try
                    {
                        primMesh.ExtrudeLinear();
                    }
                    catch (Exception ex)
                    {
                        ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
                        return null;
                    }
                }
                else
                {
                    primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f;
                    primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f;
                    primMesh.radius = 0.01f * primShape.PathRadiusOffset;
                    primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions;
                    primMesh.skew = 0.01f * primShape.PathSkew;
                    primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10;
                    primMesh.twistEnd = primShape.PathTwist * 36 / 10;
                    primMesh.taperX = primShape.PathTaperX * 0.01f;
                    primMesh.taperY = primShape.PathTaperY * 0.01f;

                    if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
                    {
                        ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
                        if (profileBegin < 0.0f) profileBegin = 0.0f;
                        if (profileEnd > 1.0f) profileEnd = 1.0f;
                    }
#if SPAM
                m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString());
#endif
                    try
                    {
                        primMesh.ExtrudeCircular();
                    }
                    catch (Exception ex)
                    {
                        ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
                        return null;
                    }
                }

                primMesh.DumpRaw(baseDir, primName, "primMesh");

                primMesh.Scale(size.X, size.Y, size.Z);

                coords = primMesh.coords;
                faces = primMesh.faces;
            }

            // Remove the reference to any JPEG2000 sculpt data so it can be GCed
            primShape.SculptData = Utils.EmptyBytes;

            int numCoords = coords.Count;
            int numFaces = faces.Count;

            // Create the list of vertices
            List<Vertex> vertices = new List<Vertex>();
            for (int i = 0; i < numCoords; i++)
            {
                Coord c = coords[i];
                vertices.Add(new Vertex(c.X, c.Y, c.Z));
            }

            Mesh mesh = new Mesh();
            // Add the corresponding triangles to the mesh
            for (int i = 0; i < numFaces; i++)
            {
                Face f = faces[i];
                mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
            }

            return mesh;
        }
Exemplo n.º 8
0
        private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod,
                                              ulong key)
        {
            PrimMesh primMesh;
            SculptMesh sculptMesh;

            List<Coord> coords = new List<Coord>();
            List<Face> faces = new List<Face>();

            Image idata = null;
            string decodedSculptFileName = "";

            if (primShape.SculptEntry)
            {
                if (((SculptType) primShape.SculptType) == SculptType.Mesh)
                {
                    if (!useMeshiesPhysicsMesh)
                        return null;

                    MainConsole.Instance.Debug("[MESH]: experimental mesh proxy generation");

                    OSD meshOsd = null;

                    if (primShape.SculptData == null || primShape.SculptData.Length <= 0)
                    {
                        MainConsole.Instance.Error("[MESH]: asset data is zero length");
                        return null;
                    }

                    long start = 0;
                    using (MemoryStream data = new MemoryStream(primShape.SculptData))
                    {
                        try
                        {
                            meshOsd = OSDParser.DeserializeLLSDBinary(data);
                        }
                        catch (Exception e)
                        {
                            MainConsole.Instance.Error("[MESH]: Exception deserializing mesh asset header:" + e);
                        }
                        start = data.Position;
                    }

                    if (meshOsd is OSDMap)
                    {
                        OSDMap map = (OSDMap) meshOsd;
                        OSDMap physicsParms = new OSDMap();

                        if (map.ContainsKey("physics_cached"))
                        {
                            OSD cachedMeshMap = map["physics_cached"]; // cached data from Aurora
                            Mesh cachedMesh = new Mesh(key);
                            cachedMesh.Deserialize(cachedMeshMap);
                            cachedMesh.WasCached = true;
                            return cachedMesh;//Return here, we found all of the info right here
                        }
                        if (map.ContainsKey("physics_shape"))
                            physicsParms = (OSDMap)map["physics_shape"]; // old asset format
                        if (physicsParms.Count == 0 && map.ContainsKey("physics_mesh"))
                            physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
                        if (physicsParms.Count == 0 && map.ContainsKey("physics_convex"))
                            // convex hull format, which we can't read, so instead
                            // read the highest lod that exists, and use it instead
                            physicsParms = (OSDMap)map["high_lod"]; 

                        int physOffset = physicsParms["offset"].AsInteger() + (int) start;
                        int physSize = physicsParms["size"].AsInteger();

                        if (physOffset < 0 || physSize == 0)
                            return null; // no mesh data in asset

                        OSD decodedMeshOsd = new OSD();
                        byte[] meshBytes = new byte[physSize];
                        Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
                        try
                        {
                            using (MemoryStream inMs = new MemoryStream(meshBytes))
                            {
                                using (MemoryStream outMs = new MemoryStream())
                                {
                                    using (ZOutputStream zOut = new ZOutputStream(outMs))
                                    {
                                        byte[] readBuffer = new byte[2048];
                                        int readLen = 0;
                                        while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
                                        {
                                            zOut.Write(readBuffer, 0, readLen);
                                        }
                                        zOut.Flush();
                                        outMs.Seek(0, SeekOrigin.Begin);

                                        byte[] decompressedBuf = outMs.GetBuffer();

                                        decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            MainConsole.Instance.Error("[MESH]: exception decoding physical mesh: " + e);
                            return null;
                        }

                        OSDArray decodedMeshOsdArray = null;

                        // physics_shape is an array of OSDMaps, one for each submesh
                        if (decodedMeshOsd is OSDArray)
                        {
                            decodedMeshOsdArray = (OSDArray) decodedMeshOsd;
                            foreach (OSD subMeshOsd in decodedMeshOsdArray)
                            {
                                if (subMeshOsd is OSDMap)
                                {
                                    OSDMap subMeshMap = (OSDMap) subMeshOsd;

                                    // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level
                                    // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no
                                    // geometry for this submesh.
                                    if (subMeshMap.ContainsKey("NoGeometry") && (subMeshMap["NoGeometry"]))
                                        continue;

                                    Vector3 posMax = new Vector3(0.5f, 0.5f, 0.5f);
                                    Vector3 posMin = new Vector3(-0.5f, -0.5f, -0.5f);
                                    if (subMeshMap.ContainsKey("PositionDomain"))//Optional, so leave the max and min values otherwise
                                    {
                                        posMax = ((OSDMap)subMeshMap["PositionDomain"])["Max"].AsVector3();
                                        posMin = ((OSDMap)subMeshMap["PositionDomain"])["Min"].AsVector3();
                                    }
                                    ushort faceIndexOffset = (ushort) coords.Count;

                                    byte[] posBytes = subMeshMap["Position"].AsBinary();
                                    for (int i = 0; i < posBytes.Length; i += 6)
                                    {
                                        ushort uX = Utils.BytesToUInt16(posBytes, i);
                                        ushort uY = Utils.BytesToUInt16(posBytes, i + 2);
                                        ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);

                                        Coord c = new Coord(
                                            Utils.UInt16ToFloat(uX, posMin.X, posMax.X)*size.X,
                                            Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y)*size.Y,
                                            Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z)*size.Z);

                                        coords.Add(c);
                                    }

                                    byte[] triangleBytes = subMeshMap["TriangleList"].AsBinary();
                                    for (int i = 0; i < triangleBytes.Length; i += 6)
                                    {
                                        ushort v1 = (ushort) (Utils.BytesToUInt16(triangleBytes, i) + faceIndexOffset);
                                        ushort v2 =
                                            (ushort) (Utils.BytesToUInt16(triangleBytes, i + 2) + faceIndexOffset);
                                        ushort v3 =
                                            (ushort) (Utils.BytesToUInt16(triangleBytes, i + 4) + faceIndexOffset);
                                        Face f = new Face(v1, v2, v3);
                                        faces.Add(f);
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
                    {
                        decodedSculptFileName = Path.Combine(decodedSculptMapPath,
                                                             "smap_" + primShape.SculptTexture.ToString());
                        try
                        {
                            if (File.Exists(decodedSculptFileName))
                            {
                                idata = Image.FromFile(decodedSculptFileName);
                            }
                        }
                        catch (Exception e)
                        {
                            MainConsole.Instance.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e);
                        }
                        //if (idata != null)
                        //    MainConsole.Instance.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
                    }

                    if (idata == null)
                    {
                        if (primShape.SculptData == null || primShape.SculptData.Length == 0)
                            return null;

                        try
                        {
                            ManagedImage unusedData;
                            OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
                            unusedData = null;

                            if (cacheSculptMaps && idata != null)
                            {
                                try
                                {
                                    idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp);
                                }
                                catch (Exception e)
                                {
                                    MainConsole.Instance.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " +
                                                e);
                                }
                            }
                        }
                        catch (DllNotFoundException)
                        {
                            MainConsole.Instance.Error(
                                "[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed.  Often times this is because of an old version of GLIBC.  You must have version 2.4 or above!");
                            return null;
                        }
                        catch (IndexOutOfRangeException)
                        {
                            MainConsole.Instance.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
                            return null;
                        }
                        catch (Exception ex)
                        {
                            MainConsole.Instance.Error(
                                "[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " +
                                ex);
                            return null;
                        }
                    }

                    SculptMesh.SculptType sculptType;
                    switch ((SculptType) primShape.SculptType)
                    {
                        case SculptType.Cylinder:
                            sculptType = SculptMesh.SculptType.cylinder;
                            break;
                        case SculptType.Plane:
                            sculptType = SculptMesh.SculptType.plane;
                            break;
                        case SculptType.Torus:
                            sculptType = SculptMesh.SculptType.torus;
                            break;
                        case SculptType.Sphere:
                            sculptType = SculptMesh.SculptType.sphere;
                            break;
                        default:
                            sculptType = SculptMesh.SculptType.plane;
                            break;
                    }

                    bool mirror = ((primShape.SculptType & 128) != 0);
                    bool invert = ((primShape.SculptType & 64) != 0);

                    if (idata == null)
                        return null;

                    sculptMesh = new SculptMesh((Bitmap) idata, sculptType, (int) lod, false, mirror, invert);

                    idata.Dispose();
                    idata = null;

                    sculptMesh.DumpRaw(baseDir, primName, "primMesh");

                    sculptMesh.Scale(size.X, size.Y, size.Z);

                    coords = sculptMesh.coords;
                    faces = sculptMesh.faces;
                }
            }
            else
            {
                float pathShearX = primShape.PathShearX < 128
                                       ? primShape.PathShearX*0.01f
                                       : (primShape.PathShearX - 256)*0.01f;
                float pathShearY = primShape.PathShearY < 128
                                       ? primShape.PathShearY*0.01f
                                       : (primShape.PathShearY - 256)*0.01f;
                float pathBegin = primShape.PathBegin*2.0e-5f;
                float pathEnd = 1.0f - primShape.PathEnd*2.0e-5f;
                float pathScaleX = (primShape.PathScaleX - 100)*0.01f;
                float pathScaleY = (primShape.PathScaleY - 100)*0.01f;

                float profileBegin = primShape.ProfileBegin*2.0e-5f;
                float profileEnd = 1.0f - primShape.ProfileEnd*2.0e-5f;
                float profileHollow = primShape.ProfileHollow*2.0e-5f;
                if (profileHollow > 0.95f)
                {
                    if (profileHollow > 0.99f)
                        profileHollow = 0.99f;
                    float sizeX = primShape.Scale.X - (primShape.Scale.X*profileHollow);
                    if (sizeX < 0.1f) //If its > 0.1, its fine to mesh at the small hollow
                        profileHollow = 0.95f + (sizeX/2); //Scale the rest by how large the size of the prim is
                }

                int sides = 4;
                if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.EquilateralTriangle)
                    sides = 3;
                else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.Circle)
                    sides = 24;
                else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.HalfCircle)
                {
                    // half circle, prim is a sphere
                    sides = 24;

                    profileBegin = 0.5f*profileBegin + 0.5f;
                    profileEnd = 0.5f*profileEnd + 0.5f;
                }

                int hollowSides = sides;
                if (primShape.HollowShape == HollowShape.Circle)
                    hollowSides = 24;
                else if (primShape.HollowShape == HollowShape.Square)
                    hollowSides = 4;
                else if (primShape.HollowShape == HollowShape.Triangle)
                    hollowSides = 3;

                primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides);

                if (primMesh.errorMessage != null)
                    if (primMesh.errorMessage.Length > 0)
                        MainConsole.Instance.Error("[ERROR] " + primMesh.errorMessage);

                primMesh.topShearX = pathShearX;
                primMesh.topShearY = pathShearY;
                primMesh.pathCutBegin = pathBegin;
                primMesh.pathCutEnd = pathEnd;

                if (primShape.PathCurve == (byte) Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible)
                {
                    primMesh.twistBegin = primShape.PathTwistBegin*18/10;
                    primMesh.twistEnd = primShape.PathTwist*18/10;
                    primMesh.taperX = pathScaleX;
                    primMesh.taperY = pathScaleY;

                    if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
                    {
                        ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
                        if (profileBegin < 0.0f) profileBegin = 0.0f;
                        if (profileEnd > 1.0f) profileEnd = 1.0f;
                    }
#if SPAM
                MainConsole.Instance.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
#endif
                    try
                    {
                        primMesh.Extrude(primShape.PathCurve == (byte) Extrusion.Straight
                                             ? PathType.Linear
                                             : PathType.Flexible);
                    }
                    catch (Exception ex)
                    {
                        ReportPrimError("Extrusion failure: exception: " + ex, primName, primMesh);
                        return null;
                    }
                }
                else
                {
                    primMesh.holeSizeX = (200 - primShape.PathScaleX)*0.01f;
                    primMesh.holeSizeY = (200 - primShape.PathScaleY)*0.01f;
                    primMesh.radius = 0.01f*primShape.PathRadiusOffset;
                    primMesh.revolutions = 1.0f + 0.015f*primShape.PathRevolutions;
                    primMesh.skew = 0.01f*primShape.PathSkew;
                    primMesh.twistBegin = primShape.PathTwistBegin*36/10;
                    primMesh.twistEnd = primShape.PathTwist*36/10;
                    primMesh.taperX = primShape.PathTaperX*0.01f;
                    primMesh.taperY = primShape.PathTaperY*0.01f;

                    if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
                    {
                        ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
                        if (profileBegin < 0.0f) profileBegin = 0.0f;
                        if (profileEnd > 1.0f) profileEnd = 1.0f;
                    }
#if SPAM
                MainConsole.Instance.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString());
#endif
                    try
                    {
                        primMesh.Extrude(PathType.Circular);
                    }
                    catch (Exception ex)
                    {
                        ReportPrimError("Extrusion failure: exception: " + ex, primName, primMesh);
                        return null;
                    }
                }

                primMesh.DumpRaw(baseDir, primName, "primMesh");

                primMesh.Scale(size.X, size.Y, size.Z);

                coords = primMesh.coords;
                faces = primMesh.faces;
                primMesh = null;
            }

            int numCoords = coords.Count;
            int numFaces = faces.Count;

            // Create the list of vertices
            List<Vertex> vertices = new List<Vertex>();
            for (int i = 0; i < numCoords; i++)
            {
                Coord c = coords[i];
                vertices.Add(new Vertex(c.X, c.Y, c.Z));
            }

            Mesh mesh = new Mesh(key);
            // Add the corresponding triangles to the mesh
            for (int i = 0; i < numFaces; i++)
            {
                Face f = faces[i];
                mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
            }
            coords.Clear();
            faces.Clear();
            coords = null;
            faces = null;
            return mesh;
        }
Exemplo n.º 9
0
        /// <summary>
        /// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may
        /// be useful as a backup proxy when level of detail is not needed or when more complex meshes fail
        /// for some reason
        /// </summary>
        /// <param name="minX"></param>
        /// <param name="maxX"></param>
        /// <param name="minY"></param>
        /// <param name="maxY"></param>
        /// <param name="minZ"></param>
        /// <param name="maxZ"></param>
        /// <returns></returns>
        private Mesh CreateSimpleBoxMesh(float minX, float maxX, float minY, float maxY, float minZ, float maxZ)
        {
            Mesh box = new Mesh(0, 8, 12);

            // bottom
            box.AddMeshVertex(minX, maxY, minZ);
            box.AddMeshVertex(maxX, maxY, minZ);
            box.AddMeshVertex(maxX, minY, minZ);
            box.AddMeshVertex(minX, minY, minZ);

            box.Add(0, 1, 2);
            box.Add(0, 2, 3);

            // top

            box.AddMeshVertex(maxX, maxY, maxZ);
            box.AddMeshVertex(minX, maxY, maxZ);
            box.AddMeshVertex(minX, minY, maxZ);
            box.AddMeshVertex(maxX, minY, maxZ);

            box.Add(4, 5, 6);
            box.Add(4, 6, 7);

            // sides
            box.Add(5, 0, 3);
            box.Add(5, 3, 6);

            box.Add(1, 0, 5);
            box.Add(1, 5, 4);

            box.Add(7, 1, 4);
            box.Add(7, 2, 1);

            box.Add(3, 2, 7);
            box.Add(3, 7, 6);

            return box;
        }
Exemplo n.º 10
0
        private static Mesh BuildMeshFromCoordsAndFaces(ulong meshKey, List<Coord> coords, List<Face> faces)
        {
            Mesh mesh = new Mesh(meshKey, coords.Count, faces.Count);

            for (int i = 0; i < coords.Count; i++)
            {
                Coord c = coords[i];
                mesh.AddMeshVertex(c.X, c.Y, c.Z);
            }

            for (int i = 0; i < faces.Count; i++)
            {
                Face f = faces[i];
                mesh.Add(f.v1, f.v2, f.v3);
            }

            return mesh;
        }
Exemplo n.º 11
0
        public Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod)
        {
            Mesh mesh = new Mesh();
            PrimMesh primMesh;
            PrimMesher.SculptMesh sculptMesh;

            List<Coord> coords;
            List<Face> faces;

            Image idata = null;
            string decodedSculptFileName = "";

            if (primShape.SculptEntry)
            {
                if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
                {
                    decodedSculptFileName = System.IO.Path.Combine(decodedScultMapPath, "smap_" + primShape.SculptTexture.ToString());
                    try
                    {
                        if (File.Exists(decodedSculptFileName))
                        {
                            idata = Image.FromFile(decodedSculptFileName);
                        }
                    }
                    catch (Exception e)
                    {
                        m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message);

                    }
                    //if (idata != null)
                    //    m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
                }

                if (idata == null)
                {
                    if (primShape.SculptData.Length == 0)
                        return null;

                    try
                    {
                        ManagedImage managedImage;  // we never use this
                        OpenJPEG.DecodeToImage(primShape.SculptData, out managedImage, out idata);

                        if (cacheSculptMaps)
                        {
                            try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
                            catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
                        }
                    }
                    catch (DllNotFoundException)
                    {
                        m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed.  Often times this is because of an old version of GLIBC.  You must have version 2.4 or above!");
                        return null;
                    }
                    catch (IndexOutOfRangeException)
                    {
                        m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this.   Physics Proxy generation failed");
                        return null;
                    }
                    catch (Exception)
                    {
                        m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy.  Sculpty texture decode failed!");
                        return null;
                    }
                }



                PrimMesher.SculptMesh.SculptType sculptType;
                switch ((OpenMetaverse.SculptType)primShape.SculptType)
                {
                    case OpenMetaverse.SculptType.Cylinder:
                        sculptType = PrimMesher.SculptMesh.SculptType.cylinder;
                        break;
                    case OpenMetaverse.SculptType.Plane:
                        sculptType = PrimMesher.SculptMesh.SculptType.plane;
                        break;
                    case OpenMetaverse.SculptType.Torus:
                        sculptType = PrimMesher.SculptMesh.SculptType.torus;
                        break;
                    case OpenMetaverse.SculptType.Sphere:
                        sculptType = PrimMesher.SculptMesh.SculptType.sphere;
                        break;
                    default:
                        sculptType = PrimMesher.SculptMesh.SculptType.plane;
                        break;
                }

                bool mirror = ((primShape.SculptType & 128) != 0);
                bool invert = ((primShape.SculptType & 64) != 0);

                sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert);

                idata.Dispose();

                sculptMesh.DumpRaw(baseDir, primName, "primMesh");

                sculptMesh.Scale(size.X, size.Y, size.Z);

                coords = sculptMesh.coords;
                faces = sculptMesh.faces;
            }

            else
            {
                float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f;
                float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f;
                float pathBegin = (float)primShape.PathBegin * 2.0e-5f;
                float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f;
                float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f;
                float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f;

                float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f;
                float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f;
                float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f;
                if (profileHollow > 0.95f)
                    profileHollow = 0.95f;

                int sides = 4;
                if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
                    sides = 3;
                else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
                    sides = 24;
                else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
                { // half circle, prim is a sphere
                    sides = 24;

                    profileBegin = 0.5f * profileBegin + 0.5f;
                    profileEnd = 0.5f * profileEnd + 0.5f;

                }

                int hollowSides = sides;
                if (primShape.HollowShape == HollowShape.Circle)
                    hollowSides = 24;
                else if (primShape.HollowShape == HollowShape.Square)
                    hollowSides = 4;
                else if (primShape.HollowShape == HollowShape.Triangle)
                    hollowSides = 3;

                primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides);

                if (primMesh.errorMessage != null)
                    if (primMesh.errorMessage.Length > 0)
                        m_log.Error("[ERROR] " + primMesh.errorMessage);

                primMesh.topShearX = pathShearX;
                primMesh.topShearY = pathShearY;
                primMesh.pathCutBegin = pathBegin;
                primMesh.pathCutEnd = pathEnd;

                if (primShape.PathCurve == (byte)Extrusion.Straight)
                {
                    primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10;
                    primMesh.twistEnd = primShape.PathTwist * 18 / 10;
                    primMesh.taperX = pathScaleX;
                    primMesh.taperY = pathScaleY;

                    if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
                    {
                        ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
                        if (profileBegin < 0.0f) profileBegin = 0.0f;
                        if (profileEnd > 1.0f) profileEnd = 1.0f;
                    }
#if SPAM
                m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
#endif
                    try
                    {
                        primMesh.ExtrudeLinear();
                    }
                    catch (Exception ex)
                    {
                        ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
                        return null;
                    }
                }
                else
                {
                    primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f;
                    primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f;
                    primMesh.radius = 0.01f * primShape.PathRadiusOffset;
                    primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions;
                    primMesh.skew = 0.01f * primShape.PathSkew;
                    primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10;
                    primMesh.twistEnd = primShape.PathTwist * 36 / 10;
                    primMesh.taperX = primShape.PathTaperX * 0.01f;
                    primMesh.taperY = primShape.PathTaperY * 0.01f;

                    if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
                    {
                        ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
                        if (profileBegin < 0.0f) profileBegin = 0.0f;
                        if (profileEnd > 1.0f) profileEnd = 1.0f;
                    }
#if SPAM
                m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString());
#endif
                    try
                    {
                        primMesh.ExtrudeCircular();
                    }
                    catch (Exception ex)
                    {
                        ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
                        return null;
                    }
                }

                primMesh.DumpRaw(baseDir, primName, "primMesh");

                primMesh.Scale(size.X, size.Y, size.Z);

                coords = primMesh.coords;
                faces = primMesh.faces;

                mesh.primMesh = primMesh;

            }


            int numCoords = coords.Count;
            int numFaces = faces.Count;

            for (int i = 0; i < numCoords; i++)
            {
                Coord c = coords[i];
                mesh.vertices.Add(new Vertex(c.X, c.Y, c.Z));
            }

            List<Vertex> vertices = mesh.vertices;
            for (int i = 0; i < numFaces; i++)
            {
                Face f = faces[i];
                mesh.triangles.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
            }

            return mesh;
        }
Exemplo n.º 12
0
        // rex, new function
        private bool CreateOSMeshFromDotMesh(byte[] vData, string vMeshName, bool vbScaleMesh)
        {
            float[] tempVertexList;
            float[] tempBounds;
            int[] tempIndexList;
            string errorMessage;

            RexDotMeshLoader.DotMeshLoader.ReadDotMeshModel(vData, out tempVertexList, out tempIndexList, out tempBounds, out errorMessage);

            if (tempVertexList == null || tempIndexList == null)
            {
                m_log.Error("[REXODEPHYSICS]: Error importing mesh:" + vMeshName + ", " + errorMessage);
                return false;
            }

            m_OriginalMesh = new Mesh();

            m_BoundsScaling = vbScaleMesh;
            m_BoundsMin.X = tempBounds[0];
            m_BoundsMin.Y = tempBounds[1];
            m_BoundsMin.Z = tempBounds[2];
            m_BoundsMax.X = tempBounds[3];
            m_BoundsMax.Y = tempBounds[4];
            m_BoundsMax.Z = tempBounds[5];

            List<Vertex> vertlist = new List<Vertex>();
            for (int i = 0; i < tempVertexList.GetLength(0); i = i + 3)
            {
                Vertex vert = new Vertex(tempVertexList[i], tempVertexList[i + 1], tempVertexList[i + 2]);
                vertlist.Add(vert);
            }

            for (int i = 0; i < tempIndexList.GetLength(0); i = i + 3)
            {
                Triangle tria = new Triangle(vertlist[(tempIndexList[i])], vertlist[(tempIndexList[i + 1])], vertlist[(tempIndexList[i + 2])]);
                m_OriginalMesh.Add(tria);
            }

            vertlist.Clear();
            return true;
        }
Exemplo n.º 13
0
        // rex, new function
        private Mesh CreateMeshFromOriginal()
        {
            float[] scalefactor = new float[3];

            if (m_OriginalMesh != null)
            {
                Vector3 scalingvector = new Vector3(_size.X, _size.Y, _size.Z);
                if (m_BoundsScaling)
                {
                    Vector3 boundssize = m_BoundsMax - m_BoundsMin;
                    if (boundssize.X != 0)
                        scalingvector.X /= boundssize.X;
                    if (boundssize.Y != 0)
                        scalingvector.Z /= boundssize.Y;
                    if (boundssize.Z != 0)
                        scalingvector.Y /= boundssize.Z;
                }

                scalefactor[0] = scalingvector.X;
                scalefactor[1] = scalingvector.Z;
                scalefactor[2] = scalingvector.Y;

                Mesh newmesh = new Mesh();
                List<Vector3> vertlist = m_OriginalMesh.getVertexList();
                int[] tempIndexList = m_OriginalMesh.getIndexListAsInt();

                for (int i = 0; i < tempIndexList.GetLength(0); i = i + 3)
                {
                    Vertex vertA = new Vertex(vertlist[(tempIndexList[i])].X * scalefactor[0], vertlist[(tempIndexList[i])].Y * scalefactor[1], vertlist[(tempIndexList[i])].Z * scalefactor[2]);
                    Vertex vertB = new Vertex(vertlist[(tempIndexList[i + 1])].X * scalefactor[0], vertlist[(tempIndexList[i + 1])].Y * scalefactor[1], vertlist[(tempIndexList[i + 1])].Z * scalefactor[2]);
                    Vertex vertC = new Vertex(vertlist[(tempIndexList[i + 2])].X * scalefactor[0], vertlist[(tempIndexList[i + 2])].Y * scalefactor[1], vertlist[(tempIndexList[i + 2])].Z * scalefactor[2]);

                    Triangle tria = new Triangle(vertA, vertB,vertC);
                    newmesh.Add(tria);
                }

                vertlist.Clear();
                return newmesh;
            }
            else
                return null;
        }
Exemplo n.º 14
0
        // This function should be called only outside of simulation loop -> OdeLock used.
        public void SetCollisionMesh(byte[] meshdata, string meshname, bool scalemesh)
        {
            lock (_parent_scene.OdeLock)
            {
                m_DotMeshCollision = false;
                if (m_OriginalMesh != null)
                {
                    // Never pinned so skip m_OriginalMesh.releasePinned();
                    m_OriginalMesh = null;
                }

                if (meshdata != null && CreateOSMeshFromDotMesh(meshdata, meshname, scalemesh))
                    m_DotMeshCollision = true;

                m_ReCreateCollision = true;
            }

            _parent_scene.AddPhysicsActorTaint(this);
        }