Study/Character

max export 5. transform 정보는?

붕대마음 2011. 4. 23. 10:15
반응형


이전 글에서는 vertex정보와 face정보를 얻어오는 부분까지 만들어 보았다.
이제 transform정보를 사용해서 실제 vertex 정보를 구해보자.

맥스에서는 Affine Transformation을 사용한다.
이는 기하학적 변환(이동, 회전, 스케일링)이라고 말한다.
점 사이의 거리나 라인 사이의 각도를 수정할 수 있지만 직선(straight line) 및 평행선(parallel line)
사이의 평행관계는 유지
한다.
Affine matrices는 3x4 matrix를 사용한다. ( non affine은 4x4를 사용.)


1. 순서는 PRS이다. (Position, Rotation, Scale)
2. 왼손 좌표계, z up system이다. (dx는 y up system)
3. P x R x S = local TM Matrix.         
  (PRS 변환이 복합적으로 잘 적용되면 결론적으로 3d affine matrix가 된다.)
4. INode::GetNodeTM(TimeValue) 함수를 사용하면 주어진 시간에서의 transform matrix를 구할 수 있다.
5. Local Transform을 구하는 방법은 아래와 같다.
   Matrix3 tmWorld = pNode->GetNodeTM(TimeValue);
   Matrix3 tmParent = pNode->GetParentTM(TimeValue);
   Matrix3 tmLocal = tmWorld * Inverse(tmParent);


우선 노드의 Transform 행렬들을 출력해 보자.
위의 글 중 5번글에 적은것을 그대로 하면 된다.
void MgExport2::ExportPRS(INode* node, int treeDepth)
{
 Matrix3 tmWorld  = node->GetNodeTM(0);
 Matrix3 tmParent = node->GetParentTM(0);
 Matrix3 tmLocal  = tmWorld * Inverse(tmParent);

 // tmLocal 출력
 Write(treeDepth, tmLocal);
}

구한 local행렬로 Position, Rotation, Scale을 구하나.
이때 max에서 사용하는 affine 구조체를 사용한다.
void MgExport2 :: Write(int indent, const Matrix3& tmVal)
{
 AffineParts affine;     // max용 구조체, (이동, 회전, 스케일회전, 스케일, 부호)값이 있음.
 float rotEuler[3];

 decomp_affine(tmVal, &affine);  // 구조체의 값을 얻음.

 // affine의 rotation quaternion를 rotation euler로 변환
 affine.q.GetEuler(&rotEuler[0], &rotEuler[1], &rotEuler[2]);

 // position 출력
 Write(indent, "PRS: P (%f, %f, %f", affine.t.x, affine.t.y, affine.t.z);

 // euler rotation
 Write(indent, "PRS: R (%f, %f, %f", rotEuler[0], rotEuler[1], rotEuler[2]);

 // scale
 Write(indent, "PRS: S (%f, %f, %f", affine.k.x, affine.k.y, affine.k.z);
}

결과물은 아래와 같다.



참고
AffineParts, decomp_Affine : http://blog.naver.com/bastard9?Redirect=Log&logNo=140087916508