⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 animout.cpp

📁 3dmax导出3d模型二次开发插件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

/*****************************************************************
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 + -