public override void Undo() { foreach (var meshId in ToDelete) { if (ProgramCore.MainForm.ctrlRenderControl.pickingController.HairMeshes.Contains(meshId)) { var mesh = ProgramCore.MainForm.ctrlRenderControl.pickingController.HairMeshes[meshId]; ProgramCore.MainForm.ctrlRenderControl.pickingController.HairMeshes.Remove(mesh); if (ProgramCore.MainForm.ctrlRenderControl.PartsLibraryMeshes.ContainsKey(mesh.Title)) { ProgramCore.MainForm.ctrlRenderControl.PartsLibraryMeshes[mesh.Title].Remove(mesh); } mesh.Destroy(); } } if (vertexPositions != null) { var newMesh = new DynamicRenderMesh(MeshType.Hair); newMesh.Create(vertexPositions, textureCoordinates, vertexIndices, texturePath, alphaTexturePath, textureAngle, textureSize); newMesh.Title = title; newMesh.groupName = title; newMesh.Transform = transform; newMesh.Position = position; newMesh.Material.DiffuseTextureMap = texturePath; newMesh.Material.TransparentTextureMap = alphaTexturePath; newMesh.TextureAngle = textureAngle; newMesh.TextureSize = textureSize; newMesh.Id = id; newMesh.IsVisible = isVisible; if (inPartsLibrary) { ProgramCore.MainForm.ctrlRenderControl.PartsLibraryMeshes[newMesh.Title].Add(newMesh); } ProgramCore.MainForm.ctrlRenderControl.pickingController.HairMeshes.Add(newMesh); } ProgramCore.MainForm.frmParts.UpdateList(); }
public void Slice(DynamicRenderMesh mesh, Camera camera) { slicePointsDictionary.Clear(); verticesDictionary.Clear(); slicePoints.Clear(); vertices.Clear(); texCoords.Clear(); indices.Clear(); triangles.Clear(); ResultMeshes.Clear(); FillVertices(mesh, camera); Vector2 A = new Vector2(99999.0f, 99999.0f), B = new Vector2(-99999.0f, -99999.0f); var tempLine = new Line2d(); var workedIndices = new List <int>(); var tempIndices = new List <int>(); foreach (var line in Lines) { for (var i = 0; i < 2; i++) { if (line.A[i] < A[i]) { A[i] = line.A[i]; } if (line.B[i] > B[i]) { B[i] = line.B[i]; } } } for (var i = 0; i < indices.Count / 3; i++) { var index = i * 3; var point0 = vertices[indices[index]]; var point1 = vertices[indices[index + 1]]; var point2 = vertices[indices[index + 2]]; if (!CheckAABB(ref point0, ref point1, ref point2, ref A, ref B)) { for (var j = 0; j < 3; j++) { tempIndices.Add(indices[index + j]); } continue; } for (var j = 0; j < 3; j++) { workedIndices.Add(indices[index + j]); } } if (workedIndices.Count == 0) { return; } var triangle = new Vector3[3]; var triangleT = new Vector2[3]; var tempCollisions = new List <Vector3>(); var tempTexCoords = new List <Vector2>(); var tempCollisionsEdgeIndices = new List <int>(); var newTriangles = new List <int>(); var info0 = CollisionInfo.Zero; var info1 = CollisionInfo.Zero; for (var i = 0; i < sliceLines.Count; i++) { var line = Lines[i]; var sliceLine = sliceLines[i]; var trianglesCount = workedIndices.Count / 3; for (var j = 0; j < trianglesCount; j++) { var index = j * 3; for (var l = 0; l < 3; l++) { triangle[l] = vertices[workedIndices[index + l]]; triangleT[l] = texCoords[workedIndices[index + l]]; } info0 = CollisionInfo.Zero; info1 = CollisionInfo.Zero; tempCollisions.Clear(); tempTexCoords.Clear(); tempCollisionsEdgeIndices.Clear(); newTriangles.Clear(); //looking for a point / intersection point of the triangle and line for (int k = 0, l = 2; k < 3; l = k, k++) { if (info1.Type != CollisionType.CT_NONE) { break; } var tPoint0 = triangle[l]; var tPoint1 = triangle[k]; var tTexCoord0 = triangleT[l]; var tTexCoord1 = triangleT[k]; tempLine.Point0.X = tPoint0.X; tempLine.Point0.Y = tPoint0.Y; tempLine.Point1.X = tPoint1.X; tempLine.Point1.Y = tPoint1.Y; float ua, ub; if (!GetUaUb(tempLine, line, out ua, out ub)) { //lines coincide? //Verify whether some point belongs line segment tempLine //if find - get result and break. } else { if (ub < 0.0f || ub > 1.0f) { continue; } var collisionPoint = tPoint0 + (tPoint1 - tPoint0) * ub; var collisionTexCoord = tTexCoord0 + (tTexCoord1 - tTexCoord0) * ub; if (tempCollisions.Count == 0 || !PointsCompare.Equals(tempCollisions[0], collisionPoint)) { tempCollisions.Add(collisionPoint); tempTexCoords.Add(collisionTexCoord); tempCollisionsEdgeIndices.Add(l); } if (ua < 0.0f || ua > 1.0f) { continue; } var pointType = CollisionType.CT_VERTEX; Vector3 point; Vector2 texCoord; var pointIndex = -1; var edgeIndex = -1; if (ub > 0.0f) { if (ub < 1.0f) { pointType = CollisionType.CT_EDGE; point = tempCollisions.Last(); texCoord = tempTexCoords.Last(); edgeIndex = l; } else { point = tPoint1; texCoord = tTexCoord1; pointIndex = workedIndices[index + k]; } } else { point = tPoint0; texCoord = tTexCoord0; pointIndex = workedIndices[index + l]; } if (info0.Type == CollisionType.CT_NONE) { info0.PointIndex = pointIndex; info0.Type = pointType; info0.Position = point; info0.TexCoord = texCoord; info0.EdgeIndex = edgeIndex; } else { if (pointIndex == -1 || info0.PointIndex != pointIndex) { info1.PointIndex = pointIndex; info1.Type = pointType; info1.Position = point; info1.TexCoord = texCoord; info1.EdgeIndex = edgeIndex; } } } } if (info1.Type == CollisionType.CT_NONE) { if (tempCollisions.Count == 0) { if (info0.Type == CollisionType.CT_NONE) { continue; } } else { if (tempCollisions.Count > 1) { //Perhaps the point inside the triangle var dir = line.Direction; for (var l = 0; l < 2; l++) { var p = l == 0 ? line.Point0 : line.Point1; if (PointInTriangle(ref triangle[0], ref triangle[1], ref triangle[2], ref p)) { var v0 = tempCollisions[1].Xy - tempCollisions[0].Xy; var v1 = p - tempCollisions[0].Xy; var k = (v1.Length / v0.Length); var z = tempCollisions[0].Z + (tempCollisions[1].Z - tempCollisions[0].Z) * k; var t = tempTexCoords[0] + (tempTexCoords[1] - tempTexCoords[0]) * k; if (info0.Type == CollisionType.CT_NONE) { info0.Type = CollisionType.CT_INSIDE; info0.Position = new Vector3(p.X, p.Y, z); info0.TexCoord = t; if (Vector2.Dot(dir, v0) > 0.0f) { info0.EdgeIndex = tempCollisionsEdgeIndices[0]; } else { info0.EdgeIndex = tempCollisionsEdgeIndices[1]; } tempCollisionsEdgeIndices.Remove(info0.EdgeIndex); } else { info1.Type = CollisionType.CT_INSIDE; info1.Position = new Vector3(p.X, p.Y, z); info1.TexCoord = t; info1.EdgeIndex = tempCollisionsEdgeIndices[0]; } } } } } } if (info0.Type == CollisionType.CT_NONE) { continue; } //Create new triangles, if we have two points of intersection, and they are not vertices int pi1 = 0, pi0 = 0; if (info1.Type != CollisionType.CT_NONE && (info0.Type != CollisionType.CT_VERTEX || info1.Type != CollisionType.CT_VERTEX)) { if (info1.Type == CollisionType.CT_VERTEX || (info1.Type == CollisionType.CT_EDGE && info0.Type == CollisionType.CT_INSIDE) || (info1.Type == CollisionType.CT_EDGE && info0.Type == CollisionType.CT_EDGE && (info0.EdgeIndex + 1) % 3 != info1.EdgeIndex) || (info0.Type == CollisionType.CT_INSIDE && info1.Type == CollisionType.CT_INSIDE && (info0.EdgeIndex + 1) % 3 != info1.EdgeIndex)) { var temp = info1; info1 = info0; info0 = temp; } if (!verticesDictionary.TryGetValue(info1.Position, out pi1)) { pi1 = vertices.Count; vertices.Add(info1.Position); texCoords.Add(info1.TexCoord); verticesDictionary.Add(info1.Position, pi1); } if (info0.Type == CollisionType.CT_VERTEX) //One point of intersection coincides with the vertex { pi0 = info0.PointIndex; int i0 = workedIndices[index], i1 = workedIndices[index + 1], i2 = workedIndices[index + 2]; if (i0 == info0.PointIndex) { i0 = i2; i2 = i1; } else { if (i2 == info0.PointIndex) { i2 = i0; i0 = i1; } } i1 = info0.PointIndex; newTriangles.AddRange(new[] { i0, i1, pi1, i1, i2, pi1 }); if (info1.Type == CollisionType.CT_INSIDE) //The second point inside the triangle { newTriangles.AddRange(new[] { i2, i0, pi1 }); } } else { if (!verticesDictionary.TryGetValue(info0.Position, out pi0)) { pi0 = vertices.Count; vertices.Add(info0.Position); texCoords.Add(info0.TexCoord); verticesDictionary.Add(info0.Position, pi0); } if (info1.Type != info0.Type) //One point crosses the brink, the second inside the triangle { var prev = info0.EdgeIndex == 0 ? 2 : info0.EdgeIndex - 1; prev = workedIndices[index + prev]; var next = info0.EdgeIndex == 2 ? 0 : info0.EdgeIndex + 1; next = workedIndices[index + next]; var curr = workedIndices[index + info0.EdgeIndex]; newTriangles.AddRange(new[] { prev, curr, pi1, curr, pi0, pi1, pi0, next, pi1, next, prev, pi1 }); } else { var c0 = workedIndices[index + info0.EdgeIndex]; var c1 = workedIndices[index + info1.EdgeIndex]; var c2 = workedIndices[index + ((info1.EdgeIndex + 1) % 3)]; if (info0.Type == CollisionType.CT_EDGE) { newTriangles.AddRange(new[] { c0, pi0, pi1, pi0, c1, pi1, pi1, c2, c0 }); } else { newTriangles.AddRange(new[] { c0, c1, pi0, c1, pi1, pi0, c1, c2, pi1, c2, c0, pi1, c0, pi0, pi1 }); } } } } int slicePointIndex; SlicePoint slicePoint; for (var l = 0; l < 2; l++) { if (l == 1 && info1.Type == CollisionType.CT_NONE) { break; } var position = l == 0 ? info0.Position.Xy : info1.Position.Xy; var pointIndex = l == 0 ? pi0 : pi1; if (!slicePointsDictionary.TryGetValue(position, out slicePointIndex)) { slicePoint = new SlicePoint { Coordinate = position }; slicePoint.Lines.Add(sliceLine); slicePoint.PreparePoint(); slicePointIndex = slicePoints.Count; slicePoints.Add(slicePoint); slicePointsDictionary.Add(position, slicePointIndex); } else { slicePoint = slicePoints[slicePointIndex]; } if (!slicePoint.Indices.Contains(pointIndex)) { slicePoint.Indices.Add(pointIndex); } } if (newTriangles.Count > 0) { for (var l = 0; l < 3; l++) { workedIndices[index + l] = newTriangles[l]; } newTriangles.RemoveRange(0, 3); workedIndices.InsertRange(index, newTriangles); var count = (newTriangles.Count / 3); j += count; trianglesCount += count; } } } for (var i = 0; i < workedIndices.Count / 3; i++) { var index = i * 3; var t = new Triangle(); for (var j = 0; j < 3; j++) { t.Indices[j] = workedIndices[index + j]; } triangles.Add(i, new TrianleConnections { Triangle = t }); } var ind = new List <int>(); var tempTriangle = new Triangle(); tempTriangle.Indices[1] = -1; foreach (var point in slicePoints) { point.PreparePoint(); foreach (var index in point.Indices) { ind.Clear(); ind.Add(index); tempTriangle.Indices[0] = index; //Duplicate the verticle several times for (var i = 1; i < point.Directions.Count; i++) { ind.Add(vertices.Count); vertices.Add(vertices[index]); texCoords.Add(texCoords[index]); } foreach (var t in triangles) { var tr = t.Value.Triangle; var id = Triangle.TriangleEquals(ref tempTriangle, ref tr); if (id > -1) { var center = (vertices[tr.Indices[0]].Xy + vertices[tr.Indices[1]].Xy + vertices[tr.Indices[2]].Xy) / 3.0f; var dir = (center - point.Coordinate).Normalized(); var angle = SlicePoint.GetAngle(ref dir); var ii = point.Directions.Count - 1; for (var j = 0; j < point.Directions.Count; j++) { if (angle < point.Directions[j]) { break; } ii = j; } tr.Indices[id] = ind[ii]; } } } } var invTransform = mesh.Transform * camera.ViewMatrix; invTransform.Invert(); for (var i = 0; i < vertices.Count; i++) { vertices[i] = Vector3.Transform(vertices[i], invTransform); } workedIndices.Clear(); foreach (var t in triangles) { foreach (var i in t.Value.Triangle.Indices) { workedIndices.Add(i); } } workedIndices.AddRange(tempIndices); triangleConnections.Clear(); triangles.Clear(); for (var i = 0; i < workedIndices.Count / 3; i++) { var index = i * 3; var t = new Triangle(); for (var j = 0; j < 3; j++) { t.Indices[j] = workedIndices[index + j]; List <int> l; if (!triangleConnections.TryGetValue(t.Indices[j], out l)) { l = new List <int>(); triangleConnections.Add(t.Indices[j], l); } l.Add(i); } triangles.Add(i, new TrianleConnections { Triangle = t }); } var mainMesh = true; while (triangles.Count > 0) { foundedTriangles.Clear(); FillTriangles(triangles.First().Key); if (mainMesh) { mesh.Create(vertices, texCoords, foundedTriangles, mesh.Material.DiffuseTextureMap, mesh.Material.TransparentTextureMap, mesh.TextureAngle, mesh.TextureSize); mainMesh = false; } else { var tmpMesh = new DynamicRenderMesh(MeshType.Hair); tmpMesh.Create(vertices, texCoords, foundedTriangles, mesh.Material.DiffuseTextureMap, mesh.Material.TransparentTextureMap, mesh.TextureAngle, mesh.TextureSize); tmpMesh.Transform = mesh.Transform; tmpMesh.Material.DiffuseColor = mesh.Material.DiffuseColor; tmpMesh.MeshAngle = mesh.MeshAngle; tmpMesh.MeshSize = mesh.MeshSize; var info = tmpMesh.GetMeshInfo(); var center = Vector3.Zero; var scale = PickingController.GetHairScale(ProgramCore.Project.ManType); foreach (var vert in info.Positions) { center.X += vert.X * scale; center.Y += vert.Y * scale; center.Z += vert.Z * scale; } center /= info.Positions.Count; tmpMesh.Position = center; ResultMeshes.Add(tmpMesh); } } }
/// <summary> Accessory file saved in program. Here is a few accessories devided by groups </summary> private List <DynamicRenderMesh> LoadSpecialAccessoryMesh(ObjItem objModel) { var result = new List <DynamicRenderMesh>(); foreach (var modelGroup in objModel.Groups) { var vertexPositions = new List <float>(); var vertexNormals = new List <float>(); var vertexTextureCoordinates = new List <float>(); var vertexBoneIndices = new List <float>(); var vertexBoneWeights = new List <float>(); var indeces = new List <uint>(); foreach (var face in modelGroup.Value.Faces) { if (face.Count == 3) { for (var i = 0; i < face.Count; i++) { var faceVertex = face[i]; ObjLoader.AppendObjTriangle(objModel, faceVertex, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); } } else if (face.Count == 4) { var faceVertex0 = face[0]; var faceVertex1 = face[1]; var faceVertex2 = face[2]; var faceVertex3 = face[3]; ObjLoader.AppendObjTriangle(objModel, faceVertex0, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex1, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex2, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex2, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex3, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex0, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); } } if (vertexPositions.Count == 0) { continue; } var renderMesh = new DynamicRenderMesh(MeshType.Accessory); if (renderMesh.Create(vertexPositions, vertexTextureCoordinates, vertexBoneIndices, vertexBoneWeights, indeces, string.Empty, string.Empty)) { renderMesh.Title = modelGroup.Key.Name == "default" ? string.Empty : modelGroup.Key.Name; renderMesh.Material.DiffuseColor = new Vector4(modelGroup.Key.DiffuseColor.X, modelGroup.Key.DiffuseColor.Y, modelGroup.Key.DiffuseColor.Z, modelGroup.Key.Transparency); if (!string.IsNullOrEmpty(modelGroup.Key.DiffuseTextureMap)) { renderMesh.Material.DiffuseTextureMap = modelGroup.Key.DiffuseTextureMap; } if (!string.IsNullOrEmpty(modelGroup.Key.TransparentTextureMap)) { renderMesh.Material.TransparentTextureMap = modelGroup.Key.TransparentTextureMap; } var center = Vector3.Zero; var count = vertexPositions.Count / 3; const float scale = 246f; for (var i = 0; i < count; i++) { center.X += vertexPositions[i * 3] * scale; center.Y += vertexPositions[i * 3 + 1] * scale; center.Z += vertexPositions[i * 3 + 2] * scale; } center /= count; renderMesh.Transform = Matrix4.CreateScale(scale); /* renderMesh.Transform[3, 0] = -center.X; * renderMesh.Transform[3, 1] = -center.Y; * renderMesh.Transform[3, 2] = -center.Z;*/ renderMesh.Position = center; AccesoryMeshes.Add(renderMesh); result.Add(renderMesh); } } return(result); }
private List <DynamicRenderMesh> LoadHairMeshes(ObjItem objModel, ObjItem objModelNull, bool fromDragAndDrop, ManType manType, MeshType meshType) { var result = new List <DynamicRenderMesh>(); var vertexPositions = new List <float>(); var vertexNormals = new List <float>(); var vertexTextureCoordinates = new List <float>(); var vertexBoneIndices = new List <float>(); var vertexBoneWeights = new List <float>(); var indeces = new List <uint>(); var vertexPositionsNull = new List <float>(); var vertexNormalsNull = new List <float>(); var vertexTextureCoordinatesNull = new List <float>(); var vertexBoneIndicesNull = new List <float>(); var vertexBoneWeightsNull = new List <float>(); var indecesNull = new List <uint>(); var groupsNull = objModelNull == null ? new Dictionary <ObjMaterial, ObjGroup> .Enumerator() : objModelNull.Groups.GetEnumerator(); ObjGroup groupNull; foreach (var modelGroup in objModel.Groups) // one group - one mesh { vertexPositions.Clear(); vertexNormals.Clear(); vertexTextureCoordinates.Clear(); vertexBoneIndices.Clear(); vertexBoneWeights.Clear(); indeces.Clear(); foreach (var face in modelGroup.Value.Faces) // combine all meshes in group - to one mesh. { GetObjFace(face, objModel, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); } var renderMesh = new DynamicRenderMesh(meshType); renderMesh.groupName = modelGroup.Value.Name; if (!objModel.modelByHeadShop) { for (var i = 0; i < vertexPositions.Count / 3; i++) { vertexPositions[i * 3 + 1] = vertexPositions[i * 3 + 1] - 0.0060975609f; } } if (renderMesh.Create(vertexPositions, vertexTextureCoordinates, vertexBoneIndices, vertexBoneWeights, indeces, string.Empty, string.Empty)) { if (objModelNull != null) { groupsNull.MoveNext(); groupNull = groupsNull.Current.Value; vertexPositionsNull.Clear(); vertexNormalsNull.Clear(); vertexTextureCoordinatesNull.Clear(); vertexBoneWeightsNull.Clear(); vertexBoneIndicesNull.Clear(); indecesNull.Clear(); foreach (var face in groupNull.Faces) { GetObjFace(face, objModelNull, ref vertexPositionsNull, ref vertexNormalsNull, ref vertexTextureCoordinatesNull, ref vertexBoneWeightsNull, ref vertexBoneIndicesNull, ref indecesNull); } renderMesh.SetNullPoints(vertexPositionsNull, vertexNormalsNull, vertexTextureCoordinatesNull); } renderMesh.Title = modelGroup.Key.Name == "default" ? string.Empty : modelGroup.Key.Name; renderMesh.Material = modelGroup.Key; renderMesh.Material.DiffuseColor = new Vector4(modelGroup.Key.DiffuseColor.X, modelGroup.Key.DiffuseColor.Y, modelGroup.Key.DiffuseColor.Z, modelGroup.Key.Transparency); if (!string.IsNullOrEmpty(modelGroup.Key.DiffuseTextureMap)) { renderMesh.Material.DiffuseTextureMap = modelGroup.Key.DiffuseTextureMap; } if (!string.IsNullOrEmpty(modelGroup.Key.TransparentTextureMap)) { renderMesh.Material.TransparentTextureMap = modelGroup.Key.TransparentTextureMap; } var scale = meshType == MeshType.Head ? GetHeadScale(manType) : GetHairScale(manType); // перегруз сделан потому, что на этапе загрузки проекта самого проекта еще может не быть. поэтому лучше передавать renderMesh.Transform = Matrix4.CreateScale(scale); var center = Vector3.Zero; var count = vertexPositions.Count / 3; for (var i = 0; i < count; i++) { center.X += vertexPositions[i * 3] * scale; center.Y += vertexPositions[i * 3 + 1] * scale; center.Z += vertexPositions[i * 3 + 2] * scale; } if (fromDragAndDrop) { center /= count; renderMesh.Transform = Matrix4.CreateScale(scale); renderMesh.Transform[3, 0] = -center.X; renderMesh.Transform[3, 1] = -center.Y; renderMesh.Transform[3, 2] = -center.Z; renderMesh.Position = center; } if (vertexTextureCoordinates.Count > 0 && vertexTextureCoordinates.All(x => x == 0)) { renderMesh.UpdateTextureCoordinates(0, 1); } if (renderMesh.vertexArray.Length > 0) { result.Add(renderMesh); } } } return(result); }
public override void Undo() { foreach (var meshId in ToDelete) { if (ProgramCore.MainForm.ctrlRenderControl.pickingController.HairMeshes.Contains(meshId)) { var mesh = ProgramCore.MainForm.ctrlRenderControl.pickingController.HairMeshes[meshId]; ProgramCore.MainForm.ctrlRenderControl.pickingController.HairMeshes.Remove(mesh); if (ProgramCore.MainForm.ctrlRenderControl.PartsLibraryMeshes.ContainsKey(mesh.Title)) ProgramCore.MainForm.ctrlRenderControl.PartsLibraryMeshes[mesh.Title].Remove(mesh); mesh.Destroy(); } } if (vertexPositions != null) { var newMesh = new DynamicRenderMesh(MeshType.Hair); newMesh.Create(vertexPositions, textureCoordinates, vertexIndices, texturePath, alphaTexturePath, textureAngle, textureSize); newMesh.Title = title; newMesh.groupName = title; newMesh.Transform = transform; newMesh.Position = position; newMesh.Material.DiffuseTextureMap = texturePath; newMesh.Material.TransparentTextureMap = alphaTexturePath; newMesh.TextureAngle = textureAngle; newMesh.TextureSize = textureSize; newMesh.Id = id; newMesh.IsVisible = isVisible; if (inPartsLibrary) ProgramCore.MainForm.ctrlRenderControl.PartsLibraryMeshes[newMesh.Title].Add(newMesh); ProgramCore.MainForm.ctrlRenderControl.pickingController.HairMeshes.Add(newMesh); } ProgramCore.MainForm.frmParts.UpdateList(); }
private void LoadBodyMeshes(string daePath, Scene scene, Node node, AnimatedNode animationNode) { if (node.HasMeshes) { var vertexPositions = new List <float>(); var vertexNormals = new List <float>(); var vertexTextureCoordinates = new List <float>(); var vertexBoneIndices = new List <float>(); var vertexBoneWeights = new List <float>(); var indeces = new List <uint>(); var fi = new FileInfo(daePath); foreach (var index in node.MeshIndices) { var mesh = scene.Meshes[index]; var hasTexCoords = mesh.HasTextureCoords(0); vertexPositions.Clear(); vertexNormals.Clear(); vertexTextureCoordinates.Clear(); vertexBoneIndices.Clear(); vertexBoneWeights.Clear(); indeces.Clear(); for (var i = 0; i < mesh.VertexCount; i++) { var vector = mesh.Vertices[i]; vertexPositions.Add(vector.X); vertexPositions.Add(vector.Y); vertexPositions.Add(vector.Z); vector = mesh.HasNormals ? mesh.Normals[i] : ZERO_VECTRO3D; vertexNormals.Add(vector.X); vertexNormals.Add(vector.Y); vertexNormals.Add(vector.Z); vector = hasTexCoords ? mesh.GetTextureCoords(0)[i] : ZERO_VECTRO3D; vertexTextureCoordinates.Add(vector.X); vertexTextureCoordinates.Add(1.0f - vector.Y); vertexBoneIndices.AddRange(new[] { 0.0f, 0.0f, 0.0f, 0.0f }); vertexBoneWeights.AddRange(new[] { 0.0f, 0.0f, 0.0f, 0.0f }); } foreach (var face in mesh.Faces) { indeces.Add(face.Indices[0]); indeces.Add(face.Indices[1]); indeces.Add(face.Indices[2]); } if (mesh.HasBones) { foreach (var bone in mesh.Bones) { if (!bone.HasVertexWeights) { continue; } int boneIndex; if (bonesMapping.ContainsKey(bone.Name)) { boneIndex = bonesMapping[bone.Name]; } else { boneIndex = Bones.Count; var boneInfo = new BoneInfo { BoneOffset = FromMatrix(bone.OffsetMatrix), }; Bones.Add(boneInfo); bonesMapping.Add(bone.Name, boneIndex); } foreach (var weight in bone.VertexWeights) { var vi = (int)weight.VertexID * 4; for (var i = 0; i < 4; i++) { if (vertexBoneWeights[vi + i] == 0.0f) { vertexBoneIndices[vi + i] = boneIndex; vertexBoneWeights[vi + i] = weight.Weight; break; } } } } } var mtr = scene.Materials[mesh.MaterialIndex]; var texturePath = string.Empty; var transparentPath = string.Empty; if (mtr.GetTextureCount(TextureType.Diffuse) > 0) { var tex = mtr.GetTexture(TextureType.Diffuse, 0); texturePath = Path.Combine(fi.DirectoryName, tex.FilePath); transparentPath = Path.Combine(Path.GetDirectoryName(tex.FilePath), Path.GetFileNameWithoutExtension(tex.FilePath) + "_alpha" + Path.GetExtension(tex.FilePath)); transparentPath = File.Exists(transparentPath) ? transparentPath : string.Empty; } var renderMesh = new DynamicRenderMesh(MeshType.Head); if (renderMesh.Create(vertexPositions, vertexNormals, vertexTextureCoordinates, vertexBoneIndices, vertexBoneWeights, indeces, texturePath, transparentPath)) { renderMesh.Transform = FromMatrix(node.Transform); renderMesh.Material.DiffuseColor = new Vector4(mtr.ColorDiffuse.R, mtr.ColorDiffuse.G, mtr.ColorDiffuse.B, mtr.ColorDiffuse.A); BodyMeshes.Add(renderMesh); } } } var parentNode = animationNode; if (animationNode == null) { rootNode = new AnimatedNode(); parentNode = rootNode; } parentNode.Name = node.Name; parentNode.Transform = FromMatrix(node.Transform); for (var i = 0; i < node.ChildCount; i++) { var childNode = new AnimatedNode { Parent = parentNode }; LoadBodyMeshes(daePath, scene, node.Children[i], childNode); parentNode.Childs.Add(childNode); } }
public void Slice(DynamicRenderMesh mesh, Camera camera) { slicePointsDictionary.Clear(); verticesDictionary.Clear(); slicePoints.Clear(); vertices.Clear(); texCoords.Clear(); indices.Clear(); triangles.Clear(); ResultMeshes.Clear(); FillVertices(mesh, camera); Vector2 A = new Vector2(99999.0f, 99999.0f), B = new Vector2(-99999.0f, -99999.0f); var tempLine = new Line2d(); var workedIndices = new List<int>(); var tempIndices = new List<int>(); foreach (var line in Lines) { for (var i = 0; i < 2; i++) { if (line.A[i] < A[i]) A[i] = line.A[i]; if (line.B[i] > B[i]) B[i] = line.B[i]; } } for (var i = 0; i < indices.Count / 3; i++) { var index = i * 3; var point0 = vertices[indices[index]]; var point1 = vertices[indices[index + 1]]; var point2 = vertices[indices[index + 2]]; if (!CheckAABB(ref point0, ref point1, ref point2, ref A, ref B)) { for (var j = 0; j < 3; j++) tempIndices.Add(indices[index + j]); continue; } for (var j = 0; j < 3; j++) workedIndices.Add(indices[index + j]); } if (workedIndices.Count == 0) return; var triangle = new Vector3[3]; var triangleT = new Vector2[3]; var tempCollisions = new List<Vector3>(); var tempTexCoords = new List<Vector2>(); var tempCollisionsEdgeIndices = new List<int>(); var newTriangles = new List<int>(); var info0 = CollisionInfo.Zero; var info1 = CollisionInfo.Zero; for (var i = 0; i < sliceLines.Count; i++) { var line = Lines[i]; var sliceLine = sliceLines[i]; var trianglesCount = workedIndices.Count / 3; for (var j = 0; j < trianglesCount; j++) { var index = j * 3; for (var l = 0; l < 3; l++) { triangle[l] = vertices[workedIndices[index + l]]; triangleT[l] = texCoords[workedIndices[index + l]]; } info0 = CollisionInfo.Zero; info1 = CollisionInfo.Zero; tempCollisions.Clear(); tempTexCoords.Clear(); tempCollisionsEdgeIndices.Clear(); newTriangles.Clear(); //looking for a point / intersection point of the triangle and line for (int k = 0, l = 2; k < 3; l = k, k++) { if (info1.Type != CollisionType.CT_NONE) break; var tPoint0 = triangle[l]; var tPoint1 = triangle[k]; var tTexCoord0 = triangleT[l]; var tTexCoord1 = triangleT[k]; tempLine.Point0.X = tPoint0.X; tempLine.Point0.Y = tPoint0.Y; tempLine.Point1.X = tPoint1.X; tempLine.Point1.Y = tPoint1.Y; float ua, ub; if (!GetUaUb(tempLine, line, out ua, out ub)) { //lines coincide? //Verify whether some point belongs line segment tempLine //if find - get result and break. } else { if (ub < 0.0f || ub > 1.0f) continue; var collisionPoint = tPoint0 + (tPoint1 - tPoint0) * ub; var collisionTexCoord = tTexCoord0 + (tTexCoord1 - tTexCoord0) * ub; if (tempCollisions.Count == 0 || !PointsCompare.Equals(tempCollisions[0], collisionPoint)) { tempCollisions.Add(collisionPoint); tempTexCoords.Add(collisionTexCoord); tempCollisionsEdgeIndices.Add(l); } if (ua < 0.0f || ua > 1.0f) continue; var pointType = CollisionType.CT_VERTEX; Vector3 point; Vector2 texCoord; var pointIndex = -1; var edgeIndex = -1; if (ub > 0.0f) { if (ub < 1.0f) { pointType = CollisionType.CT_EDGE; point = tempCollisions.Last(); texCoord = tempTexCoords.Last(); edgeIndex = l; } else { point = tPoint1; texCoord = tTexCoord1; pointIndex = workedIndices[index + k]; } } else { point = tPoint0; texCoord = tTexCoord0; pointIndex = workedIndices[index + l]; } if (info0.Type == CollisionType.CT_NONE) { info0.PointIndex = pointIndex; info0.Type = pointType; info0.Position = point; info0.TexCoord = texCoord; info0.EdgeIndex = edgeIndex; } else { if (pointIndex == -1 || info0.PointIndex != pointIndex) { info1.PointIndex = pointIndex; info1.Type = pointType; info1.Position = point; info1.TexCoord = texCoord; info1.EdgeIndex = edgeIndex; } } } } if (info1.Type == CollisionType.CT_NONE) { if (tempCollisions.Count == 0) { if (info0.Type == CollisionType.CT_NONE) continue; } else { if (tempCollisions.Count > 1) { //Perhaps the point inside the triangle var dir = line.Direction; for (var l = 0; l < 2; l++) { var p = l == 0 ? line.Point0 : line.Point1; if (PointInTriangle(ref triangle[0], ref triangle[1], ref triangle[2], ref p)) { var v0 = tempCollisions[1].Xy - tempCollisions[0].Xy; var v1 = p - tempCollisions[0].Xy; var k = (v1.Length / v0.Length); var z = tempCollisions[0].Z + (tempCollisions[1].Z - tempCollisions[0].Z) * k; var t = tempTexCoords[0] + (tempTexCoords[1] - tempTexCoords[0]) * k; if (info0.Type == CollisionType.CT_NONE) { info0.Type = CollisionType.CT_INSIDE; info0.Position = new Vector3(p.X, p.Y, z); info0.TexCoord = t; if (Vector2.Dot(dir, v0) > 0.0f) info0.EdgeIndex = tempCollisionsEdgeIndices[0]; else info0.EdgeIndex = tempCollisionsEdgeIndices[1]; tempCollisionsEdgeIndices.Remove(info0.EdgeIndex); } else { info1.Type = CollisionType.CT_INSIDE; info1.Position = new Vector3(p.X, p.Y, z); info1.TexCoord = t; info1.EdgeIndex = tempCollisionsEdgeIndices[0]; } } } } } } if (info0.Type == CollisionType.CT_NONE) continue; //Create new triangles, if we have two points of intersection, and they are not vertices int pi1 = 0, pi0 = 0; if (info1.Type != CollisionType.CT_NONE && (info0.Type != CollisionType.CT_VERTEX || info1.Type != CollisionType.CT_VERTEX )) { if (info1.Type == CollisionType.CT_VERTEX || (info1.Type == CollisionType.CT_EDGE && info0.Type == CollisionType.CT_INSIDE) || (info1.Type == CollisionType.CT_EDGE && info0.Type == CollisionType.CT_EDGE && (info0.EdgeIndex + 1) % 3 != info1.EdgeIndex) || (info0.Type == CollisionType.CT_INSIDE && info1.Type == CollisionType.CT_INSIDE && (info0.EdgeIndex + 1) % 3 != info1.EdgeIndex)) { var temp = info1; info1 = info0; info0 = temp; } if (!verticesDictionary.TryGetValue(info1.Position, out pi1)) { pi1 = vertices.Count; vertices.Add(info1.Position); texCoords.Add(info1.TexCoord); verticesDictionary.Add(info1.Position, pi1); } if (info0.Type == CollisionType.CT_VERTEX) //One point of intersection coincides with the vertex { pi0 = info0.PointIndex; int i0 = workedIndices[index], i1 = workedIndices[index + 1], i2 = workedIndices[index + 2]; if (i0 == info0.PointIndex) { i0 = i2; i2 = i1; } else { if (i2 == info0.PointIndex) { i2 = i0; i0 = i1; } } i1 = info0.PointIndex; newTriangles.AddRange(new[] { i0, i1, pi1, i1, i2, pi1 }); if (info1.Type == CollisionType.CT_INSIDE) //The second point inside the triangle newTriangles.AddRange(new[] { i2, i0, pi1 }); } else { if (!verticesDictionary.TryGetValue(info0.Position, out pi0)) { pi0 = vertices.Count; vertices.Add(info0.Position); texCoords.Add(info0.TexCoord); verticesDictionary.Add(info0.Position, pi0); } if (info1.Type != info0.Type) //One point crosses the brink, the second inside the triangle { var prev = info0.EdgeIndex == 0 ? 2 : info0.EdgeIndex - 1; prev = workedIndices[index + prev]; var next = info0.EdgeIndex == 2 ? 0 : info0.EdgeIndex + 1; next = workedIndices[index + next]; var curr = workedIndices[index + info0.EdgeIndex]; newTriangles.AddRange(new[] { prev, curr, pi1, curr, pi0, pi1, pi0, next, pi1, next, prev, pi1 }); } else { var c0 = workedIndices[index + info0.EdgeIndex]; var c1 = workedIndices[index + info1.EdgeIndex]; var c2 = workedIndices[index + ((info1.EdgeIndex + 1) % 3)]; if (info0.Type == CollisionType.CT_EDGE) { newTriangles.AddRange(new[] { c0, pi0, pi1, pi0, c1, pi1, pi1, c2, c0 }); } else { newTriangles.AddRange(new[] { c0, c1, pi0, c1, pi1, pi0, c1, c2, pi1, c2, c0, pi1, c0, pi0, pi1}); } } } } int slicePointIndex; SlicePoint slicePoint; for (var l = 0; l < 2; l++) { if (l == 1 && info1.Type == CollisionType.CT_NONE) break; var position = l == 0 ? info0.Position.Xy : info1.Position.Xy; var pointIndex = l == 0 ? pi0 : pi1; if (!slicePointsDictionary.TryGetValue(position, out slicePointIndex)) { slicePoint = new SlicePoint { Coordinate = position }; slicePoint.Lines.Add(sliceLine); slicePoint.PreparePoint(); slicePointIndex = slicePoints.Count; slicePoints.Add(slicePoint); slicePointsDictionary.Add(position, slicePointIndex); } else slicePoint = slicePoints[slicePointIndex]; if (!slicePoint.Indices.Contains(pointIndex)) slicePoint.Indices.Add(pointIndex); } if (newTriangles.Count > 0) { for (var l = 0; l < 3; l++) workedIndices[index + l] = newTriangles[l]; newTriangles.RemoveRange(0, 3); workedIndices.InsertRange(index, newTriangles); var count = (newTriangles.Count / 3); j += count; trianglesCount += count; } } } for (var i = 0; i < workedIndices.Count / 3; i++) { var index = i * 3; var t = new Triangle(); for (var j = 0; j < 3; j++) t.Indices[j] = workedIndices[index + j]; triangles.Add(i, new TrianleConnections { Triangle = t }); } var ind = new List<int>(); var tempTriangle = new Triangle(); tempTriangle.Indices[1] = -1; foreach (var point in slicePoints) { point.PreparePoint(); foreach (var index in point.Indices) { ind.Clear(); ind.Add(index); tempTriangle.Indices[0] = index; //Duplicate the verticle several times for (var i = 1; i < point.Directions.Count; i++) { ind.Add(vertices.Count); vertices.Add(vertices[index]); texCoords.Add(texCoords[index]); } foreach (var t in triangles) { var tr = t.Value.Triangle; var id = Triangle.TriangleEquals(ref tempTriangle, ref tr); if (id > -1) { var center = (vertices[tr.Indices[0]].Xy + vertices[tr.Indices[1]].Xy + vertices[tr.Indices[2]].Xy) / 3.0f; var dir = (center - point.Coordinate).Normalized(); var angle = SlicePoint.GetAngle(ref dir); var ii = point.Directions.Count - 1; for (var j = 0; j < point.Directions.Count; j++) { if (angle < point.Directions[j]) break; ii = j; } tr.Indices[id] = ind[ii]; } } } } var invTransform = mesh.Transform * camera.ViewMatrix; invTransform.Invert(); for (var i = 0; i < vertices.Count; i++) { vertices[i] = Vector3.Transform(vertices[i], invTransform); } workedIndices.Clear(); foreach (var t in triangles) { foreach (var i in t.Value.Triangle.Indices) workedIndices.Add(i); } workedIndices.AddRange(tempIndices); triangleConnections.Clear(); triangles.Clear(); for (var i = 0; i < workedIndices.Count / 3; i++) { var index = i * 3; var t = new Triangle(); for (var j = 0; j < 3; j++) { t.Indices[j] = workedIndices[index + j]; List<int> l; if (!triangleConnections.TryGetValue(t.Indices[j], out l)) { l = new List<int>(); triangleConnections.Add(t.Indices[j], l); } l.Add(i); } triangles.Add(i, new TrianleConnections { Triangle = t }); } var mainMesh = true; while (triangles.Count > 0) { foundedTriangles.Clear(); FillTriangles(triangles.First().Key); if (mainMesh) { mesh.Create(vertices, texCoords, foundedTriangles, mesh.Material.DiffuseTextureMap, mesh.Material.TransparentTextureMap, mesh.TextureAngle, mesh.TextureSize); mainMesh = false; } else { var tmpMesh = new DynamicRenderMesh(MeshType.Hair); tmpMesh.Create(vertices, texCoords, foundedTriangles, mesh.Material.DiffuseTextureMap, mesh.Material.TransparentTextureMap, mesh.TextureAngle, mesh.TextureSize); tmpMesh.Transform = mesh.Transform; tmpMesh.Material.DiffuseColor = mesh.Material.DiffuseColor; tmpMesh.MeshAngle = mesh.MeshAngle; tmpMesh.MeshSize = mesh.MeshSize; var info = tmpMesh.GetMeshInfo(1.0f); var center = Vector3.Zero; var scale = PickingController.GetHairScale(ProgramCore.Project.ManType); foreach (var vert in info.Positions) { center.X += vert.X * scale; center.Y += vert.Y * scale; center.Z += vert.Z * scale; } center /= info.Positions.Count; tmpMesh.Position = center; ResultMeshes.Add(tmpMesh); } } }
private void LoadBodyMeshes(string daePath, Scene scene, Node node, AnimatedNode animationNode) { if (node.HasMeshes) { var vertexPositions = new List<float>(); var vertexNormals = new List<float>(); var vertexTextureCoordinates = new List<float>(); var vertexBoneIndices = new List<float>(); var vertexBoneWeights = new List<float>(); var indeces = new List<uint>(); var fi = new FileInfo(daePath); foreach (var index in node.MeshIndices) { var mesh = scene.Meshes[index]; var hasTexCoords = mesh.HasTextureCoords(0); vertexPositions.Clear(); vertexNormals.Clear(); vertexTextureCoordinates.Clear(); vertexBoneIndices.Clear(); vertexBoneWeights.Clear(); indeces.Clear(); for (var i = 0; i < mesh.VertexCount; i++) { var vector = mesh.Vertices[i]; vertexPositions.Add(vector.X); vertexPositions.Add(vector.Y); vertexPositions.Add(vector.Z); vector = mesh.HasNormals ? mesh.Normals[i] : ZERO_VECTRO3D; vertexNormals.Add(vector.X); vertexNormals.Add(vector.Y); vertexNormals.Add(vector.Z); vector = hasTexCoords ? mesh.GetTextureCoords(0)[i] : ZERO_VECTRO3D; vertexTextureCoordinates.Add(vector.X); vertexTextureCoordinates.Add(1.0f - vector.Y); vertexBoneIndices.AddRange(new[] { 0.0f, 0.0f, 0.0f, 0.0f }); vertexBoneWeights.AddRange(new[] { 0.0f, 0.0f, 0.0f, 0.0f }); } foreach (var face in mesh.Faces) { indeces.Add(face.Indices[0]); indeces.Add(face.Indices[1]); indeces.Add(face.Indices[2]); } if (mesh.HasBones) { foreach (var bone in mesh.Bones) { if (!bone.HasVertexWeights) continue; int boneIndex; if (bonesMapping.ContainsKey(bone.Name)) { boneIndex = bonesMapping[bone.Name]; } else { boneIndex = Bones.Count; var boneInfo = new BoneInfo { BoneOffset = FromMatrix(bone.OffsetMatrix), }; Bones.Add(boneInfo); bonesMapping.Add(bone.Name, boneIndex); } foreach (var weight in bone.VertexWeights) { var vi = (int)weight.VertexID * 4; for (var i = 0; i < 4; i++) { if (vertexBoneWeights[vi + i] == 0.0f) { vertexBoneIndices[vi + i] = boneIndex; vertexBoneWeights[vi + i] = weight.Weight; break; } } } } } var mtr = scene.Materials[mesh.MaterialIndex]; var texturePath = string.Empty; var transparentPath = string.Empty; if (mtr.GetTextureCount(TextureType.Diffuse) > 0) { var tex = mtr.GetTexture(TextureType.Diffuse, 0); texturePath = Path.Combine(fi.DirectoryName, tex.FilePath); transparentPath = Path.Combine(Path.GetDirectoryName(tex.FilePath), Path.GetFileNameWithoutExtension(tex.FilePath) + "_alpha" + Path.GetExtension(tex.FilePath)); transparentPath = File.Exists(transparentPath) ? transparentPath : string.Empty; } var renderMesh = new DynamicRenderMesh(MeshType.Head); if (renderMesh.Create(vertexPositions, vertexNormals, vertexTextureCoordinates, vertexBoneIndices, vertexBoneWeights, indeces, texturePath, transparentPath)) { renderMesh.Transform = FromMatrix(node.Transform); renderMesh.Material.DiffuseColor = new Vector4(mtr.ColorDiffuse.R, mtr.ColorDiffuse.G, mtr.ColorDiffuse.B, mtr.ColorDiffuse.A); BodyMeshes.Add(renderMesh); } } } var parentNode = animationNode; if (animationNode == null) { rootNode = new AnimatedNode(); parentNode = rootNode; } parentNode.Name = node.Name; parentNode.Transform = FromMatrix(node.Transform); for (var i = 0; i < node.ChildCount; i++) { var childNode = new AnimatedNode { Parent = parentNode }; LoadBodyMeshes(daePath, scene, node.Children[i], childNode); parentNode.Childs.Add(childNode); } }
/// <summary> Accessory file saved in program. Here is a few accessories devided by groups </summary> private List<DynamicRenderMesh> LoadSpecialAccessoryMesh(ObjItem objModel) { var result = new List<DynamicRenderMesh>(); foreach (var modelGroup in objModel.Groups) { var vertexPositions = new List<float>(); var vertexNormals = new List<float>(); var vertexTextureCoordinates = new List<float>(); var vertexBoneIndices = new List<float>(); var vertexBoneWeights = new List<float>(); var indeces = new List<uint>(); foreach (var face in modelGroup.Value.Faces) { if (face.Count == 3) { for (var i = 0; i < face.Count; i++) { var faceVertex = face[i]; ObjLoader.AppendObjTriangle(objModel, faceVertex, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); } } else if (face.Count == 4) { var faceVertex0 = face[0]; var faceVertex1 = face[1]; var faceVertex2 = face[2]; var faceVertex3 = face[3]; ObjLoader.AppendObjTriangle(objModel, faceVertex0, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex1, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex2, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex2, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex3, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex0, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); } } if (vertexPositions.Count == 0) continue; var renderMesh = new DynamicRenderMesh(MeshType.Accessory); if (renderMesh.Create(vertexPositions, vertexTextureCoordinates, vertexBoneIndices, vertexBoneWeights, indeces, string.Empty, string.Empty)) { renderMesh.Title = modelGroup.Key.Name == "default" ? string.Empty : modelGroup.Key.Name; renderMesh.Material.DiffuseColor = new Vector4(modelGroup.Key.DiffuseColor.X, modelGroup.Key.DiffuseColor.Y, modelGroup.Key.DiffuseColor.Z, modelGroup.Key.Transparency); if (!string.IsNullOrEmpty(modelGroup.Key.DiffuseTextureMap)) renderMesh.Material.DiffuseTextureMap = modelGroup.Key.DiffuseTextureMap; if (!string.IsNullOrEmpty(modelGroup.Key.TransparentTextureMap)) renderMesh.Material.TransparentTextureMap = modelGroup.Key.TransparentTextureMap; var center = Vector3.Zero; var count = vertexPositions.Count / 3; const float scale = 246f; for (var i = 0; i < count; i++) { center.X += vertexPositions[i * 3] * scale; center.Y += vertexPositions[i * 3 + 1] * scale; center.Z += vertexPositions[i * 3 + 2] * scale; } center /= count; renderMesh.Transform = Matrix4.CreateScale(scale); /* renderMesh.Transform[3, 0] = -center.X; renderMesh.Transform[3, 1] = -center.Y; renderMesh.Transform[3, 2] = -center.Z;*/ renderMesh.Position = center; AccesoryMeshes.Add(renderMesh); result.Add(renderMesh); } } return result; }
private List<DynamicRenderMesh> LoadHairMeshes(ObjItem objModel, ObjItem objModelNull, bool fromDragAndDrop, ManType manType, MeshType meshType) { var result = new List<DynamicRenderMesh>(); var vertexPositions = new List<float>(); var vertexNormals = new List<float>(); var vertexTextureCoordinates = new List<float>(); var vertexBoneIndices = new List<float>(); var vertexBoneWeights = new List<float>(); var indeces = new List<uint>(); var vertexPositionsNull = new List<float>(); var vertexNormalsNull = new List<float>(); var vertexTextureCoordinatesNull = new List<float>(); var vertexBoneIndicesNull = new List<float>(); var vertexBoneWeightsNull = new List<float>(); var indecesNull = new List<uint>(); var groupsNull = objModelNull == null ? new Dictionary<ObjMaterial, ObjGroup>.Enumerator() : objModelNull.Groups.GetEnumerator(); ObjGroup groupNull; foreach (var modelGroup in objModel.Groups) // one group - one mesh { vertexPositions.Clear(); vertexNormals.Clear(); vertexTextureCoordinates.Clear(); vertexBoneIndices.Clear(); vertexBoneWeights.Clear(); indeces.Clear(); foreach (var face in modelGroup.Value.Faces) // combine all meshes in group - to one mesh. GetObjFace(face, objModel, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); var renderMesh = new DynamicRenderMesh(meshType); renderMesh.groupName = modelGroup.Value.Name; if (!objModel.modelByHeadShop) { for (var i = 0; i < vertexPositions.Count / 3; i++) vertexPositions[i * 3 + 1] = vertexPositions[i * 3 + 1] - 0.0060975609f; } ProgramCore.EchoToLog(String.Format("RenderMesh: {0}", modelGroup.Value.Name), EchoMessageType.Information); ProgramCore.EchoToLog( String.Format("renderMesh.Create: {0}, {1}, {2}, {3}, {4}", vertexPositions.Count, vertexTextureCoordinates.Count, vertexBoneIndices.Count, vertexBoneWeights.Count, indeces.Count), EchoMessageType.Information); if (renderMesh.Create(vertexPositions, vertexTextureCoordinates, vertexBoneIndices, vertexBoneWeights, indeces, string.Empty, string.Empty)) { if (objModelNull != null) { groupsNull.MoveNext(); groupNull = groupsNull.Current.Value; vertexPositionsNull.Clear(); vertexNormalsNull.Clear(); vertexTextureCoordinatesNull.Clear(); vertexBoneWeightsNull.Clear(); vertexBoneIndicesNull.Clear(); indecesNull.Clear(); foreach (var face in groupNull.Faces) { GetObjFace(face, objModelNull, ref vertexPositionsNull, ref vertexNormalsNull, ref vertexTextureCoordinatesNull, ref vertexBoneWeightsNull, ref vertexBoneIndicesNull, ref indecesNull); } renderMesh.SetNullPoints(vertexPositionsNull, vertexNormalsNull, vertexTextureCoordinatesNull); } renderMesh.Title = modelGroup.Key.Name == "default" ? string.Empty : modelGroup.Key.Name; renderMesh.Material = modelGroup.Key; renderMesh.Material.DiffuseColor = new Vector4(modelGroup.Key.DiffuseColor.X, modelGroup.Key.DiffuseColor.Y, modelGroup.Key.DiffuseColor.Z, modelGroup.Key.Transparency); if (!string.IsNullOrEmpty(modelGroup.Key.DiffuseTextureMap)) renderMesh.Material.DiffuseTextureMap = modelGroup.Key.DiffuseTextureMap; if (!string.IsNullOrEmpty(modelGroup.Key.TransparentTextureMap)) renderMesh.Material.TransparentTextureMap = modelGroup.Key.TransparentTextureMap; var scale = meshType == MeshType.Head ? GetHeadScale(manType) : GetHairScale(manType); // перегруз сделан потому, что на этапе загрузки проекта самого проекта еще может не быть. поэтому лучше передавать renderMesh.Transform = Matrix4.CreateScale(scale); var center = Vector3.Zero; var count = vertexPositions.Count / 3; for (var i = 0; i < count; i++) { center.X += vertexPositions[i * 3] * scale; center.Y += vertexPositions[i * 3 + 1] * scale; center.Z += vertexPositions[i * 3 + 2] * scale; } if (fromDragAndDrop) { center /= count; renderMesh.Transform = Matrix4.CreateScale(scale); renderMesh.Transform[3, 0] = -center.X; renderMesh.Transform[3, 1] = -center.Y; renderMesh.Transform[3, 2] = -center.Z; renderMesh.Position = center; } if (vertexTextureCoordinates.Count > 0 && vertexTextureCoordinates.All(x => x == 0)) renderMesh.UpdateTextureCoordinates(0, 1); if (renderMesh.vertexArray.Length > 0) result.Add(renderMesh); } } return result; }
/// <summary> Accessory file by default. Usually here is one accessory devided for differen groups. But it's not correct, so we combine it to one mesh</summary> public static DynamicRenderMesh LoadAccessoryMesh(ObjItem objModel) { var vertexPositions = new List <float>(); var vertexNormals = new List <float>(); var vertexTextureCoordinates = new List <float>(); var vertexBoneIndices = new List <float>(); var vertexBoneWeights = new List <float>(); var indeces = new List <uint>(); var defaultMaterial = default(ObjMaterial); foreach (var modelGroup in objModel.Groups) { defaultMaterial = modelGroup.Key; foreach (var face in modelGroup.Value.Faces) { if (face.Count == 3) { for (var i = 0; i < face.Count; i++) { var faceVertex = face[i]; ObjLoader.AppendObjTriangle(objModel, faceVertex, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); } } else if (face.Count == 4) { var faceVertex0 = face[0]; var faceVertex1 = face[1]; var faceVertex2 = face[2]; var faceVertex3 = face[3]; ObjLoader.AppendObjTriangle(objModel, faceVertex0, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex1, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex2, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex2, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex3, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); ObjLoader.AppendObjTriangle(objModel, faceVertex0, ref vertexPositions, ref vertexNormals, ref vertexTextureCoordinates, ref vertexBoneWeights, ref vertexBoneIndices, ref indeces); } } } var renderMesh = new DynamicRenderMesh(MeshType.Accessory); if (renderMesh.Create(vertexPositions, vertexTextureCoordinates, vertexBoneIndices, vertexBoneWeights, indeces, string.Empty, string.Empty)) { renderMesh.Material.DiffuseColor = new Vector4(defaultMaterial.DiffuseColor.X, defaultMaterial.DiffuseColor.Y, defaultMaterial.DiffuseColor.Z, defaultMaterial.Transparency); if (!string.IsNullOrEmpty(defaultMaterial.DiffuseTextureMap)) { renderMesh.Material.DiffuseTextureMap = defaultMaterial.DiffuseTextureMap; } if (!string.IsNullOrEmpty(defaultMaterial.TransparentTextureMap)) { renderMesh.Material.TransparentTextureMap = defaultMaterial.TransparentTextureMap; } var center = Vector3.Zero; var count = vertexPositions.Count / 3; float scale = 246f; #if WEB_APP scale *= ProgramCore.Project.RenderMainHelper.headMeshesController.RenderMesh.MorphScale; #endif for (var i = 0; i < count; i++) { center.X += vertexPositions[i * 3] * scale; center.Y += vertexPositions[i * 3 + 1] * scale; center.Z += vertexPositions[i * 3 + 2] * scale; } center /= count; renderMesh.Transform = Matrix4.CreateScale(scale); renderMesh.Transform[3, 0] = -center.X; renderMesh.Transform[3, 1] = -center.Y; renderMesh.Transform[3, 2] = -center.Z; renderMesh.Position = center; } return(renderMesh); }