📄 mrchelper.cpp
字号:
/**********************************************************************
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 + -