コード例 #1
0
        private void WritePmxJoint([NotNull] PmxJoint joint)
        {
            WriteString(joint.Name);
            WriteString(joint.NameEnglish);

            _writer.Write((byte)joint.Kind);
            _writer.WriteInt32AsVarLenInt(joint.BodyIndex1, RigidBodyElementSize);
            _writer.WriteInt32AsVarLenInt(joint.BodyIndex2, RigidBodyElementSize);
            _writer.Write(joint.Position);
            _writer.Write(joint.Rotation);
            _writer.Write(joint.LowerTranslationLimit);
            _writer.Write(joint.UpperTranslationLimit);
            _writer.Write(joint.LowerRotationLimit);
            _writer.Write(joint.UpperRotationLimit);
            _writer.Write(joint.TranslationSpringConstants);
            _writer.Write(joint.RotationSpringConstants);
        }
コード例 #2
0
ファイル: PmxReader.cs プロジェクト: logchan/MLTDTools
        private PmxJoint ReadPmxJoint()
        {
            var joint = new PmxJoint();

            joint.Name        = ReadString() ?? string.Empty;
            joint.NameEnglish = ReadString() ?? string.Empty;

            joint.Kind                       = (JointKind)_reader.ReadByte();
            joint.BodyIndex1                 = _reader.ReadVarLenIntAsInt32(RigidBodyElementSize);
            joint.BodyIndex2                 = _reader.ReadVarLenIntAsInt32(RigidBodyElementSize);
            joint.Position                   = _reader.ReadVector3();
            joint.Rotation                   = _reader.ReadVector3();
            joint.LowerTranslationLimit      = _reader.ReadVector3();
            joint.UpperTranslationLimit      = _reader.ReadVector3();
            joint.LowerRotationLimit         = _reader.ReadVector3();
            joint.UpperRotationLimit         = _reader.ReadVector3();
            joint.TranslationSpringConstants = _reader.ReadVector3();
            joint.RotationSpringConstants    = _reader.ReadVector3();

            return(joint);
        }
コード例 #3
0
ファイル: PmxReader.cs プロジェクト: THISISAGOODNAME/chloride
        private PmxJoint ReadPmxJoint()
        {
            var joint = new PmxJoint();

            joint.Name        = ReadString() ?? string.Empty;
            joint.NameEnglish = ReadString() ?? string.Empty;

            joint.Kind            = (JointKind)_reader.ReadByte();
            joint.BodyIndex1      = _reader.ReadVarLenIntAsInt32(RigidBodyElementSize);
            joint.BodyIndex2      = _reader.ReadVarLenIntAsInt32(RigidBodyElementSize);
            joint.Position        = _reader.ReadVector3();
            joint.RotationAngles  = _reader.ReadVector3();
            joint.LimitMoveLower  = _reader.ReadVector3();
            joint.LimitMoveUpper  = _reader.ReadVector3();
            joint.LimitAngleLower = _reader.ReadVector3();
            joint.LimitAngleUpper = _reader.ReadVector3();
            joint.SpConst_Move    = _reader.ReadVector3();
            joint.SpConst_Rotate  = _reader.ReadVector3();

            return(joint);
        }
コード例 #4
0
            private void AppendJoints([NotNull, ItemNotNull] PmxBone[] bones, [NotNull, ItemNotNull] List <PmxRigidBody> bodies, [NotNull, ItemNotNull] List <PmxJoint> joints)
            {
                foreach (var body in bodies)
                {
                    var addJoint = false;

                    switch (body.Part)
                    {
                    case CoordSystemPart.Torso:
                    case CoordSystemPart.LeftArm:
                    case CoordSystemPart.RightArm:
                    case CoordSystemPart.Legs:
                    case CoordSystemPart.Head:
                        break;

                    case CoordSystemPart.Skirt:
                    case CoordSystemPart.Hair:
                    case CoordSystemPart.Breasts:
                        addJoint = true;
                        break;

                    case CoordSystemPart.Accessories:
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    if (!addJoint)
                    {
                        continue;
                    }

                    var pmxBone    = bones[body.BoneIndex];
                    var parentBone = bones[pmxBone.ParentIndex];

                    var parentBody = bodies.Find(bo => bo.BoneIndex == parentBone.BoneIndex);

                    // This rigid body is attached to a semi-root bone. Create it as a new "root" for its sub rigid bodies.
                    if (parentBody == null)
                    {
                        switch (body.Part)
                        {
                        case CoordSystemPart.Skirt:
                            var koshi = _pmxCreator._boneLookup.GetPmxBoneName("MODEL_00/BASE/KOSHI");
                            parentBody = bodies.Find(bo => bones[bo.BoneIndex].Name == koshi);
                            break;

                        case CoordSystemPart.Hair: {
                            var l = bodies.FindAll(bo => bones[bo.BoneIndex].Name == "ATAMA");

                            // The first one is the one on body (which is larger).
                            // The second one is what should be applied to the hair.
                            parentBody = l.Count >= 2 ? l[1] : null;

                            break;
                        }

                        case CoordSystemPart.Breasts:
                            var mune2 = _pmxCreator._boneLookup.GetPmxBoneName("MODEL_00/BASE/MUNE1/MUNE2");
                            parentBody = bodies.Find(bo => bones[bo.BoneIndex].Name == mune2);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }

                    // Now calculate rotation for this joint.
                    var childBones = bones.WhereToArray(b => b.ParentIndex == pmxBone.BoneIndex);

                    // Some models may have more than one child bone in the hair chain, e.g. ex001_003mik
                    foreach (var childBone in childBones)
                    {
                        var joint = new PmxJoint();

                        joint.BodyIndex1 = bodies.IndexOf(parentBody);
                        joint.BodyIndex2 = bodies.IndexOf(body);

                        joint.Name        = body.Name;
                        joint.NameEnglish = body.NameEnglish;

                        switch (body.Part)
                        {
                        case CoordSystemPart.Hair:
                        case CoordSystemPart.Skirt:
                            joint.Kind = JointKind.Spring6Dof;
                            break;

                        default:
                            joint.Kind = JointKind.Spring6Dof;
                            break;
                        }

                        joint.Position = pmxBone.InitialPosition;
                        PmxBone rotBone1, rotBone2;

                        if (childBones.Length == 0)
                        {
                            rotBone1 = parentBone;
                            rotBone2 = pmxBone;
                        }
                        else
                        {
                            rotBone1 = pmxBone;
                            rotBone2 = childBone;
                        }

                        Debug.Assert(rotBone2 != null, nameof(rotBone2) + " != null");

                        var delta = rotBone2.InitialPosition - rotBone1.InitialPosition;

                        var         qy = (float)Math.Atan2(delta.X, delta.Z);
                        var         qx = (float)Math.Atan2(delta.Y, delta.Z);
                        const float qz = 0;

                        joint.Rotation = new Vector3(qx, qy, qz);

                        joints.Add(joint);
                    }
                }
            }
コード例 #5
0
ファイル: PmxReader.cs プロジェクト: logchan/MLTDTools
        private PmxModel ReadPmxModel()
        {
            var model = new PmxModel();

            model.Name           = ReadString() ?? string.Empty;
            model.NameEnglish    = ReadString() ?? string.Empty;
            model.Comment        = ReadString() ?? string.Empty;
            model.CommentEnglish = ReadString() ?? string.Empty;

            ReadVertexInfo();
            ReadFaceInfo();
            ReadTextureInfo();
            ReadMaterialInfo();
            ReadBoneInfo();
            ReadMorphInfo();
            ReadNodeInfo();
            ReadRigidBodyInfo();
            ReadJointInfo();
            ReadSoftBodyInfo();

            return(model);

            void ReadVertexInfo()
            {
                var vertexCount = _reader.ReadInt32();
                var vertices    = new PmxVertex[vertexCount];

                for (var i = 0; i < vertexCount; ++i)
                {
                    vertices[i] = ReadPmxVertex();
                }

                model.Vertices = vertices;
            }

            void ReadFaceInfo()
            {
                var faceCount   = _reader.ReadInt32();
                var faceIndices = new int[faceCount];

                for (var i = 0; i < faceCount; ++i)
                {
                    faceIndices[i] = _reader.ReadVarLenIntAsInt32(VertexElementSize, true);
                }

                model.FaceTriangles = faceIndices;
            }

            void ReadTextureInfo()
            {
                var textureCount       = _reader.ReadInt32();
                var textureNameMap     = new Dictionary <int, string>();
                var textureIndexLookup = new Dictionary <string, int>();

                for (var i = 0; i < textureCount; ++i)
                {
                    var textureName = ReadString() ?? string.Empty;
                    textureNameMap[i] = textureName;
                    textureIndexLookup[textureName] = i;
                }

                textureNameMap[-1] = string.Empty;

                TextureNameMap     = textureNameMap;
                TextureIndexLookup = textureIndexLookup;
            }

            void ReadMaterialInfo()
            {
                var materialCount = _reader.ReadInt32();
                var materials     = new PmxMaterial[materialCount];

                for (var i = 0; i < materialCount; ++i)
                {
                    materials[i] = ReadPmxMaterial();
                }

                model.Materials = materials;
            }

            void ReadBoneInfo()
            {
                var boneCount = _reader.ReadInt32();
                var bones     = new PmxBone[boneCount];

                for (var i = 0; i < boneCount; ++i)
                {
                    bones[i]           = ReadPmxBone();
                    bones[i].BoneIndex = i;
                }

                model.Bones           = bones;
                model.BonesDictionary = bones.ToDictionary(bone => bone.Name);

                var rootBoneIndexList = new List <int>();

                for (var i = 0; i < bones.Length; ++i)
                {
                    var bone = bones[i];

                    if (bone.ParentIndex < 0)
                    {
                        rootBoneIndexList.Add(i);
                    }
                    else
                    {
                        bone.Parent = bones[bone.ParentIndex];
                    }

                    if (bone.AppendParentIndex >= 0)
                    {
                        bone.AppendParent = bones[bone.AppendParentIndex];
                    }

                    if (bone.ExternalParentIndex >= 0)
                    {
                        bone.ExternalParent = bones[bone.ExternalParentIndex];
                    }

                    if (bone.HasFlag(BoneFlags.IK))
                    {
                        var ik = bone.IK;

                        Debug.Assert(ik != null, nameof(ik) + " != null");

                        ik.TargetBone = bones[ik.TargetBoneIndex];

                        foreach (var link in ik.Links)
                        {
                            if (link.BoneIndex >= 0)
                            {
                                link.Bone = bones[link.BoneIndex];
                            }
                        }
                    }
                }

                model.RootBoneIndices = rootBoneIndexList.ToArray();

                foreach (var bone in bones)
                {
                    bone.SetToBindingPose();
                }
            }

            void ReadMorphInfo()
            {
                var morphCount = _reader.ReadInt32();
                var morphs     = new PmxMorph[morphCount];

                for (var i = 0; i < morphCount; ++i)
                {
                    morphs[i] = ReadPmxMorph();
                }

                model.Morphs = morphs;
            }

            void ReadNodeInfo()
            {
                var nodeCount = _reader.ReadInt32();
                var nodes     = new PmxNode[nodeCount];

                for (var i = 0; i < nodeCount; ++i)
                {
                    var node = ReadPmxNode();

                    nodes[i] = node;

                    if (node.IsSystemNode)
                    {
                        if (node.Name == "Root")
                        {
                            model.RootNodeIndex = i;
                        }
                        else if (node.Name == "表情")
                        {
                            model.FacialExpressionNodeIndex = i;
                        }
                    }
                }

                model.Nodes = nodes;
            }

            void ReadRigidBodyInfo()
            {
                var bodyCount = _reader.ReadInt32();
                var bodies    = new PmxRigidBody[bodyCount];

                for (var i = 0; i < bodyCount; ++i)
                {
                    bodies[i] = ReadPmxRigidBody();
                }

                model.RigidBodies = bodies;
            }

            void ReadJointInfo()
            {
                var jointCount = _reader.ReadInt32();
                var joints     = new PmxJoint[jointCount];

                for (var i = 0; i < jointCount; ++i)
                {
                    joints[i] = ReadPmxJoint();
                }

                model.Joints = joints;
            }

            void ReadSoftBodyInfo()
            {
                if (DetailedVersion < 2.1f)
                {
                    return;
                }

                var bodyCount = _reader.ReadInt32();
                var bodies    = new PmxSoftBody[bodyCount];

                for (var i = 0; i < bodyCount; ++i)
                {
                    bodies[i] = ReadPmxSoftBody();
                }

                model.SoftBodies = bodies;
            }
        }
コード例 #6
0
            private static void AppendJoints([NotNull, ItemNotNull] IReadOnlyList <PmxBone> bones, [NotNull, ItemNotNull] List <PmxRigidBody> bodies, [NotNull, ItemNotNull] List <PmxJoint> joints)
            {
                foreach (var body in bodies)
                {
                    var addJoint = false;

                    switch (body.Part)
                    {
                    case CoordSystemPart.Torso:
                    case CoordSystemPart.LeftArm:
                    case CoordSystemPart.RightArm:
                    case CoordSystemPart.Legs:
                    case CoordSystemPart.Head:
                        break;

                    case CoordSystemPart.Skirt:
                    case CoordSystemPart.Hair:
                    case CoordSystemPart.Breasts:
                        addJoint = true;
                        break;

                    case CoordSystemPart.Accessories:
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    if (!addJoint)
                    {
                        continue;
                    }

                    var pmxBone    = bones[body.BoneIndex];
                    var parentBone = bones[pmxBone.ParentIndex];

                    var parentBody = bodies.Find(bo => bo.BoneIndex == parentBone.BoneIndex);

                    // This rigid body is attached to a semi-root bone. Create it as a new "root" for its sub rigid bodies.
                    if (parentBody == null)
                    {
                        switch (body.Part)
                        {
                        case CoordSystemPart.Skirt:
                            var koshi = BoneUtils.GetPmxBoneName("MODEL_00/BASE/KOSHI");
                            parentBody = bodies.FirstOrDefault(bo => bones[bo.BoneIndex].Name == koshi);
                            break;

                        case CoordSystemPart.Hair:
                            // The first one is the one on body (which is larger).
                            // The second one is what should be applied to the hair.
                            parentBody = bodies.Where(bo => bones[bo.BoneIndex].Name == "ATAMA").Skip(1).FirstOrDefault();
                            break;

                        case CoordSystemPart.Breasts:
                            var mune2 = BoneUtils.GetPmxBoneName("MODEL_00/BASE/MUNE1/MUNE2");
                            parentBody = bodies.FirstOrDefault(bo => bones[bo.BoneIndex].Name == mune2);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }

                    var joint = new PmxJoint();

                    joint.BodyIndex1 = bodies.IndexOf(parentBody);
                    joint.BodyIndex2 = bodies.IndexOf(body);

                    joint.Name        = body.Name;
                    joint.NameEnglish = body.NameEnglish;

                    switch (body.Part)
                    {
                    case CoordSystemPart.Hair:
                    case CoordSystemPart.Skirt:
                        joint.Kind = JointKind.Spring6Dof;
                        break;

                    default:
                        joint.Kind = JointKind.Spring6Dof;
                        break;
                    }

                    joint.Position = pmxBone.InitialPosition;

                    // Now calculate rotation for this joint.
                    var childBones = bones.Where(b => b.ParentIndex == pmxBone.BoneIndex).ToArray();

                    if (childBones.Length > 1)
                    {
                        Debug.Print("Warning: more than one child bone for joint rotation calculation. Aborting.");
                        continue;
                    }

                    PmxBone rotBone1, rotBone2;

                    if (childBones.Length == 0)
                    {
                        rotBone1 = parentBone;
                        rotBone2 = pmxBone;
                    }
                    else
                    {
                        rotBone1 = pmxBone;
                        rotBone2 = childBones[0];
                    }

                    var delta = rotBone2.InitialPosition - rotBone1.InitialPosition;

                    var qy = (float)Math.Atan2(delta.X, delta.Z);
                    var qx = (float)Math.Atan2(delta.Y, delta.Z);
                    //const float qx = 0;
                    //var qz = (float)Math.Atan2(delta.X, delta.Y);
                    const float qz = 0;

                    joint.Rotation = new Vector3(qx, qy, qz);

                    if (joint != null)
                    {
                        joints.Add(joint);
                    }
                }
            }
コード例 #7
0
        // PMDEditor.Pmx
        internal static Pmx FromStream(Stream s, PmxElementFormat f = null)
        {
            var Ret       = new Pmx();
            var pmxHeader = new PmxHeader(2f);

            pmxHeader.FromStreamEx(s, null);
            Ret.Header = pmxHeader;
            if (pmxHeader.Ver <= 1f)
            {
                var mMD_Pmd = new MMD_Pmd();
                s.Seek(0L, SeekOrigin.Begin);
                mMD_Pmd.FromStreamEx(s, null);
                Ret.FromPmx(PmxConvert.PmdToPmx(mMD_Pmd));
                return(Ret);
            }
            Ret.ModelInfo = new PmxModelInfo();
            Ret.ModelInfo.FromStreamEx(s, pmxHeader.ElementFormat);
            var num = PmxStreamHelper.ReadElement_Int32(s, 4, true);

            Ret.VertexList = new List <PmxVertex>();
            Ret.VertexList.Clear();
            Ret.VertexList.Capacity = num;
            for (var i = 0; i < num; i++)
            {
                var pmxVertex = new PmxVertex();
                pmxVertex.FromStreamEx(s, pmxHeader.ElementFormat);
                Ret.VertexList.Add(pmxVertex);
            }
            num          = PmxStreamHelper.ReadElement_Int32(s, 4, true);
            Ret.FaceList = new List <int>();
            Ret.FaceList.Clear();
            Ret.FaceList.Capacity = num;
            for (var j = 0; j < num; j++)
            {
                var item = PmxStreamHelper.ReadElement_Int32(s, pmxHeader.ElementFormat.VertexSize, false);
                Ret.FaceList.Add(item);
            }
            var pmxTextureTable = new PmxTextureTable();

            pmxTextureTable.FromStreamEx(s, pmxHeader.ElementFormat);
            num = PmxStreamHelper.ReadElement_Int32(s, 4, true);
            Ret.MaterialList = new List <PmxMaterial>();
            Ret.MaterialList.Clear();
            Ret.MaterialList.Capacity = num;
            for (var k = 0; k < num; k++)
            {
                var pmxMaterial = new PmxMaterial();
                pmxMaterial.FromStreamEx_TexTable(s, pmxTextureTable, pmxHeader.ElementFormat);
                Ret.MaterialList.Add(pmxMaterial);
            }
            num          = PmxStreamHelper.ReadElement_Int32(s, 4, true);
            Ret.BoneList = new List <PmxBone>();
            Ret.BoneList.Clear();
            Ret.BoneList.Capacity = num;

            for (var l = 0; l < num; l++)
            {
                var pmxBone = new PmxBone();
                pmxBone.FromStreamEx(s, pmxHeader.ElementFormat);
                Ret.BoneList.Add(pmxBone);
            }
            num           = PmxStreamHelper.ReadElement_Int32(s, 4, true);
            Ret.MorphList = new List <PmxMorph>();
            Ret.MorphList.Clear();
            Ret.MorphList.Capacity = num;
            for (var m = 0; m < num; m++)
            {
                var pmxMorph = new PmxMorph();
                pmxMorph.FromStreamEx(s, pmxHeader.ElementFormat);
                Ret.MorphList.Add(pmxMorph);
            }
            num          = PmxStreamHelper.ReadElement_Int32(s, 4, true);
            Ret.NodeList = new List <PmxNode>();
            Ret.NodeList.Clear();
            Ret.NodeList.Capacity = num;
            for (var n = 0; n < num; n++)
            {
                var pmxNode = new PmxNode();
                pmxNode.FromStreamEx(s, pmxHeader.ElementFormat);
                Ret.NodeList.Add(pmxNode);
                if (Ret.NodeList[n].SystemNode)
                {
                    if (Ret.NodeList[n].Name == "Root")
                    {
                        Ret.RootNode = Ret.NodeList[n];
                    }
                    else if (Ret.NodeList[n].Name == "表情")
                    {
                        Ret.ExpNode = Ret.NodeList[n];
                    }
                }
            }
            num          = PmxStreamHelper.ReadElement_Int32(s, 4, true);
            Ret.BodyList = new List <PmxBody>();
            Ret.BodyList.Clear();
            Ret.BodyList.Capacity = num;
            for (var num2 = 0; num2 < num; num2++)
            {
                var pmxBody = new PmxBody();
                pmxBody.FromStreamEx(s, pmxHeader.ElementFormat);
                Ret.BodyList.Add(pmxBody);
            }
            num           = PmxStreamHelper.ReadElement_Int32(s, 4, true);
            Ret.JointList = new List <PmxJoint>();
            Ret.JointList.Clear();
            Ret.JointList.Capacity = num;
            for (var num3 = 0; num3 < num; num3++)
            {
                var pmxJoint = new PmxJoint();
                pmxJoint.FromStreamEx(s, pmxHeader.ElementFormat);
                Ret.JointList.Add(pmxJoint);
            }
            return(Ret);
        }