private TriangleEdge[] GetEdges(PMXTriangle tri) { return(new TriangleEdge[3] { new TriangleEdge(tri.Vertex1, tri.Vertex2, this._identicalLocation), new TriangleEdge(tri.Vertex2, tri.Vertex3, this._identicalLocation), new TriangleEdge(tri.Vertex3, tri.Vertex1, this._identicalLocation) }); }
private void ImportTrianglesToMaterial(PMXMaterial mat, int triCount, int triType) { for (int i = 0; i < triCount; i++) { PMXVertex vtx1 = null, vtx2 = null, vtx3 = null; if (triType == 0x05) { vtx1 = pmxModel.Vertices[(int)sp.ReadU16()]; vtx2 = pmxModel.Vertices[(int)sp.ReadU16()]; vtx3 = pmxModel.Vertices[(int)sp.ReadU16()]; } else { vtx1 = pmxModel.Vertices[sp.ReadS32()]; vtx2 = pmxModel.Vertices[sp.ReadS32()]; vtx3 = pmxModel.Vertices[sp.ReadS32()]; } PMXTriangle tri = new PMXTriangle(pmxModel, vtx1, vtx2, vtx3); mat.Triangles.Add(tri); } }
private bool IsTriangleConnected(PMXTriangle tri, HashSet <TriangleEdge> edgeList) { TriangleEdge[] edges = GetEdges(tri); bool found = false; foreach (TriangleEdge edg in edges) { if (edgeList.Contains(edg)) { found = true; break; } } if (found) { AddEdgesToList(edges, edgeList); return(true); } else { return(false); } }
private List <PMXMaterial> SplitTriangles(PMXMaterial mat) { int[] matIndex = new int[mat.Triangles.Count]; int i, j, mI; int addedTriangles; for (i = 0; i < matIndex.Length; i++) { matIndex[i] = -1; } mI = -1; int outInfo = 0; HashSet <TriangleEdge> edgesInPart; for (i = 0; i < matIndex.Length; i++) { int cIndex = matIndex[i]; if (cIndex >= 0) { continue; } if (i >= outInfo) { Console.WriteLine(i + " / " + matIndex.Length); while (i >= outInfo) { outInfo += 250; } } mI++; matIndex[i] = mI; edgesInPart = new HashSet <TriangleEdge>(); AddEdgesToList(GetEdges(mat.Triangles[i]), edgesInPart); do { addedTriangles = 0; for (j = i + 1; j < matIndex.Length; j++) { if (matIndex[j] >= 0) { continue; } PMXTriangle tri = mat.Triangles[j]; if (IsTriangleConnected(tri, edgesInPart)) { matIndex[j] = mI; addedTriangles++; } } } while (addedTriangles > 0); } List <PMXTriangle>[] triangleGroups = new List <PMXTriangle> [mI + 1]; for (i = 0; i <= mI; i++) { triangleGroups[i] = new List <PMXTriangle>(); } for (i = 0; i < matIndex.Length; i++) { PMXTriangle tri = mat.Triangles[i]; triangleGroups[matIndex[i]].Add(tri); } PMXMaterial restMaterial = new PMXMaterial(this._model); CopyMaterialSettings(mat, restMaterial); List <PMXMaterial> newMaterials = new List <PMXMaterial>(); int resIndex = 0; foreach (List <PMXTriangle> triangleGroup in triangleGroups) { if (triangleGroup.Count < 10 && this._ignoreSmallParts) { restMaterial.Triangles.AddRange(triangleGroup); continue; } resIndex++; PMXMaterial nm = new PMXMaterial(this._model); CopyMaterialSettings(mat, nm); nm.NameEN = nm.NameEN + " " + resIndex.ToString(); nm.NameJP = nm.NameJP + " " + resIndex.ToString(); nm.Triangles.AddRange(triangleGroup); newMaterials.Add(nm); } if (restMaterial.Triangles.Count > 0) { restMaterial.NameEN = restMaterial.NameEN + " Rest"; restMaterial.NameJP = restMaterial.NameJP + " Rest"; newMaterials.Add(restMaterial); } return(newMaterials); }
private void loadMeshs() { int i, j, k, l, m; int vtxIndex = 0; for (i = 0; i < this.mdlInfo.Count7; i++) { long vtxBase = this.vertBase + this.meshInfoList[i].vtxBufferStart; long idxBase = this.faceBase + this.meshInfoList[i].idxBufferStart; uint vtxStride = this.meshInfoList[i].vtxStride; //Console.WriteLine(vtxStride); uint matBase = this.meshInfoList[i].meshId; FvfInfo[] fvfInfo = this.fvfList[i]; this.fs.Seek(this.boneMapStart + this.meshInfoList[i].bonePalletStart * 2, SeekOrigin.Begin); List <ushort> bonePallet = new List <ushort>(); for (j = 0; j < this.meshInfoList[i].bonePalletCount; j++) { bonePallet.Add(br.ReadUInt16()); } for (j = 0; j < this.meshInfoList[i].meshCount; j++) { PMXMaterial mat = new PMXMaterial(this.pmx); mat.Diffuse.R = 0.77f; mat.Diffuse.G = 0.77f; mat.Diffuse.B = 0.77f; mat.Specular.R = 0.0f; mat.Specular.G = 0.0f; mat.Specular.B = 0.0f; mat.Ambient.R = 0.5f; mat.Ambient.G = 0.5f; mat.Ambient.B = 0.5f; mat.EdgeEnabled = false; mat.EdgeSize = 0.0f; mat.StandardToonIndex = 3; string meshname = this.matInfoList[i].MeshName; if (this.matNames != null && matNames.Count > 0) { meshname = this.matNames[(int)this.meshInfoList[i].matID] + "_" + i.ToString() + "_" + j.ToString(); } mat.NameJP = meshname; mat.NameEN = meshname; MaterialInfo matInfo = this.matInfoList[(int)(matBase + j)]; if (matInfo.Lod != 1 && matInfo.Lod != -1) { continue; } this.fs.Seek(idxBase, SeekOrigin.Begin); List <int> idxTmp = new List <int>(); for (l = 0; l < matInfo.FaceCount; l++) { if (meshInfoList[i].idxType == 2) { idxTmp.Add((int)(this.br.ReadUInt32() - matInfo.FaceStart)); } else { idxTmp.Add((int)(this.br.ReadUInt16() - matInfo.FaceStart)); } } idxBase = this.fs.Position; this.fs.Seek(vtxBase + vtxStride * matInfo.FaceStart, SeekOrigin.Begin); long vtxPosition = this.fs.Position; List <PMXVertex> vertices = new List <PMXVertex>(); for (k = 0; k < matInfo.VertCount; k++) { PMXVertex vtx = new PMXVertex(this.pmx); byte[] idx = new byte[4] { 0, 0, 0, 0 }; byte[] wgt = new byte[4] { 0, 0, 0, 0 }; for (l = 0; l < fvfInfo.Length; l++) { this.fs.Seek(vtxPosition + k * vtxStride + fvfInfo[l].fvfPos, SeekOrigin.Begin); switch (fvfInfo[l].compType) { case 0: vtx.Position.X = this.br.ReadSingle() * SCALE; vtx.Position.Y = this.br.ReadSingle() * SCALE; vtx.Position.Z = this.br.ReadSingle() * SCALE * (-1); break; case 2: vtx.Normals.X = this.br.ReadSingle(); vtx.Normals.Y = this.br.ReadSingle(); vtx.Normals.Z = this.br.ReadSingle() * (-1); break; case 8: vtx.UV.U = this.br.ReadSingle(); vtx.UV.V = this.br.ReadSingle(); break; case 7: for (m = 0; m < 4; m++) { idx[m] = this.br.ReadByte(); } break; case 1: for (m = 0; m < 4; m++) { wgt[m] = this.br.ReadByte(); } break; } } int totalWeight = 0; Dictionary <ushort, int> weights = new Dictionary <ushort, int>(); for (m = 0; m < 4; m++) { byte bi = idx[m]; if (bi >= bonePallet.Count) { continue; } ushort bni = bonePallet[bi]; int weight = 0; if (weights.ContainsKey(bni)) { weight = weights[bni]; } byte cw = wgt[m]; totalWeight += cw; weight += cw; weights[bni] = weight; } if (weights.Count == 1) { PMXVertexDeformBDEF1 b1 = new PMXVertexDeformBDEF1(this.pmx, vtx); b1.Bone1 = this.pmx.Bones[weights.Keys.First()]; vtx.Deform = b1; } else { List <KeyValuePair <ushort, int> > weightList = weights.ToList(); weightList.Sort(delegate(KeyValuePair <ushort, int> pair1, KeyValuePair <ushort, int> pair2) { return(pair2.Value.CompareTo(pair1.Value)); }); for (m = 3; m >= 1; m--) { if (weightList.Count > m && weightList[m].Value == 0) { weightList.RemoveAt(m); } } if (weightList.Count == 1) { PMXVertexDeformBDEF1 b1 = new PMXVertexDeformBDEF1(this.pmx, vtx); b1.Bone1 = this.pmx.Bones[weightList[0].Key]; vtx.Deform = b1; } else if (weightList.Count == 2) { PMXVertexDeformBDEF2 b2 = new PMXVertexDeformBDEF2(this.pmx, vtx); b2.Bone1 = this.pmx.Bones[weightList[0].Key]; b2.Bone1Weight = (float)weightList[0].Value / (float)totalWeight; b2.Bone2 = this.pmx.Bones[weightList[1].Key]; vtx.Deform = b2; } else if (weightList.Count > 2) { PMXVertexDeformBDEF4 b4 = new PMXVertexDeformBDEF4(this.pmx, vtx); b4.Bone1 = this.pmx.Bones[weightList[0].Key]; b4.Bone1Weight = (float)weightList[0].Value / (float)totalWeight; b4.Bone2 = this.pmx.Bones[weightList[1].Key]; b4.Bone2Weight = (float)weightList[1].Value / (float)totalWeight; b4.Bone3 = this.pmx.Bones[weightList[2].Key]; b4.Bone3Weight = (float)weightList[2].Value / (float)totalWeight; if (weightList.Count < 4) { b4.Bone4 = null; } else { b4.Bone4 = this.pmx.Bones[weightList[3].Key]; b4.Bone4Weight = (float)weightList[3].Value / (float)totalWeight; } vtx.Deform = b4; } else { //Most likely a prop! //Console.WriteLine("Weight error on " + this.inFile); if (pmx.Bones.Count == 0) { PMXBone mb = new PMXBone(pmx); mb.NameEN = "prop"; mb.NameJP = "prop"; mb.Position = new PMXVector3(0, 0, 0); mb.Translatable = true; pmx.Bones.Add(mb); } PMXVertexDeformBDEF1 b1 = new PMXVertexDeformBDEF1(this.pmx, vtx); b1.Bone1 = this.pmx.Bones[0]; vtx.Deform = b1; } } vertices.Add(vtx); this.pmx.Vertices.Add(vtx); vtxIndex++; } for (k = 0; k < idxTmp.Count; k += 3) { PMXTriangle tri = new PMXTriangle(this.pmx); tri.Vertex1 = vertices[idxTmp[k + 2]]; tri.Vertex2 = vertices[idxTmp[k + 1]]; tri.Vertex3 = vertices[idxTmp[k + 0]]; mat.Triangles.Add(tri); } this.pmx.Materials.Add(mat); } } this.totalVertCount = (uint)vtxIndex; if (this.mdlInfo.hasExp == 0) { this.WritePMX(); } else { this.CheckForVertexMorphs(); } }