Beispiel #1
0
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);
		}
	}
Beispiel #2
0
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;
}
Beispiel #3
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);
}