示例#1
0
/**
*  @brief
*    Returns whether or not the given controller has any key control interface (x, y, z)
*/
bool PLTools::HasKeyControlInterface(Control &cController)
{
	// X
	Control *pXController = cController.GetXController();
	if (pXController) {
		IKeyControl *pKeyControl = GetKeyControlInterface(pXController);
		if (pKeyControl && pKeyControl->GetNumKeys())
			return true; // There's at least one key control interface
	}

	// Y
	Control *pYController = cController.GetYController();
	if (pYController) {
		IKeyControl *pKeyControl = GetKeyControlInterface(pYController);
		if (pKeyControl && pKeyControl->GetNumKeys())
			return true; // There's at least one key control interface
	}

	// Z
	Control *pZController = cController.GetZController();
	if (pZController) {
		IKeyControl *pKeyControl = GetKeyControlInterface(pZController);
		if (pKeyControl && pKeyControl->GetNumKeys())
			return true; // There's at least one key control interface
	}

	// Funny... but 'scale controller' (unlike position and rotation) seam to have their own way...
	IKeyControl *pKeyControl = GetKeyControlInterface(&cController);
	if (pKeyControl && pKeyControl->GetNumKeys())
		return true; // There's at least one key control interface

	// There are no key control interfaces
	return false;
}
示例#2
0
// ADJUSTROTKEYS
void AdjustRotKeys(INode *node)
{
    Control *controller = node->GetTMController();
    Control *rotControl = controller->GetRotationController();
    IKeyControl *rotKeyCont = GetKeyControlInterface(rotControl);
    int numKeys = rotKeyCont->GetNumKeys();

    for(int i = 0; i < numKeys; i++)
    {
        ITCBKey key;
        rotKeyCont->GetKey(i, &key);

        key.cont = 0;
        rotKeyCont->SetKey(i, &key);

    }
    
}
示例#3
0
Interval AnimExportUtil::getKeyFramedRotationRange( INode* node3ds, Interval animRange )
{
	require( node3ds->GetTMController() );

	TimeValue start = animRange.Start();
	TimeValue end = animRange.End();

	// target defines rotation
	if ( node3ds->GetTarget() )
		return Interval( start, start );

	Control* cont = node3ds->GetTMController()->GetRotationController();
	IKeyControl* ikeys = cont ? GetKeyControlInterface( cont ) : 0;
	if ( ikeys )
	{
		ITCBRotKey key1;
		IBezQuatKey key2;
		ILinRotKey key3;
		IKey* keyp = 0;

		if ( cont->ClassID() == Class_ID(TCBINTERP_ROTATION_CLASS_ID, 0) )
			keyp = &key1;
		else if ( cont->ClassID() == Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID, 0) )
			keyp = &key2;
		else if ( cont->ClassID() == Class_ID(LININTERP_ROTATION_CLASS_ID, 0) )
			keyp = &key3;

		if ( keyp )
		{
			if ( 0 == ikeys->GetNumKeys() )
				return Interval( start, start );

			ikeys->GetKey( 0, keyp );
			start = keyp->time;
			ikeys->GetKey( ikeys->GetNumKeys()-1, keyp );
			end = keyp->time;
		}
	}

	return Interval( start, end );
}
示例#4
0
/**
 * This method will add all the position keys found in the controller to
 * the animation path.
 */
void OSGExp::exportPosKeys(osg::AnimationPath* animationPath, Control* cont){
	if (!cont)
		return;

	int i;
	IKeyControl *ikc = GetKeyControlInterface(cont);
	
	// TCB position
	if (ikc && cont->ClassID() == Class_ID(TCBINTERP_POSITION_CLASS_ID, 0)) {
		int numKeys;
		if (numKeys = ikc->GetNumKeys()) {
			for (i=0; i<numKeys; i++) {
				ITCBPoint3Key key;
				ikc->GetKey(i, &key);
				; // NOT SUPPORTED YET
			}
		}
	}
	// Bezier position
	else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_POSITION_CLASS_ID, 0)){
		int numKeys;
		if(numKeys = ikc->GetNumKeys()){
			for (i=0; i<numKeys; i++) {
				IBezPoint3Key key;
				ikc->GetKey(i, &key);
				; // NOT SUPPORTED YET
			}
		}
	}
	// Linear position
	else if (ikc && cont->ClassID() == Class_ID(LININTERP_POSITION_CLASS_ID, 0)) {
		int numKeys;
		if(numKeys = ikc->GetNumKeys()){
			for (i=0; i<numKeys; i++) {
				ILinPoint3Key key;
				ikc->GetKey(i, &key);
				addControlPos(animationPath, (key.time/(float)TIME_TICKSPERSEC),key.val);
			}
		}
	}
}
示例#5
0
void GR2ImportImpl::ImportRotation(Control* c, TransformTrack& track, float time, GR2Array<granny_real32>& defaultKeys)
{
	if (RotationCurveData* rotData = dynamic_cast<RotationCurveData*>(track.OrientationCurve.ToPointer()))
	{
		if (rotData->GetKeyType() == QUADRATIC_KEY)
		{
			if (Control *subCtrl = MakeRotation(c, Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID,0), Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0))) 
			{
				IKeyControl *keys = GetKeyControlInterface(subCtrl);
				if (keys) 
				{
					NWArray<float> times = rotData->GetKnots();
					NWArray<Quat> points = rotData->GetQuatData();
					if (times.size() == 0 && points.size() != 0)
						times = defaultKeys;

					keys->SetNumKeys(times.size());
					for (int i=0; i<times.size(); ++i)
					{
						Quat q = points[i];
						q.w = -q.w;
						IBezQuatKey rKey;
						memset(&rKey, 0, sizeof(rKey));
						rKey.time = TimeToFrame(times[i] + time);
						SetInTanType(rKey.flags, BEZKEY_SLOW);
						SetOutTanType(rKey.flags, BEZKEY_SLOW);
						rKey.val = q;
						keys->SetKey(i, &rKey);
					}
					keys->SortKeys();
				}
			}
		}
		else if (rotData->GetKeyType() == XYZ_ROTATION_KEY)
		{
			if (Control *subCtrl = MakeRotation(c, Class_ID(EULER_CONTROL_CLASS_ID,0), Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)))
			{
				IKeyControl *xkeys = GetKeyControlInterface(subCtrl->GetXController());
				IKeyControl *ykeys = GetKeyControlInterface(subCtrl->GetYController());
				IKeyControl *zkeys = GetKeyControlInterface(subCtrl->GetZController());
				if (xkeys && ykeys && zkeys) 
				{
					NWArray<float> times = rotData->GetKnots();
					NWArray<Point3> points = rotData->GetPoint3Data();
					if (times.size() == 0 && points.size() != 0)
						times = defaultKeys;
					
					xkeys->SetNumKeys(times.size());
					ykeys->SetNumKeys(times.size());
					zkeys->SetNumKeys(times.size());
					for (int i=0; i<times.size(); ++i)
					{
						Point3 &p = points[i];
						//Quat q; Point3 p;
						//EulerToQuat(points[i], q);
						//q = invQ * q;
						//QuatToEuler(q, p);

						IBezFloatKey rKey;
						memset(&rKey, 0, sizeof(rKey));
						rKey.time = TimeToFrame(times[i] + time);
						SetInTanType(rKey.flags, BEZKEY_SLOW);
						SetOutTanType(rKey.flags, BEZKEY_SLOW);
						rKey.val = p.x;
						xkeys->SetKey(i, &rKey);
						rKey.val = p.y;
						ykeys->SetKey(i, &rKey);
						rKey.val = p.z;
						zkeys->SetKey(i, &rKey);
					}
					xkeys->SortKeys();
					ykeys->SortKeys();
					zkeys->SortKeys();
				}
			}
		}
	}
}
示例#6
0
void GR2ImportImpl::ImportPosition(Control* c, TransformTrack& track, float time, GR2Array<granny_real32>& defaultKeys)
{
	// Better use linear for now
	if (Control *subCtrl = MakePositionXYZ(c, Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0))) 
	{
		IKeyControl *xkeys = GetKeyControlInterface(subCtrl->GetXController());
		IKeyControl *ykeys = GetKeyControlInterface(subCtrl->GetYController());
		IKeyControl *zkeys = GetKeyControlInterface(subCtrl->GetZController());
		if (xkeys && ykeys && zkeys) 
		{
			if (Point3CurveData* posData = dynamic_cast<Point3CurveData*>(track.PositionCurve.ToPointer()))
			{
				NWArray<float> times = posData->GetKnots();
				NWArray<Point3> points = posData->GetPoint3Data();
				if (times.size() == 0 && points.size() != 0)
					times = defaultKeys;

				xkeys->SetNumKeys(times.size());
				ykeys->SetNumKeys(times.size());
				zkeys->SetNumKeys(times.size());
				for (int i=0; i<times.size(); ++i)
				{
					IBezFloatKey rKey;
					memset(&rKey, 0, sizeof(rKey));
					rKey.time = TimeToFrame(times[i] + time);
					SetInTanType(rKey.flags, BEZKEY_SLOW);
					SetOutTanType(rKey.flags, BEZKEY_SLOW);
					rKey.val = points[i].x;
					xkeys->SetKey(i, &rKey);
					rKey.val = points[i].y;
					ykeys->SetKey(i, &rKey);
					rKey.val = points[i].z;
					zkeys->SetKey(i, &rKey);
				}
				xkeys->SortKeys();
				ykeys->SortKeys();
				zkeys->SortKeys();
			}
		}
	}
}
示例#7
0
void AsciiExp::DumpScaleKeys(Control* cont, int indentLevel) 
{
	if (!cont)
		return;
	
	int i;
	TSTR indent = GetIndent(indentLevel);
	IKeyControl *ikc = GetKeyControlInterface(cont);
	
	if (ikc && cont->ClassID() == Class_ID(TCBINTERP_SCALE_CLASS_ID, 0))
	{
		int numKeys = ikc->GetNumKeys();
		if (numKeys != 0) {
			_ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_SCALE_TCB); 
			for (i=0; i<numKeys; i++) {
				ITCBScaleKey key;
				ikc->GetKey(i, &key);
				_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s"),
					indent.data(),
					ID_TCB_SCALE_KEY,
					key.time,
					Format(key.val));
				_ftprintf(pStream, _T("\t%s\t%s\t%s\t%s\t%s\n"), Format(key.tens), Format(key.cont), Format(key.bias), Format(key.easeIn), Format(key.easeOut));
			}
			_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
		}
	}
	else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_SCALE_CLASS_ID, 0)) {
		int numKeys = ikc->GetNumKeys();
		if (numKeys != 0) {
			_ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_SCALE_BEZIER); 
			for (i=0; i<numKeys; i++) {
				IBezScaleKey key;
				ikc->GetKey(i, &key);
				_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s"),
					indent.data(),
					ID_BEZIER_SCALE_KEY,
					key.time,
					Format(key.val));
				_ftprintf(pStream, _T("\t%s\t%s\t%d\n"), Format(key.intan), Format(key.outtan), key.flags);
			}
			_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
		}
	}
	else if (ikc && cont->ClassID() == Class_ID(LININTERP_SCALE_CLASS_ID, 0)) {
		int numKeys = ikc->GetNumKeys();
		if (numKeys != 0) {
			_ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_SCALE_LINEAR); 
			for (i=0; i<numKeys; i++) {
				ILinScaleKey key;
				ikc->GetKey(i, &key);
				_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s\n"),
					indent.data(),
					ID_SCALE_KEY,
					key.time,
					Format(key.val));
			}
			_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
		}
	}
}
示例#8
0
void AsciiExp::DumpRotKeys(Control* cont, int indentLevel) 
{
	if (!cont)
		return;
	
	int i;
	TSTR indent = GetIndent(indentLevel);
	IKeyControl *ikc = GetKeyControlInterface(cont);
	
	if (ikc && cont->ClassID() == Class_ID(TCBINTERP_ROTATION_CLASS_ID, 0)) {
		int numKeys = ikc->GetNumKeys();
		if (numKeys != 0) {
			_ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_ROT_TCB); 
			for (i=0; i<numKeys; i++) {
				ITCBRotKey key;
				ikc->GetKey(i, &key);
				_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s"), 
					indent.data(),
					ID_TCB_ROT_KEY,
					key.time,
					Format(key.val));
				_ftprintf(pStream, _T("\t%s\t%s\t%s\t%s\t%s\n"), Format(key.tens), Format(key.cont), Format(key.bias), Format(key.easeIn), Format(key.easeOut));
			}
			_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
		}
	}
	else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID, 0))
	{
		int numKeys = ikc->GetNumKeys();
		if (numKeys != 0) {
			_ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_ROT_BEZIER); 
			for (i=0; i<numKeys; i++) {
				IBezQuatKey key;
				ikc->GetKey(i, &key);
				_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s\n"), 
					indent.data(),
					 // Quaternions are converted to AngAxis when written to file
					ID_ROT_KEY,
					key.time,
					Format(key.val));
				// There is no intan/outtan for Quat Rotations
			}
			_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
		}
	}
	else if (ikc && cont->ClassID() == Class_ID(LININTERP_ROTATION_CLASS_ID, 0)) {
		int numKeys = ikc->GetNumKeys();
		if (numKeys != 0) {
			_ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_ROT_LINEAR); 
			for (i=0; i<numKeys; i++) {
				ILinRotKey key;
				ikc->GetKey(i, &key);
				_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s\n"),
					indent.data(), 
					 // Quaternions are converted to AngAxis when written to file
					ID_ROT_KEY,
					key.time,
					Format(key.val));
			}
			_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
		}
	}
}
示例#9
0
// Output float keys if this is a known float controller that
// supports key operations. Otherwise we will sample the controller 
// once for each frame to get the value.
void AsciiExp::DumpFloatKeys(Control* cont, int indentLevel) 
{
	if (!cont)
		return;
	
	int i;
	TSTR indent = GetIndent(indentLevel);
	IKeyControl *ikc = NULL;

	// If the user wants us to always sample, we will ignore the KeyControlInterface
	if (!GetAlwaysSample())
		ikc = GetKeyControlInterface(cont);
	
	// TCB float
	if (ikc && cont->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID, 0)) {
		_ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_FLOAT_TCB); 
		for (i=0; i<ikc->GetNumKeys(); i++) {
			ITCBFloatKey key;
			ikc->GetKey(i, &key);
			_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s"),
				indent.data(),
				ID_TCB_FLOAT_KEY,
				key.time,
				Format(key.val));
			_ftprintf(pStream, _T("\t%s\t%s\t%s\t%s\t%s\n"), Format(key.tens), Format(key.cont), Format(key.bias), Format(key.easeIn), Format(key.easeOut));
		}
		_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
	}
	// Bezier float
	else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID, 0)) {
		_ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_FLOAT_BEZIER); 
		for (i=0; i<ikc->GetNumKeys(); i++) {
			IBezFloatKey key;
			ikc->GetKey(i, &key);
			_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s"),
				indent.data(),
				ID_BEZIER_FLOAT_KEY,
				key.time, 
				Format(key.val));
			_ftprintf(pStream, _T("\t%s\t%s\t%d\n"), Format(key.intan), Format(key.outtan), key.flags);
		}
		_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
	}
	else if (ikc && cont->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID, 0)) {
		_ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_FLOAT_LINEAR); 
		for (i=0; i<ikc->GetNumKeys(); i++) {
			ILinFloatKey key;
			ikc->GetKey(i, &key);
			_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s\n"),
				indent.data(),
				ID_FLOAT_KEY,
				key.time,
				Format(key.val));
		}
		_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
	}
	else {
		
		// Unknown controller, no key interface or sample on demand -
		// This might be a procedural controller or something else we
		// don't know about. The last resort is to get the value from the 
		// controller at every n frames.
		
		TSTR name;
		cont->GetClassName(name);
		TSTR className = FixupName(name);
		Interface14 *iface = GetCOREInterface14();
		UINT codepage  = iface-> DefaultTextSaveCodePage(true);
		const char* className_locale = className.ToCP(codepage);
		_ftprintf(pStream, _T("%s\t\t%s \"%hs\" {\n"), indent.data(), ID_CONTROL_FLOAT_SAMPLE,
			className_locale);
		
		// If it is animated at all...
		if (cont->IsAnimated()) {
			// Get the range of the controller animation 
			Interval range; 
			// Get range of full animation
			Interval animRange = ip->GetAnimRange(); 
			TimeValue t = cont->GetTimeRange(TIMERANGE_ALL).Start();
			float value;
			
			// While we are inside the animation... 
			while (animRange.InInterval(t)) {
				// Sample the controller
				range = FOREVER;
				cont->GetValue(t, &value, range);
				
				// Set time to start of controller validity interval 
				t = range.Start();
				
				// Output the sample
				_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s\n"),
					indent.data(),
					ID_FLOAT_KEY,
					t,
					Format(value));
				
				// If the end of the controller validity is beyond the 
				// range of the animation
				if (range.End() > cont->GetTimeRange(TIMERANGE_ALL).End()) {
					break;
				}
				else {
					t = (range.End()/GetTicksPerFrame()+GetKeyFrameStep()) * GetTicksPerFrame();
				}
			}
		}
		_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
	}
}
示例#10
0
void XsiExp::DumpScaleKeys( INode * node, int indentLevel) 
{
  Control * cont = node->GetTMController()->GetScaleController();
	IKeyControl * ikc = GetKeyControlInterface(cont);
	INode * parent = node->GetParentNode();
	if (!cont || !parent || (parent && parent->IsRootNode()) || !ikc)
  {
    // no controller or root node
		return;
  }
	int numKeys = ikc->GetNumKeys();
	if (numKeys <= 1)
  {  
    return;
  }
	Object * obj = node->EvalWorldState(0).obj;
  BOOL isBone = obj && obj->ClassID() == Class_ID(BONE_CLASS_ID, 0) ? TRUE : FALSE;

  // anim keys header
  TSTR indent = GetIndent(indentLevel);
	fprintf(pStream,"%s\tSI_AnimationKey {\n", indent.data()); 
	fprintf(pStream,"%s\t\t1;\n", indent.data());     // 1 means scale keys
	fprintf(pStream,"%s\t\t%d;\n", indent.data(), numKeys);

	int t, delta = GetTicksPerFrame();
 	Matrix3 matrix;
  AffineParts ap;
	for (int i = 0; i < numKeys; i++)
  {  
    // get the key's time
	  if (cont->ClassID() == Class_ID(TCBINTERP_SCALE_CLASS_ID, 0))
    {
  	  ITCBRotKey key;
			ikc->GetKey(i, &key);
      t = key.time;
    }
    else if (cont->ClassID() == Class_ID(HYBRIDINTERP_SCALE_CLASS_ID, 0))
	  {
		  IBezQuatKey key;
		  ikc->GetKey(i, &key);
      t = key.time;
    }
	  else if (cont->ClassID() == Class_ID(LININTERP_SCALE_CLASS_ID, 0))
    {
  	  ILinRotKey key;
		  ikc->GetKey(i, &key);
      t = key.time;
    }
    // sample the node's matrix
    matrix = node->GetNodeTM(t) * Inverse(node->GetParentTM(t));
    if (!isBone)
    {
      matrix = matrix * topMatrix;
    }
    decomp_affine(matrix, &ap);

		fprintf(pStream, "%s\t\t%d; 3; %.6f, %.6f, %.6f;;%s\n", 
			indent.data(),
			t / delta,
			ap.k.x, ap.k.z, ap.k.y,
      i == numKeys - 1 ? ";\n" : ",");
	}
  // anim keys close
	fprintf(pStream,"%s\t}\n\n", indent.data());
}
void KeyTest() 
{
	int i, numKeys;
	INode *         n;
	Control *       c;
	Quat            newQuat, prevQuat;
	IKeyControl*    ikeys;
	ITCBPoint3Key   tcbPosKey;
	ITCBRotKey      tcbRotKey;
	ITCBScaleKey    tcbScaleKey;
	IBezPoint3Key   bezPosKey;
	IBezQuatKey     bezRotKey;
	IBezScaleKey    bezScaleKey;
	ILinPoint3Key   linPosKey;
	ILinRotKey      linRotKey;
	ILinScaleKey    linScaleKey;

	// Get the first node in the selection set
	if (!CMaxEnv::singleton().m_pInterace->GetSelNodeCount()) 
		return;
	n = CMaxEnv::singleton().m_pInterace->GetSelNode(0); 

	// --- Process the position keys ---
	c = n->GetTMController()->GetPositionController();
	ikeys = GetKeyControlInterface(c);

	if (!ikeys) 
	{
		// No interface available to access the keys...
		// Just sample the controller to get the position
		// data at each key...
		SampleController(n, c);
		return; 
	}

	numKeys = ikeys->GetNumKeys();
	DebugPrint(_T("\nThere are %d position key(s)"), numKeys);
	if (c->ClassID() == Class_ID(TCBINTERP_POSITION_CLASS_ID, 0)) 
	{
		for (i = 0; i < numKeys; i++) 
		{
			ikeys->GetKey(i, &tcbPosKey);
			//DebugPrint(_T("\nTCB Position Key: %d=(%.1f, %.1f, %.1f)"), 
			//	i, tcbPosKey.val.x, tcbPosKey.val.y, tcbPosKey.val.z);
		}
	}
	else if (c->ClassID() == Class_ID(HYBRIDINTERP_POSITION_CLASS_ID, 0)) 
	{
		for (i = 0; i < numKeys; i++) 
		{
			ikeys->GetKey(i, &bezPosKey);
			//DebugPrint(_T("\nBezier Position Key: %d=(%.1f, %.1f, %.1f)"), 
			//	i, bezPosKey.val.x, bezPosKey.val.y, bezPosKey.val.z);

		}
	}
	else if (c->ClassID() == Class_ID(LININTERP_POSITION_CLASS_ID, 0)) 
	{
		for (i = 0; i < numKeys; i++) 
		{
			ikeys->GetKey(i, &linPosKey);
			//DebugPrint(_T("\nLinear Position Key: %d=(%.1f, %.1f, %.1f)"), 
			//	i, linPosKey.val.x, linPosKey.val.y, linPosKey.val.z);
		}
	}
	// --- Process the rotation keys ---

	c = n->GetTMController()->GetRotationController();
	ikeys = GetKeyControlInterface(c);
	if (!ikeys) return;
	numKeys = ikeys->GetNumKeys();
	//DebugPrint(_T("\nThere are %d rotation key(s)"), numKeys);
	if (c->ClassID() == Class_ID(TCBINTERP_ROTATION_CLASS_ID, 0)) 
	{
		for (i = 0; i < numKeys; i++) 
		{
			ikeys->GetKey(i, &tcbRotKey);
			newQuat = QFromAngAxis(tcbRotKey.val.angle, tcbRotKey.val.axis);
			if (i) newQuat = prevQuat * newQuat;
			prevQuat = newQuat;
			//DebugPrint(_T("\nTCB Rotation Key: %d=(%.1f, %.1f, %.1f, %.1f)"), 
			//	i, newQuat.x, newQuat.y, newQuat.z, newQuat.w);
		}
	}
	else if (c->ClassID() == Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID, 0)) 
	{
		for (i = 0; i < numKeys; i++) 
		{
			ikeys->GetKey(i, &bezRotKey);
			newQuat = bezRotKey.val;
			if (i) 
				newQuat = prevQuat * newQuat;

			prevQuat = newQuat;
			//DebugPrint(_T("\nBezier Rotation Key: %d=(%.1f, %.1f, %.1f, %.1f)"), 
			//	i, newQuat.x, newQuat.y, newQuat.z, newQuat.w);
		}
	}
	else if (c->ClassID() == Class_ID(LININTERP_ROTATION_CLASS_ID, 0)) 
	{
		for (i = 0; i < numKeys; i++) 
		{
			ikeys->GetKey(i, &linRotKey);
			newQuat = linRotKey.val;
			if (i) 
				newQuat = prevQuat * newQuat;

			prevQuat = newQuat;
			//DebugPrint(_T("\nLinear Rotation Key: %d=(%.1f, %.1f, %.1f, %.1f)"), 
			//	i, newQuat.x, newQuat.y, newQuat.z, newQuat.w);
		}
	}

	// --- Process the scale keys ---
	c = n->GetTMController()->GetScaleController();
	ikeys = GetKeyControlInterface(c);

	if (!ikeys) return;

	numKeys = ikeys->GetNumKeys();
	
	//DebugPrint(_T("\nThere are %d scale key(s)"), numKeys);



	if (c->ClassID() == Class_ID(TCBINTERP_SCALE_CLASS_ID, 0)) 
	{

		for (i = 0; i < numKeys; i++) 
		{
			ikeys->GetKey(i, &tcbScaleKey);
			//DebugPrint(_T("\nTCB Scale Key: %2d=(%.1f, %.1f, %.1f)"), 
			//	i, tcbScaleKey.val.s.x, tcbScaleKey.val.s.y, 
			//	tcbScaleKey.val.s.z);
		}
	}
	else if (c->ClassID() == Class_ID(HYBRIDINTERP_SCALE_CLASS_ID, 0)) 
	{
		for (i = 0; i < numKeys; i++) 
		{
			ikeys->GetKey(i, &bezScaleKey);
			//DebugPrint(_T("\nBezier Scale Key: %2d=(%.1f, %.1f, %.1f)"), 
			//	i, bezScaleKey.val.s.x, bezScaleKey.val.s.y, 
			//	bezScaleKey.val.s.z);
		}
	}
	else if (c->ClassID() == Class_ID(LININTERP_SCALE_CLASS_ID, 0)) 
	{
		for (i = 0; i < numKeys; i++) 
		{
			ikeys->GetKey(i, &linScaleKey);
			DebugPrint(_T("\nLinear Scale Key: %2d=(%.1f, %.1f, %.1f)"), 
				i, linScaleKey.val.s.x, linScaleKey.val.s.y, 
				linScaleKey.val.s.z);
		}
	}
}
示例#12
0
//BOOL TbsAnimObj::IsKnownController(Control* cont)
//{
//	ulong partA, partB;
//
//	if (!cont)
//		return FALSE;
//
////Listed below are the first ULONG of the 8 byte ID. 
////The second ULONG is 0 for all built-in classes (unless noted otherwise). 
////For example a Class_ID for a TriObject would read:
////Class_ID(TRIOBJ_CLASS_ID, 0);
////Note that only built-in classes should have the second ULONG equal to 0.
////All plug-in developers should use both ULONGs.
//
//
//	// ClassID는 두개의 ULONG변수로 구성되며 내장된 클래스들은 모두 두번째 
//	// 변수는 0의 값을 갖고 있다. 
//	// 단, 개발자의 플로그인은 두번째 값을 갖게 된다.
//	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;
//}
void TbsAnimObj::DumpFloatKeys(Control* cont, TMesh* pMesh) 
{
	if (!cont)		return;	
	int i;	
	IKeyControl *ikc = NULL;	
	ikc = GetKeyControlInterface(cont);
	
	TAnimTrack Anim;

	// TCB float
	if (ikc && cont->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID, 0)) 
	{		
		for (i=0; i<ikc->GetNumKeys(); i++) 
		{
			ITCBFloatKey key;
			ikc->GetKey(i, &key);	
			Anim.iTick = key.time;
			Anim.vValue.x = key.val;
			pMesh->m_VisTrack.push_back( Anim );
		}		
	}
	// Bezier float
	else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID, 0)) {		
		for (i=0; i<ikc->GetNumKeys(); i++) {
			IBezFloatKey key;
			ikc->GetKey(i, &key);	
			Anim.iTick = key.time;
			Anim.vValue.x = key.val;
			pMesh->m_VisTrack.push_back( Anim );
			
		}		
	}
	else if (ikc && cont->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID, 0)) {		
		for (i=0; i<ikc->GetNumKeys(); i++) 
		{
			ILinFloatKey key;
			ikc->GetKey(i, &key);		
			Anim.iTick = key.time;
			Anim.vValue.x = key.val;
			pMesh->m_VisTrack.push_back( Anim );
		}		
	}
	else 
	{
		TSTR name;
		cont->GetClassName(name);
		
		// If it is animated at all...
		if (cont->IsAnimated()) {
			// Get the range of the controller animation 
			Interval range; 
			// Get range of full animation
			Interval animRange = m_p3dsMax->GetAnimRange(); 
			TimeValue t = cont->GetTimeRange(TIMERANGE_ALL).Start();
			float value;
			
			// While we are inside the animation... 
			while (animRange.InInterval(t)) 
			{
				// Sample the controller
				range = FOREVER;
				cont->GetValue(t, &value, range);
				
				// Set time to start of controller validity interval 
				t = range.Start();
				
				Anim.iTick = t;
				Anim.vValue.x = value;
				pMesh->m_VisTrack.push_back( Anim );
						
				if (range.End() > cont->GetTimeRange(TIMERANGE_ALL).End()) 
				{
					break;
				}
				else 
				{
					//t = (range.End()/GetTicksPerFrame()+GetKeyFrameStep()) * GetTicksPerFrame();
					t = (range.End()/GetTicksPerFrame()) * GetTicksPerFrame();
				}
			}
		}		
	}
}
示例#13
0
// 2. 加载骨骼数据
void M2Importer::importBoneObject()
{
	// Bone Group Header Node
	INode* groupHeadNode = createGroupHeaderNode();
	groupHeadNode->SetGroupHead(TRUE);
	groupHeadNode->SetGroupMember(FALSE);

	if (m_modelHeader->nameLength > 1)
	{
		TCHAR* modelName = (TCHAR*)(m_m2FileData + m_modelHeader->nameOfs);
		TCHAR boneGroupName[256];
		sprintf(boneGroupName, "%s_bone", modelName);
		groupHeadNode->SetName(boneGroupName);
	}
	else
		groupHeadNode->SetName("BoneGroup");


	// Bone
	// 一个Bone构造一个Node, 并且加入到组中

	ModelBoneDef* boneData = (ModelBoneDef*)(m_m2FileData + m_modelHeader->ofsBones);

	m_boneNodeList.reserve(m_modelHeader->nBones);
	for (unsigned int i = 0; i < m_modelHeader->nBones; ++i)
	{
		ModelBoneDef& boneDef = boneData[i];

		// create bone node
		HelperObject* obj = (HelperObject*)CreateInstance(HELPER_CLASS_ID, Class_ID(BONE_CLASS_ID, 0));

		ImpNode* node = m_impInterface->CreateNode();

		TCHAR boneName[256];
		sprintf(boneName, "bone_%02d", i);
		node->SetName(boneName);

		node->SetPivot(*(Point3*)&(boneDef.pivot));
		node->Reference(obj);

		m_impInterface->AddNodeToScene(node);

		// 设置变换矩阵
		Matrix3 tm;
		tm.IdentityMatrix();
		tm.SetTrans(*(Point3*)&(boneDef.pivot));
		node->SetTransform(0, tm);

		// 添加到组
		INode* realINode = node->GetINode();
		realINode->SetGroupHead(FALSE);
		realINode->SetGroupMember(TRUE);
		groupHeadNode->AttachChild(realINode);

		// 设置Bone父子关系
		realINode->ShowBone(2);
		m_boneNodeList.push_back(realINode);
		if (boneDef.parent != -1)
		{
			INode* parentNode = m_boneNodeList[boneDef.parent];
			parentNode->AttachChild(realINode);
		}

		realINode->EvalWorldState(0);
	}

	// 导入每根骨骼的关键桢数据
	for (unsigned int i = 0; i < m_modelHeader->nBones; ++i)
	{
		ModelBoneDef& boneDef = boneData[i];
		INode* realINode = m_boneNodeList[i];

		Control* tmControl = realINode->GetTMController();

		// Position
		if (boneDef.translation.nKeys)
		{
			// 设置动画控制器为线性控制器
			Control* posControl = createPositionController();
			tmControl->SetPositionController(posControl);

			unsigned int* timeData = (unsigned int*)(m_m2FileData + boneDef.translation.ofsTimes);
			Point3* keyData = (Point3*)(m_m2FileData + boneDef.translation.ofsKeys);

			// 设置动画时间范围
			bool animRangeChanged = false;
			Interval animRange = m_maxInterface->GetAnimRange();
			for (unsigned int j = 0; j < boneDef.translation.nKeys; ++j)
			{
				if (timeData[j] < animRange.Start())
				{
					animRange.SetStart(timeData[j]);
					animRangeChanged = true;
				}
				else if (timeData[j] > animRange.End())
				{
					animRange.SetEnd(timeData[j]);
					animRangeChanged = true;
				}
			}
			if (animRangeChanged)
				m_maxInterface->SetAnimRange(animRange);

			// 设置动画关键桢数据
			Control* xControl = posControl->GetXController();
			IKeyControl* xKeyControl = GetKeyControlInterface(xControl);
			xKeyControl->SetNumKeys(boneDef.translation.nKeys);

			Control* yControl = posControl->GetYController();
			IKeyControl* yKeyControl = GetKeyControlInterface(yControl);
			yKeyControl->SetNumKeys(boneDef.translation.nKeys);

			Control* zControl = posControl->GetZController();
			IKeyControl* zKeyControl = GetKeyControlInterface(zControl);
			zKeyControl->SetNumKeys(boneDef.translation.nKeys);

			for (unsigned int j = 0; j < boneDef.translation.nKeys; ++j)
			{
				// X
				AnyKey bufX;
				ILinFloatKey* keyX = reinterpret_cast<ILinFloatKey*>((IKey*)bufX);
				keyX->time = timeData[j];
				keyX->val = keyData[j].x;
				xKeyControl->AppendKey(keyX);

				// Y
				AnyKey bufY;
				ILinFloatKey* keyY = reinterpret_cast<ILinFloatKey*>((IKey*)bufY);
				keyY->time = timeData[j];
				keyY->val = keyData[j].y;
				yKeyControl->AppendKey(keyY);

				// Z
				AnyKey bufZ;
				ILinFloatKey* keyZ = reinterpret_cast<ILinFloatKey*>((IKey*)bufZ);
				keyZ->time = timeData[j];
				keyZ->val = keyData[j].z;
				zKeyControl->AppendKey(keyZ);
			}
		}
/*
		// Rotation
		if (boneDef.rotation.nKeys)
		{
			Control* rotControl = createRotationController();
			tmControl->SetRotationController(rotControl);

			unsigned int* timeData = (unsigned int*)(m_m2FileData + boneDef.rotation.ofsTimes);
			Quat* keyData = (Quat*)(m_m2FileData + boneDef.rotation.ofsKeys);

			// 设置动画时间范围
			bool animRangeChanged = false;
			Interval animRange = m_maxInterface->GetAnimRange();
			for (unsigned int j = 0; j < boneDef.rotation.nKeys; ++j)
			{
				if (timeData[j] < animRange.Start())
				{
					animRange.SetStart(timeData[j]);
					animRangeChanged = true;
				}
				else if (timeData[j] > animRange.End())
				{
					animRange.SetEnd(timeData[j]);
					animRangeChanged = true;
				}
			}
			if (animRangeChanged)
				m_maxInterface->SetAnimRange(animRange);

			// 设置动画关键桢数据
			IKeyControl* keyControl = GetKeyControlInterface(rotControl);
			keyControl->SetNumKeys(boneDef.rotation.nKeys);

			for (unsigned int j = 0; j < boneDef.rotation.nKeys; ++j)
			{
				AnyKey buf;
				ILinRotKey* key = reinterpret_cast<ILinRotKey*>((IKey*)buf);
				key->time = timeData[j];
				key->val = keyData[j];
				keyControl->AppendKey(key);
			}
		}
*/
		// Scaling
		if (boneDef.scaling.nKeys)
		{
			Control* scaControl = createScaleController();
			tmControl->SetScaleController(scaControl);

			unsigned int* timeData = (unsigned int*)(m_m2FileData + boneDef.scaling.ofsTimes);
			Point3* keyData = (Point3*)(m_m2FileData + boneDef.scaling.ofsKeys);

			// 设置动画时间范围
			bool animRangeChanged = false;
			Interval animRange = m_maxInterface->GetAnimRange();
			for (unsigned int j = 0; j < boneDef.scaling.nKeys; ++j)
			{
				if (timeData[j] < animRange.Start())
				{
					animRange.SetStart(timeData[j]);
					animRangeChanged = true;
				}
				else if (timeData[j] > animRange.End())
				{
					animRange.SetEnd(timeData[j]);
					animRangeChanged = true;
				}
			}
			if (animRangeChanged)
				m_maxInterface->SetAnimRange(animRange);

			// 设置动画关键桢数据
			IKeyControl* keyControl = GetKeyControlInterface(scaControl);
			keyControl->SetNumKeys(boneDef.scaling.nKeys);

			for (unsigned int j = 0; j < boneDef.scaling.nKeys; ++j)
			{
				AnyKey buf;
				ILinScaleKey* key = reinterpret_cast<ILinScaleKey*>((IKey*)buf);
				key->time = timeData[j];
				key->val = ScaleValue(keyData[j]);
				keyControl->AppendKey(key);
			}
		}
	}
}
示例#14
0
void bgAnimMax::DumpFloatKeys(Control* pControl, bgMesh* pMesh)
{
	if (!pControl)
		return;

	int i;
	bgAnimTrack Anim;
	IKeyControl *ikc = NULL;

	ikc = GetKeyControlInterface(pControl);
	if (ikc && pControl->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID, 0))
	{
		for (i = 0; i < ikc->GetNumKeys(); i++)
		{
			ITCBFloatKey key;
			ikc->GetKey(i, &key);
			Anim.iTick = key.time;
			Anim.vValue.x = key.val;
			pMesh->AlpTrack.push_back(Anim);
		}
	}
	else if (ikc && pControl->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID, 0))
	{
		for (i = 0; i < ikc->GetNumKeys(); i++)
		{
			IBezFloatKey key;
			ikc->GetKey(i, &key);
			Anim.iTick = key.time;
			Anim.vValue.x = key.val;
			pMesh->AlpTrack.push_back(Anim);
		}
	}
	else if (ikc && pControl->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID, 0))
	{
		for (i = 0; i < ikc->GetNumKeys(); i++)
		{
			ILinFloatKey key;
			ikc->GetKey(i, &key);
			Anim.iTick = key.time;
			Anim.vValue.x = key.val;
			pMesh->AlpTrack.push_back(Anim);
		}
	}
	else
	{
		TSTR name;
		pControl->GetClassName(name);

		if (pControl->IsAnimated())
		{
			float value;
			Interval range;
			Interval animRange = m_p3DMax->GetAnimRange();
			TimeValue t = pControl->GetTimeRange(TIMERANGE_ALL).Start();

			while (animRange.InInterval(t))
			{
				range = FOREVER;
				pControl->GetValue(t, &value, range);

				t = range.Start();

				Anim.iTick = t;
				Anim.vValue.x = value;
				pMesh->AlpTrack.push_back(Anim);

				if (range.End() > pControl->GetTimeRange(TIMERANGE_ALL).End())
				{
					break;
				}
				else
				{
					t = (range.End() / GetTicksPerFrame()) * GetTicksPerFrame();
				}
			}
		}
	}
}
示例#15
0
void RandKeysUtil::Apply()
	{
	BOOL timeMode   = iu->GetMajorMode()==TVMODE_EDITTIME;
	BOOL fcurveMode = iu->GetMajorMode()==TVMODE_EDITFCURVE;
	Interval iv = iu->GetTimeSelection();
	if (!doTime && !doVal) return;

	theHold.Begin();

	// Turn animation on
	SuspendAnimate();
	AnimateOn();

	for (int i=0; i<iu->GetNumTracks(); i++) {
		if ((timeMode||fcurveMode) && !iu->IsSelected(i)) continue;
		
		// Get Interfaces
		Animatable *anim   = iu->GetAnim(i);
		Animatable *client = iu->GetClient(i);
		int subNum         = iu->GetSubNum(i);
		Control *cont      = GetControlInterface(anim);
		IKeyControl *ikc   = GetKeyControlInterface(anim);
		IKey *key          = GetKeyPointer(anim->SuperClassID(),anim->ClassID());				
		if (!ikc || !cont || !key) continue;						
		if (fcurveMode && !anim->IsCurveSelected()) continue;

		// Get the param dim
		float min = negVal, max = posVal;
		ParamDimension *dim = client->GetParamDimension(subNum);
		if (dim) {
			min = dim->UnConvert(min);
			max = dim->UnConvert(max);
			}

		for (int j=0; j<ikc->GetNumKeys(); j++) {
			// Get the key data
			ikc->GetKey(j,key);
			
			// Check if it's selected
			if (timeMode && !iv.InInterval(key->time)) continue;
			if (!timeMode && !(key->flags&IKEY_SELECTED)) continue;			

			// Randomize time
			if (doTime) {
				key->time = (int)CompRand(
					float(key->time-negTime),
					float(key->time+posTime));
				ikc->SetKey(j,key);
				}
			}

		if (doTime) ikc->SortKeys();

		for (j=0; j<ikc->GetNumKeys(); j++) {
			// Get the key data
			ikc->GetKey(j,key);
			
			// Check if it's selected
			if (timeMode && !iv.InInterval(key->time)) continue;
			if (!timeMode && !(key->flags&IKEY_SELECTED)) continue;			

			// Randomize value
			if (doVal) {
				Point3 pt, ang;
				Point4 p4;
				float f;
				Quat q;
				ScaleValue s;				
				BOOL doX, doY, doZ, doW;
				doX = doY = doZ = doW = TRUE;
				if (!fcurveMode) {
					if (!(key->flags&IKEY_XSEL)) doX = FALSE;
					if (!(key->flags&IKEY_YSEL)) doY = FALSE;
					if (!(key->flags&IKEY_ZSEL)) doZ = FALSE;
					if (!(key->flags&IKEY_WSEL)) doW = FALSE;
					}

				switch (anim->SuperClassID()) {
					case CTRL_FLOAT_CLASS_ID:			
						cont->GetValue(key->time,&f,FOREVER);
						f = CompRand(f-min,f+max);
						cont->SetValue(key->time,&f);
						break;

					case CTRL_POSITION_CLASS_ID:
					case CTRL_POINT3_CLASS_ID:
						cont->GetValue(key->time,&pt,FOREVER);
						if (doX) pt.x = CompRand(pt.x-min,pt.x+max);
						if (doY) pt.y = CompRand(pt.y-min,pt.y+max);
						if (doZ) pt.z = CompRand(pt.z-min,pt.z+max);
						cont->SetValue(key->time,&pt);
						break;
					
					case CTRL_POINT4_CLASS_ID:
						cont->GetValue(key->time,&p4,FOREVER);
						if (doX) p4.x = CompRand(p4.x-min,p4.x+max);
						if (doY) p4.y = CompRand(p4.y-min,p4.y+max);
						if (doZ) p4.z = CompRand(p4.z-min,p4.z+max);
						if (doW) p4.w = CompRand(p4.w-min,p4.w+max);
						cont->SetValue(key->time,&p4);
						break;

					case CTRL_ROTATION_CLASS_ID:
						cont->GetValue(key->time,&q,FOREVER);
						QuatToEuler(q, ang);
						ang.x = CompRand(ang.x-min,ang.x+max);
						ang.y = CompRand(ang.y-min,ang.y+max);
						ang.z = CompRand(ang.z-min,ang.z+max);
						EulerToQuat(ang,q);
						cont->SetValue(key->time,&q);
						break;

					case CTRL_SCALE_CLASS_ID:
						cont->GetValue(key->time,&s,FOREVER);
						if (doX) s.s.x = CompRand(s.s.x-min,s.s.x+max);
						if (doY) s.s.y = CompRand(s.s.y-min,s.s.y+max);
						if (doZ) s.s.z = CompRand(s.s.z-min,s.s.z+max);
						cont->SetValue(key->time,&s);
						break;
					}
				}
			}

		
		}

	ResumeAnimate();

	theHold.Accept(GetString(IDS_RB_RANDOMIZEKEYS));
	ip->RedrawViews(ip->GetTime());
	}