トップページ > 記事閲覧
モデルのボーンを特定の方向に向かせる方法がわからない
名前:いれぶん 日時: 2026/04/29 15:46

普段からdxlibを使わせてもらってます。いれぶんといいます。 題名通り、モデルのボーンを特定の方向に向かせる方法がわからくて困っています。 以下のサイトや友人のコードを参考に作っているのですが、現状だと、回転させるボーンが上方向(ワールド座標から見て)に向きます。 どなたか実装方法がわかる方や間違っている原因などがわかる方がいましたら教えていただけると幸いです。 marupeke296.com/DXG_No64_CharacterPose.html techblog.sega.jp/entry/sega_inverse_kinematics202210 以下のコードです。 //ボーンをターゲットの方向に向かせる void HoldUpRightGunAnim::faceArmToTargetPosition(const std::shared_ptr<PlayerStatus> status) { const int modelHandle = status->getModelHandle(); const int lowerArmBoneIndex = status->getModelBoneIndex()["Rb_LowerArm_R"]; // 回転させるボーンの行列、座標を取得 const MATRIX frameWorldMatrix = MV1GetFrameLocalWorldMatrix(modelHandle, lowerArmBoneIndex); VECTOR frameWorldPosition; SetVectorFromMatrix(frameWorldMatrix, frameWorldPosition); // 対象の方向を見る(今回はカメラの注視点を見る) const MATRIX cameraTargetWorldMatrix = MInverse(GetCameraViewMatrix()); VECTOR cameraTargetWorldPosition = VTransform(VGet(0, 0, 10), cameraTargetWorldMatrix); MATRIX lookAtMatrix = LookAt(frameWorldPosition, cameraTargetWorldPosition); // ローカル行列に変換 const MATRIX parentWorldMatrix = MV1GetFrameLocalWorldMatrix(modelHandle, MV1GetFrameParent(modelHandle, lowerArmBoneIndex)); const MATRIX parentWorldRotationMatrix = MGetRotElem(parentWorldMatrix); const MATRIX frameLocalRotationMatrix = MMult(MGetRotElem(lookAtMatrix), MInverse(parentWorldRotationMatrix)); //warn? // ローカル行列に回転行列を設定 MATRIX frameLocalMatrix = MV1GetFrameLocalMatrix(modelHandle, lowerArmBoneIndex); SetRotationToMatrix(frameLocalMatrix, frameLocalRotationMatrix); //warn? // ローカル行列として適用 MV1SetFrameUserLocalMatrix(modelHandle, lowerArmBoneIndex, frameLocalMatrix); } /// <summary> /// 特定の方向を見る行列を求める /// </summary> /// <param name="fromVector">求めたい方向の座標1</param> /// <param name="toVector">求めたい方向の座標2</param> /// <param name="upVector">上方向</param> /// <returns></returns> inline MATRIX LookAt(const VECTOR fromVector, const VECTOR toVector, const VECTOR upVector = axis_y) { const VECTOR fowardDirection = VNorm(VSub(toVector, fromVector)); //前方向(向くべき方向) const VECTOR sideDirection = VNorm(VCross(upVector, fowardDirection)); //前を基準とした左右方向 const VECTOR correctUpDiretion = VNorm(VCross(fowardDirection, sideDirection));//前方向と右方向で正しい上方向を求める //求めた3つの方向と見たい方向の元となる座標から回転と座標をセットすることでlookat行列を求める const MATRIX lookAtMatrix = MMult(CreatRotationMatrixFromVector(sideDirection, correctUpDiretion, fowardDirection), MGetTranslate(fromVector)); return lookAtMatrix; } /// <summary> /// 回転行列の値を行列にセット /// </summary> /// <param name="matrix">セットされる行列</param> /// <param name="rotataionMatrix">セットする回転行列</param> inline void SetRotationToMatrix(MATRIX& matrix, const MATRIX rotataionMatrix) { /*const VECTOR scale = MGetSize(matrix);*/ const VECTOR scale = VGet(1.0f,1.0f,1.0f); //値をセットするだけだとスケールがぶっ壊れる?ので後からスケールをかけなおす matrix.m[0][0] = rotataionMatrix.m[0][0] * scale.x; matrix.m[1][0] = rotataionMatrix.m[1][0] * scale.y; matrix.m[2][0] = rotataionMatrix.m[2][0] * scale.z; matrix.m[0][1] = rotataionMatrix.m[0][1] * scale.x; matrix.m[1][1] = rotataionMatrix.m[1][1] * scale.y; matrix.m[2][1] = rotataionMatrix.m[2][1] * scale.z; matrix.m[0][2] = rotataionMatrix.m[0][2] * scale.x; matrix.m[1][2] = rotataionMatrix.m[1][2] * scale.y; matrix.m[2][2] = rotataionMatrix.m[2][2] * scale.z; } /// <summary> /// 3つのベクトルから回転行列を作る /// </summary> /// <param name="rightVector">右ベクトル</param> /// <param name="upVector">上ベクトル</param> /// <param name="forwardVector">前ベクトル</param> /// <returns></returns> inline MATRIX CreatRotationMatrixFromVector(const VECTOR rightVector, const VECTOR upVector, const VECTOR forwardVector) { //※dxlibのMATRIXは[行][列] MATRIX rotationMatrix = MGetIdent(); rotationMatrix.m[0][0] = rightVector.x; rotationMatrix.m[0][1] = rightVector.y; rotationMatrix.m[0][2] = rightVector.z; rotationMatrix.m[1][0] = upVector.x; rotationMatrix.m[1][1] = upVector.y; rotationMatrix.m[1][2] = upVector.z; rotationMatrix.m[2][0] = forwardVector.x; rotationMatrix.m[2][1] = forwardVector.y; rotationMatrix.m[2][2] = forwardVector.z; return rotationMatrix; } /// <summary> /// ベクトルの値を行列にセット /// </summary> /// <param name="matrix">値をセットする行列</param> /// <param name="vector">セットしたいベクトル</param> inline void SetVectorFromMatrix(const MATRIX& matrix, VECTOR& vector) { vector.x = matrix.m[3][0]; vector.y = matrix.m[3][1]; vector.z = matrix.m[3][2]; }
メンテ

Page: 1 |

Re: モデルのボーンを特定の方向に向かせる方法がわからない ( No.1 )
名前:管理人 日時:2026/04/30 03:03

ボーンを特定の方向に向かせる処理は、向かせたいメッシュが ボーンローカルのどの軸( X軸,Y軸,Z軸 )に向いているかによって処理が変わります モデルの構造によって処理が変わってくるのと、私がIK系にあまり詳しくないので 載せていただいたプログラムのどこを変更すれば良いかちょっと分かりません (・・; もし不都合が無ければこちらのプログラムで実際に使用されているモデルのファイルを 下記のメールアドレスにzip等で圧縮してお送り頂けないでしょうか? BQE00322(あっとまーく)nifty.com ( (あっとまーく) を @ に置き換えてください ) 実際に手元で動かしながら確認できればどうすれば良いか分かるかもしれませんので お送りいただけたら私の方で調べてみたいと思います m(_ _)m
メンテ
Re: モデルのボーンを特定の方向に向かせる方法がわからない ( No.2 )
名前:いれぶん 日時:2026/04/30 09:33

ありがとうございます。 メールにてモデルを送らせていただきました。 お時間ある時で大丈夫なので宜しくお願いします。
メンテ
Re: モデルのボーンを特定の方向に向かせる方法がわからない ( No.3 )
名前:いれぶん(解決済み) 日時:2026/04/30 17:42

すみません。 友人に手伝ってもらい解決しました。 管理人さんの言っていた通り、 ボーンローカルのどの軸( X軸,Y軸,Z軸 )に向いているかによって処理が変わります という分を考慮してなかったので、その分を補正する計算を行ったり、 間違っていた行列のかける順番を修正したり、 dxlibの関数を間違った使い方をしていた部分を修正したりしたら 想定通りの挙動になりました。 ご迷惑をおかけしました。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存