⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mrchelper.cpp

📁 游戏编程精粹2第一章源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************
 	MODULE: MRCexport
	
	DESCRIPTION: This module is the plugin for MAX 3 to export in MRC format
	
	Version:		1.22			

	DEVELOPED BY:		MARCO TOMBESI
	CONTACT:		e-mail:		baggior@libero.it		
					web-page:	digilander.iol.it/baggior

 *>	Copyright (c) Marco Tombesi, 2001
 **********************************************************************/

#include "utils.h"
#include "MRChelper.h"
#include "extra\Bipexp.h"
#include "extra\Phyexp.h"
#include "extra\ISkin.h"

// ============================================================================
bool IsMesh(INode *pNode)
{
	if(pNode == NULL)
		return false;
	ObjectState os = pNode->EvalWorldState(0); 
	if(os.obj->SuperClassID() == GEOMOBJECT_CLASS_ID)
		return true;

	return false;
}

// ============================================================================
//test if is a bone or a biped controller
bool IsBone(INode *pNode)
{
	if(pNode == NULL)
		return false;

	ObjectState os = pNode->EvalWorldState(0);

	if (!os.obj) return false;

	if(os.obj->ClassID() == Class_ID(BONE_CLASS_ID, 0))
		return true;

	if(os.obj->ClassID() == Class_ID(DUMMY_CLASS_ID, 0))
		return false;

	Control *cont = pNode->GetTMController();
	if(cont->ClassID() == BIPSLAVE_CONTROL_CLASS_ID ||		//others biped parts
		cont->ClassID() == BIPBODY_CONTROL_CLASS_ID			//biped root "Bip01"
		
	) return true;

	return false;
}

/*
// ============================================================================
bool IsBipedBone(INode *pNode)
{
	if(pNode == NULL || pNode->IsRootNode())
		return false;

	Control *cont = pNode->GetTMController();
	if(cont->ClassID() == BIPSLAVE_CONTROL_CLASS_ID ||
		cont->ClassID() == BIPBODY_CONTROL_CLASS_ID
	) return true;

	return false;
}
*/
// ============================================================================
// Get the number of direct child bones of a node
int GetChildBoneCount(INode *pNode)
{
	int count = 0;

	for(int i = 0; i < pNode->NumberOfChildren(); i++)
	{
		if(IsBone(pNode->GetChildNode(i)))
			count++;
	}
	return count;
}

// ============================================================================
// how many bones in the scene? Pass it the rootNode
int CountBones(INode* pNode)
{
	int count = 0;
	if(IsBone(pNode))
		count += 1;

	for(int i = 0; i < pNode->NumberOfChildren(); i++)
		count += CountBones(pNode->GetChildNode(i));
	return count;
}

// ============================================================================
// ============================================================================
// used by GetBoneByIndex
static bool BuildIter (INode* pnode, INode** const Iterator, int& currIdx) {
	
	if(IsBone(pnode)){
		Iterator[currIdx++] = pnode;
	}

	for(int i = 0; i < pnode->NumberOfChildren(); i++) {
		BuildIter (pnode->GetChildNode(i),Iterator,currIdx);
	}

	return true;
}

// ============================================================================
// Get bone pointer from an index, this should get passed the root node
INode* GetBoneByIndex(INode* const pRoot, int index) {
	INode* bone = NULL;
	const int bone_cnt = CountBones(pRoot);
	
	if (index>=bone_cnt) 
		return NULL;

	INode** const Iterator = new INode* [bone_cnt];
	int currIdx=0;
	
		BuildIter(pRoot,Iterator,currIdx);
	
	assert(currIdx==bone_cnt);

	bone = Iterator[index];
	
	assert (GetBoneIndex(pRoot,bone)==index);

	delete [] Iterator;
		
	assert (IsBone(bone));
	return bone;
}
// ============================================================================

// ============================================================================
// Recursive iterator to get a bone index, used with GetBoneIndex
int RecursiveGetBoneIndex(INode *pRoot, INode *pNodeTest, int &boneCount)
{
	int boneIdx = -1;

	if(IsBone(pRoot))
	{
		boneIdx = boneCount;
		boneCount++;

		if(pRoot == pNodeTest)
			return boneIdx;
	}

	// recurse child nodes
	for(int i = 0; i < pRoot->NumberOfChildren(); i++)
	{
		int boneIdx = RecursiveGetBoneIndex(pRoot->GetChildNode(i), pNodeTest, boneCount);
		if(boneIdx >= 0)
			return boneIdx;
	}

	return -1;
}

// ============================================================================
// Get an index from a node pointer
int GetBoneIndex(INode *pRoot, INode *pNode)
{
	if(!IsBone(pNode))
		return -1;

	int boneCount = 0;
	return RecursiveGetBoneIndex(pRoot, pNode, boneCount);
}


// ============================================================================
Matrix3 GetBoneTM(INode *pNode, TimeValue t)
{
	Matrix3 tm(1);

		tm = pNode->GetNodeTM(t);

	tm.NoScale();
	return tm;
}
// ============================================================================


// ============================================================================
static Modifier* GetPhysiqueMod(INode *pNode)
{
	Object *pObj = pNode->GetObjectRef();
	if(!pObj) return NULL;

	// Is derived object ?
	while(pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID)
	{
		// Yes -> Cast.
		IDerivedObject *pDerivedObj = static_cast<IDerivedObject*>(pObj);

		// Iterate over all entries of the modifier stack.
		int ModStackIndex = 0;
		while(ModStackIndex < pDerivedObj->NumModifiers())
		{
			// Get current modifier.
			Modifier* pMod = pDerivedObj->GetModifier(ModStackIndex);

			// Is this Physique ?
			if(pMod->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B))
				return pMod;

			// Next modifier stack entry.
			ModStackIndex++;

		}
		pObj = pDerivedObj->GetObjRef();
	}
	// Not found.
	return NULL;
}

// ============================================================================
static Modifier* GetSkinMod(INode *pNode)
{
	Object *pObj = pNode->GetObjectRef();
	if(!pObj) return NULL;
	
	// Is derived object ?
	while(pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID)
	{
		// Yes -> Cast.
		IDerivedObject *pDerObj = static_cast<IDerivedObject*>(pObj);

		// Iterate over all entries of the modifier stack.
		int ModStackIndex = 0;
		while (ModStackIndex < pDerObj->NumModifiers())
		{
			// Get current modifier.
			Modifier* mod = pDerObj->GetModifier(ModStackIndex);
			
			// Is this Skin ?
			if(mod->ClassID() == SKIN_CLASSID)
			{
				// Yes -> Exit.
				return mod;
			}
			
			// Next modifier stack entry.
			ModStackIndex++;
		}
		pObj = pDerObj->GetObjRef();
	}
	// Not found.
	return NULL;
}

// ============================================================================
bool ProcessBoneWeights (INode *pNode,INode *pRoot, BoneData_t* BD)
{
	if ((!pNode)||(!IsMesh(pNode))) return false;
			 
	
	Modifier *pMod = GetPhysiqueMod(pNode);
	if(!pMod)
	{
/*		pMod = GetSkinMod(pNode);
		if ( (!pMod) ||
			 (!GetSkinWeights(pNode,pRoot, pMod, BD)) )
*/			return false;
	}
	else
			GetPhysiqueWeights(pNode, pRoot, pMod, BD);

	return true;
}


// ============================================================================
int ProcessBoneStruct(INode *pNode, INode *pRoot,int parentIdx, BoneData_t* BD)
{
	//test if the node is a bone		
	if (IsBone(pNode)) 
	{	
		int currIdx = GetBoneIndex (pRoot, pNode);

		assert(-1!=currIdx);
		
		//set bone header data
		MRCbone_hdr &bHdr = BD[currIdx].Hdr;
		// get the bones inverse base matrix at time 0		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -