日々適当

hibitekitou

法線のグローバル空間での値の取得

xsi |2012-10-10
下の画像は、選択されているグリッドの法線の値をNullの位置として設定した物です。
XZ平面上に広がるグリッドだから、法線は(0,1,0)に当然なります。



法線を取得するために、以下のスクリプトを使っています。

#---
app = Application
log = LogMessage

#シーンに存在しているグリッドとNullを取得
oGrd = app.ActiveSceneRoot.FindChild("grid")
oNull = app.ActiveSceneRoot.FindChild("null")

#グリッドを構成しているPolygonNodeを取得
#ところでPolygonNodeって具体的には何なの?
oPolygons = oGrd.ActivePrimitive.Geometry.Polygons
oPolyNodes = oPolygons(0).Nodes

#法線を取得
vN = oPolyNodes(0).Normal

#Nullの位置を移動
oNullTrans = oNull.Kinematics.Global.Transform
oNullTrans.SetTranslation(vNG)
oNull.Kinematics.Global.Transform = oNullTrans
#---

で、例えば、グリッドの位置を移動してちょっと回転させたとして、上のスクリプトを実行すると、Nullの位置は変わりません。ローカル座標系内での法線の向きに変化がないからです。



では、この向きをグローバル座標系で得たい場合、どうしたらいいんでしょ。
すぐに考えつくのは、XSIMath.MapObjectPositionToWorldSpace( ObjectSpace, Position ) を使う事です。しかし、これを法線ベクトルに対して適用しちゃうと、ちょっと違う値が取得されちゃうのですね。



つまり、取得される値は上図の黄色いベクトルなんだけど、欲しいのは赤いベクトルなのです。
ってことで、赤いベクトルを得るために青いベクトルを黄色いベクトルから引いてやります。青いベクトルはグリッドの位置になります。



とりあえず、これで取得できたようです。
しかし、かなりまだるっこしいわけで、なんか一発で取得できちゃうメソッドとかないんすかね?

最終的にスクリプトはこうなってます。
app = Application
log = LogMessage

oGrd = app.ActiveSceneRoot.FindChild("grid")
oNull = app.ActiveSceneRoot.FindChild("null")

oGrdPos = XSIMath.CreateVector3()
oTrans = oGrd.Kinematics.Global.Transform
oTrans.GetTranslation(oGrdPos)

oPolygons = oGrd.ActivePrimitive.Geometry.Polygons
oPolyNodes = oPolygons(0).Nodes

vN = oPolyNodes(0).Normal
vNG = XSIMath.MapObjectPositionToWorldSpace(oTrans, vN)
vNG.Sub(vNG,oGrdPos)

oNullTrans = oNull.Kinematics.Global.Transform
oNullTrans.SetTranslation(vNG)
oNull.Kinematics.Global.Transform = oNullTrans


ちなみに先日の回転行列とかこれとかは、こんなスクリプトを書くためにやっていた事でした。



上図のこんな赤い棒たちが板を突き刺す感じのオブジェクトがあったとき、赤い棒たちの板の内部にある部分を削除したかったんです。下図の状態にしたいわけっすね。



その場合、赤い棒たちと板を分離してブーリアンしてもいいんですけど、下図の赤い部分(板の上面と下面)でスライスしてやればいいんじゃんって思うじゃないですか。



ってことで、それを実現するスクリプトを書いていた次第。



なんか車輪の再発明をしているような気がしないでもないけど、まぁ自分のお勉強用に、ね。

コメント ( 0 )|Trackback ( )
 
コメント
 
コメントはありません。
コメントを投稿する
ブログ作成者から承認されるまでコメントは反映されません
 
名前
タイトル
URL
コメント
コメント利用規約に同意の上コメント投稿を行ってください。

数字4桁を入力し、投稿ボタンを押してください。