Esempio n. 1
0
    override public Mesh GenerateSingleMesh(CSBlockType type)
    {
        Mesh mesh = GetMesh();

        Mesh singleMesh = new Mesh();

        singleMesh.name = "CubeMesh";

        List <Vector2> uv = new List <Vector2>();

        TexCoords  texCoords = ChunkMeshGenerator.type2texcoords[(byte)type];
        Vector2Int texPos    = texCoords.front;

        texPos.y = (atlas_row - 1) - texPos.y;

        foreach (Vector2 singleUV in mesh.uv)
        {
            uv.Add(new Vector2((texPos.x + singleUV.x) / atlas_column, (texPos.y + singleUV.y) / atlas_row));
        }

        singleMesh.SetVertices(mesh.vertices);
        singleMesh.SetUVs(0, uv);
        singleMesh.SetTriangles(mesh.triangles, 0);
        singleMesh.SetNormals(mesh.normals);

        return(singleMesh);
    }
Esempio n. 2
0
        private void _setTexCoords()
        {
            if (World.texcoords_cache.ContainsKey(ID))
            {
                TexCoords = World.texcoords_cache[ID];
                return;
            }

            int   tilepos = (ID - TileSet.FirstGID) + 1;
            float x, y, width, height;
            int   step = (tilepos - 1) % TileSet.TilesPerRow, row = 0;

            for (int i = 0; i != ID; i++)
            {
                if (i % TileSet.TilesPerRow == 0 && i != 0)
                {
                    row++;
                }
            }

            x      = TileSet.TileWidth * step;
            y      = TileSet.TileHeight * row;
            y      = TileSet.TileTexture.TextureHeight + y;
            width  = x + TileSet.TileWidth;
            height = y + TileSet.TileHeight;

            TexCoords = new TexCoords(x, y, width, height, TileSet.TileTexture);

            World.texcoords_cache.Add(ID, TexCoords);

            IsStatic = true;
        }
    override public void GenerateMeshInChunk(CSBlockType type, Vector3Int pos, Vector3Int globalPos, List <Vector3> vertices, List <Vector2> uv, List <int> triangles)
    {
        TexCoords texCoords = ChunkMeshGenerator.type2texcoords[(byte)type];

        AddDiagonalFace(vertices, uv, triangles, pos, texCoords.front);
        AddAntiDiagonalFace(vertices, uv, triangles, pos, texCoords.front);
    }
Esempio n. 4
0
 public void AddVertex(Vector3 pos, Vector3 normal, Vector2 texCoord)
 {
     Vertices.Add(pos);
     Normals.Add(normal);
     TexCoords.Add(texCoord);
     Indices.Add(Indices.Count);
 }
Esempio n. 5
0
    override public Mesh GenerateSingleMesh(CSBlockType type)
    {
        Mesh stairMesh = LoadMesh("stair_+y-z");

        Mesh mesh = new Mesh();

        mesh.name = "CubeMesh";

        List <Vector2> uv = new List <Vector2>();

        TexCoords  texCoords = ChunkMeshGenerator.type2texcoords[(byte)type];
        Vector2Int texPos    = texCoords.front;

        texPos.y = (atlas_row - 1) - texPos.y;

        foreach (Vector2 singleUV in stairMesh.uv)
        {
            uv.Add(new Vector2((texPos.x + singleUV.x) / atlas_column, (texPos.y + singleUV.y) / atlas_row));
        }

        mesh.vertices  = stairMesh.vertices;
        mesh.uv        = uv.ToArray();
        mesh.triangles = stairMesh.triangles;
        mesh.normals   = stairMesh.normals;

        return(mesh);
    }
Esempio n. 6
0
 static void AddFacesCullInvisible(TexCoords texCoords, Vector3Int pos, Vector3Int globalPos, List <Vector3> vertices, List <Vector2> uv, List <int> triangles)
 {
     if (texCoords.isTransparent || !ChunkManager.HasOpaqueBlock(globalPos.x, globalPos.y, globalPos.z - 1))
     {
         AddFrontFace(Matrix4x4.identity, vertices, uv, triangles, pos, texCoords.front);
     }
     if (texCoords.isTransparent || !ChunkManager.HasOpaqueBlock(globalPos.x + 1, globalPos.y, globalPos.z))
     {
         AddRightFace(Matrix4x4.identity, vertices, uv, triangles, pos, texCoords.right);
     }
     if (texCoords.isTransparent || !ChunkManager.HasOpaqueBlock(globalPos.x - 1, globalPos.y, globalPos.z))
     {
         AddLeftFace(Matrix4x4.identity, vertices, uv, triangles, pos, texCoords.left);
     }
     if (texCoords.isTransparent || !ChunkManager.HasOpaqueBlock(globalPos.x, globalPos.y, globalPos.z + 1))
     {
         AddBackFace(Matrix4x4.identity, vertices, uv, triangles, pos, texCoords.back);
     }
     if (texCoords.isTransparent || !ChunkManager.HasOpaqueBlock(globalPos.x, globalPos.y + 1, globalPos.z))
     {
         AddTopFace(Matrix4x4.identity, vertices, uv, triangles, pos, texCoords.top);
     }
     if (texCoords.isTransparent || !ChunkManager.HasOpaqueBlock(globalPos.x, globalPos.y - 1, globalPos.z))
     {
         AddBottomFace(Matrix4x4.identity, vertices, uv, triangles, pos, texCoords.bottom);
     }
 }
Esempio n. 7
0
    override public Mesh GenerateSingleMesh(CSBlockType type)
    {
        Mesh torchMesh = Resources.Load <Mesh>("Meshes/blocks/torch/torch");

        Mesh mesh = new Mesh();

        mesh.name = "CubeMesh";

        List <Vector2> uv = new List <Vector2>();

        TexCoords  texCoords = ChunkMeshGenerator.type2texcoords[(byte)CSBlockType.Torch];
        Vector2Int texPos    = texCoords.front;

        texPos.y = (atlas_row - 1) - texPos.y;

        foreach (Vector2 singleUV in torchMesh.uv)
        {
            uv.Add(new Vector2((texPos.x + singleUV.x) / atlas_column, (texPos.y + singleUV.y) / atlas_row));
        }

        Matrix4x4      matrix   = Matrix4x4.TRS(Vector3.up / 2, Quaternion.Euler(-12, 28, 24), Vector3.one * 2);
        List <Vector3> vertices = new List <Vector3>();

        for (int i = 0; i < torchMesh.vertices.Length; i++)
        {
            vertices.Add(matrix.MultiplyPoint(torchMesh.vertices[i]));
        }

        mesh.vertices  = vertices.ToArray();
        mesh.uv        = uv.ToArray();
        mesh.triangles = torchMesh.triangles;

        return(mesh);
    }
Esempio n. 8
0
    override public void GenerateMeshInChunk(CSBlockType type, Vector3Int posInChunk, Vector3Int globalPos, List <Vector3> vertices, List <Vector2> uv, List <int> triangles)
    {
        TexCoords  texCoords = ChunkMeshGenerator.type2texcoords[(byte)type];
        Vector2Int texPos    = texCoords.front;

        texPos.y = (atlas_row - 1) - texPos.y;

        CSBlockOrientation orient = ChunkManager.GetBlockOrientation(globalPos);

        Mesh stairMesh = GetStairMesh(orient, globalPos);
        int  length    = vertices.Count;

        foreach (Vector3 singleVertex in stairMesh.vertices)
        {
            Vector3 pos = singleVertex + posInChunk;
            vertices.Add(pos);
        }

        foreach (Vector2 singleUV in stairMesh.uv)
        {
            uv.Add(new Vector2((texPos.x + singleUV.x) / atlas_column, (texPos.y + singleUV.y) / atlas_row));
        }

        foreach (int index in stairMesh.triangles)
        {
            triangles.Add(index + length);
        }
    }
Esempio n. 9
0
    override public void GenerateMeshInChunk(CSBlockType type, Vector3Int pos, Vector3Int globalPos, List <Vector3> vertices, List <Vector2> uv, List <int> triangles)
    {
        TexCoords texCoords = ChunkMeshGenerator.type2texcoords[(byte)type];

        if (texCoords.isRotatable)
        {
            Matrix4x4          rotationMatrix = Matrix4x4.identity;
            CSBlockOrientation orient         = ChunkManager.GetBlockOrientation(globalPos);
            if (orient != CSBlockOrientation.Default)
            {
                if (orient == CSBlockOrientation.PositiveY_NegativeZ)
                {
                    rotationMatrix = Matrix4x4.identity;
                }
                else if (orient == CSBlockOrientation.PositiveY_NegativeX)
                {
                    rotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(0, 90, 0));
                }
                else if (orient == CSBlockOrientation.PositiveY_PositiveZ)
                {
                    rotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(0, 180, 0));
                }
                else if (orient == CSBlockOrientation.PositiveY_PositiveX)
                {
                    rotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(0, 270, 0));
                }
            }
            AddFacesNoCull(rotationMatrix, texCoords, pos, vertices, uv, triangles);
        }
        else
        {
            AddFacesCullInvisible(texCoords, pos, globalPos, vertices, uv, triangles);
        }
    }
Esempio n. 10
0
    public void GenerateMeshInChunk(CSBlockType type, Vector3Int posInChunk, Vector3Int globalPos, List <Vector3> vertices, List <Vector2> uv, List <Vector3> normals, List <int> triangles)
    {
        TexCoords  texCoords = ChunkMeshGenerator.type2texcoords[(byte)type];
        Vector2Int texPos    = texCoords.front;

        texPos.y = (atlas_row - 1) - texPos.y;

        Mesh mesh   = GetWallMesh(globalPos);
        int  length = vertices.Count;

        foreach (Vector3 singleVertex in mesh.vertices)
        {
            Vector3 pos = singleVertex + posInChunk;
            vertices.Add(pos);
        }

        foreach (Vector2 singleUV in mesh.uv)
        {
            uv.Add(new Vector2((texPos.x + singleUV.x) / atlas_column, (texPos.y + singleUV.y) / atlas_row));
        }

        foreach (Vector3 normal in mesh.normals)
        {
            normals.Add(normal);
        }

        foreach (int index in mesh.triangles)
        {
            triangles.Add(index + length);
        }
    }
Esempio n. 11
0
 public void AddVtx(Primitive src, int vtxIdx)
 {
     VertexCount++;
     Matrices.Add(src.Matrices[vtxIdx]);
     Positions.Add(src.Positions[vtxIdx]);
     Normals.Add(src.Normals[vtxIdx]);
     Colors.Add(src.Colors[vtxIdx]);
     TexCoords.Add(src.TexCoords[vtxIdx]);
 }
Esempio n. 12
0
 static void AddFacesNoCull(Matrix4x4 orientation, TexCoords texCoords, Vector3Int pos, List <Vector3> vertices, List <Vector2> uv, List <int> triangles)
 {
     AddFrontFace(orientation, vertices, uv, triangles, pos, texCoords.front);
     AddRightFace(orientation, vertices, uv, triangles, pos, texCoords.right);
     AddLeftFace(orientation, vertices, uv, triangles, pos, texCoords.left);
     AddBackFace(orientation, vertices, uv, triangles, pos, texCoords.back);
     AddTopFace(orientation, vertices, uv, triangles, pos, texCoords.top);
     AddBottomFace(orientation, vertices, uv, triangles, pos, texCoords.bottom);
 }
Esempio n. 13
0
 public Primitive(int vtxCount)
 {
     VertexCount = vtxCount;
     Matrices.AddRange(new int[vtxCount]);
     Positions.AddRange(new int[vtxCount]);
     Normals.AddRange(new int[vtxCount]);
     Colors.AddRange(new int[vtxCount]);
     TexCoords.AddRange(new int[vtxCount]);
 }
Esempio n. 14
0
File: Mesh.cs Progetto: xorza/NetGL
        public void ToStream(BinaryWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }

            writer.Write(Vertices != null);
            if (Vertices != null)
            {
                Vertices.ToStream(writer.BaseStream);
            }

            writer.Write(Tangents != null);
            if (Tangents != null)
            {
                Tangents.ToStream(writer.BaseStream);
            }

            writer.Write(Colors != null);
            if (Colors != null)
            {
                Colors.ToStream(writer.BaseStream);
            }

            writer.Write(Normals != null);
            if (Normals != null)
            {
                Normals.ToStream(writer.BaseStream);
            }

            writer.Write(TexCoords != null);
            if (TexCoords != null)
            {
                TexCoords.ToStream(writer.BaseStream);
            }

            writer.Write(Indices != null);
            if (Indices != null)
            {
                Indices.ToStream(writer.BaseStream);
            }

            writer.Write((uint)Type);
            writer.Write((uint)DrawStyle);
            writer.Write((uint)FrontFace);
            writer.WriteNullableString(Name);

            var bounds = Bounds;

            writer.Write(bounds.Center);
            writer.Write(bounds.Size);
            writer.Write(bounds.Radius);
        }
        public override string GetStepParameters()
        {
            var parameters = new List <string>();

            parameters.Add(Maps != null ? Maps.ToStepValue() : "$");
            parameters.Add(MappedTo != null ? MappedTo.ToStepValue() : "$");
            parameters.Add(TexCoords != null ? TexCoords.ToStepValue() : "$");
            parameters.Add(TexCoordIndex != null ? TexCoordIndex.ToStepValue() : "$");

            return(string.Join(", ", parameters.ToArray()));
        }
Esempio n. 16
0
    override public Mesh GenerateSingleMesh(CSBlockType type)
    {
        Mesh mesh = new Mesh();

        mesh.name = "CubeMesh";

        List <Vector3> vertices  = new List <Vector3>();
        List <Vector2> uv        = new List <Vector2>();
        List <int>     triangles = new List <int>();
        List <Vector3> normals   = new List <Vector3>();

        TexCoords texCoords = ChunkMeshGenerator.type2texcoords[(byte)type];

        AddFrontFace(Matrix4x4.identity, vertices, uv, triangles, Vector3Int.zero, texCoords.front);
        for (int i = 0; i < 4; i++)
        {
            normals.Add(Vector3.back);
        }
        AddRightFace(Matrix4x4.identity, vertices, uv, triangles, Vector3Int.zero, texCoords.right);
        for (int i = 0; i < 4; i++)
        {
            normals.Add(Vector3.right);
        }
        AddLeftFace(Matrix4x4.identity, vertices, uv, triangles, Vector3Int.zero, texCoords.left);
        for (int i = 0; i < 4; i++)
        {
            normals.Add(Vector3.left);
        }
        AddBackFace(Matrix4x4.identity, vertices, uv, triangles, Vector3Int.zero, texCoords.back);
        for (int i = 0; i < 4; i++)
        {
            normals.Add(Vector3.forward);
        }
        AddTopFace(Matrix4x4.identity, vertices, uv, triangles, Vector3Int.zero, texCoords.top);
        for (int i = 0; i < 4; i++)
        {
            normals.Add(Vector3.up);
        }
        AddBottomFace(Matrix4x4.identity, vertices, uv, triangles, Vector3Int.zero, texCoords.bottom);
        for (int i = 0; i < 4; i++)
        {
            normals.Add(Vector3.down);
        }

        mesh.SetVertices(vertices);
        mesh.SetUVs(0, uv);
        mesh.SetTriangles(triangles, 0);
        mesh.SetNormals(normals);

        return(mesh);
    }
Esempio n. 17
0
    public void GenerateMeshInChunk(CSBlockType type, Vector3Int _pos, Vector3Int _globalPos, List <Vector3> _vertices, List <Color> _colors, List <Vector2> _uv, List <int> _triangles)
    {
        texCoords      = ChunkMeshGenerator.type2texcoords[(byte)type];
        pos            = _pos;
        globalPos      = _globalPos;
        vertices       = _vertices;
        uv             = _uv;
        triangles      = _triangles;
        colors         = _colors;
        rotationMatrix = Matrix4x4.identity;

        if (texCoords.isRotatable)
        {
            CSBlockOrientation orient = ChunkManager.GetBlockOrientation(globalPos);
            if (orient != CSBlockOrientation.Default)
            {
                if (orient == CSBlockOrientation.PositiveY_NegativeZ)
                {
                    rotationMatrix = Matrix4x4.identity;
                }
                else if (orient == CSBlockOrientation.PositiveY_NegativeX)
                {
                    rotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(0, 90, 0));
                }
                else if (orient == CSBlockOrientation.PositiveY_PositiveZ)
                {
                    rotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(0, 180, 0));
                }
                else if (orient == CSBlockOrientation.PositiveY_PositiveX)
                {
                    rotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(0, 270, 0));
                }
                else if (orient == CSBlockOrientation.X)
                {
                    rotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(-90, 0, 0));
                }
                else if (orient == CSBlockOrientation.Z)
                {
                    rotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(0, 0, 90));
                }
            }
            AddFacesNoCull();
        }
        else
        {
            AddFacesCullInvisible();
        }
    }
Esempio n. 18
0
        public Primitive(Primitive original)
        {
            Type        = original.Type;
            VertexCount = original.VertexCount;
            Matrices.AddRange(original.Matrices);
            Positions.AddRange(original.Positions);
            Normals.AddRange(original.Normals);
            Colors.AddRange(original.Colors);
            TexCoords.AddRange(original.TexCoords);

            Processed          = original.Processed;
            NextCandidateCount = original.NextCandidateCount;
            NextCandidates[0]  = original.NextCandidates[0];
            NextCandidates[1]  = original.NextCandidates[1];
            NextCandidates[2]  = original.NextCandidates[2];
            NextCandidates[3]  = original.NextCandidates[3];
        }
Esempio n. 19
0
        /// <summary>
        /// Load the Sprite
        /// </summary>
        public void Load()
        {
            IsVisible = true;

            OnLoad();
            if (TexCoords == null && Texture != null)
            {
                TexCoords = new TexCoords(Width, Height, Texture);
            }
            else if (Texture == null)
            {
                throw new InvalidOperationException("This sprite has no texture! A sprite MUST have a texture!");
            }
            IsLoaded = true;

            if (Loaded != null)
            {
                Loaded(this, new SpriteEvent(this));
            }
        }
Esempio n. 20
0
    override public Mesh GenerateSingleMesh(CSBlockType type)
    {
        Mesh mesh = new Mesh();

        mesh.name = "CubeMesh";

        List <Vector3> vertices  = new List <Vector3>();
        List <Vector2> uv        = new List <Vector2>();
        List <int>     triangles = new List <int>();

        TexCoords texCoords = ChunkMeshGenerator.type2texcoords[(byte)type];

        AddDiagonalFace(vertices, uv, triangles, Vector3.zero, texCoords.front);
        AddAntiDiagonalFace(vertices, uv, triangles, Vector3.zero, texCoords.front);

        mesh.vertices  = vertices.ToArray();
        mesh.uv        = uv.ToArray();
        mesh.triangles = triangles.ToArray();

        return(mesh);
    }
Esempio n. 21
0
        public void Append(Model m, Vector3 pivot)
        {
            if (m.Vertices.Count < 3)
            {
                return;
            }

            int oldFacesPos = Faces.Count;

            Faces.AddRange(m.Faces);

            for (int i = oldFacesPos; i < Faces.Count; ++i)
            {
                for (int j = 0; j < Faces[i].VertexIndices.Length; ++j)
                {
                    Faces[i].VertexIndices[j] += Vertices.Count;
                }

                for (int j = 0; j < Faces[i].NormalIndices.Length; ++j)
                {
                    Faces[i].NormalIndices[j] += Normals.Count;
                }

                for (int j = 0; j < Faces[i].TextureIndices.Length; ++j)
                {
                    Faces[i].TextureIndices[j] += TexCoords.Count;
                }
            }

            Vertices.AddRange(m.Vertices);
            Normals.AddRange(m.Normals);
            TexCoords.AddRange(m.TexCoords);

            for (int i = 0; i < Vertices.Count; ++i)
            {
                Vertices[i] += pivot;
            }
        }
Esempio n. 22
0
        public bool TryMerge(SubMesh other)
        {
            //  return false;

            if (MaterialID != other.MaterialID)
            {
                return(false);
            }

            int offset = Positions.Count;

            Positions.AddRange(other.Positions);
            Normals.AddRange(other.Normals);
            Tangents.AddRange(other.Tangents);
            TexCoords.AddRange(other.TexCoords);
            VertexColors.AddRange(other.VertexColors);

            foreach (int index in other.Indices)
            {
                Indices.Add(index + offset);
            }

            return(true);
        }
        public override void Upload()
        {
            if (_faceInfos == null || _faceInfos.Count <= 0)
            {
                UploadedCount = 0;
                return;
            }

            GL.BindVertexArray(VaoId);

            if (UploadedCount == 0)
            {
                //0 positions
                GL.BindBuffer(BufferTarget.ArrayBuffer, BufferIds[0]);
                GL.BufferData(BufferTarget.ArrayBuffer, Positions.Count * Vector3.SizeInBytes, Positions.ToArray(),
                              BufferUsageHint.StaticDraw);
                GL.EnableVertexAttribArray(0);
                GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0);
                //1 texCoords
                GL.BindBuffer(BufferTarget.ArrayBuffer, BufferIds[1]);
                GL.BufferData(BufferTarget.ArrayBuffer, TexCoords.Count * Vector4.SizeInBytes, TexCoords.ToArray(),
                              BufferUsageHint.StaticDraw);
                GL.EnableVertexAttribArray(1);
                GL.VertexAttribPointer(1, 4, VertexAttribPointerType.Float, false, 0, 0);
                //2 normals
                GL.BindBuffer(BufferTarget.ArrayBuffer, BufferIds[2]);
                GL.BufferData(BufferTarget.ArrayBuffer, Normals.Count * Vector4.SizeInBytes, Normals.ToArray(),
                              BufferUsageHint.StaticDraw);
                GL.EnableVertexAttribArray(2);
                GL.VertexAttribPointer(2, 4, VertexAttribPointerType.Float, false, 0, 0);
                //3 color
                GL.BindBuffer(BufferTarget.ArrayBuffer, BufferIds[3]);
                GL.BufferData(BufferTarget.ArrayBuffer, Colors.Count * Vector3.SizeInBytes, Colors.ToArray(),
                              BufferUsageHint.StaticDraw);
                GL.EnableVertexAttribArray(3);
                GL.VertexAttribPointer(3, 3, VertexAttribPointerType.Float, false, 0, 0);
                //4 light
                GL.BindBuffer(BufferTarget.ArrayBuffer, BufferIds[4]);
                GL.BufferData(BufferTarget.ArrayBuffer, Lights.Count * Vector3.SizeInBytes, Lights.ToArray(),
                              BufferUsageHint.StaticDraw);
                GL.EnableVertexAttribArray(4);
                GL.VertexAttribPointer(4, 3, VertexAttribPointerType.Float, false, 0, 0);
            }
            else
            {
                //0 positions
                GL.BindBuffer(BufferTarget.ArrayBuffer, BufferIds[0]);
                GL.BufferData(BufferTarget.ArrayBuffer, Positions.Count * Vector3.SizeInBytes, Positions.ToArray(),
                              BufferUsageHint.StaticDraw);
                //1 texCoords
                GL.BindBuffer(BufferTarget.ArrayBuffer, BufferIds[1]);
                GL.BufferData(BufferTarget.ArrayBuffer, TexCoords.Count * Vector4.SizeInBytes, TexCoords.ToArray(),
                              BufferUsageHint.StaticDraw);
                //2 normals
                GL.BindBuffer(BufferTarget.ArrayBuffer, BufferIds[2]);
                GL.BufferData(BufferTarget.ArrayBuffer, Normals.Count * Vector4.SizeInBytes, Normals.ToArray(),
                              BufferUsageHint.StaticDraw);
                //3 color
                GL.BindBuffer(BufferTarget.ArrayBuffer, BufferIds[3]);
                GL.BufferData(BufferTarget.ArrayBuffer, Colors.Count * Vector3.SizeInBytes, Colors.ToArray(),
                              BufferUsageHint.StaticDraw);
                //4 light
                GL.BindBuffer(BufferTarget.ArrayBuffer, BufferIds[4]);
                GL.BufferData(BufferTarget.ArrayBuffer, Lights.Count * Vector3.SizeInBytes, Lights.ToArray(),
                              BufferUsageHint.StaticDraw);
            }

            UploadedCount  = _faceInfos.Count * 6;
            _uploadedFaces = _faceInfos.ToArray();

            var indices = new List <uint>();

            foreach (var face in _uploadedFaces)
            {
                indices.AddRange(face.Indices);
            }

            GL.BindBuffer(BufferTarget.ElementArrayBuffer, IndicesId);
            GL.BufferData(BufferTarget.ElementArrayBuffer, UploadedCount * sizeof(uint), indices.ToArray(), BufferUsageHint.DynamicDraw);
        }
Esempio n. 24
0
        public Geoset1300(BinaryReader br)
        {
            TotalSize = br.ReadUInt32();
            long end = TotalSize + br.BaseStream.Position;

            //Vertices
            if (br.HasTag("VRTX"))
            {
                NrOfVertices = br.ReadUInt32();
                for (int i = 0; i < NrOfVertices; i++)
                {
                    Vertices.Add(new CVector3(br));
                }
            }

            //Normals
            if (br.HasTag("NRMS"))
            {
                NrOfNormals = br.ReadUInt32();
                for (int i = 0; i < NrOfNormals; i++)
                {
                    Normals.Add(new CVector3(br));
                }
            }

            //TexCoords
            if (br.HasTag("UVAS"))
            {
                NrOfTexCoords = br.ReadUInt32();                 //Amount of groups
                for (int i = 0; i < NrOfNormals * NrOfTexCoords; i++)
                {
                    TexCoords.Add(new CVector2(br));
                }
            }

            //Face Group Type
            if (br.HasTag("PTYP"))
            {
                NrOfFaceTypeGroups = br.ReadUInt32();
                FaceTypes.AddRange(br.ReadBytes((int)NrOfFaceTypeGroups));
            }

            //Face Groups
            if (br.HasTag("PCNT"))
            {
                NrOfFaceGroups = br.ReadUInt32();
                for (int i = 0; i < NrOfFaceGroups; i++)
                {
                    FaceGroups.Add(br.ReadUInt32());
                }
            }

            //Indexes
            if (br.HasTag("PVTX"))
            {
                NrOfFaceVertices = br.ReadUInt32();
                for (int i = 0; i < NrOfFaceVertices / 3; i++)
                {
                    FaceVertices.Add(new CVertex(br));
                }
            }

            //Vertex Groups
            if (br.HasTag("GNDX"))
            {
                NrOfVertexGroupIndices = br.ReadUInt32();
                VertexGroupIndices.AddRange(br.ReadBytes((int)NrOfVertexGroupIndices));
            }

            //Matrix Groups
            if (br.HasTag("MTGC"))
            {
                NrOfMatrixGroups = br.ReadUInt32();
                for (int i = 0; i < NrOfMatrixGroups; i++)
                {
                    MatrixGroups.Add(br.ReadUInt32());
                }
            }

            //Matrix Indexes
            if (br.HasTag("MATS"))
            {
                NrOfMatrixIndexes = br.ReadUInt32();
                for (int i = 0; i < NrOfMatrixIndexes; i++)
                {
                    MatrixIndexes.Add(br.ReadUInt32());
                }
            }

            //Bone Indexes
            if (br.HasTag("BIDX"))
            {
                NrOfBoneIndexes = br.ReadUInt32();
                for (int i = 0; i < NrOfBoneIndexes; i++)
                {
                    BoneIndexes.Add(br.ReadUInt32());
                }
            }

            //Bone Weights
            if (br.HasTag("BWGT"))
            {
                NrOfBoneWeights = br.ReadUInt32();
                for (int i = 0; i < NrOfBoneWeights; i++)
                {
                    BoneWeights.Add(br.ReadUInt32());
                }
            }

            MaterialId     = br.ReadUInt32();
            SelectionGroup = br.ReadUInt32();
            Unselectable   = br.ReadUInt32() == 1;
            Bounds         = new CExtent(br);

            //Extents
            NrOfExtents = br.ReadUInt32();
            for (int i = 0; i < NrOfExtents; i++)
            {
                Extents.Add(new CExtent(br));
            }

            //Grouped Vertices
            for (int i = 0; i < NrOfVertices; i++)
            {
                if (!GroupedVertices.ContainsKey(VertexGroupIndices[i]))
                {
                    GroupedVertices.Add(VertexGroupIndices[i], new List <CVector3>());
                }

                GroupedVertices[VertexGroupIndices[i]].Add(Vertices[i]);
            }
        }
Esempio n. 25
0
        public void Create(string filename)
        {
            if (!File.Exists(filename))
            {
                Console.WriteLine("[E] Could not find: {0}", filename);
                return;
            }

            var vertices       = new List <Vector3>();
            var verticeIndice  = new List <int>();
            var texCoords      = new List <Vector2>();
            var texCoordIndice = new List <int>();
            var normals        = new List <Vector3>();
            var normalIndice   = new List <int>();

            using (var objStream = new StreamReader(filename))
            {
                while (!objStream.EndOfStream)
                {
                    var line = objStream.ReadLine().Trim();

                    #region "Sort out Vertices"
                    if (line.StartsWith("v "))
                    {
                        var vertexParts = Functions.SplitString(line.Replace("  ", " "), " ");

                        var vertice = new Vector3(
                            float.Parse(vertexParts[1], CultureInfo.InvariantCulture.NumberFormat),
                            float.Parse(vertexParts[2], CultureInfo.InvariantCulture.NumberFormat),
                            float.Parse(vertexParts[3], CultureInfo.InvariantCulture.NumberFormat)
                            );

                        vertices.Add(vertice);
                        continue;
                    }

                    if (line.StartsWith("vt "))
                    {
                        var vertexTexCoord = Functions.SplitString(line, " ");
                        var texCoord       = new Vector2(
                            float.Parse(vertexTexCoord[1], CultureInfo.InvariantCulture.NumberFormat),
                            float.Parse(vertexTexCoord[2], CultureInfo.InvariantCulture.NumberFormat)
                            );

                        texCoords.Add(texCoord);
                        continue;
                    }

                    if (line.StartsWith("vn "))
                    {
                        var vertexNormal = Functions.SplitString(line, " ");
                        var normal       = new Vector3(
                            float.Parse(vertexNormal[1], CultureInfo.InvariantCulture.NumberFormat),
                            float.Parse(vertexNormal[2], CultureInfo.InvariantCulture.NumberFormat),
                            float.Parse(vertexNormal[3], CultureInfo.InvariantCulture.NumberFormat)
                            );

                        normals.Add(normal);
                        continue;
                    }
                    #endregion

                    #region "Faces"
                    if (line.StartsWith("f "))
                    {
                        var faceParts = Functions.SplitString(line, " ").ToList();
                        for (var f = 0; f < faceParts.Count; f++)
                        {
                            var face = Functions.SplitString(faceParts[f], "/");
                            if (face.Length < 2)
                            {
                                continue;
                            }

                            verticeIndice.Add(int.Parse(face[0]) - 1);
                            texCoordIndice.Add(int.Parse(face[1]) - 1);
                            normalIndice.Add(int.Parse(face[2]) - 1);
                        }
                    }
                    #endregion
                }

                objStream.Close();
            }

            int indice = 0;

            foreach (var item in verticeIndice)
            {
                Vertices.Add(vertices[item]);
                Indices.Add(indice++);
            }

            foreach (var item in texCoordIndice)
            {
                TexCoords.Add(texCoords[item]);
            }

            foreach (var item in normalIndice)
            {
                Normals.Add(normals[item]);
            }

            VertexArray.Upload(Vertices, Indices);
            VertexArray.Upload(TexCoords);
            VertexArray.Upload(Normals, new List <int>());
        }
Esempio n. 26
0
    public static void RefreshMeshData(this Chunk chunk)
    {
        //Debug.Log("RefreshMeshData,chunk=" + chunk.pos);
        chunk.vertices1.Clear();
        chunk.colors1.Clear();
        chunk.uv1.Clear();
        chunk.triangles1.Clear();

        chunk.vertices2.Clear();
        chunk.uv2.Clear();
        chunk.triangles2.Clear();

        List <Color> colors = new List <Color>();

        Vector3Int pos       = new Vector3Int();
        Vector3Int globalPos = new Vector3Int();

        //压缩后的数据结构
        for (int k = 0; k < 256; k++)
        {
            for (int i = 0; i < 16; i++)
            {
                for (int j = 0; j < 16; j++)
                {
                    byte        b    = chunk.blocksInByte[256 * k + 16 * i + j];
                    CSBlockType type = (CSBlockType)b;
                    if (type != CSBlockType.None)
                    {
                        TexCoords texCoords = type2texcoords[(byte)type];

                        pos.Set(i, k, j);
                        globalPos.Set(chunk.globalX + i, k, chunk.globalZ + j);

                        if (texCoords.isPlant)
                        {
                            PlantMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices2, chunk.uv2, chunk.triangles2);
                        }
                        else
                        {
                            if (IsStair(type))
                            {
                                StairMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices1, chunk.uv1, chunk.triangles1);
                            }
                            else if (IsWall(type))
                            {
                                WallMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices1, chunk.uv1, chunk.triangles1);
                            }
                            else if (IsSlab(type))
                            {
                                SlabMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices1, chunk.uv1, chunk.triangles1);
                            }
                            else if (type == CSBlockType.Torch)
                            {
                                if (!chunk.hasBuiltMesh)
                                {
                                    //加载完第一次build
                                    chunk.AddTorch(globalPos);
                                }
                            }
                            else if (type == CSBlockType.VerticalBrickSlab)
                            {
                                VerticalSlabMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices1, chunk.colors1, chunk.uv1, chunk.triangles1);
                            }
                            else
                            {
                                //BlockMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices1, chunk.uv1, chunk.triangles1);
                                BlockMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices1, chunk.colors1, chunk.uv1, chunk.triangles1);
                            }
                        }
                    }
                }
            }
        }
        chunk.hasBuiltMesh = true;
        chunk.isDirty      = false;
    }
Esempio n. 27
0
    public static void RefreshMeshData(this Chunk chunk)
    {
        chunk.vertices1.Clear();
        chunk.uv1.Clear();
        chunk.triangles1.Clear();

        chunk.vertices2.Clear();
        chunk.uv2.Clear();
        chunk.triangles2.Clear();

        Vector3Int pos       = new Vector3Int();
        Vector3Int globalPos = new Vector3Int();

        //压缩后的数据结构
        for (int k = 0; k < 256; k++)
        {
            for (int i = 0; i < 16; i++)
            {
                for (int j = 0; j < 16; j++)
                {
                    byte        b    = chunk.blocksInByte[256 * k + 16 * i + j];
                    CSBlockType type = (CSBlockType)b;
                    if (type != CSBlockType.None)
                    {
                        TexCoords texCoords = type2texcoords[(byte)type];

                        pos.Set(i, k, j);
                        globalPos.Set(chunk.globalX + i, k, chunk.globalZ + j);

                        if (texCoords.isPlant)
                        {
                            PlantMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices2, chunk.uv2, chunk.triangles2);
                        }
                        else
                        {
                            if (IsStair(type))
                            {
                                StairMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices1, chunk.uv1, chunk.triangles1);
                            }
                            else if (IsWall(type))
                            {
                                WallMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices1, chunk.uv1, chunk.triangles1);
                            }
                            else if (IsSlab(type))
                            {
                                SlabMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices1, chunk.uv1, chunk.triangles1);
                            }
                            else if (type == CSBlockType.Torch)
                            {
                                TorchMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices2, chunk.uv2, chunk.triangles2);
                            }
                            else
                            {
                                BlockMeshGenerator.Instance.GenerateMeshInChunk(type, pos, globalPos, chunk.vertices1, chunk.uv1, chunk.triangles1);
                            }
                        }
                    }
                }
            }
        }
    }
Esempio n. 28
0
    protected bool CreateCap(Volume volume, bool partialBuild)
    {
        if ((TypeMask & VolumeFaceMask.Hollow) == 0 &&
            (TypeMask & VolumeFaceMask.Open) == 0 &&
            ((volume.Parameters.PathParameters.Begin == 0.0f) &&
             (volume.Parameters.PathParameters.End == 1.0f)) &&
            (volume.Parameters.ProfileParameters.ProfileType == ProfileType.Square &&
             volume.Parameters.PathParameters.PathType == PathType.Line)
            )
        {
            return(CreateUnCutCubeCap(volume, partialBuild));
        }

        int numVertices = 0, numIndices = 0;

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

        // All types of caps have the same number of vertices and indices
        numVertices = profile.Count;
        numIndices  = (profile.Count - 2) * 3;

        //if ((TypeMask & VolumeFaceMask.Hollow) == 0 && (TypeMask & VolumeFaceMask.Open) == 0)
        //{
        //	resizeVertices(num_vertices + 1);

        //	//if (!partial_build)
        //	{
        //		resizeIndices(num_indices + 3);
        //	}
        //}
        //else
        //{
        //	resizeVertices(num_vertices);
        //	//if (!partial_build)
        //	{
        //		resizeIndices(num_indices);
        //	}
        //}

        Positions.Clear();
        Normals.Clear();
        Tangents.Clear();
        TexCoords.Clear();
        Indices.Clear();
        Edge.Clear();

        int maxS = volume.Profile.PointCount;
        int maxT = volume.Path.PointCount;

        Centre = Vector3.zero;

        int offset = ((TypeMask & VolumeFaceMask.Top) != 0)
            ? (maxT - 1) * maxS
            : BeginS;

        // Figure out the normal, assume all caps are flat faces.
        // Cross product to get normals.

        Vector2 cuv;
        Vector2 min_uv, max_uv;
        // VFExtents change
        Vector3 min = ExtentsMin;
        Vector3 max = ExtentsMax;

        // Copy the vertices into the array

        int srcIndex = offset;                 // Index in mesh
        int endIndex = srcIndex + numVertices; // Index in mesh

        min = mesh[srcIndex];
        max = min;

        int pIndex = 0;         // Index in profile

        if ((TypeMask & VolumeFaceMask.Top) != 0)
        {
            min_uv.x = profile[pIndex].x + 0.5f;
            min_uv.y = profile[pIndex].y + 0.5f;

            max_uv = min_uv;

            while (srcIndex < endIndex)
            {
                Vector2 tc = new Vector2(profile[pIndex].x + 0.5f, profile[pIndex].y + 0.5f);
                UpdateMinMax(ref min_uv, ref max_uv, tc);
                TexCoords.Add(tc);

                UpdateMinMax(ref min, ref max, mesh[srcIndex]);
                Positions.Add(mesh[srcIndex]);

                ++pIndex;
                ++srcIndex;
            }
        }
        else
        {
            min_uv.x = profile[pIndex].x + 0.5f;
            min_uv.y = 0.5f - profile[pIndex].y;
            max_uv   = min_uv;

            while (srcIndex < endIndex)
            {
                // Mirror for underside.
                Vector2 tc = new Vector2(profile[pIndex].x + 0.5f, 0.5f - profile[pIndex].y);
                UpdateMinMax(ref min_uv, ref max_uv, tc);
                TexCoords.Add(tc);

                UpdateMinMax(ref min, ref max, mesh[srcIndex]);
                Positions.Add(mesh[srcIndex]);

                ++pIndex;
                ++srcIndex;
            }
        }

        Centre = (min + max) * 0.5f;
        cuv    = (min_uv + max_uv) * 0.5f;

        VertexData vd = new VertexData
        {
            Position = Centre,
            TexCoord = cuv
        };

        if ((TypeMask & VolumeFaceMask.Hollow) == 0 && (TypeMask & VolumeFaceMask.Open) == 0)
        {
            Positions.Add(Centre);
            TexCoords.Add(cuv);
            numVertices++;
        }

        //if (partial_build)
        //{
        //	return TRUE;
        //}

        if ((TypeMask & VolumeFaceMask.Hollow) != 0)
        {
            CreateHollowCap(numVertices, profile, (TypeMask & VolumeFaceMask.Top) == 0);
        }
        else
        {
            // Not hollow, generate the triangle fan.
            CreateSolidCap(numVertices);
        }

        Vector3 d0 = Positions[Indices[1]] - Positions[Indices[0]];
        Vector3 d1 = Positions[Indices[2]] - Positions[Indices[0]];

        Vector3 normal = Vector3.Cross(d0, d1);

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

        //llassert(llfinite(normal.getF32ptr()[0]));
        //llassert(llfinite(normal.getF32ptr()[1]));
        //llassert(llfinite(normal.getF32ptr()[2]));

        //llassert(!llisnan(normal.getF32ptr()[0]));
        //llassert(!llisnan(normal.getF32ptr()[1]));
        //llassert(!llisnan(normal.getF32ptr()[2]));

        for (int i = 0; i < numVertices; i++)
        {
            Normals.Add(normal);
        }

        return(true);
    }
Esempio n. 29
0
    protected bool CreateUnCutCubeCap(Volume volume, bool partialBuild)
    {
        List <Vector3> mesh    = volume.Points;
        List <Vector3> profile = volume.Profile.Points;
        int            maxS    = volume.Profile.PointCount;
        int            maxT    = volume.Path.PointCount;

        int gridSize = (profile.Count - 1) / 4;
        // VFExtents change
        Vector3 min = ExtentsMin;
        Vector3 max = ExtentsMax;

        int offset = ((TypeMask & VolumeFaceMask.Top) != 0)
            ? (maxT - 1) * maxS
            : BeginS;

        {
            VertexData[] corners  = new VertexData[4];
            VertexData   baseVert = new VertexData();
            for (int t = 0; t < 4; t++)
            {
                corners[t] = new VertexData
                {
                    Position = mesh[offset + (gridSize * t)],
                    TexCoord = new Vector2(profile[gridSize * t].x + 0.5f, 0.5f - profile[gridSize * t].y)
                };
            }

            {
                Vector3 lhs = corners[1].Position - corners[0].Position;
                Vector3 rhs = corners[2].Position - corners[1].Position;
                baseVert.Normal = Vector3.Cross(lhs, rhs);
                baseVert.Normal.Normalize();
            }

            if ((TypeMask & VolumeFaceMask.Top) == 0)
            {
                baseVert.Normal *= -1.0f;
            }
            else
            {
                //Swap the UVs on the U(X) axis for top face
                Vector2 swap;
                swap = corners[0].TexCoord;
                corners[0].TexCoord = corners[3].TexCoord;
                corners[3].TexCoord = swap;
                swap = corners[1].TexCoord;
                corners[1].TexCoord = corners[2].TexCoord;
                corners[2].TexCoord = swap;
            }

            int size = (gridSize + 1) * (gridSize + 1);
            //resizeVertices(size);
            Positions.Clear();
            Normals.Clear();
            Tangents.Clear();
            TexCoords.Clear();
            Indices.Clear();
            Edge.Clear();

            for (int gx = 0; gx < gridSize + 1; gx++)
            {
                for (int gy = 0; gy < gridSize + 1; gy++)
                {
                    VertexData newVert = LerpPlanarVertex(corners[0],
                                                          corners[1],
                                                          corners[3],
                                                          (float)gx / (float)gridSize,
                                                          (float)gy / (float)gridSize);

                    Positions.Add(newVert.Position);
                    Normals.Add(baseVert.Normal);
                    TexCoords.Add(newVert.TexCoord);

                    if (gx == 0 && gy == 0)
                    {
                        min = newVert.Position;
                        max = min;
                    }
                    else
                    {
                        UpdateMinMax(ref min, ref max, newVert.Position);
                    }
                }
            }

            Centre     = (min + max) * 0.5f;
            ExtentsMin = min;
            ExtentsMax = max;
        }

        if (!partialBuild)
        {
            int[] idxs = { 0, 1, (gridSize + 1) + 1, (gridSize + 1) + 1, (gridSize + 1), 0 };
            for (int gx = 0; gx < gridSize; gx++)
            {
                for (int gy = 0; gy < gridSize; gy++)
                {
                    if ((TypeMask & VolumeFaceMask.Top) != 0)
                    {
                        for (int i = 5; i >= 0; i--)
                        {
                            Indices.Add((gy * (gridSize + 1)) + gx + idxs[i]);
                        }

                        int edgeValue = gridSize * 2 * gy + gx * 2;

                        if (gx > 0)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);                             // Mark face to higlight it
                        }

                        if (gy < gridSize - 1)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        Edge.Add(edgeValue);

                        if (gx < gridSize - 1)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        if (gy > 0)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        Edge.Add(edgeValue);
                    }
                    else
                    {
                        for (int i = 0; i < 6; i++)
                        {
                            Indices.Add((gy * (gridSize + 1)) + gx + idxs[i]);
                        }

                        int edgeValue = gridSize * 2 * gy + gx * 2;

                        if (gy > 0)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        if (gx < gridSize - 1)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        Edge.Add(edgeValue);

                        if (gy < gridSize - 1)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        if (gx > 0)
                        {
                            Edge.Add(edgeValue);
                        }
                        else
                        {
                            Edge.Add(-1);
                        }

                        Edge.Add(edgeValue);
                    }
                }
            }
        }

        return(true);
    }
Esempio n. 30
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);
    }