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 by default. Usually here is one accessory devided for differen groups. But it's not correct, so we combine it to one mesh</summary> private 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; 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); } return(renderMesh); }
public List <DynamicRenderMesh> AddMehes(string path, MeshType type, bool fromDragAndDrop, ManType manType, string animationPath, bool needExporter) { var result = new List <DynamicRenderMesh>(); var objModel = ObjLoader.LoadObjFile(path, needExporter); if (objModel == null) { ProgramCore.EchoToLog(string.Format("Can't load obj model '{0}'", path), EchoMessageType.Error); return(result); } switch (type) { case MeshType.Hair: { var fi = new FileInfo(path); var objModelNull = ObjLoader.LoadObjFile(Path.Combine(fi.DirectoryName, fi.Name.Replace(fi.Extension, string.Format("_null{0}", fi.Extension)))); if (objModelNull != null && (objModelNull.Groups.Count != objModel.Groups.Count || objModel.Vertices.Count != objModelNull.Vertices.Count)) { // objModel.TextureCoords.Count != objModelNull.TextureCoords.Count)) objModelNull = null; } result = LoadHairMeshes(objModel, objModelNull, fromDragAndDrop, manType, MeshType.Hair); foreach (var renderMesh in result) { HairMeshes.Add(renderMesh); } break; } case MeshType.Accessory: return(objModel.accessoryByHeadShop ? LoadSpecialAccessoryMesh(objModel) : new List <DynamicRenderMesh> { LoadAccessoryMesh(objModel) }); case MeshType.Head: { var tempPluginTexture = string.Empty; if (ProgramCore.PluginMode) { var folderPath = Path.Combine(Application.StartupPath, "Models\\Model", manType.GetObjDirPath()); switch (ProgramCore.Project.ManType) { case ManType.Male: tempPluginTexture = Path.Combine(folderPath, "Maps", "RyNevio_faceB.jpg"); break; case ManType.Female: tempPluginTexture = Path.Combine(folderPath, "Maps", "RyBelle_face.jpg"); break; case ManType.Child: tempPluginTexture = Path.Combine(folderPath, "Maps", "AC_KidsRRHBy.jpg"); break; default: tempPluginTexture = Path.Combine(Application.StartupPath, "Plugin", "fsRndColor.png"); break; } } foreach (var mesh in HeadMeshes) { mesh.Destroy(); } HeadMeshes.Clear(); var objModelFull = animationPath == string.Empty ? null : ObjLoader.LoadObjFile(animationPath); if (objModelFull != null && (objModelFull.Groups.Count != objModel.Groups.Count || objModel.Vertices.Count != objModelFull.Vertices.Count || objModel.TextureCoords.Count != objModelFull.TextureCoords.Count)) { objModelFull = null; } LastTriangleIndex = 0; result = LoadHairMeshes(objModel, objModelFull, fromDragAndDrop, manType, MeshType.Head); var meshPartInfos = new List <MeshPartInfo>(); var a = new Vector3(99999.0f, 99999.0f, 99999.0f); var b = new Vector3(-99999.0f, -99999.0f, -99999.0f); foreach (var renderMesh in result) { HeadMeshes.Add(renderMesh); if (ProgramCore.PluginMode && ProgramCore.MainForm.PluginUvGroups.Contains(renderMesh.Material.Name)) { if (string.IsNullOrEmpty(renderMesh.Material.DiffuseTextureMap)) { renderMesh.Material.DiffuseTextureMap = tempPluginTexture; } else if (!File.Exists(renderMesh.Material.DiffuseTextureMap)) { renderMesh.Material.DiffuseTextureMap = tempPluginTexture; } } var meshPartInfo = new MeshPartInfo { VertexPositions = renderMesh.GetVertices(), TextureCoords = renderMesh.GetTexCoords(), PartName = renderMesh.Title, Color = renderMesh.Material.DiffuseColor, Texture = renderMesh.Material.Texture, TransparentTexture = renderMesh.Material.TransparentTexture, TextureName = renderMesh.Material.DiffuseTextureMap, TransparentTextureName = renderMesh.Material.TransparentTextureMap }; // создаем инфу о голове. для работы с headshop GetAABB(ref a, ref b, meshPartInfo.VertexPositions); meshPartInfos.Add(meshPartInfo); } Vector3 dv = Vector3.Zero; foreach (var meshPartInfo in meshPartInfos) { dv = MoveToPosition(ref meshPartInfo.VertexPositions, a, b, Vector3.Zero); ProgramCore.MainForm.ctrlRenderControl.headMeshesController.CreateMeshPart(meshPartInfo); } ObjExport = objModel.ObjExport; if (ObjExport != null) { ObjExport.Delta = -dv; } ProgramCore.MainForm.ctrlRenderControl.headMeshesController.FinishCreating(); // ProgramCore.MainForm.ctrlRenderControl.headMeshesController.InitializeTexturing(HeadController.GetDots(ProgramCore.Project.ManType), HeadController.GetIndices(ProgramCore.Project.ManType)); break; } default: return(result); } return(result); }
public void UpdateSelectedFace(int x, int y) { var selectedId = -1; var viewport = new int[4]; var selectBuffer = new uint[BufferSize * 4]; GL.SelectBuffer(BufferSize * 4, selectBuffer); GL.RenderMode(RenderingMode.Select); GL.InitNames(); GL.PushName(-0x01); GL.MatrixMode(MatrixMode.Projection); GL.PushMatrix(); GL.GetInteger(GetPName.Viewport, viewport); var doubleArray = new double[16]; GL.GetDouble(GetPName.ProjectionMatrix, doubleArray); GL.LoadIdentity(); PickMatrix(x, viewport[3] - y, 0.001f, 0.001f, viewport); GL.MultMatrix(doubleArray); camera.PutCamera(); GL.PushMatrix(); GL.Enable(EnableCap.DepthTest); var name = 0; foreach (var mesh in HairMeshes) { if (!mesh.IsVisible) { ++name; continue; } GL.LoadName(++name); GL.PushMatrix(); GL.MultMatrix(ref mesh.Transform); mesh.SimpleDraw(); GL.PopMatrix(); } name = 99999; foreach (var mesh in AccesoryMeshes) { if (!mesh.IsVisible) { ++name; continue; } GL.LoadName(++name); GL.PushMatrix(); GL.MultMatrix(ref mesh.Transform); mesh.SimpleDraw(); GL.PopMatrix(); } GL.PopMatrix(); GL.Flush(); GL.MatrixMode(MatrixMode.Projection); GL.PopMatrix(); GL.MatrixMode(MatrixMode.Modelview); GL.Flush(); var hits = GL.RenderMode(RenderingMode.Render); var closest = uint.MaxValue; for (var i = 0; i < hits; i++) { var distance = selectBuffer[i * 4 + 1]; if (closest >= distance) { closest = distance; selectedId = (int)selectBuffer[i * 4 + 3]; } } if (selectedId > 0) { if (selectedId >= 100000) { SelectedMeshes.Clear(); var mesh = AccesoryMeshes[selectedId - 100000]; SelectedMeshes.Add(mesh); } else { if (SelectedMeshes.Any(z => z.meshType == MeshType.Accessory)) { SelectedMeshes.Clear(); } var mesh = HairMeshes[selectedId - 1]; if (!SelectedMeshes.Contains(mesh)) { SelectedMeshes.Add(mesh); } else { SetPointColor(mesh); SelectedMeshes.Remove(mesh); } } } else { SelectedMeshes.Clear(); } }
internal void SaveSelectedHairToPartsLibrary() { if (pickingController.SelectedMeshes.Count == 0) return; if (pickingController.SelectedMeshes.All(x => x.meshType != MeshType.Hair)) return; pickingController.SelectedMeshes[0].AttachMeshes(pickingController.SelectedMeshes); var firstMesh = pickingController.SelectedMeshes.First(); pickingController.SelectedMeshes.RemoveAt(0); DeleteSelectedHair(); pickingController.SelectedMeshes.Add(firstMesh); using (var sfd = new SaveFileDialogEx("Save part", "OBJ files|*.obj")) { if (sfd.ShowDialog() != DialogResult.OK) return; var meshes = new DynamicRenderMeshes(); foreach (var mesh in pickingController.SelectedMeshes) meshes.Add(mesh); pickingController.SelectedMeshes.Clear(); ObjSaver.SaveObjFile(sfd.FileName, meshes, MeshType.Hair, headMeshesController.RenderMesh.RealScale); var fileName = Path.GetFileNameWithoutExtension(sfd.FileName); var title = fileName; var index = 0; while (PartsLibraryMeshes.ContainsKey(title)) // prevent duplicated names, because it's not occure save correct to obj { title = fileName + "_" + index; ++index; } if (!PartsLibraryMeshes.ContainsKey(title)) PartsLibraryMeshes.Add(title, new DynamicRenderMeshes()); for (var i = 0; i < meshes.Count; i++) { var mesh = meshes[i]; mesh.Title = title + "_" + i; if (!PartsLibraryMeshes[title].Contains(mesh)) PartsLibraryMeshes[title].Add(mesh); } ProgramCore.MainForm.frmParts.UpdateList(); } }
public List <DynamicRenderMesh> AddMehes(string path, MeshType type, bool fromDragAndDrop, GenesisType genesisType, ManType manType, string animationPath, bool needExporter, bool isOpenSmile) { var result = new List <DynamicRenderMesh>(); var objModel = ObjLoader.LoadObjFile(path, needExporter, isOpenSmile); if (objModel == null) { ProgramCore.EchoToLog($"Can't load obj model '{path}'", EchoMessageType.Error); return(result); } var lastTriangle = 0; switch (type) { case MeshType.Hair: { var fi = new FileInfo(path); var objModelNull = ObjLoader.LoadObjFile(Path.Combine(fi.DirectoryName, fi.Name.Replace(fi.Extension, string.Format("_null{0}", fi.Extension))), isOpenSmile); if (objModelNull != null && (objModelNull.Groups.Count != objModel.Groups.Count || objModel.Vertices.Count != objModelNull.Vertices.Count)) { // objModel.TextureCoords.Count != objModelNull.TextureCoords.Count)) objModelNull = null; } result = LoadHairMeshes(objModel, objModelNull, fromDragAndDrop, manType, MeshType.Hair, ref lastTriangle); foreach (var renderMesh in result) { HairMeshes.Add(renderMesh); } break; } case MeshType.Accessory: if (objModel.accessoryByHeadShop) { result.AddRange(LoadSpecialAccessoryMesh(objModel)); } else { var accessories = new List <DynamicRenderMesh> { LoadAccessoryMesh(objModel) }; foreach (var accessory in accessories) { AccesoryMeshes.Add(accessory); } result.AddRange(accessories); } break; case MeshType.Head: { var tempPluginTexture = string.Empty; var topPoint = 11.98351f; int tempPluginTextureIndex = 0; if (ProgramCore.PluginMode) { var folderPath = Path.Combine(Application.StartupPath, "Models", "Model", genesisType.GetGenesisPath(), manType.GetObjDirPath(isOpenSmile)); switch (ProgramCore.Project.ManType) { case ManType.Male: switch (ProgramCore.Project.GenesisType) { case GenesisType.Genesis2: tempPluginTexture = Path.Combine(folderPath, "Maps", "RyNevio_faceB.jpg"); break; case GenesisType.Genesis3: tempPluginTexture = Path.Combine(folderPath, "Maps", "RyEddie_face_1001.jpg"); break; case GenesisType.Genesis8: tempPluginTexture = Path.Combine(folderPath, "Maps", "G8MBaseFaceMapD01_1001.jpg"); break; } break; case ManType.Female: switch (ProgramCore.Project.GenesisType) { case GenesisType.Genesis2: tempPluginTexture = Path.Combine(folderPath, "Maps", "V5BreeHeadM.jpg"); break; case GenesisType.Genesis3: tempPluginTexture = Path.Combine(folderPath, "Maps", "RyJeane_face_1001.jpg"); break; case GenesisType.Genesis8: tempPluginTexture = Path.Combine(folderPath, "Maps", "G8FBaseFaceMapD_1001.jpg"); break; } break; case ManType.Child: tempPluginTexture = Path.Combine(folderPath, "Maps", "AC_KidsRRHBy.jpg"); break; default: tempPluginTexture = Path.Combine(Application.StartupPath, "Plugin", "fsRndColor.png"); break; } tempPluginTextureIndex = ProgramCore.MainForm.ctrlRenderControl.GetTexture(tempPluginTexture); } float scale = 1.0f; switch (ProgramCore.Project.ManType) { case ManType.Male: topPoint = 11.98351f; break; case ManType.Female: topPoint = 11.61f; break; case ManType.Child: //scale = 0.85f; topPoint = 9.759598f; break; } var objModelFull = animationPath == string.Empty ? null : ObjLoader.LoadObjFile(animationPath, isOpenSmile); if (objModelFull != null && (objModelFull.Groups.Count != objModel.Groups.Count || objModel.Vertices.Count != objModelFull.Vertices.Count || objModel.TextureCoords.Count != objModelFull.TextureCoords.Count)) { objModelFull = null; } var meshPartInfos = LoadHeadMeshes(objModel, fromDragAndDrop, manType, scale, ref lastTriangle); ObjExport = objModel.ObjExport; //if (ProgramCore.PluginMode) { ObjExport.DefaultA = new Vector3(99999.0f, 99999.0f, 99999.0f); ObjExport.DefaultB = new Vector3(-99999.0f, -99999.0f, -99999.0f); foreach (var meshPartInfo in meshPartInfos) { GetAABB(ref ObjExport.DefaultA, ref ObjExport.DefaultB, meshPartInfo.VertexPositions); } } if (ProgramCore.PluginMode && isOpenSmile) { PluginMorphToSmile(meshPartInfos, genesisType, manType, scale); } //result = LoadHairMeshes(objModel, objModelFull, fromDragAndDrop, manType, MeshType.Head); //var meshPartInfos = new List<MeshPartInfo>(); var a = new Vector3(99999.0f, 99999.0f, 99999.0f); var b = new Vector3(-99999.0f, -99999.0f, -99999.0f); foreach (var meshPartInfo in meshPartInfos) { if (ProgramCore.PluginMode && ProgramCore.MainForm.PluginUvGroups.Contains(meshPartInfo.MaterialName)) { if (string.IsNullOrEmpty(meshPartInfo.TextureName) || !File.Exists(meshPartInfo.TextureName)) { meshPartInfo.TextureName = tempPluginTexture; meshPartInfo.Texture = tempPluginTextureIndex; } } GetAABB(ref a, ref b, meshPartInfo.VertexPositions); } var dv = Vector3.Zero; foreach (var meshPartInfo in meshPartInfos) { // ПОТЕНЦИАЛЬНО ОПАСНОЕ МЕСТО! В случае улетания башки - AlignByTOp сделать для всех, кроме плагина. Для него оставить MoveToPosition #if (WEB_APP) dv = AlignByTop(ref meshPartInfo.VertexPositions, a, b, topPoint); #else dv = MoveToPosition(ref meshPartInfo.VertexPositions, a, b, Vector3.Zero); #endif ProgramCore.Project.RenderMainHelper.headMeshesController.CreateMeshPart(ProgramCore.Project.GenesisType, meshPartInfo); } if (ObjExport != null) { ObjExport.Delta = -dv; } ProgramCore.Project.RenderMainHelper.headMeshesController.FinishCreating(); return(null); // ProgramCore.Project.RenderMainHelper.headMeshesController.InitializeTexturing(HeadController.GetDots(ProgramCore.Project.ManType), HeadController.GetIndices(ProgramCore.Project.ManType)); } default: return(result); } foreach (var item in result) { item.Path = path; } return(result); }