0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MaxScriptで各行列を抽出してみた

Posted at

わりと試行錯誤してしまったので、自分へのメモも兼ねて投稿します。

MaxScriptで、オブジェクトの回転行列だけ取り出したいという事がありました。
しかし、オブジェクトが持っているプロパティは、各成分は、値として所持しており、『拡大』『回転』『平行移動』が合成されたトランスフォームだけだったりします。→ 参考
その為、各成分だけの行列を取り出したい場合は、以下の2通りになると考えられます。

  1. オブジェクトの所持ているプロパティから作成する
  2. 合成トランスフォームから、抜き出す

1の方法は上手く行かなかった為、2の方法で取り出しました。

検証環境
3DS Max 2022 ※ ツールのアップデートが遅れている為、2022で検証しています

作成したソースコード

関数化して、すぐに使えるようなコードになっています。
引き数は、取り出したいオブジェクトのtransformプロパティとなっています。
『拡大行列』『平行移動行列』に関しては、単位行列に必要な成分を入れて、なるべくプレーンな状態の行列を作成しています。
『回転行列』は、拡大成分が合成されている為、一度、拡大行列を作成し、その逆行列を使って抜き出しています。
行列の計算に関しては、 こちらの記事を参考にさせていただきました。

-- execute使用時は、グローバルでないと駄目
oPyramid001 = execute( "$Pyramid001" )
oPyramid002 = execute( "$Pyramid002" )
-- Pyramid002の位置をリセット
oPyramid002.transform = matrix3 1


-- 平行移動行列を抜き出す
fn GetLocationMatrix _mtx =
(
	-- 行成分抜き出し
	local pRow1 = [1, 0, 0]
	local pRow2 = [0, 1, 0]
	local pRow3 = [0, 0, 1]			
	local pRow4 = _mtx.row4

	-- 平行移動行列作成
	local outputMtx = matrix3 pRow1 pRow2 pRow3 pRow4 

	outputMtx
)

-- 拡大行列を抜き出す
fn GetScaleMatrix _mtx =
(
	-- 行成分抜き出し
	local inRow1 = _mtx.row1
	local inRow2 = _mtx.row2
	local inRow3 = _mtx.row3

	-- 拡大・縮小行列作成
	local mtxX =  sqrt ( inRow1.x * inRow1.x + inRow2.x * inRow2.x + inRow3.x * inRow3.x )
	local mtxY =  sqrt ( inRow1.y * inRow1.y + inRow2.y * inRow2.y + inRow3.y * inRow3.y )
	local mtxZ =  sqrt ( inRow1.z * inRow1.z + inRow2.z * inRow2.z + inRow3.z * inRow3.z )
	local sRow1 = [mtxX, 0, 0]
	local sRow2 = [0, mtxY, 0]
	local sRow3 = [0, 0, mtxY]			
	local sRow4 = [0, 0, 0]			
	local outputMtx = matrix3 sRow1 sRow2 sRow3 sRow4
	
	outputMtx
)

-- 回転行列を抜き出す
fn GetRotationMatrix _mtx =
(	
	local scaleMtx = GetScaleMatrix _mtx
	local ideScaleMtx = inverse scaleMtx

	-- 行成分抜き出し
	local inRow1 = _mtx.row1
	local inRow2 = _mtx.row2
	local inRow3 = _mtx.row3
	local inRow4 = scaleMtx.row4
	
	-- 回転・拡大行列抜き出し・作成
	local srMtx = matrix3 inRow1 inRow2 inRow3 inRow4

	-- 逆行列で行列を求める
	local outputMtx = srMtx * ideScaleMtx
	
	outputMtx	
)


--
-- 動作テスト
--
(
	-- 拡大行列を取得
	local scaleMtx     = GetScaleMatrix oPyramid001.transform
	-- 回転行列を取得
	local rotationMtx = GetRotationMatrix oPyramid001.transform
	-- 平行移動行列を取得
    local locationMtx = GetLocationMatrix oPyramid001.transform
	-- 拡大 x 回転 x 平行移動
    local gousei =  scaleMtx * rotationMtx * locationMtx

	-- 別のオブジェクトに反映させて行列のチェック
    oPyramid002.transform = gousei --結果を反映

	print scaleMtx
	print rotationMtx
	print locationMtx
	print gousei
)

結果

実行結果です。

Pyramid001が表示されている状態です。
Pyramid001は、拡大・回転・平行移動されているオブジェクトです。

Pyramid001が表示されている.png

Pyramid002が表示されている状態です。
Pyramid002は、初期状態で何の変換も加えていないオブジェクトです。
スクリプトでPyramid001と同じ変換を与えています。

Pyramid002が表示されている.png

二つのオブジェクトを表示した結果です。
重なっている事が確認できると思います。

二つのオブジェクト重なっている.png

おまけ

もう一つの面白いアプローチとしては、拡大・回転・平行移動のプロパティから、行列を作るという方法があった為、試しましたが、こちらは、私の方では上手く行きませんでした。
合成した行列をPyramid002に反映したところ、若干ずれがありました。
これは、Maxのバージョンによる挙動の変更などの違いかも知れませんが、各プロパティから行列を作れる事がわかり勉強になりました。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?