ビューマトリクスは逆行列にしておくのがわからなかった 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 件のコメント:
コメントを投稿