Beispiel #1
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);
        }
Beispiel #2
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;
            }
        }
Beispiel #3
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();
            }
        }