2011年5月26日木曜日

座標変換 ProjectionView

パースパクティヴ座標まで変換できたのでメモ
ビューマトリクスは逆行列にしておくのがわからなかった 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 件のコメント:

コメントを投稿