|
|
2021/10/24(Sun) 06:54:27|NO.94233
●HGIMG4で指定したXYZ回転ベクトルの向きへgppapplyでGPPAPPLY_FORCEやGPPAPPLY_IMPULSEをしたい
HGIMG4で指定した方向(xyz回転ベクトル)へgppapplyでGPPAPPLY_FORCEやGPPAPPLY_IMPULSEをしたいです。
例えば、カメラの向きと同一方向へオブジェクトを前進させたい、といった風にです。
gppapplyのGPPAPPLY_FORCEはxyzの垂直方向の方向へ力を加えることはできるのですが、
指定したXYZ回転ベクトルの向きへ力を加えるといった命令がありません。
恐らく、xyzへの力の配分の比率と、その力へ掛ける倍率で、
そのXYZ回転ベクトルの向きへ力を加えるということができると思うのですが、その方法がよく分かりません。
恐らく、sin()やcos()、もしくはfv系命令を使って配分を求めるのだと思うのですが、
3次元となるとお手上げ状態になってしまいました。
自分がイメージした概念はこんな感じです。
; camera_main = カメラノード
; camera_collision = 物理挙動が適用された非表示のノード
power = 10.0 ; どれだけの力を加えるか
getang camera_collision, x, y, z
; camera_collisionのXYZ回転ベクトルと同じ方向へcamera_collisionをpowerの力分で前進させたい
gppapply camera_collision, 何らかの処理(x)* power, 何らかの処理(y)* power, 何らかの処理(z)* power
; camera_collisionの位置と回転をカメラノードへセットする
getpos camera_collision, x, y, z
setpos camera_main, x, y, z
getang camera_collision, x, y, z
setang camera_main, x, y, z
アドバイスお願い致します。
|
|
2021/10/24(Sun) 15:00:22|NO.94235
モデル空間の、あるベクトルを
XYZ回転ベクトルで回転してグローバル座標系での
方向ベクトルを算出するには下記コード中の _rotxyz のようにします。
サンプルコードでは
デフォルメたまねちゃんのモデル空間での正面である(0,0,1)に前進します。
カメラオブジェクトの場合はカメラの正面は(0,0,-1)なので
v に代入するところを変更してください。
また頭上へのベクトルが欲しい場合は(0,1,0)を変換するとよいです。
#include "hgimg4.as"
#module
#deffunc _rotxyz array _result, array _src, double _rx, double _ry, double _rz, local _cs, local _sn, local _tv2, local _tv3
// _result: 結果を書き出す先の 3要素のdouble配列
// _src: 回転される方向ベクトル 3要素のdouble配列
// _rx, _ry, _rz: getang と一致するオイラー回転 [rad]
_cs = cos(_rx) // X回転
_sn = sin(_rx)
ddim _tv2, 3
_tv2.0 = _src.0
_tv2.1 = _src.1 * _cs - _src.2 * _sn
_tv2.2 = _src.1 * _sn + _src.2 * _cs
_cs = cos(_ry) // Y回転
_sn = sin(_ry)
ddim _tv3, 3
_tv3.0 = _tv2.0 * _cs + _tv2.2 * _sn
_tv3.1 = _tv2.1
_tv3.2 = - _tv2.0 * _sn + _tv2.2 * _cs
_cs = cos(_rz) // Z回転
_sn = sin(_rz)
_result.0 = _tv3.0 * _cs - _tv3.1 * _sn
_result.1 = _tv3.0 * _sn + _tv3.1 * _cs
_result.2 = _tv3.2
return
#global
randomize
gpload id, "res/tamane2"
setscale id, 0.1, 0.1, 0.1
setangy id, double(rnd(100)) * 0.01 * M_PI, double(rnd(100)) * 0.01 * M_PI, double(rnd(100)) * 0.01 * M_PI
gppbind id, 2.0, 1.0
gppset id, GPPSET_GRAVITY, 0.0, -0.001, 0.0
ddim v,3
ddim result, 3
power = 0.2
repeat
redraw 0
getang id, rx, ry, rz // // X->Y->Z のオイラーで取得する
v.0 = 0.0 // モデル空間での向きベクトル (0, 0, 1)
v.1 = 0.0
v.2 = 1.0
_rotxyz result, v, rx, ry, rz
gppapply id, GPPAPPLY_IMPULSE, result.0 * power, result.1 * power, result.2 * power
gpdraw
redraw 1
await 1000/60
loop
| |
|
2021/10/25(Mon) 17:02:04|NO.94239
アドバイスありがとうございます!
_rotxyz命令は応用範囲が非常に広い命令だと思いました。
例えば、gppapplyだけではなく、addposでも同様の結果が得られました。
また、_rotxyzをベースにすれば、角度を変化させるだけで、様々な軌道も簡単にプログラムできるようになるんですね。
これは本当にすごいです。
とても役立ちました!
|
|
2021/10/25(Mon) 21:58:35|NO.94240
もう解決してますが、作ってたので別パターンとしてご参考までに失礼します。
>fv系命令を使って
昔の3Dゲーム的な移動
#include "hgimg4.as"
chdir dir_exe+"\\sample\\hgimg4"
gpreset : setcls CLSMODE_SOLID, $808080
setpos GPOBJ_CAMERA, 0,100,150
; 床
gpfloor id_floor, 200,200, $404040 : gppbind id_floor, 0
; キャラ
gpload id, "res/tamane2" : setscale id, 0.1, 0.1, 0.1
ddim ang, 3 : ang.1 = M_PI
power = 1.0
repeat
;キー操作
stick key,15
; Y回転
if key&1 : ang.1+=0.05
if key&4 : ang.1-=0.05
; 移動
speed = 0.0
if key&2 : speed = power
if key&8 : speed = -power
;---------------------------------
; ココがキモ
fvset v, -ang.0, -ang.1, -ang.2
fvdir v, 0, 0, speed ; ベクトル回転させる(進む方法はz軸正面としたスピード)
;---------------------------------
setang id, ang.0, ang.1, ang.2
addpos id, v.0, v.1, v.2
; カメラ
getpos id, x,y,z : gplookat GPOBJ_CAMERA, x,y,z
redraw 0 : gpdraw : redraw 1 : await 1000/60
loop
>カメラの向きと同一方向へオブジェクトを前進させたい
TPSとかでよくある移動
#include "hgimg4.as"
chdir dir_exe+"\\sample\\hgimg4"
gpreset : setcls CLSMODE_SOLID, $808080
setpos GPOBJ_CAMERA, 0,50,150
; 床
gpfloor id_floor, 200,200, $404040 : gppbind id_floor, 0
; キャラ
gpload id, "res/tamane2" : setscale id, 0.1, 0.1, 0.1
setpos id, 0,0,-50
ddim ang, 3 : power = 1.0
repeat
;キー操作
stick key,15
; 移動
speed_x = 0.0 : speed_z = 0.0
if key&1 : speed_x = -power
if key&2 : speed_z = -power
if key&4 : speed_x = power
if key&8 : speed_z = power
;---------------------------------
; ココがキモ
; カメラに合わせた移動ベクトルを v に作成
getang GPOBJ_CAMERA, v.0, v.1, v.2 ;カメラの角度を取得
fvset v, -v.0, -v.1, -v.2 ;カメラと逆向きにする
fvdir v, speed_x, 0, speed_z ; ベクトル回転させる
; 平面に沿ったベクトルを求める
; 平面の法線方向と移動ベクトル内積(その方向への仕事量)
fvset f, 0, 1, 0 : fvinner f, v.0, v.1, v.2
; 法線方向の仕事量
fvset n, 0, 1, 0 : fvmul n, f.0,f.0,f.0
; 平面に対するベクトルを求める(移動ベクトルから法線方向の仕事量を引く)
fvsub v, n.0, n.1, n.2
;---------------------------------
; 移動
addpos id, v.0, v.1, v.2
; 回転
fvset a, 0,0,0 : fvface a, v.0, v.1, v.2
setang id, -a.0, -a.1, -a.2
addang id, 0, M_PI, 0
; カメラ
getpos id, x,y,z : gplookat GPOBJ_CAMERA, x,y,z
redraw 0 : gpdraw : redraw 1 : await 1000/60
loop
| |
|
2021/11/1(Mon) 12:19:12|NO.94270
usagiさん、アドバイスありがとうございます。
1つ目のサンプルはラジコン型の操作で、2つ目のサンプルは、カーソルキーの方向とキャラクターの移動の方向を一致させた上で
3次元上で移動させるということですね。
テクニカルで大変面白いと思います。勉強になります。
|
|
2021/11/1(Mon) 12:57:39|NO.94271
横から失礼致します。
今年のコンテストに応募した私の「〓[hgimg4]手引き〓」でも、同問題に関してのスクリプトを載せて解説させて頂いています。
ちょっと覗いて頂けると、うれしいです。
特に、画面左下の [ステップスクリプト 全(1〜11)]ボタンで、制作過程順のスクリプト集(1~11)が表示され、実行もできます。
|
|