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))); }
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); }