예제 #1
0
        public void UpdateNormals()
        {
            var normals = Normal.CalculateNormals(Vertices.Select(v => v.Position).ToList(), Indices);

            for (int i = 0; i < normals.Count; i++)
            {
                var v = Vertices[i];
                v.Normal    = normals[i];
                Vertices[i] = v;
            }
            UpdateVertexBuffer();
        }
예제 #2
0
        public bool Create(MeshPartInfo info)
        {
            if (info.VertexPositions.Count == 0)
            {
                return(false);
            }
            Guid                   = Guid.NewGuid();
            Color                  = info.Color;
            Texture                = info.Texture;
            TransparentTexture     = info.TransparentTexture;
            TextureName            = info.TextureName;
            TransparentTextureName = info.TransparentTextureName;

            //Name.Contains("SkinHead") || Name.Contains("SkinNeck")
            Name = info.PartName;
            if (Name.Contains("Pupil"))
            {
                Type = HeadMeshType.Eyes;
            }
            if (Name.Contains("SkinFace"))
            {
                Type = HeadMeshType.Face;
            }
            else
            if (Name.Contains("Lip"))
            {
                Type = HeadMeshType.Lip;
            }

            Indices.Clear();
            var positions = new List <Vector3>();
            var texCoords = new List <Vector2>();

            var positionsDict     = new Dictionary <VertexInfo, uint>(new VectorEqualityComparer());
            var pointnsDict       = new Dictionary <Vector3, int>(new VectorEqualityComparer());
            var pointsIndicesDict = new Dictionary <int, int>();

            Points.Clear();
            for (var i = 0; i < info.VertexPositions.Count; i++)
            {
                var vertexInfo = new VertexInfo
                {
                    Position  = info.VertexPositions[i],
                    TexCoords = info.TextureCoords[i]
                };
                if (!positionsDict.ContainsKey(vertexInfo))
                {
                    var index = (uint)positions.Count;
                    positionsDict.Add(vertexInfo, index);
                    Indices.Add(index);
                    positions.Add(vertexInfo.Position);
                    texCoords.Add(vertexInfo.TexCoords);

                    if (!pointnsDict.ContainsKey(vertexInfo.Position))
                    {
                        pointnsDict.Add(vertexInfo.Position, Points.Count);
                        pointsIndicesDict.Add((int)index, Points.Count);
                        Points.Add(new Point3d
                        {
                            Indices = new List <uint> {
                                index
                            },
                            Position = vertexInfo.Position
                        });
                    }
                    else
                    {
                        var id = pointnsDict[vertexInfo.Position];
                        Points[id].Indices.Add(index);
                        pointsIndicesDict.Add((int)index, id);
                    }
                }
                else
                {
                    Indices.Add(positionsDict[vertexInfo]);
                }
            }

            CountIndices = Indices.Count;
            Vertices     = new Vertex3d[positions.Count];

            var normals = Normal.CalculateNormals(positions, Indices);

            for (var i = 0; i < Vertices.Length; i++)
            {
                Vertices[i].Position         = positions[i];
                Vertices[i].OriginalPosition = positions[i];
                Vertices[i].Normal           = normals[i];
                Vertices[i].TexCoord         = texCoords[i];
                Vertices[i].AutodotsTexCoord = new Vector3(texCoords[i].X, texCoords[i].Y, 1.0f);
                Vertices[i].Color            = Vector4.One;
            }
            FillPoints(pointsIndicesDict);
            Destroy();
            GL.GenBuffers(1, out VertexBuffer);
            GL.GenBuffers(1, out IndexBuffer);
            return(true);
        }
예제 #3
0
        public void Mirror(bool leftToRight, float axis)
        {
            IsLeftToRight = leftToRight;
            UndoMirror();
            BaseVertices = new Vertex3d[Vertices.Length];
            Vertices.CopyTo(BaseVertices, 0);
            baseIndices.Clear();
            baseIndices.AddRange(Indices);

            var mirroredPoints = new SortedList <int, int>();
            var pointsMapping  = new SortedList <int, uint>();
            var vertices       = new List <Vertex3d>();
            var positions      = new List <Vector3>();
            var delta          = leftToRight ? axis + 0.00001f : axis - 0.00001f;

            for (int i = 0; i < Vertices.Length; i++)
            {
                var vertex = Vertices[i];
                if (vertex.Position.X < delta == leftToRight)
                {
                    var index = vertices.Count;
                    pointsMapping.Add(i, (uint)index);
                    vertices.Add(new Vertex3d
                    {
                        Position         = vertex.Position,
                        TexCoord         = vertex.TexCoord,
                        OriginalPosition = new Vector3(i + 2, 0.0f, 0.0f),
                        Color            = Vector4.One
                    });
                    positions.Add(vertices.Last().Position);

                    if (vertex.Position.X > -delta == leftToRight)
                    {
                        mirroredPoints.Add(index, index);
                    }
                    else
                    {
                        mirroredPoints.Add(index, vertices.Count);
                        vertices.Add(new Vertex3d
                        {
                            Position         = new Vector3(-vertex.Position.X, vertex.Position.Y, vertex.Position.Z),
                            TexCoord         = vertex.TexCoord,
                            OriginalPosition = new Vector3(-(i + 2), 0.0f, 0.0f),
                            Color            = Vector4.One
                        });
                        positions.Add(vertices.Last().Position);
                    }
                }
            }

            var   indices      = new List <uint>();
            var   linesMapping = new Dictionary <Line, int>(new VectorEqualityComparer());
            var   lines        = new[] { new Line(0, 0), new Line(0, 0) };
            float k            = 0.0f;
            var   idx          = new int[2];

            for (int i = 0; i < Indices.Count; i += 3)
            {
                var triangle    = Indices.GetRange(i, 3).Select(p => (int)p).ToArray();
                var count       = triangle.Count(pointsMapping.ContainsKey);
                var centerIndex = -1;
                switch (count)
                {
                case 3:
                    indices.AddRange(triangle.Select(t => pointsMapping[t]));
                    continue;

                case 1:
                case 2:
                    var c = count;
                    foreach (var t in triangle.Where(pointsMapping.ContainsKey))
                    {
                        var key = (int)pointsMapping[t];
                        if (mirroredPoints[key] == key)
                        {
                            centerIndex = t;
                            c--;
                        }
                    }
                    if (c == 0)
                    {
                        continue;
                    }
                    break;

                case 0:
                    continue;
                }
                for (int j = 0; j < 3; j++)
                {
                    if (pointsMapping.ContainsKey(triangle[j]) == (count == 1))
                    {
                        lines[0].A = triangle[j];
                        lines[0].B = triangle[(j + 1) % 3];
                        lines[1].A = triangle[(j + 2) % 3];
                        lines[1].B = triangle[j];
                    }
                }
                idx[0] = linesMapping.ContainsKey(lines[0]) ? linesMapping[lines[0]] : -1;
                idx[1] = linesMapping.ContainsKey(lines[1]) ? linesMapping[lines[1]] : -1;
                for (int j = 0; j < idx.Length; j++)
                {
                    if (idx[j] < 0)
                    {
                        var line = lines[j];
                        var v0   = Vertices[line.A];
                        var v1   = Vertices[line.B];
                        if (line.A == centerIndex || line.B == centerIndex)
                        {
                            count       = 1;
                            centerIndex = (j + 1) % 2;
                        }
                        else
                        {
                            idx[j] = vertices.Count;
                            linesMapping.Add(line, vertices.Count);
                            mirroredPoints.Add(vertices.Count, vertices.Count);
                            vertices.Add(new Vertex3d
                            {
                                Position         = Line.GetPoint(v0.Position, v1.Position, 0.0f, ref k),
                                OriginalPosition = new Vector3(k, line.A, line.B),
                                TexCoord         = v0.TexCoord + (v1.TexCoord - v0.TexCoord) * k,
                                Color            = Vector4.One
                            });
                            positions.Add(vertices.Last().Position);
                        }
                    }
                }
                if (count == 2)
                {
                    indices.Add((uint)idx[0]);
                    indices.Add(pointsMapping[lines[0].B]);
                    indices.Add(pointsMapping[lines[1].A]);

                    indices.Add(pointsMapping[lines[1].A]);
                    indices.Add((uint)idx[1]);
                    indices.Add((uint)idx[0]);
                }
                else
                {
                    switch (centerIndex)
                    {
                    case -1:
                        indices.Add(pointsMapping[lines[0].A]);
                        indices.Add((uint)idx[0]);
                        indices.Add((uint)idx[1]);
                        break;

                    default:
                        indices.Add(pointsMapping[lines[0].B]);
                        indices.Add(pointsMapping[lines[1].A]);
                        indices.Add((uint)idx[centerIndex]);
                        break;
                    }
                }
            }
            var cnt = indices.Count;

            for (int i = 0; i < cnt; i += 3)
            {
                var triangle = indices.GetRange(i, 3).ToArray();
                for (int j = 2; j >= 0; j--)
                {
                    indices.Add((uint)mirroredPoints[(int)triangle[j]]);
                }
            }

            var normals = Normal.CalculateNormals(positions, indices);

            for (int i = 0; i < normals.Count; i++)
            {
                var v = vertices[i];
                v.Normal    = normals[i];
                vertices[i] = v;
            }

            Indices      = indices;
            CountIndices = indices.Count;
            Vertices     = vertices.ToArray();
            UpdateBuffers();
        }