Re: MV1CollCheck_Line()の衝突判定 ( No.1 ) |
- 名前:トム 日時:2010/05/06 23:04
プログラムは、以下の通りです。
#include "DxLib.h"
const float CoLineLength = 200.0f; // 軸の下のラインの長さ
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// ウインドウモードに変更
ChangeWindowMode(TRUE) ;
// DXライブラリの初期化
// ・後始末をする必要がある
if(DxLib_Init() < 0) {
// エラーが発生したら直ちに終了
return -1 ;
}
// 描画先を裏画面に変更
SetDrawScreen(DX_SCREEN_BACK);
// 3Dモデルの読み込み
// ・後始末をする必要がある
int ModelHandle_Jiku = MV1LoadModel("Jiku.mqo");
int ModelHandle_Ground = MV1LoadModel("Ground_Ok.mqo"); // 衝突判定が正しくされる
// int ModelHandle_Ground = MV1LoadModel("Ground_Bad.mqo"); // 衝突判定が正しくされない
// モデルのコリジョン情報を構築
// ・後始末をする必要がある
MV1SetupCollInfo(
ModelHandle_Ground, // モデルのハンドル
-1, // コリジョンの情報を構築するフレームの番号
8, // コリジョン情報のX軸方向の空間分割数
8, // コリジョン情報のY軸方向の空間分割数
8 // コリジョン情報のZ軸方向の空間分割数
);
// 軸の座標を初期化
VECTOR JikuPos = VGet(0.0f, 150.0f, 0.0f);
// ESCキーが押されるかウインドウが閉じられるまでループ
while ((ProcessMessage() == 0) && (CheckHitKey(KEY_INPUT_ESCAPE) == 0)) {
// 画面をクリア
ClearDrawScreen() ;
// キー入力とパッド1の入力状態を得る
int PadData = GetJoypadInputState(DX_INPUT_KEY_PAD1);
// 軸の移動
{
// 上?
if(PadData & PAD_INPUT_UP) {
JikuPos.z += 2.0f;
}
// 下?
else if(PadData & PAD_INPUT_DOWN) {
JikuPos.z -= 2.0f;
}
// 左?
if (PadData & PAD_INPUT_LEFT) {
JikuPos.x -= 2.0f;
}
// 右?
else if (PadData & PAD_INPUT_RIGHT) {
JikuPos.x += 2.0f;
}
// R?
if(PadData & PAD_INPUT_R) {
JikuPos.y += 2.0f;
}
// L?
else if(PadData & PAD_INPUT_L) {
JikuPos.y -= 2.0f;
}
}
// カメラ Set
{
VECTOR CameraEyePos, CameraAtPos;
CameraAtPos = JikuPos;
CameraEyePos.x = CameraAtPos.x;
CameraEyePos.y = CameraAtPos.y + 400.0f;
CameraEyePos.z = CameraAtPos.z - 800.0f;
//
SetCameraPositionAndTarget_UpVecY(CameraEyePos, CameraAtPos);
}
// Zバッファを有効にする
SetUseZBuffer3D(TRUE);
// Zバッファへの書き込みを有効にする
SetWriteZBuffer3D(TRUE);
// 地面のモデル
{
MV1SetPosition(ModelHandle_Ground, VGet(0.0f, 0.0f, 0.0f));
// 3Dモデルの描画
MV1DrawModel(ModelHandle_Ground);
}
// 軸のモデル
{
MV1SetPosition( ModelHandle_Jiku, JikuPos);
// 3Dモデルの描画
MV1DrawModel(ModelHandle_Jiku);
}
// 衝突判定
{
VECTOR StartPos, EndPos;
StartPos = EndPos = JikuPos;
EndPos.y -= CoLineLength;
MV1_COLL_RESULT_POLY HitPoly;
HitPoly = MV1CollCheck_Line(
ModelHandle_Ground, // モデルのハンドル
-1, // コリジョンの情報を更新するフレームの番号
StartPos, // 当たり判定で使用する線分の始点
EndPos // 当たり判定で使用する線分の終点
);
// 当たった?
// ・当たった場合はその位置を描画する線分の終点とする
if(HitPoly.HitFlag == 1) {
EndPos = HitPoly.HitPosition;
}
// 線分の描画
DrawLine3D(StartPos, EndPos, GetColor(255,0,0));
// 当たった?
// ・当たった場合は当たったポリゴンを表示する
if(HitPoly.HitFlag == 1) {
int LineColor = GetColor(255,0,0);
VECTOR Pos0 = HitPoly.Position[0];
VECTOR Pos1 = HitPoly.Position[1];
VECTOR Pos2 = HitPoly.Position[2];
// ちょっと持ち上げて重ならないようにする
VECTOR SlideVec = VScale(HitPoly.Normal, 0.5f);
Pos0 = VAdd(Pos0, SlideVec);
Pos1 = VAdd(Pos1, SlideVec);
Pos2 = VAdd(Pos2, SlideVec);
// ワイヤーフレーム描画
DrawLine3D(Pos0, Pos1, LineColor);
DrawLine3D(Pos1, Pos2, LineColor);
DrawLine3D(Pos2, Pos0, LineColor);
}
}
// 裏画面の内容を表画面に反映
ScreenFlip();
}
// コリジョン情報の後始末
MV1TerminateCollInfo(ModelHandle_Ground, -1);
// モデルの後始末
MV1DeleteModel(ModelHandle_Jiku);
MV1DeleteModel(ModelHandle_Ground);
// DXライブラリの後始末
DxLib_End();
// ソフトの終了
return 0;
}
どうかよろしくお願いします。
|
Re: MV1CollCheck_Line()の衝突判定 ( No.2 ) |
- 名前:いっち 日時:2010/05/07 01:08
モデルファイルをアップローダか何かでご提供頂けますでしょうか?
事象の確認ぐらいは出来ると思います。
|
Re: MV1CollCheck_Line()の衝突判定 ( No.3 ) |
- 名前:トム 日時:2010/05/07 21:10
>モデルファイルをアップローダか何かでご提供頂けますでしょうか?
>事象の確認ぐらいは出来ると思います。
モデルファイルをどこにあげればよいでしょうか?
|
Re: MV1CollCheck_Line()の衝突判定 ( No.4 ) |
- 名前:いっち 日時:2010/05/07 21:15
ユーザー登録無しでダウンロードできるのであればどこでも良いと思います。
私は良く以下のサイトを使います(検索で一番最初に来るというだけの理由ですが)。
> ttp://www.axfc.net/uploader/
|
Re: MV1CollCheck_Line()の衝突判定 ( No.5 ) |
- 名前:トム 日時:2010/05/07 22:01
こんな便利なサイトがあるのですね。
モデルファイルを下記の場所にあげました。
ttp://www1.axfc.net/uploader/Sc/so/111295
Ground_Ok.mqoなら問題なく、Ground_Bad.mqoなら衝突判定がうまくいきません。
お手数ですが、プログラムのコメント部分を入れ替えて確認お願いします。
|
Re: MV1CollCheck_Line()の衝突判定 ( No.6 ) |
- 名前:いっち 日時:2010/05/07 23:53
私の環境でも事象の確認をしました。
(No.1)のソースの一部を以下のように変更して、若干傾きを加えると、どちらのモデルでも衝突判定を取れるようでした。
// 地面のモデル
{
MV1SetPosition(ModelHandle_Ground, VGet(0.0f, 0.0f, 0.0f));
// 3Dモデルの描画
MV1DrawModel(ModelHandle_Ground);
}
↓↓↓↓↓↓↓↓
// 地面のモデル
{
MV1SetPosition(ModelHandle_Ground, VGet(0.0f, 0.0f, 0.0f));
MV1SetRotationXYZ( ModelHandle_Ground, VGet( -PHI_F / 256, 0.0f, 0.0f ) );
MV1RefreshCollInfo( ModelHandle_Ground, -1 ) ;
// 3Dモデルの描画
MV1DrawModel(ModelHandle_Ground);
}
※Jiku.mqoが提供されていませんが、事象の再現に問題はありません。
|
Re: MV1CollCheck_Line()の衝突判定 ( No.7 ) |
- 名前:トム 日時:2010/05/08 10:45
確認どうもありがとうございます。
>私の環境でも事象の確認をしました。
>(No.1)のソースの一部を以下のように変更して、若干傾きを加えると、どちらのモデルでも衝突判定を取れるようでした。
こちらの想定している仕様では地面(ModelHandle_Ground)は動かないのと、
MV1RefreshCollInfo()をメインループの中で毎フレームコールするのは付加が高そうなので
(No.1)のソースの一部を以下のように変更して問題なく動作する事を確認しました。
※コリジョン情報の構築前なのでMV1RefreshCollInfo()のコールをしていません
■2行追加
// 3Dモデルの読み込み
// ・後始末をする必要がある
int ModelHandle_Jiku = MV1LoadModel("Jiku.mqo");
// int ModelHandle_Ground = MV1LoadModel("Ground_Ok.mqo"); // 衝突判定が正しくされる
int ModelHandle_Ground = MV1LoadModel("Ground_Bad.mqo"); // 衝突判定が正しくされない
MV1SetPosition(ModelHandle_Ground, VGet(0.0f, 0.0f, 0.0f)); // ←←←←←この行を追加
MV1SetRotationXYZ( ModelHandle_Ground, VGet( -PHI_F / 256, 0.0f, 0.0f ) ); // ←←←←←この行を追加
// モデルのコリジョン情報を構築
// ・後始末をする必要がある
MV1SetupCollInfo(
ModelHandle_Ground, // モデルのハンドル
-1, // コリジョンの情報を構築するフレームの番号
8, // コリジョン情報のX軸方向の空間分割数
8, // コリジョン情報のY軸方向の空間分割数
8 // コリジョン情報のZ軸方向の空間分割数
);
■1行マスク
// 地面のモデル
{
// MV1SetPosition(ModelHandle_Ground, VGet(0.0f, 0.0f, 0.0f)); // ←←←←←この行をマスク
// 3Dモデルの描画
MV1DrawModel(ModelHandle_Ground);
}
>※Jiku.mqoが提供されていませんが、事象の再現に問題はありません。
お手数をお掛けして申し訳ありません。
以下の場所に、今回の修正プログラムとモデルデータ3つをあげました。
ttp://www1.axfc.net/uploader/Sc/so/111487
若干の傾きを加えたのは、全頂点が同じ高さでない状態にするためですか?
(そうだとしたら根本の解決にはなっていない・・・)
|
Re: MV1CollCheck_Line()の衝突判定 ( No.8 ) |
- 名前:いっち 日時:2010/05/08 12:21
> (そうだとしたら根本の解決にはなっていない・・・)
もちろんその通りです。
(No.6)のレスの内容は解決策ではなく、管理人さんを含めた事象を検証なさる方々に
少しでも情報を提供するつもりで書きました。言葉足らずですみません。
ですので、本件に関しては管理人さんの見解をお待ちするのが宜しいかと思います。
|
Re: MV1CollCheck_Line()の衝突判定 ( No.9 ) |
- 名前:トム 日時:2010/05/08 21:19
>ですので、本件に関しては管理人さんの見解をお待ちするのが宜しいかと思います。
管理人さん、
(No.7)のレスに記載した場所にプログラムとモデルデータを上げてます。
特に急いでいないので、お手すきの時に症状を見てください。
よろしくお願いします。
|
Re: MV1CollCheck_Line()の衝突判定 ( No.10 ) |
- 名前:管理人 日時:2010/05/09 02:44
> トムさん、いっちさん
検証ありがとうございます&申し訳ありません m(_ _;m
ご報告していただいた通り、平坦なモデルを衝突判定処理に使おうとすると正常に動作しないバグがありました
修正版をアップしましたので、よろしければお試しください
http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用
http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用
(中身を既存のライブラリのファイルに上書きして、BCCをお使いの
場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい)
|
Re: MV1CollCheck_Line()の衝突判定 ( No.11 ) |
- 名前:トム(解決) 日時:2010/05/09 04:13
> 管理人さん
ライブラリの修正どうもありがとうございます。
> いっちさん
検証どうもありがとうござまいました。
修正版で、衝突判定が正しく行われることを確認しました。
|