Finished: Meshes & Bones. Unfinished: Materials, Skin Mod, Tex Matrix, Anim.

This commit is contained in:
Josh Yelon 2005-07-12 20:48:25 +00:00
parent 261a820d63
commit b34260896c
1 changed files with 209 additions and 23 deletions

View File

@ -10,8 +10,8 @@
#include "stdmat.h"
#include "decomp.h"
#include "shape.h"
#include "splshape.h"
#include "dummy.h"
#include "simpobj.h"
#include "iparamb2.h"
#include "eggData.h"
#include "eggVertexPool.h"
@ -33,10 +33,13 @@ static FILE *lgfile;
////////////////////////////////////////////////////////////////////////////////////////////////////
class MaxEggMesh;
class MaxEggJoint;
class BoneFunctions;
class MaxEggImporter : public SceneImport
{
public:
// GUI-related methods
MaxEggImporter();
~MaxEggImporter();
int ExtCount(); // Number of extensions supported
@ -50,23 +53,35 @@ public:
unsigned int Version(); // Version number * 100 (i.e. v3.01 = 301)
void ShowAbout(HWND hWnd); // Show DLL's "About..." box
int DoImport(const TCHAR *name,ImpInterface *ei,Interface *i, BOOL suppressPrompts);
MaxEggMesh *GetMesh(EggVertexPool *pool);
public:
// GUI-related fields
static Interface *_ip;
static ImpInterface *_impip;
static BOOL _merge;
static BOOL _importmodel;
static BOOL _importanim;
public:
// Import-related methods:
void TraverseEggData(EggData *data);
void TraverseEggNode(EggNode *node, EggGroup *context);
MaxEggMesh *GetMesh(EggVertexPool *pool);
MaxEggJoint *FindJoint(EggGroup *joint);
MaxEggJoint *MakeJoint(EggGroup *joint, EggGroup *context);
public:
Interface *_ip;
ImpInterface *_impip;
static BOOL _merge;
static BOOL _importmodel;
static BOOL _importanim;
typedef pmap<EggVertexPool *, MaxEggMesh *> MeshTable;
// Import-related fields:
typedef phash_map<EggVertexPool *, MaxEggMesh *> MeshTable;
typedef second_of_pair_iterator<MeshTable::const_iterator> MeshIterator;
typedef phash_map<EggGroup *, MaxEggJoint *> JointTable;
typedef second_of_pair_iterator<JointTable::const_iterator> JointIterator;
MeshTable _mesh_tab;
JointTable _joint_tab;
};
Interface *MaxEggImporter::_ip;
ImpInterface *MaxEggImporter::_impip;
BOOL MaxEggImporter::_merge = TRUE;
BOOL MaxEggImporter::_importmodel = TRUE;
BOOL MaxEggImporter::_importanim = TRUE;
@ -146,13 +161,15 @@ static BOOL CALLBACK AboutBoxDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
return FALSE;
}
return TRUE;
}
}
void MaxEggImporter::ShowAbout(HWND hWnd)
{
DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, AboutBoxDlgProc, 0);
DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_ABOUTBOX),
hWnd, AboutBoxDlgProc, 0);
}
static BOOL CALLBACK ImportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
MaxEggImporter *imp = (MaxEggImporter*)GetWindowLong(hWnd,GWL_USERDATA);
@ -240,17 +257,8 @@ public:
int GetTVert(TexCoordd uv);
int GetCVert(Colorf col);
int AddFace(int v0, int v1, int v2, int tv0, int tv1, int tv2, int cv0, int cv1, int cv2);
void LogData(void);
};
void MaxEggMesh::LogData(void)
{
fprintf(lgfile,"Mesh %08x faces: %d\n",_mesh,_mesh->numFaces);
for (int i=0; i<_mesh->numFaces; i++) {
fprintf(lgfile," -- %d %d %d\n",_mesh->tvFace[i].t[0],_mesh->tvFace[i].t[1],_mesh->tvFace[i].t[2]);
}
}
int MaxEggMesh::GetVert(Vertexd pos, Normald norm, EggGroup *context)
{
VertexContext key = VertexContext(VertexPos(pos,norm),context);
@ -337,6 +345,158 @@ int MaxEggMesh::AddFace(int v0, int v1, int v2, int tv0, int tv1, int tv2, int c
return idx;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// MaxEggJoint
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class MaxEggJoint
{
public:
Point3 _xv,_yv,_zv;
Point3 _pos;
Point3 _endpos;
Point3 _zaxis;
double _thickness;
bool _anyvertex;
SimpleObject2 *_bone;
INode *_node;
EggGroup *_egg_joint;
MaxEggJoint *_parent;
vector <MaxEggJoint *> _children;
public:
MaxEggJoint *ChooseBestChild(Point3 dir);
void ChooseEndPos(double thickness);
void CreateMaxBone(void);
};
MaxEggJoint *MaxEggImporter::FindJoint(EggGroup *joint)
{
if (joint==0) return 0;
return _joint_tab[joint];
}
MaxEggJoint *MaxEggImporter::MakeJoint(EggGroup *joint, EggGroup *context)
{
MaxEggJoint *parent = FindJoint(context);
MaxEggJoint *result = new MaxEggJoint;
LMatrix4d t = joint->get_transform();
if (parent) {
result->_xv = parent->_xv*((float)t(0,0)) + parent->_yv*((float)t(0,1)) + parent->_zv*((float)t(0,2));
result->_yv = parent->_xv*((float)t(1,0)) + parent->_yv*((float)t(1,1)) + parent->_zv*((float)t(1,2));
result->_zv = parent->_xv*((float)t(2,0)) + parent->_yv*((float)t(2,1)) + parent->_zv*((float)t(2,2));
result->_pos = parent->_xv*((float)t(3,0)) + parent->_yv*((float)t(3,1)) + parent->_zv*((float)t(3,2)) + parent->_pos;
} else {
result->_xv = Point3(((float)t(0,0)), ((float)t(0,1)), ((float)t(0,2)));
result->_yv = Point3(((float)t(1,0)), ((float)t(1,1)), ((float)t(1,2)));
result->_zv = Point3(((float)t(2,0)), ((float)t(2,1)), ((float)t(2,2)));
result->_pos = Point3(((float)t(3,0)), ((float)t(3,1)), ((float)t(3,2)));
}
result->_endpos = Point3(0,0,0);
result->_zaxis = Point3(0,0,0);
result->_thickness = 0.0;
result->_anyvertex = false;
result->_bone = 0;
result->_node = 0;
result->_egg_joint = joint;
result->_parent = parent;
if (parent) parent->_children.push_back(result);
_joint_tab[joint] = result;
return result;
}
MaxEggJoint *MaxEggJoint::ChooseBestChild(Point3 dir)
{
if (dir.Length() < 0.001) return 0;
dir = dir.Normalize();
double firstbest = -1000;
MaxEggJoint *firstchild = 0;
Point3 firstpos = _pos;
double secondbest = 0;
for (int i=0; i<_children.size(); i++) {
MaxEggJoint *child = _children[i];
Point3 tryfwd = child->_pos - _pos;
if ((child->_pos != firstpos) && (tryfwd.Length() > 0.001)) {
Point3 trydir = tryfwd.Normalize();
double quality = trydir % dir;
if (quality > firstbest) {
secondbest = firstbest;
firstbest = quality;
firstpos = child->_pos;
firstchild = child;
} else if (quality > secondbest) {
secondbest = quality;
}
}
}
if (firstbest > secondbest + 0.1)
return firstchild;
return 0;
}
void MaxEggJoint::ChooseEndPos(double thickness)
{
Point3 parentpos(0,0,0);
Point3 parentendpos(0,0,1);
if (_parent) {
parentpos = _parent->_pos;
parentendpos = _parent->_endpos;
}
Point3 fwd = _pos - parentpos;
if (fwd.Length() < 0.001) {
fwd = parentendpos - parentpos;
}
fwd = fwd.Normalize();
MaxEggJoint *child = ChooseBestChild(fwd);
if (child == 0) {
_endpos = fwd * ((float)(thickness * 0.8)) + _pos;
_thickness = thickness * 0.8;
} else {
_endpos = child->_pos;
_thickness = (_endpos - _pos).Length();
if (_thickness > thickness) _thickness = thickness;
}
Point3 orient = (_endpos - _pos).Normalize();
Point3 altaxis = orient ^ Point3(0,-1,0);
if (altaxis.Length() < 0.001) altaxis = orient ^ Point3(0,0,1);
_zaxis = (altaxis ^ orient).Normalize();
}
void MaxEggJoint::CreateMaxBone(void)
{
Point3 fwd = _endpos - _pos;
double len = fwd.Length();
Point3 txv = fwd * ((float)(1.0/len));
Point3 tzv = _zaxis;
Point3 tyv = tzv ^ txv;
Point3 row1 = Point3(txv % _xv, txv % _yv, txv % _zv);
Point3 row2 = Point3(tyv % _xv, tyv % _yv, tyv % _zv);
Point3 row3 = Point3(tzv % _xv, tzv % _yv, tzv % _zv);
_bone = (SimpleObject2*)CreateInstance(GEOMOBJECT_CLASS_ID, BONE_OBJ_CLASSID);
_node = (MaxEggImporter::_ip)->CreateObjectNode(_bone);
if (_parent) {
_node->Detach(0, 1);
_parent->_node->AttachChild(_node, 1);
}
_node->SetNodeTM(0, Matrix3(_xv, _yv, _zv, _pos));
_node->SetObjOffsetRot(Quat(Matrix3(row1, row2, row3, Point3(0,0,0))));
IParamBlock2 *blk = _bone->pblock2;
for (int i=0; i<blk->NumParams(); i++) {
TSTR n = blk->GetLocalName(i);
if (strcmp(n, "Length")==0) blk->SetValue(i,0,(float)len);
else if (strcmp(n, "Width")==0) blk->SetValue(i,0,(float)_thickness);
else if (strcmp(n, "Height")==0) blk->SetValue(i,0,(float)_thickness);
}
Point3 boneColor = GetUIColor(COLOR_BONES);
_node->SetWireColor(RGB(int(boneColor.x*255.0f), int(boneColor.y*255.0f), int(boneColor.z*255.0f) ));
_node->SetBoneNodeOnOff(TRUE, 0);
_node->SetRenderable(FALSE);
_node->SetName((TCHAR*)(_egg_joint->get_name().c_str()));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TraverseEggData
@ -375,7 +535,10 @@ void MaxEggImporter::TraverseEggNode(EggNode *node, EggGroup *context)
EggGroupNode *group = DCAST(EggGroupNode, node);
if (node->is_of_type(EggGroup::get_class_type())) {
EggGroup *group = DCAST(EggGroup, node);
if (group->is_joint()) context = group;
if (group->is_joint()) {
MakeJoint(group, context);
context = group;
}
}
EggGroupNode::const_iterator ci;
for (ci = group->begin(); ci != group->end(); ++ci) {
@ -387,7 +550,13 @@ void MaxEggImporter::TraverseEggNode(EggNode *node, EggGroup *context)
void MaxEggImporter::TraverseEggData(EggData *data)
{
lgfile = fopen("MaxEggImporter.log","w");
SuspendAnimate();
SuspendSetKeyMode();
AnimateOff();
TraverseEggNode(data, NULL);
MeshIterator ci;
for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
MaxEggMesh *mesh = (*ci);
@ -401,6 +570,23 @@ void MaxEggImporter::TraverseEggData(EggData *data)
mesh->_mesh->InvalidateGeomCache();
mesh->_mesh->buildNormals();
}
double thickness = 0.0;
JointIterator ji;
for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
double dfo = ((*ji)->_pos).Length();
if (dfo > thickness) thickness = dfo;
}
thickness = thickness * 0.025;
for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
MaxEggJoint *joint = *ji;
joint->ChooseEndPos(thickness);
joint->CreateMaxBone();
}
ResumeSetKeyMode();
ResumeAnimate();
if (lgfile) fclose(lgfile);
}