Beispiel #1
0
        private void WritePmxVertex([NotNull] PmxModel model, [NotNull] PmxVertex vertex)
        {
            _writer.Write(vertex.Position);
            _writer.Write(vertex.Normal);
            _writer.Write(vertex.UV);

            for (var i = 0; i < model.UvaCount && i < PmxVertex.MaxUvaCount; ++i)
            {
                _writer.Write(vertex.Uva[i]);
            }

            _writer.Write((byte)vertex.Deformation);

            switch (vertex.Deformation)
            {
            case Deformation.Bdef1:
                _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[0].BoneIndex, BoneElementSize);
                break;

            case Deformation.Bdef2:
                _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[0].BoneIndex, BoneElementSize);
                _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[1].BoneIndex, BoneElementSize);
                _writer.Write(vertex.BoneWeights[0].Weight);
                break;

            case Deformation.Bdef4:
            case Deformation.Qdef:
                _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[0].BoneIndex, BoneElementSize);
                _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[1].BoneIndex, BoneElementSize);
                _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[2].BoneIndex, BoneElementSize);
                _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[3].BoneIndex, BoneElementSize);
                _writer.Write(vertex.BoneWeights[0].Weight);
                _writer.Write(vertex.BoneWeights[1].Weight);
                _writer.Write(vertex.BoneWeights[2].Weight);
                _writer.Write(vertex.BoneWeights[3].Weight);
                break;

            case Deformation.Sdef: {
                _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[0].BoneIndex, BoneElementSize);
                _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[1].BoneIndex, BoneElementSize);
                _writer.Write(vertex.BoneWeights[0].Weight);

                _writer.Write(vertex.C0);
                _writer.Write(vertex.R0);
                _writer.Write(vertex.R1);

                break;
            }

            default:
                throw new ArgumentOutOfRangeException();
            }

            _writer.Write(vertex.EdgeScale);
        }
        private void CreateMeshList(SkinnedMeshRenderer meshRender)
        {
            GameObject gameObject = meshRender.gameObject;
            Mesh       mesh       = meshRender.sharedMesh;

            BoneWeight[] boneWeights = mesh.boneWeights;
            vertexIndexMap.Add(gameObject.transform.parent.gameObject.name, pmxFile.VertexList.Count);
            if (SavePostion)
            {
                Mesh mesh2 = new Mesh();
                meshRender.BakeMesh(mesh2);
                mesh = mesh2;
            }
            UnityEngine.Vector2[] uv       = mesh.uv;
            UnityEngine.Vector2[] uv2      = mesh.uv2;
            UnityEngine.Vector3[] normals  = mesh.normals;
            UnityEngine.Vector3[] vertices = mesh.vertices;
            for (int i = 0; i < mesh.subMeshCount; i++)
            {
                int[] triangles = mesh.GetTriangles(i);
                AddFaceList(triangles, vertexCount);
                CreateMaterial(meshRender.materials[i], triangles.Length);
            }
            vertexCount += mesh.vertexCount;
            for (int i = 0; i < mesh.vertexCount; i++)
            {
                PmxVertex pmxVertex = new PmxVertex();
                pmxVertex.UV = new PmxLib.Vector2(uv[i].x, -uv[i].y);
                ConvertBoneWeight(pmxVertex.Weight, boneWeights[i], meshRender.bones);
                Transform           t = gameObject.transform;
                UnityEngine.Vector3 n = normals[i];
                n = t.TransformDirection(n);
                pmxVertex.Normal = ToPmxVec3(n);
                UnityEngine.Vector3 v = vertices[i];
                v  = t.TransformPoint(v);
                v *= scaleFactor;
                pmxVertex.Position = ToPmxVec3(v);
                pmxVertex.UpdateDeformType();
                pmxFile.VertexList.Add(pmxVertex);
            }
        }
Beispiel #3
0
        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;
            }
        }
Beispiel #4
0
        private PmxVertex ReadPmxVertex()
        {
            var vertex = new PmxVertex();

            vertex.Position = _reader.ReadVector3();
            vertex.Normal   = _reader.ReadVector3();
            vertex.UV       = _reader.ReadVector2();

            for (var i = 0; i < UvaCount && i < PmxVertex.MaxUvaCount; ++i)
            {
                vertex.Uva[i] = _reader.ReadVector4();
            }

            vertex.Deformation = (Deformation)_reader.ReadByte();

            switch (vertex.Deformation)
            {
            case Deformation.Bdef1:
                vertex.BoneWeights[0].BoneIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize);
                vertex.BoneWeights[0].Weight    = 1;
                break;

            case Deformation.Bdef2:
                vertex.BoneWeights[0].BoneIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize);
                vertex.BoneWeights[1].BoneIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize);
                vertex.BoneWeights[0].Weight    = _reader.ReadSingle();
                vertex.BoneWeights[1].Weight    = 1 - vertex.BoneWeights[0].Weight;
                break;

            case Deformation.Bdef4:
            case Deformation.Qdef:
                vertex.BoneWeights[0].BoneIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize);
                vertex.BoneWeights[1].BoneIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize);
                vertex.BoneWeights[2].BoneIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize);
                vertex.BoneWeights[3].BoneIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize);
                vertex.BoneWeights[0].Weight    = _reader.ReadSingle();
                vertex.BoneWeights[1].Weight    = _reader.ReadSingle();
                vertex.BoneWeights[2].Weight    = _reader.ReadSingle();
                vertex.BoneWeights[3].Weight    = _reader.ReadSingle();
                break;

            case Deformation.Sdef: {
                vertex.BoneWeights[0].BoneIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize);
                vertex.BoneWeights[1].BoneIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize);
                vertex.BoneWeights[0].Weight    = _reader.ReadSingle();
                vertex.BoneWeights[1].Weight    = 1 - vertex.BoneWeights[0].Weight;

                vertex.C0 = _reader.ReadVector3();
                vertex.R0 = _reader.ReadVector3();
                vertex.R1 = _reader.ReadVector3();

                var vec = vertex.R0 * vertex.BoneWeights[0].Weight + vertex.R1 * vertex.BoneWeights[1].Weight;

                vertex.RW0 = vertex.R0 - vec;
                vertex.RW1 = vertex.R1 - vec;
            }
            break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            vertex.EdgeScale = _reader.ReadSingle();

            return(vertex);
        }
Beispiel #5
0
        private static IReadOnlyList <PmxVertex> AddVertices([NotNull] Avatar combinedAvatar, [NotNull] Mesh combinedMesh, int bodyMeshVertexCount)
        {
            var vertexCount = combinedMesh.VertexCount;
            var vertices    = new PmxVertex[vertexCount];
            // In case that vertex count is more than skin count (ill-formed MLTD models: ch_ex005_022ser)
            var skinCount = combinedMesh.Skin.Count;

            for (var i = 0; i < vertexCount; ++i)
            {
                var vertex = new PmxVertex();

                var position = combinedMesh.Vertices[i];
                var normal   = combinedMesh.Normals[i];
                var uv       = combinedMesh.UV1[i];

                vertex.Position = position.ToOpenTK().FixUnityToOpenTK();

                if (ConversionConfig.Current.ScaleToPmxSize)
                {
                    vertex.Position = vertex.Position * ScalingConfig.ScaleUnityToPmx;
                }

                vertex.Normal = normal.ToOpenTK().FixUnityToOpenTK();

                OpenTK.Vector2 fixedUv;

                // Body, then head.
                // TODO: For heads, inverting/flipping is different among models?
                // e.g. ss001_015siz can be processed via the method below; gs001_201xxx's head UVs are not inverted but some are flipped.
                if (i < bodyMeshVertexCount)
                {
                    // Invert UV!
                    fixedUv = new OpenTK.Vector2(uv.X, 1 - uv.Y);
                }
                else
                {
                    fixedUv = uv.ToOpenTK();
                }

                vertex.UV = fixedUv;

                vertex.EdgeScale = 1.0f;

                var skin = i < skinCount ? combinedMesh.Skin[i] : null;
                var affectiveInfluenceCount = skin != null?skin.Count(inf => inf != null) : 0;

                switch (affectiveInfluenceCount)
                {
                case 0:
                    // This vertex is static. It is not attached to any bone.
                    break;

                case 1:
                    vertex.Deformation = Deformation.Bdef1;
                    break;

                case 2:
                    vertex.Deformation = Deformation.Bdef2;
                    break;

                case 3:
                    throw new NotSupportedException($"Not supported: vertex #{i} has 3 influences.");

                case 4:
                    vertex.Deformation = Deformation.Bdef4;
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(affectiveInfluenceCount), "Unsupported number of bones.");
                }

                for (var j = 0; j < affectiveInfluenceCount; ++j)
                {
                    var boneId        = combinedMesh.BoneNameHashes[skin[j].BoneIndex];
                    var realBoneIndex = combinedAvatar.AvatarSkeleton.NodeIDs.FindIndex(boneId);

                    if (realBoneIndex < 0)
                    {
                        throw new ArgumentOutOfRangeException(nameof(realBoneIndex));
                    }

                    vertex.BoneWeights[j].BoneIndex = realBoneIndex;
                    vertex.BoneWeights[j].Weight    = skin[j].Weight;
                }

                vertices[i] = vertex;
            }

            return(vertices);
        }
        // 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);
        }