199 lines
5.6 KiB
C++
199 lines
5.6 KiB
C++
//**************************************************************************
|
|
//* Max2NmoCS312.cpp - Virtools File Exporter
|
|
//*
|
|
//* Romain Sididris - Copyright (c) Virtools 2001
|
|
//*
|
|
//* - This file contains some the same code than MAx2Nmo301.cpp
|
|
//* but use the 3.12 version of character studio header files
|
|
//*
|
|
//***************************************************************************
|
|
#include "Precomp.h"
|
|
#include "Max2Nmo.h"
|
|
|
|
#ifndef MAX42
|
|
|
|
#include "PhyExpCS312.h"
|
|
|
|
int AddBoneToArray(XVoidArray* bones,void* bone);
|
|
|
|
// Try to find if a skin modifier is in the modifier stack of a node
|
|
Modifier* Max2Nmo::FindSkinModifierCS312 (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::FindPhysiqueModifierCS312 (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::ExportPhysiqueMeshCS312(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;
|
|
}
|
|
|
|
#endif |