Пример #1
0
            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();
                }
            }
Пример #2
0
        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
                );
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        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;
                }
            }
        }
Пример #8
0
 public TriangleEdge(PMXVertex vtx1, PMXVertex vtx2) : this(vtx1, vtx2, false)
 {
 }
Пример #9
0
        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;
            }
        }
Пример #10
0
        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();
        }
Пример #11
0
        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();
            }
        }