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


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
0509
ukeyhgimg3でのオブジェクトの移動について11解決


ukey

リンク

2015/5/9(Sat) 21:33:10|NO.69111

hgimg3内で物体を動かす際にマウスと連動させて動かそうと思って、mousexやmousey等を
使おうと試みたのですがまったくうまくいきません

初心者なのでなにもわかってないです・・・どなたかやり方お教えください



この記事に返信する


anal

リンク

2015/5/9(Sat) 21:37:12|NO.69113

mousexは画面のピクセルの座標で
hgimg3のオブジェクトの座標はまた違う数値です。



ukey

リンク

2015/5/9(Sat) 21:40:11|NO.69114

mousexは使えないということですね・・・

マウスでクリックしたらオブジェクトが消える、というようなことはできるでしょうか?



anal

リンク

2015/5/9(Sat) 22:00:53|NO.69115

というかhgimg3は3dライブラリとして機能が著しく欠けているのでEasy3Dという
別のライブラリを使ったほうがいい。
hgimg4はあんまり質問を見かけないがどうなんであろう



ukey

リンク

2015/5/9(Sat) 22:06:54|NO.69116

では一回そっちに切り替えてみますね。
ありがとうございました!



ukey

リンク

2015/5/9(Sat) 22:07:33|NO.69117

一応解決済みとさせていただきます



暇人

リンク

2015/5/9(Sat) 22:11:11|NO.69118

一番簡単なのはhgcnvaxis使って
2Dとして判定する方法
複雑な形状のモデルに対応するのは厳しいが・・・



ukey

リンク

2015/5/9(Sat) 22:47:51|NO.69119

使ってるのはただの球です

複雑ではないですね・・・



skyblue

リンク

2015/5/10(Sun) 10:28:52|NO.69127

>hgimg4はあんまり質問を見かけないがどうなんであろう
まだ開発版だからか使用環境の制限のせいで使う人がいないからだと思います。



暇人

リンク

2015/5/11(Mon) 00:44:08|NO.69141

hgimg3を使うかどうかは分からないけど
一応球のオブジェクト判定のモジュール
http://hsp.tv/play/pforum.php?mode=pastwch&num=58413
ここ↑で使ったモジュールに命令追加

#include "hgimg3.as" //必ず#include "hgimg3.as"の後に配置 #module #uselib "User32.dll" #func SetRectfloat "SetRect" var,float,float,float,float #define setfloat4(%1,%2=0.0,%3=0.0,%4=0.0,%5=0.0) %1(3) + 0:SetRectfloat %1,%2,%3,%4,%5 #uselib "d3dx9_39.dll" #cfunc D3DXSphereBoundProbe "D3DXSphereBoundProbe" var,float,var,var //[---モジュールの初期化---] //cnvsptowp_init //必ずhginiの後に実行(カメラのefxグループを変更したりスクリーンサイズを変更した時も実行する必要がある) //返り値refdvalにスクリーン座標系から3D座標系に変換する実数値が返る //refdval*スクリーン座標*カメラからの距離で2Dから3Dに出来る #deffunc cnvsptowp_init getefx HGOBJ_CAMERA,FOV,NearZ,FarZ ssx=1.0*ginfo_sx ssy=1.0*ginfo_sy whsx=0.5*ssx whsy=0.5*ssy wwx=ssx/ginfo_winx wwy=ssy/ginfo_winy tc=sin(0.5*FOV)/cos(0.5*FOV)/whsy return tc //[---スクリーン座標をワールド座標に変換---] //fvstw wp, sx, sy, cdz // wp = 3D座標を取得する配列(wp=x,y,z) // sx = スクリーンX座標指定 // sy = スクリーンY座標指定 // cdz = カメラからの距離を3D座標系で指定(プラスがカメラの前方向) //カメラの移動回転に対応 #deffunc fvstw array wp,double sx,double sy,double cdz getpos HGOBJ_CAMERA,cpx,cpy,cpz getang HGOBJ_CAMERA,crx,cry,crz fvset wp,crx,-cry,crz fvdir wp,(((sx-whsx/wwx)*cdz*tc)*wwx),(sy-whsy/wwy)*cdz*tc*wwy,-cdz fvadd wp,cpx,cpy,cpz return //[---スクリーン座標からレイを飛ばすベクトルを取得---] //fvray rvec, sx, sy, cdz // rvec = レイのベクトル(rvec=vx,vy,vz) // sx = スクリーンX座標指定 // sy = スクリーンY座標指定 // cdz = カメラからの距離を3D座標系で指定 //カメラの移動回転に対応 #deffunc fvray array rvec,double sx,double sy getang HGOBJ_CAMERA,crx,cry,crz fvset rvec,crx,-cry,crz fvdir rvec,(((sx-whsx/wwx)*tc)*wwx),(sy-whsy/wwy)*tc*wwy,-1.0 return //[---スクリーン座標からレイを飛ばしてワールドY座標が0になる時のワールドX,Z座標を取得---] //getRayPos wpx, wpy, wpz, sx, sy // wpx = 3DX座標を取得 // wpy = 3DY座標を取得 // wpz = 3DZ座標を取得 // sx = スクリーンX座標指定 // sy = スクリーンY座標指定 //カメラの移動回転に対応 #deffunc getRayPos var wpx,var wpy,var wpz,double sx,double sy fvray _rvec, sx, sy getpos HGOBJ_CAMERA,cpx,cpy,cpz if 0.0 = _rvec(1) {_rvec(1)=0.00000001}//_rvec(1)が0.0だと次の行で割り算に使えないので適当な小さい数値を入れる(これは地面方向の傾きが0の時の対策) dis=-cpy/_rvec(1) //カメラの高さをレイのYで割るとY座標0までのカメラからの距離が出る fvmul _rvec,dis,dis,dis //レイの方向ベクトルに距離を掛ければワールド座標になる fvadd _rvec,cpx,cpy,cpz //カメラ座標を足してカメラを基準にした座標にする (この二行は fvstw _rvec,sx,sy,dis に置き換ても同等の事が出来る) wpx=_rvec wpy=_rvec(1) wpz=_rvec(2) return //[---スクリーン座標からレイを飛ばしてオブジェクトの球と接触判定、交点取得、ドラッグする---] //getSphereRayColl tid, ip, msize, sx, sy, f, exmode, group, mode // tid = レイと接触した球のオブジェID(出力)[接触が無ければ-1] // ip = レイと接触したxyz座標(出力)[ip=x,y,z 但しドラッグ中は最初に接触した部分を掴んでる感じになる] // msize = 球のモデルサイズ(入力)[これにオブジェクトスケールを掛けて利用] // sx = スクリーンX座標指定(入力) // sy = スクリーンY座標指定(入力) // f = 判定用キー(入力)[0以外なら接触判定をしてドラッグ、0なら判定ドラッグ解除] // exmode = 検索を除外するモード(入力)[findobjの解説を参照] // group = 検索対象コリジョングループ値(入力)[findobjの解説を参照] // mode = 検索モード(入力)[0=接触判定をしてドラッグ、1=接触判定のみ] //システム変数refdvalにカメラから交点の距離が返る #deffunc getSphereRayColl var tid,array ip,double msize,double sx,double sy,int f,int exmode,int group,int mode if f { if (tf=0) or (mode&1) { tf=0 getpos HGOBJ_CAMERA,cx,cy,cz setfloat4 RayPosition_f,cx,cy,cz//ベクトルdoubleをfloatにして配列に入れる sx_bak=sx sy_bak=sy fvray _rvec, sx, sy //レイベクトル setfloat4 RayDirection_f,_rvec(0),_rvec(1),_rvec(2) fvset inrv,_rvec(0),_rvec(1),_rvec(2) fvinner inrv,_rvec(0),_rvec(1),_rvec(2) fvset ip,0.0,0.0,0.0 ttim=0.0 findobj exmode,group repeat nextobj obj_id if obj_id<0 { if tf { ip=cx +_rvec(0) * ttim ,cy +_rvec(1) * ttim ,cz +_rvec(2) * ttim hgcnvaxis tdx,tdy,tdz,ip,ip(1),ip(2),2 selpos tid objgetfv difxyz fvsub difxyz,ip,ip(1),ip(2) //交点からオブジェクトまでの差分 _tid=tid }else{tid=-1} break } getscale obj_id,obj_sclx,obj_scly,obj_sclz hsize=0.5*obj_sclx*msize //球の半径 getpos obj_id,ox,oy,oz setfloat4 SphereCenter_f,ox,oy,oz //光線が球の境界ボックスに当たるかどうかを判定 if D3DXSphereBoundProbe(SphereCenter_f,hsize,RayPosition_f,RayDirection_f) {//当った cox=cx-ox coy=cy-oy coz=cz-oz fvset inrvco,_rvec(0),_rvec(1),_rvec(2) fvinner inrvco,cox,coy,coz fvset inco,cox,coy,coz fvinner inco,cox,coy,coz inco-=hsize * hsize tim = ( -inrvco - sqrt( inrvco * inrvco - inrv * inco) ) / inrv //接触までの時間 if (ttim > tim) or tf=0 { ttim=tim tf=1 //接触したフラグ tid=obj_id } } loop }else{ if (sx_bak ! sx) or (sy_bak !sy) { fvstw ip, sx, sy, -tdz setpos _tid,ip+difxyz,ip(1)+difxyz(1),ip(2)+difxyz(2) //差分を加算 } } }else{ fvset ip,0.0,0.0,0.0 tf=0 tid=-1 tdz=0.0 } return tdz #global //モジュールここまで randomize screen 0,800,600,0 cls 4 hgini //必ずhginiの後に実行(カメラのefxグループを変更したりスクリーンサイズを変更した時も実行) cnvsptowp_init setfont 16,16,12,1 ; font Tex select(cx,cy,px,mode) texload "fontchr.bmp" ; フォントテクスチャの登録 msize=14.5 //モデルのサイズ addxfile m_xmodel,dir_exe+"\\sample\\hgimg3\\eye.x" repeat 40 regobj obj, m_xmodel ; オブジェクトの登録 setpos obj,150-rnd(300),150-rnd(300),-150-rnd(200) scl=0.5+0.01*rnd(400) setscale obj,scl,scl,scl setcoli obj,2,1 loop clscolor $80 ; 背景色の設定 *main stick key,$3ff if key&128 : goto *owari getSphereRayColl target_id,ipfv,msize,mousex,mousey,key&256,0,2,0 if target_id>0 { addang target_id,0,0.05,0 } hgdraw ; 描画 title str(target_id)+" x="+ipfv+" y="+ipfv(1)+" z="+ipfv(2) hgsync 10 ; 時間待ち if key&512 {//マウス右ドラッグでカメラ回転 addang HGOBJ_CAMERA, 0.01*(my-mousey), 0.01*(mx-mousex) } mx=mousex my=mousey //マウスホイール回転でカメラZ軸移動 addpos HGOBJ_CAMERA, 0.0, 0.0, 0.05*mousew ; カーソルキーでカメラXY軸移動 if key&1 : addpos HGOBJ_CAMERA, -0.2, 0.0 if key&4 : addpos HGOBJ_CAMERA, 0.2, 0.0 if key&8 : addpos HGOBJ_CAMERA, 0.0, 0.2 if key&2 : addpos HGOBJ_CAMERA, 0.0, -0.2 goto *main *owari end
一番近い球を検索するのに総当りになるから
どれぐらいの数まで使い物になるかは分からない



暇人

リンク

2015/5/12(Tue) 19:33:37|NO.69160

ちょっと補足
>一番近い球を検索するのに総当りになるから
球の座標じゃなく一番近い球の面を判定するので
大きさの異なる球が重なってても実際に見えてる部分が交点になる

>tim = ( -inrvco - sqrt( inrvco * inrvco - inrv * inco) ) / inrv //接触までの時間
timがマイナスならカメラと重なってる
重なってるのを除外したいなら

if tim<0.0 {continue }
を挿入する

>//システム変数refdvalにカメラから交点の距離が返る
マイナスならカメラの前で、プラスならカメラと重なってる
後、距離じゃなくカメラのローカルZ座標

fvstw wpos, mousex, mousey, -refdval
これで交点と同じローカルZ座標のワールド座標に出来る
ここに判定したオブジェクトを配置するとクリックの度にずれるので
getSphereRayCollではオブジェクトの座標から交点を引いた差分を足してる



暇人

リンク

2015/5/12(Tue) 21:50:28|NO.69161

あ、画像ファイルのフォルダ指定してない・・・
> texload "fontchr.bmp" ; フォントテクスチャの登録
これは使ってないのでコメントアウトでOK・・・



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