Beispiel #1
0
 public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode)
 {
     Bitmap bitmap = (Bitmap) Image.FromFile(fileName);
     SculptMesh sculptMesh = new SculptMesh(bitmap, sculptType, lod, viewerMode);
     bitmap.Dispose();
     return sculptMesh;
 }
        public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode)
        {
            Bitmap     bitmap     = (Bitmap)Bitmap.FromFile(fileName);
            SculptMesh sculptMesh = new SculptMesh(bitmap, sculptType, lod, viewerMode);

            bitmap.Dispose();
            return(sculptMesh);
        }
Beispiel #3
0
        private void calcVertexNormals(SculptType sculptType, int xSize, int ySize)
        {
            // compute vertex normals by summing all the surface normals of all the triangles sharing
            // each vertex and then normalizing
            var numFaces = faces.Count;

            for (var i = 0; i < numFaces; i++)
            {
                var face          = faces[i];
                var surfaceNormal = face.SurfaceNormal(coords);
                normals[face.n1] += surfaceNormal;
                normals[face.n2] += surfaceNormal;
                normals[face.n3] += surfaceNormal;
            }

            var numNormals = normals.Count;

            for (var i = 0; i < numNormals; i++)
            {
                normals[i] = normals[i].Normalize();
            }

            if (sculptType != SculptType.plane)
            {
                for (var y = 0; y < ySize; y++)
                {
                    var rowOffset = y * xSize;

                    normals[rowOffset] = normals[rowOffset + xSize - 1] =
                        (normals[rowOffset] + normals[rowOffset + xSize - 1]).Normalize();
                }
            }

            foreach (var face in faces)
            {
                var vf = new ViewerFace(0);
                vf.v1 = coords[face.v1];
                vf.v2 = coords[face.v2];
                vf.v3 = coords[face.v3];

                vf.coordIndex1 = face.v1;
                vf.coordIndex2 = face.v2;
                vf.coordIndex3 = face.v3;

                vf.n1 = normals[face.n1];
                vf.n2 = normals[face.n2];
                vf.n3 = normals[face.n3];

                vf.uv1 = uvs[face.uv1];
                vf.uv2 = uvs[face.uv2];
                vf.uv3 = uvs[face.uv3];

                viewerFaces.Add(vf);
            }
        }
Beispiel #4
0
        private void calcVertexNormals(SculptType sculptType, int xSize, int ySize)
        {
            // compute vertex normals by summing all the surface normals of all the triangles sharing
            // each vertex and then normalizing
            int numFaces = this.faces.Count;

            for (int i = 0; i < numFaces; i++)
            {
                Face  face          = this.faces[i];
                Coord surfaceNormal = face.SurfaceNormal(this.coords);
                this.normals[face.n1] += surfaceNormal;
                this.normals[face.n2] += surfaceNormal;
                this.normals[face.n3] += surfaceNormal;
            }

            int numNormals = this.normals.Count;

            for (int i = 0; i < numNormals; i++)
            {
                this.normals[i] = this.normals[i].Normalize();
            }

            if (sculptType != SculptType.plane)
            {
                // blend the vertex normals at the cylinder seam
                for (int y = 0; y < ySize; y++)
                {
                    int rowOffset = y * xSize;

                    this.normals[rowOffset] =
                        this.normals[rowOffset + xSize - 1] =
                            (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize();
                }
            }

            foreach (ViewerFace vf in this.faces.Select(face => new ViewerFace(0)
            {
                v1 = this.coords[face.v1],
                v2 = this.coords[face.v2],
                v3 = this.coords[face.v3],
                coordIndex1 = face.v1,
                coordIndex2 = face.v2,
                coordIndex3 = face.v3,
                n1 = this.normals[face.n1],
                n2 = this.normals[face.n2],
                n3 = this.normals[face.n3],
                uv1 = this.uvs[face.uv1],
                uv2 = this.uvs[face.uv2],
                uv3 = this.uvs[face.uv3]
            }))
            {
                this.viewerFaces.Add(vf);
            }
        }
Beispiel #5
0
        public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool mirror, bool invert)
        {
            if (mirror)
                invert = !invert;

            SculptMap smap = new SculptMap(sculptBitmap, lod);

            List<List<Coord>> rows = smap.ToRows(mirror);

            _SculptMesh(rows, sculptType, invert);
        }
Beispiel #6
0
        public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool mirror, bool invert)
        {
            if (mirror)
            {
                invert = !invert;
            }

            SculptMap smap = new SculptMap(sculptBitmap, lod);

            List <List <Coord> > rows = smap.ToRows(mirror);

            _SculptMesh(rows, sculptType, invert);
        }
Beispiel #7
0
 public SculptData(byte[] data, int pos)
 {
     if (data.Length >= 17)
     {
         SculptTexture = new LLUUID(data, pos);
         Type          = (SculptType)data[pos + 16];
     }
     else
     {
         SculptTexture = LLUUID.Zero;
         Type          = SculptType.None;
     }
 }
Beispiel #8
0
        private void calcVertexNormals(SculptType sculptType, int xSize, int ySize)
        {  // compute vertex normals by summing all the surface normals of all the triangles sharing
            // each vertex and then normalizing
            int numFaces = this.faces.Count;

            for (int i = 0; i < numFaces; i++)
            {
                Face  face          = this.faces[i];
                Coord surfaceNormal = face.SurfaceNormal(this.coords);
                this.normals[face.v1] += surfaceNormal;
                this.normals[face.v2] += surfaceNormal;
                this.normals[face.v3] += surfaceNormal;
            }

            int numNormals = this.normals.Count;

            for (int i = 0; i < numNormals; i++)
            {
                this.normals[i] = this.normals[i].Normalize();
            }

            if (sculptType != SculptType.plane)
            { // blend the vertex normals at the cylinder seam
                int pixelsAcross = xSize + 1;
                for (int y = 0; y < ySize; y++)
                {
                    int rowOffset = y * pixelsAcross;

                    this.normals[rowOffset] = this.normals[rowOffset + xSize - 1] = (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize();
                }
            }

            foreach (Face face in this.faces)
            {
                ViewerFace vf = new ViewerFace(0);
                vf.v1 = this.coords[face.v1];
                vf.v2 = this.coords[face.v2];
                vf.v3 = this.coords[face.v3];

                vf.n1 = this.normals[face.n1];
                vf.n2 = this.normals[face.n2];
                vf.n3 = this.normals[face.n3];

                vf.uv1 = this.uvs[face.uv1];
                vf.uv2 = this.uvs[face.uv2];
                vf.uv3 = this.uvs[face.uv3];

                this.viewerFaces.Add(vf);
            }
        }
Beispiel #9
0
        private void _SculptMesh(List <List <Coord> > rows, SculptType sculptType, bool viewerMode, bool mirror,
                                 bool invert)
        {
            coords  = new List <Coord>();
            faces   = new List <Face>();
            normals = new List <Coord>();
            uvs     = new List <UVCoord>();

            sculptType = (SculptType)((int)sculptType & 0x07);

            if (mirror)
            {
                invert = !invert;
            }

            viewerFaces = new List <ViewerFace>();

            var width = rows[0].Count;

            int p1, p2, p3, p4;

            int imageX, imageY;

            if (sculptType != SculptType.plane)
            {
                if (rows.Count % 2 == 0)
                {
                    foreach (List <Coord> row in rows)
                    {
                        row.Add(row[0]);
                    }
                }
                else
                {
                    var lastIndex = rows[0].Count - 1;

                    foreach (List <Coord> row in rows)
                    {
                        row[0] = row[lastIndex];
                    }
                }
            }

            var topPole    = rows[0][width / 2];
            var bottomPole = rows[rows.Count - 1][width / 2];

            if (sculptType == SculptType.sphere)
            {
                if (rows.Count % 2 == 0)
                {
                    var count         = rows[0].Count;
                    var topPoleRow    = new List <Coord>(count);
                    var bottomPoleRow = new List <Coord>(count);

                    for (var i = 0; i < count; i++)
                    {
                        topPoleRow.Add(topPole);
                        bottomPoleRow.Add(bottomPole);
                    }
                    rows.Insert(0, topPoleRow);
                    rows.Add(bottomPoleRow);
                }
                else
                {
                    var count = rows[0].Count;

                    var topPoleRow    = rows[0];
                    var bottomPoleRow = rows[rows.Count - 1];

                    for (var i = 0; i < count; i++)
                    {
                        topPoleRow[i]    = topPole;
                        bottomPoleRow[i] = bottomPole;
                    }
                }
            }

            if (sculptType == SculptType.torus)
            {
                rows.Add(rows[0]);
            }

            var coordsDown   = rows.Count;
            var coordsAcross = rows[0].Count;
            var lastColumn   = coordsAcross - 1;

            var widthUnit  = 1.0f / (coordsAcross - 1);
            var heightUnit = 1.0f / (coordsDown - 1);

            for (imageY = 0; imageY < coordsDown; imageY++)
            {
                var rowOffset = imageY * coordsAcross;

                for (imageX = 0; imageX < coordsAcross; imageX++)
                {
                    /*
                     *   p1-----p2
                     *   | \ f2 |
                     *   |   \  |
                     *   | f1  \|
                     *   p3-----p4
                     */

                    p4 = rowOffset + imageX;
                    p3 = p4 - 1;

                    p2 = p4 - coordsAcross;
                    p1 = p3 - coordsAcross;

                    coords.Add(rows[imageY][imageX]);
                    if (viewerMode)
                    {
                        normals.Add(new Coord());
                        uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY));
                    }

                    if (imageY > 0 && imageX > 0)
                    {
                        Face f1, f2;

                        if (viewerMode)
                        {
                            if (invert)
                            {
                                f1 = new Face(p1, p4, p3, p1, p4, p3)
                                {
                                    uv1 = p1,
                                    uv2 = p4,
                                    uv3 = p3
                                };

                                f2 = new Face(p1, p2, p4, p1, p2, p4)
                                {
                                    uv1 = p1,
                                    uv2 = p2,
                                    uv3 = p4
                                };
                            }
                            else
                            {
                                f1 = new Face(p1, p3, p4, p1, p3, p4)
                                {
                                    uv1 = p1,
                                    uv2 = p3,
                                    uv3 = p4
                                };

                                f2 = new Face(p1, p4, p2, p1, p4, p2)
                                {
                                    uv1 = p1,
                                    uv2 = p4,
                                    uv3 = p2
                                };
                            }
                        }
                        else
                        {
                            if (invert)
                            {
                                f1 = new Face(p1, p4, p3);
                                f2 = new Face(p1, p2, p4);
                            }
                            else
                            {
                                f1 = new Face(p1, p3, p4);
                                f2 = new Face(p1, p4, p2);
                            }
                        }

                        faces.Add(f1);
                        faces.Add(f2);
                    }
                }
            }

            if (viewerMode)
            {
                calcVertexNormals(sculptType, coordsAcross, coordsDown);
            }
        }
Beispiel #10
0
 public SculptData(byte[] data, int pos)
 {
     if (data.Length >= 17)
     {
         SculptTexture = new LLUUID(data, pos);
         Type = (SculptType)data[pos + 16];
     }
     else
     {
         SculptTexture = LLUUID.Zero;
         Type = SculptType.None;
     }
 }
Beispiel #11
0
        public Mesh GetSculptMesh(UUID assetid, TextureExtended sculpttex, SculptType stype, Primitive prim)
        {
            Mesh result = null;

            lock (StoredMesh)
            {
                if (StoredMesh.ContainsKey(assetid.ToString()))
                {
                    result = StoredMesh[assetid.ToString()];
                    return result;
                }
            }
            if (result == null)
            {
                System.Drawing.Bitmap bm = sculpttex.DOTNETImage;
                result = PrimMesherG.SculptIrrMesh(bm, stype);
                if (!killed.Contains(sculpttex.Raw))
                {
                    try
                    {
                        killed.Add(sculpttex.Raw);
                        device.VideoDriver.RemoveTexture(sculpttex);
                    }
                    catch (AccessViolationException)
                    {
                        VUtil.LogConsole(this.ToString() + "[ACCESSVIOLATION]", "MeshFactory::GetSculptMesh");
                        System.Console.WriteLine("Unable to remove a sculpt texture from the video driver!");
                    }
                }
                bm.Dispose();
                if (result != null)
                {
                    lock (StoredMesh)
                    {
                        if (!StoredMesh.ContainsKey(assetid.ToString()))
                        {
                            StoredMesh.Add(assetid.ToString(), result);
                        }
                    }
                }
            }

            if (result != null)
            {
                return result;
            }

            return null;
        }
Beispiel #12
0
 public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert)
 {
     _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, mirror, invert);
 }
 private void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert)
 {
     _SculptMesh(new SculptMap(sculptBitmap, lod).ToRows(mirror), sculptType, viewerMode, mirror, invert);
 }
            public void Deserialize(OSDMap map)
            {
                GroupID = map["group-id"].AsUUID();
                Material = (Material)map["material"].AsInteger();
                Name = map["name"].AsString();
                Position = map["pos"].AsVector3();
                Rotation = map["rotation"].AsQuaternion();
                Scale = map["scale"].AsVector3();

                // Extra params
                OSDArray extraParams = map["extra_parameters"] as OSDArray;
                if (extraParams != null)
                {
                    ExtraParams = new ExtraParam[extraParams.Count];
                    for (int i = 0; i < extraParams.Count; i++)
                    {
                        ExtraParam extraParam = new ExtraParam();
                        extraParam.Deserialize(extraParams[i] as OSDMap);
                        ExtraParams[i] = extraParam;
                    }
                }
                else
                {
                    ExtraParams = new ExtraParam[0];
                }

                // Faces
                OSDArray faces = map["facelist"] as OSDArray;
                if (faces != null)
                {
                    Faces = new Face[faces.Count];
                    for (int i = 0; i < faces.Count; i++)
                    {
                        Face face = new Face();
                        face.Deserialize(faces[i] as OSDMap);
                        Faces[i] = face;
                    }
                }
                else
                {
                    Faces = new Face[0];
                }

                // Shape
                OSDMap shape = map["shape"] as OSDMap;
                OSDMap path = shape["path"] as OSDMap;
                PathBegin = (float)path["begin"].AsReal();
                PathCurve = path["curve"].AsInteger();
                PathEnd = (float)path["end"].AsReal();
                RadiusOffset = (float)path["radius_offset"].AsReal();
                Revolutions = (float)path["revolutions"].AsReal();
                ScaleX = (float)path["scale_x"].AsReal();
                ScaleY = (float)path["scale_y"].AsReal();
                ShearX = (float)path["shear_x"].AsReal();
                ShearY = (float)path["shear_y"].AsReal();
                Skew = (float)path["skew"].AsReal();
                TaperX = (float)path["taper_x"].AsReal();
                TaperY = (float)path["taper_y"].AsReal();
                Twist = (float)path["twist"].AsReal();
                TwistBegin = (float)path["twist_begin"].AsReal();

                OSDMap profile = shape["profile"] as OSDMap;
                ProfileBegin = (float)profile["begin"].AsReal();
                ProfileCurve = profile["curve"].AsInteger();
                ProfileEnd = (float)profile["end"].AsReal();
                ProfileHollow = (float)profile["hollow"].AsReal();

                OSDMap sculpt = shape["sculpt"] as OSDMap;
                if (sculpt != null)
                {
                    SculptID = sculpt["id"].AsUUID();
                    SculptType = (SculptType)sculpt["type"].AsInteger();
                }
                else
                {
                    SculptID = UUID.Zero;
                    SculptType = 0;
                }
            }
 public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode)
 {
     _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, false, false);
 }
 public SculptMesh(List <List <Coord> > rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert)
 {
     _SculptMesh(rows, sculptType, viewerMode, mirror, invert);
 }
Beispiel #17
0
        void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert)
        {
            coords = new List<Coord>();
            faces = new List<Face>();
            normals = new List<Coord>();
            uvs = new List<UVCoord>();

            sculptType = (SculptType)(((int)sculptType) & 0x07);

            if (mirror)
                if (sculptType == SculptType.plane)
                    invert = !invert;

            float sourceScaleFactor = (float)(lod) / (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height);

            int scale = (int)(1.0f / sourceScaleFactor);
            if (scale < 1) scale = 1;

            List<List<Coord>> rows = bitmap2Coords(sculptBitmap, scale, mirror);

            viewerFaces = new List<ViewerFace>();

            int width = sculptBitmap.Width / scale;
            // int height = sculptBitmap.Height / scale;

            int p1, p2, p3, p4;

            int imageX, imageY;

            if (sculptType != SculptType.plane)
            {
                for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++)
                    rows[rowNdx].Add(rows[rowNdx][0]);
                }

            Coord topPole = rows[0][width / 2];
            Coord bottomPole = rows[rows.Count - 1][width / 2];

            if (sculptType == SculptType.sphere)
            {
                int count = rows[0].Count;
                List<Coord> topPoleRow = new List<Coord>(count);
                List<Coord> bottomPoleRow = new List<Coord>(count);

                for (int i = 0; i < count; i++)
                {
                    topPoleRow.Add(topPole);
                    bottomPoleRow.Add(bottomPole);
                }
                rows.Insert(0, topPoleRow);
                rows.Add(bottomPoleRow);
            }
            else if (sculptType == SculptType.torus)
                rows.Add(rows[0]);

            int coordsDown = rows.Count;
            int coordsAcross = rows[0].Count;

            float widthUnit = 1.0f / (coordsAcross - 1);
            float heightUnit = 1.0f / (coordsDown - 1);

            for (imageY = 0; imageY < coordsDown; imageY++)
            {
                int rowOffset = imageY * coordsAcross;

                for (imageX = 0; imageX < coordsAcross; imageX++)
                {
                    /*
                    *   p1-----p2
                    *   | \ f2 |
                    *   |   \  |
                    *   | f1  \|
                    *   p3-----p4
                    */

                        p4 = rowOffset + imageX;
                        p3 = p4 - 1;

                    p2 = p4 - coordsAcross;
                    p1 = p3 - coordsAcross;

                    this.coords.Add(rows[imageY][imageX]);
                    if (viewerMode)
                    {
                        this.normals.Add(new Coord());
                        this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY));
                    }

                    if (imageY > 0 && imageX > 0)
                    {
                        Face f1, f2;

                        if (viewerMode)
                        {
                            if (invert)
                            {
                                f1 = new Face(p1, p4, p3, p1, p4, p3);
                                f1.uv1 = p1;
                                f1.uv2 = p4;
                                f1.uv3 = p3;

                                f2 = new Face(p1, p2, p4, p1, p2, p4);
                                f2.uv1 = p1;
                                f2.uv2 = p2;
                                f2.uv3 = p4;
                            }
                            else
                            {
                                f1 = new Face(p1, p3, p4, p1, p3, p4);
                                f1.uv1 = p1;
                                f1.uv2 = p3;
                                f1.uv3 = p4;

                                f2 = new Face(p1, p4, p2, p1, p4, p2);
                                f2.uv1 = p1;
                                f2.uv2 = p4;
                                f2.uv3 = p2;
                            }
                        }
                        else
                        {
                            if (invert)
                            {
                                f1 = new Face(p1, p4, p3);
                                f2 = new Face(p1, p2, p4);
                            }
                            else
                            {
                                f1 = new Face(p1, p3, p4);
                                f2 = new Face(p1, p4, p2);
                            }
                        }

                        this.faces.Add(f1);
                        this.faces.Add(f2);
                    }
                }
            }

            if (viewerMode)
                calcVertexNormals(sculptType, coordsAcross, coordsDown);
        }
Beispiel #18
0
        void calcVertexNormals(SculptType sculptType, int xSize, int ySize)
        {  // compute vertex normals by summing all the surface normals of all the triangles sharing
            // each vertex and then normalizing
            int numFaces = faces.Count;
            for (int i = 0; i < numFaces; i++)
            {
                Face face = faces[i];
                Coord surfaceNormal = face.SurfaceNormal(this.coords);
                normals[face.n1] += surfaceNormal;
                normals[face.n2] += surfaceNormal;
                normals[face.n3] += surfaceNormal;
            }

            int numNormals = normals.Count;
            for (int i = 0; i < numNormals; i++)
                normals[i] = normals[i].Normalize();

            if (sculptType != SculptType.plane)
            { // blend the vertex normals at the cylinder seam
                for (int y = 0; y < ySize; y++)
                {
                    int rowOffset = y * xSize;

                    normals[rowOffset] = normals[rowOffset + xSize - 1] = (normals[rowOffset] + normals[rowOffset + xSize - 1]).Normalize();
                }
            }

            foreach (Face face in faces)
            {
                ViewerFace vf = new ViewerFace(0);
                vf.v1 = coords[face.v1];
                vf.v2 = coords[face.v2];
                vf.v3 = coords[face.v3];

                vf.coordIndex1 = face.v1;
                vf.coordIndex2 = face.v2;
                vf.coordIndex3 = face.v3;

                vf.n1 = normals[face.n1];
                vf.n2 = normals[face.n2];
                vf.n3 = normals[face.n3];

                vf.uv1 = uvs[face.uv1];
                vf.uv2 = uvs[face.uv2];
                vf.uv3 = uvs[face.uv3];

                viewerFaces.Add(vf);
            }
        }
Beispiel #19
0
    protected bool CreateSide(Volume volume, bool partialBuild)
    {
        bool flat = TypeMask.HasFlag(VolumeFaceMask.Flat);

        SculptType  sculptStitching         = volume.Parameters.SculptType;
        SculptFlags sculptFlags             = volume.Parameters.SculptFlags;
        bool        sculptInvert            = sculptFlags.HasFlag(SculptFlags.Invert);
        bool        sculptMirror            = sculptFlags.HasFlag(SculptFlags.Mirror);
        bool        sculptReverseHorizontal = (sculptInvert ? !sculptMirror : sculptMirror);   // XOR

        int numVertices, numIndices;

        List <Vector3>        mesh     = volume.Points;
        List <Vector3>        profile  = volume.Profile.Points;
        List <Path.PathPoint> pathData = volume.Path.Points;

        int maxS = volume.Profile.PointCount;

        int   s, t, i;
        float ss, tt;

        numVertices = NumS * NumT;
        numIndices  = (NumS - 1) * (NumT - 1) * 6;

        // TODO: How does partial builds work?
        //partial_build = (num_vertices > NumVertices || num_indices > NumIndices) ? false : partial_build;

        //if (!partial_build)
        //{
        //	resizeVertices(num_vertices);
        //	resizeIndices(num_indices);

        //	if (!volume->isMeshAssetLoaded())
        //	{
        //		mEdge.resize(num_indices);
        //	}
        //}
        Positions.Clear();
        Normals.Clear();
        Indices.Clear();
        Edge.Clear();


        float beginStex = Mathf.Floor(profile[BeginS][2]);
        bool  test      = TypeMask.HasFlag(VolumeFaceMask.Inner | VolumeFaceMask.Flat) && NumS > 2;
        int   numS      = test ? NumS / 2 : NumS;

        int curVertex = 0;
        int endT      = BeginT + NumT;

        // Copy the vertices into the array
        for (t = BeginT; t < endT; t++)
        {
            tt = pathData[t].ExtrusionT;
            for (s = 0; s < numS; s++)
            {
                if (TypeMask.HasFlag(VolumeFaceMask.End))
                {
                    ss = s > 0 ? 1f : 0f;
                }
                else
                {
                    // Get s value for tex-coord.
                    if (!flat)
                    {
                        ss = profile[BeginS + s][2];
                    }
                    else
                    {
                        ss = profile[BeginS + s][2] - beginStex;
                    }
                }

                if (sculptReverseHorizontal)
                {
                    ss = 1f - ss;
                }

                // Check to see if this triangle wraps around the array.
                if (BeginS + s >= maxS)
                {
                    // We're wrapping
                    i = BeginS + s + maxS * (t - 1);
                }
                else
                {
                    i = BeginS + s + maxS * t;
                }

                Positions.Add(mesh[i]);
                Normals.Add(Vector3.zero);                  // This will be calculated later
                TexCoords.Add(new Vector2(ss, tt));

                curVertex++;

                if (test && s > 0)
                {
                    Positions.Add(mesh[i]);
                    Normals.Add(Vector3.zero); // This will be calculated later
                    TexCoords.Add(new Vector2(ss, tt));
                    curVertex++;
                }
            }

            if (test)
            {
                s = TypeMask.HasFlag(VolumeFaceMask.Open) ? numS - 1 : 0;

                i  = BeginS + s + maxS * t;
                ss = profile[BeginS + s][2] - beginStex;

                Positions.Add(mesh[i]);
                Normals.Add(Vector3.zero); // This will be calculated later
                TexCoords.Add(new Vector2(ss, tt));

                curVertex++;
            }
        }

        Centre = Vector3.zero;

        int curPos = 0;
        int endPos = Positions.Count;

        //get bounding box for this side
        Vector3 faceMin;
        Vector3 faceMax;

        faceMin = faceMax = Positions[curPos++];

        while (curPos < endPos)
        {
            UpdateMinMax(ref faceMin, ref faceMax, Positions[curPos++]);
        }
        // VFExtents change
        ExtentsMin = faceMin;
        ExtentsMax = faceMax;

        int tcCount = NumVertices;

        if (tcCount % 2 == 1)
        {         //odd number of texture coordinates, duplicate last entry to padded end of array
            tcCount++;
            TexCoords.Add(TexCoords[NumVertices - 1]);
        }

        int curTc = 0;
        int endTc = TexCoords.Count;

        Vector3 tcMin;
        Vector3 tcMax;

        tcMin = tcMax = TexCoords[curTc++];

        while (curTc < endTc)
        {
            UpdateMinMax(ref tcMin, ref tcMax, TexCoords[curTc++]);
        }

        //TODO: TexCoordExtents are weird this assumes Vector4
        //TexCoordExtentsMin.x = llmin(minp[0], minp[2]);
        //TexCoordExtentsMin.y = llmin(minp[1], minp[3]);
        //TexCoordExtentsMax.x = llmax(maxp[0], maxp[2]);
        //TexCoordExtentsMax.y = llmax(maxp[1], maxp[3]);

        Centre = (faceMin + faceMax) * 0.5f;

        bool flatFace = TypeMask.HasFlag(VolumeFaceMask.Flat); //(TypeMask & VolumeFaceMask.Flat) != 0;

        if (!partialBuild)
        {
            // Now we generate the indices.
            for (t = 0; t < (NumT - 1); t++)
            {
                for (s = 0; s < (NumS - 1); s++)
                {
                    Indices.Add(s + NumS * t);                                 //bottom left
                    Indices.Add(s + 1 + NumS * (t + 1));                       //top right
                    Indices.Add(s + NumS * (t + 1));                           //top left
                    Indices.Add(s + NumS * t);                                 //bottom left
                    Indices.Add(s + 1 + NumS * t);                             //bottom right
                    Indices.Add(s + 1 + NumS * (t + 1));                       //top right

                    Edge.Add((NumS - 1) * 2 * t + s * 2 + 1);                  //bottom left/top right neighbor face
                    if (t < NumT - 2)
                    {                                                          //top right/top left neighbor face
                        Edge.Add((NumS - 1) * 2 * (t + 1) + s * 2 + 1);
                    }
                    else if (NumT <= 3 || volume.Path.IsOpen == true)
                    {                     //no neighbor
                        Edge.Add(-1);
                    }
                    else
                    {                     //wrap on T
                        Edge.Add(s * 2 + 1);
                    }
                    if (s > 0)
                    {                                                                       //top left/bottom left neighbor face
                        Edge.Add((NumS - 1) * 2 * t + s * 2 - 1);
                    }
                    else if (flatFace || volume.Profile.IsOpen == true)
                    {                     //no neighbor
                        Edge.Add(-1);
                    }
                    else
                    {                       //wrap on S
                        Edge.Add((NumS - 1) * 2 * t + (NumS - 2) * 2 + 1);
                    }

                    if (t > 0)
                    {                                                                       //bottom left/bottom right neighbor face
                        Edge.Add((NumS - 1) * 2 * (t - 1) + s * 2);
                    }
                    else if (NumT <= 3 || volume.Path.IsOpen == true)
                    {                     //no neighbor
                        Edge.Add(-1);
                    }
                    else
                    {                     //wrap on T
                        Edge.Add((NumS - 1) * 2 * (NumT - 2) + s * 2);
                    }
                    if (s < NumS - 2)
                    {                                                                   //bottom right/top right neighbor face
                        Edge.Add((NumS - 1) * 2 * t + (s + 1) * 2);
                    }
                    else if (flatFace || volume.Profile.IsOpen == true)
                    {                     //no neighbor
                        Edge.Add(-1);
                    }
                    else
                    {                     //wrap on S
                        Edge.Add((NumS - 1) * 2 * t);
                    }
                    Edge.Add((NumS - 1) * 2 * t + s * 2);                                                 //top right/bottom left neighbor face
                }
            }
        }



        //      //clear normals
        //int dst = Normals.Count;
        //int end = dst + NumVertices;
        //Vector3 zero = Vector3.zero;

        //while (dst < end)
        //      {
        //          Normals.Add(zero);
        //	dst++;
        //}

        //generate normals

        // Compute triangle normals:
        int            count           = Indices.Count / 3;
        List <Vector3> triangleNormals = new List <Vector3>();
        int            idx             = 0;

        for (int triangleIndex = 0; triangleIndex < count; triangleIndex++)
        {
            Vector3 p0 = Positions[Indices[idx + 0]];
            Vector3 p1 = Positions[Indices[idx + 1]];
            Vector3 p2 = Positions[Indices[idx + 2]];

            //calculate triangle normal
            Vector3 a = p1 - p0;
            Vector3 b = p2 - p0;

            Vector3 normal = Vector3.Cross(a, b);

            if (Vector3.Dot(normal, normal) > 0.00001f)
            {
                normal.Normalize();
            }
            else
            {
                //degenerate, make up a value
                normal = normal.z >= 0 ? new Vector3(0f, 0f, 1f) : new Vector3(0f, 0f, -1f);
            }

            // This is probably an optimised way to calculate this:
            //LLQuad & vector1 = *((LLQuad*)&v1);
            //LLQuad & vector2 = *((LLQuad*)&v2);

            //LLQuad & amQ = *((LLQuad*)&a);
            //LLQuad & bmQ = *((LLQuad*)&b);

            // Vectors are stored in memory in w, z, y, x order from high to low
            // Set vector1 = { a[W], a[X], a[Z], a[Y] }
            //vector1 = _mm_shuffle_ps(amQ, amQ, _MM_SHUFFLE(3, 0, 2, 1));
            // Set vector2 = { b[W], b[Y], b[X], b[Z] }
            //vector2 = _mm_shuffle_ps(bmQ, bmQ, _MM_SHUFFLE(3, 1, 0, 2));
            // mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] }
            //vector2 = _mm_mul_ps(vector1, vector2);
            // vector3 = { a[W], a[Y], a[X], a[Z] }
            //amQ = _mm_shuffle_ps(amQ, amQ, _MM_SHUFFLE(3, 1, 0, 2));
            // vector4 = { b[W], b[X], b[Z], b[Y] }
            //bmQ = _mm_shuffle_ps(bmQ, bmQ, _MM_SHUFFLE(3, 0, 2, 1));
            // mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] }
            //vector1 = _mm_sub_ps(vector2, _mm_mul_ps(amQ, bmQ));

            //llassert(v1.isFinite3());

            triangleNormals.Add(normal);
            idx += 3;
        }

        // Add triangle normal contributions from each triangle to the vertex normals:
        idx = 0;
        for (int triangleIndex = 0; triangleIndex < count; triangleIndex++) //for each triangle
        {
            Vector3 c = triangleNormals[triangleIndex];

            Vector3 n0 = Normals[Indices[idx + 0]];
            Vector3 n1 = Normals[Indices[idx + 1]];
            Vector3 n2 = Normals[Indices[idx + 2]];

            n0 += c;
            n1 += c;
            n2 += c;

            //llassert(c.isFinite3());

            //even out quad contributions
            switch (triangleIndex % 2 + 1)
            {
            case 0: n0 += c; break;

            case 1: n1 += c; break;

            case 2: n2 += c; break;
            }
            ;

            Normals[Indices[idx + 0]] = n0;
            Normals[Indices[idx + 1]] = n1;
            Normals[Indices[idx + 2]] = n2;

            idx += 3;
        }

        // adjust normals based on wrapping and stitching

        Vector3 top = (Positions[0] - Positions[NumS * (NumT - 2)]);
        bool    s_bottom_converges = Vector3.Dot(top, top) < 0.000001f;

        top = Positions[NumS - 1] - Positions[NumS * (NumT - 2) + NumS - 1];
        bool s_top_converges = Vector3.Dot(top, top) < 0.000001f;

        if (sculptStitching == SculptType.None)          // logic for non-sculpt volumes
        {
            if (volume.Path.IsOpen == false)
            {             //wrap normals on T
                for (int j = 0; j < NumS; j++)
                {
                    Vector3 n = Normals[j] + Normals[NumS * (NumT - 1) + j];
                    Normals[j] = n;
                    Normals[NumS * (NumT - 1) + j] = n;
                }
            }

            if ((volume.Profile.IsOpen == false) && !(s_bottom_converges))
            {             //wrap normals on S
                for (int j = 0; j < NumT; j++)
                {
                    Vector3 n = Normals[NumS * j] + Normals[NumS * j + NumS - 1];
                    Normals[NumS * j]            = n;
                    Normals[NumS * j + NumS - 1] = n;
                }
            }

            if (volume.Parameters.PathParameters.PathType == PathType.Circle &&
                volume.Parameters.ProfileParameters.ProfileType == ProfileType.CircleHalf)
            {
                if (s_bottom_converges)
                {                 //all lower S have same normal
                    for (int j = 0; j < NumT; j++)
                    {
                        Normals[NumS * j] = new Vector3(1f, 0f, 0f);
                    }
                }

                if (s_top_converges)
                {                 //all upper S have same normal
                    for (int j = 0; j < NumT; j++)
                    {
                        Normals[NumS * j + NumS - 1] = new Vector3(-1f, 0f, 0f);
                    }
                }
            }
        }
        //else  // logic for sculpt volumes
        //{
        //BOOL average_poles = FALSE;
        //BOOL wrap_s = FALSE;
        //BOOL wrap_t = FALSE;

        //if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE)
        //	average_poles = TRUE;

        //if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) ||
        //	(sculpt_stitching == LL_SCULPT_TYPE_TORUS) ||
        //	(sculpt_stitching == LL_SCULPT_TYPE_CYLINDER))
        //	wrap_s = TRUE;

        //if (sculpt_stitching == LL_SCULPT_TYPE_TORUS)
        //	wrap_t = TRUE;


        //if (average_poles)
        //{
        //	// average normals for north pole

        //	LLVector4a average;
        //	average.clear();

        //	for (S32 i = 0; i < mNumS; i++)
        //	{
        //		average.add(norm[i]);
        //	}

        //	// set average
        //	for (S32 i = 0; i < mNumS; i++)
        //	{
        //		norm[i] = average;
        //	}

        //	// average normals for south pole

        //	average.clear();

        //	for (S32 i = 0; i < mNumS; i++)
        //	{
        //		average.add(norm[i + mNumS * (mNumT - 1)]);
        //	}

        //	// set average
        //	for (S32 i = 0; i < mNumS; i++)
        //	{
        //		norm[i + mNumS * (mNumT - 1)] = average;
        //	}
        //         }

        //if (wrap_s)
        //{
        //	for (S32 i = 0; i < mNumT; i++)
        //	{
        //		LLVector4a n;
        //		n.setAdd(norm[mNumS * i], norm[mNumS * i + mNumS - 1]);
        //		norm[mNumS * i] = n;
        //		norm[mNumS * i + mNumS - 1] = n;
        //	}
        //}

        //if (wrap_t)
        //{
        //	for (S32 i = 0; i < mNumS; i++)
        //	{
        //		LLVector4a n;
        //		n.setAdd(norm[i], norm[mNumS * (mNumT - 1) + i]);
        //		norm[i] = n;
        //		norm[mNumS * (mNumT - 1) + i] = n;
        //	}
        //}
        //}

        // Normalise normals:
        for (int normalIndex = 0; normalIndex < Normals.Count; normalIndex++)
        {
            Normals[normalIndex] = Normals[normalIndex].normalized;
        }

        return(true);
    }
Beispiel #20
0
        private void SetPrimType(IScriptInstance script, object[] rules, ref int i)
        {
            LLPrimitive prim = script.Host as LLPrimitive;

            if (prim == null)
            {
                return;
            }

            int code = llList2Integer(script, rules, i++);

            switch (code)
            {
            case LSLConstants.PRIM_TYPE_BOX:
            {
                int     holeShape = llList2Integer(script, rules, i++);
                Vector3 cut       = llList2Vector(script, rules, i++);
                float   hollow    = llList2Float(script, rules, i++);
                Vector3 twist     = llList2Vector(script, rules, i++);
                Vector3 topSize   = llList2Vector(script, rules, i++);
                Vector3 topShear  = llList2Vector(script, rules, i++);

                Primitive.ConstructionData primData = ObjectManager.BuildBasicShape(PrimType.Box);
                primData.Material = prim.Prim.PrimData.Material;
                primData.State    = prim.Prim.PrimData.State;

                prim.Prim.PrimData = primData;
                prim.Prim.Sculpt   = null;

                SetPrimShapeParams(prim, holeShape, cut, hollow, twist, topSize, topShear);
                break;
            }

            case LSLConstants.PRIM_TYPE_CYLINDER:
            {
                int     holeShape = llList2Integer(script, rules, i++);
                Vector3 cut       = llList2Vector(script, rules, i++);
                float   hollow    = llList2Float(script, rules, i++);
                Vector3 twist     = llList2Vector(script, rules, i++);
                Vector3 topSize   = llList2Vector(script, rules, i++);
                Vector3 topShear  = llList2Vector(script, rules, i++);

                Primitive.ConstructionData primData = ObjectManager.BuildBasicShape(PrimType.Cylinder);
                primData.Material = prim.Prim.PrimData.Material;
                primData.State    = prim.Prim.PrimData.State;

                prim.Prim.PrimData = primData;
                prim.Prim.Sculpt   = null;

                SetPrimShapeParams(prim, holeShape, cut, hollow, twist, topSize, topShear);
                break;
            }

            case LSLConstants.PRIM_TYPE_PRISM:
            {
                int     holeShape = llList2Integer(script, rules, i++);
                Vector3 cut       = llList2Vector(script, rules, i++);
                float   hollow    = llList2Float(script, rules, i++);
                Vector3 twist     = llList2Vector(script, rules, i++);
                Vector3 topSize   = llList2Vector(script, rules, i++);
                Vector3 topShear  = llList2Vector(script, rules, i++);

                Primitive.ConstructionData primData = ObjectManager.BuildBasicShape(PrimType.Prism);
                primData.Material = prim.Prim.PrimData.Material;
                primData.State    = prim.Prim.PrimData.State;

                prim.Prim.PrimData = primData;
                prim.Prim.Sculpt   = null;

                SetPrimShapeParams(prim, holeShape, cut, hollow, twist, topSize, topShear);
                break;
            }

            case LSLConstants.PRIM_TYPE_SPHERE:
            {
                int     holeShape = llList2Integer(script, rules, i++);
                Vector3 cut       = llList2Vector(script, rules, i++);
                float   hollow    = llList2Float(script, rules, i++);
                Vector3 twist     = llList2Vector(script, rules, i++);
                Vector3 dimple    = llList2Vector(script, rules, i++);

                Primitive.ConstructionData primData = ObjectManager.BuildBasicShape(PrimType.Sphere);
                primData.Material = prim.Prim.PrimData.Material;
                primData.State    = prim.Prim.PrimData.State;

                prim.Prim.PrimData = primData;
                prim.Prim.Sculpt   = null;

                SetPrimShapeParams(prim, holeShape, cut, hollow, twist, dimple);
                break;
            }

            case LSLConstants.PRIM_TYPE_TORUS:
            {
                int     holeShape    = llList2Integer(script, rules, i++);
                Vector3 cut          = llList2Vector(script, rules, i++);
                float   hollow       = llList2Float(script, rules, i++);
                Vector3 twist        = llList2Vector(script, rules, i++);
                Vector3 topSize      = llList2Vector(script, rules, i++);
                Vector3 topShear     = llList2Vector(script, rules, i++);
                Vector3 advCut       = llList2Vector(script, rules, i++);
                Vector3 taper        = llList2Vector(script, rules, i++);
                float   revolutions  = llList2Float(script, rules, i++);
                float   radiusOffset = llList2Float(script, rules, i++);
                float   skew         = llList2Float(script, rules, i++);

                Primitive.ConstructionData primData = ObjectManager.BuildBasicShape(PrimType.Torus);
                primData.Material = prim.Prim.PrimData.Material;
                primData.State    = prim.Prim.PrimData.State;

                prim.Prim.PrimData = primData;
                prim.Prim.Sculpt   = null;

                SetPrimShapeParams(prim, holeShape, cut, hollow, twist, topSize, topShear, advCut, taper, revolutions, radiusOffset, skew);
                break;
            }

            case LSLConstants.PRIM_TYPE_TUBE:
            {
                int     holeShape    = llList2Integer(script, rules, i++);
                Vector3 cut          = llList2Vector(script, rules, i++);
                float   hollow       = llList2Float(script, rules, i++);
                Vector3 twist        = llList2Vector(script, rules, i++);
                Vector3 topSize      = llList2Vector(script, rules, i++);
                Vector3 topShear     = llList2Vector(script, rules, i++);
                Vector3 advCut       = llList2Vector(script, rules, i++);
                Vector3 taper        = llList2Vector(script, rules, i++);
                float   revolutions  = llList2Float(script, rules, i++);
                float   radiusOffset = llList2Float(script, rules, i++);
                float   skew         = llList2Float(script, rules, i++);

                Primitive.ConstructionData primData = ObjectManager.BuildBasicShape(PrimType.Tube);
                primData.Material = prim.Prim.PrimData.Material;
                primData.State    = prim.Prim.PrimData.State;

                prim.Prim.PrimData = primData;
                prim.Prim.Sculpt   = null;

                SetPrimShapeParams(prim, holeShape, cut, hollow, twist, topSize, topShear, advCut, taper, revolutions, radiusOffset, skew);
                break;
            }

            case LSLConstants.PRIM_TYPE_RING:
            {
                int     holeShape    = llList2Integer(script, rules, i++);
                Vector3 cut          = llList2Vector(script, rules, i++);
                float   hollow       = llList2Float(script, rules, i++);
                Vector3 twist        = llList2Vector(script, rules, i++);
                Vector3 topSize      = llList2Vector(script, rules, i++);
                Vector3 topShear     = llList2Vector(script, rules, i++);
                Vector3 advCut       = llList2Vector(script, rules, i++);
                Vector3 taper        = llList2Vector(script, rules, i++);
                float   revolutions  = llList2Float(script, rules, i++);
                float   radiusOffset = llList2Float(script, rules, i++);
                float   skew         = llList2Float(script, rules, i++);

                Primitive.ConstructionData primData = ObjectManager.BuildBasicShape(PrimType.Ring);
                primData.Material = prim.Prim.PrimData.Material;
                primData.State    = prim.Prim.PrimData.State;

                prim.Prim.PrimData = primData;
                prim.Prim.Sculpt   = null;

                SetPrimShapeParams(prim, holeShape, cut, hollow, twist, topSize, topShear, advCut, taper, revolutions, radiusOffset, skew);
                break;
            }

            case LSLConstants.PRIM_TYPE_SCULPT:
            {
                string     sculptMap = llList2String(script, rules, i++);
                SculptType type      = (SculptType)llList2Integer(script, rules, i++);
                UUID       textureID = InventoryKey(script, sculptMap, AssetType.Texture);
                if (textureID == UUID.Zero)
                {
                    return;
                }

                Primitive.ConstructionData primData = ObjectManager.BuildBasicShape(PrimType.Sculpt);
                primData.Material = prim.Prim.PrimData.Material;
                primData.State    = prim.Prim.PrimData.State;

                Primitive.SculptData sculpt = new Primitive.SculptData();
                sculpt.Type          = type;
                sculpt.SculptTexture = textureID;

                prim.Prim.PrimData = primData;
                prim.Prim.Sculpt   = sculpt;
                break;
            }
            }
        }
Beispiel #21
0
        private void _SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool invert)
        {
            coords = new List<Coord>();
            faces = new List<Face>();

            sculptType = (SculptType)(((int)sculptType) & 0x07);

            int width = rows[0].Count;

            int p1, p2, p3, p4;

            int imageX, imageY;

            if (sculptType != SculptType.plane)
            {
                if (rows.Count % 2 == 0)
                {
                    for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++)
                        rows[rowNdx].Add(rows[rowNdx][0]);
                }
                else
                {
                    int lastIndex = rows[0].Count - 1;

                    for (int i = 0; i < rows.Count; i++)
                        rows[i][0] = rows[i][lastIndex];
                }
            }

            Coord topPole = rows[0][width / 2];
            Coord bottomPole = rows[rows.Count - 1][width / 2];

            if (sculptType == SculptType.sphere)
            {
                if (rows.Count % 2 == 0)
                {
                    int count = rows[0].Count;
                    List<Coord> topPoleRow = new List<Coord>(count);
                    List<Coord> bottomPoleRow = new List<Coord>(count);

                    for (int i = 0; i < count; i++)
                    {
                        topPoleRow.Add(topPole);
                        bottomPoleRow.Add(bottomPole);
                    }
                    rows.Insert(0, topPoleRow);
                    rows.Add(bottomPoleRow);
                }
                else
                {
                    int count = rows[0].Count;

                    List<Coord> topPoleRow = rows[0];
                    List<Coord> bottomPoleRow = rows[rows.Count - 1];

                    for (int i = 0; i < count; i++)
                    {
                        topPoleRow[i] = topPole;
                        bottomPoleRow[i] = bottomPole;
                    }
                }
            }

            if (sculptType == SculptType.torus)
                rows.Add(rows[0]);

            int coordsDown = rows.Count;
            int coordsAcross = rows[0].Count;

            float widthUnit = 1.0f / (coordsAcross - 1);
            float heightUnit = 1.0f / (coordsDown - 1);

            for (imageY = 0; imageY < coordsDown; imageY++)
            {
                int rowOffset = imageY * coordsAcross;

                for (imageX = 0; imageX < coordsAcross; imageX++)
                {
                    /*
                    *   p1-----p2
                    *   | \ f2 |
                    *   |   \  |
                    *   | f1  \|
                    *   p3-----p4
                    */

                    p4 = rowOffset + imageX;
                    p3 = p4 - 1;

                    p2 = p4 - coordsAcross;
                    p1 = p3 - coordsAcross;

                    this.coords.Add(rows[imageY][imageX]);

                    if (imageY > 0 && imageX > 0)
                    {
                        Face f1, f2;

                            if (invert)
                            {
                                f1 = new Face(p1, p4, p3);
                                f2 = new Face(p1, p2, p4);
                            }
                            else
                            {
                                f1 = new Face(p1, p3, p4);
                                f2 = new Face(p1, p4, p2);
                            }

                        this.faces.Add(f1);
                        this.faces.Add(f2);
                    }
                }
            }
        }
 public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert)
 {
     _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, mirror, invert);
 }
Beispiel #23
0
        private static List<Vertex> GenerateSculptMesh(int sculptWidth, int sculptHeight, int sizeS, int sizeT, SculptType sculptType, bool invert, bool mirror, Bitmap sculptTexture)
        {
            bool reverseHorizontal = (invert) ? !mirror : mirror;

            List<Vertex> mesh = new List<Vertex>(sizeS * sizeT);

            Rectangle rect = new Rectangle(0, 0, sculptWidth, sculptHeight);
            BitmapData bmpData = sculptTexture.LockBits(rect, ImageLockMode.ReadOnly, sculptTexture.PixelFormat);
            int components = (sculptTexture.PixelFormat == (sculptTexture.PixelFormat | PixelFormat.Alpha)) ? 4 : 3;
            //int offset = bmpData.Stride - sculptWidth * components;

            for (int s = sizeS - 1; s >= 0; s--)
            {
                // Run along the profile
                for (int t = 0; t < sizeT; t++)
                {
                    int reversedT = t;
                    if (reverseHorizontal)
                        reversedT = sizeT - t - 1;

                    int x = (int)((float)reversedT / (sizeT - 1) * (float)sculptWidth);
                    int y = (int)((float)s / (sizeS - 1) * (float)sculptHeight);

                    if (y == 0) // Top row stitching
                    {
                        // Pinch?
                        if (sculptType == SculptType.Sphere)
                            x = sculptWidth / 2;
                    }

                    if (y == sculptHeight)  // Bottom row stitching
                    {
                        // Wrap?
                        if (sculptType == SculptType.Torus)
                            y = 0;
                        else
                            y = sculptHeight - 1;

                        // Pinch?
                        if (sculptType == SculptType.Sphere)
                            x = sculptWidth / 2;
                    }

                    if (x == sculptWidth) // Side stitching
                    {
                        // Wrap?
                        if (sculptType == SculptType.Sphere || sculptType == SculptType.Torus || sculptType == SculptType.Cylinder)
                            x = 0;
                        else
                            x = sculptWidth - 1;
                    }

                    Vector3 pos;

                    unsafe
                    {
                        byte* ptr = (byte*)bmpData.Scan0 + (y * bmpData.Stride) + (x * components);
                        pos = SculptRGBToVector(*(ptr + 2), *(ptr + 1), *(ptr + 0));
                    }

                    if (mirror)
                        pos.X *= -1f;

                    // The rest of the vertex parameters will be set later
                    mesh.Add(new Vertex { Position = pos });
                }
            }

            sculptTexture.UnlockBits(bmpData);
            return mesh;
        }
Beispiel #24
0
        void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert)
        {
            coords = new List<Coord>();
            faces = new List<Face>();
            normals = new List<Coord>();
            uvs = new List<UVCoord>();

            sculptType = (SculptType)(((int)sculptType) & 0x07);

            if (mirror)
                if (sculptType == SculptType.plane)
                    invert = !invert;

            float sculptBitmapLod = (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height);

            float sourceScaleFactor = (float)(lod) / sculptBitmapLod;

            float fScale = 1.0f / sourceScaleFactor;

            int iScale = (int)fScale;
            if (iScale < 1) iScale = 1;
            if (iScale > 2 && iScale % 2 == 0)
                _SculptMesh(bitmap2Coords(ScaleImage(sculptBitmap, 64.0f / sculptBitmapLod, true), 64 / lod, mirror), sculptType, viewerMode, mirror, invert);
            else
                _SculptMesh(bitmap2Coords(sculptBitmap, iScale, mirror), sculptType, viewerMode, mirror, invert);
        }
Beispiel #25
0
 private void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror,
                          bool invert)
 {
     _SculptMesh(new SculptMap(sculptBitmap, lod).ToRows(mirror), sculptType, viewerMode, mirror, invert);
 }
        private void _SculptMesh(List <List <Coord> > rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert)
        {
            coords  = new List <Coord>();
            faces   = new List <Face>();
            normals = new List <Coord>();
            uvs     = new List <UVCoord>();

            sculptType = (SculptType)(((int)sculptType) & 0x07);

            if (mirror)
            {
                invert = !invert;
            }

            viewerFaces = new List <ViewerFace>();

            int width = rows[0].Count;

            int p1, p2, p3, p4;

            int imageX, imageY;

            if (sculptType != SculptType.plane)
            {
                if (rows.Count % 2 == 0)
                {
                    for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++)
                    {
                        rows[rowNdx].Add(rows[rowNdx][0]);
                    }
                }
                else
                {
                    int lastIndex = rows[0].Count - 1;

                    for (int i = 0; i < rows.Count; i++)
                    {
                        rows[i][0] = rows[i][lastIndex];
                    }
                }
            }

            Coord topPole    = rows[0][width / 2];
            Coord bottomPole = rows[rows.Count - 1][width / 2];

            if (sculptType == SculptType.sphere)
            {
                if (rows.Count % 2 == 0)
                {
                    int          count         = rows[0].Count;
                    List <Coord> topPoleRow    = new List <Coord>(count);
                    List <Coord> bottomPoleRow = new List <Coord>(count);

                    for (int i = 0; i < count; i++)
                    {
                        topPoleRow.Add(topPole);
                        bottomPoleRow.Add(bottomPole);
                    }
                    rows.Insert(0, topPoleRow);
                    rows.Add(bottomPoleRow);
                }
                else
                {
                    int count = rows[0].Count;

                    List <Coord> topPoleRow    = rows[0];
                    List <Coord> bottomPoleRow = rows[rows.Count - 1];

                    for (int i = 0; i < count; i++)
                    {
                        topPoleRow[i]    = topPole;
                        bottomPoleRow[i] = bottomPole;
                    }
                }
            }

            if (sculptType == SculptType.torus)
            {
                rows.Add(rows[0]);
            }

            int coordsDown   = rows.Count;
            int coordsAcross = rows[0].Count;
            //            int lastColumn = coordsAcross - 1;

            float widthUnit  = 1.0f / (coordsAcross - 1);
            float heightUnit = 1.0f / (coordsDown - 1);

            for (imageY = 0; imageY < coordsDown; imageY++)
            {
                int rowOffset = imageY * coordsAcross;

                for (imageX = 0; imageX < coordsAcross; imageX++)
                {
                    /*
                     *   p1-----p2
                     *   | \ f2 |
                     *   |   \  |
                     *   | f1  \|
                     *   p3-----p4
                     */

                    p4 = rowOffset + imageX;
                    p3 = p4 - 1;

                    p2 = p4 - coordsAcross;
                    p1 = p3 - coordsAcross;

                    this.coords.Add(rows[imageY][imageX]);
                    if (viewerMode)
                    {
                        this.normals.Add(new Coord());
                        this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY));
                    }

                    if (imageY > 0 && imageX > 0)
                    {
                        Face f1, f2;

                        if (viewerMode)
                        {
                            if (invert)
                            {
                                f1     = new Face(p1, p4, p3, p1, p4, p3);
                                f1.uv1 = p1;
                                f1.uv2 = p4;
                                f1.uv3 = p3;

                                f2     = new Face(p1, p2, p4, p1, p2, p4);
                                f2.uv1 = p1;
                                f2.uv2 = p2;
                                f2.uv3 = p4;
                            }
                            else
                            {
                                f1     = new Face(p1, p3, p4, p1, p3, p4);
                                f1.uv1 = p1;
                                f1.uv2 = p3;
                                f1.uv3 = p4;

                                f2     = new Face(p1, p4, p2, p1, p4, p2);
                                f2.uv1 = p1;
                                f2.uv2 = p4;
                                f2.uv3 = p2;
                            }
                        }
                        else
                        {
                            if (invert)
                            {
                                f1 = new Face(p1, p4, p3);
                                f2 = new Face(p1, p2, p4);
                            }
                            else
                            {
                                f1 = new Face(p1, p3, p4);
                                f2 = new Face(p1, p4, p2);
                            }
                        }

                        this.faces.Add(f1);
                        this.faces.Add(f2);
                    }
                }
            }

            if (viewerMode)
            {
                calcVertexNormals(sculptType, coordsAcross, coordsDown);
            }
        }
Beispiel #27
0
        private void calcVertexNormals(SculptType sculptType, int xSize, int ySize)
        {
            // compute vertex normals by summing all the surface normals of all the triangles sharing
            // each vertex and then normalizing
            int numFaces = this.faces.Count;
            for (int i = 0; i < numFaces; i++)
            {
                Face face = this.faces[i];
                Coord surfaceNormal = face.SurfaceNormal(this.coords);
                this.normals[face.n1] += surfaceNormal;
                this.normals[face.n2] += surfaceNormal;
                this.normals[face.n3] += surfaceNormal;
            }

            int numNormals = this.normals.Count;
            for (int i = 0; i < numNormals; i++)
                this.normals[i] = this.normals[i].Normalize();

            if (sculptType != SculptType.plane)
            {
                // blend the vertex normals at the cylinder seam
                for (int y = 0; y < ySize; y++)
                {
                    int rowOffset = y*xSize;

                    this.normals[rowOffset] =
                        this.normals[rowOffset + xSize - 1] =
                        (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize();
                }
            }
            
#if (!ISWIN)
            foreach(Face face in this.faces)
            {
                ViewerFace vf = new ViewerFace(0)
                                                                    {
                                                                        v1 = this.coords[face.v1],
                                                                        v2 = this.coords[face.v2],
                                                                        v3 = this.coords[face.v3],
                                                                        coordIndex1 = face.v1,
                                                                        coordIndex2 = face.v2,
                                                                        coordIndex3 = face.v3,
                                                                        n1 = this.normals[face.n1],
                                                                        n2 = this.normals[face.n2],
                                                                        n3 = this.normals[face.n3],
                                                                        uv1 = this.uvs[face.uv1],
                                                                        uv2 = this.uvs[face.uv2],
                                                                        uv3 = this.uvs[face.uv3]
                                                                    };
                this.viewerFaces.Add(vf);

            }
#else
            foreach (ViewerFace vf in this.faces.Select(face => new ViewerFace(0)
                                                                    {
                                                                        v1 = this.coords[face.v1],
                                                                        v2 = this.coords[face.v2],
                                                                        v3 = this.coords[face.v3],
                                                                        coordIndex1 = face.v1,
                                                                        coordIndex2 = face.v2,
                                                                        coordIndex3 = face.v3,
                                                                        n1 = this.normals[face.n1],
                                                                        n2 = this.normals[face.n2],
                                                                        n3 = this.normals[face.n3],
                                                                        uv1 = this.uvs[face.uv1],
                                                                        uv2 = this.uvs[face.uv2],
                                                                        uv3 = this.uvs[face.uv3]
                                                                    }))
            {
                this.viewerFaces.Add(vf);
            }
#endif
        }
Beispiel #28
0
 public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode)
 {
     _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, false, false);
 }
Beispiel #29
0
        public SculptMesh(List <List <Vector3> > rows, SculptType sculptType, bool viewerMode, int lod)
        {
            uint vertsWanted = 1024;

            switch ((LevelDetail)lod)
            {
            case LevelDetail.Highest:
                vertsWanted = 1024;
                break;

            case LevelDetail.High:
                vertsWanted = 1024;
                break;

            case LevelDetail.Low:
                vertsWanted = 256;
                break;

            default:
                vertsWanted = 32;
                break;
            }

            // It is defined that the sculpt texture shall be no smaller than 64 pixels
            // and that the behavior with a 32 x 32 texture is
            uint height = (uint)rows.Count();

            if (height < 2)
            {
                return;
            }

            uint width = (uint)rows[0].Count();

            if (width < 2)
            {
                return;
            }

            // Sculpt textures must be powers of two.
            if (!((height & (~height + 1)) == height) ||
                !((width & (~width + 1)) == width))
            {
                return;
            }

            // Sculpties are limited to 1024 vertices. If the count is exceeded, the texture
            // sample rate will be reduced until the vertex count fits.
            ushort step = 1;

            uint verts = width * height;

            while (verts > vertsWanted)
            {
                step <<= 1;

                // In the below cases, this LOD has no geometry (doesn't show)
                if (step >= width)
                {
                    return;
                }
                if (step >= height)
                {
                    return;
                }

                verts >>= 2;
            }

            sculptType = (SculptType)(((int)sculptType) & 0x07);

            ushort horizontalDivisions = (ushort)(width / step);
            ushort verticalDivisions   = (ushort)(height / step);
            ushort matrixWidth         = (ushort)(horizontalDivisions + 1);
            ushort matrixHeight        = (ushort)(verticalDivisions + 1);

            float divisionU = 1.0f / (float)horizontalDivisions;
            float divisionV = 1.0f / (float)verticalDivisions;

            // Reduce the input texture to our coordinate matrix. This greatly simplifies
            // what is to come.
            Vector3[,] matrix = new Vector3[matrixHeight, matrixWidth];

            int v, vv;
            int h, hh;

            int oneMinushalfStep = -step / 2;

            oneMinushalfStep += step;

            for (v = 0, vv = 0; v < (int)height; ++vv, v += step)
            {
                for (h = 0, hh = 0; h < (int)width; ++hh, h += step)
                {
                    matrix[vv, hh] = rows[v][h];
                }
                if (step > 1)
                {
                    if (step > 2)
                    {
                        matrix[vv, hh] = rows[v][h - oneMinushalfStep];
                    }
                    else
                    {
                        matrix[vv, hh] = rows[v][h - 1];
                    }
                }
                else
                {
                    // This WILL cause texture mapping errors but we have no
                    // closer approximation to the data needed here.
                    matrix[vv, hh] = matrix[vv, hh - 1];
                }
            }

            for (h = 0, hh = 0; h < (int)width; ++hh, h += step)
            {
                if (step > 1)
                {
                    if (step > 2)
                    {
                        matrix[vv, hh] = rows[v - oneMinushalfStep][h];
                    }
                    else
                    {
                        matrix[vv, hh] = rows[v - 1][h];
                    }
                }
                else
                {
                    matrix[vv, hh] = matrix[vv - 1, hh];
                }
            }

            if (hh == matrixWidth - 1 && h == width && step > 1)
            {
                if (step > 2)
                {
                    matrix[vv, hh] = rows[v - oneMinushalfStep][h - 1];
                }
                else
                {
                    matrix[vv, hh] = rows[v - 1][h - 1];
                }
            }

            if (sculptType == SculptType.sphere)
            {
                // Find the poles for spherical sitching

                // The south pole is taken from the "extra" row (33) data
                // unless the source texture is 32 pixels tall. In that case
                // it is taken from the center of the last valid row. The
                // results may be undefined.

                Vector3 northPole = matrix[0, matrixWidth / 2];
                Vector3 southPole = matrix[matrixHeight - 1, matrixWidth / 2];

                // Spherical sculpts get all vertices in the 1st and 33rd
                // row stitched to a common "pole" taken from the center
                // of the top and the last valid input row.
                // The coordinates in the top row get overwritten by this
                // operation.

                for (int h1 = 0; h1 < matrixWidth; ++h1)
                {
                    matrix[0, h1] = northPole;
                    matrix[matrixHeight - 1, h1] = southPole;
                }
            }

            // For these two, stitch sides left to right
            if (sculptType == SculptType.sphere || sculptType == SculptType.cylinder || sculptType == SculptType.torus)
            {
                for (int v1 = 0; v1 < matrixHeight; ++v1)
                {
                    matrix[v1, matrixWidth - 1] = matrix[v1, 0];
                }
            }

            // For this one, stitch top to bottom as well
            if (sculptType == SculptType.torus)
            {
                for (int h1 = 0; h1 < matrixWidth; ++h1)
                {
                    matrix[matrixHeight - 1, h1] = matrix[0, h1];
                }
            }

            coords.Clear();
            normals.Clear();
            faces.Clear();

            int p1, p2, p3, p4;

            for (int imageY = 0; imageY < matrixHeight; imageY++)
            {
                int rowOffset = imageY * matrixWidth;

                for (int imageX = 0; imageX < matrixWidth; imageX++)
                {
                    //*
                    //*   p1-----p2
                    //*   | \ f2 |
                    //*   |   \  |
                    //*   | f1  \|
                    //*   p3-----p4
                    //*

                    p4 = rowOffset + imageX;
                    p3 = p4 - 1;

                    p2 = p4 - matrixWidth;
                    p1 = p3 - matrixWidth;

                    coords.Add(matrix[imageY, imageX]);

                    if (viewerMode)
                    {
                        normals.Add(new Vector3());
                        uvs.Add(new Vector2(divisionU * imageX, divisionV * imageY));
                    }

                    if (imageY > 0 && imageX > 0)
                    {
                        Face f;
                        f = new Face(p1, p3, p4);
                        faces.Add(f);
                        f = new Face(p1, p4, p2);
                        faces.Add(f);
                    }
                }
            }

            if (viewerMode)
            {
                calcVertexNormals(sculptType, matrixWidth, matrixHeight);
            }
        }
Beispiel #30
0
 public SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert)
 {
     _SculptMesh(rows, sculptType, viewerMode, mirror, invert);
 }
Beispiel #31
0
        void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert)
        {
            coords  = new List <Coord>();
            faces   = new List <Face>();
            normals = new List <Coord>();
            uvs     = new List <UVCoord>();

            if (mirror)
            {
                if (sculptType == SculptType.plane)
                {
                    invert = !invert;
                }
            }

            float sourceScaleFactor = (float)(lod) / (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height);
            bool  scaleSourceImage  = sourceScaleFactor < 1.0f ? true : false;

            Bitmap bitmap;

            if (scaleSourceImage)
            {
                bitmap = ScaleImage(sculptBitmap, sourceScaleFactor);
            }
            else
            {
                bitmap = sculptBitmap;
            }

            viewerFaces = new List <ViewerFace>();

            int width  = bitmap.Width;
            int height = bitmap.Height;

            float widthUnit  = 1.0f / width;
            float heightUnit = 1.0f / (height - 1);

            int   p1, p2, p3, p4;
            Color color;
            float x, y, z;

            int imageX, imageY;

            if (sculptType == SculptType.sphere)
            {
                int lastRow = height - 1;

                // poles of sphere mesh are the center pixels of the top and bottom rows
                Color newC1 = bitmap.GetPixel(width / 2, 0);
                Color newC2 = bitmap.GetPixel(width / 2, lastRow);

                for (imageX = 0; imageX < width; imageX++)
                {
                    bitmap.SetPixel(imageX, 0, newC1);
                    bitmap.SetPixel(imageX, lastRow, newC2);
                }
            }


            int pixelsDown   = sculptType == SculptType.plane ? height : height + 1;
            int pixelsAcross = sculptType == SculptType.plane ? width : width + 1;

            for (imageY = 0; imageY < pixelsDown; imageY++)
            {
                int rowOffset = imageY * width;

                for (imageX = 0; imageX < pixelsAcross; imageX++)
                {
                    /*
                     *   p1-----p2
                     *   | \ f2 |
                     *   |   \  |
                     *   | f1  \|
                     *   p3-----p4
                     */

                    if (imageX < width)
                    {
                        p4 = rowOffset + imageX;
                        p3 = p4 - 1;
                    }
                    else
                    {
                        p4 = rowOffset; // wrap around to beginning
                        p3 = rowOffset + imageX - 1;
                    }

                    p2 = p4 - width;
                    p1 = p3 - width;

                    color = bitmap.GetPixel(imageX == width ? 0 : imageX, imageY == height ? height - 1 : imageY);

                    x = (color.R - 128) * pixScale;
                    if (mirror)
                    {
                        x = -x;
                    }
                    y = (color.G - 128) * pixScale;
                    z = (color.B - 128) * pixScale;

                    Coord c = new Coord(x, y, z);
                    this.coords.Add(c);
                    if (viewerMode)
                    {
                        this.normals.Add(new Coord());
                        this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY));
                    }

                    if (imageY > 0 && imageX > 0)
                    {
                        Face f1, f2;

                        if (viewerMode)
                        {
                            if (invert)
                            {
                                f1     = new Face(p1, p4, p3, p1, p4, p3);
                                f1.uv1 = p1;
                                f1.uv2 = p4;
                                f1.uv3 = p3;

                                f2     = new Face(p1, p2, p4, p1, p2, p4);
                                f2.uv1 = p1;
                                f2.uv2 = p2;
                                f2.uv3 = p4;
                            }
                            else
                            {
                                f1     = new Face(p1, p3, p4, p1, p3, p4);
                                f1.uv1 = p1;
                                f1.uv2 = p3;
                                f1.uv3 = p4;

                                f2     = new Face(p1, p4, p2, p1, p4, p2);
                                f2.uv1 = p1;
                                f2.uv2 = p4;
                                f2.uv3 = p2;
                            }
                        }
                        else
                        {
                            if (invert)
                            {
                                f1 = new Face(p1, p4, p3);
                                f2 = new Face(p1, p2, p4);
                            }
                            else
                            {
                                f1 = new Face(p1, p3, p4);
                                f2 = new Face(p1, p4, p2);
                            }
                        }

                        this.faces.Add(f1);
                        this.faces.Add(f2);
                    }
                }
            }

            if (scaleSourceImage)
            {
                bitmap.Dispose();
            }

            if (viewerMode)
            {
                calcVertexNormals(sculptType, width, height);
            }
        }
Beispiel #32
0
        private void _SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror,
                                 bool invert)
        {
            coords = new List<Coord>();
            faces = new List<Face>();
            normals = new List<Coord>();
            uvs = new List<UVCoord>();

            sculptType = (SculptType) (((int) sculptType) & 0x07);

            if (mirror)
                invert = !invert;

            viewerFaces = new List<ViewerFace>();

            int width = rows[0].Count;

            int p1, p2, p3, p4;

            int imageX, imageY;

            if (sculptType != SculptType.plane)
            {
                if (rows.Count%2 == 0)
                {
                    foreach (List<Coord> t in rows)
                        t.Add(t[0]);
                }
                else
                {
                    int lastIndex = rows[0].Count - 1;

                    foreach (List<Coord> t in rows)
                        t[0] = t[lastIndex];
                }
            }

            Coord topPole = rows[0][width/2];
            Coord bottomPole = rows[rows.Count - 1][width/2];

            if (sculptType == SculptType.sphere)
            {
                if (rows.Count%2 == 0)
                {
                    int count = rows[0].Count;
                    List<Coord> topPoleRow = new List<Coord>(count);
                    List<Coord> bottomPoleRow = new List<Coord>(count);

                    for (int i = 0; i < count; i++)
                    {
                        topPoleRow.Add(topPole);
                        bottomPoleRow.Add(bottomPole);
                    }
                    rows.Insert(0, topPoleRow);
                    rows.Add(bottomPoleRow);
                }
                else
                {
                    int count = rows[0].Count;

                    List<Coord> topPoleRow = rows[0];
                    List<Coord> bottomPoleRow = rows[rows.Count - 1];

                    for (int i = 0; i < count; i++)
                    {
                        topPoleRow[i] = topPole;
                        bottomPoleRow[i] = bottomPole;
                    }
                }
            }

            if (sculptType == SculptType.torus)
                rows.Add(rows[0]);

            int coordsDown = rows.Count;
            int coordsAcross = rows[0].Count;

            float widthUnit = 1.0f/(coordsAcross - 1);
            float heightUnit = 1.0f/(coordsDown - 1);

            for (imageY = 0; imageY < coordsDown; imageY++)
            {
                int rowOffset = imageY*coordsAcross;

                for (imageX = 0; imageX < coordsAcross; imageX++)
                {
                    /*
                    *   p1-----p2
                    *   | \ f2 |
                    *   |   \  |
                    *   | f1  \|
                    *   p3-----p4
                    */

                    p4 = rowOffset + imageX;
                    p3 = p4 - 1;

                    p2 = p4 - coordsAcross;
                    p1 = p3 - coordsAcross;

                    this.coords.Add(rows[imageY][imageX]);
                    if (viewerMode)
                    {
                        this.normals.Add(new Coord());
                        this.uvs.Add(new UVCoord(widthUnit*imageX, heightUnit*imageY));
                    }

                    if (imageY > 0 && imageX > 0)
                    {
                        Face f1, f2;

                        if (viewerMode)
                        {
                            if (invert)
                            {
                                f1 = new Face(p1, p4, p3, p1, p4, p3) {uv1 = p1, uv2 = p4, uv3 = p3};

                                f2 = new Face(p1, p2, p4, p1, p2, p4) {uv1 = p1, uv2 = p2, uv3 = p4};
                            }
                            else
                            {
                                f1 = new Face(p1, p3, p4, p1, p3, p4) {uv1 = p1, uv2 = p3, uv3 = p4};

                                f2 = new Face(p1, p4, p2, p1, p4, p2) {uv1 = p1, uv2 = p4, uv3 = p2};
                            }
                        }
                        else
                        {
                            if (invert)
                            {
                                f1 = new Face(p1, p4, p3);
                                f2 = new Face(p1, p2, p4);
                            }
                            else
                            {
                                f1 = new Face(p1, p3, p4);
                                f2 = new Face(p1, p4, p2);
                            }
                        }

                        this.faces.Add(f1);
                        this.faces.Add(f2);
                    }
                }
            }

            if (viewerMode)
                calcVertexNormals(sculptType, coordsAcross, coordsDown);
        }
        void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert)
        {
            coords  = new List <Coord>();
            faces   = new List <Face>();
            normals = new List <Coord>();
            uvs     = new List <UVCoord>();

            sculptType = (SculptType)(((int)sculptType) & 0x07);

            if (mirror)
            {
                if (sculptType == SculptType.plane)
                {
                    invert = !invert;
                }
            }

            float sourceScaleFactor = (float)(lod) / (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height);

            int scale = (int)(1.0f / sourceScaleFactor);

            if (scale < 1)
            {
                scale = 1;
            }

            List <List <Coord> > rows = bitmap2Coords(sculptBitmap, scale, mirror);

            viewerFaces = new List <ViewerFace>();

            int width = sculptBitmap.Width / scale;
            // int height = sculptBitmap.Height / scale;

            int p1, p2, p3, p4;

            int imageX, imageY;

            if (sculptType != SculptType.plane)
            {
                for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++)
                {
                    rows[rowNdx].Add(rows[rowNdx][0]);
                }
            }

            Coord topPole    = rows[0][width / 2];
            Coord bottomPole = rows[rows.Count - 1][width / 2];

            if (sculptType == SculptType.sphere)
            {
                int          count         = rows[0].Count;
                List <Coord> topPoleRow    = new List <Coord>(count);
                List <Coord> bottomPoleRow = new List <Coord>(count);

                for (int i = 0; i < count; i++)
                {
                    topPoleRow.Add(topPole);
                    bottomPoleRow.Add(bottomPole);
                }
                rows.Insert(0, topPoleRow);
                rows.Add(bottomPoleRow);
            }
            else if (sculptType == SculptType.torus)
            {
                rows.Add(rows[0]);
            }

            int coordsDown   = rows.Count;
            int coordsAcross = rows[0].Count;

            float widthUnit  = 1.0f / (coordsAcross - 1);
            float heightUnit = 1.0f / (coordsDown - 1);

            for (imageY = 0; imageY < coordsDown; imageY++)
            {
                int rowOffset = imageY * coordsAcross;

                for (imageX = 0; imageX < coordsAcross; imageX++)
                {
                    /*
                     *   p1-----p2
                     *   | \ f2 |
                     *   |   \  |
                     *   | f1  \|
                     *   p3-----p4
                     */

                    p4 = rowOffset + imageX;
                    p3 = p4 - 1;

                    p2 = p4 - coordsAcross;
                    p1 = p3 - coordsAcross;

                    this.coords.Add(rows[imageY][imageX]);
                    if (viewerMode)
                    {
                        this.normals.Add(new Coord());
                        this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY));
                    }

                    if (imageY > 0 && imageX > 0)
                    {
                        Face f1, f2;

                        if (viewerMode)
                        {
                            if (invert)
                            {
                                f1     = new Face(p1, p4, p3, p1, p4, p3);
                                f1.uv1 = p1;
                                f1.uv2 = p4;
                                f1.uv3 = p3;

                                f2     = new Face(p1, p2, p4, p1, p2, p4);
                                f2.uv1 = p1;
                                f2.uv2 = p2;
                                f2.uv3 = p4;
                            }
                            else
                            {
                                f1     = new Face(p1, p3, p4, p1, p3, p4);
                                f1.uv1 = p1;
                                f1.uv2 = p3;
                                f1.uv3 = p4;

                                f2     = new Face(p1, p4, p2, p1, p4, p2);
                                f2.uv1 = p1;
                                f2.uv2 = p4;
                                f2.uv3 = p2;
                            }
                        }
                        else
                        {
                            if (invert)
                            {
                                f1 = new Face(p1, p4, p3);
                                f2 = new Face(p1, p2, p4);
                            }
                            else
                            {
                                f1 = new Face(p1, p3, p4);
                                f2 = new Face(p1, p4, p2);
                            }
                        }

                        this.faces.Add(f1);
                        this.faces.Add(f2);
                    }
                }
            }

            if (viewerMode)
            {
                calcVertexNormals(sculptType, coordsAcross, coordsDown);
            }
        }
Beispiel #34
0
        void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert)
        {
            coords = new List<Coord>();
            faces = new List<Face>();
            normals = new List<Coord>();
            uvs = new List<UVCoord>();

            sculptType = (SculptType)(((int)sculptType) & 0x07);

            if (mirror)
                if (sculptType == SculptType.plane)
                    invert = !invert;

            float sourceScaleFactor = (float)(lod) / (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height);

            int scale = (int)(1.0f / sourceScaleFactor);
            if (scale < 1) scale = 1;

            _SculptMesh(bitmap2Coords(sculptBitmap, scale, mirror), sculptType, viewerMode, mirror, invert);
        }
Beispiel #35
0
        private void calcVertexNormals(SculptType sculptType, int xSize, int ySize)
        {
            normals.Clear();
            for (int i = 0; i < coords.Count(); i++)
            {
                normals[i] = new Vector3();
            }

            int numFaces = faces.Count();

            for (int i = 0; i < numFaces; i++)
            {
                Face    face          = faces[i];
                Vector3 surfaceNormal = face.SurfaceNormal(coords);
                normals[face.v1] += surfaceNormal;
                normals[face.v2] += surfaceNormal;
                normals[face.v3] += surfaceNormal;
            }

            if (sculptType == SculptType.sphere)
            {
                Vector3 avg = new Vector3(0, 0, 0);
                for (int i = 0; i < xSize; i++)
                {
                    avg += normals[i];
                }
                for (int i = 0; i < xSize; i++)
                {
                    normals[i] = avg;
                }
                avg.X = 0;
                avg.Y = 0;
                avg.Z = 0;
                int lastrow = xSize * (ySize - 1);
                for (int i = lastrow; i < lastrow + xSize; i++)
                {
                    avg += normals[i];
                }
                for (int i = lastrow; i < lastrow + xSize; i++)
                {
                    normals[i] = avg;
                }
            }

            if (sculptType == SculptType.sphere || sculptType == SculptType.cylinder || sculptType == SculptType.torus)
            { // blend the vertex normals at the cylinder seam
                int xminusOne = xSize - 1;
                for (int y = 0; y < ySize; y++)
                {
                    int rowOffset = y * xSize;
                    normals[rowOffset] = normals[rowOffset + xminusOne] = (normals[rowOffset] + normals[rowOffset + xminusOne]);
                }
            }

            if (sculptType == SculptType.torus)
            {
                int lastrow = xSize * (ySize - 1);
                for (int x = 0; x < xSize; x++)
                {
                    normals[x] = normals[lastrow + x] = (normals[x] + normals[lastrow + x]);
                }
            }

            int numNormals = normals.Count();

            for (int i = 0; i < numNormals; i++)
            {
                normals[i] = Vector3.Normalize(normals[i]);
            }
        }