初めまして。DXライブラリィを氏よして、MMDキャラクターを動かすプログラムを組んでいるのですが、物理演算のリセットがうまくいかないのでご相談させてください。
以下のソースは、MV1PhysicsResetState 解説のサンプルに「キャラクターの向きを設定する」機能を追加した物です。(その他、MMDモデルのファイル名変更)
サンプルでは、物理演算のリセットがうまくいっているようにみえるのですが、下記のようにMMDキャラクターを横向きにすると、スペースキーを押し続けると物理演算がバタバタして乱れるという現象が起こります。
なにか物理演算のリセットの方法が間違っているのでしょうか?
横向きの状態で物理演算をきれいにリセットする方法がありましたら、助言をいただきたいのですが。よろしくお願いいたします。
// ----------------------------------------------------------------------------
// 物理演算リセット処理、回転角度実験 2012.07.19
// 解説のサンプルファイルを改造したもの
// ----------------------------------------------------------------------------
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
int ModelHandle ;
int PosX, PosZ, PosY ;
float kaiten_f ;
// ウインドウモードで起動
ChangeWindowMode( TRUE ) ;
// DXライブラリの初期化
if( DxLib_Init() < 0 )
{
// エラーが発生したら直ちに終了
return -1 ;
}
// 次に読み込むモデルの物理演算モードをリアルタイム物理演算にする
MV1SetLoadModelUsePhysicsMode( DX_LOADMODEL_PHYSICS_REALTIME ) ;
// 3Dモデルの読み込み
ModelHandle = MV1LoadModel( "model1/model001.pmd" ) ; // 初音ミク
// 描画先を裏画面に変更
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 ) ) ;
// 座標をリセット
PosX = 0 ;
PosY = 0 ;
PosZ = 0 ;
// 回転角度設定テスト -----------------------------------------------------------------
kaiten_f = 90.0f * PHI_F / 180.0f ;
MV1SetRotationXYZ( ModelHandle, VGet( 0.0f, kaiten_f , 0.0f ) ) ;
// ウインドウが閉じられるまでループ
while( ProcessMessage() == 0 )
{
// 画面をクリア
ClearDrawScreen() ;
// キーボードの上下左右でモデルの座標を変更
// ( シフトキーを押しながら上下キーでモデルを上下に移動 )
if( CheckHitKey( KEY_INPUT_LSHIFT ) )
{
if( CheckHitKey( KEY_INPUT_DOWN ) ) PosY -- ;
if( CheckHitKey( KEY_INPUT_UP ) ) PosY ++ ;
}
else
{
if( CheckHitKey( KEY_INPUT_LEFT ) ) PosX -- ;
if( CheckHitKey( KEY_INPUT_RIGHT ) ) PosX ++ ;
if( CheckHitKey( KEY_INPUT_DOWN ) ) PosZ -- ;
if( CheckHitKey( KEY_INPUT_UP ) ) PosZ ++ ;
}
// モデルの座標をセット
MV1SetPosition( ModelHandle, VGet( PosX * 0.5f, PosY * 0.5f, PosZ * 0.5f ) ) ;
// スペースキーが押されたら原点に戻る
if( GetInputChar( TRUE ) == ' ' )
{
PosX = 0 ;
PosY = 0 ;
PosZ = 0 ;
// モデルの座標を原点に移動
MV1SetPosition( ModelHandle, VGet( 0.0f, 0.0f, 0.0f ) ) ;
// モデルの物理演算の状態をリセット
MV1PhysicsResetState( ModelHandle ) ;
}
// 物理演算を60分の1秒経過したという想定で実行
MV1PhysicsCalculation( ModelHandle, 1000.0f / 60.0f ) ;
// 3Dモデルの描画
MV1DrawModel( ModelHandle ) ;
// 裏画面の内容を表画面に反映
ScreenFlip() ;
}
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}