Example #1
0
        /// <summary>
        /// Convert a PrimMesher.PrimMesh to OpenSim.Region.Physics.Meshing.Mesh
        /// </summary>
        /// <param name="meshIn"></param>
        /// <returns></returns>
        public static Mesh PrimMeshToMesh(PrimMesh meshIn)
        {
            Mesh mesh = new Mesh();

#if COLLIDER_ODE
            mesh.PBS = meshIn.PBS
#endif
            mesh.primMesh = meshIn;
            {
                List <Coord> coords    = meshIn.coords;
                List <Face>  faces     = meshIn.faces;
                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);
        }
Example #2
0
        public override object GetClassFrom(JMXStructure Structure)
        {
            PrimMesh obj = new PrimMesh()
            {
                Path  = (string)((JMXAttribute)Structure.Childs[0]).Value,
                Int01 = (int)((JMXAttribute)Structure.Childs[1]).Value
            };

            return(obj);
        }
Example #3
0
        /// <summary>
        /// Convert a Openmetaverse.Primitive to a PrimMesh
        /// </summary>
        /// <param name="thePrim"></param>
        /// <param name="detail"></param>
        /// <param name="pos"></param>
        /// <param name="rot"></param>
        /// <returns></returns>
        public PrimMesh PrimitiveToPrimMesh(Primitive thePrim, LevelOfDetail detail, Vector3 Scale, Quaternion rot)
        {
            bool     UseExtremeDetail = Scale.X + Scale.Y + Scale.Z > UseExtremeDetailSize;
            PrimMesh mesh             = ConstructionDataToPrimMesh(thePrim.PrimData, detail, UseExtremeDetail ? 2 : 1);

#if COLLIDER_ODE
            mesh.PBS = PrimToBaseShape(thePrim);
#endif
            mesh.Scale(Scale.X, Scale.Y, Scale.Z);
            // if (rot != Quaternion.Identity)
            mesh.AddRot(QuaternionToQuat(rot));
            return(mesh);
        }
Example #4
0
 private void ReportPrimError(string message, string primName, PrimMesh primMesh)
 {
     MainConsole.Instance.Error(message);
     MainConsole.Instance.Error("\nPrim Name: " + primName);
     MainConsole.Instance.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString());
 }
Example #5
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) == SculptType.Mesh)
                {
                    if (!UseMeshesPhysicsMesh)
                        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 = System.IO.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
                        {
                            idata = m_j2kDecoder.DecodeToImage(primShape.SculptData);

                            if (idata != null && cacheSculptMaps &&
                                (cacheSculptAlphaMaps || (((ImageFlags) (idata.Flags) & ImageFlags.HasAlpha) == 0)))
                            {
                                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;
                switch ((primShape.ProfileCurve & 0x07))
                {
                    case (byte) ProfileShape.EquilateralTriangle:
                        sides = 3;
                        break;
                    case (byte) ProfileShape.Circle:
                        sides = 24;
                        break;
                    case (byte) ProfileShape.HalfCircle:
                        sides = 24;
                        profileBegin = 0.5f*profileBegin + 0.5f;
                        profileEnd = 0.5f*profileEnd + 0.5f;
                        break;
                }

                int hollowSides = sides;
                switch (primShape.HollowShape)
                {
                    case HollowShape.Circle:
                        hollowSides = 24;
                        break;
                    case HollowShape.Square:
                        hollowSides = 4;
                        break;
                    case HollowShape.Triangle:
                        hollowSides = 3;
                        break;
                }

                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;
            }

            Mesh mesh = new Mesh(key);
            //mesh.m_triangles = faces;
            //mesh.m_vertices = coords;
            // Add the corresponding triangles to the mesh
            mesh.Set(coords, faces);
            coords.Clear();
            faces.Clear();
            coords = null;
            faces = null;
            return mesh;
        }
        /// <summary>
        /// Generate a mesh from the shape data the accompanies a prim.
        /// </summary>
        /// <param name="primName"></param>
        /// <param name="primShape"></param>
        /// <param name="size"></param>
        /// <param name="key"></param> 
        /// <returns>created mesh or null if invalid</returns>
        Mesh GenerateFromPrimShapeData (string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, ulong key)
        {
            PrimMesh primMesh;

            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;          // assume the prim is square
            switch ((primShape.ProfileCurve & 0x07)) {
            case (byte)ProfileShape.EquilateralTriangle:
                sides = 3;
                break;
            case (byte)ProfileShape.Circle:
                sides = GetLevelOfDetail (lod);
                break;
            case (byte)ProfileShape.HalfCircle:
                sides = GetLevelOfDetail (lod);
                profileBegin = (0.5f * profileBegin) + 0.5f;
                profileEnd = (0.5f * profileEnd) + 0.5f;
                break;
            }

            int hollowSides = sides;
            switch (primShape.HollowShape) {
            case HollowShape.Circle:
                hollowSides = GetLevelOfDetail (lod);
                break;
            case HollowShape.Square:
                hollowSides = 4;
                break;
            case HollowShape.Triangle:
                hollowSides = 3;
                break;
            }

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

            if (!string.IsNullOrEmpty (primMesh.errorMessage))
                MainConsole.Instance.Error ("[Prim mesh]: 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 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 + (primShape.PathRevolutions * 0.015f);
                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 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;
                }
            }

#if SPAM
                debugprimMesh.DumpRaw(baseDir, primName, "primMesh");
#endif

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

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

            Mesh mesh = new Mesh (key);
            mesh.Set (coords, faces);
            coords.Clear ();
            faces.Clear ();

            // debug info only
            //Console.Write ("P");

            return mesh;
        }
Example #7
0
        public Mesh PrimitiveToMesh(Primitive primitive, Vector3 Scale, Quaternion rot)
        {
            bool wasSculpt = primitive.Sculpt != null;

            if (wasSculpt && WorldPathSystem.SculptCollisions)
            {
                Primitive.SculptData SD = primitive.Sculpt;
                UUID       Id           = SD.SculptTexture;
                SculptMesh SM;
                if (!SculptedMeshes.TryGetValue(Id, out SM))
                {
                    byte[] bytes = WorldObjects.GridMaster.TextureBytesForUUID(SD.SculptTexture);
                    SM = ToSculptMesh(bytes, primitive.Sculpt, "" + primitive);
                    if (MaintainSculptPool)
                    {
                        SculptedMeshes[Id] = SM;
                    }
                    //  SM.DumpRaw(".", primitive.ID.ToString(), "sculptMesh" + primitive.LocalID);
                }
                if (SM != null)
                {
                    SM = SM.Copy();
                    SM.Scale(Scale.X, Scale.Y, Scale.Z);
                    SM.AddRot(QuaternionToQuat(rot));
                    return(ToMesh(
#if COLLIDER_ODE
                               PrimToBaseShape(primitive),
                        #endif

                               SM.coords, SM.faces, SM.viewerFaces, primitive.Type == PrimType.Sphere));
                }
            }

            this.scaleSize = Scale.X + Scale.Y + Scale.Z;
            bool UseExtremeDetail = scaleSize > UseExtremeDetailSize;
            //LevelOfDetail detail;
            if (scaleSize < UseLowDetailSize)
            {
                detail = LevelOfDetail.Low;
            }
            else
            {
                detail = LevelOfDetail.Medium;
            }
            if (UseExtremeDetail)
            {
                if (primitive.Type == PrimType.Box)
                {
                    detail = LevelOfDetail.Medium;
                }
                else
                {
                    detail = LevelOfDetail.High;
                }
            }

            PrimMesh primMesh = ConstructionDataToPrimMesh(primitive.PrimData, detail, UseExtremeDetail ? 2 : 1);
            primMesh.Scale(Scale.X, Scale.Y, Scale.Z);
            primMesh.AddRot(QuaternionToQuat(rot));
            Mesh m = PrimMeshToMesh(primMesh);
#if COLLIDER_ODE
            m.PBS = PrimToBaseShape(primitive);
#endif
            return(m);
        }
        /// <summary>
        /// Generate a mesh from the shape data the accompanies a prim.
        /// </summary>
        /// <param name="primName"></param>
        /// <param name="primShape"></param>
        /// <param name="size"></param>
        /// <param name="key"></param>
        /// <returns>created mesh or null if invalid</returns>
        Mesh GenerateFromPrimShapeData(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, ulong key)
        {
            PrimMesh primMesh;

            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;          // assume the prim is square

            switch ((primShape.ProfileCurve & 0x07))
            {
            case (byte)ProfileShape.EquilateralTriangle:
                sides = 3;
                break;

            case (byte)ProfileShape.Circle:
                sides = GetLevelOfDetail(lod);
                break;

            case (byte)ProfileShape.HalfCircle:
                sides        = GetLevelOfDetail(lod);
                profileBegin = (0.5f * profileBegin) + 0.5f;
                profileEnd   = (0.5f * profileEnd) + 0.5f;
                break;
            }

            int hollowSides = sides;

            switch (primShape.HollowShape)
            {
            case HollowShape.Circle:
                hollowSides = GetLevelOfDetail(lod);
                break;

            case HollowShape.Square:
                hollowSides = 4;
                break;

            case HollowShape.Triangle:
                hollowSides = 3;
                break;
            }

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

            if (!string.IsNullOrEmpty(primMesh.errorMessage))
            {
                MainConsole.Instance.Error("[Prim mesh]: 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 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 + (primShape.PathRevolutions * 0.015f);
                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 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);
                }
            }

#if SPAM
            debugprimMesh.DumpRaw(baseDir, primName, "primMesh");
#endif

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

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

            Mesh mesh = new Mesh(key);
            mesh.Set(coords, faces);
            coords.Clear();
            faces.Clear();

            // debug info only
            //Console.Write ("P");

            return(mesh);
        }
Example #9
0
        /// <summary>
        /// Generate the co-ords and faces necessary to construct a mesh from the shape data the accompanies a prim.
        /// </summary>
        /// <param name="primName"></param>
        /// <param name="primShape"></param>
        /// <param name="size"></param>
        /// <param name="coords">Coords are added to this list by the method.</param>
        /// <param name="faces">Faces are added to this list by the method.</param>
        /// <returns>true if coords and faces were successfully generated, false if not</returns>
        private bool GenerateCoordsAndFacesFromPrimShapeData(
            string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List <Coord> coords, out List <Face> faces)
        {
            PrimMesh primMesh;

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

            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;
            LevelOfDetail iLOD  = (LevelOfDetail)lod;

            if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
            {
                sides = 3;
            }
            else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
            {
                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
                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;
            }

            int hollowSides = sides;

            if (primShape.HollowShape == HollowShape.Circle)
            {
                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)
            {
                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(false);
                }
            }
            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(false);
                }
            }

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

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

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

            return(true);
        }
Example #10
0
        private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
        {
            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.Debug("[MESH]: experimental mesh proxy generation");

                    OSD meshOsd;

                    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))
                    {
                        meshOsd = (OSDMap)OSDParser.DeserializeLLSDBinary(data);
                        start   = data.Position;
                    }

                    if (meshOsd is OSDMap)
                    {
                        OSDMap map          = (OSDMap)meshOsd;
                        OSDMap physicsParms = (OSDMap)map["physics_shape"];
                        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)
                        {
                            decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
                            foreach (OSD subMeshOsd in decodedMeshOsdArray)
                            {
                                if (subMeshOsd is OSDMap)
                                {
                                    OSDMap subMeshMap = (OSDMap)subMeshOsd;

                                    OpenMetaverse.Vector3 posMax = ((OSDMap)subMeshMap["PositionDomain"])["Max"].AsVector3();
                                    OpenMetaverse.Vector3 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 = 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);
        }
Example #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;

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

                try
                {
                    ManagedImage managedImage;  // we never use this
                    OpenJPEG.DecodeToImage(primShape.SculptData, out managedImage, out idata);
                }
                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;
            }


            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);
        }
Example #12
0
        public static PrimMesh GetPrimMesh(LLPrimitive llprim, DetailLevel lod, bool isBasicMesh)
        {
            OMV.Primitive.ConstructionData primData = llprim.Prim.PrimData;
            int sides = 4;
            int hollowsides = 4;

            float profileBegin = primData.ProfileBegin;
            float profileEnd = primData.ProfileEnd;
            bool isSphere = false;

            if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.Circle)
            {
                switch (lod)
                {
                    case DetailLevel.Low:
                        sides = 6;
                        break;
                    case DetailLevel.Medium:
                        sides = 12;
                        break;
                    default:
                        sides = 24;
                        break;
                }
            }
            else if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.EqualTriangle)
                sides = 3;
            else if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle)
            {
                // half circle, prim is a sphere
                isSphere = true;
                switch (lod)
                {
                    case DetailLevel.Low:
                        sides = 6;
                        break;
                    case DetailLevel.Medium:
                        sides = 12;
                        break;
                    default:
                        sides = 24;
                        break;
                }
                profileBegin = 0.5f * profileBegin + 0.5f;
                profileEnd = 0.5f * profileEnd + 0.5f;
            }

            if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Same)
                hollowsides = sides;
            else if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Circle)
            {
                switch (lod)
                {
                    case DetailLevel.Low:
                        hollowsides = 6;
                        break;
                    case DetailLevel.Medium:
                        hollowsides = 12;
                        break;
                    default:
                        hollowsides = 24;
                        break;
                }
            }
            else if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Triangle)
                hollowsides = 3;

            PrimMesh newPrim = new PrimMesh(sides, profileBegin, profileEnd, (float)primData.ProfileHollow, hollowsides);
            newPrim.viewerMode = !isBasicMesh;
            newPrim.holeSizeX = primData.PathScaleX;
            newPrim.holeSizeY = primData.PathScaleY;
            newPrim.pathCutBegin = primData.PathBegin;
            newPrim.pathCutEnd = primData.PathEnd;
            newPrim.topShearX = primData.PathShearX;
            newPrim.topShearY = primData.PathShearY;
            newPrim.radius = primData.PathRadiusOffset;
            newPrim.revolutions = primData.PathRevolutions;
            newPrim.skew = primData.PathSkew;
            switch (lod)
            {
                case DetailLevel.Low:
                    newPrim.stepsPerRevolution = 6;
                    break;
                case DetailLevel.Medium:
                    newPrim.stepsPerRevolution = 12;
                    break;
                default:
                    newPrim.stepsPerRevolution = 24;
                    break;
            }

            if ((primData.PathCurve == OMV.PathCurve.Line) || (primData.PathCurve == OMV.PathCurve.Flexible))
            {
                newPrim.taperX = 1.0f - primData.PathScaleX;
                newPrim.taperY = 1.0f - primData.PathScaleY;
                newPrim.twistBegin = (int)(180 * primData.PathTwistBegin);
                newPrim.twistEnd = (int)(180 * primData.PathTwist);
                newPrim.ExtrudeLinear();
            }
            else
            {
                newPrim.taperX = primData.PathTaperX;
                newPrim.taperY = primData.PathTaperY;
                newPrim.twistBegin = (int)(360 * primData.PathTwistBegin);
                newPrim.twistEnd = (int)(360 * primData.PathTwist);
                newPrim.ExtrudeCircular();
            }

            int numViewerFaces = newPrim.viewerFaces.Count;
            int numPrimFaces = newPrim.numPrimFaces;

            for (uint i = 0; i < numViewerFaces; i++)
            {
                ViewerFace vf = newPrim.viewerFaces[(int)i];

                if (isSphere)
                {
                    vf.uv1.U = (vf.uv1.U - 0.5f) * 2.0f;
                    vf.uv2.U = (vf.uv2.U - 0.5f) * 2.0f;
                    vf.uv3.U = (vf.uv3.U - 0.5f) * 2.0f;
                }
            }

            return newPrim;
        }
Example #13
0
        private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
        {
            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 == 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);
        }
Example #14
0
        // from IdealistViewer.PrimMesherG.cs
        public PrimMesh ConstructionDataToPrimMesh(Primitive.ConstructionData primData, LevelOfDetail detail, float detailMult)
        {
            this.sides       = 4;
            this.hollowsides = 4;

            float profileBegin = primData.ProfileBegin;
            float profileEnd   = primData.ProfileEnd;
            bool  isSphere     = false;

            if ((ProfileCurve)(primData.profileCurve & 0x07) == ProfileCurve.Circle)
            {
                switch (detail)
                {
                case LevelOfDetail.Low:
                    sides = 6;
                    break;

                case LevelOfDetail.Medium:
                    sides = 12;
                    break;

                default:
                    sides = 24;
                    break;
                }
            }
            else if ((ProfileCurve)(primData.profileCurve & 0x07) == ProfileCurve.EqualTriangle)
            {
                sides = 3;
            }
            else if ((ProfileCurve)(primData.profileCurve & 0x07) == ProfileCurve.HalfCircle)
            { // half circle, prim is a sphere
                isSphere = true;
                switch (detail)
                {
                case LevelOfDetail.Low:
                    sides = 6;
                    break;

                case LevelOfDetail.Medium:
                    sides = 12;
                    break;

                default:
                    sides = 24;
                    break;
                }
                profileBegin = 0.5f * profileBegin + 0.5f;
                profileEnd   = 0.5f * profileEnd + 0.5f;
            }

            if ((HoleType)primData.ProfileHole == HoleType.Same)
            {
                hollowsides = sides;
            }
            else if ((HoleType)primData.ProfileHole == HoleType.Circle)
            {
                switch (detail)
                {
                case LevelOfDetail.Low:
                    hollowsides = 6;
                    break;

                case LevelOfDetail.Medium:
                    hollowsides = 12;
                    break;

                default:
                    hollowsides = 24;
                    break;
                }
            }
            else if ((HoleType)primData.ProfileHole == HoleType.Triangle)
            {
                hollowsides = 3;
            }

            //  if (UseExtremeDetail)
            {
                sides       = (int)(sides * detailMult);
                hollowsides = (int)(hollowsides * detailMult);
            }
            PrimMesh primMesh = new PrimMesh(sides, profileBegin, profileEnd, (float)primData.ProfileHollow, hollowsides);

            primMesh.viewerMode   = UseViewerMode;
            primMesh.holeSizeX    = primData.PathScaleX;
            primMesh.holeSizeY    = primData.PathScaleY;
            primMesh.pathCutBegin = primData.PathBegin;
            primMesh.pathCutEnd   = primData.PathEnd;
            primMesh.topShearX    = primData.PathShearX;
            primMesh.topShearY    = primData.PathShearY;
            primMesh.radius       = primData.PathRadiusOffset;
            primMesh.revolutions  = primData.PathRevolutions;
            primMesh.skew         = primData.PathSkew;
            switch (detail)
            {
            case LevelOfDetail.Low:
                primMesh.stepsPerRevolution = 6;
                break;

            case LevelOfDetail.Medium:
                primMesh.stepsPerRevolution = 12;
                break;

            default:
                primMesh.stepsPerRevolution = 24;
                break;
            }

            //if (UseExtremeDetail)
            {
                primMesh.stepsPerRevolution = (int)(primMesh.stepsPerRevolution * detailMult);
            }


            if (primData.PathCurve == PathCurve.Line)
            {
                primMesh.taperX     = 1.0f - primData.PathScaleX;
                primMesh.taperY     = 1.0f - primData.PathScaleY;
                primMesh.twistBegin = (int)(180 * primData.PathTwistBegin);
                primMesh.twistEnd   = (int)(180 * primData.PathTwist);
                primMesh.ExtrudeLinear();
            }
            else
            {
                primMesh.taperX     = primData.PathTaperX;
                primMesh.taperY     = primData.PathTaperY;
                primMesh.twistBegin = (int)(360 * primData.PathTwistBegin);
                primMesh.twistEnd   = (int)(360 * primData.PathTwist);
                primMesh.ExtrudeCircular();
            }


            if (UseViewerMode)
            {
                int numViewerFaces = primMesh.viewerFaces.Count;
                for (uint i = 0; i < numViewerFaces; i++)
                {
                    ViewerFace vf = primMesh.viewerFaces[(int)i];

                    if (isSphere)
                    {
                        vf.uv1.U = (vf.uv1.U - 0.5f) * 2.0f;
                        vf.uv2.U = (vf.uv2.U - 0.5f) * 2.0f;
                        vf.uv3.U = (vf.uv3.U - 0.5f) * 2.0f;
                    }
                }
            }
            return(primMesh);
        }
Example #15
0
 public PrimMeshVM(string Name, PrimMesh Mesh) : base(Name, true)
 {
     Childs.Add(new JMXAttribute("Path", Mesh.Path));
     Childs.Add(new JMXAttribute("UnkInt01", Mesh.Int01));
 }
Example #16
0
 private void ReportPrimError(string message, string primName, PrimMesh primMesh)
 {
     m_log.Error(message);
     m_log.Error("\nPrim Name: " + primName);
     m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString());
 }
        /// <summary>
        /// Generate the co-ords and faces necessary to construct a mesh from the shape data the accompanies a prim.
        /// </summary>
        /// <param name="primName"></param>
        /// <param name="primShape"></param>
        /// <param name="size"></param>
        /// <param name="coords">Coords are added to this list by the method.</param>
        /// <param name="faces">Faces are added to this list by the method.</param>
        /// <returns>true if coords and faces were successfully generated, false if not</returns>
        bool GenerateFromPrimShapeData(string primName, PrimitiveBaseShape primShape, Vector3 size,
            float lod, out List<Coord> coords, out List<Face> faces)
        {
            PrimMesh primMesh;
            coords = new List<Coord>();
            faces = new List<Face>();
            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;

            // defaults for LOD
            LevelOfDetail iLOD = (LevelOfDetail)lod;
            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;
            }

            switch ((primShape.ProfileCurve & 0x07))
            {
            case (byte) ProfileShape.EquilateralTriangle:
                sides = 3;
                break;
            case (byte) ProfileShape.Circle:
                break;      // use lod set above
            case (byte) ProfileShape.HalfCircle:
                profileBegin = 0.5f * profileBegin + 0.5f;
                profileEnd = 0.5f * profileEnd + 0.5f;
                break;      // use lod already set and...
            }

            int hollowSides = sides;
            // default lod for hollows
            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;
            }

            switch (primShape.HollowShape)
            {
            case HollowShape.Circle:
                //hollowSides = 24;
                break; // use lod preset
            case HollowShape.Square:
                hollowSides = 4;
                break;
            case HollowShape.Triangle:
                hollowSides = 3;
                break;
            }

            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 false;
                }
            } 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 false;
                }
            }

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

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

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

            return true;
        }
 void ReportPrimError(string message, string primName, PrimMesh primMesh)
 {
     MainConsole.Instance.Error(message);
     MainConsole.Instance.Error("\nPrim Name: " + primName);
     MainConsole.Instance.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString());
 }
Example #19
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) == SculptType.Mesh)
                {
                    if (!UseMeshesPhysicsMesh)
                    {
                        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 = System.IO.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
                        {
                            idata = m_j2kDecoder.DecodeToImage(primShape.SculptData);

                            if (idata != null && cacheSculptMaps &&
                                (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) == 0)))
                            {
                                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;
                switch ((primShape.ProfileCurve & 0x07))
                {
                case (byte)ProfileShape.EquilateralTriangle:
                    sides = 3;
                    break;

                case (byte)ProfileShape.Circle:
                    sides = 24;
                    break;

                case (byte)ProfileShape.HalfCircle:
                    sides        = 24;
                    profileBegin = 0.5f * profileBegin + 0.5f;
                    profileEnd   = 0.5f * profileEnd + 0.5f;
                    break;
                }

                int hollowSides = sides;
                switch (primShape.HollowShape)
                {
                case HollowShape.Circle:
                    hollowSides = 24;
                    break;

                case HollowShape.Square:
                    hollowSides = 4;
                    break;

                case HollowShape.Triangle:
                    hollowSides = 3;
                    break;
                }

                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;
            }

            Mesh mesh = new Mesh(key);
            //mesh.m_triangles = faces;
            //mesh.m_vertices = coords;
            // Add the corresponding triangles to the mesh
            mesh.Set(coords, faces);
            coords.Clear();
            faces.Clear();
            coords = null;
            faces  = null;
            return(mesh);
        }
        public VertexIndexer(PrimMesh primMesh)
        {
            int maxPrimFaceNumber = 0;

            foreach (ViewerFace vf in primMesh.viewerFaces)
            {
                if (maxPrimFaceNumber < vf.primFaceNumber)
                {
                    maxPrimFaceNumber = vf.primFaceNumber;
                }
            }

            this.numPrimFaces = maxPrimFaceNumber + 1;

            int[] numViewerVerts      = new int[numPrimFaces];
            int[] numVertsPerPrimFace = new int[numPrimFaces];

            for (int i = 0; i < numPrimFaces; i++)
            {
                numViewerVerts[i]      = 0;
                numVertsPerPrimFace[i] = 0;
            }

            foreach (ViewerFace vf in primMesh.viewerFaces)
            {
                numVertsPerPrimFace[vf.primFaceNumber] += 3;
            }

            this.viewerVertices    = new List <List <ViewerVertex> >(numPrimFaces);
            this.viewerPolygons    = new List <List <ViewerPolygon> >(numPrimFaces);
            this.viewerVertIndices = new int[numPrimFaces][];

            // create index lists
            for (int primFaceNumber = 0; primFaceNumber < numPrimFaces; primFaceNumber++)
            {
                //set all indices to -1 to indicate an invalid index
                int[] vertIndices = new int[primMesh.coords.Count];
                for (int i = 0; i < primMesh.coords.Count; i++)
                {
                    vertIndices[i] = -1;
                }
                viewerVertIndices[primFaceNumber] = vertIndices;

                viewerVertices.Add(new List <ViewerVertex>(numVertsPerPrimFace[primFaceNumber]));
                viewerPolygons.Add(new List <ViewerPolygon>());
            }

            // populate the index lists
            foreach (ViewerFace vf in primMesh.viewerFaces)
            {
                int v1, v2, v3;

                int[] vertIndices = viewerVertIndices[vf.primFaceNumber];
                List <ViewerVertex> viewerVerts = viewerVertices[vf.primFaceNumber];

                // add the vertices
                if (vertIndices[vf.coordIndex1] < 0)
                {
                    viewerVerts.Add(new ViewerVertex(vf.v1, vf.n1, vf.uv1));
                    v1 = viewerVerts.Count - 1;
                    vertIndices[vf.coordIndex1] = v1;
                }
                else
                {
                    v1 = vertIndices[vf.coordIndex1];
                }

                if (vertIndices[vf.coordIndex2] < 0)
                {
                    viewerVerts.Add(new ViewerVertex(vf.v2, vf.n2, vf.uv2));
                    v2 = viewerVerts.Count - 1;
                    vertIndices[vf.coordIndex2] = v2;
                }
                else
                {
                    v2 = vertIndices[vf.coordIndex2];
                }

                if (vertIndices[vf.coordIndex3] < 0)
                {
                    viewerVerts.Add(new ViewerVertex(vf.v3, vf.n3, vf.uv3));
                    v3 = viewerVerts.Count - 1;
                    vertIndices[vf.coordIndex3] = v3;
                }
                else
                {
                    v3 = vertIndices[vf.coordIndex3];
                }

                viewerPolygons[vf.primFaceNumber].Add(new ViewerPolygon(v1, v2, v3));
            }
        }
Example #21
0
 /// <summary>
 /// frees up the source mesh data to minimize memory - call this method after calling get*Locked() functions
 /// </summary>
 public void releaseSourceMeshData()
 {
     triangles = null;
     vertices  = null;
     primMesh  = null;
 }