예제 #1
0
void RemovePivotScale(INode* node)
{
	const TimeValue  t  = ccMaxWorld::MaxTime();
	Matrix3 nodeTM = node->GetNodeTM(t);

	Point3 pos = nodeTM.GetRow(3);
	Matrix3 objectTM = node->GetObjectTM(t);
	nodeTM = objectTM;
	nodeTM.SetRow(3, pos);
	Matrix3 pv = objectTM * Inverse(nodeTM);
	node->SetNodeTM(t, nodeTM);

	node->SetObjOffsetPos(pv.GetTrans()); 
	node->SetObjOffsetRot(IdentQuat()); 
	node->SetObjOffsetScale(ScaleValue(Point3(1,1,1))); 
}
예제 #2
0
void ResetXForm::ResetNodes(const INodeTab& nodesToReset)
{
	Interface *ip = GetCOREInterface();
	for (int i = 0; i < nodesToReset.Count(); i++) {
		INode *node = nodesToReset[i];
		if (!node || node->IsGroupMember() || node->IsGroupHead()) 
			continue;
		if (SelectedAncestor(node)) 
			continue;

		Matrix3 ntm, ptm, rtm(1), piv(1), tm;
		
		// Get Parent and Node TMs
		ntm = node->GetNodeTM(ip->GetTime());
		ptm = node->GetParentTM(ip->GetTime());
		
		// Compute the relative TM
		ntm = ntm * Inverse(ptm);
		
		// The reset TM only inherits position
		rtm.SetTrans(ntm.GetTrans());
		
		// Set the node TM to the reset TM		
		tm = rtm*ptm;
		node->SetNodeTM(ip->GetTime(), tm);

		// Compute the pivot TM
		piv.SetTrans(node->GetObjOffsetPos());
		PreRotateMatrix(piv,node->GetObjOffsetRot());
		ApplyScaling(piv,node->GetObjOffsetScale());
		
		// Reset the offset to 0
		node->SetObjOffsetPos(Point3(0,0,0));
		node->SetObjOffsetRot(IdentQuat());
		node->SetObjOffsetScale(ScaleValue(Point3(1,1,1)));

		// Take the position out of the matrix since we don't reset position
		ntm.NoTrans();

		// Apply the offset to the TM
		ntm = piv * ntm;

		// Apply a derived object to the node's object
		Object *obj = node->GetObjectRef();
		IDerivedObject *dobj = CreateDerivedObject(obj);
		
		// Create an XForm mod
		SimpleMod *mod = (SimpleMod*)ip->CreateInstance(
			OSM_CLASS_ID,
			Class_ID(CLUSTOSM_CLASS_ID,0));

		// Apply the transformation to the mod.
		SetXFormPacket pckt(ntm);
		mod->tmControl->SetValue(ip->GetTime(),&pckt);

		// Add the modifier to the derived object.
		dobj->SetAFlag(A_LOCK_TARGET); // RB 3/11/99: When the macro recorder is on the derived object will get deleted unless it is locked.
		dobj->AddModifier(mod);
		dobj->ClearAFlag(A_LOCK_TARGET);

		// Replace the node's object
		node->SetObjectRef(dobj);
	}
	
//	Why on earth were we clearing the undo stack?
//	GetSystemSetting(SYSSET_CLEAR_UNDO);
	ip->RedrawViews(ip->GetTime());
	SetSaveRequiredFlag(TRUE);
}
void OrientConstRotation::Update(TimeValue t){
	Interval iv = FOREVER;
	ivalid = FOREVER;
	
	int ct = pblock->Count(orientation_target_list);
	int ctf = pblock->Count(orientation_target_weight);

	float total_orient_target_weight_prev = 0.0f, total_orient_target_weight_current = 0.0f;
	float orient_targ_Wt_current = 0.0f;
	Quat quat_prev, quat_current, lCurRot;
	INode *orient_target_prev= NULL, *orient_target_current= NULL;
	Matrix3 targetTM(1);
	Point3 trans, scaleP;

	quat_prev.Identity();
	quat_current.Identity();
	lCurRot.Identity();

		if (ct == 1){
			pblock->GetValue(orientation_target_list, t, orient_target_prev, iv, 0);
			pblock->GetValue(orientation_target_weight, t, orient_targ_Wt_current, iv, 0);
				ivalid &= iv;

				if (orient_target_prev == NULL){
					targetTM.IdentityMatrix();
				}
				else {
					targetTM = orient_target_prev->GetNodeTM(t, &ivalid);
				}

				if (IsLocal() && orient_target_prev != NULL) {
					targetTM = targetTM * Inverse(orient_target_prev->GetParentTM(t));
				}
				AffineParts comps;		// Requires header decomp.h
				decomp_affine(targetTM, &comps);
				quat_current = comps.q;
				quat_current.Normalize();
				quat_current.MakeClosest(quat_prev);

				lCurRot = quat_current;

				quat_prev = lCurRot;
				total_orient_target_weight_prev += orient_targ_Wt_current;
//			}
		}
		else if (ct > 1){

			pblock->GetValue(orientation_target_list, t, orient_target_prev, iv, 0);
			pblock->GetValue(orientation_target_weight, t, orient_targ_Wt_current, iv, 0);
//			if (orient_target_prev != NULL)
//			{
				ivalid &= iv;

				if (orient_target_prev == NULL){
					targetTM.IdentityMatrix();
				}
				else {
					targetTM = orient_target_prev->GetNodeTM(t, &ivalid);
				}

				if (IsLocal() && orient_target_prev != NULL) {
					targetTM = targetTM * Inverse(orient_target_prev->GetParentTM(t));
				}
				AffineParts comps;		// Requires header decomp.h
				decomp_affine(targetTM, &comps);
				quat_current = comps.q;
				quat_current.Normalize();
				quat_current.MakeClosest(quat_prev);

				lCurRot = quat_current;

				quat_prev = lCurRot;
				total_orient_target_weight_prev += orient_targ_Wt_current;
//			}

			for (int i = 0; i < ct -1; i++) {
//				ct = pblock->Count(orientation_target_list);
				pblock->GetValue(orientation_target_list, t, orient_target_current, iv, i+1);
				pblock->GetValue(orientation_target_weight, t, orient_targ_Wt_current, iv, i+1);
//				if (orient_target_current != NULL){
					ivalid &= iv;

					if (orient_target_current == NULL){
						targetTM.IdentityMatrix();
					}
					else {
						targetTM = orient_target_current->GetNodeTM(t, &ivalid);
					}

//					Matrix3 targetTM = orient_target_current->GetNodeTM(t, &ivalid);
					if (IsLocal() && orient_target_current != NULL) {
						targetTM = targetTM * Inverse(orient_target_current->GetParentTM(t));
					}
					AffineParts comps;		// Requires header decomp.h
					decomp_affine(targetTM, &comps);
					quat_current = comps.q;
					quat_current.Normalize();
					quat_current.MakeClosest(quat_prev);

					float slerp_wt = 0.0f;
					if ((total_orient_target_weight_prev + orient_targ_Wt_current) != 0.0){
						slerp_wt = orient_targ_Wt_current / (total_orient_target_weight_prev + orient_targ_Wt_current);
					}

					lCurRot = Slerp(quat_prev, quat_current, slerp_wt);
					lCurRot.Normalize();

					quat_prev = lCurRot;
					total_orient_target_weight_prev += orient_targ_Wt_current;
//				}
			}			//for (int i = 0; i < ct -1; i++)
		}				//else if (ct > 1)

		if (oldTargetNumber != ct) {
			InitialOrientQuat = lCurRot;
		}

		curRot = lCurRot;
		if (total_orient_target_weight_prev > 0.0){
			if (Relative()){
				if(IsLocal()){
					curRot =   baseRotQuatLocal * (lCurRot /InitialOrientQuat);
				}
				else{
					curRot =   baseRotQuatWorld * (lCurRot /InitialOrientQuat);
				}
			}
		}
		else {
			curRot = baseRotQuatLocal;
		}
		curRot.MakeClosest(IdentQuat());
		curRot.Normalize();
		oldTargetNumber = ct;
//	if (ivalid.Empty()) ivalid.SetInstant(t);
}