示例#1
0
        private static void ReadRigidBodies(BinaryReader reader, RawMMDModel model, PmxConfig pmxConfig)
        {
            var rigidBodyNum = reader.ReadInt32();

            model.Rigidbodies = new MMDRigidBody[rigidBodyNum];
            for (var i = 0; i < rigidBodyNum; ++i)
            {
                var rigidBody = new MMDRigidBody
                {
                    Name   = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding),
                    NameEn = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding),
                    AssociatedBoneIndex = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize),
                    CollisionGroup      = reader.ReadByte(),
                    CollisionMask       = reader.ReadUInt16(),
                    Shape         = (MMDRigidBody.RigidBodyShape)reader.ReadByte(),
                    Dimemsions    = MMDReaderUtil.ReadRawCoordinateVector3(reader),
                    Position      = MMDReaderUtil.ReadVector3(reader),
                    Rotation      = MMDReaderUtil.ReadAmpVector3(reader, Mathf.Rad2Deg),
                    Mass          = reader.ReadSingle(),
                    TranslateDamp = reader.ReadSingle(),
                    RotateDamp    = reader.ReadSingle(),
                    Restitution   = reader.ReadSingle(),
                    Friction      = reader.ReadSingle(),
                    Type          = (MMDRigidBody.RigidBodyType)reader.ReadByte()
                };
                model.Rigidbodies[i] = rigidBody;
            }
        }
示例#2
0
        //unused data
        /// <summary>
        /// 作者写了一个没有用的标签
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="pmxConfig"></param>
        private static void ReadEntries(BinaryReader reader, PmxConfig pmxConfig)
        {
            //OYM:注意,这是个void方法...作者把所有的数据都丢了23333
            var entryItemNum = reader.ReadInt32();

            for (var i = 0; i < entryItemNum; ++i)
            {
                MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding); //entryItemName
                MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding); //entryItemNameEn
                reader.ReadByte();                                         //isSpecial
                var elementNum = reader.ReadInt32();
                for (var j = 0; j < elementNum; ++j)
                {
                    var isMorph = reader.ReadByte() == 1;
                    if (isMorph)
                    {
                        MmdReaderUtil.ReadIndex(reader, pmxConfig.MorphIndexSize); //morphIndex
                    }
                    else
                    {
                        MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize); //boneIndex
                    }
                }
            }
        }
示例#3
0
        private static void ReadVertices(BinaryReader reader, RawMMDModel model, PmxConfig pmxConfig)
        {
            var vertexNum = reader.ReadInt32();

            model.Vertices = new Vertex[vertexNum];
            for (uint i = 0; i < vertexNum; ++i)
            {
                var vertex = ReadVertex(reader, pmxConfig);
                model.Vertices[i] = vertex;
            }
        }
示例#4
0
        /// <summary>
        /// 一个读取顶点数目的方法
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="model"></param>
        /// <param name="pmxConfig"></param>
        private static void ReadVertices(BinaryReader reader, MmdModel model, PmxConfig pmxConfig)
        {
            //OYM:不啰嗦了
            var vertexNum = reader.ReadInt32();

            model.Vertices = new Vertex[vertexNum];
            for (uint i = 0; i < vertexNum; ++i)
            {
                var vertex = ReadVertex(reader, pmxConfig); //OYM:对一个顶点进行数据提取
                model.Vertices[i] = vertex;                 //OYM:赋值
            }
        }
示例#5
0
        private static MMDTexture[] ReadTextureList(BinaryReader reader, PmxConfig pmxConfig)
        {
            var textureNum  = reader.ReadInt32();
            var textureList = new MMDTexture[textureNum];

            for (var i = 0; i < textureNum; ++i)
            {
                var texturePathEncoding = pmxConfig.Utf8Encoding ? Encoding.UTF8 : Encoding.Unicode;
                var texturePath         = MMDReaderUtil.ReadSizedString(reader, texturePathEncoding);
                textureList[i] = new MMDTexture(texturePath);
            }
            return(textureList);
        }
示例#6
0
        private static void ReadTriangles(BinaryReader reader, RawMMDModel model, PmxConfig pmxConfig)
        {
            var triangleIndexCount = reader.ReadInt32();

            model.TriangleIndexes = new int[triangleIndexCount];
            if (triangleIndexCount % 3 != 0)
            {
                throw new MMDFileParseException("triangle index count " + triangleIndexCount + " is not multiple of 3");
            }
            for (var i = 0; i < triangleIndexCount; ++i)
            {
                model.TriangleIndexes[i] = MMDReaderUtil.ReadIndex(reader, pmxConfig.VertexIndexSize);
            }
        }
示例#7
0
        /// <summary>
        /// 读取三角形数目
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="model"></param>
        /// <param name="pmxConfig"></param>
        private static void ReadTriangles(BinaryReader reader, MmdModel model, PmxConfig pmxConfig)
        {
            var triangleIndexCount = reader.ReadInt32();

            model.TriangleIndexes = new int[triangleIndexCount];
            if (triangleIndexCount % 3 != 0)//OYM:如果不是三的整数倍就报错(这样子就代表肯定有个三角形的数据丢失了)
            {
                throw new MmdFileParseException("triangle index count " + triangleIndexCount + " is not multiple of 3");
            }
            for (var i = 0; i < triangleIndexCount; ++i)
            {
                model.TriangleIndexes[i] = MmdReaderUtil.ReadIndex(reader, pmxConfig.VertexIndexSize);//OYM:读取三角形,注意三角形是根据顶点的序号数目生成的
            }
        }
示例#8
0
        private static PmxConfig ReadPmxConfig(BinaryReader reader, RawMMDModel model)
        {
            var pmxConfig = new PmxConfig();

            pmxConfig.Utf8Encoding       = reader.ReadByte() != 0;
            pmxConfig.ExtraUvNumber      = reader.ReadSByte();
            pmxConfig.VertexIndexSize    = reader.ReadSByte();
            pmxConfig.TextureIndexSize   = reader.ReadSByte();
            pmxConfig.MaterialIndexSize  = reader.ReadSByte();
            pmxConfig.BoneIndexSize      = reader.ReadSByte();
            pmxConfig.MorphIndexSize     = reader.ReadSByte();
            pmxConfig.RigidBodyIndexSize = reader.ReadSByte();

            model.ExtraUvNumber = pmxConfig.ExtraUvNumber;
            pmxConfig.Encoding  = pmxConfig.Utf8Encoding ? Encoding.UTF8 : Encoding.Unicode;
            return(pmxConfig);
        }
示例#9
0
        private static PmxConfig ReadPmxConfig(BinaryReader reader, MmdModel model)
        {
            //https://www.cnblogs.com/tanding/archive/2012/07/02/2572702.html
            //OYM:下面一摞方法都是读取一个字节,从0-256到-128-128的方法都有.

            var pmxConfig = new PmxConfig();

            pmxConfig.Utf8Encoding       = reader.ReadByte() != 0; //OYM:是否是UTF8
            pmxConfig.ExtraUvNumber      = reader.ReadSByte();     //OYM:UV数量
            pmxConfig.VertexIndexSize    = reader.ReadSByte();     //OYM:不知道
            pmxConfig.TextureIndexSize   = reader.ReadSByte();     //OYM:不知道
            pmxConfig.MaterialIndexSize  = reader.ReadSByte();     //OYM:不知道,下面都不知道,懒得写了
            pmxConfig.BoneIndexSize      = reader.ReadSByte();
            pmxConfig.MorphIndexSize     = reader.ReadSByte();
            pmxConfig.RigidBodyIndexSize = reader.ReadSByte();

            model.ExtraUvNumber = pmxConfig.ExtraUvNumber;
            pmxConfig.Encoding  = pmxConfig.Utf8Encoding ? Encoding.UTF8 : Encoding.Unicode;
            return(pmxConfig);
        }
示例#10
0
        private static void ReadJoints(BinaryReader reader, RawMMDModel model, PmxConfig pmxConfig)
        {
            var constraintNum = reader.ReadInt32();

            model.Joints = new Model.Joint[constraintNum];
            for (var i = 0; i < constraintNum; ++i)
            {
                var joint = new Model.Joint
                {
                    Name   = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding),
                    NameEn = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding)
                };
                var dofType = reader.ReadByte();
                if (dofType == 0)
                {
                    joint.AssociatedRigidBodyIndex[0] =
                        MMDReaderUtil.ReadIndex(reader, pmxConfig.RigidBodyIndexSize);
                    joint.AssociatedRigidBodyIndex[1] =
                        MMDReaderUtil.ReadIndex(reader, pmxConfig.RigidBodyIndexSize);
                    joint.Position         = MMDReaderUtil.ReadVector3(reader);
                    joint.Rotation         = MMDReaderUtil.ReadAmpVector3(reader, Mathf.Rad2Deg);
                    joint.PositionLowLimit = MMDReaderUtil.ReadVector3(reader);
                    joint.PositionHiLimit  = MMDReaderUtil.ReadVector3(reader);
                    joint.RotationLowLimit = MMDReaderUtil.ReadVector3(reader);
                    joint.RotationHiLimit  = MMDReaderUtil.ReadVector3(reader);
                    joint.SpringTranslate  = MMDReaderUtil.ReadVector3(reader);
                    joint.SpringRotate     = MMDReaderUtil.ReadVector3(reader);
                }
                else
                {
                    throw new MMDFileParseException("Only 6DOF spring joints are supported.");
                }

                model.Joints[i] = joint;
            }
        }
示例#11
0
        private static void ReadMorphs(BinaryReader reader, RawMMDModel model, PmxConfig pmxConfig)
        {
            var morphNum       = reader.ReadInt32();
            int?baseMorphIndex = null;

            model.Morphs = new Morph[morphNum];
            for (var i = 0; i < morphNum; ++i)
            {
                var morph = new Morph
                {
                    Name     = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding),
                    NameEn   = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding),
                    Category = (Morph.MorphCategory)reader.ReadByte()
                };
                if (morph.Category == Morph.MorphCategory.MorphCatSystem)
                {
                    baseMorphIndex = i;
                }
                morph.Type = (Morph.MorphType)reader.ReadByte();
                var morphDataNum = reader.ReadInt32();
                morph.MorphDatas = new Morph.MorphData[morphDataNum];
                switch (morph.Type)
                {
                case Morph.MorphType.MorphTypeGroup:
                    for (var j = 0; j < morphDataNum; ++j)
                    {
                        var morphData =
                            new Morph.GroupMorphData
                        {
                            MorphIndex = MMDReaderUtil.ReadIndex(reader, pmxConfig.MorphIndexSize),
                            MorphRate  = reader.ReadSingle()
                        };
                        morph.MorphDatas[j] = morphData;
                    }
                    break;

                case Morph.MorphType.MorphTypeVertex:
                    for (var j = 0; j < morphDataNum; ++j)
                    {
                        var morphData =
                            new Morph.VertexMorphData
                        {
                            VertexIndex = MMDReaderUtil.ReadIndex(reader, pmxConfig.VertexIndexSize),
                            Offset      = MMDReaderUtil.ReadVector3(reader)
                        };
                        morph.MorphDatas[j] = morphData;
                    }
                    break;

                case Morph.MorphType.MorphTypeBone:
                    for (var j = 0; j < morphDataNum; ++j)
                    {
                        var morphData =
                            new Morph.BoneMorphData
                        {
                            BoneIndex   = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize),
                            Translation = MMDReaderUtil.ReadVector3(reader),
                            Rotation    = MMDReaderUtil.ReadQuaternion(reader)
                        };
                        morph.MorphDatas[j] = morphData;
                    }

                    break;

                case Morph.MorphType.MorphTypeUv:
                case Morph.MorphType.MorphTypeExtUv1:
                case Morph.MorphType.MorphTypeExtUv2:
                case Morph.MorphType.MorphTypeExtUv3:
                case Morph.MorphType.MorphTypeExtUv4:
                    for (var j = 0; j < morphDataNum; ++j)
                    {
                        var morphData =
                            new Morph.UvMorphData
                        {
                            VertexIndex = MMDReaderUtil.ReadIndex(reader, pmxConfig.VertexIndexSize),
                            Offset      = MMDReaderUtil.ReadVector4(reader)
                        };
                        morph.MorphDatas[j] = morphData;
                    }

                    break;

                case Morph.MorphType.MorphTypeMaterial:
                    for (var j = 0; j < morphDataNum; j++)
                    {
                        var morphData = new Morph.MaterialMorphData();
                        var mmIndex   = MMDReaderUtil.ReadIndex(reader, pmxConfig.MaterialIndexSize);
                        if (mmIndex < model.Parts.Length && mmIndex > 0)     //TODO mmdlib的代码里是和bone数比较。确认这个逻辑
                        {
                            morphData.MaterialIndex = mmIndex;
                            morphData.Global        = false;
                        }
                        else
                        {
                            morphData.MaterialIndex = 0;
                            morphData.Global        = true;
                        }
                        morphData.Method      = (Morph.MaterialMorphData.MaterialMorphMethod)reader.ReadByte();
                        morphData.Diffuse     = MMDReaderUtil.ReadColor(reader, true);
                        morphData.Specular    = MMDReaderUtil.ReadColor(reader, false);
                        morphData.Shiness     = reader.ReadSingle();
                        morphData.Ambient     = MMDReaderUtil.ReadColor(reader, false);
                        morphData.EdgeColor   = MMDReaderUtil.ReadColor(reader, true);
                        morphData.EdgeSize    = reader.ReadSingle();
                        morphData.Texture     = MMDReaderUtil.ReadVector4(reader);
                        morphData.SubTexture  = MMDReaderUtil.ReadVector4(reader);
                        morphData.ToonTexture = MMDReaderUtil.ReadVector4(reader);
                        morph.MorphDatas[j]   = morphData;
                    }
                    break;

                default:
                    throw new MMDFileParseException("invalid morph type " + morph.Type);
                }
                if (baseMorphIndex != null)
                {
                    //TODO rectify system-reserved category
                }

                model.Morphs[i] = morph;
            }
        }
示例#12
0
        private static Vertex ReadVertex(BinaryReader reader, PmxConfig pmxConfig)
        {
            var pv     = ReadVertexBasic(reader);
            var vertex = new Vertex
            {
                Coordinate   = pv.Coordinate,
                Normal       = pv.Normal,
                UvCoordinate = pv.UvCoordinate
            };

            if (pmxConfig.ExtraUvNumber > 0)
            {
                var extraUv = new Vector4[pmxConfig.ExtraUvNumber];
                for (var ei = 0; ei < pmxConfig.ExtraUvNumber; ++ei)
                {
                    extraUv[ei] = MMDReaderUtil.ReadVector4(reader);
                }
                vertex.ExtraUvCoordinate = extraUv;
            }

            var op           = new SkinningOperator();
            var skinningType = (SkinningOperator.SkinningType)reader.ReadByte();

            op.Type = skinningType;

            switch (skinningType)
            {
            case SkinningOperator.SkinningType.SkinningBdef1:
                var bdef1 = new SkinningOperator.Bdef1();
                bdef1.BoneId = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                op.Param     = bdef1;
                break;

            case SkinningOperator.SkinningType.SkinningBdef2:
                var bdef2 = new SkinningOperator.Bdef2();
                bdef2.BoneId[0]  = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                bdef2.BoneId[1]  = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                bdef2.BoneWeight = reader.ReadSingle();
                op.Param         = bdef2;
                break;

            case SkinningOperator.SkinningType.SkinningBdef4:
                var bdef4 = new SkinningOperator.Bdef4();
                for (var j = 0; j < 4; ++j)
                {
                    bdef4.BoneId[j] = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                }
                for (var j = 0; j < 4; ++j)
                {
                    bdef4.BoneWeight[j] = reader.ReadSingle();
                }
                op.Param = bdef4;
                break;

            case SkinningOperator.SkinningType.SkinningSdef:
                var sdef = new SkinningOperator.Sdef();
                sdef.BoneId[0]  = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                sdef.BoneId[1]  = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                sdef.BoneWeight = reader.ReadSingle();
                sdef.C          = MMDReaderUtil.ReadVector3(reader);
                sdef.R0         = MMDReaderUtil.ReadVector3(reader);
                sdef.R1         = MMDReaderUtil.ReadVector3(reader);
                op.Param        = sdef;
                break;

            default:
                throw new MMDFileParseException("invalid skinning type: " + skinningType);
            }
            vertex.SkinningOperator = op;
            vertex.EdgeScale        = reader.ReadSingle();
            return(vertex);
        }
示例#13
0
 private static void ReadModelNameAndDescription(BinaryReader reader, RawMMDModel model, PmxConfig pmxConfig)
 {
     model.Name          = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding);
     model.NameEn        = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding);
     model.Description   = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding);
     model.DescriptionEn = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding);
 }
示例#14
0
        /// <summary>
        /// 读取骨骼数目
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="model"></param>
        /// <param name="pmxConfig"></param>
        private static void ReadBones(BinaryReader reader, MmdModel model, PmxConfig pmxConfig)
        {
            var boneNum = reader.ReadInt32();//OYM:获取骨骼数目

            model.Bones = new Bone[boneNum];
            for (var i = 0; i < boneNum; ++i)
            {
                var bone = new Bone
                {
                    Name     = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding),
                    NameEn   = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding),
                    Position = MmdReaderUtil.ReadVector3(reader)
                };
                var parentIndex = MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);//OYM:获取父骨骼的序号
                if (parentIndex < boneNum && parentIndex >= 0)
                {
                    bone.ParentIndex = parentIndex;
                }
                else
                {
                    bone.ParentIndex = -1;
                }
                bone.TransformLevel = reader.ReadInt32();//OYM:不知道
                //下面一排位运算,跳过
                var flag = reader.ReadUInt16();
                bone.ChildBoneVal.ChildUseId = (flag & PmxBoneFlags.PmxBoneChildUseId) != 0;
                bone.Rotatable        = (flag & PmxBoneFlags.PmxBoneRotatable) != 0;
                bone.Movable          = (flag & PmxBoneFlags.PmxBoneMovable) != 0;
                bone.Visible          = (flag & PmxBoneFlags.PmxBoneVisible) != 0;
                bone.Controllable     = (flag & PmxBoneFlags.PmxBoneControllable) != 0;
                bone.HasIk            = (flag & PmxBoneFlags.PmxBoneHasIk) != 0;
                bone.AppendRotate     = (flag & PmxBoneFlags.PmxBoneAcquireRotate) != 0;
                bone.AppendTranslate  = (flag & PmxBoneFlags.PmxBoneAcquireTranslate) != 0;
                bone.RotAxisFixed     = (flag & PmxBoneFlags.PmxBoneRotAxisFixed) != 0;
                bone.UseLocalAxis     = (flag & PmxBoneFlags.PmxBoneUseLocalAxis) != 0;
                bone.PostPhysics      = (flag & PmxBoneFlags.PmxBonePostPhysics) != 0;
                bone.ReceiveTransform = (flag & PmxBoneFlags.PmxBoneReceiveTransform) != 0;
                if (bone.ChildBoneVal.ChildUseId)
                {
                    bone.ChildBoneVal.Index = MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                }
                else
                {
                    bone.ChildBoneVal.Offset = MmdReaderUtil.ReadVector3(reader);
                }
                if (bone.RotAxisFixed)//OYM:旋转角固定?
                {
                    bone.RotAxis = MmdReaderUtil.ReadVector3(reader);
                }
                if (bone.AppendRotate || bone.AppendTranslate)//OYM:看不懂,告辞
                {
                    bone.AppendBoneVal.Index = MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                    bone.AppendBoneVal.Ratio = reader.ReadSingle();
                }
                if (bone.UseLocalAxis)//OYM:使用本地坐标
                {
                    Vector3 localX = MmdReaderUtil.ReadVector3(reader);
                    Vector3 localZ = MmdReaderUtil.ReadVector3(reader);
                    Vector3 localY = Vector3.Cross(localX, localZ); //OYM:差积出来你也太懒了吧
                    localZ = Vector3.Cross(localX, localY);         //OYM:再差积一次防止坐标轴反了?
                    localX.Normalize();
                    localY.Normalize();
                    localZ.Normalize();
                    bone.LocalAxisVal.AxisX = localX;
                    bone.LocalAxisVal.AxisY = localY;
                    bone.LocalAxisVal.AxisZ = localZ;
                }
                if (bone.ReceiveTransform)
                {
                    bone.ExportKey = reader.ReadInt32();
                }
                if (bone.HasIk)
                {
                    ReadBoneIk(reader, bone, pmxConfig.BoneIndexSize);//OYM:来看看别人IK怎么描述位置的
                }

                model.Bones[i] = bone;
            }
        }
示例#15
0
 private static void ReadModelNameAndDescription(BinaryReader reader, MmdModel model, PmxConfig pmxConfig)
 {
     //OYM:一堆读取信息,没什么好看的
     model.Name          = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding);
     model.NameEn        = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding);
     model.Description   = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding);
     model.DescriptionEn = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding);
 }
示例#16
0
        /// <summary>
        /// 关键部分
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="pmxConfig"></param>
        /// <returns></returns>
        private static Vertex ReadVertex(BinaryReader reader, PmxConfig pmxConfig)
        {
            var pv = ReadVertexBasic(reader);
            //new一个顶点,赋值

            var vertex = new Vertex
            {
                Coordinate   = pv.Coordinate,
                Normal       = pv.Normal,
                UvCoordinate = pv.UvCoordinate
            };

            //OYM:如果有额外的uv(在底层设置那里)
            //OYM:也不知道到底有什么用...
            if (pmxConfig.ExtraUvNumber > 0)
            {
                var extraUv = new Vector4[pmxConfig.ExtraUvNumber];
                for (var ei = 0; ei < pmxConfig.ExtraUvNumber; ++ei)
                {
                    extraUv[ei] = MmdReaderUtil.ReadVector4(reader);
                }
                vertex.ExtraUvCoordinate = extraUv;
            }

            var op           = new SkinningOperator();
            var skinningType = (SkinningOperator.SkinningType)reader.ReadByte(); //OYM:蒙皮种类

            op.Type = skinningType;                                              //OYM:看不懂就完事了

            switch (skinningType)                                                //OYM:应该是权重没跑了
            {
            case SkinningOperator.SkinningType.SkinningBdef1:
                var bdef1 = new SkinningOperator.Bdef1();    //OYM:注意这里用了父类可以为任意形式子类的方法,很模糊但是还是要好好学
                bdef1.BoneId = MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                op.Param     = bdef1;
                break;

            case SkinningOperator.SkinningType.SkinningBdef2:
                var bdef2 = new SkinningOperator.Bdef2();
                bdef2.BoneId[0]  = MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                bdef2.BoneId[1]  = MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                bdef2.BoneWeight = reader.ReadSingle();
                op.Param         = bdef2;
                break;

            case SkinningOperator.SkinningType.SkinningBdef4:
                var bdef4 = new SkinningOperator.Bdef4();
                for (var j = 0; j < 4; ++j)
                {
                    bdef4.BoneId[j] = MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                }
                for (var j = 0; j < 4; ++j)
                {
                    bdef4.BoneWeight[j] = reader.ReadSingle();
                }
                op.Param = bdef4;
                break;

            case SkinningOperator.SkinningType.SkinningSdef:    //OYM:这个猜不准,到时候再看
                var sdef = new SkinningOperator.Sdef();
                sdef.BoneId[0]  = MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                sdef.BoneId[1]  = MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                sdef.BoneWeight = reader.ReadSingle();
                sdef.C          = MmdReaderUtil.ReadVector3(reader);
                sdef.R0         = MmdReaderUtil.ReadVector3(reader);
                sdef.R1         = MmdReaderUtil.ReadVector3(reader);
                op.Param        = sdef;
                break;

            default:
                throw new MmdFileParseException("invalid skinning type: " + skinningType);
            }
            vertex.SkinningOperator = op;                  //OYM:顶点的蒙皮操作
            vertex.EdgeScale        = reader.ReadSingle(); //OYM:这个实在猜不准,但是考虑到就一个单精度,猜一个倍率好了
            return(vertex);
        }
示例#17
0
        private static void ReadParts(BinaryReader reader, ModelReadConfig config, RawMMDModel model, PmxConfig pmxConfig, MMDTexture[] textureList)
        {
            var partNum       = reader.ReadInt32();
            var partBaseShift = 0;

            model.Parts = new Part[partNum];
            for (var i = 0; i < partNum; i++)
            {
                var part     = new Part();
                var material = ReadMaterial(reader, config, pmxConfig.Encoding, pmxConfig.TextureIndexSize, textureList);
                part.Material = material;
                var partTriangleIndexNum = reader.ReadInt32();
                if (partTriangleIndexNum % 3 != 0)
                {
                    throw new MMDFileParseException("part" + i + " triangle index count " + partTriangleIndexNum +
                                                    " is not multiple of 3");
                }
                part.BaseShift        = partBaseShift;
                part.TriangleIndexNum = partTriangleIndexNum;
                partBaseShift        += partTriangleIndexNum;
                model.Parts[i]        = part;
            }
        }
示例#18
0
        private static void ReadBones(BinaryReader reader, RawMMDModel model, PmxConfig pmxConfig)
        {
            var boneNum = reader.ReadInt32();

            model.Bones = new Bone[boneNum];
            for (var i = 0; i < boneNum; ++i)
            {
                var bone = new Bone
                {
                    Name     = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding),
                    NameEn   = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding),
                    Position = MMDReaderUtil.ReadVector3(reader)
                };
                var parentIndex = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                if (parentIndex < boneNum && parentIndex >= 0)
                {
                    bone.ParentIndex = parentIndex;
                }
                else
                {
                    bone.ParentIndex = -1;
                }
                bone.TransformLevel = reader.ReadInt32();
                var flag = reader.ReadUInt16();
                bone.ChildBoneVal.ChildUseId = (flag & PmxBoneFlags.PmxBoneChildUseId) != 0;
                bone.Rotatable        = (flag & PmxBoneFlags.PmxBoneRotatable) != 0;
                bone.Movable          = (flag & PmxBoneFlags.PmxBoneMovable) != 0;
                bone.Visible          = (flag & PmxBoneFlags.PmxBoneVisible) != 0;
                bone.Controllable     = (flag & PmxBoneFlags.PmxBoneControllable) != 0;
                bone.HasIk            = (flag & PmxBoneFlags.PmxBoneHasIk) != 0;
                bone.AppendRotate     = (flag & PmxBoneFlags.PmxBoneAcquireRotate) != 0;
                bone.AppendTranslate  = (flag & PmxBoneFlags.PmxBoneAcquireTranslate) != 0;
                bone.RotAxisFixed     = (flag & PmxBoneFlags.PmxBoneRotAxisFixed) != 0;
                bone.UseLocalAxis     = (flag & PmxBoneFlags.PmxBoneUseLocalAxis) != 0;
                bone.PostPhysics      = (flag & PmxBoneFlags.PmxBonePostPhysics) != 0;
                bone.ReceiveTransform = (flag & PmxBoneFlags.PmxBoneReceiveTransform) != 0;
                if (bone.ChildBoneVal.ChildUseId)
                {
                    bone.ChildBoneVal.Index = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                }
                else
                {
                    bone.ChildBoneVal.Offset = MMDReaderUtil.ReadVector3(reader);
                }
                if (bone.RotAxisFixed)
                {
                    bone.RotAxis = MMDReaderUtil.ReadVector3(reader);
                }
                if (bone.AppendRotate || bone.AppendTranslate)
                {
                    bone.AppendBoneVal.Index = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize);
                    bone.AppendBoneVal.Ratio = reader.ReadSingle();
                }
                if (bone.UseLocalAxis)
                {
                    var localX = MMDReaderUtil.ReadVector3(reader);
                    var localZ = MMDReaderUtil.ReadVector3(reader);
                    var localY = Vector3.Cross(localX, localZ);
                    localZ = Vector3.Cross(localX, localY);
                    localX.Normalize();
                    localY.Normalize();
                    localZ.Normalize();
                    bone.LocalAxisVal.AxisX = localX;
                    bone.LocalAxisVal.AxisY = localY;
                    bone.LocalAxisVal.AxisZ = localZ;
                }
                if (bone.ReceiveTransform)
                {
                    bone.ExportKey = reader.ReadInt32();
                }
                if (bone.HasIk)
                {
                    ReadBoneIk(reader, bone, pmxConfig.BoneIndexSize);
                }

                model.Bones[i] = bone;
            }
        }
示例#19
0
        /// <summary>
        /// 读取变形
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="model"></param>
        /// <param name="pmxConfig"></param>
        private static void ReadMorphs(BinaryReader reader, MmdModel model, PmxConfig pmxConfig)
        {
            var morphNum       = reader.ReadInt32();//OYM:表情包数量
            int?baseMorphIndex = null;

            model.Morphs = new Morph[morphNum];
            for (var i = 0; i < morphNum; ++i)
            {
                var morph = new Morph
                {
                    Name     = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding),
                    NameEn   = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding),
                    Category = (Morph.MorphCategory)reader.ReadByte()
                };

                if (morph.Category == Morph.MorphCategory.MorphCatSystem)
                {
                    baseMorphIndex = i;//OYM:这个就相当于是一个基类吧
                }

                morph.Type = (Morph.MorphType)reader.ReadByte();      //OYM:变形方式
                var morphDataNum = reader.ReadInt32();
                morph.MorphDatas = new Morph.MorphData[morphDataNum]; //OYM:获取表情变形的数据
                switch (morph.Type)
                {
                case Morph.MorphType.MorphTypeGroup:    //OYM:不知道干啥用的
                    for (var j = 0; j < morphDataNum; ++j)
                    {
                        var morphData =
                            new Morph.GroupMorph
                        {
                            MorphIndex = MmdReaderUtil.ReadIndex(reader, pmxConfig.MorphIndexSize),
                            MorphRate  = reader.ReadSingle()
                        };
                        morph.MorphDatas[j] = morphData;
                    }
                    break;

                case Morph.MorphType.MorphTypeVertex:    //OYM:喜闻乐见的顶点变形
                    for (var j = 0; j < morphDataNum; ++j)
                    {
                        var morphData =
                            new Morph.VertexMorph
                        {
                            VertexIndex = MmdReaderUtil.ReadIndex(reader, pmxConfig.VertexIndexSize), //OYM:顶点的序号
                            Offset      = MmdReaderUtil.ReadVector3(reader)                           //OYM:偏移量
                        };
                        morph.MorphDatas[j] = morphData;
                    }
                    break;

                case Morph.MorphType.MorphTypeBone:    //OYM:骨骼变形
                    for (var j = 0; j < morphDataNum; ++j)
                    {
                        var morphData =
                            new Morph.BoneMorph
                        {
                            BoneIndex   = MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize), //OYM:骨骼序号
                            Translation = MmdReaderUtil.ReadVector3(reader),                        //OYM:移动方向
                            Rotation    = MmdReaderUtil.ReadQuaternion(reader)                      //OYM:旋转方向
                        };
                        morph.MorphDatas[j] = morphData;
                    }

                    break;

                //OYM:下面一堆case都是执行靠后面那个方法
                case Morph.MorphType.MorphTypeUv:
                case Morph.MorphType.MorphTypeExtUv1:
                case Morph.MorphType.MorphTypeExtUv2:
                case Morph.MorphType.MorphTypeExtUv3:
                case Morph.MorphType.MorphTypeExtUv4:
                    for (var j = 0; j < morphDataNum; ++j)
                    {
                        //OYM:获取信息就完事了
                        var morphData =
                            new Morph.UvMorph
                        {
                            VertexIndex = MmdReaderUtil.ReadIndex(reader, pmxConfig.VertexIndexSize),
                            Offset      = MmdReaderUtil.ReadVector4(reader)
                        };
                        morph.MorphDatas[j] = morphData;
                    }

                    break;

                case Morph.MorphType.MorphTypeMaterial:
                    for (var j = 0; j < morphDataNum; j++)
                    {
                        var morphData = new Morph.MaterialMorph();
                        var mmIndex   = MmdReaderUtil.ReadIndex(reader, pmxConfig.MaterialIndexSize);
                        //OYM:补一个,作者居然还顺便修复了一个bug23333
                        if (mmIndex < model.Parts.Length && mmIndex > 0)     //TODO mmdlib的代码里是和bone数比较。确认这个逻辑
                        {
                            morphData.MaterialIndex = mmIndex;
                            morphData.Global        = false;
                        }
                        else
                        {
                            morphData.MaterialIndex = 0;
                            morphData.Global        = true;
                        }
                        morphData.Method      = (Morph.MaterialMorph.MaterialMorphMethod)reader.ReadByte();
                        morphData.Diffuse     = MmdReaderUtil.ReadColor(reader, true);
                        morphData.Specular    = MmdReaderUtil.ReadColor(reader, false);
                        morphData.Shiness     = reader.ReadSingle();
                        morphData.Ambient     = MmdReaderUtil.ReadColor(reader, false);
                        morphData.EdgeColor   = MmdReaderUtil.ReadColor(reader, true);
                        morphData.EdgeSize    = reader.ReadSingle();
                        morphData.Texture     = MmdReaderUtil.ReadVector4(reader);
                        morphData.SubTexture  = MmdReaderUtil.ReadVector4(reader);
                        morphData.ToonTexture = MmdReaderUtil.ReadVector4(reader);
                        morph.MorphDatas[j]   = morphData;
                    }
                    break;

                default:
                    throw new MmdFileParseException("invalid morph type " + morph.Type);
                }
                if (baseMorphIndex != null)
                {
                    //TODO rectify system-reserved category
                    //OYM:不清楚作者要干啥
                }

                model.Morphs[i] = morph;
            }
        }