📄 animout.cpp
字号:
}
/*****************************************************************
Convert Bezier keys Tangent flags from Max to Virtools
*****************************************************************/
CKBezierKeyFlags MaxBezFlags2Virtools(DWORD f)
{
CKBezierKeyFlags Flags;
DWORD InType = GetInTanType(f);
DWORD OutType = GetOutTanType(f);
switch (InType) {
case BEZKEY_SMOOTH: Flags.SetInTangentMode(BEZIER_KEY_AUTOSMOOTH); break;
case BEZKEY_LINEAR: Flags.SetInTangentMode(BEZIER_KEY_LINEAR); break;
case BEZKEY_STEP: Flags.SetInTangentMode(BEZIER_KEY_STEP); break;
case BEZKEY_FAST: Flags.SetInTangentMode(BEZIER_KEY_FAST); break;
case BEZKEY_SLOW: Flags.SetInTangentMode(BEZIER_KEY_SLOW); break;
case BEZKEY_USER: Flags.SetInTangentMode(BEZIER_KEY_TANGENTS); break;
}
switch (OutType) {
case BEZKEY_SMOOTH: Flags.SetOutTangentMode(BEZIER_KEY_AUTOSMOOTH); break;
case BEZKEY_LINEAR: Flags.SetOutTangentMode(BEZIER_KEY_LINEAR); break;
case BEZKEY_STEP: Flags.SetOutTangentMode(BEZIER_KEY_STEP); break;
case BEZKEY_FAST: Flags.SetOutTangentMode(BEZIER_KEY_FAST); break;
case BEZKEY_SLOW: Flags.SetOutTangentMode(BEZIER_KEY_SLOW); break;
case BEZKEY_USER: Flags.SetOutTangentMode(BEZIER_KEY_TANGENTS); break;
}
return Flags;
}
/********************************************************************************
Creates a Position Controller on a CKObjectAnimation using
Max Controller key frame data. the 3 standard type of controller
are supported : Linear,Bezier and TCB
*********************************************************************************/
void Max2Nmo::DumpPosKeys(Control* cont,CKObjectAnimation* anim)
{
if (!cont) return;
IKeyControl *ikc = GetKeyControlInterface(cont);
if (!ikc) return ;
int i,numKeys = ikc->GetNumKeys();
if (!numKeys) return ;
Class_ID cont_cid = cont->ClassID();
// If this is not a standard controller we return
if (cont_cid.PartB()) return;
//--- Create the appropriate Virtools position controller
CKANIMATION_CONTROLLER VirtoolsCtrlType;
switch (cont_cid.PartA()) {
case TCBINTERP_POSITION_CLASS_ID : VirtoolsCtrlType = CKANIMATION_TCBPOS_CONTROL; break;
case HYBRIDINTERP_POSITION_CLASS_ID : VirtoolsCtrlType = CKANIMATION_BEZIERPOS_CONTROL; break;
case LININTERP_POSITION_CLASS_ID : VirtoolsCtrlType = CKANIMATION_LINPOS_CONTROL; break;
default : return;
}
CKAnimController* ctrl = anim->CreateController(VirtoolsCtrlType);
//--- And convert max keys
switch (cont_cid.PartA()) {
case TCBINTERP_POSITION_CLASS_ID :
for (i=0; i<numKeys; i++) {
ITCBPoint3Key key;
ikc->GetKey(i, &key); // Get Max Key
// Create Virtools Key
CKTCBPositionKey VirtoolsKey(FrameTime(key.time),
VxVector(key.val.x,key.val.z,key.val.y),
key.tens,key.cont,key.bias,
key.easeIn,key.easeOut);
ctrl->AddKey(&VirtoolsKey);
}
break;
case HYBRIDINTERP_POSITION_CLASS_ID :
for (i=0; i<numKeys; i++) {
IBezPoint3Key key;
ikc->GetKey(i, &key); // Get Max Key
// Convert Max Bezier tangent to Virtools format
CKBezierKeyFlags Flags=MaxBezFlags2Virtools(key.flags);
float ScaleFactor = GetFrameRate()*16.0f/3.0f;
VxVector InTang(key.intan.x,key.intan.z,key.intan.y),
OutTang(key.outtan.x,key.outtan.z,key.outtan.y);
InTang*=ScaleFactor;
OutTang*=ScaleFactor;
// Create Virtools Bezier Key
CKBezierPositionKey VirtoolsKey(FrameTime(key.time),
VxVector(key.val.x,key.val.z,key.val.y),
Flags,
InTang,OutTang);
ctrl->AddKey(&VirtoolsKey);
}
break;
case LININTERP_POSITION_CLASS_ID :
for (i=0; i<numKeys; i++) {
ILinPoint3Key key;
ikc->GetKey(i, &key); // Get Max Key
// Create Virtools linear Position Key
ctrl->AddKey(&CKPositionKey(FrameTime(key.time),
VxVector(key.val.x,key.val.z,key.val.y)));
}
break;
}
}
/********************************************************************************
Creates a Rotation Controller on a CKObjectAnimation using
Max Controller key frame data. the 3 standard type of controller
are supported : Linear,TCB (Bezier will be converted to linear)
********************************************************************************/
void Max2Nmo::DumpRotKeys(Control* cont,CKObjectAnimation* anim)
{
if (!cont) return;
IKeyControl *ikc = GetKeyControlInterface(cont);
if (!ikc) return ;
int numKeys = ikc->GetNumKeys();
if (!numKeys) return ;
CK3dEntity* ent = anim->Get3dEntity();
//-- Light and Camera animation need an additional rotation around X axis to be valid
//-- in Virtools ( Z axis is supposed to be the direction of the lights and cameras )
Quat RotateX;
RotateX.Identity();
if (CKIsChildClassOf(ent,CKCID_CAMERA) || CKIsChildClassOf(ent,CKCID_LIGHT)) {
RotateX=QFromAngAxis(HALFPI,Point3(1.0f,0.0f,0.0f));
}
Class_ID cont_cid = cont->ClassID();
// If this is not a standard controller we return
if (cont_cid.PartB()) return;
//--- Create the appropriate Virtools position controller
CKANIMATION_CONTROLLER VirtoolsCtrlType;
switch (cont_cid.PartA()) {
case TCBINTERP_ROTATION_CLASS_ID : VirtoolsCtrlType = CKANIMATION_TCBROT_CONTROL; break;
case HYBRIDINTERP_ROTATION_CLASS_ID :
case LININTERP_ROTATION_CLASS_ID : VirtoolsCtrlType = CKANIMATION_LINROT_CONTROL; break;
default : return;
}
CKAnimController* ctrl = anim->CreateController(VirtoolsCtrlType);
//--- And convert key frame data
switch (cont_cid.PartA()) {
case TCBINTERP_ROTATION_CLASS_ID :
{
// TCB Rotation anim use relative keys in Max => Need to convert to absolute
// rotation for Virtools
Quat absoluteRotQuat;
Quat quatFromAngAxis;
absoluteRotQuat.Identity();
for (int i=0; i<numKeys; i++) {
// Get Max key
ITCBRotKey key;
ikc->GetKey(i, &key);
// Convert 2 Virtools format
if (key.val.angle<0) {
key.val.angle = -key.val.angle;
key.val.axis = -key.val.axis;
}
key.val.axis = Normalize(key.val.axis);
quatFromAngAxis=QFromAngAxis(key.val.angle,key.val.axis);
absoluteRotQuat*=(const Quat&)quatFromAngAxis;
Quat Val = RotateX*absoluteRotQuat;
// And create Virtools Key
CKTCBRotationKey VirtoolsKey(FrameTime(key.time),
VxQuaternion(-Val.x,-Val.z,-Val.y,Val.w),
key.tens,key.cont,key.bias,
key.easeIn,key.easeOut);
ctrl->AddKey(&VirtoolsKey);
}
} break;
case HYBRIDINTERP_ROTATION_CLASS_ID :
case LININTERP_ROTATION_CLASS_ID :
{
for (int i=0; i<numKeys; i++) {
ILinRotKey key;
ikc->GetKey(i, &key);
Quat Val = RotateX*key.val;
ctrl->AddKey(&CKRotationKey(FrameTime(key.time),
VxQuaternion(-Val.x,-Val.z,-Val.y,Val.w)));
}
} break;
}
}
/**********************************************************************************
Creates a Scale Controller on a CKObjectAnimation using
Max Controller key frame data
**********************************************************************************/
void Max2Nmo::DumpScaleKeys(Control* cont,CKObjectAnimation* anim)
{
if (!cont) return;
IKeyControl *ikc = GetKeyControlInterface(cont);
if (!ikc) return ;
int numKeys = ikc->GetNumKeys();
if (!numKeys) return ;
//----------- TCB position
if (cont->ClassID() == Class_ID(TCBINTERP_SCALE_CLASS_ID, 0)) {
CKAnimController* ctrl = anim->CreateController(CKANIMATION_TCBSCL_CONTROL);
for (int i=0; i<numKeys; i++) {
ITCBScaleKey key;
ikc->GetKey(i, &key);
CKTCBScaleKey VirtoolsKey(FrameTime(key.time),
VxVector(key.val.s.x,key.val.s.z,key.val.s.y),
key.tens,key.cont,key.bias,
key.easeIn,key.easeOut);
ctrl->AddKey(&VirtoolsKey);
}
}
//----------- Bezier position
else if (cont->ClassID() == Class_ID(HYBRIDINTERP_SCALE_CLASS_ID, 0))
{
CKAnimController* ctrl = anim->CreateController(CKANIMATION_BEZIERSCL_CONTROL);
for (int i=0; i<numKeys; i++) {
IBezScaleKey key;
ikc->GetKey(i, &key);
CKBezierKeyFlags Flags=MaxBezFlags2Virtools(key.flags);
float ScaleFactor = GetFrameRate()*16.0f/3.0f;
VxVector InTang(key.intan.x,key.intan.z,key.intan.y),OutTang(key.outtan.x,key.outtan.z,key.outtan.y);
InTang*=ScaleFactor;
OutTang*=ScaleFactor;
CKBezierScaleKey VirtoolsKey(FrameTime(key.time),
VxVector(key.val.s.x,key.val.s.z,key.val.s.y),
Flags,
InTang,OutTang);
ctrl->AddKey(&VirtoolsKey);
}
}
//----------- Linear position
else if (cont->ClassID() == Class_ID(LININTERP_SCALE_CLASS_ID, 0)) {
CKAnimController* ctrl = anim->CreateController(CKANIMATION_LINSCL_CONTROL);
for (int i=0; i<numKeys; i++) {
ILinScaleKey key;
ikc->GetKey(i, &key);
ctrl->AddKey(&CKScaleKey(FrameTime(key.time),
VxVector(key.val.s.x,key.val.s.z,key.val.s.y)));
}
}
}
//-- Not truly the correct way to compare floats of arbitary magnitude...
BOOL EqualPoint3(Point3 p1, Point3 p2)
{
if (fabs(p1.x - p2.x) > ALMOST_ZERO) return FALSE;
if (fabs(p1.y - p2.y) > ALMOST_ZERO) return FALSE;
if (fabs(p1.z - p2.z) > ALMOST_ZERO) return FALSE;
return TRUE;
}
//-- Determine if a TM controller is known by the system.
Max2Nmo::IsKnownController(Control* cont)
{
ulong partA, partB;
if (!cont) return TRUE;
partA = cont->ClassID().PartA();
partB = cont->ClassID().PartB();
if (partB != 0x00) return FALSE;
switch (partA) {
case TCBINTERP_POSITION_CLASS_ID:
case TCBINTERP_ROTATION_CLASS_ID:
case TCBINTERP_SCALE_CLASS_ID:
case HYBRIDINTERP_POSITION_CLASS_ID:
case HYBRIDINTERP_ROTATION_CLASS_ID:
case HYBRIDINTERP_SCALE_CLASS_ID:
case LININTERP_POSITION_CLASS_ID:
case LININTERP_ROTATION_CLASS_ID:
case LININTERP_SCALE_CLASS_ID:
return TRUE;
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -