📄 max2nmocs301.cpp
字号:
//**************************************************************************
//* Max2NmoCS312.cpp - Virtools File Exporter
//*
//* Romain Sididris - Copyright (c) Virtools 2001
//*
//* - This file contains some the same code than MAx2Nmo312.cpp
//* but use the 3.00 version of character studio header files
//*
//* In the case of Max 4.2 (Character Studio 3.2) , Only this file is used...
//***************************************************************************
#include "Precomp.h"
#include "Max2Nmo.h"
#ifdef MAX42
#include "PhyExp.h"
#else
#include "PhyExpCS300.h"
#endif
int AddBoneToArray(XVoidArray* bones,void* bone);
// Try to find if a skin modifier is in the modifier stack of a node
Modifier* Max2Nmo::FindSkinModifierCS300 (INode* node)
{
// Get object from node. Abort if no object.
Object* pObj = node->GetObjectRef();
if (!pObj) return NULL;
// Is derived object ?
SClass_ID sid = pObj->SuperClassID();
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 ) {
return mod;
}
// Next modifier stack entry.
ModStackIndex++;
}
pObj = pDerObj->GetObjRef();
}
return NULL;
}
// Try to find if a physique modifier is in the modifier stack of a node
Modifier* Max2Nmo::FindPhysiqueModifierCS300 (INode* node)
{
// Get object from node. Abort if no object.
Object* pObj = node->GetObjectRef();
if (!pObj) return NULL;
// Is derived object ?
SClass_ID sid = pObj->SuperClassID();
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 Physique ?
if (mod->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B) ) {
return mod;
}
// Next modifier stack entry.
ModStackIndex++;
}
pObj = pDerObj->GetObjRef();
}
// Not found.
return NULL;
}
/********************************************************************
********************************************************************/
BOOL Max2Nmo::ExportPhysiqueMeshCS300(INode* node,CK3dEntity* ent)
{
Modifier *PhysiqueModifier = FindPhysiqueModifier(node);
if (!PhysiqueModifier) return FALSE;
IPhysiqueExport *phyInterface = (IPhysiqueExport *)( PhysiqueModifier->GetInterface(I_PHYINTERFACE) );
if (!phyInterface) return FALSE;
IPhyContextExport* context=phyInterface->GetContextInterface(node);
if (!context) return FALSE;
VirtoolsTransitionMesh* tmp_mesh= VirtoolsExporter->GetTransitionMesh(node);
context->AllowBlending(TRUE);
context->ConvertToRigid(TRUE);
CKMesh* mesh=ent->GetCurrentMesh();
if (!mesh) return FALSE;
Report(REPORT_HLEVEL,"%s : Converting Physique modifier to Skinning\r\n",node->GetName());
Matrix3 InitTM;
VxMatrix Mat;
CKSkin* skin = ent->CreateSkin();
int NbPhyVertices = context->GetNumberVertices();
int VertexCount = mesh->GetModifierVertexCount();
XVoidArray bones;
CKDWORD Stride=0;
BYTE* pts=mesh->GetModifierVertices(&Stride);
CKDWORD NStride=0;
BYTE* norms=(BYTE*)mesh->GetNormalsPtr(&NStride);
BOOL DoNormal = (mesh->GetClassID() != CKCID_PATCHMESH);
skin->SetVertexCount(VertexCount);
if (DoNormal) {
skin->SetNormalCount(VertexCount);
}
//----- Convert vertices info to skin data
for(int j = 0 ; j < VertexCount ; j++,pts+=Stride,norms+=NStride) {
int MaxVertexIndex = tmp_mesh ? tmp_mesh->m_VirtoolsVertices[j].OriginalPosIndex : j;
IPhyVertexExport* vert=context->GetVertexInterface(MaxVertexIndex);
CKSkinVertexData* vertexdata = skin->GetVertexData(j);
if (vert)
if (vert->GetVertexType()==RIGID_NON_BLENDED_TYPE) {
IPhyRigidVertex* rvert=(IPhyRigidVertex*)vert;
vertexdata->SetBoneCount(1);
vertexdata->SetBone(0,AddBoneToArray(&bones,rvert->GetNode()));
vertexdata->SetWeight(0,1.0f);
vertexdata->SetInitialPos(*(VxVector *)pts);
if (DoNormal) {
skin->SetNormal(j,*(VxVector *)norms);
}
} else
if (vert->GetVertexType()==RIGID_BLENDED_TYPE) {
// RIGID_BLENDED_TYPE
IPhyBlendedRigidVertex* bvert=(IPhyBlendedRigidVertex*)vert;
int nbbones = bvert->GetNumberNodes();
vertexdata->SetBoneCount(nbbones);
vertexdata->SetInitialPos(*(VxVector *)pts);
if (DoNormal) {
skin->SetNormal(j,*(VxVector *)norms);
}
float sum = 0;
for (int k=0;k<nbbones;++k) {
sum += bvert->GetWeight(k);
}
sum = 1.0f/sum;
for (k=0;k<nbbones;++k) {
vertexdata->SetBone(k,AddBoneToArray(&bones,bvert->GetNode(k)));
vertexdata->SetWeight(k,sum * bvert->GetWeight(k));
}
} else {
Report(REPORT_HLEVEL,"%s : Invalid skin vertex type (Not Rigid)\r\n",node->GetName());
}
context->ReleaseVertexInterface(vert);
}
//----- Create Bones
int NbBones=bones.Size();
skin->SetBoneCount(NbBones);
for(j = 0 ; j < NbBones; j++) {
INode* bone=(INode *)bones[j];
CK3dEntity* ent = VirtoolsExporter->GetEntityByKey(bone);
CKSkinBoneData* bonedata = skin->GetBoneData(j);
bonedata->SetBone(ent);
if (ent) {
bonedata->SetBoneInitialInverseMatrix(ent->GetInverseWorldMatrix());
}
}
InitTM=node->GetNodeTM(0);
ConvertMaxMatrix2Virtools(InitTM, Mat);
skin->SetObjectInitMatrix(Mat);
phyInterface->ReleaseContextInterface(context);
PhysiqueModifier->ReleaseInterface(I_PHYINTERFACE,phyInterface);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -