void ResetXForm::SelectionSetChanged(Interface *ip,IUtil *iu) { if (ip->GetSelNodeCount()) { BOOL res = FALSE; for (int i=0; i<ip->GetSelNodeCount(); i++) { INode *node = ip->GetSelNode(i); if (!node->IsGroupMember() && !node->IsGroupHead()) { res = TRUE; break; } } EnableWindow(GetDlgItem(hPanel,IDC_RESETTM_SELECTED),res); } else { EnableWindow(GetDlgItem(hPanel,IDC_RESETTM_SELECTED),FALSE); } }
NxActor* MxActor::createNxActor() { if (m_bulletBody) { MaxMsgBox(NULL, _T("Error: body was already added to the dynamics world"), _T("Error"), MB_OK); return 0; } // find proxy node m_proxyNode = NULL; TSTR str = MxUserPropUtils::GetUserPropStr(m_node, "Proxy_Geometry"); char* proxyName = str.data(); if(proxyName && strlen(proxyName) > 0 && (stricmp(proxyName, "<None>") != 0)) { m_proxyNode = GetCOREInterface()->GetINodeByName(proxyName); } // ccMaxNode* pActorNode = ccMaxWorld::FindNode(m_node); assert(pActorNode); maxNodeActor = pActorNode; maxNodeProxy = NULL; if(m_proxyNode) { maxNodeProxy = ccMaxWorld::FindNode(m_proxyNode); assert(maxNodeProxy); //Point3 p1 = maxNodeActor->PhysicsNodePoseTM.GetRow(3), p2 = maxNodeProxy->PhysicsNodePoseTM.GetRow(3); Point3 p1 = maxNodeActor->NodePosInPhysics, p2 = maxNodeProxy->NodePosInPhysics; ProxyDistance = p1 - p2; } NxActorDesc& actorDesc = m_desc; NxBodyDesc& bodyDesc = m_bodyDesc; //LoadParameters(actorDesc, bodyDesc); actorDesc.globalPose = pActorNode->PhysicsNodePoseTM;//MxMathUtils::MaxMatrixToNx(pActorNode->PhysicsNodePoseTM); SaveLastPose(pActorNode->PhysicsNodePoseTM); //m_bodydesc.solverIterationCount = (NxU32)mSetting_solveriterationcount; // support it in future? std::vector<INode*> stack; std::vector<INode*> shapes; //Check if the object is using a proxy, in that case only those shapes should be added INode* current = m_node; if(m_proxyNode) current = m_proxyNode; stack.push_back(current); //DEBUG_S("List collision shapes"); while (stack.size() > 0) { current = stack[0]; if(stack.size() > 1) { stack[0] = stack.back(); } stack.pop_back(); if(current->EvalWorldState(0).obj->SuperClassID()==GEOMOBJECT_CLASS_ID) { shapes.push_back(current); } //go through grouped objects for(int i = 0; i < current->NumberOfChildren(); i++) { INode *c = current->GetChildNode(i); if (c->IsGroupMember()) { stack.push_back(c); } } } if (shapes.size() == 0) { if (gCurrentstream) gCurrentstream->printf("Unable to add %s as an actor, it has no shapes.\n", m_node->GetName()); return 0; } ccMaxNode* baseNode = pActorNode; if(maxNodeProxy) { baseNode = maxNodeProxy; } btAlignedObjectArray<btCollisionShape*> collisionShapes; btAlignedObjectArray<btTransform> localTransforms; for (int i = 0; i < shapes.size(); i++) { INode* current = shapes[i]; //DEBUG_F(" Debug adding shape node: %s\n", current->GetName()); ccMaxNode* pn = ccMaxWorld::FindNode(current); assert(pn); btCollisionShape* collisionShape = createShape(actorDesc, pn, pActorNode); collisionShapes.push_back(collisionShape); btTransform localTrans; max2Bullet(actorDesc.localPose,localTrans); localTransforms.push_back(localTrans); } //create a rigid body and add it to the world if (collisionShapes.size()) { btCollisionShape* collisionShape = 0; if (collisionShapes.size()==1) { collisionShape = collisionShapes[0]; } else { btCompoundShape* compound = new btCompoundShape(); for (int i=0;i<collisionShapes.size();i++) { compound->addChildShape(localTransforms[i],collisionShapes[i]); } //clear local pose actorDesc.localPose.IdentityMatrix(); collisionShape = compound; } if (collisionShape) { btVector3 localInertia(0,0,0); if (actorDesc.mass) { collisionShape->calculateLocalInertia(actorDesc.mass,localInertia); } m_bulletBody = new btRigidBody(actorDesc.mass,0,collisionShape,localInertia); m_bulletBody->setUserPointer(this); btScalar restitution; if (MxUserPropUtils::GetUserPropFloat(m_node, "Restitution", restitution)) { m_bulletBody->setRestitution(restitution); } btScalar staticFriction = 0.f; //take the maximum for now MxUserPropUtils::GetUserPropFloat(m_node, "StaticFriction", staticFriction); btScalar friction = 0.f; if (MxUserPropUtils::GetUserPropFloat(m_node, "Friction", friction)) { if (staticFriction>friction) friction = staticFriction; m_bulletBody->setFriction(friction); } // char bla[1024]; // sprintf(bla,"restitution=%f",restitution); // MaxMsgBox(NULL, _T(bla), _T("Error"), MB_OK); syncGlobalPose(); gDynamicsWorld->addRigidBody(m_bulletBody); // MaxMsgBox(NULL, _T("adding rigid body"), _T("Error"), MB_OK); } } bool isvalid = actorDesc.isValid(); actorDesc.name = m_node->GetName(); //NxMat34 pose0 = actorDesc.globalPose; //m_actor = gPluginData->getScene()->createActor(actorDesc); //if(! m_actor) return 0; //NxMat34 pose1 = m_actor->getGlobalPose(); // sometimes pose1 != pose0; it is strange //m_actor->userData = this; if(MxUserPropUtils::GetUserPropBool(m_node, "PutToSleep", false)) { //m_actor->putToSleep(); } // for collision force when contact happens /* NxU32 num = m_actor->getNbShapes(); NxShape*const* ps = m_actor->getShapes(); for(NxU32 i = 0; i < num; ++i) { NxShape* nxShape = ps[i]; nxShape->setFlag(NX_SF_POINT_CONTACT_FORCE, true); } */ //save last pose Matrix3 poseTM = maxNodeActor->GetCurrentTM(); SaveLastPose(poseTM); //return m_actor; return 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); }