HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2018
0425
暇人hgimg3でX形式モデルファイルから判定用データを作り衝突判定等を行うモジュール13解決


暇人

リンク

2018/4/25(Wed) 23:00:10|NO.84150

X形式モデルファイルから判定用データを作り
衝突判定、地面や天井、壁に沿っての移動等を行うモジュールです。
2D座標から3D座標への変換や、境界球の判定、境界ボックスを設定して判定等も出来ます。

地形との判定をする命令があるモジュールは mod_hgCnvRayCol.hsp ですが
内部で mod_FindGridLine.hsp を使用してます。
なので二つのファイルを同じフォルダに置き #include してください。
mod_hgCnvRayCol.hsp内でhgimg3とmod_FindGridLineをインクルードしてるので
mod_hgCnvRayColだけを#includeすれば大丈夫

mod_FindGridLineは二次元配列の指定された二点間に0以外があるか検索したり
範囲外の直線をカットしたり出来ます。
mod_hgCnvRayCol内ではポリゴンの区分けとグリッドの境界座標取得と判定有効範囲かの判定に使ってます。

「 mod_FindGridLine.hsp 」で追加される命令

FindGridLineAll array_line_hit, map_data, array_line_x1, array_line_y1, array_line_x2, array_line_y2, Tile_Size, linmax, loopf, maplen_x, maplen_y //FindGridLineとNextGridLineを組み合わせた命令 FindGridLine line_hit, map_data, line_x1, line_y1, line_x2, line_y2, Tile_Size, loopf, maplen_x, maplen_y //直線のライン上に0以外があるかmap_dataを判定(0以外があったら一旦抜けるのでNextGridLineを使って同じライン上の先を判定できる) NextGridLine line_hit //FindGridLineの後に使用 ClipLine array_line_x1, array_line_y1, array_line_x2, array_line_y2, i_clipsizex, i_clipsizey, linmax //「指定サイズ外の直線をカットする」 //グリッドの境界線とクロスした座標が入ってる変数(FindGridLineAll、FindGridLine、NextGridLine実行で代入される) GridCrossPosx GridCrossPosy


mod_hgCnvRayColは座標変換のモジュールに色々追加してったらこうなってしまった感じ・・・
基本的にレイを飛ばして判定する感じになってます。
スクリーン座標のままで使えたり
移動ベクトルで良いのと
レイベクトルと距離を指定する必要があったりと
似てる命令でも色々違ったりするので注意してください
取得の方も同じ感じで注意が・・・


hghitモジュールとの違い
レイと三角形の衝突判定にはDirectX9(d3dx9)のD3DXIntersectTriを使用してる
X形式ファイルのデータ変換が数倍から数十倍早い(データが大きいほど差が出る)
変換したデータをセーブ、ロード出来る(sb_bg1.xを変換保存すると sb_bg1.x_0.000000_.coldat になる。0.0はサイズ自動で区分けされた時)
四角形のX形式ファイルも三角形に分割してデータ化(見た目と違ってしまう可能性はある)
自動で区分けする(1マスのサイズも自動で決まるけど自分でも指定出来る)
区分けされてるので一回の判定が軽くなる
簡易的に高さでも別けてる(区域で一番高いものより上の判定はスルー)ので処理数が増えやすいマウス座標から地形をポイントするのが軽くなる
移動、回転、スケール変更に対応
壁の繋がりが90度未満の鋭角でも嵌らないように対応(一回目は壁の外側に押し出して、基点から押し出された位置までを再判定して衝突したら停止)
地面上移動判定に天井も対応してるので階層構造もOK(内部にいると高さで別けてる恩恵は無いから処理量は増える)
地面と壁のデータは同じ物も使える(変換時に壁と急斜面、地面でフラグわけして壁と地面の判定命令内で違う方を除外する)
物によっては表示用モデルそのままでも判定用データに出来る(少しでも処理を軽くしたいなら軽いモデルデータを別々に用意したほうが良い・・・後、見た目壁に半分入り込むのはアレだけど・・・)
変換データは配列じゃなくIDで管理
データ変換作業メモリを結構消費する(sdimで区分け数分確保するので再度sdimしてもメモリ開放されないのでリリース時は変換じゃなくデータロードした方が良い)

d3dx9を使用してるのでOSインストール後一度は下記のDirectXをインストールする必要があります。

DirectX エンド ユーザー ランタイム Web インストーラ
https://www.microsoft.com/ja-jp/download/details.aspx?id=35


「 mod_hgCnvRayCol.hsp 」

hgCnvRayCol_init //モジュールの初期化(loadTerrain実行時に初期化されてなければ初期化されます) fvstw wp, sx, sy, cdz //スクリーン座標をワールド座標に変換 fvray rvec, sx, sy, cdz //スクリーン座標からレイを飛ばすベクトルを取得 getRayPos wpx, wpy, wpz, sx, sy, gzero //スクリーン座標からレイを飛ばしてワールドY座標が0になる時のワールドX,Z座標を取得 setPlane pid, v1, v2, v3 //平面との交点調査用の平面を作成 getPlaneLinePoint px, py, pz, pid, v1, v2 //平面と直線の交点を調べる PlaneDotNormal pid, VECTOR3 //平面と 3D ベクトルの内積を計算する NormalToAng %1, %2, %3, %4 //面法線を入力して面の角度取得 ObjAxisAng oid, aax, aay, aaz, Axis, ang, lw //軸を指定してオブジェクトを回転 setRayMeshObj oid, sx, sy, max, min, NZ, FZ //addmeshで作成したオブジェクト(OBJ_GROUNDを設定した物)に対してレイを飛ばして交点にオブジェクトを配置(連続でオブジェを移動させgetcolvecして最初にmin以内になった座標を取得) getRayObjID oid, sx, sy, max, min, NZ, FZ //スクリーン座標からの直線状にあるオブジェクトのidを取得して指定したオブジェクトを交点に配置します getscboxobjid oid, sx, sy, exmode, group, hsx, hsy, max_range //3Dオブジェクト座標をスクリーン座標に変換して指定座標に縦横の判定サイズ以内にあるオブジェクトIDを返す getscobjid oid, sx, sy, exmode, group, max_range //基本的にgetscboxobjidと同じだが判定サイズはgetcolvecで取得(modelcols のp5を0にしてコリジョンスケールを設定) getSphereRayColl oid, ip, msize, sx, sy, f, exmode, group, mode //スクリーン座標からレイを飛ばしてオブジェクトの球と接触判定、交点取得、ドラッグする getBoxRayColl oid, spxyz, cty, sx, sy, f, exmode, group, mode //スクリーン座標からレイを飛ばしてオブジェクトのBOXと接触判定、交点取得、ドラッグする SphereBoundProbe oid, spxyz, cty, rp, rvec, exmode, group, mode //基点座標からレイを飛ばしてオブジェクトの球との交点取得 BoxBoundProbe oid, spxyz, cty, rp, rvec, f, exmode, group, mode //基点座標からレイを飛ばしてオブジェクトのボックスとの交点取得 getBoxNormalVec oid, poly_no, nm //BoxBoundProbe,getBoxRayColl,RayBoundingBoxSingleで衝突したポリゴンナンバーから面法線を取得する setBoundingBox oid, bbminx, bbminy, bbminz, bbmaxx, bbmaxy, bbmaxz //オブジェIDを指定して判定用バウンディングボックスを設定する RayBoxBoundProbe oid, rpxyz, rvec, p_Dist, mode, wg //setBoundingBoxで設定したオブジェクトに対して衝突判定をする getMovBoundingBoxCol oid, poly_no, Posfeetx, Posfeety, Posfeetz, MoveVec, Step, tall, exmode, group, poly_no, gf //setBoundingBoxで設定したオブジェクトにレイを飛ばして衝突した場合障害物として処理 //setBoundingBoxで設定したデータを取得する関数型マクロ getBBMin(%1,%2) // 変数 = getBBMin( ObjID , 0〜2 ) [x=0 y=1 z=2 ] getBBMax(%1,%2) getBBSize(%1,%2) getBBSentre(%1,%2) //[---下のvarは変数、Arrは配列、getはマクロ関数はRayBoxBoundProbe使用後に裏面衝突してた場合使用可能---] varBBBackDist //交点までの距離 ArrBBBackNormal //衝突面の法線 varBBBackInner //衝突面との内積 getBBBack_UV() //交点のUV値 //[---下のArrは配列でgetMovBoundingBoxCol使用後に使用できる---] ArrBBGroundNormal //地上面の法線が代入される配列 ArrBBCeilingNormal //天井面の法線が代入される配列 RayIntersectTri %1, %2, %3, %4 //配列に3頂点のXYZ座標を入れてレイを飛ばし判定 setVertexTri vtlid, VerTri, VerTriMax, VTList //三角形リストを登録 getRayIntersectTriListCol tridx, Dist, vtlid, sidx, maxidx, rpxyz, rvec //setVertexTriで設定した三角形リストをレイと衝突判定します //-----ここからの命令はX形式モデルファイルから判定用地形データを作成して衝突判定移動処理をする---- loadTerrain tid, xfilnam, pdsize, ltopt, loadf //モデルからTerrainデータ作成 setTerrainPar Gap_p, Sticky_p, WallSteepSlopes_p, WallVerticalRange_p, GroundRange_p, BBoxGroundRange_p //Terrainデータ変換時、判定時の設定 getTerrainBoundingBox tid, minbbox, maxbbox //loadTerrainで使用したIDを使いバウンテンボックスを取得する setTerrainLinkObj tid, oid, opt //Terrainデータ判定時に座標、回転、スケール参照先指定(これを設定した場合setpos,tsetang,tsetscaleの設定は必要なくなります) //loadTerrainで作ったデータを移動、回転、スケールの変更(データは変更せずに判定時に反映させる) setpos tid, tx, ty, tz //Terrainデータのposグループ情報を設定 tsetang tid, tx, ty, tz //Terrainデータのangグループ情報を設定 tsetscale tid, tx, ty, tz //Terrainデータのscaleグループ情報を設定 setTerrainWallSlopes tid, wss //Terrainデータの壁と急斜面フラグを再設定(地形を回転、スケール変更した場合必要な時がある) getMovTerrainGroundCol tid, Posfeetx, Posfeety, Posfeetz, MoveVec, Step, tall, poly_no, gf, mtgcf //Terrainデータを垂直判定、衝突してた場合地面と天井から押し出した移動量にMoveVecを変更(地面のY座標をrefdvalに返す) getMovTerrainWallCol tid, Posfeetx, Posfeety, Posfeetz, MoveVec, poly_no, Step //Terrainデータにレイを飛ばして壁を判定し衝突した壁の外に押し出す移動量にMoveVecを変更 getTerrainWallCol tid, RayPosx, RayPosy, RayPosz, RayDir, d_sz, poly_no, Step, tcf //Terrainデータにレイを飛ばして壁を判定(実際の移動はしない、MoveVecに取得のみ) getTerrainCol tid, RayPosx, RayPosy, RayPosz, RayDir, d_sz, poly_no, tcf, hcnt //Terrainデータにレイを飛ばして一番近い面を判定 getTerrainTriCol tid, RayPosx, RayPosy, RayPosz, RayDir, d_sz, poly_no, tcf //Terrainデータ内の1枚の三角形をレイを飛ばして判定 varTerrainTriInner //Terrainデータの衝突判定して衝突した面との内積を取得(参照用変数) ArrTerrainNormal //Terrainデータの衝突判定をした時に衝突した面の法線を参照できる getTerrainTri_UV //Terrainデータの衝突判定をした時に衝突した面のUVを取得 getTerrainPolMaterial tid, poly_no //Terrainデータのポリゴンナンバーからマテリアルを取得 ArrGroundNormal //getMovTerrainGroundCol実行後に取得出来る地上面の法線 //デバッグ用表示スイッチマクロ定義(ライン表示はTerrainLine_debug実行で表示される、ボックスはBoundingbox_debug実行で移動等に対応) #define global mod_hgCnvRayCol_debug 0 //-1=全てOFF、0=全てON、1=TerrainGroundのライン非表示、2=TerrainWallのライン非表示、4=Terrainのライン非表示、8=TerrainTriのライン非表示、16=setBoundingBoxで登録したオブジェクトに重なるボックス非表示、64=loadTerrain実行時の作業工程非表示、128=loadTerrainの区域分割時のライン非表示 Boundingbox_debug //デッバク表示ONの時にhgdrawの前に配置する事でバウンテンボックスを表示 TerrainLine_debug //デッバク表示ONの時にhgdrawとhgsyncの間に配置する事でTerrain系で判定処理した三角形をライン表示


モジュールをアップロードしたURLは次のレスで書きます。



この記事に返信する


暇人

リンク

2018/4/25(Wed) 23:27:45|NO.84151

投稿できない・・・
yahooボックスのURLがまずいのか・・・

「 mod_FindGridLine.hsp 」
https://yahoo.jp/box/ZE8OI2

「 mod_hgCnvRayCol.hsp 」
https://yahoo.jp/box/NwF3kE



暇人

リンク

2018/4/25(Wed) 23:47:36|NO.84152

あら?・・・
問題はサンプルスクリプトの方だったのか
サンプルが投稿できないから
サンプルもアップしてURLに・・・


地形を影付きで移動する最小限のサンプル
https://yahoo.jp/box/IXsnTn



暇人

リンク

2018/4/26(Thu) 01:27:06|NO.84153

mod_hgCnvRayColのsetTerrainLinkObjにバグ(angyにposyが使われてた・・・)
があったので修正しました。
URLはNO.84151のと同じです。



暇人

リンク

2018/4/26(Thu) 01:47:41|NO.84154

>fvray rvec, sx, sy, cdz //スクリーン座標からレイを飛ばすベクトルを取得
はパラメータが一つ多く説明にかいてました
正しくは

fvray rvec, sx, sy
です。



暇人

リンク

2018/4/26(Thu) 02:59:31|NO.84155

やっぱりスクリプトが書き込めないのでURLを・・・

NO.84152のサンプルに
setTerrainLinkObj
getMovTerrainWallCol
getTerrainCol
の命令を追加使用したサンプル
マウスクリックでカメラ移動

https://yahoo.jp/box/KEtAbh



暇人

リンク

2018/4/27(Fri) 00:23:33|NO.84173

命令説明のパラメータ部分に間違いがありました↓
>getMovBoundingBoxCol oid, poly_no, Posfeetx, Posfeety, Posfeetz, MoveVec, Step, tall, exmode, group, poly_no, gf //setBoundingBoxで設定したオブジェクトにレイを飛ばして衝突した場合障害物として処理
正しくは

>getMovBoundingBoxCol oid, Posfeetx, Posfeety, Posfeetz, MoveVec, Step, tall, exmode, group, poly_no, gf
です。
NO.84154の修正と
getMovBoundingBoxColで天井に衝突した時の動作と薄い天井だと影の座標が天井の上の面になるのを修正しました。
URLはNO.84151のままです。


getTerrainBoundingBox
setBoundingBox
getMovBoundingBoxCol
を使用したサンプル
https://yahoo.jp/box/v0jn4y

バウンテングボックスで階段や部屋を作ってみた
平らじゃない場所にボックスを置いてるので上下が徐々に狭くなる部分があると動けなくなる可能性がある・・・

:操作方法
カメラの向きを基準に歩行キーで前後左右に移動
マウス右ドッグでカメラ回転
Ctrlでジャンプ

半透明なのはバウンテイングボックのデバッグ表示です。
実際のオブジェクトより横から当たる部分を大きくしてます。
状況で色が変わります。
青が通常
緑が境界球判定で衝突した
黄が壁として衝突
赤が地面(衝突して無くても)
紫が天井として衝突(壁としない高さ以上で衝突した物)

Terrainの方でも同じだけど
壁としない高さ以上で衝突した場合(壁とする高さ以下には何も無い時)
頭をぶつけたとしてXZの移動を停止します。
手前に傾いてる壁など



暇人

リンク

2018/4/28(Sat) 15:42:16|NO.84192

説明の間違い
>NO.84173
>紫が天井として衝突(壁としない高さ以上で衝突した物)
結果的に衝突して無くても天井として判定処理をした物

mod_hgCnvRayColの修正
getMovBoundingBoxColでバウンディングボックスを傾けて繋げた坂にして登ると引っかかる事があるのと
バウンディングボックスに上下を挟まれると動けなくなるのを修正
セーブデータの仕様を変更する場合を考えて今回からバージョンを設定
mod_hgCnvRayCol_VER で確認できる(今は0.7)



暇人

リンク

2018/4/29(Sun) 19:08:10|NO.84214

NO.84192のgetMovBoundingBoxCol修正じゃ不十分だったのを修正
getMovBoundingBoxColの既存パラメータを修正して指定オブジェや
前回の一段判定(境界球)でヒットしたオブジェを再判定できるようにした。

mod_hgCnvRayCol_debugをマクロ定義してもデバッグ表示に変化が無かったのを修正
#define global mod_hgCnvRayCol_debug 0 //このマクロ定義はmod_hgCnvRayColのインクルード前にしてください

URLはNO.84151と同じ



暇人

リンク

2018/4/30(Mon) 03:34:40|NO.84215

0.71での修正でバウンディングボックスのデバッグ表示が対応できてなかったのを修正
mod_hgCnvRayCol_debugをマクロ定義しないとデバッグ表示されなくなってたのを修正

定義なしで全て表示
#define mod_hgCnvRayCol_debug 0 //全て表示
#define mod_hgCnvRayCol_debug -1 //全てOFF
実行ファイルにした場合は定義してても全てOFFになります。

getMovTerrainGroundColでライン上の判定が抜ける事があるのを修正(これはD3DXIntersectTriの問題なので完全に修正できてるかは不明)
(mod_hgCnvRayCol_VER 0.72)
URLはNO.84151のままです。

サンプルでNO.84155、NO.84152にアップしたスクリプトだと
モデルファイルのテクスチャが読み込めてなかったのを修正しました。
URLはそのまです。



暇人

リンク

2018/5/1(Tue) 18:03:38|NO.84230

・setTerrainParのWallVerticalRange_pをデフォルト値0.000001から0.000003に変更(テストで使ったフリー素材の壁が0.000001より誤差が大きかった)
・setTerrainParのSticky_p説明の「大きすぎるとジャンプできない等問題が起きる」を削除(getMovTerrainGroundColのgf使用で問題なくなってた)
・getMovTerrainGroundColで上昇中に天井に衝突したり上下に挟まれる場合の処理を改善
・getMovTerrainWallColで一回目の判定で衝突した場合基点から押し出した位置までの
移動量で二回目の判定をしてたのを一回目の交点からの移動量に変更(これで90度未満の鋭角で角まで行けなくなる事があるのを改善)
結果は最初の基点からの移動量で変わらない

「 mod_FindGridLine.hsp 」
https://ux.getuploader.com/himajin130414/download/40

「 mod_hgCnvRayCol.hsp Ver0.73」
https://ux.getuploader.com/himajin130414/download/43


同じファイル名をアップロード出来ないと不便なのでローダー変更


getMovTerrainGroundColの仕様:
・Stepより高い位置の地上や天井に衝突した場合XZ移動を停止します。(下から衝突した場合を除く)
更に上昇中の場合上昇速度を0.0にします。
(移動停止等せずにまともにやると、更に複数回の判定処理が必要になるので妥協案)
XZ移動が停止された場合statに8が加わります。



getMovTerrainWallColの仕様:
・getMovTerrainWallColはgetTerrainWallColを二回実行してます。
一回目は壁から押し出して、交点から押し出された座標を次の移動量として再判定して衝突したらそこで停止して基点からの移動量を出力
(内角に衝突しどちらにも行け無い場合に行ったり来たりするのでブレが出る可能性あり)
・判定の高さは Posfeety-Step で、これより低い壁は判定されないので乗り越える事が出来ます。
これは上昇中も同様なので、本来乗れない段差にのれたり上昇の速度関係なく1フレームでStep分上に上がって不自然に見えたりします。
(ジャンプ中はStepを0.0にすることで問題はなくなります)
・手前に傾いてる地形に衝突した場合XZ移動を停止してstatに8を加えます。
(これも地面判定と同様の理由の妥協案)



暇人

リンク

2018/5/27(Sun) 16:48:10|NO.84508

NO.84214の修正での
>getMovBoundingBoxColの既存パラメータを修正して指定オブジェや
> 前回の一段判定(境界球)でヒットしたオブジェを再判定できるようにした。
前回の一段判定の再判定をexmode==-1,group=-1に変更(前まではgroup=0だった)

getMovBoundingBoxColの上昇中に移動したら上下に挟まれる場合の処理を改善
getMovBoundingBoxColでXZ移動停止した時statに8が加わってなかったのを修正
RayBoxBoundProbeの返り値statに-1は無いのに説明書きしてたのを修正
setBoundingBoxでデバッグ表示してない時にも設定削除した時にデバッグ表示用のオブジェクトを削除しようとしてたのを修正
setBoundingBoxで設定削除してもRayBoxBoundProbe、getMovBoundingBoxColで判定してたのを修正
Boundingbox_debugで中心座標が画面外のボックスは非表示になるように修正


影用の地面検索範囲が接地面検索範囲にも影響してたのを修正(tall値が大きいと地形に潜ってしまってた)
getMovTerrainGroundColでも高さで判定するかを選別するように変更(通常は影用に広く見るからあまり意味無いかも・・・)
loadTerrainでXZ座標からポリゴンサイズを取得出来ないようなモデル(font_a.x等)の場合前回の分割サイズが使われてたのを修正
getTerrainBoundingBoxでリサイズを指定してサイズに収まるように変更するスケール値とリサイズ後のBoundingBoxとボックスサイズを取得出来るように変更
壁と地面で同じデータを使用してる場合getMovTerrainGroundColが最初に実行されないと以降のgetMovTerrainGroundColに問題が出るのを修正
(getMovTerrainWallColはXZ方向の移動が無い限り実際の判定処理はされないから開始後直ぐに移動させない限り影響でなかった・・・)
setTerrainParの Gap_p を最小値が 0.0001 になるように修正(これより小さいと0.0と同じになってしまう場合があるので)
SphereBoundProbe,getSphereRayColl,getTerrainTriCol,getTerrainWallCol,getRayIntersectTriListのパラメータ名等が説明と違ってる所があったのを修正
ObjZeroPosAngの説明で命令名がObjZeroCamになってたりパラメータの説明に間違いがったのを修正
getMovTerrainWallColに地面も判定するパラメータ追加

説明間違い修正後の命令

SphereBoundProbe oid, vertex, msize, rp, rvec, exmode, group, mode getSphereRayColl oid, vertex, msize, sx, sy, f, exmode, group, mode getTerrainTriCol tid, RayPosx, RayPosy, RayPosz, MoveVec getTerrainWallCol tid, Posfeetx, Posfeety, Posfeetz, MoveVec, poly_no, Step, tcf ObjZeroPosAng oid , _t_px, _t_py, _t_pz, _t_Angx, _t_Angy, _t_Angz getRayIntersectTriList tridx, Dist, vtlid, sidx, maxidx, rpxyz, rvec, mode


追加命令

setBoxBoundColDir mid, mdir //getMovBoundingBoxColとRayBoxBoundProbeでモデルID別に特定の面だけ判定するように設定 getBoundingBoxStopMove MoveVec //getMovBoundingBoxColのstatに8が返って来た時に面座標と重なるのを回避 getTerrainGroundStopMove MoveVec //getMovTerrainGroundColのstatに8が返って来た時に面座標と重なるのを回避 getTerrainPar Gap_p, Sticky_p, WallSteepSlopes_p, WallVerticalRange_p, GroundRange_p, BBoxGroundRange_p //setTerrainParで設定されてる値を取得 setTerrainColOff tid, offlist, offmax //Terrainデータの判定しない面を設定 UnlockTerrainColOff tid, lock //setTerrainColOffの設定解除 addTerrainMeshmap tid, m_mesh, m_mode, texid, o_mesh, opt //TerrainデータからMeshmapモデルとOBJ_GROUND|OBJ_HIDEを設定したオブジェクトを作成します ApplyTerrainMeshmap tid //addTerrainMeshmapで作成したMeshmapに現在の座標とスケールを適用します


注意事項:
パラメータにexmode,groupのある命令(getMovBoundingBoxCol等)は命令内で findobj 、 nextobj を使用しています。
なので、

findobj 0,1 repeat nextobj id if id<0 {break} getpos id,px,py,pz getdir id,dx,dy,dz fvset mv,dx,dy,dz getMovBoundingBoxCol oid,px,py,pz,mv・・・・ ・ ・ loop
のような使い方は出来ません。(getMovBoundingBoxCol内でfindobjが再設定されるので)


findobjを使いたい場合は

findobj 0,1 repeat nextobj id(cnt) if id(cnt)<0 {break} loop repeat if id(cnt)<0 {break} getpos id(cnt),px,py,pz getdir id(cnt),dx,dy,dz fvset mv,dx,dy,dz getMovBoundingBoxCol oid,px,py,pz,mv・・・・ ・ ・ loop

こんな感じにする必要があります。

検索除外が必要ないなら enumobj を使う手も・・・

※仕様1
getMovBoundingBoxColで上方向に移動してる時の判定は速度が速いとすり抜けます。


※仕様2
getMovBoundingBoxCol、getMovTerrainGroundColで天井等に衝突した場合XZの移動量を0.0にして処理してますが
問題点として

■■

こんな感じの地形だった場合に、右側から出っ張ってる部分に頭をぶつけた時
衝突前の座標が面ピッタリの場合があって、この後の動作に支障を来たす事があります。
これを回避する簡単な方法として初期座標と移動速度に0.0001程度加えると回避できる場合があります。(速度が一定じゃない場合は使えない・・・)
一応回避作として命令を用意しました(これでも完全じゃありませんが・・・)
getMovBoundingBoxColなら getBoundingBoxStopMove を使用してください(頭に当たったボックスのみ再判定して重なるのを防ぐ)
getMovTerrainGroundColなら getTerrainGroundStopMove を使用してください(頭上からGap分レイを飛ばしてgetTerrainWallCol)


※仕様3
Boundingbox_debugで設定されてる元のオブジェクトが削除されたかを確認して
削除されてた場合デバッグ用ボックスも削除しますが、元オブジェが削除されてから
直ぐにオブジェクトが作成された場合は、IDが再利用されてBoundingbox_debug実行時には
有効オブジェになってるので削除されません(座標等が新しいオブジェから取得されます)
これが気になる場合は元オブジェ削除時に setBoundingBox oid として設定も削除してください


※仕様4
以下はMeshmap側の問題ですが・・・
addTerrainMeshmapで使用できるモデルデータは均等に分割されてる物のみです。(バグか仕様か描画は問題なけどobjwalkが均等以外対応してない)
Meshmapとメタセコイアの三角形分割は違うのでメタセコイア上で三角形分割してY軸90度回転してから造形してXファイルを出力させる必要があります。
(なのでテクスチャは逆方向に90度回転させとく必要も・・・)
分割数は16129(127*127)まで(これ以上はモデルが作られなかったりアプリエラーが出る)
複数のMeshmapを並べる場合隣接部分の内側と外側の2列は同じ面方向にする必要があります。(バグか仕様かマイナス方向に1マス余分に判定されるので)
取得出来る地面の法線がおかしい場合がある(隣接する面に影響されてる感じ)
上のに関係してるのか三角形に分割されてるラインの部分が高い場合地形に潜ることがある(描画と一致してない)
(グリッドサイズが大きいほど埋まったり空中に浮くのが目立つ・・・)
Meshmapのスムージング適用がメタセコイアとは違うので同じにはならない(Meshmapのはなんか根本的に違う感じ)

「 mod_hgCnvRayCol.hsp Ver0.75 」
https://ux.getuploader.com/himajin130414/download/44


addTerrainMeshmapの使用サンプル

#include "mod_hgCnvRayCol.hsp" if 0.75>mod_hgCnvRayCol_VER {dialog "このサンプルに対応してないバージョンです":end} gsel 0,1 hgini chdir dir_exe+"\\sample\\hgimg3\\" MetricBaseValue=4.0 //1メートルの基準値(1.0にすると影の浮きが20センチになって目立つので・・・) addxfile m_xmodel,"tamane_w.x" modelorder m_xmodel,0 //回転しないなら無くても良いけど忘れるとやっかいなのでX形式のモデルはとりあえずmodelorderを実行 regobj mychr, m_xmodel,OBJ_STAND|OBJ_WALKCLIP objfloor mychr,0.2 ; 地面からのオフセット値を指定する(影がデフォルトで0.2ぐらい浮いてるので) mysy=MetricBaseValue*1.8 //自分の身長を1.8メートルに指定 setscale mychr,mysy/329.8,mysy/329.8,mysy/329.8 //mysyになるようにスケール設定(329.8は tamane_w.x の高さ) addeprim m_sd,EPRIM_CIRCLE seteprim m_sd,0,2 seteprim m_sd,1,12 seteprim m_sd,2,1.0 seteprim m_sd,3,1.0 seteprim m_sd,16,$80000000 seteprim m_sd,17,$80000000 seteprim m_sd,18,$80000000 seteprim m_sd,19,$00000000 regobj mysdw, m_sd, OBJ_LATE|OBJ_LAND|OBJ_STAND ; 半透明なのでOBJ_LATEを指定する setscale mysdw,0.5,0.5,0.5 setefx mysdw,$500 ; 半透明(色減算)の指定 objchild mychr, mysdw ; 自分の子供として影を登録 fname_ground="sb_bg1.x" addxfile m_ground,fname_ground modelorder m_ground,0 regobj ground_oid, m_ground,//OBJ_HIDE Terrain_id=ground_oid //オブジェIDをTerrainデータIDとしても使用 //Terrainデータ作成 loadTerrain Terrain_id,fname_ground //地面の地形データとオブジェクトを関連付け setTerrainLinkObj Terrain_id, ground_oid, 0 //addTerrainMeshmap実行時にオブジェクトの移動スケール変更が反映されるように設定 //グリッドサイズが大きいと地形に潜りやすいので実際のサイズより小さく設定 getTerrainBoundingBox Terrain_id, minbbox, maxbbox,sizebbox,100.0,0 //Xサイズ100になるようにTerrain_idのバウンテンボックス取得 setscale ground_oid,refdval,refdval,refdval setborder sizebbox-MetricBaseValue*0.5,200,sizebbox(2)-MetricBaseValue*0.5 ; 移動範囲の設定 hgprm 2,-100 //地面の上限 //TerrainデータからOBJ_GROUND|OBJ_HIDEが設定されたMeshmapを作成 addTerrainMeshmap Terrain_id, m_mesh, 0,,obj_mesh,0 clscolor $6060 ; 背景色の設定 cammode CAM_MODE_LOOKAT cax=-0.5 cay=0.0 my_mvx=0.0 my_mvy=0.0 my_mvz=0.0 gravity=MetricBaseValue*0.98/60.0 cam_dis=40.0 spd=0.25 hid="xfile","Meshmap" title hid *main stick key,$ffff-64-1024 if key&128 : end mx=mousex my=mousey mw=mousew cam_dis+=0.02*mw //マウスホイールでカメラの距離調整 if key&512 {//マウス右ドラックでカメラ回転 mx_dif=mx-mx_bak my_dif=my-my_bak cax+=0.005*my_dif cay-=0.005*mx_dif } mx_bak=mx my_bak=my if key&64 {//Ctrlでジャンプ my_mvy=-MetricBaseValue*0.3 } if key&1024 {//Tabで地上表示切替 HIDE^1 title hid(HIDE) setobjmode obj_mesh,OBJ_HIDE,0^HIDE setobjmode ground_oid,OBJ_HIDE,1^HIDE } my_mvx=0.0 my_mvy+gravity my_mvz=0.0 if key&1 :my_mvx=-spd if key&2 :my_mvz=-spd if key&4 :my_mvx=spd if key&8 :my_mvz=spd fvset mypos,cax,-cay,0.0 fvdir mypos,my_mvx,0.0,my_mvz objwalk vres,mychr,mypos,my_mvy,mypos(2) if vres(1)<=0.0 and my_mvy>0.0 {my_mvy=0.0}//落下中に接地したので落下速度を0に getpos mychr,px,py,pz fvset camfv,cax,-cay,0.0 fvdir camfv,0.0,0.0,cam_dis setpos HGOBJ_CAMERA, px+camfv,py+camfv(1)-mysy,pz+camfv(2) ; カメラ位置の設定 selcint objset3 px,py-mysy,pz hgdraw hgsync 16 goto *main



暇人

リンク

2018/5/27(Sun) 17:01:53|NO.84509

書き忘れ

sb_bg1.x とaddmeshmapで作られるモデルでは三角形分割が違うので
NO.84508のサンプルでは地形に潜りやすいです。
Shiftで表示切替できるのでどんな感じか分かります。



暇人

リンク

2018/5/29(Tue) 20:56:16|NO.84527

>Shiftで表示切替できるのでどんな感じか分かります。
ShiftじゃなくてTabでした・・・



ONION software Copyright 1997-2023(c) All rights reserved.