Hgimg3じゃなくてHgimg?
addangが使えるのはHgimg3だから
Hgimg3で解答
任意軸での回転が出来ないと無理だと思うのでクォータニオンを使って対処
//モジュールここから(このモジュールはDirectX9が必須です)
#module "mod_D3DXQ"
#uselib "d3dx9_39.dll"
#func D3DXMatrixRotationX "D3DXMatrixRotationX" var,float
#func D3DXMatrixTranslation "D3DXMatrixTranslation" var,float,float,float
#func D3DXQuaternionRotationAxis "D3DXQuaternionRotationAxis" int,var,float
#func global D3DXMatRotQ "D3DXMatrixRotationQuaternion" var,int
#func D3DXQuaternionMultiply "D3DXQuaternionMultiply" int,int,int
#func D3DXMatrixMultiply "D3DXMatrixMultiply" var,var,var
#func D3DXMatrixRotationYawPitchRoll "D3DXMatrixRotationYawPitchRoll" var,float,float,float
#func D3DXQuaternionRotationMatrix "D3DXQuaternionRotationMatrix" int,int
#cfunc global D3DXQuaternionN "D3DXQuaternionNormalize" int,int
#const H_PI M_PI/2.0
//「----クォータニオンモジュールの初期化----」
//D3DXQuaternion_init qmax
//qmax [クォータニオンID使用最大数(省略時1024)]int
#deffunc D3DXQ_init int qmax
if qmax<=0 {_qmax=1024}else{_qmax=qmax}
dim q,4*_qmax
q_ptr=varptr(q)
dim qid_list,_qmax
ddim temp_double,1
dim tq,4
tq_ptr=varptr(tq)
dim TurnMat,16
dim temp_Mat,16
dupptr dup_x,varptr(temp_Mat(12)),4,4
dupptr dup_y,varptr(temp_Mat(13)),4,4
dupptr dup_z,varptr(temp_Mat(14)),4,4
dupptr dup_mov,varptr(temp_Mat(12)),4*3,4
return
//「--------------クォータニオンから各オイラー角取得----」
//QGetAngXYZ %1 ,%2 ,%3 ,%4
//%1 [クォータニオンID(入力)]int
//%2 ,%3 ,%4 [各オイラー角(出力)]double
#define global QGetAngXYZ(%1,%2,%3,%4) D3DXMatRotQ TurnMat@mod_D3DXQ,D3DXQuaternionN(tq_ptr@mod_D3DXQ,qid_list@mod_D3DXQ(%1)):MatToEul TurnMat@mod_D3DXQ,%2,%3,%4
//「--------------指定角度から指定QIDにクォータニオン作成----」
//QSetRotXYZ qid, rx, ry, rz
// qid [クォータニオンID(入力)]int
// rx, ry, rz [各オイラー角(入力)]double
//(使用できる最大IDを超えるとstatに-1が返る)
#deffunc QSetRotXYZ int qid,double rx,double ry,double rz
if qid < _qmax {
D3DXMatrixRotationYawPitchRoll temp_Mat,-ry, 0.0, rz
D3DXMatrixRotationX TurnMat,rx
D3DXMatrixMultiply temp_Mat,temp_Mat,TurnMat
D3DXQuaternionRotationMatrix varptr(q(qid*4)),stat
qid_list(qid)=stat
}else{
return -1
}
return 0
//「-------------QIDを指定して入力クォータニオンの姿勢を基準に軸を指定して入力クォータニオンを回転----」
//QAddAxisRot qid, ax ,ay ,az , qrot
// qid [クォータニオンID(入力)]int
// ax ,ay ,az [回転軸ベクトル(入力)]double
// qrot [回転量(入力)]double
// World [軸がローカルかワールドか指定 0=ローカル軸 1=ワールド軸 (入力)]int
#deffunc QAddAxisRot int qid,double ax,double ay,double az,double qrot,int World
D3DXMatrixTranslation temp_Mat,ax ,ay ,az
D3DXQuaternionRotationAxis tq_ptr,dup_mov,qrot
if World {D3DXQuaternionMultiply qid_list(qid),stat,qid_list(qid)}else{D3DXQuaternionMultiply qid_list(qid),qid_list(qid),stat}
return
//「-------------QIDを指定して入力クォータニオンの姿勢を基準に軸を指定して入力クォータニオンを回転----」
//GetAxis A_index, Axisx, Axisy, Axisz
// A_index [ワールド軸を指定(0=X軸 1=Y軸 2=Z軸)]int
// Axisx, Axisy, Axisz [指定された軸に重なるほど1.0に近くなる(出力)]double
#deffunc GetAxis int A_index,var Axisx,var Axisy,var Axisz
Axisx=ftd(TurnMat(0+A_index*4))
Axisy=ftd(TurnMat(1+A_index*4))
Axisz=ftd(TurnMat(2+A_index*4))
return
//「-------------回転行列から各オイラー角取得----(QtoRxyzから使われる事が前提で単体では使用しない)」
//MatToEul Mat, ex, ey, ez
// Mat [回転行列4*4(入力)]float
// ex ,ey ,ez [各オイラー角(出力)]double
#deffunc MatToEul array Mat ,var ex,var ey,var ez
Mat8=limitf(ftd(Mat(8)),-1.0,1.0)
ey=-atan(Mat8,sqrt(1.0-Mat8*Mat8))
if absf(cos(ey))<0.001{
ex=atan(ftd(Mat(6)),ftd(Mat(5)))
if Mat8>0.0 {ey=-H_PI}else{ey=H_PI}
ez=0.0
}else{
ex=atan(-ftd(Mat(9)),ftd(Mat(10)))
ez=atan(-ftd(Mat(4)),ftd(Mat(0)))
}
return
//「----doubleからfloatに変換----」
//変数 = dtf( double )
#defcfunc dtf double _x
D3DXMatrixTranslation temp_Mat,_x
return dup_x
//「----floatからdoubleに変換----」
//変数 = ftd( float )
#defcfunc ftd int p1
temp=p1 << 29,p1 & 0x80000000 | ((p1 & 0x7fffffff) >> 3) + ((p1 & 0x7fffffff) ! 0) * 0x38000000
memcpy temp_double,temp,8
return temp_double
#global
//モジュールここまで
#include "hgimg3.as"
D3DXQ_init //モジュール初期化
screen 0,640,480,0
cls 4
hgini
addbox mdid,1,1//中心(親)のボックスモデル
regobj mychr,mdid ; 中心(親)のボックスオブジェクト
texload dir_exe+"\\sample\\hgimg3\\fontchr.bmp" ; テクスチャの登録
texid=stat
//パネルの位置
// 4 1 3
// 2
// 6
// 5
dx=0,0,1,-1,0,0 //パネル配置座標
dy=0,1,0,0,-1,0
dz=1,0,0,0,0,-1
drx=0,-90+180,0,0,90+180,-180 //パネルの角度
dry=0,0,90,-90,180,0
repeat 6
addplate m_plate,0,5,5,16*(1+cnt),16*3,16+16*(1+cnt),16+16*3,texid
regobj p_id(cnt),m_plate
objchild mychr,p_id(cnt) //パネルを中心のオブジェクトに連結
setpos p_id(cnt),2.5*dx(cnt),2.5*dy(cnt),2.5*dz(cnt)
setang p_id(cnt),deg2rad(drx(cnt)),deg2rad(dry(cnt)),0
loop
selcpos
objset3 6.0, -10.0, 20.0
selcang
objset3 -0.3, 0.3, 0.0
R90=M_PI/2 //90度のラジアン
//オブジェクトIDを使ってクォータニオン作成(使いやすいようにクォータニオンIDとオブジェクトIDを同じにしてる)
QSetRotXYZ mychr, 0.0, 0.0, 0.0
clscolor $4444
*main
stick k,0
if k&128 : goto *owari ; [ESC]で終了
if k&1 : QAddAxisRot mychr, 0.0, 1.0, 0.0, R90 ,1 //ワールドY軸を回転(←)
if k&4 : QAddAxisRot mychr, 0.0, 1.0, 0.0, -R90 ,1 //(→)
if k&2 : QAddAxisRot mychr, 1.0, 0.0, 0.0, -R90 ,1 //ワールドX軸を回転(↑)
if k&8 : QAddAxisRot mychr, 1.0, 0.0, 0.0, R90 ,1 //(↓)
if k&256 : QAddAxisRot mychr, 0.0, 0.0, 1.0, R90 ,1 //ワールドZ軸を回転(左クリック)
if k&512 : QAddAxisRot mychr, 0.0, 0.0, 1.0, -R90 ,1 //(右クリック)
//クォータニオンからオイラー角を取得
QGetAngXYZ mychr,rx,ry,rz
setang mychr,rx,ry,rz
//ローカル軸が向いてる方向を取得(1を指定するとワールドY軸にどのローカル軸が向いてるかが分かる)
GetAxis 1, Axisx, Axisy, Axisz //直前にQGetAngXYZされたクォータニオンに対して取得
ax=int(Axisx*1.1) //1.1を掛けてるのはint型にする時に誤差で0になるのを防ぐ
ay=int(Axisy*1.1)
az=int(Axisz*1.1)
//Axisx, Axisy, Axisz の組み合わせで数字が分かる(+-1がワールドY軸に重なってるローカル軸で、符号で上下が分かる)
;0,0,-1 //1
;0,-1,0 //2
;-1,0,0 //3
;1,0,0 //4
;0,1,0 //5
;0,0,1 //6
if ax {if ax=1 {no=4}else{no=3}}
if ay {if ay=1 {no=5}else{no=2}}
if az {if az=1 {no=6}else{no=1}}
title strf("X(%.1f) Y(%.1f) Z(%.1f)",rad2deg(rx),rad2deg(ry),rad2deg(rz))+strf(" [軸 ax(%d) ay(%d) ax(%d)]", ax, ay, az)+" サイコロの目="+no
hgdraw ; 描画処理
hgsync 16 ; 時間待ち
goto *main
*owari
end
これはワールド軸を基準にして回転させてるけど
サイコロのローカル軸で回転も出来る