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; }
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; }
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; }
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); } }
//この関数で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; }
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; }
// (ベクトル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); }
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; }
// 表情モーフを設定 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; } } } } }
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; }
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; }
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); }
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); }