예제 #1
0
 public static void read(MmdVector3 i_dest, DataReader i_reader)
 {
     i_dest.x = i_reader.readFloat();
     i_dest.y = i_reader.readFloat();
     i_dest.z = i_reader.readFloat();
     return;
 }
예제 #2
0
        public void updateNeckBone(float i_x, float i_y, float i_z)
        {
            MmdVector3 looktarget = this.__updateNeckBone_looktarget;

            looktarget.x = i_x;
            looktarget.y = i_y;
            looktarget.z = i_z;
            if (this.m_pNeckBone == null)
            {
                return;
            }
            this.m_pNeckBone.lookAt(looktarget);

            PmdBone[] bone_array = this._ref_pmd_model.getBoneArray();
            int       i;

            for (i = 0; i < bone_array.Length; i++)
            {
                if (this.m_pNeckBone == bone_array[i])
                {
                    break;
                }
            }
            for (; i < bone_array.Length; i++)
            {
                bone_array[i].updateMatrix();
            }
            return;
        }
예제 #3
0
 public static void write(MmdVector3 i_dest, DataWriter i_writer)
 {
     i_writer.writeFloat(i_dest.x);
     i_writer.writeFloat(i_dest.y);
     i_writer.writeFloat(i_dest.z);
     return;
 }
예제 #4
0
        private PmdBone m_pNeckBone;            // 首のボーン


        private void getMotionPosRot(MotionData pMotionData, float fFrame, MmdVector3 pvec3Pos, MmdVector4 pvec4Rot)
        {
            int i;
            int ulNumKeyFrame = pMotionData.ulNumKeyFrames;

            // 最終フレームを過ぎていた場合
            if (fFrame > pMotionData.pKeyFrames[ulNumKeyFrame - 1].fFrameNo)
            {
                fFrame = pMotionData.pKeyFrames[ulNumKeyFrame - 1].fFrameNo;
            }

            // 現在の時間がどのキー近辺にあるか
            for (i = 0; i < ulNumKeyFrame; i++)
            {
                if (fFrame <= pMotionData.pKeyFrames[i].fFrameNo)
                {
                    break;
                }
            }

            // 前後のキーを設定
            int lKey0,
                lKey1;

            lKey0 = i - 1;
            lKey1 = i;

            if (lKey0 <= 0)
            {
                lKey0 = 0;
            }
            if (i == ulNumKeyFrame)
            {
                lKey1 = ulNumKeyFrame - 1;
            }

            // 前後のキーの時間
            float fTime0 = pMotionData.pKeyFrames[lKey0].fFrameNo;
            float fTime1 = pMotionData.pKeyFrames[lKey1].fFrameNo;

            // 前後のキーの間でどの位置にいるか
            float fLerpValue;

            if (lKey0 != lKey1)
            {
                fLerpValue = (fFrame - fTime0) / (fTime1 - fTime0);
                pvec3Pos.Vector3Lerp(pMotionData.pKeyFrames[lKey0].vec3Position, pMotionData.pKeyFrames[lKey1].vec3Position, fLerpValue);
                pvec4Rot.QuaternionSlerp(pMotionData.pKeyFrames[lKey0].vec4Rotate, pMotionData.pKeyFrames[lKey1].vec4Rotate, fLerpValue);
                pvec4Rot.QuaternionNormalize(pvec4Rot);//これほんとにいるの?
            }
            else
            {
                pvec3Pos.setValue(pMotionData.pKeyFrames[lKey0].vec3Position);
                pvec4Rot.setValue(pMotionData.pKeyFrames[lKey0].vec4Rotate);
            }
        }
예제 #5
0
        //この関数でthis._vertex_arrayを更新する。
        public void updateSkinning(MmdMatrix[] i_skinning_mat)
        {
            MmdPmdModel pmd = this._ref_pmd;
            int         number_of_vertex = pmd.getNumberOfVertex();

            MmdVector3[]  org_pos_array    = pmd.getPositionArray();
            MmdVector3[]  org_normal_array = pmd.getNormatArray();
            PmdSkinInfo[] org_skin_info    = pmd.getSkinInfoArray();
            CustomVertex.PositionNormalTextured[] vertex_array = this._vertex_array;
            // 頂点スキニング
            MmdMatrix  matTemp  = new MmdMatrix();
            MmdVector3 position = new MmdVector3();
            MmdVector3 normal   = new MmdVector3();

            for (int i = 0; i < number_of_vertex; i++)
            {
                PmdSkinInfo si = org_skin_info[i];
                if (si.fWeight == 0.0f)
                {
                    MmdMatrix mat = i_skinning_mat[si.unBoneNo[1]];
                    position.Vector3Transform(org_pos_array[i], mat);
                    normal.Vector3Rotate(org_normal_array[i], mat);
                }
                else if (si.fWeight >= 0.9999f)
                {
                    MmdMatrix mat = i_skinning_mat[si.unBoneNo[0]];
                    position.Vector3Transform(org_pos_array[i], mat);
                    normal.Vector3Rotate(org_normal_array[i], mat);
                }
                else
                {
                    MmdMatrix mat0 = i_skinning_mat[si.unBoneNo[0]];
                    MmdMatrix mat1 = i_skinning_mat[si.unBoneNo[1]];
                    matTemp.MatrixLerp(mat0, mat1, si.fWeight);
                    position.Vector3Transform(org_pos_array[i], matTemp);
                    normal.Vector3Rotate(org_normal_array[i], matTemp);
                }
                //ここの転写は少し考える。
                vertex_array[i].X  = position.x;
                vertex_array[i].Y  = position.y;
                vertex_array[i].Z  = position.z;
                vertex_array[i].Nx = normal.x;
                vertex_array[i].Ny = normal.y;
                vertex_array[i].Nz = normal.z;
            }
            return;
        }
예제 #6
0
파일: PmdIK.cs 프로젝트: nyatla/nymmd
        private void limitAngle(MmdVector4 pvec4Out, MmdVector4 pvec4Src)
        {
            MmdVector3 vec3Angle = this._work_vector3[0];

            // XYZ軸回転の取得
            vec3Angle.QuaternionToEuler(pvec4Src);

            // 角度制限
            if (vec3Angle.x < -Math.PI)
            {
                vec3Angle.x = (float)-Math.PI;
            }
            if (-0.002f < vec3Angle.x)
            {
                vec3Angle.x = -0.002f;
            }
            vec3Angle.y = 0.0f;
            vec3Angle.z = 0.0f;

            // XYZ軸回転からクォータニオンへ
            pvec4Out.QuaternionCreateEuler(vec3Angle);
            return;
        }
예제 #7
0
        // (ベクトル1→ベクトル2)にフィットするような剛体を生成
        public void MakeBodyFromTwoVector(string bone_name, MmdVector3 v1, MmdVector3 v2)
        {
            PMD_RigidBody rigidbody = new PMD_RigidBody();

            rigidbody.rigidbody_name = bone_name; // 諸データ:名称 // 頭
            rigidbody.rigidbody_rel_bone_index = GetBoneIDByName(bone_name); // 諸データ:関連ボーン番号 // 03 00 == 3 // 頭
 
            float x1 = v1.x;
            float y1 = v1.y;
            float z1 = v1.z;
            float x2 = v2.x;
            float y2 = v2.y;
            float z2 = v2.z;
            double L = Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1));
            rigidbody.pos_pos.x = (x1 + x2) / 2.0f - x1; // 位置:位置(x, y, z)
            rigidbody.pos_pos.y = (y1 + y2) / 2.0f - y1; // 位置:位置(x, y, z)
            rigidbody.pos_pos.z = (z1 + z2) / 2.0f - z1; // 位置:位置(x, y, z)
            if (y1 >= y2) rigidbody.pos_rot.x = (float)Math.Asin((z1 - z2) / L); // 位置:回転(rad(x), rad(y), rad(z))
            else rigidbody.pos_rot.x = (float)Math.Asin((z2 - z1) / L);
            if (y1 >= y2) rigidbody.pos_rot.z = (float)Math.Asin(-(x1 - x2) / L); // 位置:回転(rad(x), rad(y), rad(z))
            else rigidbody.pos_rot.z = (float)Math.Asin(-(x2 - x1) / L);

            rigidbody.rigidbody_group_index = 0; // 諸データ:グループ // 00
            rigidbody.rigidbody_group_target = -1; // 諸データ:グループ:対象 // 0xFFFFとの差 // 38 FE
            rigidbody.shape_type = 2; // 形状:タイプ(0:球、1:箱、2:カプセル) // 00 // 球
            rigidbody.shape_w = 0.4f; // 形状:半径(幅) // CD CC CC 3F // 1.6
            rigidbody.shape_h = (float)(L * 0.8); // 形状:高さ // CD CC CC 3D // 0.1

            rigidbody.rigidbody_weight = 0.5f; // 諸データ:質量 // 00 00 80 3F // 1.0
            rigidbody.rigidbody_pos_dim = 0.5f; // 諸データ:移動減 // 00 00 00 00
            rigidbody.rigidbody_rot_dim = 0.5f; // 諸データ:回転減 // 00 00 00 00
            rigidbody.rigidbody_recoil = 0.0f; // 諸データ:反発力 // 00 00 00 00
            rigidbody.rigidbody_friction = 0.0f; // 諸データ:摩擦力 // 00 00 00 00
            rigidbody.rigidbody_type = 0; // 諸データ:タイプ(0:Bone追従、1:物理演算、2:物理演算(Bone位置合せ)) // 00 // Bone追従

            body_list.Add(rigidbody);
        }
예제 #8
0
파일: PmdIK.cs 프로젝트: nyatla/nymmd
        public void update()
        {
            MmdVector3 vec3OrgTargetPos = this.__update_vec3OrgTargetPos;
            MmdMatrix  matInvBone       = this.__update_matInvBone;

            vec3OrgTargetPos.x = (float)m_pTargetBone.m_matLocal.m[3, 0];
            vec3OrgTargetPos.y = (float)m_pTargetBone.m_matLocal.m[3, 1];
            vec3OrgTargetPos.z = (float)m_pTargetBone.m_matLocal.m[3, 2];

            MmdVector3 vec3EffPos    = this._work_vector3[0];
            MmdVector3 vec3TargetPos = this._work_vector3[1];
            MmdVector3 vec3Diff      = this._work_vector3[2];
            MmdVector3 vec3RotAxis   = this._work_vector3[3];
            MmdVector4 vec4RotQuat   = this._work_vector4;

            for (int i = this.m_ppBoneList.Length - 1; i >= 0; i--)
            {
                this.m_ppBoneList[i].updateMatrix();
            }
            m_pEffBone.updateMatrix();

            for (int it = 0; it < m_unCount; it++)
            {
                for (int cbLinkIdx = 0; cbLinkIdx < this.m_ppBoneList.Length; cbLinkIdx++)
                {
                    // エフェクタの位置の取得
                    vec3EffPos.x = (float)m_pEffBone.m_matLocal.m[3, 0];
                    vec3EffPos.y = (float)m_pEffBone.m_matLocal.m[3, 1];
                    vec3EffPos.z = (float)m_pEffBone.m_matLocal.m[3, 2];

                    // ワールド座標系から注目ノードの局所(ローカル)座標系への変換
                    matInvBone.MatrixInverse(m_ppBoneList[cbLinkIdx].m_matLocal);

                    // エフェクタ,到達目標のローカル位置
                    vec3EffPos.Vector3Transform(vec3EffPos, matInvBone);
                    vec3TargetPos.Vector3Transform(vec3OrgTargetPos, matInvBone);

                    // 十分近ければ終了

                    vec3Diff.Vector3Sub(vec3EffPos, vec3TargetPos);
                    if (vec3Diff.Vector3DotProduct(vec3Diff) < 0.0000001f)
                    {
                        return;
                    }

                    // (1) 基準関節→エフェクタ位置への方向ベクトル
                    vec3EffPos.Vector3Normalize(vec3EffPos);

                    // (2) 基準関節→目標位置への方向ベクトル
                    vec3TargetPos.Vector3Normalize(vec3TargetPos);

                    // ベクトル (1) を (2) に一致させるための最短回転量(Axis-Angle)
                    //
                    // 回転角
                    double fRotAngle = Math.Acos(vec3EffPos.Vector3DotProduct(vec3TargetPos));

                    if (0.00000001 < Math.Abs(fRotAngle))
                    {
                        if (fRotAngle < -m_fFact)
                        {
                            fRotAngle = -m_fFact;
                        }
                        else if (m_fFact < fRotAngle)
                        {
                            fRotAngle = m_fFact;
                        }

                        // 回転軸

                        vec3RotAxis.Vector3CrossProduct(vec3EffPos, vec3TargetPos);
                        if (vec3RotAxis.Vector3DotProduct(vec3RotAxis) < 0.0000001)
                        {
                            continue;
                        }

                        vec3RotAxis.Vector3Normalize(vec3RotAxis);

                        // 関節回転量の補正
                        vec4RotQuat.QuaternionCreateAxis(vec3RotAxis, fRotAngle);

                        if (m_ppBoneList[cbLinkIdx].m_bIKLimitAngle)
                        {
                            limitAngle(vec4RotQuat, vec4RotQuat);
                        }

                        vec4RotQuat.QuaternionNormalize(vec4RotQuat);

                        m_ppBoneList[cbLinkIdx].m_vec4Rotate.QuaternionMultiply(m_ppBoneList[cbLinkIdx].m_vec4Rotate, vec4RotQuat);
                        m_ppBoneList[cbLinkIdx].m_vec4Rotate.QuaternionNormalize(m_ppBoneList[cbLinkIdx].m_vec4Rotate);

                        for (int i = cbLinkIdx; i >= 0; i--)
                        {
                            m_ppBoneList[i].updateMatrix();
                        }
                        m_pEffBone.updateMatrix();
                    }
                }
            }
            return;
        }
예제 #9
0
        // 表情モーフを設定
        private void MakePMDFaces()
        {
            int n_vertex = 0;  // 表情の頂点の番号(通し番号)
            int n_inList = -1; // list中のvertexの番号(処理の前に++するために、初期値は0でなく-1としている)
            // -----------------------------------------------------
            // 表情情報(base以外)
            // -----------------------------------------------------
            List <Vector3[]> verPos_face = new List <Vector3[]>();

            foreach (TSOSubMesh sub_mesh in mesh_list)
            {
                int n_inMesh = -1;   // mesh中のvertexの番号(処理の前に++するために、初期値は0でなく-1としている)
                verPos_face.Clear(); // 前回の分を消去

                foreach (MorphGroup mg in morph.Groups)
                {
                    foreach (Morph mi in mg.Items)
                    {
                        // 現在のモーフを有効にする
                        mi.Ratio = 1.0f;

                        // モーフ変形を実行
                        fig.TPOList.Transform();
                        morph.Morph(fig.Tmo);
                        fig.UpdateBoneMatricesWithoutTMOFrame();

                        // 現在のモーフを無効にする
                        mi.Ratio = 0.0f;

                        Matrix[] clipped_boneMatrices_for_morphing = ClipBoneMatrices(sub_mesh, fig.Tmo);

                        // Tmo(各表情に対応する)中のBoneに従って、Mesh中の頂点位置を置き換える
                        Vector3[] output_v = new Vector3[sub_mesh.vertices.Length];
                        int       n        = 0;
                        foreach (Vertex vertex in sub_mesh.vertices)
                        {
                            Vector3 pos = Vector3.Empty;
                            Vector3 nor = Vector3.Empty;

                            foreach (SkinWeight sw in vertex.skin_weights)
                            {
                                // 頂点位置
                                Matrix m = clipped_boneMatrices_for_morphing[sw.bone_index];
                                pos += Vector3.TransformCoordinate(vertex.position, m) * sw.weight;
                            }

                            output_v[n++] = pos;
                        }
                        verPos_face.Add(output_v);
                    }

                    // モーフ変形を初期化する
                    fig.TPOList.Transform();
                    morph.Morph(fig.Tmo);
                    fig.UpdateBoneMatricesWithoutTMOFrame();
                }

                foreach (Vertex vertex in sub_mesh.vertices)
                {
                    n_inList++; // list中のvertexの番号を一つ増やす
                    n_inMesh++; // mesh中のvertexの番号を一つ増やす
                    int idx = inList_indices[n_inList];

                    if (idx == -1)
                    {
                        continue;
                    }

                    PMD_Vertex pmd_v = pmd.pmd_vertex[idx];

                    // 表情に関連するboneに影響を受ける頂点であれば、情報を記憶する
                    foreach (SkinWeight skin_w in vertex.skin_weights)
                    {
                        // 表情に関連するboneに影響を受ける頂点であれば、表情用の頂点とする
                        if (FACE_BONE_MIN <= sub_mesh.bone_indices[skin_w.bone_index] &&
                            sub_mesh.bone_indices[skin_w.bone_index] <= FACE_BONE_MAX)
                        {
                            // 表情の頂点情報(base以外)
                            for (int i = 1; i < pmd.number_of_face; i++)
                            {
                                // 表情用の頂点の番号(baseの番号。skin_vert_index)
                                pmd.pmd_face[i].pVertices[n_vertex].ulIndex = n_vertex;

                                // bace以外は相対位置で指定
                                MmdVector3 pmd_face_pos = Trans.CopyPos(verPos_face[i - 1][n_inMesh]);
                                pmd.pmd_face[i].pVertices[n_vertex].vec3Pos.x = pmd_face_pos.x - pmd_v.vec3Pos.x;
                                pmd.pmd_face[i].pVertices[n_vertex].vec3Pos.y = pmd_face_pos.y - pmd_v.vec3Pos.y;
                                pmd.pmd_face[i].pVertices[n_vertex].vec3Pos.z = pmd_face_pos.z - pmd_v.vec3Pos.z;
                            }

                            n_vertex++;
                            break;
                        }
                    }
                }
            }
        }
예제 #10
0
        private void initialize(PmdFileData pmd)
        {
            // -----------------------------------------------------
            // モデル名をコピー
            this._name = pmd.pmd_header.szName;

            // -----------------------------------------------------
            // 頂点数をコピー
            this._number_of_vertex = pmd.number_of_vertex;

            // 頂点配列をコピー
            this._position_array  = MmdVector3.createArray(this._number_of_vertex);
            this._normal_array    = MmdVector3.createArray(this._number_of_vertex);
            this._texture_uv      = MmdTexUV.createArray(this._number_of_vertex);
            this._skin_info_array = new PmdSkinInfo[this._number_of_vertex];

            for (int i = 0; i < this._number_of_vertex; i++)
            {
                _position_array[i].setValue(pmd.pmd_vertex[i].vec3Pos);
                _normal_array[i].setValue(pmd.pmd_vertex[i].vec3Normal);
                _texture_uv[i].setValue(pmd.pmd_vertex[i].uvTex);

                this._skin_info_array[i]             = new PmdSkinInfo();
                this._skin_info_array[i].fWeight     = pmd.pmd_vertex[i].cbWeight / 100.0f;
                this._skin_info_array[i].unBoneNo[0] = pmd.pmd_vertex[i].unBoneNo[0];
                this._skin_info_array[i].unBoneNo[1] = pmd.pmd_vertex[i].unBoneNo[1];
            }

            // -----------------------------------------------------
            // マテリアル配列をコピー
            this._materials = new PmdMaterial[pmd.number_of_materials];

            int indices_ptr = 0;

            for (int i = 0; i < pmd.number_of_materials; i++)
            {
                this._materials[i]            = new PmdMaterial();
                this._materials[i].toon_index = pmd.pmd_material[i].toon_index;
                this._materials[i].edge_flag  = pmd.pmd_material[i].edge_flag;

                this._materials[i].indices = new short[pmd.pmd_material[i].ulNumIndices];
                System.Array.Copy(pmd.indices_array, indices_ptr, this._materials[i].indices, 0, pmd.pmd_material[i].ulNumIndices);
                indices_ptr += pmd.pmd_material[i].ulNumIndices;

                this._materials[i].col4Diffuse.setValue(pmd.pmd_material[i].col4Diffuse);

                this._materials[i].col4Specular.r = pmd.pmd_material[i].col3Specular.r;
                this._materials[i].col4Specular.g = pmd.pmd_material[i].col3Specular.g;
                this._materials[i].col4Specular.b = pmd.pmd_material[i].col3Specular.b;
                this._materials[i].col4Specular.a = 1.0f;

                this._materials[i].col4Ambient.r = pmd.pmd_material[i].col3Ambient.r;
                this._materials[i].col4Ambient.g = pmd.pmd_material[i].col3Ambient.g;
                this._materials[i].col4Ambient.b = pmd.pmd_material[i].col3Ambient.b;
                this._materials[i].col4Ambient.a = 1.0f;

                this._materials[i].fShininess = pmd.pmd_material[i].fShininess;

                this._materials[i].texture_name = pmd.pmd_material[i].szTextureFileName;
                if (this._materials[i].texture_name.Length < 1)
                {
                    this._materials[i].texture_name = null;
                }
            }

            // -----------------------------------------------------
            // Bone配列のコピー
            this.m_pBoneArray = new PmdBone[pmd.number_of_bone];
            for (int i = 0; i < pmd.number_of_bone; i++)
            {
                //ボーンの親子関係を一緒に読みだすので。
                this.m_pBoneArray[i] = new PmdBone(pmd.pmd_bone[i], this.m_pBoneArray);
            }
            for (int i = 0; i < pmd.number_of_bone; i++)
            {
                this.m_pBoneArray[i].recalcOffset();
            }

            // -----------------------------------------------------
            // IK配列のコピー
            this.m_pIKArray = new PmdIK[pmd.number_of_ik];
            // IK配列を作成
            if (pmd.number_of_ik > 0)
            {
                for (int i = 0; i < pmd.number_of_ik; i++)
                {
                    this.m_pIKArray[i] = new PmdIK(pmd.pmd_ik[i], this.m_pBoneArray);
                }
                System.Array.Sort <PmdIK>(this.m_pIKArray, new DataComparator());
            }

            // -----------------------------------------------------
            // Face配列のコピー
            if (pmd.number_of_face > 0)
            {
                this.m_pFaceArray = new PmdFace[pmd.number_of_face];
                for (int i = 0; i < pmd.number_of_face; i++)
                {
                    this.m_pFaceArray[i] = new PmdFace(pmd.pmd_face[i], this.m_pFaceArray[0]);
                }
            }

            return;
        }
예제 #11
0
        private void initialize(BinaryReader i_reader)
        {
            DataReader reader = new DataReader(i_reader);



            PMD_Header pPMDHeader = new PMD_Header();

            pPMDHeader.read(reader);
            if (!pPMDHeader.szMagic.Equals("PMD", StringComparison.CurrentCultureIgnoreCase))
            {
                throw new MmdException();
            }

            this._name = pPMDHeader.szName;

            // -----------------------------------------------------
            // 頂点数取得
            this._number_of_vertex = reader.readInt();//
            if (this._number_of_vertex < 0)
            {
                throw new MmdException();
            }

            // 頂点配列をコピー
            this._position_array  = MmdVector3.createArray(this._number_of_vertex);
            this._normal_array    = MmdVector3.createArray(this._number_of_vertex);
            this._texture_uv      = MmdTexUV.createArray(this._number_of_vertex);
            this._skin_info_array = new PmdSkinInfo[this._number_of_vertex];

            PMD_Vertex tmp_pmd_vertex = new PMD_Vertex();

            for (int i = 0; i < _number_of_vertex; i++)
            {
                tmp_pmd_vertex.read(reader);

                _position_array[i].setValue(tmp_pmd_vertex.vec3Pos);
                _normal_array[i].setValue(tmp_pmd_vertex.vec3Normal);
                _texture_uv[i].setValue(tmp_pmd_vertex.uvTex);

                this._skin_info_array[i]             = new PmdSkinInfo();
                this._skin_info_array[i].fWeight     = tmp_pmd_vertex.cbWeight / 100.0f;
                this._skin_info_array[i].unBoneNo[0] = tmp_pmd_vertex.unBoneNo[0];
                this._skin_info_array[i].unBoneNo[1] = tmp_pmd_vertex.unBoneNo[1];
            }
            // -----------------------------------------------------
            // 頂点インデックス数取得
            short[] indices_array = createIndicesArray(reader);


            // -----------------------------------------------------
            // マテリアル数取得
            int number_of_materials = reader.readInt();

            // マテリアル配列をコピー
            this._materials = new PmdMaterial[number_of_materials];

            PMD_Material tmp_pmd_material = new PMD_Material();

            int indices_ptr = 0;

            for (int i = 0; i < number_of_materials; i++)
            {
                tmp_pmd_material.read(reader);

                this._materials[i]         = new PmdMaterial();
                this._materials[i].unknown = tmp_pmd_material.unknown;

                this._materials[i].indices = new short[tmp_pmd_material.ulNumIndices];
                System.Array.Copy(indices_array, indices_ptr, this._materials[i].indices, 0, tmp_pmd_material.ulNumIndices);
                indices_ptr += tmp_pmd_material.ulNumIndices;

                this._materials[i].col4Diffuse.setValue(tmp_pmd_material.col4Diffuse);

                this._materials[i].col4Specular.r = tmp_pmd_material.col3Specular.r;
                this._materials[i].col4Specular.g = tmp_pmd_material.col3Specular.g;
                this._materials[i].col4Specular.b = tmp_pmd_material.col3Specular.b;
                this._materials[i].col4Specular.a = 1.0f;

                this._materials[i].col4Ambient.r = tmp_pmd_material.col3Ambient.r;
                this._materials[i].col4Ambient.g = tmp_pmd_material.col3Ambient.g;
                this._materials[i].col4Ambient.b = tmp_pmd_material.col3Ambient.b;
                this._materials[i].col4Ambient.a = 1.0f;

                this._materials[i].fShininess = tmp_pmd_material.fShininess;

                this._materials[i].texture_name = tmp_pmd_material.szTextureFileName;
                if (this._materials[i].texture_name.Length < 1)
                {
                    this._materials[i].texture_name = null;
                }
            }

            //Boneの読み出し
            this.m_pBoneArray = createBoneArray(reader);
            //IK配列の読み出し
            this.m_pIKArray = createIKArray(reader, this.m_pBoneArray);
            //Face配列の読み出し
            this.m_pFaceArray = createFaceArray(reader);
            return;
        }
예제 #12
0
        public void lookAt(MmdVector3 pvecTargetPos)
        {
            // どうもおかしいので要調整
            MmdMatrix  matTemp           = this._lookAt_matTemp;
            MmdMatrix  matInvTemp        = this._lookAt_matInvTemp;
            MmdVector3 vec3LocalTgtPosZY = this._lookAt_vec3LocalTgtPosZY;
            MmdVector3 vec3LocalTgtPosXZ = this._lookAt_vec3LocalTgtPosXZ;

            matTemp.MatrixIdentity();
            matTemp.m[3, 0] = m_vec3Position.x + m_vec3Offset.x;
            matTemp.m[3, 1] = m_vec3Position.y + m_vec3Offset.y;
            matTemp.m[3, 2] = m_vec3Position.z + m_vec3Offset.z;

            if (this._parent_bone != null)
            {
                matInvTemp.MatrixInverse(_parent_bone.m_matLocal);
                matTemp.MatrixMultiply(matTemp, matInvTemp);
            }
            matTemp.MatrixInverse(matTemp);


            vec3LocalTgtPosZY.Vector3Transform(pvecTargetPos, matTemp);

            vec3LocalTgtPosXZ.setValue(vec3LocalTgtPosZY);
            vec3LocalTgtPosXZ.y = 0.0f;
            vec3LocalTgtPosXZ.Vector3Normalize(vec3LocalTgtPosXZ);

            vec3LocalTgtPosZY.x = 0.0f;
            vec3LocalTgtPosZY.Vector3Normalize(vec3LocalTgtPosZY);

            MmdVector3 vec3Angle = this._lookAt_vec3Angle;

            vec3Angle.x = vec3Angle.y = vec3Angle.z = 0;

            if (vec3LocalTgtPosZY.z > 0.0f)
            {
                vec3Angle.x = (float)(Math.Asin(vec3LocalTgtPosZY.y) - (20.0 * Math.PI / 180.0));
            }
            if (vec3LocalTgtPosXZ.x < 0.0f)
            {
                vec3Angle.y = (float)Math.Acos(vec3LocalTgtPosXZ.z);
            }
            else
            {
                vec3Angle.y = (float)-Math.Acos(vec3LocalTgtPosXZ.z);
            }

            if (vec3Angle.x < (-25.0 * Math.PI / 180.0))
            {
                vec3Angle.x = (float)(-25.0 * Math.PI / 180.0);
            }
            if ((45.0f * Math.PI / 180.0) < vec3Angle.x)
            {
                vec3Angle.x = (float)(45.0 * Math.PI / 180.0);
            }
            if (vec3Angle.y < (-80.0 * Math.PI / 180.0))
            {
                vec3Angle.y = (float)(-80.0 * Math.PI / 180.0);
            }
            if ((80.0 * Math.PI / 180.0) < vec3Angle.y)
            {
                vec3Angle.y = (float)(80.0 * Math.PI / 180.0);
            }

            m_vec4Rotate.QuaternionCreateEuler(vec3Angle);
        }
예제 #13
0
        private bool updateBoneFace(float fElapsedFrame)
        {
            //---------------------------------------------------------
            // 指定フレームのデータでボーンを動かす
            PmdBone[]  ppBone       = this.m_ppBoneList;
            MmdVector3 vec3Position = new MmdVector3();
            MmdVector4 vec4Rotate   = new MmdVector4();

            MotionData[] pMotionDataList = _ref_vmd_motion.refMotionDataArray();
            for (int i = 0; i < pMotionDataList.Length; i++)
            {
                if (ppBone[i] == null)
                {
                    continue;
                }
                getMotionPosRot(pMotionDataList[i], m_fFrame, vec3Position, vec4Rotate);

                // 補間なし
                ppBone[i].m_vec3Position.setValue(vec3Position);
                ppBone[i].m_vec4Rotate.setValue(vec4Rotate);

                //	 補間あり
                //				Vector3Lerp( &((*pBone)->m_vec3Position), &((*pBone)->m_vec3Position), &vec3Position, fLerpValue );
                //				QuaternionSlerp( &((*pBone)->m_vec4Rotate), &((*pBone)->m_vec4Rotate), &vec4Rotate, fLerpValue );
            }

            //---------------------------------------------------------
            // 指定フレームのデータで表情を変形する
            MmdVector3[] position_array = this._ref_pmd_model.getPositionArray();

            PmdFace[]  ppFace        = this.m_ppFaceList;
            FaceData[] pFaceDataList = _ref_vmd_motion.refFaceDataArray();
            for (int i = 0; i < pFaceDataList.Length; i++)
            {
                if (ppFace[i] == null)
                {
                    continue;
                }

                float fFaceRate = getFaceRate(pFaceDataList[i], m_fFrame);

                if (fFaceRate == 1.0f)
                {
                    ppFace[i].setFace(position_array);
                }
                else if (0.001f < fFaceRate)
                {
                    ppFace[i].blendFace(position_array, fFaceRate);
                }
            }

            //---------------------------------------------------------
            // フレームを進める
            bool bMotionFinshed = false;

            this.m_fOldFrame = this.m_fFrame;
            this.m_fFrame   += fElapsedFrame;

            if (this.m_bLoop)
            {
                if (m_fOldFrame >= this._ref_vmd_motion.getMaxFrame())
                {
                    this.m_fOldFrame = 0.0f;
                    this.m_fFrame    = this.m_fFrame - this._ref_vmd_motion.getMaxFrame();
                }
            }

            if (this.m_fFrame >= this._ref_vmd_motion.getMaxFrame())
            {
                this.m_fFrame  = this._ref_vmd_motion.getMaxFrame();
                bMotionFinshed = true;
            }

            return(bMotionFinshed);
        }