3DSMAX convert OGRE(D3D)

1. 坐标转换:

坐标变换比较简单,按照轴的对应关系转换就可以了,按照多数插件的做法是yz互换,但是会发现场景是左右颠倒的,因为3dsmax是右手坐标系(Z向上,Y向内),而D3D是左手坐标系(Y向上,Z向内),所以x应该取负。

void MaxVtx2DX( Point3& p,Vec3& v )
{
 v.x = -p.x;
 v.y = p.z;
 v.z = p.y;
}

2.旋转转换

通常动画场景我们需要独立的旋转分量,一般是Quatnion,quat的转换就不是这么简单了。因为quat包含了正余弦值。

一个可以保证正确性的方法是,把Quat转成旋转矩阵,取得三根轴向,把轴看作矢量,按照上面规则进行处理。轴取自于行,还是取自于列,可能不同系统规定不同,但是我们可以用普适的方法去获得:用矩阵去变换基向量:

比如 M.Transform( Vector(1,0,0)) 得到的一定是X轴的朝向。

 

void MaxMtx2OgreTransform( Matrix3& mtx,Ogre::Vector3& pos,Ogre::Vector3& scale,Ogre::Quaternion&quat )
{
 Point3 p,s;
 Quat q;

 AffineParts ap;
 decomp_affine(mtx,&ap);

 s = Point3( ap.f,ap.f,ap.f);
 p = ap.t;
 q = ap.q;
 AngAxis aa(q);
 
 Matrix3 rtm;

 rtm.SetRotate(q);
 
 Vec3 ax,ay,az;

 Point3 right(1,0,0);
 Point3 up(0,0,1);
 Point3 dir(0,1,0);

 right = rtm.VectorTransform( right );
 up = rtm.VectorTransform( up );
 dir = rtm.VectorTransform( dir );

 MaxVtx2DX( right,ax );
 MaxVtx2DX( up,ay );
 MaxVtx2DX( dir,az );

 Vec3 tr,sc;
 MaxVtx2DX( p,tr );

 sc.x = s.x;
 sc.y = s.y;
 sc.z = s.z;

 quat.FromAxes(
  Ogre::Vector3(-ax.x,-ax.y,-ax.z),
  Ogre::Vector3(ay.x,ay.y,ay.z),
  Ogre::Vector3(az.x,az.y,az.z)
  );

 pos = Ogre::Vector3( tr.x,tr.y,tr.z );
 scale = Ogre::Vector3( sc.x,sc.y,sc.z );

}

 

3.相对变换

3DSMAX自身取相对变换是 Invert(ptm)*ntm,但是对于OGRE-D3D应该是反过来。

Matrix3 GetRelativeTM( Matrix3 ptm,Matrix3 ntm )
{
 Matrix3 iptm = ptm;
 iptm.Invert();
 Matrix3 tm = ntm *iptm ;
 
 return tm;
}

 

4.骨骼动画

骨骼动画的相对变换,应该是相对BindingPose,并且是局部变换对局部变换求相对变换:

AnimTransofrmMatrix = GetRelativeTM(BindingPoseLocalMatrix,NodeLocalMatrix(t))

t是time。

 

 

posted on 2010-08-13 09:45  cgwolver  阅读(1583)  评论(0编辑  收藏  举报

导航