decompose()と同じ計算の関数を作ってみる。要はmatrix3dToEulerAngleとmatrix3dToQuaternion(axisAngle)を作ればいい。オライリーの「実例で学ぶゲーム3D数学」に助けられた。matrix3dToQuaternionはほぼ本の通りに実装。matrix3dToEulerAngleに関しては、拡大縮小の値をとるためにがんばった。Math.atan2(sin,cos)で角度のラジアンが得られる。sin/cosの関係なので、cosは必ず0以外。両方に同じ値がくっついててもかまわない。するとそれぞれの値は次のような関係の行列になっていることを念頭におく。それぞれの値を導き出せばいい。平行移動量は[distance_x,distance_y,distance_z]で決定。Math.atan2(sx,cx);がほしいわけだが、そのものは得られない。Math.atan2(e[6],e[10]);である。これでradian_xとsx,cxが求められた。Math.atan2(-e[2],e[6]/sx);ともなる。Math.atan2(-e[2],e[10]/cx);も用意しておく。これでradian_yとsy,cyが求められた。同様にradian_zとsz,czを得られる。式が複雑で0の除算の可能性があるため、場合分けを念を入れてしてある。これらが求まれば、scale_x,y,zも求まる。これも0の除算を慎重に避ける。scale_x,y,zのどれか一つでも0が入ると計算不可能になるので注意。Math.atan2()を活用していることに注意。randomで値を入れて、各要素を比較して確認とした。逆方向を向いて後ろ歩きしているような符号、かも。この点をまだ理解しきれてないので、完全にはできてない。10,0,12,36だと、誤差が結構おおきい、、汗。バグの疑いが無くなってからやるべきだったか、、、。上の行列は10,0,12,36以前のもので、10,0,12,36からはprependScale的な計算に変わったので次の行列を計算することになる。Matrix3D.decompose()の動作確認。/*Matrix3D.decompose();と同じ機能の関数を作ってみる。10,0,12,36で動作確認。要はmatrix3dToEulerAngleとmatrix3dToQuaternion(axisAngle)を作ればいい。オライリーの「実例で学ぶゲーム3D数学」http://www.amazon.co.jp/gp/product/4873113776各要素にrandomで値を入れて、各要素を比較して確認とした。逆方向を向いて後ろ歩きしているような符号、かも。この点をまだ理解しきれてないので、完全にはできてない。10,0,12,36だと、誤差が結構おおきい、、汗。バグの疑いが無くなってからやるべきだったか、、、。◆追記やっぱり、10,0,12,36でappendからprependにrotationの仕方がかわったからっぽい。Mtrx3D.decompose(entity,"axisAngle");//確認txt+="↓Matrix3D.decomposeの結果\n";txt+="eulerAngles:"+Matrix3DEA+"\n";//txt+="quaternion"+Matrix3DQ+Matrix3DQ[1].w+"\n";//txt+="axisAngle"+Matrix3DAA+Matrix3DAA[1].w+"\n";txt+="\n";txt+="↓同機能関数Mtrx3D.decomposeの結果\n";txt+="eulerAngles"+Mtrx3DEA+"\n";//txt+="quaternion"+Mtrx3DQ+Mtrx3DQ[1].w+"\n";//txt+="axisAngle"+Mtrx3DAA+Mtrx3DAA[1].w+"\n";txt+="\n"+Util.hikaku2(Matrix3DEA,Mtrx3DEA,"eulerAngles");txt+="\n"+Util.hikaku2(Matrix3DQ,Mtrx3DQ,"quaternion");txt+="\n"+Util.hikaku2(Matrix3DAA,Mtrx3DAA,"axisAngle");////テキストフィールドを作りtxtを流し込み。vec;}//行列をクオータニオン(+軸角度方向)に変換する関数//オライリーの「実例で学ぶゲーム3D数学」P187を参考にした。//ただし、本の行列とは行と列が異なるので、書き換えてる。Vector3D(x,y,z,w),scale]);}//行列をオイラー角にする関数//縮小拡大の値を得るためにかならず実行。Vector3D(rounding(scale_x),rounding(scale_y),rounding(scale_z))]);//値を丸める関数。100万倍して、四捨五入をし10000で割った時に、1で割り切れれば、//さらに100で割った値を代入する。//これで0.999999...などを1にする。//計算精度を上げるには大きい方が有利なので//45度以上、という意味で以下でもいい。Vector3D(rounding(scale_x),rounding(scale_y),rounding(scale_z))]);//値を丸める関数。100万倍して、四捨五入をし10000で割った時に、1で割り切れれば、//さらに100で割った値を代入する。//これで0.999999...などを1にする。5回目に参加して来ました。