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