예제 #1
0
        public MmdMotionPlayer(MmdPmdModel i_pmd_model, MmdVmdMotion i_vmd_model)
        {
            this._ref_pmd_model  = i_pmd_model;
            this._ref_vmd_motion = i_vmd_model;
            this.m_bLoop         = false;

            PmdBone[] bone_array = i_pmd_model.getBoneArray();

            //スキニング用のmatrix
            this._skinning_mat = MmdMatrix.createArray(bone_array.Length);


            //---------------------------------------------------------
            // 操作対象ボーンのポインタを設定する
            MotionData[] pMotionDataList = i_vmd_model.refMotionDataArray();
            this.m_ppBoneList = new PmdBone[pMotionDataList.Length];
            for (int i = 0; i < pMotionDataList.Length; i++)
            {
                this.m_ppBoneList[i] = i_pmd_model.getBoneByName(pMotionDataList[i].szBoneName);
            }


            //---------------------------------------------------------
            // 操作対象表情のポインタを設定する
            FaceData[] pFaceDataList = i_vmd_model.refFaceDataArray();
            this.m_ppFaceList = new PmdFace[pFaceDataList.Length];
            for (int i = 0; i < pFaceDataList.Length; i++)
            {
                this.m_ppFaceList[i] = i_pmd_model.getFaceByName(pFaceDataList[i].szFaceName);
            }


            //首^H頭のボーンを探しておく
            this.m_pNeckBone = null;
            for (int i = 0; i < bone_array.Length; i++)
            {
                if (bone_array[i].getName().Equals("頭"))
                {
                    this.m_pNeckBone = bone_array[i];
                    break;
                }
            }

            // 変数初期値設定
            this.m_fOldFrame = this.m_fFrame = 0.0f;
            return;
        }
예제 #2
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;
        }
예제 #3
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;
        }
예제 #4
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);
        }
예제 #5
0
 public void updateSkinningMat(MmdMatrix o_matrix)
 {
     o_matrix.MatrixMultiply(this.m_matInvTransform, this.m_matLocal);
     return;
 }