示例#1
0
        /// <summary>
        /// Method for generating mesh Face from a heightmap
        /// </summary>
        /// <param name="zMap">Two dimension array of floats containing height information</param>
        /// <param name="xBegin">Starting value for X</param>
        /// <param name="xEnd">Max value for X</param>
        /// <param name="yBegin">Starting value for Y</param>
        /// <param name="yEnd">Max value of Y</param>
        /// <returns></returns>
        public Face TerrainMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float yEnd)
        {
            SculptMesh newMesh      = new SculptMesh(zMap, xBegin, xEnd, yBegin, yEnd, true);
            Face       terrain      = new Face();
            int        faceVertices = newMesh.coords.Count;

            terrain.Vertices = new List <Vertex>(faceVertices);
            terrain.Indices  = new List <ushort>(newMesh.faces.Count * 3);

            for (int j = 0; j < faceVertices; j++)
            {
                var vert = new OMVR.Vertex
                {
                    Position = new Vector3(newMesh.coords[j].X, newMesh.coords[j].Y, newMesh.coords[j].Z),
                    Normal   = new Vector3(newMesh.normals[j].X, newMesh.normals[j].Y, newMesh.normals[j].Z),
                    TexCoord = new Vector2(newMesh.uvs[j].U, newMesh.uvs[j].V)
                };
                terrain.Vertices.Add(vert);
            }

            for (int j = 0; j < newMesh.faces.Count; j++)
            {
                terrain.Indices.Add((ushort)newMesh.faces[j].v1);
                terrain.Indices.Add((ushort)newMesh.faces[j].v2);
                terrain.Indices.Add((ushort)newMesh.faces[j].v3);
            }

            return(terrain);
        }
示例#2
0
 public ToolCollection(SculptMesh sculptMesh) : base(
         new Dictionary <ToolType, Tool> {
     { ToolType.Standard, new StandardTool(sculptMesh) },
     { ToolType.Move, new MoveTool(sculptMesh) },
     { ToolType.Smooth, new SmoothTool(sculptMesh) },
 }
         )
 {
 }
示例#3
0
        public IEnumerator BuildMesh()
        {
            var timer = new Timer("build-mesh");

            Mesh mesh = null;

            timer.PrintTime(() => mesh = IcoSphereCreator.Create(7, .5f), "Create mesh");

            var wrapper = new GameObject().AddComponent <MeshWrapperBehaviour>();

            timer.PrintTime(() => sculptMesh = new SculptMesh(wrapper, mesh), "Parse mesh");

            timer.PrintTotalTime();
            timer.SaveCsv();

            Assert.AreEqual(163842, mesh.vertices.Length);

            yield return(null);
        }
示例#4
0
        public virtual void Init(SculptMesh sculptMesh, Menu menu)
        {
            MeshWrapper = sculptMesh.Wrapper;

            Menu = menu;

            deformer       = new Deformer(sculptMesh);
            mirrorDeformer = new Deformer(sculptMesh);

            tools       = new ToolCollection(sculptMesh);
            mirrorTools = new ToolCollection(sculptMesh);

            uiComponents.ForEach(ui => ui.Init(Menu));

            stateStack = new Stack <SculptState>();

            running = true;
            new Thread(
                new ThreadStart(SculptLoop)
                ).Start();
        }
        /// <summary>
        /// Generate a mesh from the sculpt data the accompanies a prim.
        /// </summary>
        /// <param name="primName"></param>
        /// <param name="primShape"></param>
        /// <param name="size"></param>
        /// <param name="lod"></param>
        /// <param name="key"></param>
        /// <returns>created mesh or null if invalid</returns>
        Mesh GenerateFromPrimSculptData(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, ulong key)
        {
            SculptMesh sculptMesh;
            Image      idata = null;
            string     decodedSculptFileName = "";


            if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
            {
                decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath,
                                                               "smap_" + primShape.SculptTexture);
                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);
                    ManagedImage mImage;
                    OpenJPEG.DecodeToImage(primShape.SculptData, out mImage);

                    if (mImage == null)
                    {
                        // In some cases it seems that the decode can return a null bitmap without throwing an exception
                        MainConsole.Instance.WarnFormat("[Sculpt]: OpenJPEG decoded sculpt data for {0} to a null bitmap.  Ignoring.", primName);
                        return(null);
                    }

                    if ((mImage.Channels & ManagedImage.ImageChannels.Alpha) != 0)
                    {
                        mImage.ConvertChannels(mImage.Channels & ~ManagedImage.ImageChannels.Alpha);
                    }

                    Bitmap imgData = LoadTGAClass.LoadTGA(new MemoryStream(mImage.ExportTGA()));
                    idata  = imgData;
                    mImage = null;

                    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.\n" +
                        "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();
#if SPAM
            sculptMesh.DumpRaw(baseDir, primName, "primMesh");
#endif

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

            var coords = sculptMesh.coords;
            var faces  = sculptMesh.faces;

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

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

            return(mesh);
        }
示例#6
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;
        }
示例#7
0
        /// <summary>
        /// Generate a mesh from the sculpt data the accompanies a prim.
        /// </summary>
        /// <param name="primName"></param>
        /// <param name="primShape"></param>
        /// <param name="size"></param>
        /// <param name="lod"></param>
        /// <param name="key"></param> 
        /// <returns>created mesh or null if invalid</returns>
        Mesh GenerateFromPrimSculptData (string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, ulong key)
        {
            SculptMesh sculptMesh;
            Image idata = null;
            string decodedSculptFileName = "";


            if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) {
                decodedSculptFileName = System.IO.Path.Combine (decodedSculptMapPath,
                    "smap_" + primShape.SculptTexture);
                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);
                    ManagedImage mImage;
                    OpenJPEG.DecodeToImage (primShape.SculptData, out mImage);

                    if (mImage == null) {
                        // In some cases it seems that the decode can return a null bitmap without throwing an exception
                        MainConsole.Instance.WarnFormat ("[Sculpt]: OpenJPEG decoded sculpt data for {0} to a null bitmap.  Ignoring.", primName);
                        return null;
                    }

                    if ((mImage.Channels & ManagedImage.ImageChannels.Alpha) != 0)
                        mImage.ConvertChannels (mImage.Channels & ~ManagedImage.ImageChannels.Alpha);

                    Bitmap imgData = LoadTGAClass.LoadTGA (new MemoryStream (mImage.ExportTGA ()));
                    idata = imgData;
                    mImage = null;

                    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.\n" +
                        "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 ();
#if SPAM
                sculptMesh.DumpRaw (baseDir, primName, "primMesh");
#endif

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

            var coords = sculptMesh.coords;
            var faces = sculptMesh.faces;

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

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

            return mesh;
        }
示例#8
0
 public MoveTool(SculptMesh mesh) : base(ToolType.Move, mesh)
 {
     prevPosition = Vector3.zero;
 }
示例#9
0
 public SmoothTool(SculptMesh mesh) : base(ToolType.Smooth, mesh)
 {
 }
示例#10
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);
        }
示例#11
0
 public StandardTool(SculptMesh mesh) : base(ToolType.Standard, mesh)
 {
 }
        /// <summary>
        /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim.
        /// </summary>
        /// <param name="primName"></param>
        /// <param name="primShape"></param>
        /// <param name="size"></param>
        /// <param name="lod"></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 GenerateFromPrimSculptData(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod,
            out List<Coord> coords, out List<Face> faces)
        {
            coords = new List<Coord> ();
            faces = new List<Face> ();
            SculptMesh sculptMesh;
            Image idata = null;
            string decodedSculptFileName = "";

            if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
            {
                decodedSculptFileName = System.IO.Path.Combine (decodedSculptMapPath,
                    "smap_" + primShape.SculptTexture);
                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 false;

                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.\n" +
                        "Often times this is because of an old version of GLIBC.  You must have version 2.4 or above!");
                    return false;
                } catch (IndexOutOfRangeException)
                {
                    MainConsole.Instance.Error (
                        "[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
                    return false;
                } catch (Exception ex)
                {
                    MainConsole.Instance.Error (
                        "[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " +
                        ex);
                    return false;
                }
            }

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

            sculptMesh = new 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;

            return true;
        }
示例#13
0
 public Tool(ToolType type, SculptMesh sculptMesh)
 {
     Type       = type;
     SculptMesh = sculptMesh;
 }
示例#14
0
        // partly from OpenSim.Region.Physics.Meshing
        public static SculptMesh ToSculptMesh(byte[] sculptData, Primitive.SculptData sculptDataIn, string sculptDataString)//( Vector3 size, Quaternion Rotation)
        {
            SculptMesh sculptMesh;

            if (sculptData == null || sculptData.Length == 0)
            {
                Error("[PHYSICS]: Missing Sclupt Data ", sculptDataString);
                return(null);
            }

            System.Drawing.Image idata = null;

            try
            {
                OpenMetaverse.Imaging.ManagedImage managedImage;  // we never use this
                if (!OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(sculptData, out managedImage, out idata))
                {
                    Error("[PHYSICS]: OpenMetaverse.Imaging.OpenJPEG.DecodeToImage failed ", sculptDataString);
                    return(null);
                }
            }
            catch (DllNotFoundException)
            {
                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!",
                    sculptDataString);
                return(null);
            }
            catch (IndexOutOfRangeException e)
            {
                Error("[PHYSICS]: OpenJpeg was unable to decode this.   Physics Proxy generation failed " + e, sculptDataString);
                return(null);
            }
            catch (Exception e)
            {
                Error("[PHYSICS]: Unable to generate a Sculpty physics proxy.  Sculpty texture decode failed! " + e, sculptDataString);
                return(null);
            }

            SculptMesh.SculptType sculptType;

            switch (sculptDataIn.Type)
            {
            case OpenMetaverse.SculptType.Cylinder:
                sculptType = SculptMesh.SculptType.cylinder;
                break;

            case OpenMetaverse.SculptType.Plane:
                sculptType = SculptMesh.SculptType.plane;
                break;

            case OpenMetaverse.SculptType.Torus:
                sculptType = SculptMesh.SculptType.torus;
                break;

            case OpenMetaverse.SculptType.Sphere:
            default:
                sculptType = SculptMesh.SculptType.sphere;
                break;
            }
            if (idata == null)
            {
                Error("[PHYSICS]: IData Null ", sculptDataString);
                return(null);
            }
            sculptMesh = new SculptMesh((System.Drawing.Bitmap)idata, sculptType, (int)32, false, sculptDataIn.Mirror, sculptDataIn.Invert);

            idata.Dispose();

            //    sculptMesh.DumpRaw(baseDir, primName, "primMesh");
            return(sculptMesh);
        }