void CExportNel::addSkeletonBindPos (INode& skinedNode, mapBoneBindPos& boneBindPos)
{
	// Return success
	uint ok=NoError;

	// Get the skin modifier
	Modifier* skin=getModifier (&skinedNode, SKIN_CLASS_ID);

	// Found it ?
	if (skin)
	{
		// Get a com_skin2 interface
		ISkin *comSkinInterface=(ISkin*)skin->GetInterface (SKIN_INTERFACE);

		// Should been controled with isSkin before.
		nlassert (comSkinInterface);

		// Found com_skin2 ?
		if (comSkinInterface)
		{
			// Get local data
			ISkinContextData *localData=comSkinInterface->GetContextInterface(&skinedNode);

			// Should been controled with isSkin before.
			nlassert (localData);

			// Found ?
			if (localData)
			{
				// Check same vertices count
				uint vertCount=localData->GetNumPoints();

				// For each vertex
				for (uint vert=0; vert<vertCount; vert++)
				{
					// Get bones count for this vertex
					uint boneCount=localData->GetNumAssignedBones (vert);

					// For each bones
					for (uint bone=0; bone<boneCount; bone++)
					{
						// Get the bone id
						int boneId=localData->GetAssignedBone(vert, bone);

						// Get bone INode*
						INode *boneNode=comSkinInterface->GetBone(boneId);

						// Get the bind matrix of the bone
						Matrix3 bindPos;
						comSkinInterface->GetBoneInitTM(boneNode, bindPos);

						// Add an entry inthe map
						boneBindPos.insert (mapBoneBindPos::value_type (boneNode, bindPos));
					}
				}
			}

			// Release the interface
			skin->ReleaseInterface (SKIN_INTERFACE, comSkinInterface);
		}
	}
	else
	{
		// Get the skin modifier
		Modifier* skin=getModifier (&skinedNode, PHYSIQUE_CLASS_ID);

		// Should been controled with isSkin before.
		nlassert (skin);

		// Found it ?
		if (skin)
		{
			// Get a com_skin2 interface
			IPhysiqueExport *physiqueInterface=(IPhysiqueExport *)skin->GetInterface (I_PHYINTERFACE);

			// Should been controled with isSkin before.
			nlassert (physiqueInterface);

			// Found com_skin2 ?
			if (physiqueInterface)
			{
				// Get local data
				IPhyContextExport *localData=physiqueInterface->GetContextInterface(&skinedNode);

				// Should been controled with isSkin before.
				nlassert (localData);

				// Found ?
				if (localData)
				{
					// Use rigid export
					localData->ConvertToRigid (TRUE);

					// Allow blending
					localData->AllowBlending (TRUE);

					// Check same vertices count
					uint vertCount=localData->GetNumberVertices();

					// For each vertex
					for (uint vert=0; vert<vertCount; vert++)
					{
						if (vert==111)
							int toto=0;
						// Get a vertex interface
						IPhyVertexExport *vertexInterface=localData->GetVertexInterface (vert);

						// Check if it is a rigid vertex or a blended vertex
						int type=vertexInterface->GetVertexType ();
						if (type==RIGID_TYPE)
						{
							// this is a rigid vertex
							IPhyRigidVertex			*rigidInterface=(IPhyRigidVertex*)vertexInterface;

							// Get bone INode*
							INode *bone=rigidInterface->GetNode();

							// Get the bind matrix of the bone
							Matrix3 bindPos;
							int res=physiqueInterface->GetInitNodeTM (bone, bindPos);
							nlassert (res==MATRIX_RETURNED);

							// Add an entry inthe map
							if (boneBindPos.insert (mapBoneBindPos::value_type (bone, bindPos)).second)
							{
#ifdef NL_DEBUG
								// *** Debug info

								// Bone name
								std::string boneName=getName (*bone);

								// Local matrix
								Matrix3 nodeTM;
								nodeTM=bone->GetNodeTM (0);

								// Offset matrix
								Matrix3 offsetScaleTM (TRUE);
								Matrix3 offsetRotTM (TRUE);
								Matrix3 offsetPosTM (TRUE);
								ApplyScaling (offsetScaleTM, bone->GetObjOffsetScale ());
								offsetRotTM.SetRotate (bone->GetObjOffsetRot ());
								offsetPosTM.SetTrans (bone->GetObjOffsetPos ());
								Matrix3 offsetTM = offsetScaleTM * offsetRotTM * offsetPosTM;

								// Local + offset matrix
								Matrix3 nodeOffsetTM = offsetTM * nodeTM;

								// Init TM
								Matrix3 initTM;
								int res=physiqueInterface->GetInitNodeTM (bone, initTM);
								nlassert (res==MATRIX_RETURNED);

								// invert
								initTM.Invert();
								Matrix3 compNode=nodeTM*initTM;
								Matrix3 compOffsetNode=nodeOffsetTM*initTM;
								Matrix3 compOffsetNode2=nodeOffsetTM*initTM;
#endif // NL_DEBUG
							}
						}
						else
						{
							// It must be a blendable vertex
							nlassert (type==RIGID_BLENDED_TYPE);
							IPhyBlendedRigidVertex	*blendedInterface=(IPhyBlendedRigidVertex*)vertexInterface;

							// For each bones
							uint boneIndex;
							uint count=(uint)blendedInterface->GetNumberNodes ();
							for (boneIndex=0; boneIndex<count; boneIndex++)
							{
								// Get the bone pointer
								INode *bone = blendedInterface->GetNode(boneIndex);

								if (bone == NULL)
								{
									nlwarning("bone == NULL; boneIndex = %i / %i", boneIndex, count);
								}
								else
								{
									// Get the bind matrix of the bone
									Matrix3 bindPos;
									int res = physiqueInterface->GetInitNodeTM (bone, bindPos);

									if (res != MATRIX_RETURNED)
									{
										nlwarning("res != MATRIX_RETURNED; res = %i; boneIndex = %i / %i", res, boneIndex, count);
										nlwarning("bone = %i", (uint32)(void *)bone);
										std::string boneName = getName (*bone);
										nlwarning("boneName = %s", boneName.c_str());
										nlassert(false);
									}

									// Add an entry inthe map
									if (boneBindPos.insert (mapBoneBindPos::value_type (bone, bindPos)).second)
									{
	#ifdef NL_DEBUG
										// *** Debug info

										// Bone name
										std::string boneName=getName (*bone);

										// Local matrix
										Matrix3 nodeTM;
										nodeTM=bone->GetNodeTM (0);

										// Offset matrix
										Matrix3 offsetScaleTM (TRUE);
										Matrix3 offsetRotTM (TRUE);
										Matrix3 offsetPosTM (TRUE);
										ApplyScaling (offsetScaleTM, bone->GetObjOffsetScale ());
										offsetRotTM.SetRotate (bone->GetObjOffsetRot ());
										offsetPosTM.SetTrans (bone->GetObjOffsetPos ());
										Matrix3 offsetTM = offsetScaleTM * offsetRotTM * offsetPosTM;

										// Local + offset matrix
										Matrix3 nodeOffsetTM = offsetTM * nodeTM;

										// Init TM
										Matrix3 initTM;
										int res=physiqueInterface->GetInitNodeTM (bone, initTM);
										nlassert (res==MATRIX_RETURNED);

										// invert
										initTM.Invert();
										Matrix3 compNode=nodeTM*initTM;
										Matrix3 compOffsetNode=nodeOffsetTM*initTM;
										Matrix3 compOffsetNode2=nodeOffsetTM*initTM;
#endif // NL_DEBUG
									}
								}
							}
						}
					
						// Release vertex interfaces
						localData->ReleaseVertexInterface (vertexInterface);
					}

					// Release locaData interface
					physiqueInterface->ReleaseContextInterface (localData);
				}

				// Release the interface
				skin->ReleaseInterface (SKIN_INTERFACE, physiqueInterface);
			}
		}
	}
}
Exemple #2
0
void PivotSnap::Snap(Object* pobj, IPoint2 *p, TimeValue t)
{	
	// This snap computes the bounding box points of a node as 
	// well as the pivot point

	//local copy of the cursor position
	Point2 fp = Point2((float)p->x, (float)p->y);

	//In this snap mode we actually need to get a pointer to the node so that we 
	// can check for WSM's and compute the pivot point
	INode *inode = theman->GetNode();
	Matrix3 atm(1); //This will hold the nodes tm before WSMs

	//See if this guys has any spacewarps applied
	BOOL wsm = (BOOL) inode->GetProperty(PROPID_HAS_WSM);

	//If it does then we'll need to get a meaningful tm as follows
	if(wsm)
		atm = inode->GetObjTMBeforeWSM(t);

	//get the node's bounding box
	Box3 box;
	box.Init();
	pobj->GetDeformBBox(t, box, NULL );

	if(EssentiallyEmpty(box))
		pobj->GetLocalBoundBox(t, inode, theman->GetVpt() , box);

		//We need a hitmesh which shows the bounding box of the node
	//This automatic variable gets passed to the hitmesh copy constructor
	// in every case
	HitMesh thehitmesh, *phitmesh;
	thehitmesh.setNumVerts(8);
	for(int jj = 0;jj<8;++jj)
		thehitmesh.setVert(jj,box[jj]);


	BOOL got_one= FALSE;

	//Compute all the hit point candidates
	if(	GetActive(PIV_SUB))
	{
		got_one = FALSE;
		Point3 *pivpt;

		//JH 10/02/01
		//DID 296059
		Matrix3 tm(1);
		Point3 pos = inode->GetObjOffsetPos();
		tm.PreTranslate(pos);
		Quat quat = inode->GetObjOffsetRot();
		PreRotateMatrix(tm, quat);
		ScaleValue scale = inode->GetObjOffsetScale();
		ApplyScaling(tm, scale);
		Matrix3 InvTm = Inverse(tm);



		//JH 10/02/01
		//atm contains the identity normally, or the node TM before spacewarps, when space warps are applied
		//We're computing a point relative to the node TM, so in the former case the inverse of
		//the object offset pos is what we want. In the latter (when the node TM is identtity, we must add
		//in the node TM before WSM.
		pivpt = new Point3(atm.GetTrans() + InvTm.GetTrans());

		//Make a hitmesh
		phitmesh = new HitMesh(thehitmesh);

		//now register a hit with the osnap manager
		theman->RecordHit(new OsnapHit(*pivpt, this, PIV_SUB, phitmesh));
	}

	if(	GetActive(BBOX_SUB))
	{

		//set up our highlight mesh
		for(int ii = 0;ii<8;++ii)
		{
			phitmesh = new HitMesh(thehitmesh);

			theman->RecordHit(new OsnapHit(box[ii], this, BBOX_SUB, phitmesh));
		}
	}


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