public Dictionary <Guid, PartMorphInfo> LoadPartsMorphInfo(string path, RenderMesh renderMesh) { var vertexPositions = new List <float>(); List <float> tmp = null; List <uint> uitmp = null; var vertices = new List <Vector3>(); var objModel = ObjLoader.LoadObjFile(path); if (objModel == null) { ProgramCore.EchoToLog(string.Format("Can't load obj model '{0}'", path), EchoMessageType.Error); return(null); } var a = new Vector3(99999.0f, 99999.0f, 99999.0f); var b = new Vector3(-99999.0f, -99999.0f, -99999.0f); var result = new Dictionary <Guid, PartMorphInfo>(); foreach (var modelGroup in objModel.Groups) // one group - one mesh { vertexPositions.Clear(); foreach (var face in modelGroup.Value.Faces) // combine all meshes in group - to one mesh. { GetObjFace(face, objModel, ref vertexPositions, ref tmp, ref tmp, ref tmp, ref tmp, ref uitmp); } vertices.Clear(); for (int i = 0; i < vertexPositions.Count; i += 3) { vertices.Add(new Vector3(vertexPositions[i], vertexPositions[i + 1], vertexPositions[i + 2])); } PartMorphInfo morphInfo = null; float scale = ProgramCore.PluginMode && ProgramCore.MainForm.ctrlRenderControl.pickingController.ObjExport != null ? ProgramCore.MainForm.ctrlRenderControl.pickingController.ObjExport.Scale : 1.0f; var part = renderMesh.Parts.FirstOrDefault( p => (p.Name.ToLower().Contains(modelGroup.Value.Name.ToLower()) || modelGroup.Value.Name.ToLower().Contains(p.Name.ToLower())) && PartMorphInfo.CreatePartMorphInfo(vertices, p, scale, out morphInfo)); if (part != null) { result.Add(part.Guid, morphInfo); GetAABB(ref a, ref b, vertices); } } foreach (var r in result) { MoveToPosition(ref r.Value.PointsMorph, a, b, Vector3.Zero); } return(result); }
//private void UpdateFaceRect() //{ // var indicies = ProgramCore.Project.RenderMainHelper.headController.GetFaceIndexes(); // List<MirroredHeadPoint> faceDots; // switch (ProgramCore.MainForm.ctrlRenderControl.Mode) // { // // case Mode.HeadShapedots: // case Mode.HeadLine: // case Mode.HeadShapeFirstTime: // case Mode.HeadShape: // faceDots = ProgramCore.Project.RenderMainHelper.headController.GetSpecialShapedots(indicies); // break; // default: // faceDots = ProgramCore.Project.RenderMainHelper.headController.GetSpecialAutodots(indicies); // break; // } // if (faceDots.Count == 0) // return; // { // var minX1 = faceDots.Min(point => point.ValueMirrored.X); // var maxX1 = faceDots.Max(point => point.ValueMirrored.X); // var minY1 = faceDots.Min(point => point.ValueMirrored.Y); // var maxY1 = faceDots.Max(point => point.ValueMirrored.Y); // var rrr = new RectangleF((float)minX1, (float)minY1, (float)(maxX1 - minX1), (float)(maxY1 - minY1)); // } // var minX = faceDots.Min(point => point.ValueMirrored.X) * ImageTemplateWidth + ImageTemplateOffsetX; // var maxX = faceDots.Max(point => point.ValueMirrored.X) * ImageTemplateWidth + ImageTemplateOffsetX; // var minY = faceDots.Min(point => point.ValueMirrored.Y) * ImageTemplateHeight + ImageTemplateOffsetY; // var maxY = faceDots.Max(point => point.ValueMirrored.Y) * ImageTemplateHeight + ImageTemplateOffsetY; // FaceRectTransformed = new Rectangle((int)minX, (int)minY, (int)(maxX - minX), (int)(maxY - minY)); // CentralFacePoint = new Vector2(minX + (maxX - minX) * 0.5f, minY + (maxY - minY) / 3f); //} //private void RecalcUserCenters() //{ // MouthTransformed = new Vector2(ProgramCore.Project.MouthUserCenter.X * ImageTemplateWidth + ImageTemplateOffsetX, // ProgramCore.Project.MouthUserCenter.Y * ImageTemplateHeight + ImageTemplateOffsetY); // LeftEyeTransformed = new Vector2(ProgramCore.Project.LeftEyeUserCenter.X * ImageTemplateWidth + ImageTemplateOffsetX, // ProgramCore.Project.LeftEyeUserCenter.Y * ImageTemplateHeight + ImageTemplateOffsetY); // RightEyeTransformed = new Vector2(ProgramCore.Project.RightEyeUserCenter.X * ImageTemplateWidth + ImageTemplateOffsetX, // ProgramCore.Project.RightEyeUserCenter.Y * ImageTemplateHeight + ImageTemplateOffsetY); // NoseTransformed = new Vector2(ProgramCore.Project.NoseUserCenter.X * ImageTemplateWidth + ImageTemplateOffsetX, // ProgramCore.Project.NoseUserCenter.Y * ImageTemplateHeight + ImageTemplateOffsetY); //} public void AttachHair(string hairObjPath, string materialPath, ManType manType) { var objModel = ObjLoader.LoadObjFile(hairObjPath, false); if (objModel == null) { return; } var temp = 0; var meshes = PickingController.LoadHairMeshes(objModel, null, true, manType, MeshType.Hair, ref temp); foreach (var mesh in meshes) { if (mesh == null || mesh.vertexArray.Length == 0) //ТУТ! { continue; } mesh.Material.DiffuseTextureMap = materialPath; } var objName = Path.GetFileNameWithoutExtension(hairObjPath); if (HairPositions.ContainsKey(objName)) { var meshSize = HairPositions[objName].Item2; var s = HairPositions[objName].Item1 * ProgramCore.Project.RenderMainHelper.headMeshesController.RenderMesh.MorphScale; // домножаем на 8 для веб версии. все на 8 домножаем! любим 8! for (var i = 0; i < meshes.Count; i++) { var mesh = meshes[i]; if (mesh == null || mesh.vertexArray.Length == 0) //ТУТ! { continue; } mesh.Position += new Vector3(s[0], s[1], s[2]); mesh.Transform[3, 0] += s[0]; mesh.Transform[3, 1] += s[1]; mesh.Transform[3, 2] += s[2]; if (!float.IsNaN(meshSize)) { mesh.InterpolateMesh(meshSize); } } } ProgramCore.Project.RenderMainHelper.pickingController.HairMeshes.Clear(); ProgramCore.Project.RenderMainHelper.pickingController.HairMeshes.AddRange(meshes); }
public void AttachAccessory(string accessoryObjPath, string accessoryMaterialPath, ManType manType) { var objModel = ObjLoader.LoadObjFile(accessoryObjPath, false); if (objModel == null) { return; } var mesh = PickingController.LoadAccessoryMesh(objModel); if (string.IsNullOrEmpty(accessoryMaterialPath)) { mesh.Material.DiffuseColor = new Vector4(0.5f, 0.4f, 0.3f, 1); } else { mesh.Material.DiffuseTextureMap = accessoryMaterialPath; } var objName = Path.GetFileNameWithoutExtension(accessoryObjPath); if (AccessoryPositions.ContainsKey(objName)) { var meshSize = AccessoryPositions[objName].Item2; var s = AccessoryPositions[objName].Item1 * ProgramCore.Project.RenderMainHelper.headMeshesController.RenderMesh.MorphScale; // домножаем на 8 для веб версии. все на 8 домножаем! любим 8! mesh.Position += new Vector3(s[0], s[1], s[2]); mesh.Transform[3, 0] += s[0]; mesh.Transform[3, 1] += s[1]; mesh.Transform[3, 2] += s[2]; if (!float.IsNaN(meshSize)) { mesh.Transform[3, 0] -= s[0]; // применяем изменение размера mesh.Transform[3, 1] -= s[1]; mesh.Transform[3, 2] -= s[2]; mesh.Transform *= Matrix4.CreateScale(meshSize / mesh.MeshSize); mesh.Transform[3, 0] += s[0]; mesh.Transform[3, 1] += s[1]; mesh.Transform[3, 2] += s[2]; mesh.IsChanged = true; mesh.MeshSize = meshSize; } } ProgramCore.Project.RenderMainHelper.pickingController.AccesoryMeshes.Add(mesh); }
public static RenderMesh LoadFromFile(string filePath) { var result = new RenderMesh(); var objData = ObjLoader.LoadObjFile(filePath); var lastTriangle = 0; var meshPartsInfo = LoadHeadMeshes(objData, 1.0f, ref lastTriangle); Vector3 A = new Vector3(99999.0f, 99999.0f, 99999.0f); Vector3 B = new Vector3(-99999.0f, -99999.0f, -99999.0f); foreach (var meshPartInfo in meshPartsInfo) { foreach (var p in meshPartInfo.VertexPositions) { A.X = Math.Min(A.X, p.X); A.Y = Math.Min(A.Y, p.Y); A.Z = Math.Min(A.Z, p.Z); B.X = Math.Max(B.X, p.X); B.Y = Math.Max(B.Y, p.Y); B.Z = Math.Max(B.Z, p.Z); } } Vector3 Center = (A + B) * 0.5f; foreach (var meshPartInfo in meshPartsInfo) { var meshPart = new MeshPart(); if (meshPart.Create(meshPartInfo, -Center)) { result.UpdateAABB(meshPart); result.Parts.Add(meshPart); } } foreach (var part in result.Parts) { part.UpdateBuffers(); } return(result); }
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); }
private void PluginMorphToSmile(List <MeshPartInfo> meshesInfo, GenesisType genesisType, ManType manType, float scale) { var lastTriangle = 0; var path = Path.Combine(Application.StartupPath, "Models", "Model", genesisType.GetGenesisPath(), manType.GetObjPathSmilePlugin()); var objModel = ObjLoader.LoadObjFile(path, true, true); var smileMeshes = LoadHeadMeshes(objModel, false, manType, scale, ref lastTriangle); /*var a0 = new Vector3(99999.0f, 99999.0f, 99999.0f); * var b0 = new Vector3(-99999.0f, -99999.0f, -99999.0f); * foreach (var meshPartInfo in meshesInfo) * { * GetAABB(ref a0, ref b0, meshPartInfo.VertexPositions); * } * var a1 = new Vector3(99999.0f, 99999.0f, 99999.0f); * var b1 = new Vector3(-99999.0f, -99999.0f, -99999.0f); * foreach (var meshPartInfo in smileMeshes) * { * GetAABB(ref a1, ref b1, meshPartInfo.VertexPositions); * } * var dist0 = (b0 - a0).Length; * var dist1 = (b1 - a1).Length; * var center0 = (b0 + a0) * 0.5f; * var center1 = (b1 + a1) * 0.5f;*/ float k = 265.4678407f; //! Вот это нужно подобрать //dist1 / dist0; float MaxY0 = -99999.0f; float MaxY1 = -99999.0f; foreach (var meshInfo in meshesInfo) { for (int i = 0; i < meshInfo.VertexPositions.Count; ++i) { MaxY0 = Math.Max(MaxY0, meshInfo.VertexPositions[i].Y); } } foreach (var meshInfo in meshesInfo) { var mesh = smileMeshes.FirstOrDefault(m => m.PartName == meshInfo.PartName); if (mesh.VertexPositions.Count == meshInfo.VertexPositions.Count) { for (int i = 0; i < mesh.VertexPositions.Count; ++i) { //meshInfo.VertexPositions[i] = center0 + (mesh.VertexPositions[i] - center1) * k; meshInfo.VertexPositions[i] = mesh.VertexPositions[i] / k; MaxY1 = Math.Max(MaxY1, meshInfo.VertexPositions[i].Y); } } } foreach (var meshInfo in meshesInfo) { for (int i = 0; i < meshInfo.VertexPositions.Count; ++i) { Vector3 v = meshInfo.VertexPositions[i]; v.Y += (MaxY0 - MaxY1); meshInfo.VertexPositions[i] = v; } } }
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); }