形状を囲むOBBを計算 (スクリプト)
「物理アシスタント」のスクリプトの機能を使用して、
選択形状を囲むバウンディングボックスを計算します。
このとき、形状にフィットするように傾けたOBB (Oriented Bounding Box)を求めます。
OBBとは ?
OBBとは形状を囲むバウンディングボックスの種類の1つで、
形状に合わせて傾いた姿勢を持つことができます。
OBBは、中心とサイズ、傾きを表す回転行列を持ちます。
OBB情報を計算
以下をスクリプトウィンドウで実行すると、ブラウザで選択された形状の
OBBとしての中心位置/サイズ/回転行列を計算できます。
scene = xshade.scene()
shape = scene.active_shape()
# 物理シーンを作成.
p = scene.create_physics()
# OBBの計算(回転を考慮、ローカル座標で計算).
obbData = p.calc_obb_shape(shape, True, False)
print "中心位置 : " + str(obbData.center)
print "サイズ : " + str(obbData.size)
print "回転行列 : " + str(obbData.rotation)
# 物理シーンを破棄.
p.remove()
「p = scene.create_physics()」で物理シーンを作成、
「p.remove()」で物理シーンを破棄しています。
その間で「obbData = p.calc_obb_shape(shape, True, False)」を呼ぶと、OBBの計算が行われます。
第一引数は形状の参照、
第二引数をTrueにすると回転を考慮、
第三引数をTrueにするとワールド座標としての計算/Falseにするとローカル座標としての計算、となります。
結果が「physics_obb」クラスに戻り値として入ります。
physics_obbの「center」が中心位置、「size」がサイズ、「rotation」が回転行列となります。
形状を囲むOBBとして、直方体を配置
例として、ブラウザで選択された形状に重なるようにOBBの直方体を配置します。
scene = xshade.scene()
shape = scene.active_shape()
# 物理シーンを作成.
p = scene.create_physics()
# OBBの計算(回転を考慮、ローカル座標で計算).
obbData = p.calc_obb_shape(shape, True, False)
# 原点位置に、obbData.sizeのボックスを生成.
box = scene.create_primitive_box("box", 0, True, 1, 1, 1,
[ obbData.size[0] * 0.5, -obbData.size[1] * 0.5, -obbData.size[2] * 0.5],
[ obbData.size[0] * 0.5, -obbData.size[1] * 0.5, obbData.size[2] * 0.5],
[-obbData.size[0] * 0.5, -obbData.size[1] * 0.5, obbData.size[2] * 0.5],
[-obbData.size[0] * 0.5, -obbData.size[1] * 0.5, -obbData.size[2] * 0.5],
[0, obbData.size[1], 0],
True, True)
# OBBと位置と回転行列.
boxPos = obbData.center
boxRotM = obbData.rotation
# 回転行列に位置を加える.
m = [[0 for j in range(4)] for i in range(4)]
for i in range(4):
for j in range(4):
m[i][j] = boxRotM[i][j]
m[3][0] = boxPos[0]
m[3][1] = boxPos[1]
m[3][2] = boxPos[2]
# box形状に行列として反映.
box.transform(m)
# 物理シーンを破棄
p.remove()
これを実行すると、以下のように選択形状を囲む直方体が配置されます。