現在、pmdとvmdを組み合わせて、プレイヤーモデルをアニメーションさせようと考えているのですが、
物理演算について2つほど疑問があるので質問させていただきます。
(1)MV1SetLoadModelUsePhysicsMode( DX_LOADMODEL_PHYSICS_LOADCALC); で読み込む場合
最初のフレームと最終フレームをシームレスに繋げる方法は無いでしょうか?
例えば歩行モーションなどで、髪の毛が物理演算で動いている場合、
始端と終端のポーズが同じであっても髪の毛は慣性で遅延し、
ループの境目で初期位置に瞬間移動してしまいます。
MV1SetAttachAnimBlendRateのような形で、同一番号のアニメーションの始端終端をブレンドする方法はあるのでしょうか?
(2)MV1SetLoadModelUsePhysicsMode(DX_LOADMODEL_PHYSICS_REALTIME); で読み込む場合
先の問題より、シームレスなモーションを作るためにリアルタイム物理演算を行おうと考えたのですが、
この場合では、MV1DuplicateModelで作ったモデルに対して物理演算を適用しようとすると
剛体を仕込んだ部位が画面上から消滅し、処理速度も著しく落ちてしまいます。
以下はサンプルの物理アニメーションに、MV1DuplicateModelでコピーしたモデルを加えた物です。
私の環境では、左に映るモデルの表示に異常がありました。
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
int ModelHandle, CopyModelHandle, AttachIndex ;
float TotalTime, PlayTime ;
// ウインドウモードで起動
ChangeWindowMode( TRUE ) ;
// DXライブラリの初期化
if( DxLib_Init() < 0 )
{
// エラーが発生したら直ちに終了
return -1 ;
}
// 次に読み込むモデルの物理演算モードをリアルタイム物理演算にする
MV1SetLoadModelUsePhysicsMode( DX_LOADMODEL_PHYSICS_REALTIME ) ;
// 3Dモデルの読み込み
ModelHandle = MV1LoadModel( "test.pmd" ) ;
CopyModelHandle = MV1DuplicateModel( ModelHandle ) ;
// 描画先を裏画面に変更
SetDrawScreen( DX_SCREEN_BACK ) ;
// カメラに映る範囲( カメラからの距離の範囲 )を設定
SetCameraNearFar( 10.0f, 1000.0f ) ;
// カメラの位置と向きを設定
SetCameraPositionAndTarget_UpVecY( VGet( 0.0f, 19.0f, -22.5f ), VGet( 0.0f, 10.0f, 0.0f ) ) ;
// 3Dモデルの0番目のアニメーションをアタッチする
AttachIndex = MV1AttachAnim( ModelHandle, 0, -1, FALSE ) ;
MV1AttachAnim( CopyModelHandle, 0, -1, FALSE ) ;
//モデル位置のセット
MV1SetPosition( ModelHandle, VGet( 10.0f, 0.0f, 0.0f ) ) ;
MV1SetPosition( CopyModelHandle, VGet( -10.0f, 0.0f, 0.0f ) ) ;
// アタッチしたアニメーションの総再生時間を取得する
TotalTime = MV1GetAttachAnimTotalTime( ModelHandle, AttachIndex ) ;
// 物理演算の状態をリセット
MV1PhysicsResetState( ModelHandle ) ;
MV1PhysicsResetState( CopyModelHandle ) ;
// 再生時間の初期化
PlayTime = 0.0f ;
// 何かキーが押されるかウインドウが閉じられるまでループ
while( ProcessMessage() == 0 && CheckHitKeyAll() == 0 )
{
// 画面をクリア
ClearDrawScreen() ;
// 再生時間を進める
PlayTime += 0.5f ;
// 再生時間がアニメーションの総再生時間に達したら再生時間を0に戻す
if( PlayTime >= TotalTime )
{
PlayTime = 0.0f ;
// 再生時間をセットする
MV1SetAttachAnimTime( ModelHandle, AttachIndex, PlayTime ) ;
MV1SetAttachAnimTime( CopyModelHandle, AttachIndex, PlayTime ) ;
// モーションがループしたときに位置が移動することがあるので物理演算の状態をリセット
MV1PhysicsResetState( ModelHandle ) ;
MV1PhysicsResetState( CopyModelHandle ) ;
}
else
{
// 再生時間をセットする
MV1SetAttachAnimTime( ModelHandle, AttachIndex, PlayTime ) ;
MV1SetAttachAnimTime( CopyModelHandle, AttachIndex, PlayTime ) ;
}
// 物理演算を60分の1秒経過したという設定で実行
MV1PhysicsCalculation( ModelHandle, 1000.0f / 60.0f ) ;
MV1PhysicsCalculation( CopyModelHandle, 1000.0f / 60.0f ) ;
// 3Dモデルの描画
MV1DrawModel( ModelHandle ) ;
MV1DrawModel( CopyModelHandle ) ;
// 裏画面の内容を表画面に反映
ScreenFlip() ;
}
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}
質問は以上です。
よろしければ回答をお願いいたします。