public TriangleEdge(PMXVertex vtx1b, PMXVertex vtx2b, bool identicalLocation) { this._identicalLocation = identicalLocation; PMXExtendedVertex vtx1 = (PMXExtendedVertex)vtx1b; PMXExtendedVertex vtx2 = (PMXExtendedVertex)vtx2b; if (vtx1.EasySlashIndex < vtx2.EasySlashIndex) { this.Vertex1 = vtx1; this.Vertex2 = vtx2; } else { this.Vertex1 = vtx2; this.Vertex2 = vtx1; } if (!identicalLocation) { this._hashCode = ((~this.Vertex1.EasySlashIndex) ^ this.Vertex2.EasySlashIndex); } else { this._hashCode = (this.Vertex1.Position.X + this.Vertex1.Position.Y + this.Vertex1.Position.Z + this.Vertex2.Position.X + this.Vertex2.Position.Y + this.Vertex2.Position.Z).GetHashCode(); } }
public override bool Equals(object obj) { if (!(obj is PMXVertex)) { return(false); } PMXVertex vtx = (PMXVertex)obj; if (this.GetHashCode() != vtx.GetHashCode()) { return(false); } return ( this.Position.X == vtx.Position.X && this.Position.Y == vtx.Position.Y && this.Position.Z == vtx.Position.Z && this.Normals.X == vtx.Normals.X && this.Normals.Y == vtx.Normals.Y && this.Normals.Z == vtx.Normals.Z && this.UV.U == vtx.UV.U && this.UV.V == vtx.UV.V ); }
private static PMXVertex ReplaceVertexIfRequired(PMXVertex input, PMXModel md, int[] duplicateList) { int dupIndex = duplicateList[((PMXExtendedVertex)input).EasySlashIndex]; if (dupIndex >= 0) { return(md.Vertices[dupIndex]); } return(input); }
private static float DetermineWeight(PMXVertex v, List <PMXBone> checkBones) { Dictionary <PMXBone, float> weights = new Dictionary <PMXBone, float>(); float weightSum = 0.0f; if (v.Deform is PMXVertexDeformBDEF4) { PMXVertexDeformBDEF4 df4 = (PMXVertexDeformBDEF4)(v.Deform); AddWeightInternal(df4.Bone1, df4.Bone1Weight, weights, ref weightSum); AddWeightInternal(df4.Bone2, df4.Bone2Weight, weights, ref weightSum); AddWeightInternal(df4.Bone3, df4.Bone3Weight, weights, ref weightSum); AddWeightInternal(df4.Bone4, df4.Bone4Weight, weights, ref weightSum); } else if (v.Deform is PMXVertexDeformBDEF2) { PMXVertexDeformBDEF2 df2 = (PMXVertexDeformBDEF2)(v.Deform); AddWeightInternal(df2.Bone1, df2.Bone1Weight, weights, ref weightSum); AddWeightInternal(df2.Bone2, 1.0f - df2.Bone1Weight, weights, ref weightSum); } else { PMXVertexDeformBDEF1 df1 = (PMXVertexDeformBDEF1)(v.Deform); AddWeightInternal(df1.Bone1, 1.0f, weights, ref weightSum); } if (weights.Count == 0 || weightSum <= 0.0f) { return(0.0f); } float resWeight = 0.0f; foreach (PMXBone b in checkBones) { if (weights.ContainsKey(b)) { resWeight += weights[b]; } } if (resWeight > 1.0f) { return(1.0f); } else if (resWeight < 0.0f) { return(0.0f); } return(resWeight); }
private PMXVertex GetVertexOfIndex(ref int index) { PMXVertex vtx = null; if (pmxModel.Vertices.Count <= index) { vtx = new PMXExtendedVertex(pmxModel); pmxModel.Vertices.Add(vtx); } else { vtx = pmxModel.Vertices[index]; } index++; return(vtx); }
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); } }
static void MirrorX(PMXModel md) { foreach (PMXVertex vtx in md.Vertices) { vtx.Position.X *= -1.0f; vtx.Normals.X *= -1.0f; } foreach (PMXBone bn in md.Bones) { bn.Position.X *= -1.0f; } foreach (PMXMaterial mat in md.Materials) { foreach (PMXTriangle tri in mat.Triangles) { PMXVertex b1 = tri.Vertex1; tri.Vertex1 = tri.Vertex3; tri.Vertex3 = b1; } } }
public TriangleEdge(PMXVertex vtx1, PMXVertex vtx2) : this(vtx1, vtx2, false) { }
private void CreateDeform(PMXVertex vtx, int boneCount, int boneIndexSize, int floatLength) { PMXBone[] bones = new PMXBone[boneCount]; float[] weights = new float[boneCount]; for (int i = 0; i < boneCount; i++) { switch (boneIndexSize) { case 1: bones[i] = GetBoneByBoneId((int)sp.ReadU8()); break; case 2: bones[i] = GetBoneByBoneId((int)sp.ReadU16()); break; default: throw new Exception(); } } for (int i = 0; i < boneCount; i++) { switch (floatLength) { case 2: weights[i] = sp.ReadHalfFloat(); break; case 4: weights[i] = sp.ReadSingle(); break; default: throw new Exception(); } } List <BonePlusWeight> usableBones = new List <BonePlusWeight>(); for (int i = 0; i < boneCount; i++) { if (bones[i] != null) { usableBones.Add(new BonePlusWeight() { Bone = bones[i], Weight = weights[i] }); } } usableBones.Sort(); if (usableBones.Count == 1) { PMXVertexDeformBDEF1 df = new PMXVertexDeformBDEF1(pmxModel, vtx); df.Bone1 = usableBones[0].Bone; vtx.Deform = df; } else if (usableBones.Count == 2) { PMXVertexDeformBDEF2 df = new PMXVertexDeformBDEF2(pmxModel, vtx); df.Bone1 = usableBones[0].Bone; df.Bone2 = usableBones[1].Bone; df.Bone1Weight = (usableBones[0].Weight) / (usableBones[0].Weight + usableBones[1].Weight); vtx.Deform = df; } else if (usableBones.Count == 3) { PMXVertexDeformBDEF4 df = new PMXVertexDeformBDEF4(pmxModel, vtx); float totalWeight = usableBones[0].Weight + usableBones[1].Weight + usableBones[2].Weight; df.Bone1 = usableBones[0].Bone; df.Bone2 = usableBones[1].Bone; df.Bone3 = usableBones[2].Bone; df.Bone4 = null; df.Bone1Weight = (usableBones[0].Weight) / totalWeight; df.Bone2Weight = (usableBones[1].Weight) / totalWeight; df.Bone3Weight = (usableBones[2].Weight) / totalWeight; df.Bone4Weight = 0.0f; vtx.Deform = df; } else { PMXVertexDeformBDEF4 df = new PMXVertexDeformBDEF4(pmxModel, vtx); float totalWeight = usableBones[0].Weight + usableBones[1].Weight + usableBones[2].Weight + usableBones[3].Weight; df.Bone1 = usableBones[0].Bone; df.Bone2 = usableBones[1].Bone; df.Bone3 = usableBones[2].Bone; df.Bone4 = usableBones[3].Bone; df.Bone1Weight = (usableBones[0].Weight) / totalWeight; df.Bone2Weight = (usableBones[1].Weight) / totalWeight; df.Bone3Weight = (usableBones[2].Weight) / totalWeight; df.Bone4Weight = (usableBones[3].Weight) / totalWeight; vtx.Deform = df; } }
private void CheckForVertexMorphs() { int i, j, k, l; this.fs.Seek(this.fvfListEnd + 4, SeekOrigin.Begin); uint expCount = this.br.ReadUInt32(); uint affectedMeshes = this.br.ReadUInt32(); for (i = 0; i < expCount; i++) { string expName = this.br.ReadASCIINullTerminatedString(); PMXMorph morph = new PMXMorph(this.pmx); morph.NameEN = expName; morph.NameJP = expName; morph.Panel = PMXMorph.PanelType.Other; this.pmx.Morphs.Add(morph); } this.fs.Seek(expCount * 4, SeekOrigin.Current); float dx, dy, dz; for (i = 0; i < affectedMeshes; i++) { int meshId = this.br.ReadInt32(); this.fs.Seek(16, SeekOrigin.Current); //we only need the mesh id //Seems for these models meshId and matId is identical so let's just mix the info uint vtxStride = this.meshInfoList[i].vtxStride; uint vtxCount = this.matInfoList[i].VertCount; uint vtxOffset = 0; for (j = 0; j < meshId; j++) { vtxOffset += this.matInfoList[j].VertCount; } for (j = 0; j < expCount; j++) { for (k = 0; k < vtxCount; k++) { dx = this.br.ReadSingle() * SCALE; dy = this.br.ReadSingle() * SCALE; dz = this.br.ReadSingle() * SCALE * (-1); this.fs.Seek(vtxStride - 8, SeekOrigin.Current); if (dx != 0.0f || dy != 0.0f || dz != 0.0f) { PMXMorph m = this.pmx.Morphs[j]; PMXVertex v = this.pmx.Vertices[(int)(k + vtxOffset)]; PMXMorphOffsetVertex ov = new PMXMorphOffsetVertex(this.pmx, m); ov.Vertex = v; ov.Translation.X = dx; ov.Translation.Y = dy; ov.Translation.Z = dz; m.Offsets.Add(ov); } } } } /*PMXMorph morph = new PMXMorph(this.pmx); * morph.NameJP = expressionNames[0]; * morph.NameEN = expressionNames[0]; * * long offset = fs.Position - this.fvfListEnd; * * Console.WriteLine(expCount); * Console.WriteLine(totalVertCount * 72); * Console.WriteLine(totalVertCount * 72 * expCount); * Console.WriteLine(this.mdlInfo.expSize.ToString("X8").ToUpper()); * Console.WriteLine((this.fvfListEnd + this.mdlInfo.expSize).ToString("X8")); * * this.fs.Seek(0x100, SeekOrigin.Current); * * uint x = 0; * * while (br.ReadByte() == 0) * { * x++; * } * Console.WriteLine(x); * Console.WriteLine(fs.Position.ToString("X8"));*/ /*float dx, dy, dz; * for (i = 0; i < totalVertCount; i++) * { * dx = br.ReadSingle() * SCALE; * dy = br.ReadSingle() * SCALE; * dz = br.ReadSingle() * SCALE * (-1); * * if (dx != 0.0f || dy != 0.0f || dz != 0.0f) * { * PMXMorphOffsetVertex dvtx = new PMXMorphOffsetVertex(this.pmx, morph); * dvtx.Vertex = this.pmx.Vertices[i]; * dvtx.Translation.X = dx; * dvtx.Translation.Y = dy; * dvtx.Translation.Z = dz; * morph.Offsets.Add(dvtx); * } * this.fs.Seek(60, SeekOrigin.Current); * }*/ //this.pmx.Morphs.Add(morph); this.WritePMX(); }
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(); } }