Justyさんにお尋ねしたいこと
Justyさんにお尋ねしたいこと
先日はありがとうございました。
ただ解析していてどうしても理解できない点があったので質問させていただきました。
大きく2つあります。
まずメッシュの傾きについての
namespace内の
intersectInfo->pos = p + v * dist;
intersectInfo->length = dist;
の1行目はたぶん当たったら戻る位置を表していると思うのですがあっているでしょうか?
また2行目の意味がわかりません。
ボールからのレイの長さをどこでだしているのか?
2つ目は
今まで感覚でかいていたのであっているかはわかりませんが
bool Gs_CheckIntersect(GsMESH id, const VEC3 &rayPos,
const VEC3 &rayVec, const MAT &m, IntersectInfo *intersectInfo)
&rayPosなどはアドレスを渡して関数内で参照している。
IntersectInfo *intersectInfoは関数内で値を変更している
であっていますでしょうか?
PGがわけのわからない質問をしてきたので戸惑っていますw
ただ解析していてどうしても理解できない点があったので質問させていただきました。
大きく2つあります。
まずメッシュの傾きについての
namespace内の
intersectInfo->pos = p + v * dist;
intersectInfo->length = dist;
の1行目はたぶん当たったら戻る位置を表していると思うのですがあっているでしょうか?
また2行目の意味がわかりません。
ボールからのレイの長さをどこでだしているのか?
2つ目は
今まで感覚でかいていたのであっているかはわかりませんが
bool Gs_CheckIntersect(GsMESH id, const VEC3 &rayPos,
const VEC3 &rayVec, const MAT &m, IntersectInfo *intersectInfo)
&rayPosなどはアドレスを渡して関数内で参照している。
IntersectInfo *intersectInfoは関数内で値を変更している
であっていますでしょうか?
PGがわけのわからない質問をしてきたので戸惑っていますw
Re:Justyさんにお尋ねしたいこと
>1行目はたぶん当たったら戻る位置を表していると思うのですがあっているでしょうか?
戻る位置、というよりただの交点の位置です。
>また2行目の意味がわかりません。
レイの始点から交点までの距離です。
D3DXIntersect()の第8引数の結果をそのまま代入しているだけです。
>ボールからのレイの長さをどこでだしているのか?
D3DXIntersect()に引き渡しているレイのベクトルの長さのことですか?
この関数では向きしか見ないので、長さは0でなければ何でもいいと思いますが。
distのことであれば、D3DXIntersect()が長さを求めてくれています。
>&rayPosなどはアドレスを渡して関数内で参照している。
概ねそうです。参照を渡して関数内でそれを参照しています。
constをつけているので、入力専用です。
>IntersectInfo *intersectInfoは関数内で値を変更している
そうです。
こちらは出力専用です。
Re:Justyさんにお尋ねしたいこと
あまりにも速度を出しすぎると貫通してしまうので
if(FAILED(D3DXIntersect(lpMesh, &p, &v, &isHit, 0, 0, 0, &dist, 0, 0)))
dist = dist+2; // これではだめでした・・・
みたいなことを書いてメッシュとボールの判定する長さを少し大きくしたいです><
またメッシュの
判定外に出たら落ちるのではなく止まる?というかというのも書きたいです。
傾いていたとしても使えるメッシュの上(Y軸方向に)あたり判定的な物をつけたいです。
たとえばボールが上のほうに飛んでしまってもメッシュの端より向こうにはいかないみたいな感じです><
if(FAILED(D3DXIntersect(lpMesh, &p, &v, &isHit, 0, 0, 0, &dist, 0, 0)))
dist = dist+2; // これではだめでした・・・
みたいなことを書いてメッシュとボールの判定する長さを少し大きくしたいです><
またメッシュの
判定外に出たら落ちるのではなく止まる?というかというのも書きたいです。
傾いていたとしても使えるメッシュの上(Y軸方向に)あたり判定的な物をつけたいです。
たとえばボールが上のほうに飛んでしまってもメッシュの端より向こうにはいかないみたいな感じです><
Re:Justyさんにお尋ねしたいこと
プログラマが見つかり、おめでとうごさいます。
さて、この質問についてですが、
1 回答者を名指ししている
2 現在プログラム担当ではない紅葉さんが質問をしている
と言う点についてちょっと良くないんじゃないかと感じます。
特に2についてはプログラマの方が質問に来られるのが筋と考えます。
さて、この質問についてですが、
1 回答者を名指ししている
2 現在プログラム担当ではない紅葉さんが質問をしている
と言う点についてちょっと良くないんじゃないかと感じます。
特に2についてはプログラマの方が質問に来られるのが筋と考えます。
Re:無題
とりあえず、ヒントだけ。
数学的な部分やコーディングは自力で頑張って下さい。
>高速に回転させるとフレーム間に判定が取れずに下に落ちてしまいます
箱の1フレーム前のローカル座標系のボールの位置と、
今のフレームの箱のローカル座標系のボールの位置のレイで調べてれば
ある程度高速で回転させてもあたると思います。
或いはマップを回転させるのではなく、カメラを反対側に回転させてボールとマップが
回転したかのように見せ、ボールの重力方向をそれに合わせて変えてあげてもいいですね。
あとは床の向きを調べて、押し上げればいいはずです。
>ポリゴンのない場所の上(端)にボールがあったら落ちない、
>みたいなことは書けないのでしょうか
勿論できます。
その為の Gs_CheckIntersect()です。
真下に飛ばせば床があるかどうかわかるので、後はその位置には
移動しないようにするだけです。
或いはマップの方に壁となるポリゴンを追加して、その部分は不可視属性を
つけて描画しないようにするとか、表示マップとは別に壁となるポリゴンを
追加したコリジョンマップを用意してもいいですね(こっちの方が簡単かも)
>この方は今日発覚したのですがポインタも使えませんでした・
凄いですね(w
数学的な部分やコーディングは自力で頑張って下さい。
>高速に回転させるとフレーム間に判定が取れずに下に落ちてしまいます
箱の1フレーム前のローカル座標系のボールの位置と、
今のフレームの箱のローカル座標系のボールの位置のレイで調べてれば
ある程度高速で回転させてもあたると思います。
或いはマップを回転させるのではなく、カメラを反対側に回転させてボールとマップが
回転したかのように見せ、ボールの重力方向をそれに合わせて変えてあげてもいいですね。
あとは床の向きを調べて、押し上げればいいはずです。
>ポリゴンのない場所の上(端)にボールがあったら落ちない、
>みたいなことは書けないのでしょうか
勿論できます。
その為の Gs_CheckIntersect()です。
真下に飛ばせば床があるかどうかわかるので、後はその位置には
移動しないようにするだけです。
或いはマップの方に壁となるポリゴンを追加して、その部分は不可視属性を
つけて描画しないようにするとか、表示マップとは別に壁となるポリゴンを
追加したコリジョンマップを用意してもいいですね(こっちの方が簡単かも)
>この方は今日発覚したのですがポインタも使えませんでした・
凄いですね(w
遅れてしまいすいませんでした
ポインタもつかえずなぜライブラリを使えたのでしょう・・・
というかライブラリで使っているのですが・・・
やはり急激に移動させると地面との判定が崩れてしまいます。
一応Axis.Rtでマップの軸の行列でしています。
多分、移動のmoveらへんがおかしいのかも知れません。
また床との判定をしておちなくすることについてですが
真下に判定を出してもあったっているかの情報だけで
どこと当たっているかはわからなくないでしょうか?
一応、床との判定を
bool MapHitF として 処理で
MapHitF = Gs_CheckIntersect(GsMeshHang[id].lpMesh, p, v, intersectInfo,pNum);
と考えているのですが使い方が違うのでしょうか?
時間があればで構いませんので変なところを修正いただけますと助かります。
添付したものを解凍した直下にDATAの解凍したものを入れれば動きます><
制作のチームを辞められるの今月の末になってしまいました・・・
できる限りのことは頑張ってやります><
というかライブラリで使っているのですが・・・
やはり急激に移動させると地面との判定が崩れてしまいます。
一応Axis.Rtでマップの軸の行列でしています。
多分、移動のmoveらへんがおかしいのかも知れません。
また床との判定をしておちなくすることについてですが
真下に判定を出してもあったっているかの情報だけで
どこと当たっているかはわからなくないでしょうか?
一応、床との判定を
bool MapHitF として 処理で
MapHitF = Gs_CheckIntersect(GsMeshHang[id].lpMesh, p, v, intersectInfo,pNum);
と考えているのですが使い方が違うのでしょうか?
時間があればで構いませんので変なところを修正いただけますと助かります。
添付したものを解凍した直下にDATAの解凍したものを入れれば動きます><
制作のチームを辞められるの今月の末になってしまいました・・・
できる限りのことは頑張ってやります><
Re:遅れてしまいすいませんでした
>やはり急激に移動させると地面との判定が崩れてしまいます。
高速回転時の判定については、上記の通りです。
要はマップの座標系を使う或いはマップではなくカメラを回転させることで、
マップは静止している(とみなす)ようにして、ボールがどこからどこに移動しているのかを
調べれば抜けなくなるはずです。
あと本来であれば、こういうのはレイではなく"球(或いはカプセル)とマップ"でコリジョンを
とった方がいいかと思いますが、レイでやるならその開始位置は球の中心位置からではなく
レイのベクトルとは反対側に半径分だけ戻した位置からレイを飛ばすと球が半分以上めり込んだ
状態でもぶつかるはずです。
(レイの終端側も半径分伸ばしてあげるといいですね)
>真下に判定を出してもあったっているかの情報だけで
>どこと当たっているかはわからなくないでしょうか?
単純に床からはみ出して落ちなくするだけなら、真下に当たり判定がないなら、
その場所には移動しなければいい(つまり1フレーム前の床があった時の座標を使うとか
どこか別の床のあるところに移動させる)のではないでしょうか。
それでゲームの意図と合うかどうかはわかりませんが、少なくとも
はみ出して落ちなくはなります。
Re:遅れてしまいすいませんでした
>>箱の1フレーム前のローカル座標系のボールの位置と、
>>今のフレームの箱のローカル座標系のボールの位置のレイで調べてれば
いろいろな方法を試してみたのですができませんでした><
実際には下のAxis.Rtについて編集したのですがだめでした。
if((Gs_CheckIntersect(MESH, boxPos, boxV*-2.f, Axis.Rt, &intersect,pNum) ||
Gs_CheckIntersect(MESH, Ball.Pos, Ball.Move, Axis.Rt, &intersect,pNum))&&
intersect.length < ballRadius * 2.f)
>>つまり1フレーム前の床があった時の座標を使う
const VEC3 &boxPos = Ball.Pos + g + Ball.Move + boxV; // とりあえず移動先を仮定
をBall.OldPosに変更してみたのですが判定を取ってくれなくなってしまいました><
カメラを回転はもしかしたらステージが増えるかもしれないので実装しない方向で決まりました。
すいませんです><
>>今のフレームの箱のローカル座標系のボールの位置のレイで調べてれば
いろいろな方法を試してみたのですができませんでした><
実際には下のAxis.Rtについて編集したのですがだめでした。
if((Gs_CheckIntersect(MESH, boxPos, boxV*-2.f, Axis.Rt, &intersect,pNum) ||
Gs_CheckIntersect(MESH, Ball.Pos, Ball.Move, Axis.Rt, &intersect,pNum))&&
intersect.length < ballRadius * 2.f)
>>つまり1フレーム前の床があった時の座標を使う
const VEC3 &boxPos = Ball.Pos + g + Ball.Move + boxV; // とりあえず移動先を仮定
をBall.OldPosに変更してみたのですが判定を取ってくれなくなってしまいました><
カメラを回転はもしかしたらステージが増えるかもしれないので実装しない方向で決まりました。
すいませんです><
Re:遅れてしまいすいませんでした
>いろいろな方法を試してみたのですができませんでした
数学・幾何学的にきちんと考え、目標までの道筋を立ててから、
コードを書いていますか?
2Dは勿論、3Dの場合は特に理論を伴わず意味も考えず、
闇雲にコードを書くだけではいつまで経ってもできませんよ。
とりあえず、コリジョン判定の基礎から勉強し直した方がいいと思います。
少なくとも、今のままではどうしようもないでしょう。
>Ball.OldPosに変更してみたのですが判定を取ってくれなくなってしまいました
意味はよくわかりませんが、そこを OldPosにしてしまうということは
理論的に理解できていないか、プログラムが理解できていないかのどちらかです。
プログラム的に理解できていない場合は理解する以外にはどうしようもないので、
理論的だった場合について触れておきます。
簡単に書くとこういうことです。
貴方が歩いていたら前に穴が空いていたとします。
当然前に進んで、足を穴に踏み入れれば落ちていきますが、
進めば落ちることがわかった段階でその場で止まるなり、
向きを変えて穴のないところに移動すれなり(そこはゲームの仕様次第)、
すれば落ちずにすみます。
>カメラを回転はもしかしたらステージが増えるかもしれないので実装しない
カメラの回転とステージの増加との関連性は不明ですが、カメラも回転しない、
上記のように箱は動かないものみなして処理するのも無理、であれば
少しずつ動かして処理するというのもいいでしょう。
例えば、1フレームで10動くとしたら、1フレームの中で
1ずつ動かして最大 10回判定する方法です。
ボールと箱が大きく動くからすり抜けてしまうわけで、すり抜ける余地のない単位で
少しずつ動かして判定すればすり抜けません。
勿論、10でもすり抜けてしまうなら、20,30,50,100と細かくして
判定すればいつかは抜けなくなります。
Re:遅れてしまいすいませんでした
>>Justyさん
このライブラリを使い2Dでしたら多分、殆どのことができるのですが
3Dはまったくの素人で書き方もあまり理解していません。
勉強したいのですが製作期間がないのと、私がこのチームをやめますので
期日までに作業ができないと、ウダウダ言われそうなので・・・
できるだけのことはします。
以前、進めていただいた本も読んだのですがパイプラインやテクスチャなどについての説明で
数学関係については理解できないです・・・
ただ本を読んでメッシュの法線は多分作れています。
しかし、どうしてもできないです・・・
現在は以下のような状況なのですが、いじりすぎてもう何処を触ればいいかわからなくなってきました・・・
現在の課題は
・高速で回転させると判定が取れない
・マップから落ちないようにする。
の2点です。
どうか教えていただけないでしょうか><
このライブラリを使い2Dでしたら多分、殆どのことができるのですが
3Dはまったくの素人で書き方もあまり理解していません。
勉強したいのですが製作期間がないのと、私がこのチームをやめますので
期日までに作業ができないと、ウダウダ言われそうなので・・・
できるだけのことはします。
以前、進めていただいた本も読んだのですがパイプラインやテクスチャなどについての説明で
数学関係については理解できないです・・・
ただ本を読んでメッシュの法線は多分作れています。
しかし、どうしてもできないです・・・
現在は以下のような状況なのですが、いじりすぎてもう何処を触ればいいかわからなくなってきました・・・
現在の課題は
・高速で回転させると判定が取れない
・マップから落ちないようにする。
の2点です。
どうか教えていただけないでしょうか><
// 描画 // ステージ Gs_DrawKanadeAxis(M_MAP, GRoll.Axis.Rt); // ボール Gs_DrawModel(GRoll.Ball.OldPos.x,GRoll.Ball.OldPos.y,GRoll.Ball.OldPos.z,M_PLAY,0.3f,0.3f,0.3f,0,0,0); //Common.c 中身 // ボールの移動 void C_ROLL::BallMove(GsMESH MESH) { // 下に落ちる移動量 const VEC3 g = VEC3(0, -0.0098f/3.f, 0); // 試しに移動させて、床にあたっているかどうかを調べる const float ballRadius = 0.3f * 2; /* VEC3 v = VEC3( (PolyVt[0].x+PolyVt[1].x+PolyVt[2].x)/3, (PolyVt[0].y+PolyVt[1].y+PolyVt[2].y)/3, (PolyVt[0].z+PolyVt[1].z+PolyVt[2].z)/3 ); VEC3 boxV(v.x,v.y,v.z); */ VEC3 boxV = VEC3(Axis.Rt._21,Axis.Rt._22,Axis.Rt._23); boxV *= ballRadius; Ball.Normal = boxV; const VEC3 &boxPos = Ball.Pos + g + Ball.Move + boxV; // とりあえず移動先を仮定 static DWORD pNum; // ポリゴン番号 DWORD OldpNum = pNum; IntersectInfo intersect; if((Gs_CheckIntersect(MESH, boxPos, boxV*-2.f, Axis.Rt, &intersect,pNum) || Gs_CheckIntersect(MESH, Ball.Pos, Ball.Move, Axis.Rt, &intersect,pNum))&& intersect.length < ballRadius * 2.f){ // ボールがめり込んでいるので補正 VEC3 move = VEC3(PolyRay.x/100000,0,PolyRay.z/100000); Ball.OldPos = Ball.Pos; Ball.Pos = intersect.pos + move; // Ball.Pos = intersect.pos + boxV; /*if(move.x * move.x < 0.001f*0.001f) move.x = 0; if(move.z * move.z < 0.001f*0.001f) move.z = 0; if(move.x <= 0 && move.z <= 0) f *= 0;*/ } else { // ボールは中に浮いているので落下させる Ball.Move += g; Ball.Pos += Ball.Move; Ball.OldPos = Ball.Pos; } // メッシュのポリゴン番号(pNum)における3頂点 GetVerticesOnePoly(MESH,pNum,PolyVt,Axis.Rt); D3DXVECTOR3 v1,v2; v1 = PolyVt[1]-PolyVt[0]; v2 = PolyVt[2]-PolyVt[0]; D3DXVec3Cross(&PolyRay,&v1,&v2); // 法線(PolyRay←C_ROLLクラス) // 落ちすぎたらリセット if(Ball.Pos.y < -50) { Ball.OldPos = Ball.Pos = VEC3(0, 5.0f, 0); Ball.Move = VEC3(0, 0, 0); } D3DXMatrixTranslation(&Ball.Mat,Ball.Pos.x,Ball.Pos.y,Ball.Pos.z); }