mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
Remove duplicate files
This commit is contained in:
parent
ecf196bb1a
commit
813b15da3c
@ -1,265 +0,0 @@
|
|||||||
// Filename: maxEggImport.cxx
|
|
||||||
// Created by: jyelon (15Jul05)
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// PANDA 3D SOFTWARE
|
|
||||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
//
|
|
||||||
// All use of this software is subject to the terms of the revised BSD
|
|
||||||
// license. You should have received a copy of this license along
|
|
||||||
// with this source code in a file named "LICENSE."
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// This is the wrapper code for the max importer plugin.
|
|
||||||
// It includes:
|
|
||||||
//
|
|
||||||
// - user interface dialogs and popups
|
|
||||||
// - plugin initialization/registration
|
|
||||||
//
|
|
||||||
// It does not include the actual code to traverse the EggData.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// MAX includes
|
|
||||||
#include "maxEggLoader.h"
|
|
||||||
#include "Max.h"
|
|
||||||
#include "maxImportRes.h"
|
|
||||||
#include "istdplug.h"
|
|
||||||
|
|
||||||
// panda includes.
|
|
||||||
#include "notifyCategoryProxy.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
class MaxEggImporter : public SceneImport
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// GUI-related methods
|
|
||||||
MaxEggImporter();
|
|
||||||
~MaxEggImporter();
|
|
||||||
int ExtCount(); // Number of extensions supported
|
|
||||||
const TCHAR * Ext(int n); // Extension #n (i.e. "EGG")
|
|
||||||
const TCHAR * LongDesc(); // Long ASCII description (i.e. "Egg Importer")
|
|
||||||
const TCHAR * ShortDesc(); // Short ASCII description (i.e. "Egg")
|
|
||||||
const TCHAR * AuthorName(); // ASCII Author name
|
|
||||||
const TCHAR * CopyrightMessage();// ASCII Copyright message
|
|
||||||
const TCHAR * OtherMessage1(); // Other message #1
|
|
||||||
const TCHAR * OtherMessage2(); // Other message #2
|
|
||||||
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);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// GUI-related fields
|
|
||||||
static BOOL _merge;
|
|
||||||
static BOOL _importmodel;
|
|
||||||
static BOOL _importanim;
|
|
||||||
};
|
|
||||||
|
|
||||||
BOOL MaxEggImporter::_merge = TRUE;
|
|
||||||
BOOL MaxEggImporter::_importmodel = TRUE;
|
|
||||||
BOOL MaxEggImporter::_importanim = FALSE;
|
|
||||||
|
|
||||||
MaxEggImporter::MaxEggImporter()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MaxEggImporter::~MaxEggImporter()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int MaxEggImporter::ExtCount()
|
|
||||||
{
|
|
||||||
// Number of different extensions handled by this importer.
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TCHAR * MaxEggImporter::Ext(int n)
|
|
||||||
{
|
|
||||||
// Fetch the extensions handled by this importer.
|
|
||||||
switch(n) {
|
|
||||||
case 0: return _T("egg");
|
|
||||||
default: return _T("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const TCHAR * MaxEggImporter::LongDesc()
|
|
||||||
{
|
|
||||||
return _T("Panda3D Egg Importer");
|
|
||||||
}
|
|
||||||
|
|
||||||
const TCHAR * MaxEggImporter::ShortDesc()
|
|
||||||
{
|
|
||||||
return _T("Panda3D Egg");
|
|
||||||
}
|
|
||||||
|
|
||||||
const TCHAR * MaxEggImporter::AuthorName()
|
|
||||||
{
|
|
||||||
return _T("Joshua Yelon");
|
|
||||||
}
|
|
||||||
|
|
||||||
const TCHAR * MaxEggImporter::CopyrightMessage()
|
|
||||||
{
|
|
||||||
return _T("Copyight (c) 2005 Josh Yelon");
|
|
||||||
}
|
|
||||||
|
|
||||||
const TCHAR * MaxEggImporter::OtherMessage1()
|
|
||||||
{
|
|
||||||
return _T("");
|
|
||||||
}
|
|
||||||
|
|
||||||
const TCHAR * MaxEggImporter::OtherMessage2()
|
|
||||||
{
|
|
||||||
return _T("");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int MaxEggImporter::Version()
|
|
||||||
{
|
|
||||||
return 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL CALLBACK AboutBoxDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
switch (msg) {
|
|
||||||
case WM_INITDIALOG:
|
|
||||||
CenterWindow(hWnd, GetParent(hWnd));
|
|
||||||
break;
|
|
||||||
case WM_COMMAND:
|
|
||||||
switch (LOWORD(wParam)) {
|
|
||||||
case IDOK:
|
|
||||||
EndDialog(hWnd, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaxEggImporter::ShowAbout(HWND hWnd)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
switch (msg) {
|
|
||||||
case WM_INITDIALOG:
|
|
||||||
imp = (MaxEggImporter*)lParam;
|
|
||||||
SetWindowLong(hWnd,GWL_USERDATA,lParam);
|
|
||||||
CenterWindow(hWnd, GetParent(hWnd));
|
|
||||||
CheckDlgButton(hWnd, IDC_MERGE, imp->_merge);
|
|
||||||
CheckDlgButton(hWnd, IDC_IMPORTMODEL, imp->_importmodel);
|
|
||||||
CheckDlgButton(hWnd, IDC_IMPORTANIM, imp->_importanim);
|
|
||||||
break;
|
|
||||||
case WM_COMMAND:
|
|
||||||
switch (LOWORD(wParam)) {
|
|
||||||
case IDOK:
|
|
||||||
imp->_merge = IsDlgButtonChecked(hWnd, IDC_MERGE);
|
|
||||||
imp->_importmodel = IsDlgButtonChecked(hWnd, IDC_IMPORTMODEL);
|
|
||||||
imp->_importanim = IsDlgButtonChecked(hWnd, IDC_IMPORTANIM);
|
|
||||||
EndDialog(hWnd, 1);
|
|
||||||
break;
|
|
||||||
case IDCANCEL:
|
|
||||||
EndDialog(hWnd, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MaxEggImporter::DoImport(const TCHAR *name,ImpInterface *ii,Interface *i, BOOL suppressPrompts)
|
|
||||||
{
|
|
||||||
// Prompt the user with our dialogbox.
|
|
||||||
if (!DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_IMPORT_DLG),
|
|
||||||
i->GetMAXHWnd(), ImportDlgProc, (LPARAM)this)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostringstream log;
|
|
||||||
Notify::ptr()->set_ostream_ptr(&log, false);
|
|
||||||
bool ok = MaxLoadEggFile(name, _merge ? true:false, _importmodel ? true:false, _importanim ? true:false);
|
|
||||||
string txt = log.str();
|
|
||||||
if (txt != "") MessageBox(NULL, txt.c_str(), "Panda3D Importer", MB_OK);
|
|
||||||
else {
|
|
||||||
if (!ok) MessageBox(NULL, "Import Failed, unknown reason\n", "Panda3D Importer", MB_OK);
|
|
||||||
}
|
|
||||||
Notify::ptr()->set_ostream_ptr(NULL, false);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Plugin Initialization
|
|
||||||
//
|
|
||||||
// The following code enables Max to load this DLL, get a list
|
|
||||||
// of the classes defined in this DLL, and provides a means for
|
|
||||||
// Max to create instances of those classes.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HINSTANCE hInstance;
|
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved)
|
|
||||||
{
|
|
||||||
static int controlsInit = FALSE;
|
|
||||||
hInstance = hinstDLL;
|
|
||||||
|
|
||||||
if (!controlsInit) {
|
|
||||||
controlsInit = TRUE;
|
|
||||||
InitCustomControls(hInstance);
|
|
||||||
InitCommonControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PANDAEGGIMP_CLASS_ID1 0x377193ab
|
|
||||||
#define PANDAEGGIMP_CLASS_ID2 0x897afe12
|
|
||||||
|
|
||||||
class MaxEggImporterClassDesc: public ClassDesc
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int IsPublic() {return 1;}
|
|
||||||
void *Create(BOOL loading = FALSE) {return new MaxEggImporter;}
|
|
||||||
const TCHAR *ClassName() {return _T("MaxEggImporter");}
|
|
||||||
SClass_ID SuperClassID() {return SCENE_IMPORT_CLASS_ID;}
|
|
||||||
Class_ID ClassID() {return Class_ID(PANDAEGGIMP_CLASS_ID1,PANDAEGGIMP_CLASS_ID2);}
|
|
||||||
const TCHAR *Category() {return _T("Chrutilities");}
|
|
||||||
};
|
|
||||||
|
|
||||||
static MaxEggImporterClassDesc MaxEggImporterDesc;
|
|
||||||
|
|
||||||
__declspec( dllexport ) const TCHAR* LibDescription()
|
|
||||||
{
|
|
||||||
return _T("Panda3D Egg Importer");
|
|
||||||
}
|
|
||||||
|
|
||||||
__declspec( dllexport ) int LibNumberClasses()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
__declspec( dllexport ) ClassDesc* LibClassDesc(int i)
|
|
||||||
{
|
|
||||||
switch(i) {
|
|
||||||
case 0: return &MaxEggImporterDesc;
|
|
||||||
default: return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__declspec( dllexport ) ULONG LibVersion()
|
|
||||||
{
|
|
||||||
return VERSION_3DSMAX;
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
EXPORTS
|
|
||||||
LibDescription @1
|
|
||||||
LibNumberClasses @2
|
|
||||||
LibClassDesc @3
|
|
||||||
LibVersion @4
|
|
||||||
SECTIONS
|
|
||||||
.data READ WRITE
|
|
@ -1,732 +0,0 @@
|
|||||||
// Filename: maxEggImport.cxx
|
|
||||||
// Created by: jyelon (15Jul05)
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// PANDA 3D SOFTWARE
|
|
||||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
//
|
|
||||||
// All use of this software is subject to the terms of the revised BSD
|
|
||||||
// license. You should have received a copy of this license along
|
|
||||||
// with this source code in a file named "LICENSE."
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// This file contains the code for class MaxEggLoader. This class
|
|
||||||
// does the actual work of copying an EggData tree into the max scene.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
#include "pandatoolbase.h"
|
|
||||||
#include "notifyCategoryProxy.h"
|
|
||||||
|
|
||||||
#include "eggData.h"
|
|
||||||
#include "eggVertexPool.h"
|
|
||||||
#include "eggVertex.h"
|
|
||||||
#include "eggPolygon.h"
|
|
||||||
#include "eggPrimitive.h"
|
|
||||||
#include "eggGroupNode.h"
|
|
||||||
#include "eggPolysetMaker.h"
|
|
||||||
#include "eggBin.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "Max.h"
|
|
||||||
#include "maxImportRes.h"
|
|
||||||
#include "istdplug.h"
|
|
||||||
#include "stdmat.h"
|
|
||||||
#include "decomp.h"
|
|
||||||
#include "shape.h"
|
|
||||||
#include "simpobj.h"
|
|
||||||
#include "iparamb2.h"
|
|
||||||
#include "iskin.h"
|
|
||||||
#include "modstack.h"
|
|
||||||
|
|
||||||
#include "maxEggLoader.h"
|
|
||||||
|
|
||||||
class MaxEggMesh;
|
|
||||||
class MaxEggJoint;
|
|
||||||
class MaxEggTex;
|
|
||||||
|
|
||||||
NotifyCategoryDeclNoExport(maxloader);
|
|
||||||
NotifyCategoryDef(maxloader, "");
|
|
||||||
|
|
||||||
class MaxEggLoader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool ConvertEggData(EggData *data, bool merge, bool model, bool anim);
|
|
||||||
bool ConvertEggFile(const char *name, bool merge, bool model, bool anim);
|
|
||||||
|
|
||||||
public:
|
|
||||||
void TraverseEggNode(EggNode *node, EggGroup *context);
|
|
||||||
MaxEggMesh *GetMesh(EggVertexPool *pool);
|
|
||||||
MaxEggJoint *FindJoint(EggGroup *joint);
|
|
||||||
MaxEggJoint *MakeJoint(EggGroup *joint, EggGroup *context);
|
|
||||||
MaxEggTex *GetTex(const string &fn);
|
|
||||||
void CreateSkinModifier(MaxEggMesh *M);
|
|
||||||
|
|
||||||
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;
|
|
||||||
typedef phash_map<string, MaxEggTex *> TexTable;
|
|
||||||
typedef second_of_pair_iterator<TexTable::const_iterator> TexIterator;
|
|
||||||
|
|
||||||
MeshTable _mesh_tab;
|
|
||||||
JointTable _joint_tab;
|
|
||||||
TexTable _tex_tab;
|
|
||||||
int _next_tex;
|
|
||||||
CoordinateSystem _coord_sys;
|
|
||||||
};
|
|
||||||
|
|
||||||
Point3 ConvertCoordSys(CoordinateSystem sys, LVector3d vec)
|
|
||||||
{
|
|
||||||
if (sys == CS_yup_right) {
|
|
||||||
return Point3(vec[0], -vec[2], vec[1]);
|
|
||||||
} else {
|
|
||||||
return Point3(vec[0], vec[1], vec[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// MaxEggTex
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class MaxEggTex
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
string _path;
|
|
||||||
int _id;
|
|
||||||
StdMat *_mat;
|
|
||||||
BitmapTex *_bmt;
|
|
||||||
};
|
|
||||||
|
|
||||||
MaxEggTex *MaxEggLoader::GetTex(const string &fn)
|
|
||||||
{
|
|
||||||
if (_tex_tab.count(fn))
|
|
||||||
return _tex_tab[fn];
|
|
||||||
|
|
||||||
BitmapTex *bmt = NewDefaultBitmapTex();
|
|
||||||
bmt->SetMapName((TCHAR*)(fn.c_str()));
|
|
||||||
StdMat *mat = NewDefaultStdMat();
|
|
||||||
mat->SetSubTexmap(ID_DI, bmt);
|
|
||||||
mat->SetTexmapAmt(ID_DI, 1.0, 0);
|
|
||||||
mat->EnableMap(ID_DI, TRUE);
|
|
||||||
mat->SetActiveTexmap(bmt);
|
|
||||||
GetCOREInterface()->ActivateTexture(bmt, mat);
|
|
||||||
|
|
||||||
MaxEggTex *res = new MaxEggTex;
|
|
||||||
res->_path = fn;
|
|
||||||
res->_id = _next_tex ++;
|
|
||||||
res->_bmt = bmt;
|
|
||||||
res->_mat = mat;
|
|
||||||
|
|
||||||
_tex_tab[fn] = res;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// MaxEggJoint
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class MaxEggJoint
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LMatrix4d _trans;
|
|
||||||
LVector3d _endpos;
|
|
||||||
LVector3d _perp;
|
|
||||||
double _thickness;
|
|
||||||
bool _inskin;
|
|
||||||
SimpleObject2 *_bone;
|
|
||||||
INode *_node;
|
|
||||||
EggGroup *_egg_joint;
|
|
||||||
MaxEggJoint *_parent;
|
|
||||||
vector <MaxEggJoint *> _children;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void GetRotation(LVector3d &xv, LVector3d &yv, LVector3d &zv);
|
|
||||||
LVector3d GetPos(void) { return _trans.get_row3(3); }
|
|
||||||
MaxEggJoint *ChooseBestChild(LVector3d dir);
|
|
||||||
void ChooseEndPos(double thickness);
|
|
||||||
void CreateMaxBone(CoordinateSystem sys);
|
|
||||||
};
|
|
||||||
|
|
||||||
void MaxEggJoint::GetRotation(LVector3d &xv, LVector3d &yv, LVector3d &zv)
|
|
||||||
{
|
|
||||||
xv = _trans.get_row3(0);
|
|
||||||
yv = _trans.get_row3(1);
|
|
||||||
zv = _trans.get_row3(2);
|
|
||||||
xv.normalize();
|
|
||||||
yv.normalize();
|
|
||||||
zv = xv.cross(yv);
|
|
||||||
zv.normalize();
|
|
||||||
yv = zv.cross(xv);
|
|
||||||
}
|
|
||||||
|
|
||||||
MaxEggJoint *MaxEggLoader::FindJoint(EggGroup *joint)
|
|
||||||
{
|
|
||||||
if (joint==0) return 0;
|
|
||||||
return _joint_tab[joint];
|
|
||||||
}
|
|
||||||
|
|
||||||
MaxEggJoint *MaxEggLoader::MakeJoint(EggGroup *joint, EggGroup *context)
|
|
||||||
{
|
|
||||||
MaxEggJoint *parent = FindJoint(context);
|
|
||||||
MaxEggJoint *result = new MaxEggJoint;
|
|
||||||
LMatrix4d t = joint->get_transform3d();
|
|
||||||
if (parent) {
|
|
||||||
result->_trans = t * parent->_trans;
|
|
||||||
} else {
|
|
||||||
result->_trans = t;
|
|
||||||
}
|
|
||||||
result->_endpos = LVector3d(0,0,0);
|
|
||||||
result->_perp = LVector3d(0,0,0);
|
|
||||||
result->_thickness = 0.0;
|
|
||||||
result->_inskin = 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(LVector3d dir)
|
|
||||||
{
|
|
||||||
if (dir.length() < 0.001) return 0;
|
|
||||||
dir.normalize();
|
|
||||||
double firstbest = -1000;
|
|
||||||
MaxEggJoint *firstchild = 0;
|
|
||||||
LVector3d firstpos = GetPos();
|
|
||||||
double secondbest = 0;
|
|
||||||
for (int i=0; i<_children.size(); i++) {
|
|
||||||
MaxEggJoint *child = _children[i];
|
|
||||||
LVector3d tryfwd = child->GetPos() - GetPos();
|
|
||||||
if ((child->GetPos() != firstpos) && (tryfwd.length() > 0.001)) {
|
|
||||||
LVector3d trydir = tryfwd;
|
|
||||||
trydir.normalize();
|
|
||||||
double quality = trydir.dot(dir);
|
|
||||||
if (quality > firstbest) {
|
|
||||||
secondbest = firstbest;
|
|
||||||
firstbest = quality;
|
|
||||||
firstpos = child->GetPos();
|
|
||||||
firstchild = child;
|
|
||||||
} else if (quality > secondbest) {
|
|
||||||
secondbest = quality;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (firstbest > secondbest + 0.1)
|
|
||||||
return firstchild;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaxEggJoint::ChooseEndPos(double thickness)
|
|
||||||
{
|
|
||||||
LVector3d parentpos(0,0,0);
|
|
||||||
LVector3d parentendpos(0,0,1);
|
|
||||||
if (_parent) {
|
|
||||||
parentpos = _parent->GetPos();
|
|
||||||
parentendpos = _parent->_endpos;
|
|
||||||
}
|
|
||||||
LVector3d fwd = GetPos() - parentpos;
|
|
||||||
if (fwd.length() < 0.001) {
|
|
||||||
fwd = parentendpos - parentpos;
|
|
||||||
}
|
|
||||||
fwd.normalize();
|
|
||||||
MaxEggJoint *child = ChooseBestChild(fwd);
|
|
||||||
if (child == 0) {
|
|
||||||
_endpos = fwd * thickness * 0.8 + GetPos();
|
|
||||||
_thickness = thickness * 0.8;
|
|
||||||
} else {
|
|
||||||
_endpos = child->GetPos();
|
|
||||||
_thickness = (_endpos - GetPos()).length();
|
|
||||||
if (_thickness > thickness) _thickness = thickness;
|
|
||||||
}
|
|
||||||
LVector3d orient = _endpos - GetPos();
|
|
||||||
orient.normalize();
|
|
||||||
LVector3d altaxis = orient.cross(LVector3d(0,-1,0));
|
|
||||||
if (altaxis.length() < 0.001) altaxis = orient.cross(LVector3d(0,0,1));
|
|
||||||
_perp = altaxis.cross(orient);
|
|
||||||
_perp.normalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaxEggJoint::CreateMaxBone(CoordinateSystem sys)
|
|
||||||
{
|
|
||||||
LVector3d rxv,ryv,rzv;
|
|
||||||
GetRotation(rxv, ryv, rzv);
|
|
||||||
Point3 xv(ConvertCoordSys(sys, rxv));
|
|
||||||
Point3 yv(ConvertCoordSys(sys, ryv));
|
|
||||||
Point3 zv(ConvertCoordSys(sys, rzv));
|
|
||||||
Point3 pos(ConvertCoordSys(sys, GetPos()));
|
|
||||||
Point3 endpos(ConvertCoordSys(sys, _endpos));
|
|
||||||
Point3 tzv(ConvertCoordSys(sys, _perp));
|
|
||||||
|
|
||||||
Point3 fwd = endpos - pos;
|
|
||||||
double len = fwd.Length();
|
|
||||||
Point3 txv = fwd * ((float)(1.0/len));
|
|
||||||
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);
|
|
||||||
Matrix3 oomat(row1,row2,row3,Point3(0,0,0));
|
|
||||||
Quat ooquat(oomat);
|
|
||||||
_bone = (SimpleObject2*)CreateInstance(GEOMOBJECT_CLASS_ID, BONE_OBJ_CLASSID);
|
|
||||||
_node = GetCOREInterface()->CreateObjectNode(_bone);
|
|
||||||
_node->SetNodeTM(0, Matrix3(xv, yv, zv, pos));
|
|
||||||
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()));
|
|
||||||
_node->SetObjOffsetRot(ooquat);
|
|
||||||
if (_parent) {
|
|
||||||
_node->Detach(0, 1);
|
|
||||||
_parent->_node->AttachChild(_node, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// MaxEggMesh
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef pair<double, EggGroup *> MaxEggWeight;
|
|
||||||
|
|
||||||
struct MaxEggVertex
|
|
||||||
{
|
|
||||||
Vertexd _pos;
|
|
||||||
Normald _normal;
|
|
||||||
vector<MaxEggWeight> _weights;
|
|
||||||
int _index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MEV_Compare: public stl_hash_compare<MaxEggVertex>
|
|
||||||
{
|
|
||||||
size_t operator()(const MaxEggVertex &key) const
|
|
||||||
{
|
|
||||||
return key._pos.add_hash(key._normal.get_hash());
|
|
||||||
}
|
|
||||||
bool operator()(const MaxEggVertex &k1, const MaxEggVertex &k2) const
|
|
||||||
{
|
|
||||||
int n = k1._pos.compare_to(k2._pos);
|
|
||||||
if (n < 0) return true;
|
|
||||||
if (n > 0) return false;
|
|
||||||
n = k1._normal.compare_to(k2._normal);
|
|
||||||
if (n < 0) return true;
|
|
||||||
if (n > 0) return false;
|
|
||||||
n = k1._weights.size() - k2._weights.size();
|
|
||||||
if (n < 0) return true;
|
|
||||||
if (n > 0) return false;
|
|
||||||
for (int i=0; i<k1._weights.size(); i++) {
|
|
||||||
double d = k1._weights[i].first - k2._weights[i].first;
|
|
||||||
if (d < 0) return true;
|
|
||||||
if (d > 0) return false;
|
|
||||||
EggGroup *g1 = k1._weights[i].second;
|
|
||||||
EggGroup *g2 = k2._weights[i].second;
|
|
||||||
if (g1 < g2) return true;
|
|
||||||
if (g1 > g2) return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef phash_set<MaxEggVertex, MEV_Compare> VertTable;
|
|
||||||
typedef phash_map<TexCoordd, int> TVertTable;
|
|
||||||
typedef phash_map<Colorf, int> CVertTable;
|
|
||||||
|
|
||||||
class MaxEggMesh
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
string _name;
|
|
||||||
TriObject *_obj;
|
|
||||||
Mesh *_mesh;
|
|
||||||
INode *_node;
|
|
||||||
IDerivedObject *_dobj;
|
|
||||||
Modifier *_skin_mod;
|
|
||||||
ISkin *_iskin;
|
|
||||||
ISkinImportData *_iskin_import;
|
|
||||||
int _vert_count;
|
|
||||||
int _tvert_count;
|
|
||||||
int _cvert_count;
|
|
||||||
int _face_count;
|
|
||||||
|
|
||||||
VertTable _vert_tab;
|
|
||||||
TVertTable _tvert_tab;
|
|
||||||
CVertTable _cvert_tab;
|
|
||||||
|
|
||||||
int GetVert(EggVertex *vert, EggGroup *context, CoordinateSystem sys);
|
|
||||||
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, int tex);
|
|
||||||
EggGroup *GetControlJoint(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CTRLJOINT_DEFORM ((EggGroup*)((char*)(-1)))
|
|
||||||
|
|
||||||
int MaxEggMesh::GetVert(EggVertex *vert, EggGroup *context, CoordinateSystem sys)
|
|
||||||
{
|
|
||||||
MaxEggVertex vtx;
|
|
||||||
vtx._pos = vert->get_pos3();
|
|
||||||
vtx._normal = vert->get_normal();
|
|
||||||
vtx._index = 0;
|
|
||||||
|
|
||||||
EggVertex::GroupRef::const_iterator gri;
|
|
||||||
for (gri = vert->gref_begin(); gri != vert->gref_end(); ++gri) {
|
|
||||||
EggGroup *egg_joint = (*gri);
|
|
||||||
double membership = egg_joint->get_vertex_membership(vert);
|
|
||||||
vtx._weights.push_back(MaxEggWeight(membership, egg_joint));
|
|
||||||
}
|
|
||||||
if (vtx._weights.size()==0) {
|
|
||||||
if (context != 0)
|
|
||||||
vtx._weights.push_back(MaxEggWeight(1.0, context));
|
|
||||||
}
|
|
||||||
|
|
||||||
VertTable::const_iterator vti = _vert_tab.find(vtx);
|
|
||||||
if (vti != _vert_tab.end())
|
|
||||||
return vti->_index;
|
|
||||||
|
|
||||||
if (_vert_count == _mesh->numVerts) {
|
|
||||||
int nsize = _vert_count*2 + 100;
|
|
||||||
_mesh->setNumVerts(nsize, _vert_count?TRUE:FALSE);
|
|
||||||
}
|
|
||||||
vtx._index = _vert_count++;
|
|
||||||
_vert_tab.insert(vtx);
|
|
||||||
_mesh->setVert(vtx._index, ConvertCoordSys(sys, vtx._pos));
|
|
||||||
return vtx._index;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MaxEggMesh::GetTVert(TexCoordd uv)
|
|
||||||
{
|
|
||||||
if (_tvert_tab.count(uv))
|
|
||||||
return _tvert_tab[uv];
|
|
||||||
if (_tvert_count == _mesh->numTVerts) {
|
|
||||||
int nsize = _tvert_count*2 + 100;
|
|
||||||
_mesh->setNumTVerts(nsize, _tvert_count?TRUE:FALSE);
|
|
||||||
}
|
|
||||||
int idx = _tvert_count++;
|
|
||||||
_mesh->setTVert(idx, uv.get_x(), uv.get_y(), 0.0);
|
|
||||||
_tvert_tab[uv] = idx;
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MaxEggMesh::GetCVert(Colorf col)
|
|
||||||
{
|
|
||||||
if (_cvert_tab.count(col))
|
|
||||||
return _cvert_tab[col];
|
|
||||||
if (_cvert_count == _mesh->numCVerts) {
|
|
||||||
int nsize = _cvert_count*2 + 100;
|
|
||||||
_mesh->setNumVertCol(nsize, _cvert_count?TRUE:FALSE);
|
|
||||||
}
|
|
||||||
int idx = _cvert_count++;
|
|
||||||
_mesh->vertCol[idx] = Point3(col.get_x(), col.get_y(), col.get_z());
|
|
||||||
_cvert_tab[col] = idx;
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
MaxEggMesh *MaxEggLoader::GetMesh(EggVertexPool *pool)
|
|
||||||
{
|
|
||||||
MaxEggMesh *result = _mesh_tab[pool];
|
|
||||||
if (result == 0) {
|
|
||||||
string name = pool->get_name();
|
|
||||||
int nsize = name.size();
|
|
||||||
if ((nsize > 6) && (name.rfind(".verts")==(nsize-6)))
|
|
||||||
name.resize(nsize-6);
|
|
||||||
result = new MaxEggMesh;
|
|
||||||
result->_name = name;
|
|
||||||
result->_obj = CreateNewTriObject();
|
|
||||||
result->_mesh = &result->_obj->GetMesh();
|
|
||||||
result->_mesh->setMapSupport(0, TRUE);
|
|
||||||
result->_node = GetCOREInterface()->CreateObjectNode(result->_obj);
|
|
||||||
result->_dobj = 0;
|
|
||||||
result->_skin_mod = 0;
|
|
||||||
result->_iskin = 0;
|
|
||||||
result->_iskin_import = 0;
|
|
||||||
result->_vert_count = 0;
|
|
||||||
result->_tvert_count = 0;
|
|
||||||
result->_cvert_count = 0;
|
|
||||||
result->_face_count = 0;
|
|
||||||
result->_node->SetName((TCHAR*)(name.c_str()));
|
|
||||||
_mesh_tab[pool] = result;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MaxEggMesh::AddFace(int v0, int v1, int v2, int tv0, int tv1, int tv2, int cv0, int cv1, int cv2, int tex)
|
|
||||||
{
|
|
||||||
static int dump = 0;
|
|
||||||
if (_face_count == _mesh->numFaces) {
|
|
||||||
int nsize = _face_count*2 + 100;
|
|
||||||
BOOL keep = _mesh->numFaces ? TRUE:FALSE;
|
|
||||||
_mesh->setNumFaces(nsize, keep);
|
|
||||||
_mesh->setNumTVFaces(nsize, keep, _face_count);
|
|
||||||
_mesh->setNumVCFaces(nsize, keep, _face_count);
|
|
||||||
}
|
|
||||||
int idx = _face_count++;
|
|
||||||
_mesh->faces[idx].setVerts(v0,v1,v2);
|
|
||||||
_mesh->faces[idx].smGroup = 1;
|
|
||||||
_mesh->faces[idx].flags = EDGE_ALL | HAS_TVERTS;
|
|
||||||
_mesh->faces[idx].setMatID(tex);
|
|
||||||
_mesh->tvFace[idx].setTVerts(tv0,tv1,tv2);
|
|
||||||
_mesh->vcFace[idx].setTVerts(cv0,cv1,cv2);
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
EggGroup *MaxEggMesh::GetControlJoint(void)
|
|
||||||
{
|
|
||||||
EggGroup *result;
|
|
||||||
VertTable::const_iterator vert = _vert_tab.begin();
|
|
||||||
if (vert == _vert_tab.end()) return 0;
|
|
||||||
switch (vert->_weights.size()) {
|
|
||||||
case 0:
|
|
||||||
for (++vert; vert != _vert_tab.end(); ++vert)
|
|
||||||
if (vert->_weights.size() != 0)
|
|
||||||
return CTRLJOINT_DEFORM;
|
|
||||||
return 0;
|
|
||||||
case 1:
|
|
||||||
result = vert->_weights[0].second;
|
|
||||||
for (++vert; vert != _vert_tab.end(); ++vert)
|
|
||||||
if ((vert->_weights.size() != 1) || (vert->_weights[0].second != result))
|
|
||||||
return CTRLJOINT_DEFORM;
|
|
||||||
return result;
|
|
||||||
default:
|
|
||||||
return CTRLJOINT_DEFORM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaxEggLoader::CreateSkinModifier(MaxEggMesh *M)
|
|
||||||
{
|
|
||||||
vector <MaxEggJoint *> joints;
|
|
||||||
|
|
||||||
M->_dobj = CreateDerivedObject(M->_obj);
|
|
||||||
M->_node->SetObjectRef(M->_dobj);
|
|
||||||
M->_skin_mod = (Modifier*)CreateInstance(OSM_CLASS_ID, SKIN_CLASSID);
|
|
||||||
M->_iskin = (ISkin*)M->_skin_mod->GetInterface(I_SKIN);
|
|
||||||
M->_iskin_import = (ISkinImportData*)M->_skin_mod->GetInterface(I_SKINIMPORTDATA);
|
|
||||||
M->_dobj->SetAFlag(A_LOCK_TARGET);
|
|
||||||
M->_dobj->AddModifier(M->_skin_mod);
|
|
||||||
M->_dobj->ClearAFlag(A_LOCK_TARGET);
|
|
||||||
GetCOREInterface()->ForceCompleteRedraw();
|
|
||||||
|
|
||||||
VertTable::const_iterator vert;
|
|
||||||
for (vert=M->_vert_tab.begin(); vert != M->_vert_tab.end(); ++vert) {
|
|
||||||
for (int i=0; i<vert->_weights.size(); i++) {
|
|
||||||
double strength = vert->_weights[i].first;
|
|
||||||
MaxEggJoint *joint = FindJoint(vert->_weights[i].second);
|
|
||||||
if (!joint->_inskin) {
|
|
||||||
joint->_inskin = true;
|
|
||||||
joints.push_back(joint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i=0; i<joints.size(); i++) {
|
|
||||||
BOOL last = (i == (joints.size()-1)) ? TRUE : FALSE;
|
|
||||||
M->_iskin_import->AddBoneEx(joints[i]->_node, last);
|
|
||||||
joints[i]->_inskin = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetCOREInterface()->SetCommandPanelTaskMode(TASK_MODE_MODIFY);
|
|
||||||
GetCOREInterface()->SelectNode(M->_node);
|
|
||||||
GetCOREInterface()->ForceCompleteRedraw();
|
|
||||||
|
|
||||||
for (vert=M->_vert_tab.begin(); vert != M->_vert_tab.end(); ++vert) {
|
|
||||||
Tab<INode*> maxJoints;
|
|
||||||
Tab<float> maxWeights;
|
|
||||||
maxJoints.ZeroCount();
|
|
||||||
maxWeights.ZeroCount();
|
|
||||||
for (int i=0; i<vert->_weights.size(); i++) {
|
|
||||||
float strength = (float)(vert->_weights[i].first);
|
|
||||||
MaxEggJoint *joint = FindJoint(vert->_weights[i].second);
|
|
||||||
maxWeights.Append(1,&strength);
|
|
||||||
maxJoints.Append(1,&(joint->_node));
|
|
||||||
}
|
|
||||||
M->_iskin_import->AddWeights(M->_node, vert->_index, maxJoints, maxWeights);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TraverseEggData
|
|
||||||
//
|
|
||||||
// We have an EggData in memory, and now we're going to copy that
|
|
||||||
// over into the max scene graph.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void MaxEggLoader::TraverseEggNode(EggNode *node, EggGroup *context)
|
|
||||||
{
|
|
||||||
vector<int> vertIndices;
|
|
||||||
vector<int> tvertIndices;
|
|
||||||
vector<int> cvertIndices;
|
|
||||||
|
|
||||||
if (node->is_of_type(EggPolygon::get_class_type())) {
|
|
||||||
EggPolygon *poly = DCAST(EggPolygon, node);
|
|
||||||
|
|
||||||
int texid;
|
|
||||||
LMatrix3d uvtrans = LMatrix3d::ident_mat();
|
|
||||||
if (poly->has_texture()) {
|
|
||||||
EggTexture *tex = poly->get_texture(0);
|
|
||||||
texid = GetTex(tex->get_fullpath().to_os_specific())->_id;
|
|
||||||
if (tex->has_transform())
|
|
||||||
uvtrans = tex->get_transform2d();
|
|
||||||
} else {
|
|
||||||
texid = GetTex("")->_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
EggPolygon::const_iterator ci;
|
|
||||||
MaxEggMesh *mesh = GetMesh(poly->get_pool());
|
|
||||||
vertIndices.clear();
|
|
||||||
tvertIndices.clear();
|
|
||||||
cvertIndices.clear();
|
|
||||||
for (ci = poly->begin(); ci != poly->end(); ++ci) {
|
|
||||||
EggVertex *vtx = (*ci);
|
|
||||||
EggVertexPool *pool = poly->get_pool();
|
|
||||||
TexCoordd uv = vtx->get_uv();
|
|
||||||
vertIndices.push_back(mesh->GetVert(vtx, context, _coord_sys));
|
|
||||||
tvertIndices.push_back(mesh->GetTVert(uv * uvtrans));
|
|
||||||
cvertIndices.push_back(mesh->GetCVert(vtx->get_color()));
|
|
||||||
}
|
|
||||||
for (int i=1; i<vertIndices.size()-1; i++)
|
|
||||||
mesh->AddFace(vertIndices[0], vertIndices[i], vertIndices[i+1],
|
|
||||||
tvertIndices[0], tvertIndices[i], tvertIndices[i+1],
|
|
||||||
cvertIndices[0], cvertIndices[i], cvertIndices[i+1],
|
|
||||||
texid);
|
|
||||||
} else if (node->is_of_type(EggGroupNode::get_class_type())) {
|
|
||||||
EggGroupNode *group = DCAST(EggGroupNode, node);
|
|
||||||
if (node->is_of_type(EggGroup::get_class_type())) {
|
|
||||||
EggGroup *group = DCAST(EggGroup, node);
|
|
||||||
if (group->is_joint()) {
|
|
||||||
MakeJoint(group, context);
|
|
||||||
context = group;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EggGroupNode::const_iterator ci;
|
|
||||||
for (ci = group->begin(); ci != group->end(); ++ci) {
|
|
||||||
TraverseEggNode(*ci, context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MaxEggLoader::ConvertEggData(EggData *data, bool merge, bool model, bool anim)
|
|
||||||
{
|
|
||||||
if (!merge) {
|
|
||||||
maxloader_cat.error() << "Currently, only 'merge' mode is implemented.\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((anim) || (!model)) {
|
|
||||||
maxloader_cat.error() << "Currently, only model-loading is implemented.\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MeshIterator ci;
|
|
||||||
JointIterator ji;
|
|
||||||
TexIterator ti;
|
|
||||||
|
|
||||||
SuspendAnimate();
|
|
||||||
SuspendSetKeyMode();
|
|
||||||
AnimateOff();
|
|
||||||
_next_tex = 0;
|
|
||||||
_coord_sys = data->get_coordinate_system();
|
|
||||||
|
|
||||||
TraverseEggNode(data, NULL);
|
|
||||||
|
|
||||||
for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
|
|
||||||
MaxEggMesh *mesh = (*ci);
|
|
||||||
mesh->_mesh->setNumVerts(mesh->_vert_count, TRUE);
|
|
||||||
mesh->_mesh->setNumTVerts(mesh->_tvert_count, TRUE);
|
|
||||||
mesh->_mesh->setNumVertCol(mesh->_cvert_count, TRUE);
|
|
||||||
mesh->_mesh->setNumFaces(mesh->_face_count, TRUE);
|
|
||||||
mesh->_mesh->setNumTVFaces(mesh->_face_count, TRUE, mesh->_face_count);
|
|
||||||
mesh->_mesh->setNumVCFaces(mesh->_face_count, TRUE, mesh->_face_count);
|
|
||||||
mesh->_mesh->InvalidateTopologyCache();
|
|
||||||
mesh->_mesh->InvalidateGeomCache();
|
|
||||||
mesh->_mesh->buildNormals();
|
|
||||||
}
|
|
||||||
|
|
||||||
double thickness = 0.0;
|
|
||||||
for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
|
|
||||||
double dfo = ((*ji)->GetPos()).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(_coord_sys);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
|
|
||||||
MaxEggMesh *mesh = (*ci);
|
|
||||||
EggGroup *joint = mesh->GetControlJoint();
|
|
||||||
if (joint) CreateSkinModifier(mesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_next_tex) {
|
|
||||||
TSTR name;
|
|
||||||
MultiMtl *mtl = NewDefaultMultiMtl();
|
|
||||||
mtl->SetNumSubMtls(_next_tex);
|
|
||||||
for (ti = _tex_tab.begin(); ti != _tex_tab.end(); ++ti) {
|
|
||||||
MaxEggTex *tex = *ti;
|
|
||||||
mtl->SetSubMtlAndName(tex->_id, tex->_mat, name);
|
|
||||||
}
|
|
||||||
for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
|
|
||||||
MaxEggMesh *mesh = *ci;
|
|
||||||
mesh->_node->SetMtl(mtl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) delete *ci;
|
|
||||||
for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) delete *ji;
|
|
||||||
for (ti = _tex_tab.begin(); ti != _tex_tab.end(); ++ti) delete *ti;
|
|
||||||
|
|
||||||
ResumeSetKeyMode();
|
|
||||||
ResumeAnimate();
|
|
||||||
|
|
||||||
maxloader_cat.info() << "Egg import successful\n";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MaxEggLoader::ConvertEggFile(const char *name, bool merge, bool model, bool anim)
|
|
||||||
{
|
|
||||||
EggData data;
|
|
||||||
Filename datafn = Filename::from_os_specific(name);
|
|
||||||
if (!data.read(datafn)) {
|
|
||||||
maxloader_cat.error() << "Cannot read Egg file for import\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ConvertEggData(&data, merge, model, anim);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The two global functions that form the API of this module.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool MaxLoadEggData(EggData *data, bool merge, bool model, bool anim)
|
|
||||||
{
|
|
||||||
MaxEggLoader loader;
|
|
||||||
return loader.ConvertEggData(data, merge, model, anim);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MaxLoadEggFile(const char *name, bool merge, bool model, bool anim)
|
|
||||||
{
|
|
||||||
MaxEggLoader loader;
|
|
||||||
return loader.ConvertEggFile(name, merge, model, anim);
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
|||||||
// Filename: maxEggLoader.h
|
|
||||||
// Created by: jyelon (15jul05)
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// PANDA 3D SOFTWARE
|
|
||||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
//
|
|
||||||
// All use of this software is subject to the terms of the revised BSD
|
|
||||||
// license. You should have received a copy of this license along
|
|
||||||
// with this source code in a file named "LICENSE."
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef MAXEGGLOADER_H
|
|
||||||
#define MAXEGGLOADER_H
|
|
||||||
|
|
||||||
class EggData;
|
|
||||||
|
|
||||||
bool MaxLoadEggData(EggData *data, bool merge, bool model, bool anim);
|
|
||||||
bool MaxLoadEggFile(const char *name, bool merge, bool model, bool anim);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Visual C++ generated include file.
|
|
||||||
// Used by maxImportRes.rc
|
|
||||||
//
|
|
||||||
#define IDD_PANEL 101
|
|
||||||
#define IDD_ABOUTBOX 102
|
|
||||||
#define IDD_IMPORT_DLG 103
|
|
||||||
#define IDC_MERGE 1002
|
|
||||||
#define IDC_IMPORTMODEL 1003
|
|
||||||
#define IDC_IMPORTANIM 1004
|
|
||||||
|
|
||||||
// Next default values for new objects
|
|
||||||
//
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 105
|
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1020
|
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
|
||||||
#endif
|
|
||||||
#endif
|
|
Binary file not shown.
@ -1,122 +0,0 @@
|
|||||||
// Microsoft Visual C++ generated resource script.
|
|
||||||
//
|
|
||||||
#include "maxImportRes.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "afxres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (U.S.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// DESIGNINFO
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
GUIDELINES DESIGNINFO
|
|
||||||
BEGIN
|
|
||||||
IDD_ABOUTBOX, DIALOG
|
|
||||||
BEGIN
|
|
||||||
LEFTMARGIN, 7
|
|
||||||
RIGHTMARGIN, 176
|
|
||||||
TOPMARGIN, 7
|
|
||||||
BOTTOMMARGIN, 60
|
|
||||||
END
|
|
||||||
|
|
||||||
IDD_IMPORT_DLG, DIALOG
|
|
||||||
BEGIN
|
|
||||||
LEFTMARGIN, 7
|
|
||||||
RIGHTMARGIN, 187
|
|
||||||
TOPMARGIN, 7
|
|
||||||
BOTTOMMARGIN, 71
|
|
||||||
END
|
|
||||||
END
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"maxImportRes.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"#include ""afxres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Dialog
|
|
||||||
//
|
|
||||||
|
|
||||||
IDD_ABOUTBOX DIALOGEX 0, 0, 183, 67
|
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
|
||||||
CAPTION "About Panda3D Egg Importer"
|
|
||||||
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
|
||||||
BEGIN
|
|
||||||
DEFPUSHBUTTON "OK",IDOK,66,45,50,14
|
|
||||||
CTEXT "Panda3D Egg Importer\n\nCarnegie Mellon\nEntertainment Technology Center",
|
|
||||||
IDC_STATIC,7,7,169,36
|
|
||||||
END
|
|
||||||
|
|
||||||
IDD_IMPORT_DLG DIALOGEX 0, 0, 194, 78
|
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
|
||||||
CAPTION "Panda3D Egg Import"
|
|
||||||
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
|
||||||
BEGIN
|
|
||||||
DEFPUSHBUTTON "OK",IDOK,137,10,50,14
|
|
||||||
PUSHBUTTON "Cancel",IDCANCEL,137,30,50,14
|
|
||||||
CONTROL "Merge with Current Scene",IDC_MERGE,"Button",
|
|
||||||
BS_AUTOCHECKBOX | WS_TABSTOP,15,20,106,10
|
|
||||||
GROUPBOX "Input Options",IDC_STATIC,5,7,126,64
|
|
||||||
CONTROL "Import Model",IDC_IMPORTMODEL,"Button",BS_AUTOCHECKBOX |
|
|
||||||
WS_TABSTOP,15,41,73,10
|
|
||||||
CONTROL "Import Animation",IDC_IMPORTANIM,"Button",
|
|
||||||
BS_AUTOCHECKBOX | WS_TABSTOP,15,54,73,10
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // English (U.S.) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user