ビューマトリクスは逆行列にしておくのがわからなかった orz
とりあえず、でけた。
#Python
from win32com.client import constants as c
import math
app = Application
log = app.Logmessage
def main():
Application.FreezeModeling("", "", "")
sel = app.Selection(0)
sub = sel.SubComponent
sID = sub.ComponentCollection.IndexArray
obj = sub.Parent3DObject
geo = obj.ActivePrimitive.Geometry
pnts = geo.Points
posa = pnts.PositionArray
posa = [ list( posa[ 0 ] ) , list(posa[ 1 ] ) , list( posa[ 2 ] ) ]
cam = app.GetValue( "Camera" )
#Matrix
om = getObjMatrix(obj)
vm = getViewMatrix(cam)
pm = getProjectionMatrix(cam)
m = om
m.MulInPlace( vm )
m.MulInPlace( pm )
im = XSIMath.CreateMatrix4()
im.Invert(m)
#ポイント移動
for i in sID:
pos = pnts(i).Position
pos.MulByMatrix4InPlace(m)
#ここでポイントをビュー座標で変換できる
#縦(pos.y)が基本 値は -1 ~ 1
#横(pos.x)はアスペクト比*2が、画面全長
#奥行き near ~ farを 0~1であらわす
pos.x # = 0
pos.y # = 0
pos.z # = 0
pos.MulByMatrix4InPlace(im)
posa[0][i] = pos.x
posa[1][i] = pos.y
posa[2][i] = pos.z
pnts.PositionArray = posa
#プロジェクションマトリクス
def getProjectionMatrix(inCamera):
cam = inCamera
#オーソグラフィックスの場合
if cam.proj.value != 1:
m = XSIMath.CreateMatrix4()
return m
#パースパクティヴの場合
aspect = cam.aspect.value
near = cam.near.value
far = cam.far.value
fov = cam.fov.Value
# SIは横のアスペクトが基本らしい。コレを変えた場合は修正が必要
fov = XSIMath.DegreesToRadians( fov ) / aspect
w = aspect * (math.cos(fov * 0.5) / math.sin(fov * 0.5))
h = 1 * (math.cos(fov * 0.5) / math.sin(fov * 0.5))
q = far / (far - near);
m = XSIMath.CreateMatrix4()
m.Set(
w , 0 , 0 , 0 ,
0 , h , 0 , 0 ,
0 , 0 , q , 1 ,
0 , 0 , -q * near, 0 )
return m
#オブジェクトのマトリクス
def getObjMatrix(inObj):
obj = inObj
m = XSIMath.CreateMatrix4()
obj.Kinematics.Global.Transform.GetMatrix4( m )
return m
#ビューマトリクス
def getViewMatrix(inCamera):
cam = inCamera
m = XSIMath.CreateMatrix4()
pos = XSIMath.CreateVector3()
oTrans = cam.Kinematics.Global.Transform
oTrans.GetMatrix4( m )
a = m.Get2()
m.Set(
a[0] , a[1] , a[2] , 0 ,
a[4] , a[5] , a[6] , 0 ,
-a[8] , -a[9] , -a[10] , 0 ,
a[12] , a[13] , a[14] , 1 )
m.InvertInPlace()
return m
main()
0 件のコメント:
コメントを投稿