トップページ > 過去ログ > 記事閲覧
物理演算のリセット条件について
名前:CYARACON 日時: 2012/07/19 04:51

初めまして。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 ; }

Page: 1 |

Re: 物理演算のリセット条件について ( No.1 )
名前:Will 日時:2012/07/20 09:22

> if( GetInputChar( TRUE ) == ' ' ) この判定では、スペースキーを押し続けた場合に毎フレーム初期化されるのでバタつくのだと思います。 また、キーの押下判定は CheckHitKeyを使うべきです。 GetInputChar出なければならない理由が何かあったのでしょうか? 以下のように修正すると良いかと思います。   BOOL keyin = FALSE; // ウインドウが閉じられるまでループ while( ProcessMessage() == 0 ) { // 中略 if (CheckHitKey[KEY_INPUT_SPACE] && !keyin) // スペースキーが押されていてかつ押しっぱなしではない { keyin = TRUE; // 初期化の処理 } else if (!CheckHitKey[KEY_INPUT_SPACE]) // スペースキーが離された { keyin = FALSE; } }
Re: 物理演算のリセット条件について ( No.2 )
名前:CYARACON 日時:2012/07/21 00:48

>Willさん コメントありがとございます。 > GetInputChar出なければならない理由が何かあったのでしょうか? GetInputCharは、関数の解説のサンプルがそうなっていたから、というだけの理由で、深い意味はありません。 > 毎フレーム初期化されるのでバタつくのだと思います 「初期化」というのは、同じ値に再設定されるから、何度初期化されても同じポーズが維持されているのかと思っていました。 初期化の意味がまだ理解できていないようです。もうしばらくいろいろ実験しています。
Re: 物理演算のリセット条件について ( No.3 )
名前:管理人 日時:2012/07/22 01:03

物理の初期状態は特に「安定した状態」というわけではありませんので、 物理の状態を初期化した場合はその「安定していない初期状態」に戻ることになるので バタつくことになります 初期化した後安定した状態にしたい場合は MV1PhysicsResetState( ModelHandle ) ; の後に for( int i = 0 ; i < 120 ; i ++ ) { MV1PhysicsCalculation( ModelHandle, 1000.0f / 60.0f ) ; } のように物理時間を進めて安定した状態に変化させる必要があります ( ただ、重い物理演算の処理を一度に120回も実行するので重いです ) 因みに少し試した感じだと初期化前の状態を初期化後も引きずっているみたいです・・・ Bullet のオブジェクト自体を作成し直しているわけではないので何かしらの情報が 初期化できていないようです いずれ直したいと思いますが、それは少し先になると思います、すみません m(_ _;m
Re: 物理演算のリセット条件について ( No.4 )
名前:CYARACON 日時:2012/07/22 08:03

> 管理人さん コメントありがとうございます。 初期化というのはそういう意味だったのですね。 なんとなくわかってきました。 >物理時間を進めて安定した状態に変化させる必要があります なるほど、私の方でも試してみます。

Page: 1 |