예제 #1
0
파일: PMD.cs 프로젝트: ruly-rudel/ruly
        private void parseIKList(BinaryReader br)
        {
            // the number of Vertexes
            short num = br.ReadInt16();

            Log.Debug("PMD", "IK: " + num.ToString());
            if (num > 0)
            {
                IK = new IK[num];
                for (int i = 0; i < num; i++)
                {
                    IK ik = new IK();

                    ik.ik_bone_index        = br.ReadInt16();
                    ik.ik_target_bone_index = br.ReadInt16();
                    ik.ik_chain_length      = br.ReadByte();
                    ik.iterations           = br.ReadInt16();
                    ik.control_weight       = br.ReadSingle();

                    ik.ik_child_bone_index = new short[ik.ik_chain_length];
                    for (int j = 0; j < ik.ik_chain_length; j++)
                    {
                        ik.ik_child_bone_index[j] = br.ReadInt16();
                    }

                    IK[i] = ik;
                }
            }
            else
            {
                IK = null;
            }
        }
예제 #2
0
        public void Load(string filename)
        {
            using (var fs = File.OpenRead(filename))
                using (var bs = new BinaryReader(fs))
                {
                    // header
                    string s = bs.ReadString();
                    Log.Debug("RMC", "MAGIC: " + s);

                    // VertNormUv
                    Log.Debug("RMC", "VertNormUv");
                    VertNormUv = ReadFloats(bs);

                    // Index
                    Log.Debug("RMC", "Index");
                    Index = ReadShorts(bs);

                    // Bone
                    Log.Debug("RMC", "Bone");
                    Bones = new Bone[bs.ReadUInt32()];
                    Log.Debug("RMC", "count : " + Bones.Length.ToString());
                    for (int i = 0; i < Bones.Length; i++)
                    {
                        Bones[i]          = new Bone();
                        Bones[i].name     = bs.ReadString();
                        Bones[i].parent   = bs.ReadInt16();
                        Bones[i].tail     = bs.ReadInt16();
                        Bones[i].type     = bs.ReadByte();
                        Bones[i].ik       = bs.ReadInt16();
                        Bones[i].head_pos = ReadFloats(bs, 3);
                        Bones[i].is_leg   = bs.ReadBoolean();
                    }

                    // IKs
                    Log.Debug("RMC", "IK");
                    IKs = new IK[bs.ReadUInt32()];
                    Log.Debug("RMC", "count : " + IKs.Length.ToString());
                    for (int i = 0; i < IKs.Length; i++)
                    {
                        IKs[i] = new IK();
                        IKs[i].ik_bone_index        = bs.ReadInt32();
                        IKs[i].ik_target_bone_index = bs.ReadInt32();
                        IKs[i].ik_chain_length      = bs.ReadByte();
                        IKs[i].iterations           = bs.ReadInt32();
                        IKs[i].control_weight       = bs.ReadSingle();
                        IKs[i].ik_child_bone_index  = new short[bs.ReadUInt32()];
                        for (int j = 0; j < IKs[i].ik_child_bone_index.Length; j++)
                        {
                            IKs[i].ik_child_bone_index[j] = bs.ReadInt16();
                        }
                    }

                    // Materials
                    Log.Debug("RMC", "Material");
                    Materials = new FMaterial[bs.ReadUInt32()];
                    Log.Debug("RMC", "count : " + Materials.Length.ToString());
                    for (int i = 0; i < Materials.Length; i++)
                    {
                        Materials[i] = new FMaterial();


                        Materials[i].diffuse_color   = ReadFloats(bs, 4);
                        Materials[i].power           = bs.ReadSingle();
                        Materials[i].specular_color  = ReadFloats(bs, 3);
                        Materials[i].emmisive_color  = ReadFloats(bs, 3);
                        Materials[i].toon_index      = bs.ReadByte();
                        Materials[i].edge_flag       = bs.ReadByte();
                        Materials[i].face_vert_count = bs.ReadInt32();
                        if (bs.ReadBoolean())
                        {
                            Materials[i].texture = bs.ReadString();
                            Log.Debug("RMC", "load texture in material ... " + Materials[i].texture);
                            var sf = bs.ReadByte();
                            if (sf == 1)
                            {
                                Materials[i].sph = bs.ReadString();
                                Materials[i].spa = null;
                                Log.Debug("RMC", "load sphere(sph) in material ... " + Materials[i].sph);
                            }
                            else if (sf == 2)
                            {
                                Materials[i].sph = null;
                                Materials[i].spa = bs.ReadString();
                                Log.Debug("RMC", "load sphere(spa) in material ... " + Materials[i].spa);
                            }
                        }
                        Materials[i].face_vert_offset = bs.ReadInt32();
                        Materials[i].bone_num         = bs.ReadInt32();
                        Log.Debug("RMC", "Bone num: " + Materials[i].bone_num.ToString());
                        Materials[i].weight       = bs.ReadBytes(VertNormUv.Length / 8 * 3);
                        Materials[i].bone_inv_map = new int[48]; // ad-hock
                        for (int j = 0; j < Materials[i].bone_inv_map.Length; j++)
                        {
                            Materials[i].bone_inv_map[j] = bs.ReadInt32();
                        }
                    }

                    // ToonNames
                    Log.Debug("RMC", "ToonNames");
                    ToonNames = new string[11];
                    for (int i = 0; i < 11; i++)
                    {
                        ToonNames[i] = bs.ReadString();
                        Log.Debug("RMC", ToonNames[i]);
                    }
                }
        }
예제 #3
0
파일: PMD.cs 프로젝트: ruly-rudel/ruly
        private void parseIKList(BinaryReader br)
        {
            // the number of Vertexes
            short num = br.ReadInt16();
            Log.Debug("PMD", "IK: " + num.ToString());
            if (num > 0) {
                IK = new IK[num];
                for (int i = 0; i < num; i++) {
                    IK ik = new IK();

                    ik.ik_bone_index = br.ReadInt16();
                    ik.ik_target_bone_index = br.ReadInt16();
                    ik.ik_chain_length = br.ReadByte();
                    ik.iterations = br.ReadInt16();
                    ik.control_weight = br.ReadSingle();

                    ik.ik_child_bone_index = new short[ik.ik_chain_length];
                    for (int j = 0; j < ik.ik_chain_length; j++) {
                        ik.ik_child_bone_index[j] = br.ReadInt16();
                    }

                    IK[i] = ik;
                }
            } else {
                IK = null;
            }
        }
예제 #4
0
파일: PMF.cs 프로젝트: ruly-rudel/ruly
        public void Load(string filename)
        {
            using(var fs = File.OpenRead(filename))
            using(var bs = new BinaryReader(fs))
            {
                // header
                string s = bs.ReadString();
                Log.Debug("RMC", "MAGIC: " + s);

                // VertNormUv
                Log.Debug("RMC", "VertNormUv");
                VertNormUv = ReadFloats(bs);

                // Index
                Log.Debug("RMC", "Index");
                Index = ReadShorts(bs);

                // Bone
                Log.Debug("RMC", "Bone");
                Bones = new Bone[bs.ReadUInt32()];
                Log.Debug("RMC", "count : " + Bones.Length.ToString());
                for (int i = 0; i < Bones.Length; i++)
                {
                    Bones[i] = new Bone();
                    Bones[i].name = bs.ReadString();
                    Bones[i].parent = bs.ReadInt16();
                    Bones[i].tail = bs.ReadInt16();
                    Bones[i].type = bs.ReadByte();
                    Bones[i].ik = bs.ReadInt16();
                    Bones[i].head_pos = ReadFloats(bs, 3);
                    Bones[i].is_leg = bs.ReadBoolean();
                }

                // IKs
                Log.Debug("RMC", "IK");
                IKs = new IK[bs.ReadUInt32()];
                Log.Debug("RMC", "count : " + IKs.Length.ToString());
                for (int i = 0; i < IKs.Length; i++)
                {
                    IKs[i] = new IK();
                    IKs[i].ik_bone_index = bs.ReadInt32();
                    IKs[i].ik_target_bone_index = bs.ReadInt32();
                    IKs[i].ik_chain_length = bs.ReadByte();
                    IKs[i].iterations = bs.ReadInt32();
                    IKs[i].control_weight = bs.ReadSingle();
                    IKs[i].ik_child_bone_index = new short[bs.ReadUInt32()];
                    for (int j = 0; j < IKs[i].ik_child_bone_index.Length; j++)
                    {
                        IKs[i].ik_child_bone_index[j] = bs.ReadInt16();
                    }
                }

                // Materials
                Log.Debug("RMC", "Material");
                Materials = new FMaterial[bs.ReadUInt32()];
                Log.Debug("RMC", "count : " + Materials.Length.ToString());
                for (int i = 0; i < Materials.Length; i++)
                {
                    Materials[i] = new FMaterial();

                    Materials[i].diffuse_color = ReadFloats(bs, 4);
                    Materials[i].power = bs.ReadSingle();
                    Materials[i].specular_color = ReadFloats(bs, 3);
                    Materials[i].emmisive_color = ReadFloats(bs, 3);
                    Materials[i].toon_index = bs.ReadByte();
                    Materials[i].edge_flag = bs.ReadByte();
                    Materials[i].face_vert_count = bs.ReadInt32();
                    if (bs.ReadBoolean())
                    {
                        Materials[i].texture = bs.ReadString();
                        Log.Debug("RMC", "load texture in material ... " + Materials[i].texture);
                        var sf = bs.ReadByte();
                        if (sf == 1)
                        {
                            Materials[i].sph = bs.ReadString();
                            Materials[i].spa = null;
                            Log.Debug("RMC", "load sphere(sph) in material ... " + Materials[i].sph);
                        } else if (sf == 2)
                        {
                            Materials[i].sph = null;
                            Materials[i].spa = bs.ReadString();
                            Log.Debug("RMC", "load sphere(spa) in material ... " + Materials[i].spa);
                        }
                    }
                    Materials[i].face_vert_offset = bs.ReadInt32();
                    Materials[i].bone_num = bs.ReadInt32();
                    Log.Debug("RMC", "Bone num: " + Materials[i].bone_num.ToString());
                    Materials[i].weight = bs.ReadBytes(VertNormUv.Length / 8 * 3);
                    Materials[i].bone_inv_map = new int[48];    // ad-hock
                    for (int j = 0; j < Materials[i].bone_inv_map.Length; j++)
                    {
                        Materials[i].bone_inv_map[j] = bs.ReadInt32();
                    }
                }

                // ToonNames
                Log.Debug("RMC", "ToonNames");
                ToonNames = new string[11];
                for (int i = 0; i < 11; i++)
                {
                    ToonNames[i] = bs.ReadString();
                    Log.Debug("RMC", ToonNames[i]);
                }
            }
        }
예제 #5
0
파일: Shell.cs 프로젝트: ruly-rudel/ruly
        private void ccdIK1(IK ik)
        {
            var effecterVecs = new float[4];
            var targetVecs = new float[4];
            var targetInvs = new float[4];
            var effecterInvs = new float[4];
            var axis = new float[3];
            var mQuatworks = new double[4];
            var mMatworks = new float[16];

            var effecter = Surface.RenderBones[ik.ik_bone_index];
            var target = Surface.RenderBones[ik.ik_target_bone_index];

            getCurrentPosition(effecterVecs, effecter);

            for (int i = 0; i < ik.iterations; i++) {
                for (int j = 0; j < ik.ik_chain_length; j++) {
                    var b = Surface.RenderBones[ik.ik_child_bone_index[j]];

                    clearUpdateFlags(b, target);
                    getCurrentPosition(targetVecs, target);

                    if (b.bone.is_leg) {
                        if (i == 0) {
                            var ba = Surface.RenderBones[ik.ik_child_bone_index[ik.ik_chain_length - 1]];
                            getCurrentPosition(targetInvs, b);
                            getCurrentPosition(effecterInvs, ba);

                            double eff_len = Matrix.Length(effecterVecs[0] - effecterInvs[0], effecterVecs[1] - effecterInvs[1], effecterVecs[2] - effecterInvs[2]);
                            double b_len = Matrix.Length(targetInvs[0] - effecterInvs[0], targetInvs[1] - effecterInvs[1], targetInvs[2] - effecterInvs[2]);
                            double t_len = Matrix.Length(targetVecs[0] - targetInvs[0], targetVecs[1] - targetInvs[1], targetVecs[2] - targetInvs[2]);

                            double angle1 = Math.Acos((eff_len * eff_len - b_len * b_len - t_len * t_len) / (2 * b_len * t_len));
                            if (!double.IsNaN(angle1)) {
                                axis[0] = -1;
                                axis[1] = axis[2] = 0;
                                Quaternion.createFromAngleAxis(mQuatworks, angle1, axis);
                                Quaternion.mul(b.quaternion, b.quaternion, mQuatworks);
                                Quaternion.toMatrixPreserveTranslate(b.matrix_current, b.quaternion);
                            }
                        }
                        continue;
                    }

                    if (Matrix.Length(targetVecs[0] - effecterVecs[0], targetVecs[1] - effecterVecs[1], targetVecs[2] - effecterVecs[2]) < 0.001f) {
                        // clear all
                        foreach (var c in Surface.RenderBones) {
                            c.updated = false;
                        }
                        return;
                    }

                    float[] current = getCurrentMatrix(b);
                    Vector.invertM(mMatworks, 0, current, 0);
                    Matrix.MultiplyMV(effecterInvs, 0, mMatworks, 0, effecterVecs, 0);
                    Matrix.MultiplyMV(targetInvs, 0, mMatworks, 0, targetVecs, 0);

                    // calculate rotation angle/axis
                    Vector.normalize(effecterInvs);
                    Vector.normalize(targetInvs);
                    double angle2 = Math.Acos(Vector.dot(effecterInvs, targetInvs));
                    angle2 *= ik.control_weight;

                    if (!double.IsNaN(angle2)) {
                        Vector.cross(axis, targetInvs, effecterInvs);
                        Vector.normalize(axis);

                        if (!double.IsNaN(axis[0]) && !double.IsNaN(axis[1]) && !double.IsNaN(axis[2])) {
                            Quaternion.createFromAngleAxis(mQuatworks, angle2, axis);
                            Quaternion.mul(b.quaternion, b.quaternion, mQuatworks);
                            Quaternion.toMatrixPreserveTranslate(b.matrix_current, b.quaternion);
                        }
                    }
                }
            }
            // clear all
            foreach (var b in Surface.RenderBones) {
                b.updated = false;
            }
        }
예제 #6
0
파일: Shell.cs 프로젝트: ruly-rudel/ruly
        private void ccdIK1(IK ik)
        {
            var effecterVecs = new float[4];
            var targetVecs   = new float[4];
            var targetInvs   = new float[4];
            var effecterInvs = new float[4];
            var axis         = new float[3];
            var mQuatworks   = new double[4];
            var mMatworks    = new float[16];

            var effecter = Surface.RenderBones[ik.ik_bone_index];
            var target   = Surface.RenderBones[ik.ik_target_bone_index];

            getCurrentPosition(effecterVecs, effecter);

            for (int i = 0; i < ik.iterations; i++)
            {
                for (int j = 0; j < ik.ik_chain_length; j++)
                {
                    var b = Surface.RenderBones[ik.ik_child_bone_index[j]];

                    clearUpdateFlags(b, target);
                    getCurrentPosition(targetVecs, target);

                    if (b.bone.is_leg)
                    {
                        if (i == 0)
                        {
                            var ba = Surface.RenderBones[ik.ik_child_bone_index[ik.ik_chain_length - 1]];
                            getCurrentPosition(targetInvs, b);
                            getCurrentPosition(effecterInvs, ba);

                            double eff_len = Matrix.Length(effecterVecs[0] - effecterInvs[0], effecterVecs[1] - effecterInvs[1], effecterVecs[2] - effecterInvs[2]);
                            double b_len   = Matrix.Length(targetInvs[0] - effecterInvs[0], targetInvs[1] - effecterInvs[1], targetInvs[2] - effecterInvs[2]);
                            double t_len   = Matrix.Length(targetVecs[0] - targetInvs[0], targetVecs[1] - targetInvs[1], targetVecs[2] - targetInvs[2]);

                            double angle1 = Math.Acos((eff_len * eff_len - b_len * b_len - t_len * t_len) / (2 * b_len * t_len));
                            if (!double.IsNaN(angle1))
                            {
                                axis[0] = -1;
                                axis[1] = axis[2] = 0;
                                Quaternion.createFromAngleAxis(mQuatworks, angle1, axis);
                                Quaternion.mul(b.quaternion, b.quaternion, mQuatworks);
                                Quaternion.toMatrixPreserveTranslate(b.matrix_current, b.quaternion);
                            }
                        }
                        continue;
                    }

                    if (Matrix.Length(targetVecs[0] - effecterVecs[0], targetVecs[1] - effecterVecs[1], targetVecs[2] - effecterVecs[2]) < 0.001f)
                    {
                        // clear all
                        foreach (var c in Surface.RenderBones)
                        {
                            c.updated = false;
                        }
                        return;
                    }

                    float[] current = getCurrentMatrix(b);
                    Vector.invertM(mMatworks, 0, current, 0);
                    Matrix.MultiplyMV(effecterInvs, 0, mMatworks, 0, effecterVecs, 0);
                    Matrix.MultiplyMV(targetInvs, 0, mMatworks, 0, targetVecs, 0);

                    // calculate rotation angle/axis
                    Vector.normalize(effecterInvs);
                    Vector.normalize(targetInvs);
                    double angle2 = Math.Acos(Vector.dot(effecterInvs, targetInvs));
                    angle2 *= ik.control_weight;

                    if (!double.IsNaN(angle2))
                    {
                        Vector.cross(axis, targetInvs, effecterInvs);
                        Vector.normalize(axis);

                        if (!double.IsNaN(axis[0]) && !double.IsNaN(axis[1]) && !double.IsNaN(axis[2]))
                        {
                            Quaternion.createFromAngleAxis(mQuatworks, angle2, axis);
                            Quaternion.mul(b.quaternion, b.quaternion, mQuatworks);
                            Quaternion.toMatrixPreserveTranslate(b.matrix_current, b.quaternion);
                        }
                    }
                }
            }
            // clear all
            foreach (var b in Surface.RenderBones)
            {
                b.updated = false;
            }
        }