「応用技術」(2012/02/26 (日) 11:40:21) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
*技術指南/応用技術
ここでは、3Dゲームを作成するのに使用するかもしれない応用技術を紹介します。
ちょっと難しいですが、自由度は高くなります。
#hr(height=2,color=#ffA500)
-&link_anchor(Collision){コリジョン判定}
-&link_anchor(Frame){フレーム操作}
-&link_anchor(Accessory){アクセサリの装備}
#hr(height=2,color=#ffA500)
****&aname(Collision,option=nolink){コリジョン}
-球と球
簡易的なコリジョン判定
DxLibの関数ではHitCheck_Sphere_Sphereを使うと簡単です
#highlight(cpp){int HitCheck_Sphere_Sphere( VECTOR Sphere1CenterPos, float Sphere1R, VECTOR Sphere2CenterPos, float Sphere2R ) ;
// 球と球の当たり判定( TRUE:当たっている FALSE:当たっていない )
}
但し,これ以外の方法で球と球の判定であれば,球の中心点の座標からの距離と2つの球の半径で比べる方法もある.
#highlight(linenumber,cpp){{VECTOR R1,R2;//球体の座標1,2
float r1 = 1.0f, r2 = 2.0f;//球体の半径を決める
R1=VGet(0,0,0);
R2=Vget(2,0,0);
if(VSquareSize(VSub(R1,R2) ) <= (r1+r2)*(r1+r2))
{//平方根の計算は処理が重いので2乗のまま扱う
//2つの球が接触しているときの処理
} }}
-対モデル判定
モデルとの判定となると簡易的なコリジョンと比べ計算量も増えるため重くなります
しかし,簡易的な場合と比較してある程度厳密に判定をすることが可能となります
特に,ゲームでは地面のステージモデルとキャラとの当たり判定とかには使えるのではないでしょうか
モデルで判定を行う場合には,MV1SetupCollInfo関数でモデルのコリジョン情報を構築する必要があります
#highlight(cpp){int MV1SetupCollInfo( int MHandle, int FrameIndex, int XDivNum, int YDivNum, int ZDivNum ) ;//コリジョン情報を構築する
}
参考:http://homepage2.nifty.com/natupaji/DxLib/function/dxfunc_3d.html#R9N1
--モデルと線分
ステージと抽象化したキャラとの当たり判定の例
厳密なコリジョン判定
--モデルと球
ステージと抽象化したキャラとの当たり判定の例
厳密なコリジョン判定ただ重くなるかと
#hr(height=2,color=#ffA500)
****&aname(Frame,option=nolink){フレーム操作}
#hr(height=2,color=#ffA500)
****&aname(Accessory,option=nolink){アクセサリの装備}
3Dのゲームとなるとキャラに武器を持たせモーションに合わせて振り回すといったことをするかと思います。
DxLibでやる場合はMV1GetFrameLocalWorldMatrix関数を使います。
#highlight(cpp){MV1GetFrameLocalWorldMatrix( int MHandle, int FrameIndex ) ;}
指定のフレームのローカル座標からワールド座標に変換する行列を得る。
>キャラクターモデルのアクセサリを付けたいフレーム( ボーン )の座標変換情報である行列をMV1GetFrameLocalWorldMatrix で取得して、それを MV1SetMatrix でアクセサリモデルの座標変換情報として設定することで、アクセサリモデルの原点がキャラクターモデルのアクセサリを付けたいフレームの座標になり、その状態で描画するとそのフレームにくっついているように見えるというものです
参考:[[アクセサリの装備@DxLib掲示板>http://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=past&no=2064]]
-ソース
#region
#highlight(linenumber,cpp){{
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
// ウインドウモードで起動
ChangeWindowMode( TRUE ) ;
int CharModel ; // キャラクターモデル
int AccessModel ; // アクセサリーモデル
if( DxLib_Init() < 0 ) return -1 ;// エラーが発生したら直ちに終了
// 別々に読み込み
MV1SetLoadModelUsePhysicsMode( DX_LOADMODEL_PHYSICS_DISABLE ) ;//非物理演算モードで読み込む
CharModel = MV1LoadModel( "Model/Sakuya/model.pmd" ) ;
AccessModel = MV1LoadModel( "Accessory/Sakuya/右手ナイフセット.pmd" ) ;
SetDrawScreen( DX_SCREEN_BACK ) ;
MV1SetPosition( CharModel, VGet( 320.0f, 225.0f, -370.0f ) ) ;
SetCameraNearFar( 1.0f, 150.0f ) ;
// メインループ
while( ProcessMessage() == 0 )
{
ClearDrawScreen() ;
// キャラクターモデルを描画
MV1DrawModel( CharModel ) ;
// アクセサリモデルを、キャラクターの右手フレームの座標系にあわせてから描画
// キャラクターモデルの右手フレームの名前からフレーム番号を取得
//
// ※…右手フレームの名前はモデルによって違いますので、DxLibModelViewer.exe で
// キャラクターモデルを開いて、名前を確認してください
int RightHandFrameNo ;
RightHandFrameNo = MV1SearchFrame( CharModel, "右手首" ) ;
// キャラクターモデルの右手フレームの行列を取得
MATRIX RightHandMatrix ;
RightHandMatrix = MV1GetFrameLocalWorldMatrix( CharModel, RightHandFrameNo ) ;
// キャラクターモデルの右手フレームの行列をアクセサリモデルの行列としてセットしてから描画
MV1SetMatrix( AccessModel, RightHandMatrix ) ;
MV1DrawModel( AccessModel ) ;
ScreenFlip();
}
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}
}}
#endregion
*技術指南/応用技術
ここでは、3Dゲームを作成するのに使用するかもしれない応用技術を紹介します。
ちょっと難しいですが、自由度は高くなります。
#hr(height=2,color=#ffA500)
-&link_anchor(Collision){コリジョン判定}
-&link_anchor(Frame){フレーム操作}
-&link_anchor(Accessory){アクセサリの装備}
#hr(height=2,color=#ffA500)
****&aname(Collision,option=nolink){コリジョン}
-球と球
簡易的なコリジョン判定
DxLibの関数ではHitCheck_Sphere_Sphereを使うと簡単です
#highlight(cpp){int HitCheck_Sphere_Sphere( VECTOR Sphere1CenterPos, float Sphere1R, VECTOR Sphere2CenterPos, float Sphere2R ) ;
// 球と球の当たり判定( TRUE:当たっている FALSE:当たっていない )
}
但し,これ以外の方法で球と球の判定であれば,球の中心点の座標からの距離と2つの球の半径で比べる方法もある.
#highlight(linenumber,cpp){{VECTOR R1,R2;//球体の座標1,2
float r1 = 1.0f, r2 = 2.0f;//球体の半径を決める
R1=VGet(0,0,0);
R2=Vget(2,0,0);
if(VSquareSize(VSub(R1,R2) ) <= (r1+r2)*(r1+r2))
{//平方根の計算は処理が重いので2乗のまま扱う
//2つの球が接触しているときの処理
} }}
-対モデル判定
モデルとの判定となると簡易的なコリジョンと比べ計算量も増えるため重くなります
しかし,簡易的な場合と比較してある程度厳密に判定をすることが可能となります
特に,ゲームでは地面のステージモデルとキャラとの当たり判定とかには使えるのではないでしょうか
モデルで判定を行う場合には,MV1SetupCollInfo関数でモデルのコリジョン情報を構築する必要があります
#highlight(cpp){int MV1SetupCollInfo( int MHandle, int FrameIndex, int XDivNum, int YDivNum, int ZDivNum ) ;//コリジョン情報を構築する
}
参考:http://homepage2.nifty.com/natupaji/DxLib/function/dxfunc_3d.html#R9N1
--モデルと線分
--モデルと球
--モデルとカプセル型
参考(DxLibの3Dアクションサンプル):
http://homepage2.nifty.com/natupaji/DxLib/program/dxprogram_3DAction.html
#hr(height=2,color=#ffA500)
****&aname(Frame,option=nolink){フレーム操作}
#hr(height=2,color=#ffA500)
****&aname(Accessory,option=nolink){アクセサリの装備}
3Dのゲームとなるとキャラに武器を持たせモーションに合わせて振り回すといったことをするかと思います。
DxLibでやる場合はMV1GetFrameLocalWorldMatrix関数を使います。
#highlight(cpp){MV1GetFrameLocalWorldMatrix( int MHandle, int FrameIndex ) ;}
指定のフレームのローカル座標からワールド座標に変換する行列を得る。
>キャラクターモデルのアクセサリを付けたいフレーム( ボーン )の座標変換情報である行列をMV1GetFrameLocalWorldMatrix で取得して、それを MV1SetMatrix でアクセサリモデルの座標変換情報として設定することで、アクセサリモデルの原点がキャラクターモデルのアクセサリを付けたいフレームの座標になり、その状態で描画するとそのフレームにくっついているように見えるというものです
参考:[[アクセサリの装備@DxLib掲示板>http://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=past&no=2064]]
-ソース
#region
#highlight(linenumber,cpp){{
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
// ウインドウモードで起動
ChangeWindowMode( TRUE ) ;
int CharModel ; // キャラクターモデル
int AccessModel ; // アクセサリーモデル
if( DxLib_Init() < 0 ) return -1 ;// エラーが発生したら直ちに終了
// 別々に読み込み
MV1SetLoadModelUsePhysicsMode( DX_LOADMODEL_PHYSICS_DISABLE ) ;//非物理演算モードで読み込む
CharModel = MV1LoadModel( "Model/Sakuya/model.pmd" ) ;
AccessModel = MV1LoadModel( "Accessory/Sakuya/右手ナイフセット.pmd" ) ;
SetDrawScreen( DX_SCREEN_BACK ) ;
MV1SetPosition( CharModel, VGet( 320.0f, 225.0f, -370.0f ) ) ;
SetCameraNearFar( 1.0f, 150.0f ) ;
// メインループ
while( ProcessMessage() == 0 )
{
ClearDrawScreen() ;
// キャラクターモデルを描画
MV1DrawModel( CharModel ) ;
// アクセサリモデルを、キャラクターの右手フレームの座標系にあわせてから描画
// キャラクターモデルの右手フレームの名前からフレーム番号を取得
//
// ※…右手フレームの名前はモデルによって違いますので、DxLibModelViewer.exe で
// キャラクターモデルを開いて、名前を確認してください
int RightHandFrameNo ;
RightHandFrameNo = MV1SearchFrame( CharModel, "右手首" ) ;
// キャラクターモデルの右手フレームの行列を取得
MATRIX RightHandMatrix ;
RightHandMatrix = MV1GetFrameLocalWorldMatrix( CharModel, RightHandFrameNo ) ;
// キャラクターモデルの右手フレームの行列をアクセサリモデルの行列としてセットしてから描画
MV1SetMatrix( AccessModel, RightHandMatrix ) ;
MV1DrawModel( AccessModel ) ;
ScreenFlip();
}
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}
}}
#endregion
表示オプション
横に並べて表示:
変化行の前後のみ表示: