Bladeren bron

Split off 3ds Max exporter to a separate repository

It now lives at https://github.com/panda3d/max-egg-plugin

See #1584
rdb 1 jaar geleden
bovenliggende
commit
fff9ea594c

+ 0 - 20
makepanda/installer.nsi

@@ -86,7 +86,6 @@ LangString DESC_SecPython ${LANG_ENGLISH} "Contains a ${REGVIEW}-bit copy of Pyt
 LangString DESC_SecEnsurePip ${LANG_ENGLISH} "Installs the pip package manager into the included Python installation."
 LangString DESC_SecHeadersLibs ${LANG_ENGLISH} "Headers and libraries needed for C++ development with Panda3D."
 LangString DESC_SecSamples ${LANG_ENGLISH} "The sample programs demonstrate how to make Python applications with Panda3D."
-LangString DESC_SecMaxPlugins ${LANG_ENGLISH} "Plug-ins for Autodesk 3ds Max (${REGVIEW}-bit) that can be used to export models to Panda3D."
 LangString DESC_SecMayaPlugins ${LANG_ENGLISH} "Plug-ins and scripts for Autodesk Maya (${REGVIEW}-bit) that can be used to export models to Panda3D."
 
 var READABLE
@@ -114,7 +113,6 @@ var READABLE
 !insertmacro !defineifexist HAVE_BULLET "${BUILT}\bin\libpandabullet.dll"
 !insertmacro !defineifexist HAVE_ODE "${BUILT}\bin\libpandaode.dll"
 !insertmacro !defineifexist HAVE_SAMPLES "${SOURCE}\samples"
-!insertmacro !defineifexist HAVE_MAX_PLUGINS "${BUILT}\plugins\*.dlo"
 !insertmacro !defineifexist HAVE_MAYA_PLUGINS "${BUILT}\plugins\*.mll"
 
 !macro RemovePythonPath PYVER
@@ -697,21 +695,6 @@ Section "Sample programs" SecSamples
 SectionEnd
 !endif
 
-!ifdef HAVE_MAX_PLUGINS
-Section "3ds Max plug-ins" SecMaxPlugins
-    SectionIn 1 2
-
-    SetDetailsPrint both
-    DetailPrint "Installing Autodesk 3ds Max plug-ins..."
-    SetDetailsPrint listonly
-
-    SetOutPath $INSTDIR\plugins
-    File /nonfatal /r "${BUILT}\plugins\*.dle"
-    File /nonfatal /r "${BUILT}\plugins\*.dlo"
-    File /nonfatal /r "${BUILT}\plugins\*.ms"
-SectionEnd
-!endif
-
 !ifdef HAVE_MAYA_PLUGINS
 Section "Maya plug-ins" SecMayaPlugins
     SectionIn 1 2
@@ -960,9 +943,6 @@ SectionEnd
   !ifdef HAVE_SAMPLES
     !insertmacro MUI_DESCRIPTION_TEXT ${SecSamples} $(DESC_SecSamples)
   !endif
-  !ifdef HAVE_MAX_PLUGINS
-    !insertmacro MUI_DESCRIPTION_TEXT ${SecMaxPlugins} $(DESC_SecMaxPlugins)
-  !endif
   !ifdef HAVE_MAYA_PLUGINS
     !insertmacro MUI_DESCRIPTION_TEXT ${SecMayaPlugins} $(DESC_SecMayaPlugins)
   !endif

+ 3 - 66
makepanda/makepanda.py

@@ -86,7 +86,7 @@ PkgListSet(["PYTHON", "DIRECT",                        # Python support
   "ODE", "BULLET", "PANDAPHYSICS",                     # Physics
   "SPEEDTREE",                                         # SpeedTree
   "ZLIB", "PNG", "JPEG", "TIFF", "OPENEXR", "SQUISH",  # 2D Formats support
-  ] + MAYAVERSIONS + MAXVERSIONS + [ "FCOLLADA", "ASSIMP", "EGG", # 3D Formats support
+  ] + MAYAVERSIONS + [ "FCOLLADA", "ASSIMP", "EGG",    # 3D Formats support
   "FREETYPE", "HARFBUZZ",                              # Text rendering
   "VRPN", "OPENSSL",                                   # Transport
   "FFTW",                                              # Algorithm helpers
@@ -176,6 +176,8 @@ def parseopts(args):
     removedopts = [
         "use-touchinput", "no-touchinput", "no-awesomium", "no-directscripts",
         "no-carbon", "no-physx", "no-rocket", "host", "osxtarget=",
+        "no-max6", "no-max7", "no-max8", "no-max9", "no-max2009",
+        "no-max2010", "no-max2011", "no-max2012", "no-max2013", "no-max2014",
         ]
 
     # All recognized options.
@@ -521,7 +523,6 @@ MakeBuildTree()
 
 SdkLocateDirectX(STRDXSDKVERSION)
 SdkLocateMaya()
-SdkLocateMax()
 SdkLocateMacOSX(OSX_ARCHS)
 SdkLocatePython(False)
 SdkLocateWindows(WINDOWS_SDK)
@@ -530,7 +531,6 @@ SdkLocateAndroid()
 
 SdkAutoDisableDirectX()
 SdkAutoDisableMaya()
-SdkAutoDisableMax()
 SdkAutoDisableSpeedTree()
 
 if not PkgSkip("PYTHON") and SDK["PYTHONVERSION"] == "python2.7":
@@ -585,15 +585,6 @@ if (COMPILER == "MSVC"):
                 IncDirectory(pkg, SDK[pkg]      + "/include")
                 DefSymbol(pkg, "MAYAVERSION", pkg)
                 DefSymbol(pkg, "MLIBRARY_DONTUSE_MFC_MANIFEST", "")
-            elif (pkg[:3]=="MAX"):
-                IncDirectory(pkg, SDK[pkg]      + "/include")
-                IncDirectory(pkg, SDK[pkg]      + "/include/CS")
-                IncDirectory(pkg, SDK[pkg+"CS"] + "/include")
-                IncDirectory(pkg, SDK[pkg+"CS"] + "/include/CS")
-                DefSymbol(pkg, "MAX", pkg)
-                if (int(pkg[3:]) >= 2013):
-                    DefSymbol(pkg, "UNICODE", "")
-                    DefSymbol(pkg, "_UNICODE", "")
             elif (pkg[:2]=="DX"):
                 IncDirectory(pkg, SDK[pkg]      + "/include")
             elif GetThirdpartyDir() is not None:
@@ -776,15 +767,6 @@ if (COMPILER == "MSVC"):
             LibName(pkg, '"' + SDK[pkg] + '/lib/OpenMaya.lib"')
             LibName(pkg, '"' + SDK[pkg] + '/lib/OpenMayaAnim.lib"')
             LibName(pkg, '"' + SDK[pkg] + '/lib/OpenMayaUI.lib"')
-    for pkg in MAXVERSIONS:
-        if not PkgSkip(pkg):
-            LibName(pkg, SDK[pkg] +  '/lib/core.lib')
-            LibName(pkg, SDK[pkg] +  '/lib/edmodel.lib')
-            LibName(pkg, SDK[pkg] +  '/lib/gfx.lib')
-            LibName(pkg, SDK[pkg] +  '/lib/geom.lib')
-            LibName(pkg, SDK[pkg] +  '/lib/mesh.lib')
-            LibName(pkg, SDK[pkg] +  '/lib/maxutil.lib')
-            LibName(pkg, SDK[pkg] +  '/lib/paramblk2.lib')
 
     if not PkgSkip("SPEEDTREE"):
         if GetTargetArch() == 'x64':
@@ -3293,8 +3275,6 @@ if not PkgSkip("PANDATOOL"):
 if not PkgSkip("PYTHON") and os.path.isdir(GetThirdpartyBase() + "/Pmw"):
     CopyTree(GetOutputDir() + "/Pmw", GetThirdpartyBase() + "/Pmw", exclude=["Pmw_1_3", "Pmw_1_3_3"])
 
-ConditionalWriteFile(GetOutputDir()+'/include/ctl3d.h', '/* dummy file to make MAX happy */')
-
 # Since Eigen is included by all sorts of core headers, as a convenience
 # to C++ users on Win and Mac, we include it in the Panda include directory.
 if not PkgSkip("EIGEN") and GetTarget() in ("windows", "darwin") and GetThirdpartyDir():
@@ -3459,8 +3439,6 @@ if not PkgSkip("PANDATOOL"):
     CopyAllHeaders('pandatool/src/lwoprogs')
     CopyAllHeaders('pandatool/src/maya')
     CopyAllHeaders('pandatool/src/mayaegg')
-    CopyAllHeaders('pandatool/src/maxegg')
-    CopyAllHeaders('pandatool/src/maxprogs')
     CopyAllHeaders('pandatool/src/objegg')
     CopyAllHeaders('pandatool/src/objprogs')
     CopyAllHeaders('pandatool/src/vrml')
@@ -5790,47 +5768,6 @@ for VER in MAYAVERSIONS:
     TargetAdd('libmayaegg'+VNUM+'.lib', input='mayaegg'+VNUM+'_loader.obj')
     TargetAdd('libmayaegg'+VNUM+'.lib', input='mayaegg'+VNUM+'_composite1.obj')
 
-#
-# DIRECTORY: pandatool/src/maxegg/
-#
-
-for VER in MAXVERSIONS:
-    VNUM = VER[3:]
-    if PkgSkip(VER) or PkgSkip("PANDATOOL") or PkgSkip("EGG"):
-        continue
-
-    OPTS=['DIR:pandatool/src/maxegg', VER,  "WINCOMCTL", "WINCOMDLG", "WINUSER", "MSFORSCOPE", "RTTI"]
-    TargetAdd('maxEgg'+VNUM+'.res', opts=OPTS, input='maxEgg.rc')
-    TargetAdd('maxegg'+VNUM+'_loader.obj', opts=OPTS, input='maxEggLoader.cxx')
-    TargetAdd('maxegg'+VNUM+'_composite1.obj', opts=OPTS, input='p3maxegg_composite1.cxx')
-    TargetAdd('maxegg'+VNUM+'.dlo', input='maxegg'+VNUM+'_composite1.obj')
-    TargetAdd('maxegg'+VNUM+'.dlo', input='maxEgg'+VNUM+'.res')
-    TargetAdd('maxegg'+VNUM+'.dlo', input='maxEgg.def', ipath=OPTS)
-    TargetAdd('maxegg'+VNUM+'.dlo', input=COMMON_EGG2X_LIBS)
-    TargetAdd('maxegg'+VNUM+'.dlo', opts=OPTS)
-
-#
-# DIRECTORY: pandatool/src/maxprogs/
-#
-
-for VER in MAXVERSIONS:
-    VNUM = VER[3:]
-    if PkgSkip(VER) or PkgSkip("PANDATOOL") or PkgSkip("EGG"):
-        continue
-
-    OPTS=['DIR:pandatool/src/maxprogs', VER,  "WINCOMCTL", "WINCOMDLG", "WINUSER", "MSFORSCOPE", "RTTI"]
-    TargetAdd('maxImportRes.res', opts=OPTS, input='maxImportRes.rc')
-    TargetAdd('maxprogs'+VNUM+'_maxeggimport.obj', opts=OPTS, input='maxEggImport.cxx')
-    TargetAdd('maxeggimport'+VNUM+'.dle', input='maxegg'+VNUM+'_loader.obj')
-    TargetAdd('maxeggimport'+VNUM+'.dle', input='maxprogs'+VNUM+'_maxeggimport.obj')
-    TargetAdd('maxeggimport'+VNUM+'.dle', input='libpandaegg.dll')
-    TargetAdd('maxeggimport'+VNUM+'.dle', input='libpanda.dll')
-    TargetAdd('maxeggimport'+VNUM+'.dle', input='libpandaexpress.dll')
-    TargetAdd('maxeggimport'+VNUM+'.dle', input='maxImportRes.res')
-    TargetAdd('maxeggimport'+VNUM+'.dle', input='maxEggImport.def', ipath=OPTS)
-    TargetAdd('maxeggimport'+VNUM+'.dle', input=COMMON_DTOOL_LIBS)
-    TargetAdd('maxeggimport'+VNUM+'.dle', opts=OPTS)
-
 #
 # DIRECTORY: pandatool/src/vrml/
 #

+ 0 - 41
makepanda/makepandacore.py

@@ -120,28 +120,12 @@ MAYAVERSIONINFO = [("MAYA6",   "6.0"),
                    ("MAYA2022","2022"),
 ]
 
-MAXVERSIONINFO = [("MAX6", "SOFTWARE\\Autodesk\\3DSMAX\\6.0", "installdir", "maxsdk\\cssdk\\include"),
-                  ("MAX7", "SOFTWARE\\Autodesk\\3DSMAX\\7.0", "Installdir", "maxsdk\\include\\CS"),
-                  ("MAX8", "SOFTWARE\\Autodesk\\3DSMAX\\8.0", "Installdir", "maxsdk\\include\\CS"),
-                  ("MAX9", "SOFTWARE\\Autodesk\\3DSMAX\\9.0", "Installdir", "maxsdk\\include\\CS"),
-                  ("MAX2009", "SOFTWARE\\Autodesk\\3DSMAX\\11.0\\MAX-1:409", "Installdir", "maxsdk\\include\\CS"),
-                  ("MAX2010", "SOFTWARE\\Autodesk\\3DSMAX\\12.0\\MAX-1:409", "Installdir", "maxsdk\\include\\CS"),
-                  ("MAX2011", "SOFTWARE\\Autodesk\\3DSMAX\\13.0\\MAX-1:409", "Installdir", "maxsdk\\include\\CS"),
-                  ("MAX2012", "SOFTWARE\\Autodesk\\3DSMAX\\14.0\\MAX-1:409", "Installdir", "maxsdk\\include\\CS"),
-                  ("MAX2013", "SOFTWARE\\Autodesk\\3DSMAX\\15.0\\MAX-1:409", "Installdir", "maxsdk\\include\\CS"),
-                  ("MAX2014", "SOFTWARE\\Autodesk\\3DSMAX\\16.0\\MAX-1:409", "Installdir", "maxsdk\\include\\CS"),
-]
-
 MAYAVERSIONS = []
-MAXVERSIONS = []
 DXVERSIONS = ["DX9"]
 
 for (ver,key) in MAYAVERSIONINFO:
     MAYAVERSIONS.append(ver)
 
-for (ver,key1,key2,subdir) in MAXVERSIONINFO:
-    MAXVERSIONS.append(ver)
-
 ########################################################################
 ##
 ## Potentially Conflicting Files
@@ -2158,20 +2142,6 @@ def SdkLocateMaya():
                     if (os.path.isdir(ddir1)):   SDK[ver] = ddir1
                     elif (os.path.isdir(ddir2)): SDK[ver] = ddir2
 
-def SdkLocateMax():
-    if (GetHost() != "windows"): return
-    for version,key1,key2,subdir in MAXVERSIONINFO:
-        if (PkgSkip(version)==0):
-            if (version not in SDK):
-                GetSdkDir("maxsdk"+version.lower()[3:], version)
-                GetSdkDir("maxsdk"+version.lower()[3:], version+"CS")
-                if (not version in SDK):
-                    top = GetRegistryKey(key1,key2)
-                    if (top != 0):
-                        SDK[version] = top + "maxsdk"
-                        if (os.path.isdir(top + "\\" + subdir)!=0):
-                            SDK[version+"CS"] = top + subdir
-
 def SdkLocatePython(prefer_thirdparty_python=False):
     if PkgSkip("PYTHON"):
         # We're not compiling with Python support.  We still need to set this
@@ -2727,17 +2697,6 @@ def SdkAutoDisableMaya():
             WARNINGS.append("I have automatically added this command-line option: --no-"+ver.lower())
             PkgDisable(ver)
 
-def SdkAutoDisableMax():
-    for version,key1,key2,subdir in MAXVERSIONINFO:
-        if (PkgSkip(version)==0) and ((version not in SDK) or (version+"CS" not in SDK)):
-            if (GetHost() == "windows"):
-                if (version in SDK):
-                    WARNINGS.append("Your copy of "+version+" does not include the character studio SDK")
-                else:
-                    WARNINGS.append("The registry does not appear to contain a pointer to "+version)
-                WARNINGS.append("I have automatically added this command-line option: --no-"+version.lower())
-            PkgDisable(version)
-
 def SdkAutoDisableSpeedTree():
     if ("SPEEDTREE" not in SDK) and (PkgSkip("SPEEDTREE")==0):
         PkgDisable("SPEEDTREE")

+ 0 - 860
pandatool/src/maxegg/maxEgg.cxx

@@ -1,860 +0,0 @@
-/**
- * @file maxEgg.cxx
- * @author Steven "Sauce" Osman
- * @date 2003-01
- * @author Ken Strickland
- * @date 2003-02-25
- *
- * This file implements the classes that are used in the Panda 3D file
- * exporter for 3D Studio Max.
- */
-
-#include "maxEgg.h"
-
-
-const double meshVerts[252][3] = {
-    {0.729464, -0.919852, 0.714986},
-    {0.466137, -0.594656, 0.160201},
-    {-0.265897, -1.14704, 0.714986},
-    {0.466137, -0.594656, 0.160201},
-    {-0.177333, -0.741523, 0.160201},
-    {-0.265897, -1.14704, 0.714986},
-    {-0.265897, -1.14704, 0.714986},
-    {-0.177333, -0.741523, 0.160201},
-    {-1.06411, -0.510479, 0.714986},
-    {-0.177333, -0.741523, 0.160201},
-    {-0.693356, -0.330009, 0.160201},
-    {-1.06411, -0.510479, 0.714986},
-    {-1.06411, 0.510479, 0.714986},
-    {-1.06411, -0.510479, 0.714986},
-    {-0.693356, 0.330009, 0.160201},
-    {-0.693356, -0.330009, 0.160201},
-    {-0.693356, 0.330009, 0.160201},
-    {-1.06411, -0.510479, 0.714986},
-    {-0.265897, 1.14704, 0.714986},
-    {-1.06411, 0.510479, 0.714986},
-    {-0.177333, 0.741523, 0.160201},
-    {-0.693356, 0.330009, 0.160201},
-    {-0.177333, 0.741523, 0.160201},
-    {-1.06411, 0.510479, 0.714986},
-    {0.729464, 0.919852, 0.714986},
-    {-0.265897, 1.14704, 0.714986},
-    {0.466137, 0.594656, 0.160201},
-    {-0.177333, 0.741523, 0.160201},
-    {0.466137, 0.594656, 0.160201},
-    {-0.265897, 1.14704, 0.714986},
-    {1.17244, 0.0, 0.714986},
-    {0.729464, 0.919852, 0.714986},
-    {0.752508, 0.0, 0.160201},
-    {0.466137, 0.594656, 0.160201},
-    {0.752508, 0.0, 0.160201},
-    {0.729464, 0.919852, 0.714986},
-    {0.729464, -0.919852, 0.714986},
-    {1.17244, 0.0, 0.714986},
-    {0.466137, -0.594656, 0.160201},
-    {0.752508, 0.0, 0.160201},
-    {0.466137, -0.594656, 0.160201},
-    {1.17244, 0.0, 0.714986},
-    {-0.286334, -1.26822, 1.44995},
-    {0.814187, -1.01703, 1.44995},
-    {-0.265897, -1.14704, 0.714986},
-    {0.729464, -0.919852, 0.714986},
-    {-0.265897, -1.14704, 0.714986},
-    {0.814187, -1.01703, 1.44995},
-    {-1.16888, -0.564412, 1.44995},
-    {-0.286334, -1.26822, 1.44995},
-    {-1.06411, -0.510479, 0.714986},
-    {-0.265897, -1.14704, 0.714986},
-    {-1.06411, -0.510479, 0.714986},
-    {-0.286334, -1.26822, 1.44995},
-    {-1.16888, 0.564411, 1.44995},
-    {-1.16888, -0.564412, 1.44995},
-    {-1.06411, 0.510479, 0.714986},
-    {-1.06411, -0.510479, 0.714986},
-    {-1.06411, 0.510479, 0.714986},
-    {-1.16888, -0.564412, 1.44995},
-    {-1.16888, 0.564411, 1.44995},
-    {-1.06411, 0.510479, 0.714986},
-    {-0.286334, 1.26822, 1.44995},
-    {-1.06411, 0.510479, 0.714986},
-    {-0.265897, 1.14704, 0.714986},
-    {-0.286334, 1.26822, 1.44995},
-    {-0.286334, 1.26822, 1.44995},
-    {-0.265897, 1.14704, 0.714986},
-    {0.814187, 1.01703, 1.44995},
-    {-0.265897, 1.14704, 0.714986},
-    {0.729464, 0.919852, 0.714986},
-    {0.814187, 1.01703, 1.44995},
-    {1.30396, 0.0, 1.44995},
-    {0.814187, 1.01703, 1.44995},
-    {1.17244, 0.0, 0.714986},
-    {0.729464, 0.919852, 0.714986},
-    {1.17244, 0.0, 0.714986},
-    {0.814187, 1.01703, 1.44995},
-    {1.30396, 0.0, 1.44995},
-    {1.17244, 0.0, 0.714986},
-    {0.814187, -1.01703, 1.44995},
-    {1.17244, 0.0, 0.714986},
-    {0.729464, -0.919852, 0.714986},
-    {0.814187, -1.01703, 1.44995},
-    {-0.286334, -1.26822, 1.44995},
-    {-0.227573, -1.05763, 2.16723},
-    {0.814187, -1.01703, 1.44995},
-    {0.814187, -1.01703, 1.44995},
-    {-0.227573, -1.05763, 2.16723},
-    {0.690208, -0.848157, 2.16723},
-    {-1.16888, -0.564412, 1.44995},
-    {-0.963577, -0.470692, 2.16723},
-    {-0.286334, -1.26822, 1.44995},
-    {-0.286334, -1.26822, 1.44995},
-    {-0.963577, -0.470692, 2.16723},
-    {-0.227573, -1.05763, 2.16723},
-    {-1.16888, -0.564412, 1.44995},
-    {-1.16888, 0.564411, 1.44995},
-    {-0.963577, -0.470692, 2.16723},
-    {-1.16888, 0.564411, 1.44995},
-    {-0.963577, 0.470692, 2.16723},
-    {-0.963577, -0.470692, 2.16723},
-    {-1.16888, 0.564411, 1.44995},
-    {-0.286334, 1.26822, 1.44995},
-    {-0.963577, 0.470692, 2.16723},
-    {-0.286334, 1.26822, 1.44995},
-    {-0.227574, 1.05763, 2.16723},
-    {-0.963577, 0.470692, 2.16723},
-    {-0.286334, 1.26822, 1.44995},
-    {0.814187, 1.01703, 1.44995},
-    {-0.227574, 1.05763, 2.16723},
-    {0.814187, 1.01703, 1.44995},
-    {0.690208, 0.848157, 2.16723},
-    {-0.227574, 1.05763, 2.16723},
-    {0.814187, 1.01703, 1.44995},
-    {1.30396, 0.0, 1.44995},
-    {0.690208, 0.848157, 2.16723},
-    {1.30396, 0.0, 1.44995},
-    {1.09866, 0.0, 2.16723},
-    {0.690208, 0.848157, 2.16723},
-    {0.814187, -1.01703, 1.44995},
-    {0.690208, -0.848157, 2.16723},
-    {1.30396, 0.0, 1.44995},
-    {1.30396, 0.0, 1.44995},
-    {0.690208, -0.848157, 2.16723},
-    {1.09866, 0.0, 2.16723},
-    {-0.227573, -1.05763, 2.16723},
-    {-0.154893, -0.759032, 2.72566},
-    {0.690208, -0.848157, 2.16723},
-    {0.690208, -0.848157, 2.16723},
-    {-0.154893, -0.759032, 2.72566},
-    {0.50377, -0.608696, 2.72566},
-    {-0.963577, -0.470692, 2.16723},
-    {-0.683099, -0.337801, 2.72566},
-    {-0.227573, -1.05763, 2.16723},
-    {-0.227573, -1.05763, 2.16723},
-    {-0.683099, -0.337801, 2.72566},
-    {-0.154893, -0.759032, 2.72566},
-    {-0.963577, -0.470692, 2.16723},
-    {-0.963577, 0.470692, 2.16723},
-    {-0.683099, -0.337801, 2.72566},
-    {-0.963577, 0.470692, 2.16723},
-    {-0.683099, 0.337801, 2.72566},
-    {-0.683099, -0.337801, 2.72566},
-    {-0.963577, 0.470692, 2.16723},
-    {-0.227574, 1.05763, 2.16723},
-    {-0.683099, 0.337801, 2.72566},
-    {-0.227574, 1.05763, 2.16723},
-    {-0.154893, 0.759032, 2.72566},
-    {-0.683099, 0.337801, 2.72566},
-    {-0.227574, 1.05763, 2.16723},
-    {0.690208, 0.848157, 2.16723},
-    {-0.154893, 0.759032, 2.72566},
-    {0.690208, 0.848157, 2.16723},
-    {0.50377, 0.608696, 2.72566},
-    {-0.154893, 0.759032, 2.72566},
-    {0.690208, 0.848157, 2.16723},
-    {1.09866, 0.0, 2.16723},
-    {0.50377, 0.608696, 2.72566},
-    {1.09866, 0.0, 2.16723},
-    {0.796903, 0.0, 2.72566},
-    {0.50377, 0.608696, 2.72566},
-    {1.09866, 0.0, 2.16723},
-    {0.690208, -0.848157, 2.16723},
-    {0.796903, 0.0, 2.72566},
-    {0.690208, -0.848157, 2.16723},
-    {0.50377, -0.608696, 2.72566},
-    {0.796903, 0.0, 2.72566},
-    {0.50377, -0.608696, 2.72566},
-    {-0.154893, -0.759032, 2.72566},
-    {0.259722, -0.299638, 3.11175},
-    {-0.154893, -0.759032, 2.72566},
-    {-0.0645132, -0.373643, 3.11175},
-    {0.259722, -0.299638, 3.11175},
-    {-0.154893, -0.759032, 2.72566},
-    {-0.683099, -0.337801, 2.72566},
-    {-0.0645132, -0.373643, 3.11175},
-    {-0.683099, -0.337801, 2.72566},
-    {-0.324529, -0.166287, 3.11175},
-    {-0.0645132, -0.373643, 3.11175},
-    {-0.683099, -0.337801, 2.72566},
-    {-0.683099, 0.337801, 2.72566},
-    {-0.324529, -0.166287, 3.11175},
-    {-0.683099, 0.337801, 2.72566},
-    {-0.324529, 0.166287, 3.11175},
-    {-0.324529, -0.166287, 3.11175},
-    {-0.683099, 0.337801, 2.72566},
-    {-0.154893, 0.759032, 2.72566},
-    {-0.324529, 0.166287, 3.11175},
-    {-0.154893, 0.759032, 2.72566},
-    {-0.0645132, 0.373642, 3.11175},
-    {-0.324529, 0.166287, 3.11175},
-    {-0.154893, 0.759032, 2.72566},
-    {0.50377, 0.608696, 2.72566},
-    {-0.0645132, 0.373642, 3.11175},
-    {0.50377, 0.608696, 2.72566},
-    {0.259722, 0.299638, 3.11175},
-    {-0.0645132, 0.373642, 3.11175},
-    {0.50377, 0.608696, 2.72566},
-    {0.796903, 0.0, 2.72566},
-    {0.259722, 0.299638, 3.11175},
-    {0.796903, 0.0, 2.72566},
-    {0.40402, 0.0, 3.11175},
-    {0.259722, 0.299638, 3.11175},
-    {0.796903, 0.0, 2.72566},
-    {0.50377, -0.608696, 2.72566},
-    {0.40402, 0.0, 3.11175},
-    {0.50377, -0.608696, 2.72566},
-    {0.259722, -0.299638, 3.11175},
-    {0.40402, 0.0, 3.11175},
-    {-0.177333, -0.741523, 0.160201},
-    {0.466137, -0.594656, 0.160201},
-    {-0.00334214, 0.0, 0.00443203},
-    {-0.693356, -0.330009, 0.160201},
-    {-0.177333, -0.741523, 0.160201},
-    {-0.00334214, 0.0, 0.00443203},
-    {-0.693356, 0.330009, 0.160201},
-    {-0.693356, -0.330009, 0.160201},
-    {-0.00334214, 0.0, 0.00443203},
-    {-0.177333, 0.741523, 0.160201},
-    {-0.693356, 0.330009, 0.160201},
-    {-0.00334214, 0.0, 0.00443203},
-    {0.466137, 0.594656, 0.160201},
-    {-0.177333, 0.741523, 0.160201},
-    {-0.00334214, 0.0, 0.00443203},
-    {0.752508, 0.0, 0.160201},
-    {0.466137, 0.594656, 0.160201},
-    {-0.00334214, 0.0, 0.00443203},
-    {0.466137, -0.594656, 0.160201},
-    {0.752508, 0.0, 0.160201},
-    {-0.00334214, 0.0, 0.00443203},
-    {0.259722, -0.299638, 3.11175},
-    {-0.0645132, -0.373643, 3.11175},
-    {0.0207683, 0.0, 3.20912},
-    {-0.0645132, -0.373643, 3.11175},
-    {-0.324529, -0.166287, 3.11175},
-    {0.0207683, 0.0, 3.20912},
-    {-0.324529, -0.166287, 3.11175},
-    {-0.324529, 0.166287, 3.11175},
-    {0.0207683, 0.0, 3.20912},
-    {-0.324529, 0.166287, 3.11175},
-    {-0.0645132, 0.373642, 3.11175},
-    {0.0207683, 0.0, 3.20912},
-    {-0.0645132, 0.373642, 3.11175},
-    {0.259722, 0.299638, 3.11175},
-    {0.0207683, 0.0, 3.20912},
-    {0.259722, 0.299638, 3.11175},
-    {0.40402, 0.0, 3.11175},
-    {0.0207683, 0.0, 3.20912},
-    {0.40402, 0.0, 3.11175},
-    {0.259722, -0.299638, 3.11175},
-    {0.0207683, 0.0, 3.20912}
-};
-
-
-// Disable the forcing int to true or false performance warning
-#pragma warning(disable: 4800)
-
-/* MaxEggPluginClassDesc - A class that describes 3DS Plugin support.
-   This basically says "Yes, I am a helper object!"
-*/
-
-class MaxEggPluginClassDesc : public ClassDesc
-{
-public:
-  int          IsPublic() { return TRUE; }
-  void         *Create(BOOL loading = FALSE) { return new MaxEggPlugin(); }
-  const TCHAR  *ClassName() { return GetString(IDS_CLASS_NAME); }
-  SClass_ID    SuperClassID() { return HELPER_CLASS_ID; }
-  Class_ID     ClassID() { return MaxEggPlugin_CLASS_ID; }
-  const TCHAR  *Category() { return GetString(IDS_CATEGORY); }
-  // returns fixed parsable name (scripter-visible name)
-  const TCHAR *InternalName() { return _T("MaxEggPlugin"); }
-};
-
-// Our private global instance of the above class
-static MaxEggPluginClassDesc MaxEggPluginDesc;
-
-// Called by LibClassDesc to find out what the plugin is
-ClassDesc* GetMaxEggPluginDesc() { return &MaxEggPluginDesc; }
-
-// Initialize class-static variables
-Mesh MaxEggPlugin::mesh;
-short MaxEggPlugin::meshBuilt=0;
-HWND MaxEggPlugin::hMaxEggParams = nullptr;
-IObjParam *MaxEggPlugin::iObjParams;
-
-/* MaxEggPluginOptionsDlgProc() - This is the callback function for the
-   dialog box that appears at the beginning of the conversion process.
- */
-
-INT_PTR CALLBACK MaxEggPluginOptionsDlgProc( HWND hWnd, UINT message,
-                                          WPARAM wParam, LPARAM lParam )
-{
-  MaxOptionsDialog *tempEgg;
-  int sel, res;
-
-  // We pass in our plugin through the lParam variable.  Let's convert it
-  // back.
-  MaxEggPlugin *imp = (MaxEggPlugin*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
-  if ( !imp && message != WM_INITDIALOG ) return FALSE;
-
-  switch(message)
-    {
-    // When we start, center the window.
-    case WM_INITDIALOG:
-      // this line is very necessary to pass the plugin as the lParam
-      SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam);
-      SetDlgFont( hWnd, imp->iObjParams->GetAppHFont() );
-      MaxEggPlugin::hMaxEggParams = hWnd;
-      return TRUE; break;
-
-    case WM_MOUSEACTIVATE:
-      imp->iObjParams->RealizeParamPanel();
-      return TRUE; break;
-
-    case WM_LBUTTONDOWN:
-    case WM_LBUTTONUP:
-    case WM_MOUSEMOVE:
-      imp->iObjParams->RollupMouseMessage(hWnd,message,wParam,lParam);
-      return TRUE; break;
-
-    // A control was modified
-    case WM_COMMAND:
-      // The modified control is found in the lower word of the wParam long.
-      switch( LOWORD(wParam) ) {
-        case IDC_OVERWRITE_CHECK:
-          imp->autoOverwrite =
-            (IsDlgButtonChecked(hWnd, IDC_OVERWRITE_CHECK) == BST_CHECKED);
-          return TRUE; break;
-        case IDC_PVIEW_CHECK:
-          imp->pview =
-            (IsDlgButtonChecked(hWnd, IDC_PVIEW_CHECK) == BST_CHECKED);
-          return TRUE; break;
-        case IDC_LOGGING:
-          imp->logOutput =
-            (IsDlgButtonChecked(hWnd, IDC_LOGGING) == BST_CHECKED);
-          return TRUE; break;
-        case IDC_ADD_EGG:
-          tempEgg = new MaxOptionsDialog();
-          tempEgg->SetMaxInterface(imp->iObjParams);
-          tempEgg->SetAnimRange();
-          res = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_EGG_DETAILS),
-                               hWnd, MaxOptionsDialogProc, (LPARAM)tempEgg);
-          if (res == TRUE) {
-            imp->SaveCheckState();
-            imp->AddEgg(tempEgg);
-            imp->UpdateUI();
-          }
-          else delete tempEgg;
-          return TRUE; break;
-        case IDC_EDIT_EGG:
-          sel = ListView_GetSelectionMark(GetDlgItem(hWnd, IDC_LIST_EGGS));
-          if (sel != -1) {
-            MaxOptionsDialog *tempEgg = imp->GetEgg(sel);
-            if (tempEgg) {
-                tempEgg->SetAnimRange();
-                tempEgg->CullBadNodes();
-                DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_EGG_DETAILS),
-                               hWnd, MaxOptionsDialogProc, (LPARAM)tempEgg);
-            }
-            imp->SaveCheckState();
-            imp->UpdateUI();
-          }
-          return TRUE; break;
-        case IDC_REMOVE_EGG:
-          sel = ListView_GetSelectionMark(GetDlgItem(hWnd, IDC_LIST_EGGS));
-          if (sel != -1) {
-            imp->SaveCheckState();
-            imp->RemoveEgg(sel);
-            imp->UpdateUI();
-          }
-          return TRUE; break;
-        case IDC_EXPORT:
-          imp->DoExport();
-          return TRUE; break;
-      }
-    }
-  return FALSE;
-}
-
-MaxEggPlugin::MaxEggPlugin() :
-autoOverwrite(false), pview(true), logOutput(false), numEggs(0), maxEggs(5)
-{
-    eggList = new MaxOptionsDialog*[maxEggs];
-    BuildMesh();
-}
-
-MaxEggPlugin::~MaxEggPlugin() {
-    for (int i = 0; i < numEggs; i++) delete eggList[i];
-    delete [] eggList;
-}
-
-void MaxEggPlugin::AddEgg(MaxOptionsDialog *newEgg) {
-    if (numEggs >= maxEggs) {
-        MaxOptionsDialog **newList;
-        maxEggs *= 2;
-        newList = new MaxOptionsDialog*[maxEggs];
-        for (int i = 0; i < numEggs; i++) newList[i] = eggList[i];
-        delete [] eggList;
-        eggList = newList;
-    }
-
-    eggList[numEggs++] = newEgg;
-}
-
-void MaxEggPlugin::RemoveEgg(int i) {
-    if (i >= 0 && i < numEggs) {
-        delete eggList[i];
-        for (int j = i+1; j < numEggs;) eggList[i++] = eggList[j++];
-        --numEggs;
-    }
-}
-
-void MaxEggPlugin::BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev )
-{
-    iObjParams = ip;
-    for (int i=0; i<numEggs; i++) {
-        eggList[i]->SetMaxInterface(ip);
-    }
-
-    if ( !hMaxEggParams ) {
-        hMaxEggParams = ip->AddRollupPage(hInstance,
-                                          MAKEINTRESOURCE(IDD_PANEL),
-                                          MaxEggPluginOptionsDlgProc,
-                                          GetString(IDS_PARAMS),
-                                          (LPARAM)this );
-        ip->RegisterDlgWnd(hMaxEggParams);
-    } else {
-        SetWindowLongPtr( hMaxEggParams, GWLP_USERDATA, (LPARAM)this );
-    }
-
-    UpdateUI();
-}
-
-void MaxEggPlugin::EndEditParams( IObjParam *ip, ULONG flags,Animatable *prev)
-{
-    SaveCheckState();
-    if ( flags&END_EDIT_REMOVEUI ) {
-        ip->UnRegisterDlgWnd(hMaxEggParams);
-        ip->DeleteRollupPage(hMaxEggParams);
-        hMaxEggParams = nullptr;
-    } else {
-        SetWindowLongPtr( hMaxEggParams, GWLP_USERDATA, 0L );
-    }
-}
-
-void MaxEggPlugin::SaveCheckState() {
-    if (!hMaxEggParams) return;
-    HWND lv = GetDlgItem(hMaxEggParams, IDC_LIST_EGGS);
-    for (int i = 0; i < numEggs; i++)
-        eggList[i]->_checked = ListView_GetCheckState(lv, i);
-}
-
-void MaxEggPlugin::UpdateUI() {
-    HWND lv = GetDlgItem(hMaxEggParams, IDC_LIST_EGGS);
-    LV_COLUMN pCol;
-
-    if (ListView_GetColumnWidth(lv, 1) <= 0 || ListView_GetColumnWidth(lv, 1) > 10000) {
-        // Columns have not been setup, so initialize the control
-        ListView_SetExtendedListViewStyleEx(lv, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT,
-                                            LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);
-
-        pCol.fmt = LVCFMT_LEFT;
-        pCol.cx = 96;
-        pCol.pszText = _T("Filename");
-        pCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
-        pCol.iSubItem = 0;
-        ListView_InsertColumn(lv, 0, &pCol);
-
-        pCol.cx = 44;
-        pCol.pszText = _T("Type");
-        ListView_InsertColumn(lv, 1, &pCol);
-    }
-
-    // Add the eggs to the list
-    ListView_DeleteAllItems(lv);
-    LV_ITEM Item;
-    Item.mask = LVIF_TEXT;
-
-    for (int i = 0; i < numEggs; i++) {
-        Item.iItem = i;
-        Item.iSubItem = 0;
-        Item.pszText = eggList[i]->_short_name;
-        ListView_InsertItem(lv, &Item);
-        Item.iSubItem = 1;
-        switch(eggList[i]->_anim_type) {
-        case MaxEggOptions::AT_chan:  Item.pszText = _T("Animation"); break;
-        case MaxEggOptions::AT_both:  Item.pszText = _T("Both"); break;
-        case MaxEggOptions::AT_pose:  Item.pszText = _T("Static"); break;
-        case MaxEggOptions::AT_model: Item.pszText = _T("Model"); break;
-        default:                      Item.pszText = _T("Model"); break;
-        }
-        ListView_SetItem(lv, &Item);
-        ListView_SetCheckState(lv, i, eggList[i]->_checked);
-    }
-
-    // Set the "Overwrite Existing Files" and "Pview" checkboxes
-    CheckDlgButton(hMaxEggParams, IDC_OVERWRITE_CHECK,
-                   autoOverwrite ? BST_CHECKED : BST_UNCHECKED);
-    CheckDlgButton(hMaxEggParams, IDC_PVIEW_CHECK,
-                   pview ? BST_CHECKED : BST_UNCHECKED);
-    CheckDlgButton(hMaxEggParams, IDC_LOGGING,
-                   logOutput ? BST_CHECKED : BST_UNCHECKED);
-}
-
-void MaxEggPlugin::DoExport() {
-    int good = 0, bad = 0;
-
-    std::basic_stringstream<TCHAR> status;
-
-    SaveCheckState();
-
-    for (int i = 0; i < numEggs; i++) {
-        if (eggList[i]->_checked) {
-            // If "auto overwrite" was not checked and the file exists, ask if
-            // the user wishes to overwrite the file
-            bool do_write = true;
-
-            if (!autoOverwrite && GetFileAttributes(eggList[i]->_file_name) != INVALID_FILE_ATTRIBUTES) {
-                TCHAR msg[1024];
-                _stprintf(msg, _T("Overwrite file \"%s.egg\"?"), eggList[i]->_short_name);
-                do_write = (MessageBox(hMaxEggParams, msg, _T("Panda3D Exporter"), MB_YESNO | MB_ICONQUESTION) == IDYES);
-            }
-            if (do_write) {
-                MaxToEggConverter converter;
-                if (converter.convert((MaxEggOptions*)eggList[i])) {
-                    good += 1;
-                    status << _T("Successfully created ") << eggList[i]->_short_name << _T(".egg\n");
-                } else {
-                    bad += 1;
-                    status << _T("Could not export ") << eggList[i]->_short_name << _T(".egg\n");
-                }
-            } else {
-                bad += 1;
-                status << _T("Skipped file ") << eggList[i]->_short_name << _T(".egg\n");
-            }
-        }
-    }
-
-    UINT mask = MB_OK;
-
-    if (good == 0 && bad == 0) {
-        mask |= MB_ICONEXCLAMATION;
-        MessageBox(hMaxEggParams, _T("Nothing to export!"), _T("Panda3D Export results"), mask);
-    } else {
-        if (bad > 0) mask |= MB_ICONEXCLAMATION;
-        else mask |= MB_ICONINFORMATION;
-        MessageBox(hMaxEggParams, status.str().c_str(), _T("Panda3D Export results"), mask);
-    }
-
-    int pviewed = 0;
-    if (pview && good > 0) {
-        for (i = 0; i < numEggs; i++) {
-            if (eggList[i]->_checked && eggList[i]->_successful) {
-                if (eggList[i]->_anim_type != MaxEggOptions::AT_chan) {
-                    PROCESS_INFORMATION pi;
-                    STARTUPINFO si;
-
-                    memset(&si, 0, sizeof(si));
-                    si.cb = sizeof(si);
-
-                    TCHAR cmdLine[2048];
-                    // If we have just one model and animation file, pview
-                    // them both
-                    if (numEggs == 2 && eggList[i]->_anim_type == MaxEggOptions::AT_model &&
-                        eggList[1-i]->_checked && eggList[1-i]->_successful &&
-                        eggList[1-i]->_anim_type == MaxEggOptions::AT_chan) {
-                        _stprintf(cmdLine, _T("pview \"%s\" \"%s\""), eggList[i]->_file_name, eggList[1-i]->_file_name);
-                    } else {
-                        _stprintf(cmdLine, _T("pview \"%s\""), eggList[i]->_file_name);
-                    }
-                    CreateProcess(nullptr, cmdLine, nullptr, nullptr, FALSE, CREATE_NEW_CONSOLE,
-                                  nullptr, nullptr, &si, &pi);
-                    pviewed += 1;
-                }
-            }
-        }
-    }
-}
-
-
-void MaxEggPlugin::BuildMesh()
-{
-    int i;
-    if(meshBuilt) return;
-
-    mesh.setNumVerts(252);
-    mesh.setNumFaces(84);
-    mesh.setSmoothFlags(0);
-    mesh.setNumTVerts (0);
-    mesh.setNumTVFaces (0);
-
-    for (i=0; i<252; i++)
-        mesh.setVert(i, meshVerts[i][0]*10, meshVerts[i][1]*10, meshVerts[i][2]*10);
-    for (i=0; i<84; i++) {
-        mesh.faces[i].setEdgeVisFlags(1, 1, 0);
-        mesh.faces[i].setSmGroup(0);
-        mesh.faces[i].setVerts(i*3, i*3+1, i*3+2);
-    }
-
-    mesh.InvalidateGeomCache();
-    mesh.BuildStripsAndEdges();
-
-    meshBuilt = TRUE;
-}
-
-// The creation callback - sets the initial position of the helper in the
-// scene.
-
-class MaxEggPluginCreateMouseCallBack: public CreateMouseCallBack
-{
-public:
-    int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat );
-};
-
-int MaxEggPluginCreateMouseCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat )
-{
-    if (msg==MOUSE_POINT||msg==MOUSE_MOVE) {
-        switch(point) {
-        case 0:
-            mat.SetTrans(vpt->SnapPoint(m,m,nullptr,SNAP_IN_PLANE));
-            break;
-        case 1:
-            mat.SetTrans(vpt->SnapPoint(m,m,nullptr,SNAP_IN_PLANE));
-            if (msg==MOUSE_POINT) return CREATE_STOP;
-            break;
-        }
-    } else if (msg == MOUSE_ABORT) {
-        return CREATE_ABORT;
-    }
-    return CREATE_CONTINUE;
-}
-
-static MaxEggPluginCreateMouseCallBack MaxEggCreateMouseCB;
-
-CreateMouseCallBack* MaxEggPlugin::GetCreateMouseCallBack()
-{ return &MaxEggCreateMouseCB; }
-
-// Boilerplate functions for dealing with the display of the plugin
-
-void MaxEggPlugin::GetMat(TimeValue t, INode* inode, ViewExp* vpt, Matrix3& tm)
-{
-    tm = inode->GetObjectTM(t);
-    tm.NoScale();
-    PN_stdfloat scaleFactor = vpt->NonScalingObjectSize()*vpt->GetVPWorldWidth(tm.GetTrans())/(PN_stdfloat)360.0;
-    tm.Scale(Point3(scaleFactor,scaleFactor,scaleFactor));
-}
-
-void MaxEggPlugin::GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm, BOOL useSel )
-{
-    box = mesh.getBoundingBox(tm);
-}
-
-void MaxEggPlugin::GetLocalBoundBox(TimeValue t, INode* inode, ViewExp* vpt, Box3& box )
-{
-    Matrix3 m = inode->GetObjectTM(t);
-    Point3 pt;
-    Point3 q[4];
-    PN_stdfloat scaleFactor = vpt->GetVPWorldWidth(m.GetTrans())/360.0f;
-    box = mesh.getBoundingBox();
-    box.Scale(scaleFactor);
-}
-
-void MaxEggPlugin::GetWorldBoundBox(TimeValue t, INode* inode, ViewExp* vpt, Box3& box )
-{
-    int i, nv; Matrix3 tm; Point3 pt;
-    GetMat(t,inode,vpt,tm);
-    nv = mesh.getNumVerts();
-    box.Init();
-    for (i=0; i<nv; i++)
-        box += tm*mesh.getVert(i);
-}
-
-int MaxEggPlugin::HitTest(TimeValue t, INode *inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt)
-{
-    HitRegion hitRegion;
-    DWORD savedLimits;
-    Matrix3 m;
-    GraphicsWindow *gw = vpt->getGW();
-    Material *mtl = gw->getMaterial();
-    MakeHitRegion(hitRegion,type,crossing,4,p);
-    gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM);
-    GetMat(t,inode,vpt,m);
-    gw->setTransform(m);
-    gw->clearHitCode();
-    if (mesh.select( gw, mtl, &hitRegion, flags & HIT_ABORTONHIT ))
-        return TRUE;
-    return FALSE;
-}
-
-int MaxEggPlugin::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags)
-{
-    Matrix3 m;
-    GraphicsWindow *gw = vpt->getGW();
-    Material *mtl = gw->getMaterial();
-
-    GetMat(t,inode,vpt,m);
-    gw->setTransform(m);
-    DWORD rlim = gw->getRndLimits();
-    gw->setRndLimits(GW_WIREFRAME|GW_BACKCULL);
-    if (inode->Selected())
-        gw->setColor( LINE_COLOR, GetSelColor());
-    else if(!inode->IsFrozen())
-        gw->setColor( LINE_COLOR, GetUIColor(COLOR_TAPE_OBJ));
-    mesh.render( gw, mtl, nullptr, COMP_ALL);
-    return 0;
-}
-
-RefResult MaxEggPlugin::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message )
-{
-    UpdateUI();
-    return REF_SUCCEED;
-}
-
-ObjectState MaxEggPlugin::Eval(TimeValue time)
-{
-    return ObjectState(this);
-}
-
-Interval MaxEggPlugin::ObjectValidity(TimeValue t)
-{
-    Interval ivalid;
-    ivalid.SetInfinite();
-    return ivalid;
-}
-
-RefTargetHandle MaxEggPlugin::Clone(RemapDir& remap)
-{
-    MaxEggPlugin* newob = new MaxEggPlugin();
-    return(newob);
-}
-
-// Loading and saving the plugin
-
-IOResult MaxEggPlugin::Save(ISave *isave) {
-    SaveCheckState();
-    for (int i = 0; i < numEggs; i++)
-        eggList[i]->Save(isave);
-    ChunkSave(isave,   CHUNK_OVERWRITE_FLAG,  autoOverwrite);
-    ChunkSave(isave,   CHUNK_PVIEW_FLAG,      pview);
-    ChunkSave(isave,   CHUNK_LOG_OUTPUT,      logOutput);
-
-    return IO_OK;
-}
-
-IOResult MaxEggPlugin::Load(ILoad *iload) {
-    IOResult res = iload->OpenChunk();
-    MaxOptionsDialog *temp;
-
-    while (res == IO_OK) {
-        switch(iload->CurChunkID()) {
-        case CHUNK_OVERWRITE_FLAG: autoOverwrite = ChunkLoadBool(iload); break;
-        case CHUNK_PVIEW_FLAG:     pview = ChunkLoadBool(iload); break;
-        case CHUNK_LOG_OUTPUT:     logOutput = ChunkLoadBool(iload); break;
-        case CHUNK_EGG_EXP_OPTIONS:
-            temp = new MaxOptionsDialog();
-            temp->SetMaxInterface(iObjParams);
-            temp->Load(iload);
-            AddEgg(temp);
-            break;
-        }
-        iload->CloseChunk();
-        res = iload->OpenChunk();
-    }
-
-    return IO_OK;
-}
-
-/**********************************************************************
- *
- * DLL Initialization
- *
- **********************************************************************/
-
-extern ClassDesc* GetMaxEggPluginDesc();
-
-HINSTANCE hInstance;
-int controlsInit = FALSE;
-
-// This function is called by Windows when the DLL is loaded.  This function
-// may also be called many times during time critical operations like
-// rendering.  Therefore developers need to be careful what they do inside
-// this function.  In the code below, note how after the DLL is loaded the
-// first time only a few statements are executed.
-
-BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved)
-{
-        hInstance = hinstDLL;                           // Hang on to this DLL's instance handle.
-
-        if (!controlsInit) {
-                controlsInit = TRUE;
-
-#if MAX_VERSION_MAJOR < 14
-                // It appears that InitCustomControls is deprecated in 2012.
-                // I'm not sure if we can just remove it like this, but I've
-                // heard that it seems to work, so let's do it like this.
-                InitCustomControls(hInstance);  // Initialize MAX's custom controls
-#endif
-                InitCommonControls();                   // Initialize Win95 controls
-        }
-
-        return (TRUE);
-}
-
-// This function returns a string that describes the DLL and where the user
-// could purchase the DLL if they don't have it.
-__declspec( dllexport ) const TCHAR* LibDescription()
-{
-        return GetString(IDS_LIBDESCRIPTION);
-}
-
-// This function returns the number of plug-in classes this DLL operates on.
-// TODO: Must change this number when adding a new class
-__declspec( dllexport ) int LibNumberClasses()
-{
-        return 1;
-}
-
-// This function returns the descriptions of the plug-in classes this DLL
-// operates on.
-__declspec( dllexport ) ClassDesc* LibClassDesc(int i)
-{
-        switch(i) {
-                case 0: return GetMaxEggPluginDesc();
-                default: return nullptr;
-        }
-}
-
-// This function returns a pre-defined constant indicating the version of the
-// system under which it was compiled.  It is used to allow the system to
-// catch obsolete DLLs.
-__declspec( dllexport ) ULONG LibVersion()
-{
-        return VERSION_3DSMAX;
-}
-
-TCHAR *GetString(int id)
-{
-        static TCHAR buf[256];
-
-        if (hInstance)
-                return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : nullptr;
-        return nullptr;
-}

+ 0 - 8
pandatool/src/maxegg/maxEgg.def

@@ -1,8 +0,0 @@
-LIBRARY MaxEgg
-EXPORTS
-	LibDescription			@1
-	LibNumberClasses		@2
-	LibClassDesc			@3
-	LibVersion				@4
-SECTIONS
-	.data READ WRITE

+ 0 - 172
pandatool/src/maxegg/maxEgg.h

@@ -1,172 +0,0 @@
-/*
-  MaxEgg.h
-  Created by Steven "Sauce" Osman, Jan03
-  Modified and maintained by Ken Strickland, (02/01/03)-(05/15/03)
-  Modified and maintained by Corey Revilla, (05/22/03)-present
-  Carnegie Mellon University, Entetainment Technology Center
-
-  This file contains a 3dsMax exporter derived from discreet's own SceneExport
-  plug-in class; this exporter is basically a wrapper around the MaxToEgg
-  Panda-converter class, and just sets up the interface and environment
-  in which the MaxToEgg class can be "run" as if it were a standalone app.
-*/
-#ifndef __MaxEgg__H
-#define __MaxEgg__H
-
-#include "pandatoolbase.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <crtdbg.h>
-#include <errno.h>
-
-using std::min;
-using std::max;
-
-#include "eggGroup.h"
-#include "eggTable.h"
-#include "eggXfmSAnim.h"
-#include "eggData.h"
-#include "referenceCount.h"
-#include "pointerTo.h"
-#include "namable.h"
-
-#include <iostream>
-#include <fstream>
-#include <vector>
-
-#define WIN32_LEAN_AND_MEAN
-#include <windef.h>
-#include <windows.h>
-
-#include <Max.h>
-#include <iparamb2.h>
-#include <iparamm2.h>
-#include <istdplug.h>
-#include <iskin.h>
-#include <stdmat.h>
-#include <phyexp.h>
-#include <surf_api.h>
-#include <bipexp.h>
-#include <modstack.h>
-
-#include "eggCoordinateSystem.h"
-#include "eggGroup.h"
-#include "eggPolygon.h"
-#include "eggTextureCollection.h"
-#include "eggTexture.h"
-#include "eggVertex.h"
-#include "eggVertexPool.h"
-#include "eggNurbsCurve.h"
-#include "pandatoolbase.h"
-#include "eggXfmSAnim.h"
-#include "pathStore.h"
-
-#include "maxNodeDesc.h"
-#include "maxNodeTree.h"
-#include "maxOptionsDialog.h"
-#include "maxResource.h"
-#include "maxToEggConverter.h"
-
-#define MaxEggPlugin_CLASS_ID   Class_ID(0x7ac0d6b7, 0x55731ef6)
-
-#pragma conform(forScope, off)
-
-/* Externed Globals
- */
-extern HINSTANCE hInstance;
-
-/* Global Functions
- */
-extern TCHAR *GetString(int id);
-
-/* This class defines the 3D Studio Max exporter itself.  It is basically a
-   shell that is invoked by 3D Studio Max's export API.  It then sets up
-   MaxToEgg instance and attempts to "fool it" into thinking that it is
-   actually being invoked as a standalone program.  The thought behind this
-   is that some day MaxToEgg may well be a standalone program, provided that
-   a suitable interface to Max files can be connected from a standalone
-   program instead of a plugin.
-*/
-
-#if MAX_VERSION_MAJOR < 9
-  #define DefaultRemapDir NoRemap
-#endif
-
-class MaxEggPlugin : public HelperObject
-{
-  MaxOptionsDialog **eggList;
-  int numEggs;
-  int maxEggs;
-
- public:
-  bool autoOverwrite;
-  bool pview;
-  bool logOutput;
-
-  // Class vars
-  static Mesh mesh;           // This plugin generates no geometry, this mesh is not passed on to 3D Studio.
-  static short meshBuilt;
-  static HWND hMaxEggParams;
-  static IObjParam *iObjParams;
-
-  // ConstructorDestructor
-  MaxEggPlugin();
-  virtual ~MaxEggPlugin();
-
-  // Other class Methods
-  void DoExport();
-  void UpdateUI();
-  void SaveCheckState();
-  void BuildMesh();
-
-  void AddEgg(MaxOptionsDialog *newEgg);
-  void RemoveEgg(int i);
-  MaxOptionsDialog *GetEgg(int i) { return (i >= 0 && i < numEggs) ? eggList[i] : nullptr; }
-
-  // Required implimented virtual methods: inherited virtual methods for
-  // Reference-management
-  RefResult NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message );
-  void GetMat(TimeValue t, INode* inod, ViewExp *vpt, Matrix3& mat);
-
-  // From BaseObject
-  int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt);
-  int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags);
-  CreateMouseCallBack* GetCreateMouseCallBack();
-  void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);
-  void EndEditParams( IObjParam *ip, ULONG flags,Animatable *next);
-#if MAX_VERSION_MAJOR < 15
-  TCHAR *GetObjectName() { return GetString(IDS_LIBDESCRIPTION); }
-#else
-  const TCHAR *GetObjectName() { return GetString(IDS_LIBDESCRIPTION); }
-#endif
-
-  // From Object
-  ObjectState Eval(TimeValue time);
-  void InitNodeName(TSTR& s) { s = GetString(IDS_CLASS_NAME); }
-  Interval ObjectValidity(TimeValue time);
-  void Invalidate();
-  int DoOwnSelectHilite() { return 1; }
-
-  // From GeomObject
-  int IntersectRay(TimeValue t, Ray& r, PN_stdfloat& at) { return 0; }
-  void GetWorldBoundBox(TimeValue t, INode *mat, ViewExp *vpt, Box3& box );
-  void GetLocalBoundBox(TimeValue t, INode *mat, ViewExp *vpt, Box3& box );
-  void GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm, BOOL useSel );
-
-  // Animatable methods
-  void DeleteThis() { delete this; }
-  Class_ID ClassID() { return MaxEggPlugin_CLASS_ID; }
-  void GetClassName(TSTR& s) { s = TSTR(GetString(IDS_CLASS_NAME)); }
-  TSTR SubAnimName(int i) { return TSTR(GetString(IDS_CLASS_NAME)); }
-
-  // From ref
-  RefTargetHandle Clone(RemapDir& remap = DefaultRemapDir());
-
-  // IO
-  IOResult Save(ISave *isave);
-  IOResult Load(ILoad *iload);
-};
-
-
-#endif // __MaxEgg__H

+ 0 - 200
pandatool/src/maxegg/maxEgg.rc

@@ -1,200 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "maxResource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "WinResrc.h"
-#define IDC_STATIC -1
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// Neutral resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
-#ifdef _WIN32
-LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
-#pragma code_page(1252)
-#endif //_WIN32
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-IDD_EGG_DETAILS DIALOGEX 0, 0, 256, 203
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Export Settings"
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
-    LTEXT           "Animation Type:",IDC_STATIC,6,5,54,8,NOT WS_GROUP
-    CONTROL         "Model",IDC_MODEL,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_GROUP,65,4,38,12
-    CONTROL         "Animation",IDC_ANIMATION,"Button",BS_AUTORADIOBUTTON | BS_LEFT,108,4,50,12
-    CONTROL         "Both",IDC_BOTH,"Button",BS_AUTORADIOBUTTON | BS_LEFT,164,4,35,12
-    CONTROL         "Static",IDC_POSE,"Button",BS_AUTORADIOBUTTON | BS_LEFT,206,4,38,12
-    LTEXT           "Filename",IDC_STATIC,12,30,66,8,NOT WS_GROUP
-    CONTROL         "Custom1",IDC_FILENAME,"CustEdit",WS_TABSTOP,12,42,180,12
-    CONTROL         "Browse...",IDC_BROWSE,"CustButton",WS_TABSTOP,198,42,48,12
-    CONTROL         "Export Entire Scene",IDC_EXPORT_ALL,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_GROUP,12,59,79,10
-    CONTROL         "Export Meshes:",IDC_EXPORT_SELECTED,"Button",BS_AUTORADIOBUTTON | BS_LEFT,12,71,66,10
-    LISTBOX         IDC_LIST_EXPORT,12,84,114,36,LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL | WS_TABSTOP
-    CONTROL         "Add...",IDC_ADD_EXPORT,"CustButton",WS_TABSTOP,12,126,54,12
-    CONTROL         "Remove...",IDC_REMOVE_EXPORT,"CustButton",WS_TABSTOP,72,126,54,12
-    CONTROL         "Export All Frames",IDC_EXP_ALL_FRAMES,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_GROUP,144,59,72,10
-    CONTROL         "Use Range:",IDC_EXP_SEL_FRAMES,"Button",BS_AUTORADIOBUTTON | BS_LEFT | BS_VCENTER,144,71,53,10
-    LTEXT           "Start Frame",IDC_SF_LABEL,144,90,42,8,WS_DISABLED | NOT WS_GROUP
-    CONTROL         "Custom4",IDC_SF,"CustEdit",WS_DISABLED | WS_TABSTOP,186,87,48,12
-    LTEXT           "End Frame",IDC_EF_LABEL,143,104,42,8,WS_DISABLED | NOT WS_GROUP
-    CONTROL         "Custom5",IDC_EF,"CustEdit",WS_DISABLED | WS_TABSTOP,186,102,48,12
-    CONTROL         "Double-sided Polygons",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,144,126,102,12
-    CONTROL         "OK",IDC_OK,"CustButton",WS_TABSTOP,162,179,42,12
-    CONTROL         "Cancel",IDC_CANCEL,"CustButton",WS_TABSTOP,208,179,42,12
-    LTEXT           "The collision tags are now defined within each object's User Defined properties window. For more information and help please consult the panda3d manual at www.panda3d.org",IDC_STATIC,12,146,225,26
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-1 VERSIONINFO
- FILEVERSION 3,0,0,0
- PRODUCTVERSION 3,0,0,0
- FILEFLAGSMASK 0x0L
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x40004L
- FILETYPE 0x2L
- FILESUBTYPE 0x0L
-BEGIN
-    BLOCK "StringFileInfo"
-    BEGIN
-        BLOCK "040904b0"
-        BEGIN
-            VALUE "FileVersion", "4.0.0.0"
-            VALUE "InternalName", "MaxEgg"
-            VALUE "OriginalFilename", "MaxEgg.dle"
-            VALUE "ProductName", "3ds max"
-            VALUE "ProductVersion", "4.0.0.0"
-            VALUE "FileDescription", "Panda3D .egg exporter"
-            VALUE "Comments", "TECH: "
-            VALUE "LegalTrademarks", "3D Studio MAX, Biped, Character Studio, Heidi, Kinetix and Physique are registered trademarks and 3ds max, combustion, Discreet, DWG Unplugged, DXF, FLI and FLC are trademarks of Autodesk, Inc."
-        END
-    END
-    BLOCK "VarFileInfo"
-    BEGIN
-        VALUE "Translation", 0x409, 1200
-    END
-END
-
-#endif    // Neutral resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-/////////////////////////////////////////////////////////////////////////////
-// 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
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-IDD_PANEL DIALOGEX 0, 0, 108, 192
-STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE | WS_SYSMENU
-FONT 8, "MS Sans Serif", 0, 0, 0x1
-BEGIN
-    CTEXT           "Panda 3D EGG Exporter",IDC_PANEL_TITLE,6,6,96,11,WS_BORDER | NOT WS_GROUP
-    LTEXT           "Eggs",IDC_EGGS_LABEL,6,19,62,8,NOT WS_GROUP
-    CONTROL         "Custom1",IDC_LIST_EGGS,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_TABSTOP,6,28,96,69,WS_EX_CLIENTEDGE
-    CONTROL         "Add...",IDC_ADD_EGG,"CustButton",WS_TABSTOP,6,102,24,12
-    CONTROL         "Edit...",IDC_EDIT_EGG,"CustButton",WS_TABSTOP,36,102,30,12
-    CONTROL         "Remove",IDC_REMOVE_EGG,"CustButton",WS_TABSTOP,72,102,30,12
-    CONTROL         "Overwrite Existing Files",IDC_OVERWRITE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,126,103,8,WS_EX_TRANSPARENT
-    CONTROL         "Export Now",IDC_EXPORT,"CustButton",WS_TABSTOP,5,164,96,18
-    CONTROL         "Pview Output",IDC_PVIEW_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,138,103,8,WS_EX_TRANSPARENT
-    CONTROL         "Log Output",IDC_LOGGING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,148,90,11
-END
-
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE 
-BEGIN
-    "resource.\0"
-END
-
-3 TEXTINCLUDE 
-BEGIN
-    "\r\0"
-END
-
-2 TEXTINCLUDE 
-BEGIN
-    "#include ""afxres.h""\r\0"
-END
-
-#endif    // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// DESIGNINFO
-//
-
-#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO 
-BEGIN
-    IDD_PANEL, DIALOG
-    BEGIN
-        RIGHTMARGIN, 107
-    END
-END
-#endif    // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// String Table
-//
-
-STRINGTABLE 
-BEGIN
-    IDS_LIBDESCRIPTION      "Panda3D .egg exporter"
-    IDS_CATEGORY            "Exporters"
-    IDS_CLASS_NAME          "Panda3D"
-    IDS_PARAMS              "Parameters"
-    IDS_SPIN                "Spin"
-END
-
-#endif    // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-/////////////////////////////////////////////////////////////////////////////
-#endif    // not APSTUDIO_INVOKED
-

+ 0 - 726
pandatool/src/maxegg/maxEggLoader.cxx

@@ -1,726 +0,0 @@
-/**
- * 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."
- *
- * @file maxEggLoader.cxx
- * @author jyelon
- * @date 2005-07-15
- *
- * 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"
-
-using std::min;
-using std::max;
-
-#include <stdio.h>
-#include <Max.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"
-
-using std::vector;
-
-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 Filename &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<std::string, MaxEggTex *> TexTable;
-  typedef second_of_pair_iterator<TexTable::const_iterator> TexIterator;
-
-  MeshTable        _mesh_tab;
-  JointTable       _joint_tab;
-  TexTable         _tex_tab;
-  int              _next_tex;
-};
-
-Point3 MakeMaxPoint(LVector3d vec)
-{
-  return Point3(vec[0], vec[1], vec[2]);
-}
-
-// MaxEggTex
-
-class MaxEggTex
-{
-public:
-  Filename   _path;
-  int        _id;
-  StdMat    *_mat;
-  BitmapTex *_bmt;
-};
-
-MaxEggTex *MaxEggLoader::GetTex(const Filename &fn)
-{
-  if (_tex_tab.count(fn))
-    return _tex_tab[fn];
-
-  BitmapTex *bmt = NewDefaultBitmapTex();
-#ifdef _UNICODE
-  bmt->SetMapName((TCHAR*) fn.to_os_specific_w().c_str());
-#else
-  bmt->SetMapName((char*) fn.to_os_specific().c_str());
-#endif
-
-  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(void);
-};
-
-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(void)
-{
-  LVector3d rxv,ryv,rzv;
-  GetRotation(rxv, ryv, rzv);
-  Point3 xv(MakeMaxPoint(rxv));
-  Point3 yv(MakeMaxPoint(ryv));
-  Point3 zv(MakeMaxPoint(rzv));
-  Point3 pos(MakeMaxPoint(GetPos()));
-  Point3 endpos(MakeMaxPoint(_endpos));
-  Point3 tzv(MakeMaxPoint(_perp));
-
-  Point3 fwd = endpos - pos;
-  double len = fwd.Length();
-  Point3 txv = fwd * ((PN_stdfloat)(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      (_tcscmp(n, _T("Length")) == 0) blk->SetValue(i, 0, (PN_stdfloat) len);
-    else if (_tcscmp(n, _T("Width")) == 0)  blk->SetValue(i, 0, (PN_stdfloat) _thickness);
-    else if (_tcscmp(n, _T("Height")) == 0) blk->SetValue(i, 0, (PN_stdfloat) _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);
-
-#ifdef _UNICODE
-  TCHAR wname[1024];
-  wname[1023] = 0;
-  mbstowcs(wname, _egg_joint->get_name().c_str(), 1023);
-  _node->SetName(wname);
-#else
-  _node->SetName((char*) _egg_joint->get_name().c_str());
-#endif
-
-  _node->SetObjOffsetRot(ooquat);
-  if (_parent) {
-    _node->Detach(0, 1);
-    _parent->_node->AttachChild(_node, 1);
-  }
-}
-
-// MaxEggMesh
-
-typedef std::pair<double, EggGroup *> MaxEggWeight;
-
-struct MaxEggVertex
-{
-  LVertexd              _pos;
-  LNormald              _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<LTexCoordd, int>            TVertTable;
-typedef phash_map<LColor, int>               CVertTable;
-
-class MaxEggMesh
-{
-public:
-
-  std::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);
-  int GetTVert(const LTexCoordd &uv);
-  int GetCVert(const LColor &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)
-{
-  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, MakeMaxPoint(vtx._pos));
-  return vtx._index;
-}
-
-int MaxEggMesh::GetTVert(const LTexCoordd &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(const LColor &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) {
-    std::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;
-#ifdef _UNICODE
-    TCHAR wname[1024];
-    wname[1023] = 0;
-    mbstowcs(wname, name.c_str(), 1023);
-    result->_node->SetName(wname);
-#else
-    result->_node->SetName((char*) name.c_str());
-#endif
-    _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<PN_stdfloat> maxWeights;
-    maxJoints.ZeroCount();
-    maxWeights.ZeroCount();
-    for (int i=0; i<vert->_weights.size(); i++) {
-      PN_stdfloat strength = (PN_stdfloat)(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())->_id;
-      if (tex->has_transform())
-        uvtrans = tex->get_transform2d();
-    } else {
-      texid = GetTex(Filename())->_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();
-      LTexCoordd uv = vtx->get_uv();
-      vertIndices.push_back(mesh->GetVert(vtx, context));
-      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;
-
-  data->set_coordinate_system(CS_zup_right);
-
-  SuspendAnimate();
-  SuspendSetKeyMode();
-  AnimateOff();
-  _next_tex = 0;
-
-  TraverseEggNode(data, nullptr);
-
-  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();
-  }
-
-  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);
-}

+ 0 - 22
pandatool/src/maxegg/maxEggLoader.h

@@ -1,22 +0,0 @@
-/**
- * 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."
- *
- * @file maxEggLoader.h
- * @author jyelon
- * @date 2005-07-15
- */
-
-#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

+ 0 - 198
pandatool/src/maxegg/maxNodeDesc.cxx

@@ -1,198 +0,0 @@
-/**
- * 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."
- *
- * @file maxNodeDesc.cxx
- * @author crevilla
- * from mayaNodeDesc.cxx created by:  drose (06Jun03)
- */
-
-#include "maxEgg.h"
-
-TypeHandle MaxNodeDesc::_type_handle;
-
-/**
- * Creates a MaxNodeDesc.  The name is copied from the given max node.  Use
- * from_INode to actually associate the desc with a given max node.
- */
-MaxNodeDesc::
-MaxNodeDesc(MaxNodeDesc *parent, INode *max_node) :
-  _parent(parent) {
-
-  if (max_node != nullptr) {
-    const TCHAR *max_name = max_node->GetName();
-#ifdef _UNICODE
-    char name_mb [1024];
-    name_mb[1023] = 0;
-    wcstombs(name_mb, max_name, 1023);
-    set_name(name_mb);
-#else
-    set_name(max_name);
-#endif
-  }
-
-  _max_node = nullptr;
-  _egg_group = nullptr;
-  _egg_table = nullptr;
-  _anim = nullptr;
-  _joint_type = JT_none;
-  _joint_entry = nullptr;
-
-  // Add ourselves to our parent.
-  if (_parent != nullptr) {
-    _parent->_children.push_back(this);
-  }
-}
-
-/**
- *
- */
-MaxNodeDesc::
-~MaxNodeDesc() {}
-
-/**
- * Indicates an associated between the MaxNodeDesc and some Max Node instance.
- */
-void MaxNodeDesc::
-from_INode(INode *max_node) {
-  if (_max_node == nullptr) {
-    _max_node = max_node;
-
-    // This is how I decided to check to see if this max node is a joint.  It
-    // works in all instances I've seen so far, but this may be a good
-    // starting place to look if joints are not being picked up correctly in
-    // the future.
-
-    // Check to see if the node's controller is a biped If so treat it as a
-    // joint Get the node's transform control
-    Control *c = max_node->GetTMController();
-    if (_max_node->GetBoneNodeOnOff() ||
-        (c && //c exists and it's type is a biped
-        ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
-         (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
-         (c->ClassID() == FOOTPRINT_CLASS_ID)))) {
-
-      // This node is a joint.
-      _joint_type = JT_node_joint;
-      if (_parent != nullptr) {
-        _parent->mark_joint_parent();
-      }
-    }
-  }
-}
-
-/**
- * Returns true if a Max INode has been associated with this node, false
- * otherwise.
- */
-bool MaxNodeDesc::
-has_max_node() const {
-  return (_max_node != nullptr);
-}
-
-/**
- * Returns the INode associated with this node.  It is an error to call this
- * unless has_max_node() returned true.
- */
-INode *MaxNodeDesc::
-get_max_node() const {
-  nassertr(_max_node != nullptr, _max_node);
-  return _max_node;
-}
-
-
-void MaxNodeDesc::
-set_joint(bool onoff) {
-  if (onoff)
-    _joint_type = JT_joint;
-  else
-    _joint_type = JT_none;
-}
-
-/**
- * Returns true if the node should be treated as a joint by the converter.
- */
-bool MaxNodeDesc::
-is_joint() const {
-  return _joint_type == JT_joint || _joint_type == JT_pseudo_joint;
-}
-
-/**
- * Returns true if the node is the parent or ancestor of a joint.
- */
-bool MaxNodeDesc::
-is_joint_parent() const {
-  return _joint_type == JT_joint_parent;
-}
-
-/**
- * Returns true if the node is the parent or ancestor of a joint.
- */
-bool MaxNodeDesc::
-is_node_joint() const {
-  return _joint_type == JT_node_joint;
-}
-
-/**
- * Recursively clears the egg pointers from this node and all children.
- */
-void MaxNodeDesc::
-clear_egg() {
-  _egg_group = nullptr;
-  _egg_table = nullptr;
-  _anim = nullptr;
-
-  Children::const_iterator ci;
-  for (ci = _children.begin(); ci != _children.end(); ++ci) {
-    MaxNodeDesc *child = (*ci);
-    child->clear_egg();
-  }
-}
-
-/**
- * Indicates that this node has at least one child that is a joint or a
- * pseudo-joint.
- */
-void MaxNodeDesc::
-mark_joint_parent() {
-  if (_joint_type == JT_none) {
-    _joint_type = JT_joint_parent;
-    if (_parent != nullptr) {
-      _parent->mark_joint_parent();
-    }
-  }
-}
-
-/**
- * Walks the hierarchy, looking for non-joint nodes that are both children and
- * parents of a joint.  These nodes are deemed to be pseudo joints, since the
- * converter must treat them as joints.
- */
-void MaxNodeDesc::
-check_pseudo_joints(bool joint_above) {
-  if (_joint_type == JT_joint_parent && joint_above) {
-    // This is one such node: it is the parent of a joint (JT_joint_parent is
-    // set), and it is the child of a joint (joint_above is set).
-    _joint_type = JT_pseudo_joint;
-  }
-
-  if (_joint_type == JT_joint) {
-    // If this node is itself a joint, then joint_above is true for all child
-    // nodes.
-    joint_above = true;
-  }
-
-  // Don't bother traversing further if _joint_type is none, since that means
-  // this node has no joint children.
-  if (_joint_type != JT_none) {
-    Children::const_iterator ci;
-    for (ci = _children.begin(); ci != _children.end(); ++ci) {
-      MaxNodeDesc *child = (*ci);
-      child->check_pseudo_joints(joint_above);
-    }
-  }
-}

+ 0 - 82
pandatool/src/maxegg/maxNodeDesc.h

@@ -1,82 +0,0 @@
-/**
- * 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."
- *
- * @file maxNodeDesc.h
- * @author crevilla
- * from mayaNodeDesc.h created by:  drose (06Jun03)
- */
-
-#ifndef MAXNODEDESC_H
-#define MAXNODEDESC_H
-
-/**
- * Describes a single instance of a node in the Max scene graph, relating it
- * to the corresponding egg structures (e.g.  node, group, or table entry)
- * that will be created.
- */
-class MaxNodeDesc : public ReferenceCount, public Namable {
- public:
-  MaxNodeDesc(MaxNodeDesc *parent = nullptr, INode *max_node = nullptr);
-  ~MaxNodeDesc();
-
-  void from_INode(INode *max_node);
-  bool has_max_node() const;
-  INode *get_max_node() const;
-
-  void set_joint(bool onoff);
-  bool is_joint() const;
-  bool is_joint_parent() const;
-  bool is_node_joint() const;
-
-  MaxNodeDesc *_parent;
-  MaxNodeDesc *_joint_entry;
-  typedef pvector< MaxNodeDesc* > Children;
-  Children _children;
-
- private:
-  void clear_egg();
-  void mark_joint_parent();
-  void check_pseudo_joints(bool joint_above);
-
-  INode *_max_node;
-
-  EggGroup *_egg_group;
-  EggTable *_egg_table;
-  EggXfmSAnim *_anim;
-
-  enum JointType {
-    JT_none,         // Not a joint.
-    JT_node_joint,    // Node that represents a joint in the geometry
-                                         // but not the actual joint itself
-    JT_joint,        // An actual joint in Max.
-    JT_pseudo_joint, // Not a joint in Max, but treated just like a
-                     // joint for the purposes of the converter.
-    JT_joint_parent, // A parent or ancestor of a joint or pseudo joint.
-  };
-  JointType _joint_type;
-
-
- public:
-  static TypeHandle get_class_type() {
-    return _type_handle;
-  }
-  static void init_type() {
-    ReferenceCount::init_type();
-    Namable::init_type();
-    register_type(_type_handle, "MaxNodeDesc",
-                  ReferenceCount::get_class_type(),
-                  Namable::get_class_type());
-  }
-
- private:
-  static TypeHandle _type_handle;
-
-  friend class MaxNodeTree;
-};
-
-#endif

+ 0 - 447
pandatool/src/maxegg/maxNodeTree.cxx

@@ -1,447 +0,0 @@
-/**
- * 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."
- *
- * @file maxNodeTree.cxx
- * @author crevilla
- * from mayaNodeTree.cxx created by:  drose (06Jun03)
- */
-
-#include "maxEgg.h"
-
-/**
- *
- */
-MaxNodeTree::
-MaxNodeTree() {
-  _root = new MaxNodeDesc;
-  _fps = 0.0;
-  _export_mesh = false;
-  _egg_data = nullptr;
-  _egg_root = nullptr;
-  _skeleton_node = nullptr;
-}
-
-/**
- * Returns a pointer to the node corresponding to the indicated INode object,
- * creating it first if necessary.
- */
-MaxNodeDesc *MaxNodeTree::
-build_node(INode *max_node) {
-  MaxNodeDesc *node_desc = r_build_node(max_node);
-  node_desc->from_INode(max_node);
-
-  if (node_desc->is_node_joint()) {
-    node_desc->_joint_entry = build_joint(max_node, node_desc);
-  }
-  return node_desc;
-}
-
-/**
- * Returns a pointer to the node corresponding to the indicated INode object,
- * creating it first if necessary.
- */
-MaxNodeDesc *MaxNodeTree::
-build_joint(INode *max_node, MaxNodeDesc *node_joint) {
-  MaxNodeDesc *node_desc = r_build_joint(node_joint, max_node);
-  node_desc->from_INode(max_node);
-  node_desc->set_joint(true);
-  return node_desc;
-}
-
-bool MaxNodeTree::node_in_list(ULONG handle, ULONG *list, int len) {
-  if (!list) return true;
-  for (int i = 0; i < len; i++)
-    if (list[i] == handle) return true;
-  return false;
-}
-
-bool MaxNodeTree::is_joint(INode *node) {
-  Control *c = node->GetTMController();
-  return (node->GetBoneNodeOnOff() ||                    //joints
-         (c &&                                           //bipeds
-         ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
-         (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
-         (c->ClassID() == FOOTPRINT_CLASS_ID))));
-}
-
-bool MaxNodeTree::
-r_build_hierarchy(INode *root, ULONG *selection_list, int len) {
-  if (node_in_list(root->GetHandle(), selection_list, len))
-    build_node(root);
-  // Export children
-  for ( int i = 0; i < root->NumberOfChildren(); i++ ) {
-    // *** Should probably be checking the return value of the following line
-    r_build_hierarchy(root->GetChildNode(i), selection_list, len);
-  }
-  return true;
-}
-/**
- * Walks through the complete Max hierarchy and builds up the corresponding
- * tree.
- */
-bool MaxNodeTree::
-build_complete_hierarchy(INode *root, ULONG *selection_list, int len) {
-
-  // Get the entire Max scene.
-  if (root == nullptr) {
-    // *** Log an error
-    return false;
-  }
-
-  bool all_ok = true;
-  r_build_hierarchy(root, selection_list, len);
-
-  if (all_ok) {
-    _root->check_pseudo_joints(false);
-  }
-
-  return all_ok;
-}
-
-/**
- * Returns the total number of nodes in the hierarchy, not counting the root
- * node.
- */
-int MaxNodeTree::
-get_num_nodes() const {
-  return _nodes.size();
-}
-
-/**
- * Returns the nth node in the hierarchy, in an arbitrary ordering.
- */
-MaxNodeDesc *MaxNodeTree::
-get_node(int n) const {
-  nassertr(n >= 0 && n < (int)_nodes.size(), nullptr);
-  return _nodes[n];
-}
-
-/**
- * Removes all of the references to generated egg structures from the tree,
- * and prepares the tree for generating new egg structures.
- */
-void MaxNodeTree::
-clear_egg(EggData *egg_data, EggGroupNode *egg_root,
-          EggGroupNode *skeleton_node) {
-  _root->clear_egg();
-  _egg_data = egg_data;
-  _egg_root = egg_root;
-  _skeleton_node = skeleton_node;
-}
-
-/**
- * Returns the EggGroupNode corresponding to the group or joint for the
- * indicated node.  Creates the group node if it has not already been created.
- */
-EggGroup *MaxNodeTree::
-get_egg_group(MaxNodeDesc *node_desc) {
-  nassertr(_egg_root != nullptr, nullptr);
-
-  if (node_desc->_egg_group == nullptr) {
-    // We need to make a new group node.
-    EggGroup *egg_group;
-
-    nassertr(node_desc->_parent != nullptr, nullptr);
-    egg_group = new EggGroup(node_desc->get_name());
-    if (node_desc->is_joint()) {
-      egg_group->set_group_type(EggGroup::GT_joint);
-    }
-    if (node_desc->_parent == _root) {
-      // The parent is the root.  Set collision properties for the root if it
-      // has them:
-      if(!_export_mesh)
-      {
-          set_collision_tags(node_desc, egg_group);
-      }
-      _egg_root->add_child(egg_group);
-
-    } else {
-      // The parent is another node.  if export mesh, the tag should be added
-      // at the second level
-      if(_export_mesh)
-      {
-        if(node_desc->_parent->_parent == _root)
-        {
-            set_collision_tags(node_desc, egg_group);
-        }
-      }
-      EggGroup *parent_egg_group = get_egg_group(node_desc->_parent);
-      parent_egg_group->add_child(egg_group);
-    }
-
-    node_desc->_egg_group = egg_group;
-  }
-
-  return node_desc->_egg_group;
-}
-
-/**
- * Returns the EggTable corresponding to the joint for the indicated node.
- * Creates the table node if it has not already been created.
- */
-EggTable *MaxNodeTree::
-get_egg_table(MaxNodeDesc *node_desc) {
-  nassertr(_skeleton_node != nullptr, nullptr);
-  nassertr(node_desc->is_joint(), nullptr);
-
-  if (node_desc->_egg_table == nullptr) {
-    // We need to make a new table node.
-    nassertr(node_desc->_parent != nullptr, nullptr);
-
-    EggTable *egg_table = new EggTable(node_desc->get_name());
-    node_desc->_anim = new EggXfmSAnim("xform",
-                                       _egg_data->get_coordinate_system());
-    node_desc->_anim->set_fps(_fps);
-    egg_table->add_child(node_desc->_anim);
-
-    if (!node_desc->_parent->is_joint()) {
-      // The parent is not a joint; put it at the top.
-      _skeleton_node->add_child(egg_table);
-
-    } else {
-      // The parent is another joint.
-      EggTable *parent_egg_table = get_egg_table(node_desc->_parent);
-      parent_egg_table->add_child(egg_table);
-    }
-
-    node_desc->_egg_table = egg_table;
-  }
-
-  return node_desc->_egg_table;
-}
-
-/**
- * Returns the anim table corresponding to the joint for the indicated node.
- * Creates the table node if it has not already been created.
- */
-EggXfmSAnim *MaxNodeTree::
-get_egg_anim(MaxNodeDesc *node_desc) {
-  get_egg_table(node_desc);
-  return node_desc->_anim;
-}
-
-/**
- * The recursive implementation of build_node().
- */
-MaxNodeDesc *MaxNodeTree::
-r_build_node(INode* max_node) {
-  // If we have already encountered this pathname, return the corresponding
-  // MaxNodeDesc immediately.
-
-  ULONG node_handle = 0;
-
-  if (max_node) {
-    node_handle = max_node->GetHandle();
-  }
-
-  NodesByPath::const_iterator ni = _nodes_by_path.find(node_handle);
-  if (ni != _nodes_by_path.end()) {
-    return (*ni).second;
-  }
-
-  // Otherwise, we have to create it.  Do this recursively, so we create each
-  // node along the path.
-  MaxNodeDesc *node_desc;
-
-  if (!max_node) {
-    // This is the top.
-    node_desc = _root;
-
-  } else {
-    INode *parent_node;
-
-    if (max_node->IsRootNode()) {
-      parent_node = nullptr;
-    } else {
-      parent_node = max_node->GetParentNode();
-    }
-
-    MaxNodeDesc *parent_node_desc = r_build_node(parent_node);
-    node_desc = new MaxNodeDesc(parent_node_desc, max_node);
-    _nodes.push_back(node_desc);
-  }
-
-  _nodes_by_path.insert(NodesByPath::value_type(node_handle, node_desc));
-  return node_desc;
-}
-
-/**
- * The recursive implementation of build_joint().
- */
-MaxNodeDesc *MaxNodeTree::
-r_build_joint(MaxNodeDesc *node_desc, INode *max_node)
-{
-  MaxNodeDesc *node_joint;
-  if (node_desc == _root) {
-    node_joint = new MaxNodeDesc(_root, max_node);
-    _nodes.push_back(node_joint);
-    return node_joint;
-  } else if (node_desc->is_node_joint() && node_desc->_joint_entry) {
-    node_joint = new MaxNodeDesc(node_desc->_joint_entry, max_node);
-    _nodes.push_back(node_joint);
-    return node_joint;
-  } else {
-    return r_build_joint(node_desc->_parent, max_node);
-  }
-}
-
-/**
- * The recursive implementation of build_node().
- */
-MaxNodeDesc *MaxNodeTree::
-find_node(INode* max_node) {
-  // If we have already encountered this pathname, return the corresponding
-  // MaxNodeDesc immediately.
-
-  ULONG node_handle = 0;
-
-  if (max_node) {
-    node_handle = max_node->GetHandle();
-  }
-
-  NodesByPath::const_iterator ni = _nodes_by_path.find(node_handle);
-  if (ni != _nodes_by_path.end()) {
-    return (*ni).second;
-  }
-
-  return nullptr;
-}
-
-/**
- * The recursive implementation of build_node().
- */
-MaxNodeDesc *MaxNodeTree::
-find_joint(INode* max_node)
-{
-  MaxNodeDesc *node = find_node(max_node);
-  if (!node || (is_joint(max_node) && !node->is_node_joint()))
-    node = build_node(max_node);
-  return node->_joint_entry;
-}
-
-/**
- * Sets the corresponding collision tag to the egg_group based on the User
- * Defined Tab in the object properties panel
- */
-void MaxNodeTree::set_collision_tags(MaxNodeDesc *node_desc, EggGroup *egg_group) {
-    // Max has huge problems passing strings and bools to Get and SetUserProp
-    // So instead we have to use Integers.  Now we have to check for every
-    // collide type, then get its collide flags and do some number crunching
-    // to get the actual flag into the group
-
-    int check = 1; //is the value true. This could be anything really
-
-      // We have to check each collision type in turn to see if it's true Ugly
-      // but it works per object, not globaly
-    if (node_desc->get_max_node()->GetUserPropInt(_T("polyset"), check)) {
-        // we have a polyset.
-      if (check == 1) {
-        egg_group->set_collision_name(node_desc->get_name());
-        egg_group->set_cs_type(EggGroup::CST_polyset);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("plane"), check)) {
-      // plane
-      if (check == 1) {
-        egg_group->set_collision_name(node_desc->get_name());
-        egg_group->set_cs_type(EggGroup::CST_plane);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("polygon"), check)) {
-      // polygon
-      if (check == 1) {
-        egg_group->set_collision_name(node_desc->get_name());
-        egg_group->set_cs_type(EggGroup::CST_polygon);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("sphere"), check)) {
-      // sphere
-      if (check == 1) {
-        egg_group->set_collision_name(node_desc->get_name());
-        egg_group->set_cs_type(EggGroup::CST_sphere);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("inv-sphere"), check)) {
-      // invsphere
-      if (check == 1) {
-        egg_group->set_collision_name(node_desc->get_name());
-        egg_group->set_cs_type(EggGroup::CST_inv_sphere);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("invsphere"), check)) {
-      // invsphere (different spelling)
-      if (check == 1) {
-        egg_group->set_collision_name(node_desc->get_name());
-        egg_group->set_cs_type(EggGroup::CST_inv_sphere);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("tube"), check)) {
-      // tube
-      if (check == 1) {
-        egg_group->set_collision_name(node_desc->get_name());
-        egg_group->set_cs_type(EggGroup::CST_tube);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("floor-mesh"), check)) {
-      // floor-mesh
-      if (check == 1) {
-        egg_group->set_collision_name(node_desc->get_name());
-        egg_group->set_cs_type(EggGroup::CST_floor_mesh);
-      }
-    }
-
-    if (node_desc->get_max_node()->GetUserPropInt(_T("descend"), check)) {
-      if (check == 1) {
-      // we have the descend flag specified
-      egg_group->set_collide_flags(EggGroup::CF_descend);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("event"), check)) {
-      if (check == 1) {
-      // we have the event flag specified
-      egg_group->set_collide_flags(EggGroup::CF_event);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("keep"), check)) {
-      if (check == 1) {
-      // we have the keep flag specified
-      egg_group->set_collide_flags(EggGroup::CF_keep);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("solid"), check)) {
-      if (check == 1) {
-      // we have the solid flag specified
-      egg_group->set_collide_flags(EggGroup::CF_solid);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("center"), check)) {
-      if (check == 1) {
-      // we have the center flag specified
-      egg_group->set_collide_flags(EggGroup::CF_center);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("turnstile"), check)) {
-      if (check == 1) {
-      // we have the turnstile flag specified
-      egg_group->set_collide_flags(EggGroup::CF_turnstile);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("level"), check)) {
-      if (check == 1) {
-      // we have the level flag specified
-      egg_group->set_collide_flags(EggGroup::CF_level);
-      }
-    }
-    if (node_desc->get_max_node()->GetUserPropInt(_T("intangible"), check)) {
-      if (check == 1) {
-      // we have the intangible flag specified
-      egg_group->set_collide_flags(EggGroup::CF_intangible);
-      }
-    }
-    return;
-}

+ 0 - 66
pandatool/src/maxegg/maxNodeTree.h

@@ -1,66 +0,0 @@
-/**
- * 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."
- *
- * @file maxNodeTree.h
- * @author crevilla
- * from mayaNodeTree.h created by:  drose (06Jun03)
- */
-
-#ifndef MAXNODETREE_H
-#define MAXNODETREE_H
-
-class EggData;
-class EggGroupNode;
-
-/**
- * Describes a complete tree of max nodes for conversion.
- */
-class MaxNodeTree {
-public:
-  MaxNodeTree();
-  MaxNodeDesc *build_node(INode *max_node);
-  MaxNodeDesc *build_joint(INode *max_node, MaxNodeDesc *node_joint);
-  bool build_complete_hierarchy(INode *root, ULONG *selection_list, int len);
-  MaxNodeDesc *find_node(INode *max_node);
-  MaxNodeDesc *find_joint(INode *max_node);
-
-  int get_num_nodes() const;
-  MaxNodeDesc *get_node(int n) const;
-
-  void clear_egg(EggData *egg_data, EggGroupNode *egg_root,
-                 EggGroupNode *skeleton_node);
-  EggGroup *get_egg_group(MaxNodeDesc *node_desc);
-  EggTable *get_egg_table(MaxNodeDesc *node_desc);
-  EggXfmSAnim *get_egg_anim(MaxNodeDesc *node_desc);
-
-  MaxNodeDesc* _root;
-  PN_stdfloat _fps;
-  // the flag for the setting up collision bool _has_collision;
-  // EggGroup::CollideFlags _cf_type; EggGroup::CollisionSolidType _cs_type;
-  bool _export_mesh;
-
-private:
-  EggData *_egg_data;
-  EggGroupNode *_egg_root;
-  EggGroupNode *_skeleton_node;
-
-  MaxNodeDesc *r_build_node(INode *max_node);
-  MaxNodeDesc *r_build_joint(MaxNodeDesc *node_desc, INode *max_node);
-  bool node_in_list(ULONG handle, ULONG *list, int len);
-  bool r_build_hierarchy(INode *root, ULONG *selection_list, int len);
-  bool is_joint(INode *node);
-  void set_collision_tags(MaxNodeDesc *node_desc, EggGroup *egg_group);
-
-  typedef pmap<ULONG, MaxNodeDesc *> NodesByPath;
-  NodesByPath _nodes_by_path;
-
-  typedef pvector<MaxNodeDesc *> Nodes;
-  Nodes _nodes;
-};
-
-#endif

+ 0 - 701
pandatool/src/maxegg/maxOptionsDialog.cxx

@@ -1,701 +0,0 @@
-/*
-  maxEggExpOptions.cxx
-  Created by Phillip Saltzman, 2/15/05
-  Carnegie Mellon University, Entetainment Technology Center
-
-  This file implements the classes that are used to choose
-  what to export from 3D Studio max
-
-  Updated by Fei Wang, Carnegie Mellon University Entertainment
-  Technology Center student, 14Aug2009:  added enableAddCollisionChoices
-*/
-
-#include "maxEgg.h"
-
-// Disable the forcing int to true or false performance warning
-#pragma warning(disable: 4800)
-
-void SetICustEdit(HWND wnd, int nIDDlgItem, TCHAR *text)
-{
-  ICustEdit *edit = GetICustEdit(GetDlgItem(wnd, nIDDlgItem));
-  edit->SetText(text);
-  ReleaseICustEdit(edit);
-}
-
-void SetICustEdit(HWND wnd, int nIDDlgItem, int n)
-{
-  TCHAR text[80];
-  _stprintf(text, _T("%d"), n);
-  ICustEdit *edit = GetICustEdit(GetDlgItem(wnd, nIDDlgItem));
-  edit->SetText(text);
-  ReleaseICustEdit(edit);
-}
-
-TCHAR *GetICustEditT(HWND wnd)
-{
-  static TCHAR buffer[2084];
-  ICustEdit *edit = GetICustEdit(wnd);
-  edit->GetText(buffer, 2084);
-  ReleaseICustEdit(edit);
-  return buffer;
-}
-
-int GetICustEditI(HWND wnd, BOOL *valid)
-{
-  ICustEdit *edit = GetICustEdit(wnd);
-  int i = edit->GetInt(valid);
-  ReleaseICustEdit(edit);
-  return i;
-}
-
-void ChunkSave(ISave *isave, int chunkid, int value)
-{
-  ULONG nb;
-  isave->BeginChunk(chunkid);
-  isave->Write(&value, sizeof(int), &nb);
-  isave->EndChunk();
-}
-
-void ChunkSave(ISave *isave, int chunkid, ULONG value)
-{
-  ULONG nb;
-  isave->BeginChunk(chunkid);
-  isave->Write(&value, sizeof(ULONG), &nb);
-  isave->EndChunk();
-}
-
-void ChunkSave(ISave *isave, int chunkid, bool value)
-{
-  ULONG nb;
-  isave->BeginChunk(chunkid);
-  isave->Write(&value, sizeof(bool), &nb);
-  isave->EndChunk();
-}
-
-void ChunkSave(ISave *isave, int chunkid, TCHAR *value)
-{
-  ULONG nb;
-  isave->BeginChunk(chunkid);
-  int length = _tcslen(value) + 1;
-  isave->Write(&length, sizeof(int), &nb);
-  isave->Write(value, length * sizeof(TCHAR), &nb);
-  isave->EndChunk();
-}
-
-TCHAR *ChunkLoadString(ILoad *iload, TCHAR *buffer, int maxLength)
-{
-  ULONG nb;
-  int length;
-  IOResult res;
-  res = iload->Read(&length, sizeof(int), &nb);
-  assert(res == IO_OK && length <= maxLength);
-  res = iload->Read(buffer, length * sizeof(TCHAR), &nb);
-  assert(res == IO_OK);
-  return buffer;
-}
-
-int ChunkLoadInt(ILoad *iload)
-{
-  ULONG nb;
-  int value;
-  IOResult res;
-  res = iload->Read(&value, sizeof(int), &nb);
-  assert(res == IO_OK);
-  return value;
-}
-
-int ChunkLoadULONG(ILoad *iload)
-{
-  ULONG nb, value;
-  IOResult res;
-  res = iload->Read(&value, sizeof(ULONG), &nb);
-  assert(res == IO_OK);
-  return value;
-}
-
-bool ChunkLoadBool(ILoad *iload)
-{
-  ULONG nb;
-  bool value;
-  IOResult res;
-  res = iload->Read(&value, sizeof(bool), &nb);
-  assert(res == IO_OK);
-  return value;
-}
-
-void showAnimControls(HWND hWnd, BOOL val) {
-  ShowWindow(GetDlgItem(hWnd, IDC_EF_LABEL), val);
-  ShowWindow(GetDlgItem(hWnd, IDC_EF), val);
-  ShowWindow(GetDlgItem(hWnd, IDC_SF_LABEL), val);
-  SetWindowText(GetDlgItem(hWnd, IDC_EXP_SEL_FRAMES),
-                val ? _T("Use Range:") : _T("Use Frame:"));
-}
-
-void enableAnimControls(HWND hWnd, BOOL val) {
-  EnableWindow(GetDlgItem(hWnd, IDC_SF_LABEL), val);
-  EnableWindow(GetDlgItem(hWnd, IDC_SF), val);
-  EnableWindow(GetDlgItem(hWnd, IDC_EF_LABEL), val);
-  EnableWindow(GetDlgItem(hWnd, IDC_EF), val);
-}
-
-void enableChooserControls(HWND hWnd, BOOL val) {
-  EnableWindow(GetDlgItem(hWnd, IDC_LIST_EXPORT), val);
-  EnableWindow(GetDlgItem(hWnd, IDC_ADD_EXPORT), val);
-  EnableWindow(GetDlgItem(hWnd, IDC_REMOVE_EXPORT), val);
-}
-
-
-#define ANIM_RAD_NONE 0
-#define ANIM_RAD_EXPALL 1
-#define ANIM_RAD_EXPSEL 2
-#define ANIM_RAD_ALL    3
-void enableAnimRadios(HWND hWnd, int mask) {
-  EnableWindow(GetDlgItem(hWnd, IDC_EXP_ALL_FRAMES), mask & ANIM_RAD_EXPALL);
-  EnableWindow(GetDlgItem(hWnd, IDC_EXP_SEL_FRAMES), mask & ANIM_RAD_EXPSEL);
-}
-
-// Handles the work of actually picking the target.
-class AddNodeCB : public HitByNameDlgCallback
-{
-public:
-  MaxOptionsDialog *ph; //Pointer to the parent class
-  HWND hWnd;            //Handle to the parent dialog
-
-  AddNodeCB (MaxOptionsDialog *instance, HWND wnd) :
-    ph(instance), hWnd(wnd) {}
-
-#if MAX_VERSION_MAJOR < 15
-  virtual TCHAR *dialogTitle() {return _T("Objects to Export");}
-  virtual TCHAR *buttonText()  {return _T("Select");}
-#else
-  virtual const MCHAR *dialogTitle() {return _M("Objects to Export");}
-  virtual const MCHAR *buttonText()  {return _M("Select");}
-#endif
-
-  virtual int filter(INode *node);
-  virtual void proc(INodeTab &nodeTab);
-};
-
-// This tells what should be in the list Allow only triangular objects, nurbs,
-// and joints
-int AddNodeCB::filter(INode *node) {
-  if (!node) return 0;
-
-  Object *obj = node->EvalWorldState(0).obj;
-  Control *c = node->GetTMController();
-  NURBSSet getSet;
-  bool is_bone = (node->GetBoneNodeOnOff() ||     //True for bones
-     (c &&                                          //True for bipeds
-     ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
-     (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
-     (c->ClassID() == FOOTPRINT_CLASS_ID))));
-
-
-  if (IsDlgButtonChecked(hWnd, IDC_ANIMATION) == BST_CHECKED)
-    return is_bone && !ph->FindNode(node->GetHandle());
-  else
-    return (
-    is_bone || ((obj->SuperClassID() == HELPER_CLASS_ID && obj->ClassID() != MaxEggPlugin_CLASS_ID)) ||
-    ((obj->SuperClassID() == GEOMOBJECT_CLASS_ID && //Allow geometrics
-      obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) ||
-     (obj->SuperClassID() == SHAPE_CLASS_ID &&      //Allow CV NURBS
-      obj->ClassID() == EDITABLE_SURF_CLASS_ID &&
-      GetNURBSSet(obj, 0, getSet, TRUE) &&
-      getSet.GetNURBSObject(0)->GetType() == kNCVCurve)) &&
-    !ph->FindNode(node->GetHandle()));             //Only allow items not already selected
-}
-
-// Adds all of the selected items to the list
-void AddNodeCB::proc(INodeTab &nodeTab) {
-
-  for (int i = 0; i < nodeTab.Count(); i++)
-    ph->AddNode(nodeTab[i]->GetHandle());
-  ph->RefreshNodeList(hWnd);
-}
-
-// This callback class generates a list of nodes that have previously been
-// selected
-class RemoveNodeCB : public HitByNameDlgCallback
-{
-public:
-    MaxOptionsDialog *ph; //Pointer to the parent class
-    HWND hWnd;            //Handle to the parent dialog
-
-    RemoveNodeCB (MaxOptionsDialog *instance, HWND wnd) :
-        ph(instance), hWnd(wnd) {}
-
-#if MAX_VERSION_MAJOR < 15
-    virtual TCHAR *dialogTitle() {return _T("Objects to Remove");}
-    virtual TCHAR *buttonText()  {return _T("Remove");}
-#else
-    virtual const MCHAR *dialogTitle() {return _M("Objects to Remove");}
-    virtual const MCHAR *buttonText()  {return _M("Remove");}
-#endif
-
-    virtual int filter(INode *node) {return (node && ph->FindNode(node->GetHandle()));}
-    virtual void proc(INodeTab &nodeTab);
-};
-
-
-// Adds all of the selected items to the list
-void RemoveNodeCB::proc(INodeTab &nodeTab) {
-    for (int i = 0; i < nodeTab.Count(); i++)
-        ph->RemoveNodeByHandle(nodeTab[i]->GetHandle());
-    ph->RefreshNodeList(hWnd);
-}
-
-MaxEggOptions::MaxEggOptions() {
-    _max_interface = nullptr;
-    _anim_type = MaxEggOptions::AT_model;
-    _start_frame = INT_MIN;
-    _end_frame = INT_MIN;
-    _double_sided = false;
-
-
-    _file_name[0]=0;
-    _short_name[0]=0;
-    _path_replace = new PathReplace;
-    _path_replace->_path_store = PS_relative;
-    _export_whole_scene = true;
-    _export_all_frames = true;
-    _successful = false;
-}
-
-INT_PTR CALLBACK MaxOptionsDialogProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
-{
-    TCHAR tempFilename[2048];
-    // We pass in our plugin through the lParam variable.  Let's convert it
-    // back.
-    MaxOptionsDialog *imp = (MaxOptionsDialog*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
-    if ( !imp && message != WM_INITDIALOG ) return FALSE;
-
-    switch(message) {
-
-    case WM_INITDIALOG:
-        // this line is very necessary to pass the plugin as the lParam
-        SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam);
-        ((MaxOptionsDialog*)lParam)->UpdateUI(hWnd);
-
-        return TRUE; break;
-
-    case WM_CLOSE:
-        EndDialog(hWnd, FALSE);
-        return TRUE; break;
-
-    case WM_COMMAND:
-        // The modified control is found in the lower word of the wParam long.
-        switch( LOWORD(wParam) ) {
-        case IDC_MODEL:
-            if (HIWORD(wParam) == BN_CLICKED) {
-                SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
-                              _T("Export Meshes:"));
-                enableAnimRadios(hWnd, ANIM_RAD_NONE);
-                showAnimControls(hWnd, TRUE);
-                enableAnimControls(hWnd, FALSE);
-                if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
-                imp->_prev_type = MaxEggOptions::AT_model;
-
-                return TRUE;
-            }
-            break;
-
-        case IDC_ANIMATION:
-            if (HIWORD(wParam) == BN_CLICKED) {
-                SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
-                              _T("Export Bones:"));
-                enableAnimRadios(hWnd, ANIM_RAD_ALL);
-                showAnimControls(hWnd, TRUE);
-                enableAnimControls(hWnd, IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES));
-                if (imp->_prev_type != MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
-                imp->_prev_type = MaxEggOptions::AT_chan;
-                CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_ALL_FRAMES);
-
-                return TRUE;
-            }
-            break;
-        case IDC_BOTH:
-            if (HIWORD(wParam) == BN_CLICKED) {
-                SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
-                              _T("Export Models:"));
-                enableAnimRadios(hWnd, ANIM_RAD_ALL);
-                showAnimControls(hWnd, TRUE);
-                enableAnimControls(hWnd, IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES));
-                if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
-                imp->_prev_type = MaxEggOptions::AT_both;
-                CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_ALL_FRAMES);
-
-                return TRUE;
-            }
-            break;
-        case IDC_POSE:
-            if (HIWORD(wParam) == BN_CLICKED) {
-                SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
-                              _T("Export Meshes:"));
-                enableAnimRadios(hWnd, ANIM_RAD_EXPSEL);
-                showAnimControls(hWnd, FALSE);
-                enableAnimControls(hWnd, TRUE);
-                CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_SEL_FRAMES);
-                if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
-                imp->_prev_type = MaxEggOptions::AT_pose;
-
-                return TRUE;
-            }
-            break;
-        case IDC_EXP_ALL_FRAMES:
-            if (HIWORD(wParam) == BN_CLICKED) {
-                enableAnimControls(hWnd, FALSE);
-                if(imp->_prev_type == MaxEggOptions::AT_chan)
-                {
-                  CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_ANIMATION);
-                }
-                if(imp->_prev_type == MaxEggOptions::AT_both)
-                {
-                  CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_BOTH);
-                }
-                return TRUE;
-            }
-            break;
-
-        case IDC_EXP_SEL_FRAMES:
-            if (HIWORD(wParam) == BN_CLICKED) {
-                enableAnimControls(hWnd, TRUE);
-                if(imp->_prev_type == MaxEggOptions::AT_chan)
-                {
-                  CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_ANIMATION);
-                }
-                if(imp->_prev_type == MaxEggOptions::AT_both)
-                {
-                  CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_BOTH);
-                }
-                return TRUE;
-            }
-            break;
-
-        case IDC_EXPORT_ALL:
-            if (HIWORD(wParam) == BN_CLICKED) {
-                enableChooserControls(hWnd, FALSE);
-                return TRUE;
-            }
-            break;
-
-        case IDC_EXPORT_SELECTED:
-            if (HIWORD(wParam) == BN_CLICKED) {
-                enableChooserControls(hWnd, TRUE);
-                return TRUE;
-            }
-            break;
-
-
-        // deal with adding meshes
-        case IDC_ADD_EXPORT:
-            {
-                if (!imp->_choosing_nodes) {
-                    AddNodeCB PickCB(imp, hWnd);
-                    imp->_choosing_nodes = true;
-                    imp->_max_interface->DoHitByNameDialog(&PickCB);
-                    imp->_choosing_nodes = false;
-                }
-            }
-            return TRUE; break;
-
-        case IDC_REMOVE_EXPORT:
-            {
-                if (!imp->_choosing_nodes) {
-                    imp->_choosing_nodes = true;
-                    RemoveNodeCB PickCB(imp, hWnd);
-                    imp->_max_interface->DoHitByNameDialog(&PickCB);
-                    imp->_choosing_nodes = false;
-                }
-            }
-            return TRUE; break;
-
-        case IDC_OK:
-            if (imp->UpdateFromUI(hWnd)) EndDialog(hWnd, TRUE);
-            return TRUE; break;
-        case IDC_CANCEL:
-            EndDialog(hWnd, FALSE);
-            return TRUE; break;
-        case IDC_BROWSE:
-            OPENFILENAME ofn;
-            _tcscpy(tempFilename, GetICustEditT(GetDlgItem(hWnd, IDC_FILENAME)));
-
-            memset(&ofn, 0, sizeof(ofn));
-            ofn.nMaxFile = 2047;
-            ofn.lpstrFile = tempFilename;
-            ofn.lStructSize = sizeof(ofn);
-            ofn.hwndOwner = hWnd;
-            ofn.Flags = OFN_HIDEREADONLY | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST;
-            ofn.lpstrDefExt = _T("egg");
-            ofn.lpstrFilter = _T("Panda3D Egg Files (*.egg)\0*.egg\0All Files (*.*)\0*.*\0");
-
-            SetFocus(GetDlgItem(hWnd, IDC_FILENAME));
-            if (GetSaveFileName(&ofn))
-                SetICustEdit(hWnd, IDC_FILENAME, ofn.lpstrFile);
-            // else { char buf[255]; sprintf(buf, "%d",
-            // CommDlgExtendedError()); MessageBox(hWnd, buf, "Error on
-            // GetSaveFileName", MB_OK); }
-            return TRUE; break;
-        case IDC_CHECK1:
-            if (IsDlgButtonChecked(hWnd, IDC_CHECK1))
-                if (MessageBox(hWnd, _T("Warning: Exporting double-sided polygons can severely hurt ")
-                               _T("performance in Panda3D.\n\nAre you sure you want to export them?"),
-                               _T("Panda3D Exporter"), MB_YESNO | MB_ICONQUESTION) != IDYES)
-                    CheckDlgButton(hWnd, IDC_CHECK1, BST_UNCHECKED);
-            return TRUE; break;
-
-        default:
-            // char buf[255]; sprintf(buf, "%d", LOWORD(wParam));
-            // MessageBox(hWnd, buf, "Unknown WParam", MB_OK);
-            break;
-        }
-    }
-    return FALSE;
-}
-
-void MaxOptionsDialog::SetAnimRange() {
-    // Get the start and end frames and the animation frame rate from Max
-    Interval anim_range = _max_interface->GetAnimRange();
-    _min_frame = anim_range.Start()/GetTicksPerFrame();
-    _max_frame = anim_range.End()/GetTicksPerFrame();
-}
-
-MaxOptionsDialog::MaxOptionsDialog() :
-    MaxEggOptions(),
-    _min_frame(0),
-    _max_frame(0),
-    _checked(true),
-    _choosing_nodes(false),
-    _prev_type(AT_model)
-{
-}
-
-MaxOptionsDialog::~MaxOptionsDialog ()
-{
-}
-
-
-void MaxOptionsDialog::UpdateUI(HWND hWnd) {
-    int typeButton = IDC_MODEL;
-    int anim_exp = _export_all_frames ? IDC_EXP_ALL_FRAMES : IDC_EXP_SEL_FRAMES;
-    int model_exp = _export_whole_scene ? IDC_EXPORT_ALL : IDC_EXPORT_SELECTED;
-
-    switch (_anim_type) {
-    case MaxEggOptions::AT_chan:  typeButton = IDC_ANIMATION; break;
-    case MaxEggOptions::AT_both:  typeButton = IDC_BOTH; break;
-    case MaxEggOptions::AT_pose:  typeButton = IDC_POSE; break;
-    case MaxEggOptions::AT_model: typeButton = IDC_MODEL; break;
-    }
-
-    _prev_type = _anim_type;
-
-    CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, typeButton);
-    SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(typeButton, BN_CLICKED), 0);
-    CheckRadioButton(hWnd, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, model_exp);
-    SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(model_exp, BN_CLICKED), 0);
-    CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, anim_exp);
-    SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(anim_exp, BN_CLICKED), 0);
-
-    CheckDlgButton(hWnd, IDC_CHECK1,
-                   _double_sided ? BST_CHECKED : BST_UNCHECKED);
-
-
-    SetICustEdit(hWnd, IDC_FILENAME, _file_name);
-    if (_start_frame != INT_MIN) {
-        SetICustEdit(hWnd, IDC_SF, _start_frame);
-        SetICustEdit(hWnd, IDC_EF, _end_frame);
-    } else {
-        SetICustEdit(hWnd, IDC_SF, _min_frame);
-        SetICustEdit(hWnd, IDC_EF, _max_frame);
-    }
-
-    RefreshNodeList(hWnd);
-}
-
-void MaxOptionsDialog::ClearNodeList(HWND hWnd) {
-    _node_list.clear();
-    RefreshNodeList(hWnd);
-}
-
-void MaxOptionsDialog::RefreshNodeList(HWND hWnd) {
-  // Clear and repopulate the node box
-  HWND nodeLB = GetDlgItem(hWnd, IDC_LIST_EXPORT);
-  SendMessage(nodeLB, LB_RESETCONTENT, 0, 0);
-  for (int i = 0; i < _node_list.size(); i++) {
-      INode *temp = _max_interface->GetINodeByHandle(_node_list[i]);
-      const TCHAR *name = _T("Unknown Node");
-      if (temp) name = temp->GetName();
-      SendMessage(nodeLB, LB_ADDSTRING, 0, (LPARAM)name);
-  }
-}
-
-bool MaxOptionsDialog::UpdateFromUI(HWND hWnd) {
-  BOOL valid;
-  Anim_Type newAnimType;
-  int newSF = INT_MIN, newEF = INT_MIN;
-  TCHAR msg[1024];
-
-  if (IsDlgButtonChecked(hWnd, IDC_MODEL))          newAnimType = MaxEggOptions::AT_model;
-  else if (IsDlgButtonChecked(hWnd, IDC_ANIMATION)) newAnimType = MaxEggOptions::AT_chan;
-  else if (IsDlgButtonChecked(hWnd, IDC_BOTH))      newAnimType = MaxEggOptions::AT_both;
-  else                                              newAnimType = MaxEggOptions::AT_pose;
-
-  if (newAnimType != MaxEggOptions::AT_model && IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES)) {
-      newSF = GetICustEditI(GetDlgItem(hWnd, IDC_SF), &valid);
-      if (!valid) {
-          MessageBox(hWnd, _T("Start Frame must be an integer"), _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
-          return false;
-      }
-      if (newSF < _min_frame) {
-          _stprintf(msg, _T("Start Frame must be at least %d"), _min_frame);
-          MessageBox(hWnd, msg, _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
-          return false;
-      }
-      if (newSF > _max_frame) {
-          _stprintf(msg, _T("Start Frame must be at most %d"), _max_frame);
-          MessageBox(hWnd, msg, _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
-          return false;
-      }
-      if (newAnimType != MaxEggOptions::AT_pose) {
-          newEF = GetICustEditI(GetDlgItem(hWnd, IDC_EF), &valid);
-          if (!valid) {
-              MessageBox(hWnd, _T("End Frame must be an integer"), _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
-              return false;
-          }
-          if (newEF > _max_frame) {
-              _stprintf(msg, _T("End Frame must be at most %d"), _max_frame);
-              MessageBox(hWnd, msg, _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
-              return false;
-          }
-          if (newEF < newSF) {
-              MessageBox(hWnd, _T("End Frame must be greater than the start frame"), _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
-              return false;
-          }
-      }
-  }
-
-  TCHAR *temp = GetICustEditT(GetDlgItem(hWnd, IDC_FILENAME));
-  if (!_tcslen(temp)) {
-    MessageBox(hWnd, _T("The filename cannot be empty"), _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
-    return false;
-  }
-
-  if (_tcslen(temp) < 4 || _tcsncmp(_T(".egg"), temp+(_tcslen(temp) - 4), 4)) {
-    _stprintf(_file_name, _T("%s.egg"), temp);
-  } else {
-    _tcscpy(_file_name, temp);
-  }
-
-  temp = _tcsrchr(_file_name, '\\');
-  if (!temp) temp = _file_name;
-  else temp++;
-
-  if (_tcslen(temp) > sizeof(_short_name))
-    _stprintf(_short_name, _T("%.*s..."), sizeof(_short_name)-4, temp);
-  else {
-    _tcscpy(_short_name, temp);
-    _short_name[_tcslen(_short_name) - 4] = 0; //Cut off the .egg
-  }
-
-  _start_frame = newSF;
-  _end_frame = newEF;
-  _anim_type = newAnimType;
-  _double_sided = IsDlgButtonChecked(hWnd, IDC_CHECK1);
-
-
-  _export_whole_scene = IsDlgButtonChecked(hWnd, IDC_EXPORT_ALL);
-  _export_all_frames = IsDlgButtonChecked(hWnd, IDC_EXP_ALL_FRAMES);
-
-  return true;
-}
-
-bool MaxOptionsDialog::FindNode(ULONG INodeHandle) {
-    for (int i = 0; i < _node_list.size(); i++)
-        if (_node_list[i] == INodeHandle) return true;
-    return false;
-}
-
-void MaxOptionsDialog::AddNode(ULONG INodeHandle) {
-  if (FindNode(INodeHandle)) return;
-  _node_list.push_back(INodeHandle);
-}
-
-void MaxOptionsDialog::CullBadNodes() {
-  if (!_max_interface) return;
-  std::vector<ULONG> good;
-  for (int i=0; i<_node_list.size(); i++) {
-      ULONG handle = _node_list[i];
-      if (_max_interface->GetINodeByHandle(handle)) {
-          good.push_back(handle);
-      }
-  }
-  _node_list = good;
-}
-
-void MaxOptionsDialog::RemoveNode(int i) {
-    if (i >= 0 && i < _node_list.size()) {
-        for (int j = i+1; j < _node_list.size(); j++)
-            _node_list[i++] = _node_list[j++];
-        _node_list.pop_back();
-    }
-}
-
-void MaxOptionsDialog::RemoveNodeByHandle(ULONG INodeHandle) {
-    for (int i = 0; i < _node_list.size(); i++) {
-        if (_node_list[i] == INodeHandle) {
-            RemoveNode(i);
-            return;
-        }
-    }
-}
-
-IOResult MaxOptionsDialog::Save(ISave *isave) {
-    isave->BeginChunk(CHUNK_EGG_EXP_OPTIONS);
-    ChunkSave(isave, CHUNK_ANIM_TYPE, _anim_type);
-    ChunkSave(isave, CHUNK_FILENAME, _file_name);
-    ChunkSave(isave, CHUNK_SHORTNAME, _short_name);
-    ChunkSave(isave, CHUNK_SF, _start_frame);
-    ChunkSave(isave, CHUNK_EF, _end_frame);
-    ChunkSave(isave, CHUNK_DBL_SIDED, _double_sided);
-    ChunkSave(isave, CHUNK_EGG_CHECKED, _checked);
-    ChunkSave(isave, CHUNK_ALL_FRAMES, _export_all_frames);
-    ChunkSave(isave, CHUNK_EXPORT_FULL, _export_whole_scene);
-
-    isave->BeginChunk(CHUNK_NODE_LIST);
-    for (int i = 0; i < _node_list.size(); i++)
-        ChunkSave(isave, CHUNK_NODE_HANDLE, _node_list[i]);
-    isave->EndChunk();
-    isave->EndChunk();
-    return IO_OK;
-}
-
-IOResult MaxOptionsDialog::Load(ILoad *iload) {
-    IOResult res = iload->OpenChunk();
-
-    while (res == IO_OK) {
-        switch(iload->CurChunkID()) {
-        case CHUNK_ANIM_TYPE: _anim_type = (Anim_Type)ChunkLoadInt(iload); break;
-        case CHUNK_FILENAME: ChunkLoadString(iload, _file_name, sizeof(_file_name)); break;
-        case CHUNK_SHORTNAME: ChunkLoadString(iload, _short_name, sizeof(_short_name)); break;
-        case CHUNK_SF: _start_frame = ChunkLoadInt(iload); break;
-        case CHUNK_EF: _end_frame = ChunkLoadInt(iload); break;
-        case CHUNK_DBL_SIDED: _double_sided = ChunkLoadBool(iload); break;
-        case CHUNK_EGG_CHECKED: _checked = ChunkLoadBool(iload); break;
-        case CHUNK_ALL_FRAMES: _export_all_frames = ChunkLoadBool(iload); break;
-        case CHUNK_EXPORT_FULL: _export_whole_scene = ChunkLoadBool(iload); break;
-
-        case CHUNK_NODE_LIST:
-            res = iload->OpenChunk();
-            while (res == IO_OK) {
-                if (iload->CurChunkID() == CHUNK_NODE_HANDLE) AddNode(ChunkLoadULONG(iload));
-                iload->CloseChunk();
-                res = iload->OpenChunk();
-            }
-            break;
-        }
-        iload->CloseChunk();
-        res = iload->OpenChunk();
-    }
-
-    if (res == IO_END) return IO_OK;
-    return IO_ERROR;
-}

+ 0 - 112
pandatool/src/maxegg/maxOptionsDialog.h

@@ -1,112 +0,0 @@
-/*
-  maxEggExpOptions.h
-  Created by Phillip Saltzman, 2/15/05
-  Carnegie Mellon University, Entetainment Technology Center
-
-  This file contains a class that allows users to specify
-  export options, and then execute the export
-*/
-
-#ifndef __maxEggExpOptions__H
-#define __maxEggExpOptions__H
-
-#include "pathReplace.h"
-
-#pragma conform(forScope, off)
-
-/* Externed Globals */
-extern HINSTANCE hInstance;
-
-// Saveload chunk definitions
-#define CHUNK_OVERWRITE_FLAG  0x1000
-#define CHUNK_PVIEW_FLAG      0x1001
-#define CHUNK_LOG_OUTPUT      0x1002
-#define CHUNK_EGG_EXP_OPTIONS 0x1100
-#define CHUNK_ANIM_TYPE       0x1101
-#define CHUNK_EGG_CHECKED     0x1102
-#define CHUNK_DBL_SIDED       0x1103
-#define CHUNK_SF              0x1104
-#define CHUNK_EF              0x1105
-#define CHUNK_FILENAME        0x1106
-#define CHUNK_SHORTNAME       0x1107
-#define CHUNK_EXPORT_FULL     0x1108
-#define CHUNK_ALL_FRAMES      0x1109
-#define CHUNK_NODE_LIST       0x1200
-#define CHUNK_NODE_HANDLE     0x1201
-// #define CHUNK_ADD_COLLISION   0x1202 #define CHUNK_CS_TYPE         0x1203
-// #define CHUNK_CF_TYPE         0x1204
-
-// Global functions
-void ChunkSave(ISave *isave, int chunkid, int value);
-void ChunkSave(ISave *isave, int chunkid, bool value);
-void ChunkSave(ISave *isave, int chunkid, char *value);
-TCHAR *ChunkLoadString(ILoad *iload, TCHAR *buffer, int maxLength);
-int ChunkLoadInt(ILoad *iload);
-bool ChunkLoadBool(ILoad *iload);
-void SetICustEdit(HWND wnd, int nIDDlgItem, TCHAR *text);
-INT_PTR CALLBACK MaxOptionsDialogProc(HWND hWnd, UINT message,
-                                      WPARAM wParam, LPARAM lParam );
-
-struct MaxEggOptions
-{
-    MaxEggOptions();
-
-    enum Anim_Type {
-        AT_none,
-        AT_model,
-        AT_chan,
-        AT_pose,
-        AT_strobe,
-        AT_both
-    };
-
-
-    IObjParam *_max_interface;
-    Anim_Type _anim_type;
-    int _start_frame;
-    int _end_frame;
-    bool _double_sided;
-    bool _successful;
-    bool _export_whole_scene;
-    bool _export_all_frames;
-    TCHAR _file_name[2048];
-    TCHAR _short_name[256];
-    PT(PathReplace) _path_replace;
-    std::vector<ULONG> _node_list;
-};
-
-class MaxOptionsDialog : public MaxEggOptions
-{
-  friend class MaxEggPlugin;
-
-  public:
-    int _min_frame, _max_frame;
-    bool _checked;
-    bool _choosing_nodes;
-    MaxEggOptions::Anim_Type _prev_type;
-
-    MaxOptionsDialog();
-    ~MaxOptionsDialog();
-
-    // All these List functions should probably take what list they need to
-    // operate on rather than just operating on a global list
-    void SetMaxInterface(IObjParam *iface) { _max_interface = iface; }
-    void UpdateUI(HWND hWnd);
-    bool UpdateFromUI(HWND hWnd);
-    void RefreshNodeList(HWND hWnd);
-    void SetAnimRange();
-
-    bool FindNode(ULONG INodeHandle); //returns true if the node is already in the list
-    void AddNode(ULONG INodeHandle);
-    void RemoveNode(int i);
-    void RemoveNodeByHandle(ULONG INodeHandle);
-    void ClearNodeList(HWND hWnd);
-    void CullBadNodes();
-
-    ULONG GetNode(int i) { return (i >= 0 && i < _node_list.size()) ? _node_list[i] : ULONG_MAX; }
-
-    IOResult Load(ILoad *iload);
-    IOResult Save(ISave *isave);
-};
-
-#endif // __MaxEggExpOptions__H

+ 0 - 53
pandatool/src/maxegg/maxResource.h

@@ -1,53 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by maxEgg.rc
-//
-#define IDS_LIBDESCRIPTION              1
-#define IDS_CATEGORY                    2
-#define IDS_CLASS_NAME                  3
-#define IDS_PARAMS                      4
-#define IDS_SPIN                        5
-#define IDD_PANEL                       101
-#define IDD_EGG_DETAILS                 102
-#define IDC_EGGS_LABEL                  1019
-#define IDC_ADD_EGG                     1021
-#define IDC_EDIT_EGG                    1022
-#define IDC_REMOVE_EGG                  1023
-#define IDC_LIST_EGGS                   1024
-#define IDC_OVERWRITE_CHECK             1027
-#define IDC_EXPORT                      1028
-#define IDC_PANEL_TITLE                 1029
-#define IDC_OVERWRITE_CHECK2            1030
-#define IDC_PVIEW_CHECK                 1030
-#define IDC_MODEL                       1033
-#define IDC_ANIMATION                   1034
-#define IDC_BOTH                        1035
-#define IDC_POSE                        1036
-#define IDC_FILENAME                    1038
-#define IDC_BROWSE                      1039
-#define IDC_EXPORT_ALL                  1040
-#define IDC_EXPORT_SELECTED             1041
-#define IDC_ADD_EXPORT                  1043
-#define IDC_LIST_EXPORT                 1044
-#define IDC_REMOVE_EXPORT               1046
-#define IDC_EXP_ALL_FRAMES              1049
-#define IDC_EXP_SEL_FRAMES              1050
-#define IDC_SF                          1051
-#define IDC_SF_LABEL                    1052
-#define IDC_EF                          1053
-#define IDC_CHECK1                      1054
-#define IDC_EF_LABEL                    1057
-#define IDC_OK                          1058
-#define IDC_CANCEL                      1059
-#define IDC_LOGGING                     1060
-
-// Next default values for new objects
-// 
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        103
-#define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1080
-#define _APS_NEXT_SYMED_VALUE           102
-#endif
-#endif

+ 0 - 1416
pandatool/src/maxegg/maxToEggConverter.cxx

@@ -1,1416 +0,0 @@
-/**
- * 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."
- *
- * @file maxToEggConverter.cxx
- * @author Corey Revilla and Ken Strickland
- * @date 2003-06-22
- * from mayaToEggConverter.cxx created by drose (10Nov99)
- *
- * Updated by Fei Wang, Carnegie Mellon University Entertainment
- * Technology Center student, 29Jul2009:  Fixed vertex color,
- * animation hierarchy, texture swapping bugs; added collision choices to
- * exporter.
- *
- * Updated by Andrew Gartner, Carnegie Mellon University Entertainment
- * Technology Center. 27Apr2010: Collision is now done through User Defined Properties
- * By default a plane without a standard material gets UV's as well
- * as any object without a texture but with a standard material.
- * Point objects are now supported as "locators" for a point in space
- * within the egg.
- */
-
-#include "maxEgg.h"
-#include "config_putil.h"
-
-using std::string;
-
-/**
- *
- */
-MaxToEggConverter::
-MaxToEggConverter()
-{
-    reset();
-}
-
-/**
- *
- */
-MaxToEggConverter::
-~MaxToEggConverter()
-{
-}
-
-/**
-
- */
-void MaxToEggConverter::reset() {
-    _cur_tref = 0;
-    _current_frame = 0;
-    _textures.clear();
-    _egg_data = nullptr;
-}
-
-/**
- * Fills up the egg_data structure according to the global Max model data.
- * Returns true if successful, false if there is an error.  If from_selection
- * is true, the converted geometry is based on that which is selected;
- * otherwise, it is the entire Max scene.
- */
-bool MaxToEggConverter::convert(MaxEggOptions *options) {
-
-    _options = options;
-
-    Filename fn;
-#ifdef _UNICODE
-    fn = Filename::from_os_specific_w(_options->_file_name);
-#else
-    fn = Filename::from_os_specific(_options->_file_name);
-#endif
-
-    _options->_path_replace->_path_directory = fn.get_dirname();
-
-    _egg_data = new EggData;
-    if (_egg_data->get_coordinate_system() == CS_default) {
-        _egg_data->set_coordinate_system(CS_zup_right);
-    }
-
-    // Figure out the animation parameters.
-
-    // Get the start and end frames and the animation frame rate from Max
-
-    Interval anim_range = _options->_max_interface->GetAnimRange();
-    int start_frame = anim_range.Start()/GetTicksPerFrame();
-    int end_frame = anim_range.End()/GetTicksPerFrame();
-
-    if (!_options->_export_all_frames) {
-        if (_options->_start_frame < start_frame) _options->_start_frame = start_frame;
-        if (_options->_start_frame > end_frame)   _options->_start_frame = end_frame;
-        if (_options->_end_frame < start_frame)   _options->_end_frame = start_frame;
-        if (_options->_end_frame > end_frame)     _options->_end_frame = end_frame;
-        if (_options->_end_frame < _options->_start_frame)  _options->_end_frame = _options->_start_frame;
-        start_frame = _options->_start_frame;
-        end_frame = _options->_end_frame;
-    }
-
-    int frame_inc = 1;
-    int output_frame_rate = GetFrameRate();
-
-    bool all_ok = true;
-
-    if (_options->_export_whole_scene) {
-        _tree._export_mesh = false;
-        all_ok = _tree.build_complete_hierarchy(_options->_max_interface->GetRootNode(), nullptr, 0);
-    } else {
-        _tree._export_mesh = true;
-        all_ok = _tree.build_complete_hierarchy(_options->_max_interface->GetRootNode(), &_options->_node_list.front(), _options->_node_list.size());
-    }
-
-    if (all_ok) {
-        switch (_options->_anim_type) {
-        case MaxEggOptions::AT_pose:
-            // pose: set to a specific frame, then get out the static
-            // geometry.  sprintf(Logger::GetLogString(), "Extracting geometry
-            // from frame #%d.", start_frame); Logger::Log( MTEC,
-            // Logger::SAT_MEDIUM_LEVEL, Logger::GetLogString() );
-            // Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "Converting static
-            // model."  );
-            _current_frame = start_frame;
-            all_ok = convert_hierarchy(_egg_data);
-            break;
-
-        case MaxEggOptions::AT_model:
-            // model: get out an animatable model with joints and vertex
-            // membership.
-            all_ok = convert_char_model();
-            break;
-
-        case MaxEggOptions::AT_chan:
-            // chan: get out a series of animation tables.
-            all_ok = convert_char_chan(start_frame, end_frame, frame_inc,
-                                       output_frame_rate);
-            break;
-
-        case MaxEggOptions::AT_both:
-            // both: Put a model and its animation into the same egg file.
-            _options->_anim_type = MaxEggOptions::AT_model;
-            if (!convert_char_model()) {
-                all_ok = false;
-            }
-            _options->_anim_type = MaxEggOptions::AT_chan;
-            if (!convert_char_chan(start_frame, end_frame, frame_inc,
-                                   output_frame_rate)) {
-                all_ok = false;
-            }
-            // Set the type back to AT_both
-            _options->_anim_type = MaxEggOptions::AT_both;
-            break;
-
-          default:
-            all_ok = false;
-        };
-
-        reparent_decals(_egg_data);
-    }
-
-    if (all_ok) {
-        _egg_data->recompute_tangent_binormal_auto();
-        _egg_data->remove_unused_vertices(true);
-    }
-
-    _options->_successful = all_ok;
-
-    if (all_ok) {
-#ifdef _UNICODE
-        Filename fn = Filename::from_os_specific_w(_options->_file_name);
-#else
-        Filename fn = Filename::from_os_specific(_options->_file_name);
-#endif
-        return _egg_data->write_egg(fn);
-    } else {
-        return false;
-    }
-}
-
-/**
- * Converts the file as an animatable character model, with joints and vertex
- * membership.
- */
-bool MaxToEggConverter::
-convert_char_model() {
-    std::string character_name = "character";
-    _current_frame = _options->_start_frame;
-
-    EggGroup *char_node = new EggGroup(character_name);
-    _egg_data->add_child(char_node);
-    char_node->set_dart_type(EggGroup::DT_default);
-
-    return convert_hierarchy(char_node);
-}
-
-/**
- * Converts the animation as a series of tables to apply to the character
- * model, as retrieved earlier via AC_model.
- */
-bool MaxToEggConverter::
-convert_char_chan(double start_frame, double end_frame, double frame_inc,
-                  double output_frame_rate) {
-    std::string character_name = "character";
-
-    EggTable *root_table_node = new EggTable();
-    _egg_data->add_child(root_table_node);
-    EggTable *bundle_node = new EggTable(character_name);
-    bundle_node->set_table_type(EggTable::TT_bundle);
-    root_table_node->add_child(bundle_node);
-    EggTable *skeleton_node = new EggTable("<skeleton>");
-    bundle_node->add_child(skeleton_node);
-
-    // Set the frame rate before we start asking for anim tables to be
-    // created.
-    _tree._fps = output_frame_rate / frame_inc;
-    _tree.clear_egg(_egg_data, nullptr, skeleton_node);
-
-    // Now we can get the animation data by walking through all of the frames,
-    // one at a time, and getting the joint angles at each frame.
-
-    // This is just a temporary EggGroup to receive the transform for each
-    // joint each frame.
-    EggGroup* tgroup;
-
-    int num_nodes = _tree.get_num_nodes();
-    int i;
-
-    TimeValue frame = start_frame;
-    TimeValue frame_stop = end_frame;
-    while (frame <= frame_stop) {
-        _current_frame = frame;
-        for (i = 0; i < num_nodes; i++) {
-            // Find all joints in the hierarchy
-            MaxNodeDesc *node_desc = _tree.get_node(i);
-            if (node_desc->is_joint()) {
-                tgroup = new EggGroup();
-                INode *max_node = node_desc->get_max_node();
-
-                if (node_desc->_parent && node_desc->_parent->is_joint()) {
-                    // If this joint also has a joint as a parent, the
-                    // parent's transformation has to be divided out of this
-                    // joint's TM
-                    get_joint_transform(max_node, node_desc->_parent->get_max_node(),
-                                        tgroup);
-                } else {
-                    get_joint_transform(max_node, nullptr, tgroup);
-                }
-
-                EggXfmSAnim *anim = _tree.get_egg_anim(node_desc);
-                if (!anim->add_data(tgroup->get_transform3d())) {
-                    // *** log an error
-                }
-                delete tgroup;
-            }
-        }
-
-        frame += frame_inc;
-    }
-
-    // Now optimize all of the tables we just filled up, for no real good
-    // reason, except that it makes the resulting egg file a little easier to
-    // read.
-    for (i = 0; i < num_nodes; i++) {
-        MaxNodeDesc *node_desc = _tree.get_node(i);
-        if (node_desc->is_joint()) {
-            _tree.get_egg_anim(node_desc)->optimize();
-        }
-    }
-
-    return true;
-}
-
-/**
- * Generates egg structures for each node in the Max hierarchy.
- */
-bool MaxToEggConverter::
-convert_hierarchy(EggGroupNode *egg_root) {
-    // int num_nodes = _tree.get_num_nodes();
-
-    _tree.clear_egg(_egg_data, egg_root, nullptr);
-    for (int i = 0; i < _tree.get_num_nodes(); i++) {
-        if (!process_model_node(_tree.get_node(i))) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-/**
- * Converts the indicated Max node to the corresponding Egg structure.
- * Returns true if successful, false if an error was encountered.
- */
-bool MaxToEggConverter::
-process_model_node(MaxNodeDesc *node_desc) {
-    if (!node_desc->has_max_node()) {
-        // If the node has no Max equivalent, never mind.
-        return true;
-    }
-
-    // Skip all nodes that represent joints in the geometry, but aren't the
-    // actual joints themselves
-    if (node_desc->is_node_joint()) {
-        return true;
-    }
-
-    TimeValue time = 0;
-    INode *max_node = node_desc->get_max_node();
-
-    ObjectState state;
-    state = max_node->EvalWorldState(_current_frame * GetTicksPerFrame());
-
-    if (node_desc->is_joint()) {
-        EggGroup *egg_group = _tree.get_egg_group(node_desc);
-        // Don't bother with joints unless we're getting an animatable model.
-        if (_options->_anim_type == MaxEggOptions::AT_model) {
-            get_joint_transform(max_node, egg_group);
-        }
-    } else {
-        if (state.obj) {
-            EggGroup *egg_group = nullptr;
-            TriObject *myMaxTriObject;
-            Mesh max_mesh;
-            // Call the correct exporter based on what type of object this is.
-            switch( state.obj->SuperClassID() ){
-
-            case GEOMOBJECT_CLASS_ID:
-                egg_group = _tree.get_egg_group(node_desc);
-                get_transform(max_node, egg_group);
-
-                // Try converting this geometric object to a mesh we can use.
-                if (!state.obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) {
-                    return false;
-                }
-                // Convert our state object to a TriObject.
-                myMaxTriObject = (TriObject *) state.obj->ConvertToType(time, Class_ID(TRIOBJ_CLASS_ID, 0 ));
-                // *** Want to figure this problem out If actual conversion
-                // was required, then we want to delete this new mesh later to
-                // avoid mem leaks.  **BROKEN. doesnt delete
-
-                // Now, get the mesh.
-                max_mesh = myMaxTriObject->GetMesh();
-                make_polyset(max_node, &max_mesh, egg_group);
-
-                if (myMaxTriObject != state.obj)
-                    delete myMaxTriObject;
-                break;
-
-            case SHAPE_CLASS_ID:
-                if (state.obj->ClassID() == EDITABLE_SURF_CLASS_ID) {
-                    NURBSSet getSet;
-                    if (GetNURBSSet(state.obj, time, getSet, TRUE)) {
-                        NURBSObject *nObj = getSet.GetNURBSObject(0);
-                        if (nObj->GetType() == kNCVCurve) {
-                            // It's a CV Curve, process it
-                            egg_group = _tree.get_egg_group(node_desc);
-                            get_transform(max_node, egg_group);
-                            make_nurbs_curve(max_node, (NURBSCVCurve *)nObj,
-                                             time, egg_group);
-                        }
-                    }
-                }
-                break;
-
-            case CAMERA_CLASS_ID:
-                break;
-
-            case LIGHT_CLASS_ID:
-                break;
-
-            case HELPER_CLASS_ID:
-              // we should export Point objects to give Max the equivalent of
-              // Maya locators
-              if (state.obj->ClassID() == Class_ID(POINTHELP_CLASS_ID, 0)) {
-
-                egg_group = _tree.get_egg_group(node_desc);
-                get_transform(max_node, egg_group);
-
-              } else {
-
-                break;
-
-              }
-
-
-
-
-            }
-        }
-    }
-
-    return true;
-}
-
-/**
- * Extracts the transform on the indicated Maya node, and applies it to the
- * corresponding Egg node.
- */
-void MaxToEggConverter::
-get_transform(INode *max_node, EggGroup *egg_group) {
-    if (_options->_anim_type == MaxEggOptions::AT_model) {
-        // When we're getting an animated model, we only get transforms for
-        // joints.
-        return;
-    }
-
-    if ( !egg_group ) {
-        return;
-    }
-
-    // Gets the TM for this node, a matrix which encapsulates all
-    // transformations it takes to get to the current node, including parent
-    // transformations.
-    Matrix3 pivot = max_node->GetNodeTM(_current_frame * GetTicksPerFrame());
-
-    // This is the Panda-flava-flav-style matrix we'll be exporting to.
-    Point3 row0 = pivot.GetRow(0);
-    Point3 row1 = pivot.GetRow(1);
-    Point3 row2 = pivot.GetRow(2);
-    Point3 row3 = pivot.GetRow(3);
-
-    LMatrix4d m4d(row0.x, row0.y, row0.z, 0.0f,
-                  row1.x, row1.y, row1.z, 0.0f,
-                  row2.x, row2.y, row2.z, 0.0f,
-                  row3.x, row3.y, row3.z, 1.0f );
-
-    // Now here's the tricky part.  I believe this command strips out the node
-    // "frame" which is the sum of all transformations enacted by the parent
-    // of this node.  This should reduce to the transformation relative to
-    // this node's parent
-    m4d = m4d * egg_group->get_node_frame_inv();
-    if (!m4d.almost_equal(LMatrix4d::ident_mat(), 0.0001)) {
-        egg_group->add_matrix4(m4d);
-    }
-}
-
-/**
- * Extracts the transform on the indicated Maya node, and applies it to the
- * corresponding Egg node.
- */
-LMatrix4d MaxToEggConverter::
-get_object_transform(INode *max_node) {
-
-    // Gets the TM for this node, a matrix which encapsulates all
-    // transformations it takes to get to the current node, including parent
-    // transformations.
-    Matrix3 pivot = max_node->GetObjectTM(_current_frame * GetTicksPerFrame());
-
-    Point3 row0 = pivot.GetRow(0);
-    Point3 row1 = pivot.GetRow(1);
-    Point3 row2 = pivot.GetRow(2);
-    Point3 row3 = pivot.GetRow(3);
-
-    LMatrix4d m4d(row0.x, row0.y, row0.z, 0.0f,
-                  row1.x, row1.y, row1.z, 0.0f,
-                  row2.x, row2.y, row2.z, 0.0f,
-                  row3.x, row3.y, row3.z, 1.0f );
-    return m4d;
-}
-
-/**
- * Extracts the transform on the indicated Maya node, as appropriate for a
- * joint in an animated character, and applies it to the indicated node.  This
- * is different from get_transform() in that it does not respect the
- * _transform_type flag, and it does not consider the relative transforms
- * within the egg file.
- */
-void MaxToEggConverter::
-get_joint_transform(INode *max_node, EggGroup *egg_group) {
-
-    if ( !egg_group ) {
-        return;
-    }
-
-    // Gets the TM for this node, a matrix which encapsulates all
-    // transformations it takes to get to the current node, including parent
-    // transformations.
-    Matrix3 pivot = max_node->GetNodeTM(_current_frame * GetTicksPerFrame());
-    Point3 row0 = pivot.GetRow(0);
-    Point3 row1 = pivot.GetRow(1);
-    Point3 row2 = pivot.GetRow(2);
-    Point3 row3 = pivot.GetRow(3);
-
-    LMatrix4d m4d(row0.x, row0.y, row0.z, 0.0f,
-                  row1.x, row1.y, row1.z, 0.0f,
-                  row2.x, row2.y, row2.z, 0.0f,
-                  row3.x, row3.y, row3.z, 1.0f );
-
-    // Now here's the tricky part.  I believe this command strips out the node
-    // "frame" which is the sum of all transformations enacted by the parent
-    // of this node.  This should reduce to the transformation relative to
-    // this node's parent
-    m4d = m4d * egg_group->get_node_frame_inv();
-    if (!m4d.almost_equal(LMatrix4d::ident_mat(), 0.0001)) {
-        egg_group->add_matrix4(m4d);
-    }
-}
-
-/**
- * Extracts the transform on the indicated Maya node, as appropriate for a
- * joint in an animated character, and applies it to the indicated node.  This
- * is different from get_transform() in that it does not respect the
- * _transform_type flag, and it does not consider the relative transforms
- * within the egg file.
- */
-void MaxToEggConverter::
-get_joint_transform(INode *max_node, INode *parent_node, EggGroup *egg_group) {
-
-    if ( !egg_group ) {
-        return;
-    }
-
-    // Gets the TM for this node, a matrix which encapsulates all
-    // transformations it takes to get to the current node, including parent
-    // transformations.
-    Matrix3 pivot = max_node->GetNodeTM(_current_frame * GetTicksPerFrame());
-    Point3 row0 = pivot.GetRow(0);
-    Point3 row1 = pivot.GetRow(1);
-    Point3 row2 = pivot.GetRow(2);
-    Point3 row3 = pivot.GetRow(3);
-
-    LMatrix4d m4d(row0.x, row0.y, row0.z, 0.0f,
-                  row1.x, row1.y, row1.z, 0.0f,
-                  row2.x, row2.y, row2.z, 0.0f,
-                  row3.x, row3.y, row3.z, 1.0f );
-
-    if (parent_node) {
-        Matrix3 parent_pivot = parent_node->GetNodeTM(_current_frame * GetTicksPerFrame());
-        // parent_pivot.Invert();
-        row0 = parent_pivot.GetRow(0);
-        row1 = parent_pivot.GetRow(1);
-        row2 = parent_pivot.GetRow(2);
-        row3 = parent_pivot.GetRow(3);
-
-        LMatrix4d pi_m4d(row0.x, row0.y, row0.z, 0.0f,
-                         row1.x, row1.y, row1.z, 0.0f,
-                         row2.x, row2.y, row2.z, 0.0f,
-                         row3.x, row3.y, row3.z, 1.0f );
-
-        // Now here's the tricky part.  I believe this command strips out the
-        // node "frame" which is the sum of all transformations enacted by the
-        // parent of this node.  This should reduce to the transformation
-        // relative to this node's parent
-        pi_m4d.invert_in_place();
-        m4d = m4d * pi_m4d;
-    }
-    if (!m4d.almost_equal(LMatrix4d::ident_mat(), 0.0001)) {
-        egg_group->add_matrix4(m4d);
-    }
-}
-
-/**
- * Converts the indicated Maya NURBS curve (a standalone curve, not a trim
- * curve) to a corresponding egg structure and attaches it to the indicated
- * egg group.
- */
-bool MaxToEggConverter::
-make_nurbs_curve(INode *max_node, NURBSCVCurve *curve,
-                 TimeValue time, EggGroup *egg_group)
-{
-    int degree = curve->GetOrder();
-    int cvs = curve->GetNumCVs();
-    int knots = curve->GetNumKnots();
-    int i;
-
-    if (knots != cvs + degree) {
-        return false;
-    }
-
-#ifdef _UNICODE
-    char mbname[1024];
-    mbname[1023] = 0;
-    wcstombs(mbname, max_node->GetName(), 1023);
-    string name(mbname);
-#else
-    string name = max_node->GetName();
-#endif
-
-    string vpool_name = name + ".cvs";
-    EggVertexPool *vpool = new EggVertexPool(vpool_name);
-    egg_group->add_child(vpool);
-
-    EggNurbsCurve *egg_curve = new EggNurbsCurve(name);
-    egg_group->add_child(egg_curve);
-    egg_curve->setup(degree, knots);
-
-    for (i = 0; i < knots; i++)
-        egg_curve->set_knot(i, curve->GetKnot(i));
-
-    LMatrix4d vertex_frame_inv = egg_group->get_vertex_frame_inv();
-
-    for (i = 0; i < cvs; i++) {
-        NURBSControlVertex *cv = curve->GetCV(i);
-        if (!cv) {
-            char buf[1024];
-            sprintf(buf, "Error getting CV %d", i);
-            return false;
-        } else {
-            EggVertex vert;
-            LPoint4d p4d(0, 0, 0, 1.0);
-            cv->GetPosition(time, p4d[0], p4d[1], p4d[2]);
-            p4d = p4d * vertex_frame_inv;
-            vert.set_pos(p4d);
-            egg_curve->add_vertex(vpool->create_unique_vertex(vert));
-        }
-    }
-
-    return true;
-}
-
-/**
- * Converts the indicated Maya polyset to a bunch of EggPolygons and parents
- * them to the indicated egg group.
- */
-void MaxToEggConverter::
-make_polyset(INode *max_node, Mesh *mesh,
-             EggGroup *egg_group, Shader *default_shader) {
-
-    mesh->buildNormals();
-
-    if (mesh->getNumFaces() == 0) {
-        return;
-    }
-
-    // One way to convert the mesh would be to first get out all the vertices
-    // in the mesh and add them into the vpool, then when we traverse the
-    // polygons we would only have to index them into the vpool according to
-    // their Maya vertex index.
-
-    // Unfortunately, since Maya may store multiple normals andor colors for
-    // each vertex according to which polygon it is in, that approach won't
-    // necessarily work.  In egg, those split-property vertices have to become
-    // separate vertices.  So instead of adding all the vertices up front,
-    // we'll start with an empty vpool, and add vertices to it on the fly.
-
-#ifdef _UNICODE
-    char mbname[1024];
-    mbname[1023] = 0;
-    wcstombs(mbname, max_node->GetName(), 1023);
-    string node_name(mbname);
-#else
-    string node_name = max_node->GetName();
-#endif
-
-    string vpool_name = node_name + ".verts";
-    EggVertexPool *vpool = new EggVertexPool(vpool_name);
-    egg_group->add_child(vpool);
-
-    // We will need to transform all vertices from world coordinate space into
-    // the vertex space appropriate to this node.  Usually, this is the same
-    // thing as world coordinate space, and this matrix will be identity; but
-    // if the node is under an instance (particularly, for instance, a
-    // billboard) then the vertex space will be different from world space.
-    LMatrix4d vertex_frame = get_object_transform(max_node) *
-        egg_group->get_vertex_frame_inv();
-
-
-    for ( int iFace=0; iFace < mesh->getNumFaces(); iFace++ ) {
-        EggPolygon *egg_poly = new EggPolygon;
-        egg_group->add_child(egg_poly);
-
-        egg_poly->set_bface_flag(_options->_double_sided);
-
-        Face face = mesh->faces[iFace];
-
-        const PandaMaterial &pmat = get_panda_material(max_node->GetMtl(), face.getMatID());
-
-        // Get the vertices for the polygon.
-        for ( int iVertex=0; iVertex < 3; iVertex++ ) {
-            EggVertex vert;
-
-            // Get the vertex position
-            Point3 vertex = mesh->getVert(face.v[iVertex]);
-            LPoint3d p3d(vertex.x, vertex.y, vertex.z);
-            p3d = p3d * vertex_frame;
-            vert.set_pos(p3d);
-
-            // Get the vertex normal
-            Point3 normal = get_max_vertex_normal(mesh, iFace, iVertex);
-            LVector3d n3d(normal.x, normal.y, normal.z);
-            // *** Not quite sure if this transform should be applied, but it
-            // may explain why normals were weird previously
-            n3d = n3d * vertex_frame;
-            vert.set_normal(n3d);
-
-            // Get the vertex color
-            if(mesh->vcFace)  // if has vcFace, has used vertex color
-            {
-                VertColor vertexColor = get_max_vertex_color(mesh, iFace, iVertex);
-                LColor pVC(vertexColor.x, vertexColor.y, vertexColor.z, 1);
-                vert.set_color(pVC);
-            }
-            // Get the UVs for this vertex
-
-            // first check if we returned nothing in the channels slot we need
-            // UV's even in this case because the user may not have put a
-            // material on the object at all
-            if (pmat._map_channels.size() == 0) {
-              // since the channel will always be one because there's no other
-              // textures then don't bother with the name
-              UVVert uvw = get_max_vertex_texcoord(mesh, iFace, iVertex, 1);
-              vert.set_uv( LTexCoordd(uvw.x, uvw.y));
-            }
-            // otherwise go through and generate the maps per channel this
-            // will also generate default UV's as long as the user applies a
-            // standard material to the object
-            for (int iChan=0; iChan<pmat._map_channels.size(); iChan++) {
-                int channel = pmat._map_channels[iChan];
-                std::ostringstream uvname;
-                uvname << "m" << channel;
-                UVVert uvw = get_max_vertex_texcoord(mesh, iFace, iVertex, channel);
-                // changes allow the first channel to be swapped
-                if(channel == 1)
-                    vert.set_uv( LTexCoordd(uvw.x, uvw.y));
-                else
-                    vert.set_uv( uvname.str(), LTexCoordd(uvw.x, uvw.y));
-
-            }
-
-            vert.set_external_index(face.v[iVertex]);
-
-            egg_poly->add_vertex(vpool->create_unique_vertex(vert));
-        }
-
-        // Max uses normals, not winding, to determine which way a polygon
-        // faces.  Make sure the winding and that normal agree
-
-        EggVertex *verts[3];
-        LPoint3d points[3];
-
-        for (int i = 0; i < 3; i++) {
-            verts[i] = egg_poly->get_vertex(i);
-            points[i] = verts[i]->get_pos3();
-        }
-
-        LVector3d realNorm = ((points[1] - points[0]).cross(points[2] - points[0]));
-        Point3 maxNormTemp = mesh->getFaceNormal(iFace);
-        LVector3d maxNorm = (LVector3d(maxNormTemp.x, maxNormTemp.y, maxNormTemp.z) *
-                             vertex_frame);
-
-        if (realNorm.dot(maxNorm) < 0.0) {
-            egg_poly->set_vertex(0, verts[2]);
-            egg_poly->set_vertex(2, verts[0]);
-        }
-
-        for (int i=0; i<pmat._texture_list.size(); i++) {
-            egg_poly->add_texture(pmat._texture_list[i]);
-        }
-        egg_poly->set_color(pmat._color);
-
-
-    }
-
-    // Now that we've added all the polygons (and created all the vertices),
-    // go back through the vertex pool and set up the appropriate joint
-    // membership for each of the vertices.
-
-    if (_options->_anim_type == MaxEggOptions::AT_model) {
-        get_vertex_weights(max_node, vpool);
-    }
-}
-
-UVVert MaxToEggConverter::get_max_vertex_texcoord(Mesh *mesh, int faceNo, int vertNo, int channel) {
-
-    // extract the texture coordinate
-    UVVert uvVert(0,0,0);
-    if(mesh->mapSupport(channel)) {
-        TVFace *pTVFace = mesh->mapFaces(channel);
-        UVVert *pUVVert = mesh->mapVerts(channel);
-        uvVert = pUVVert[pTVFace[faceNo].t[vertNo]];
-    } else if(mesh->numTVerts > 0) {
-        uvVert = mesh->tVerts[mesh->tvFace[faceNo].t[vertNo]];
-    }
-    return uvVert;
-}
-
-VertColor MaxToEggConverter::get_max_vertex_color(Mesh *mesh,int FaceNo,int VertexNo, int channel) {
-
-  VertColor vc(0,0,0);
-  if(mesh->mapSupport(channel))
-  {
-    // We get the color from vcFace
-    TVFace& _vcface = mesh->vcFace[FaceNo];
-    // Get its index into the vertCol array
-    int VertexColorIndex = _vcface.t[VertexNo];
-    // Get its color
-    vc =mesh->vertCol[VertexColorIndex];
-  }
-  else
-  {
-    TVFace *pTVFace = mesh->mapFaces(channel);
-    vc = mesh->vertCol[pTVFace[FaceNo].t[VertexNo]];
-  }
-  return vc;
-}
-
-VertColor MaxToEggConverter::get_max_vertex_color(Mesh *mesh,int FaceNo,int VertexNo)
-{
-    VertColor vc(0,0,0);
-    // We get the color from vcFace
-    TVFace& _vcface = mesh->vcFace[FaceNo];
-    // Get its index into the vertCol array
-    int VertexColorIndex = _vcface.t[VertexNo];
-    // Get its color
-    vc =mesh->vertCol[VertexColorIndex];
-    return vc;
-}
-
-Point3 MaxToEggConverter::get_max_vertex_normal(Mesh *mesh, int faceNo, int vertNo)
-{
-    Face f = mesh->faces[faceNo];
-    DWORD smGroup = f.smGroup;
-    int vert = f.getVert(vertNo);
-    RVertex *rv = mesh->getRVertPtr(vert);
-
-    int numNormals;
-    Point3 vertexNormal;
-
-    // Is normal specified SPCIFIED is not currently used, but may be used in
-    // future versions.
-    if (rv->rFlags & SPECIFIED_NORMAL) {
-        vertexNormal = rv->rn.getNormal();
-    }
-    // If normal is not specified it's only available if the face belongs to a
-    // smoothing group
-    else if ((numNormals = rv->rFlags & NORCT_MASK) && smGroup) {
-        // If there is only one vertex is found in the rn member.
-        if (numNormals == 1) {
-            vertexNormal = rv->rn.getNormal();
-        }
-        else {
-            // If two or more vertices are there you need to step through them
-            // and find the vertex with the same smoothing group as the
-            // current face.  You will find multiple normals in the ern
-            // member.
-            for (int i = 0; i < numNormals; i++) {
-                if (rv->ern[i].getSmGroup() & smGroup) {
-                    vertexNormal = rv->ern[i].getNormal();
-                }
-            }
-        }
-    }
-    else {
-        // Get the normal from the Face if no smoothing groups are there
-        vertexNormal = mesh->getFaceNormal(faceNo);
-    }
-
-    return vertexNormal;
-}
-
-/**
- *
- */
-void MaxToEggConverter::
-get_vertex_weights(INode *max_node, EggVertexPool *vpool) {
-    // Try to get the weights out of a physique if one exists
-    Modifier *mod = FindSkinModifier(max_node, PHYSIQUE_CLASSID);
-    EggVertexPool::iterator vi;
-
-    if (mod) {
-        // create a physique export interface
-        IPhysiqueExport *pPhysiqueExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
-        if (pPhysiqueExport) {
-            // create a context export interface
-            IPhyContextExport *pContextExport =
-                (IPhyContextExport *)pPhysiqueExport->GetContextInterface(max_node);
-            if (pContextExport) {
-                // set the flags in the context export interface
-                pContextExport->ConvertToRigid(TRUE);
-                pContextExport->AllowBlending(TRUE);
-
-                for (vi = vpool->begin(); vi != vpool->end(); ++vi) {
-                    EggVertex *vert = (*vi);
-                    int max_vi = vert->get_external_index();
-
-                    // get the vertex export interface
-                    IPhyVertexExport *pVertexExport =
-                        (IPhyVertexExport *)pContextExport->GetVertexInterface(max_vi);
-                    if (pVertexExport) {
-                        int vertexType = pVertexExport->GetVertexType();
-
-                        // handle the specific vertex type
-                        if(vertexType == RIGID_TYPE) {
-                            // typecast to rigid vertex
-                            IPhyRigidVertex *pTypeVertex = (IPhyRigidVertex *)pVertexExport;
-                            INode *bone_node = pTypeVertex->GetNode();
-                            MaxNodeDesc *joint_node_desc = _tree.find_joint(bone_node);
-                            if (joint_node_desc){
-                                EggGroup *joint = _tree.get_egg_group(joint_node_desc);
-                                if (joint != nullptr)
-                                    joint->ref_vertex(vert, 1.0f);
-                            }
-                        }
-                        else if(vertexType == RIGID_BLENDED_TYPE) {
-                            // typecast to blended vertex
-                            IPhyBlendedRigidVertex *pTypeVertex = (IPhyBlendedRigidVertex *)pVertexExport;
-
-                            for (int ji = 0; ji < pTypeVertex->GetNumberNodes(); ++ji) {
-                                PN_stdfloat weight = pTypeVertex->GetWeight(ji);
-                                if (weight > 0.0f) {
-                                    INode *bone_node = pTypeVertex->GetNode(ji);
-                                    MaxNodeDesc *joint_node_desc = _tree.find_joint(bone_node);
-                                    if (joint_node_desc){
-                                        EggGroup *joint = _tree.get_egg_group(joint_node_desc);
-                                        if (joint != nullptr)
-                                            joint->ref_vertex(vert, weight);
-                                    }
-                                }
-                            }
-                        }
-                        // Release the vertex interface
-                        pContextExport->ReleaseVertexInterface(pVertexExport);
-                    }
-                }
-                // Release the context interface
-                pPhysiqueExport->ReleaseContextInterface(pContextExport);
-            }
-            // Release the physique export interface
-            mod->ReleaseInterface(I_PHYINTERFACE, pPhysiqueExport);
-        }
-    }
-    else {
-        // No physique, try to find a skin
-        mod = FindSkinModifier(max_node, SKIN_CLASSID);
-        if (mod) {
-            ISkin *skin = (ISkin*)mod->GetInterface(I_SKIN);
-            if (skin) {
-                ISkinContextData *skinMC = skin->GetContextInterface(max_node);
-                if (skinMC) {
-                    for (vi = vpool->begin(); vi != vpool->end(); ++vi) {
-                        EggVertex *vert = (*vi);
-                        int max_vi = vert->get_external_index();
-
-                        for (int ji = 0; ji < skinMC->GetNumAssignedBones(max_vi); ++ji) {
-                            PN_stdfloat weight = skinMC->GetBoneWeight(max_vi, ji);
-                            if (weight > 0.0f) {
-                                INode *bone_node = skin->GetBone(skinMC->GetAssignedBone(max_vi, ji));
-                                MaxNodeDesc *joint_node_desc = _tree.find_joint(bone_node);
-                                if (joint_node_desc){
-                                    EggGroup *joint = _tree.get_egg_group(joint_node_desc);
-                                    if (joint != nullptr) {
-                                        joint->ref_vertex(vert, weight);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-
-/**
- * Converts a Max material into a set of Panda textures and a primitive color.
- */
-const MaxToEggConverter::PandaMaterial &MaxToEggConverter::
-get_panda_material(Mtl *mtl, MtlID matID) {
-
-    MaterialMap::iterator it = _material_map.find(mtl);
-    if (it != _material_map.end()) {
-        return (*it).second;
-    }
-
-    PandaMaterial &pandaMat = _material_map[mtl];
-    pandaMat._color = LColor(1,1,1,1);
-    pandaMat._any_diffuse = false;
-    pandaMat._any_opacity = false;
-    pandaMat._any_gloss = false;
-    pandaMat._any_normal = false;
-
-
-
-
-    // If it's a multi-material, dig down.
-
-    while (( mtl != 0) && (mtl->ClassID() == Class_ID(MULTI_CLASS_ID, 0 ))) {
-        if (matID < mtl->NumSubMtls()) {
-            mtl = mtl->GetSubMtl(matID);
-        } else {
-            mtl = 0;
-        }
-    }
-
-    // If it's a standard material, we're good.
-
-    if ((mtl != 0) && (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0 ))) {
-        StdMat *maxMaterial = (StdMat*)mtl;
-        analyze_diffuse_maps(pandaMat, maxMaterial->GetSubTexmap(ID_DI));
-        analyze_opacity_maps(pandaMat, maxMaterial->GetSubTexmap(ID_OP));
-        analyze_gloss_maps(pandaMat, maxMaterial->GetSubTexmap(ID_SP));
-        if (!pandaMat._any_gloss)
-            analyze_gloss_maps(pandaMat, maxMaterial->GetSubTexmap(ID_SS));
-        if (!pandaMat._any_gloss)
-            analyze_gloss_maps(pandaMat, maxMaterial->GetSubTexmap(ID_SH));
-        analyze_glow_maps(pandaMat, maxMaterial->GetSubTexmap(ID_SI));
-        analyze_normal_maps(pandaMat, maxMaterial->GetSubTexmap(ID_BU));
-        for (int i=0; i<pandaMat._texture_list.size(); i++) {
-            EggTexture *src = pandaMat._texture_list[i];
-            pandaMat._texture_list[i] =
-                _textures.create_unique_texture(*src, ~EggTexture::E_tref_name);
-        }
-
-        // The existence of a texture on either color channel completely
-        // replaces the corresponding flat color.
-        if (!pandaMat._any_diffuse) {
-            // Get the default diffuse color of the material without the
-            // texture map
-            Point3 diffuseColor = Point3(maxMaterial->GetDiffuse(0));
-            pandaMat._color[0] = diffuseColor.x;
-            pandaMat._color[1] = diffuseColor.y;
-            pandaMat._color[2] = diffuseColor.z;
-        }
-        if (!pandaMat._any_opacity) {
-            pandaMat._color[3] = (maxMaterial->GetOpacity(_current_frame * GetTicksPerFrame()));
-        }
-        if (pandaMat._texture_list.size() < 1) {
-            // if we don't have any maps whatsoever, give the material a dummy
-            // channel so that UV's get created
-            pandaMat._map_channels.push_back(1);
-        }
-        return pandaMat;
-    }
-
-    // Otherwise, it's unrecognizable.  Leave result blank.
-    return pandaMat;
-}
-/**
- *
- */
-void MaxToEggConverter::analyze_diffuse_maps(PandaMaterial &pandaMat, Texmap *mat) {
-    if (mat == 0) return;
-
-    if (mat->ClassID() == Class_ID(RGBMULT_CLASS_ID, 0)) {
-        for (int i=0; i<mat->NumSubTexmaps(); i++) {
-            analyze_diffuse_maps(pandaMat, mat->GetSubTexmap(i));
-        }
-        return;
-    }
-
-    if (mat->ClassID() == Class_ID(BMTEX_CLASS_ID, 0)) {
-        pandaMat._any_diffuse = true;
-        PT(EggTexture) tex = new EggTexture(generate_tex_name(), "");
-
-        BitmapTex *diffuseTex = (BitmapTex *)mat;
-
-        Filename fullpath, outpath;
-#ifdef _UNICODE
-        Filename filename = Filename::from_os_specific_w(diffuseTex->GetMapName());
-#else
-        Filename filename = Filename::from_os_specific(diffuseTex->GetMapName());
-#endif
-        _options->_path_replace->full_convert_path(filename, get_model_path(),
-                                                   fullpath, outpath);
-        tex->set_filename(outpath);
-        tex->set_fullpath(fullpath);
-
-        apply_texture_properties(*tex, diffuseTex->GetMapChannel());
-        add_map_channel(pandaMat, diffuseTex->GetMapChannel());
-
-        Bitmap *diffuseBitmap = diffuseTex->GetBitmap(0);
-        if ( diffuseBitmap && diffuseBitmap->HasAlpha()) {
-            tex->set_format(EggTexture::F_rgba);
-        } else {
-            tex->set_format(EggTexture::F_rgb);
-        }
-        tex->set_env_type(EggTexture::ET_modulate);
-
-        pandaMat._texture_list.push_back(tex);
-    }
-}
-
-/**
- *
- */
-void MaxToEggConverter::analyze_opacity_maps(PandaMaterial &pandaMat, Texmap *mat) {
-    if (mat == 0) return;
-
-    if (mat->ClassID() == Class_ID(RGBMULT_CLASS_ID, 0)) {
-        for (int i=0; i<mat->NumSubTexmaps(); i++) {
-            analyze_opacity_maps(pandaMat, mat->GetSubTexmap(i));
-        }
-        return;
-    }
-
-    if (mat->ClassID() == Class_ID(BMTEX_CLASS_ID, 0)) {
-        pandaMat._any_opacity = true;
-        BitmapTex *transTex = (BitmapTex *)mat;
-
-        Filename fullpath, outpath;
-#ifdef _UNICODE
-        Filename filename = Filename::from_os_specific_w(transTex->GetMapName());
-#else
-        Filename filename = Filename::from_os_specific(transTex->GetMapName());
-#endif
-        _options->_path_replace->full_convert_path(filename, get_model_path(),
-                                                   fullpath, outpath);
-
-        // See if this opacity map already showed up.
-        for (int i=0; i<pandaMat._texture_list.size(); i++) {
-            EggTexture *tex = pandaMat._texture_list[i];
-            if ((tex->get_env_type()==EggTexture::ET_modulate)&&(tex->get_fullpath() == fullpath)) {
-                tex->set_format(EggTexture::F_rgba);
-                return;
-            }
-        }
-
-        // Try to find a diffuse map to pair this with as an alpha-texture.
-        std::string uvname = get_uv_name(transTex->GetMapChannel());
-        for (int i=0; i<pandaMat._texture_list.size(); i++) {
-            EggTexture *tex = pandaMat._texture_list[i];
-            if ((tex->get_env_type()==EggTexture::ET_modulate)&&
-                (tex->get_format() == EggTexture::F_rgb)&&
-                (tex->get_uv_name() == uvname)) {
-                tex->set_format(EggTexture::F_rgba);
-                tex->set_alpha_filename(outpath);
-                tex->set_alpha_fullpath(fullpath);
-                return;
-            }
-        }
-
-        // Otherwise, just create it as an alpha-texture.
-        PT(EggTexture) tex = new EggTexture(generate_tex_name(), "");
-        tex->set_filename(outpath);
-        tex->set_fullpath(fullpath);
-
-        apply_texture_properties(*tex, transTex->GetMapChannel());
-        add_map_channel(pandaMat, transTex->GetMapChannel());
-        tex->set_format(EggTexture::F_alpha);
-
-        pandaMat._texture_list.push_back(tex);
-    }
-}
-
-/**
- *
- */
-void MaxToEggConverter::analyze_glow_maps(PandaMaterial &pandaMat, Texmap *mat) {
-    if (mat == 0) return;
-
-    if (mat->ClassID() == Class_ID(BMTEX_CLASS_ID, 0)) {
-        BitmapTex *gtex = (BitmapTex *)mat;
-
-        Filename fullpath, outpath;
-#ifdef _UNICODE
-        Filename filename = Filename::from_os_specific_w(gtex->GetMapName());
-#else
-        Filename filename = Filename::from_os_specific(gtex->GetMapName());
-#endif
-        _options->_path_replace->full_convert_path(filename, get_model_path(),
-                                                   fullpath, outpath);
-
-        // Try to find a diffuse map to pair this with as an alpha-texture.
-        std::string uvname = get_uv_name(gtex->GetMapChannel());
-        for (int i=0; i<pandaMat._texture_list.size(); i++) {
-            EggTexture *tex = pandaMat._texture_list[i];
-            if ((tex->get_env_type()==EggTexture::ET_modulate)&&
-                (tex->get_format() == EggTexture::F_rgb)&&
-                (tex->get_uv_name() == uvname)) {
-                tex->set_env_type(EggTexture::ET_modulate_glow);
-                tex->set_format(EggTexture::F_rgba);
-                tex->set_alpha_filename(outpath);
-                tex->set_alpha_fullpath(fullpath);
-                return;
-            }
-        }
-
-        // Otherwise, just create it as a separate glow-texture.
-        PT(EggTexture) tex = new EggTexture(generate_tex_name(), "");
-        tex->set_env_type(EggTexture::ET_glow);
-        tex->set_filename(outpath);
-        tex->set_fullpath(fullpath);
-        apply_texture_properties(*tex, gtex->GetMapChannel());
-        add_map_channel(pandaMat, gtex->GetMapChannel());
-        tex->set_format(EggTexture::F_alpha);
-
-        pandaMat._texture_list.push_back(tex);
-    }
-}
-
-/**
- *
- */
-void MaxToEggConverter::analyze_gloss_maps(PandaMaterial &pandaMat, Texmap *mat) {
-    if (mat == 0) return;
-
-    if (mat->ClassID() == Class_ID(BMTEX_CLASS_ID, 0)) {
-        pandaMat._any_gloss = true;
-        BitmapTex *gtex = (BitmapTex *)mat;
-
-        Filename fullpath, outpath;
-#ifdef _UNICODE
-        Filename filename = Filename::from_os_specific_w(gtex->GetMapName());
-#else
-        Filename filename = Filename::from_os_specific(gtex->GetMapName());
-#endif
-        _options->_path_replace->full_convert_path(filename, get_model_path(),
-                                                   fullpath, outpath);
-
-        // Try to find a diffuse map to pair this with as an alpha-texture.
-        std::string uvname = get_uv_name(gtex->GetMapChannel());
-        for (int i=0; i<pandaMat._texture_list.size(); i++) {
-            EggTexture *tex = pandaMat._texture_list[i];
-            if ((tex->get_env_type()==EggTexture::ET_modulate)&&
-                (tex->get_format() == EggTexture::F_rgb)&&
-                (tex->get_uv_name() == uvname)) {
-                tex->set_env_type(EggTexture::ET_modulate_gloss);
-                tex->set_format(EggTexture::F_rgba);
-                tex->set_alpha_filename(outpath);
-                tex->set_alpha_fullpath(fullpath);
-                return;
-            }
-        }
-
-        // Otherwise, just create it as a separate gloss-texture.
-        PT(EggTexture) tex = new EggTexture(generate_tex_name(), "");
-        tex->set_env_type(EggTexture::ET_gloss);
-        tex->set_filename(outpath);
-        tex->set_fullpath(fullpath);
-        apply_texture_properties(*tex, gtex->GetMapChannel());
-        add_map_channel(pandaMat, gtex->GetMapChannel());
-        tex->set_format(EggTexture::F_alpha);
-
-        pandaMat._texture_list.push_back(tex);
-    }
-}
-
-/**
- *
- */
-void MaxToEggConverter::analyze_normal_maps(PandaMaterial &pandaMat, Texmap *mat) {
-    if (mat == 0) return;
-
-    if (mat->ClassID() == Class_ID(BMTEX_CLASS_ID, 0)) {
-        pandaMat._any_normal = true;
-        BitmapTex *ntex = (BitmapTex *)mat;
-
-        Filename fullpath, outpath;
-#ifdef _UNICODE
-        Filename filename = Filename::from_os_specific_w(ntex->GetMapName());
-#else
-        Filename filename = Filename::from_os_specific(ntex->GetMapName());
-#endif
-        _options->_path_replace->full_convert_path(filename, get_model_path(),
-                                                   fullpath, outpath);
-
-        PT(EggTexture) tex = new EggTexture(generate_tex_name(), "");
-        tex->set_env_type(EggTexture::ET_normal);
-        tex->set_filename(outpath);
-        tex->set_fullpath(fullpath);
-        apply_texture_properties(*tex, ntex->GetMapChannel());
-        add_map_channel(pandaMat, ntex->GetMapChannel());
-        tex->set_format(EggTexture::F_rgb);
-
-        pandaMat._texture_list.push_back(tex);
-    }
-}
-
-/**
- * Adds the specified map channel to the map channel list, if it's not already
- * there.
- */
-void MaxToEggConverter::add_map_channel(PandaMaterial &pandaMat, int chan) {
-    for (int i=0; i<pandaMat._map_channels.size(); i++) {
-        if (pandaMat._map_channels[i] == chan) {
-            return;
-        }
-    }
-    pandaMat._map_channels.push_back(chan);
-}
-
-/**
- * Generates an arbitrary unused texture name.
- */
-std::string MaxToEggConverter::generate_tex_name() {
-    std::ostringstream name_strm;
-    name_strm << "Tex" << ++_cur_tref;
-    return name_strm.str();
-}
-
-/**
- * Returns the UV-name of the nth map-channel.
- */
-std::string MaxToEggConverter::get_uv_name(int channel) {
-    std::ostringstream uvname;
-    uvname << "m" << channel;
-    return uvname.str();
-}
-
-/**
- * Applies all the appropriate texture properties to the EggTexture object,
- * including wrap modes and texture matrix.
- */
-void MaxToEggConverter::
-apply_texture_properties(EggTexture &tex, int channel) {
-
-    // we leave a channel 1 for texture swapping, so don't name it
-    if(channel == 1)
-      tex.set_uv_name("");
-    else
-      tex.set_uv_name(get_uv_name(channel));
-
-    tex.set_minfilter(EggTexture::FT_linear_mipmap_linear);
-    tex.set_magfilter(EggTexture::FT_linear);
-
-    EggTexture::WrapMode wrap_u = EggTexture::WM_repeat;
-    EggTexture::WrapMode wrap_v = EggTexture::WM_repeat;
-
-    tex.set_wrap_u(wrap_u);
-    tex.set_wrap_v(wrap_v);
-}
-
-
-/**
- * Recursively walks the egg hierarchy, reparenting "decal" type nodes below
- * their corresponding "decalbase" type nodes, and setting the flags.
- *
- * Returns true on success, false if some nodes were incorrect.
- */
-bool MaxToEggConverter::
-reparent_decals(EggGroupNode *egg_parent) {
-    bool okflag = true;
-
-    // First, walk through all children of this node, looking for the one
-    // decal base, if any.
-    EggGroup *decal_base = nullptr;
-    pvector<EggGroup *> decal_children;
-
-    EggGroupNode::iterator ci;
-    for (ci = egg_parent->begin(); ci != egg_parent->end(); ++ci) {
-        EggNode *child =  (*ci);
-        if (child->is_of_type(EggGroup::get_class_type())) {
-            EggGroup *child_group = (EggGroup *) child;
-            if (child_group->has_object_type("decalbase")) {
-                if (decal_base != nullptr) {
-                    // error
-                    okflag = false;
-                }
-                child_group->remove_object_type("decalbase");
-                decal_base = child_group;
-
-            } else if (child_group->has_object_type("decal")) {
-                child_group->remove_object_type("decal");
-                decal_children.push_back(child_group);
-            }
-        }
-    }
-
-    if (decal_base == nullptr) {
-        if (!decal_children.empty()) {
-            // warning
-        }
-
-    } else {
-        if (decal_children.empty()) {
-            // warning
-
-        } else {
-            // All the decal children get moved to be a child of decal base.
-            // This usually will not affect the vertex positions, but it could
-            // if the decal base has a transform and the decal child is an
-            // instance node.  So don't do that.
-            pvector<EggGroup *>::iterator di;
-            for (di = decal_children.begin(); di != decal_children.end(); ++di) {
-                EggGroup *child_group = (*di);
-                decal_base->add_child(child_group);
-            }
-
-            // Also set the decal state on the base.
-            decal_base->set_decal_flag(true);
-        }
-    }
-
-    // Now recurse on each of the child nodes.
-    for (ci = egg_parent->begin(); ci != egg_parent->end(); ++ci) {
-        EggNode *child =  (*ci);
-        if (child->is_of_type(EggGroupNode::get_class_type())) {
-            EggGroupNode *child_group = (EggGroupNode *) child;
-            if (!reparent_decals(child_group)) {
-                okflag = false;
-            }
-        }
-    }
-
-    return okflag;
-}
-
-Modifier* MaxToEggConverter::FindSkinModifier (INode* node, const Class_ID &type)
-{
-    // Get object from node.  Abort if no object.
-    Object* pObj = node->GetObjectRef();
-    if (!pObj) return nullptr;
-
-    // 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.
-        for (int stackId = 0; stackId < pDerObj->NumModifiers(); ++stackId) {
-            // Get current modifier.
-            Modifier* mod = pDerObj->GetModifier(stackId);
-
-            // Is this what we are looking for?
-            if (mod->ClassID() == type )
-                return mod;
-        }
-
-        // continue with next derived object
-        pObj = pDerObj->GetObjRef();
-    }
-
-    // Not found.
-    return nullptr;
-}

+ 0 - 111
pandatool/src/maxegg/maxToEggConverter.h

@@ -1,111 +0,0 @@
-/**
- * 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."
- *
- * @file maxToEggConverter.h
- * @author Corey Revilla and Ken Strickland
- * @date 2003-06-22
- * from mayaToEggConverter.cxx created by drose (10Nov99)
- */
-
-#ifndef __maxToEggConverter__H
-#define __maxToEggConverter__H
-
-#pragma conform(forScope, off)
-
-/* Error-Reporting Includes
- */
-#define MTEC Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM4
-
-/* Helpful Defintions and Casts
- */
-#define null 0
-#define PHYSIQUE_CLASSID Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B)
-
-/* External Helper Functions for UI
- */
-// *** Figure out why this is causing link errors DWORD WINAPI
-// ProgressBarFunction(LPVOID arg);
-
-/**
- * This class supervises the construction of an EggData structure from a Max
- * model
- */
-class MaxToEggConverter {
- public:
-    MaxToEggConverter();
-    ~MaxToEggConverter();
-
-    bool convert(MaxEggOptions *options);
-
- private:
-    struct PandaMaterial {
-        std::vector<PT(EggTexture)> _texture_list;
-        LColor _color;
-        std::vector<int> _map_channels;
-        bool _any_diffuse;
-        bool _any_opacity;
-        bool _any_gloss;
-        bool _any_normal;
-    };
-    typedef std::map<Mtl*,PandaMaterial> MaterialMap;
-    MaxEggOptions    *_options;
-    int               _current_frame;
-    PT(EggData)       _egg_data;
-    std::string            _program_name;
-    MaxNodeTree       _tree;
-    int               _cur_tref;
-    EggTextureCollection _textures;
-    MaterialMap       _material_map;
-
-    void reset();
-
-    bool convert_char_model();
-    bool convert_char_chan(double start_frame, double end_frame,
-                           double frame_inc, double output_frame_rate);
-    bool convert_hierarchy(EggGroupNode *egg_root);
-    bool process_model_node(MaxNodeDesc *node_desc);
-
-    void get_transform(INode *max_node, EggGroup *egg_group);
-    LMatrix4d get_object_transform(INode *max_node);
-    void get_joint_transform(INode *max_node, EggGroup *egg_group);
-    void get_joint_transform(INode *max_node, INode *parent_node,
-                             EggGroup *egg_group);
-
-    bool make_nurbs_curve(INode *max_node, NURBSCVCurve *curve,
-                          TimeValue time, EggGroup *egg_group);
-    void make_polyset(INode *max_node,
-                      Mesh *mesh,
-                      EggGroup *egg_group,
-                      Shader *default_shader = nullptr);
-
-    Point3 get_max_vertex_normal(Mesh *mesh, int faceNo, int vertNo);
-    VertColor get_max_vertex_color(Mesh *mesh, int FaceNo, int VertexNo);
-    VertColor get_max_vertex_color(Mesh *mesh,int FaceNo,int VertexNo, int channel);
-    UVVert get_max_vertex_texcoord(Mesh *mesh, int faceNo, int vertNo, int channel);
-
-    void get_vertex_weights(INode *max_node, EggVertexPool *vpool);
-
-    const PandaMaterial &get_panda_material(Mtl *mtl, MtlID id);
-    void analyze_diffuse_maps(PandaMaterial &pandaMat, Texmap *m);
-    void analyze_opacity_maps(PandaMaterial &pandaMat, Texmap *m);
-    void analyze_gloss_maps(PandaMaterial &pandaMat, Texmap *m);
-    void analyze_glow_maps(PandaMaterial &pandaMat, Texmap *m);
-    void analyze_normal_maps(PandaMaterial &pandaMat, Texmap *m);
-    void add_map_channel(PandaMaterial &pandaMat, int channel);
-    void apply_texture_properties(EggTexture &tex, int channel);
-    std::string generate_tex_name();
-    std::string get_uv_name(int n);
-    bool reparent_decals(EggGroupNode *egg_parent);
-
- public:
-
-    Modifier* FindSkinModifier (INode* node, const Class_ID &type);
-};
-
-
-#endif

+ 0 - 6
pandatool/src/maxegg/p3maxegg_composite1.cxx

@@ -1,6 +0,0 @@
-
-#include "maxNodeDesc.cxx"
-#include "maxNodeTree.cxx"
-#include "maxOptionsDialog.cxx"
-#include "maxToEggConverter.cxx"
-#include "maxEgg.cxx"

+ 0 - 277
pandatool/src/maxprogs/maxEggImport.cxx

@@ -1,277 +0,0 @@
-/**
- * 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."
- *
- * @file maxEggImport.cxx
- * @author jyelon
- * @date 2005-07-15
- *
- * 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.
- */
-
-// Include this before everything
-#include "pandatoolbase.h"
-
-using std::min;
-using std::max;
-
-// local includes
-#include "maxEggLoader.h"
-#include "maxImportRes.h"
-
-// MAX includes
-#include <Max.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 INT_PTR 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 INT_PTR CALLBACK ImportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-  MaxEggImporter *imp = (MaxEggImporter*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
-  switch (msg) {
-  case WM_INITDIALOG:
-    imp = (MaxEggImporter*)lParam;
-    SetWindowLongPtr(hWnd, GWLP_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);
-
-#ifdef _UNICODE
-  char sname[2048];
-  sname[2047] = 0;
-  wcstombs(sname, name, 2047);
-  bool ok = MaxLoadEggFile(sname, _merge ? true:false, _importmodel ? true:false, _importanim ? true:false);
-#else
-  bool ok = MaxLoadEggFile(name, _merge ? true:false, _importmodel ? true:false, _importanim ? true:false);
-#endif
-
-  std::string txt = log.str();
-  if (txt != "") {
-    MessageBoxA(nullptr, txt.c_str(), "Panda3D Importer", MB_OK);
-  } else if (!ok) {
-    MessageBoxA(nullptr, "Import Failed, unknown reason\n", "Panda3D Importer", MB_OK);
-  }
-
-  Notify::ptr()->set_ostream_ptr(nullptr, 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;
-    // It appears that InitCustomControls is deprecated in 2012. I'm not sure
-    // if we can just remove it like this, but I've heard that it seems to
-    // work, so let's do it like this.
-#if MAX_VERSION_MAJOR < 14
-    InitCustomControls(hInstance);
-#endif
-    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;
-}

+ 0 - 7
pandatool/src/maxprogs/maxEggImport.def

@@ -1,7 +0,0 @@
-EXPORTS
-	LibDescription			@1
-	LibNumberClasses		@2
-	LibClassDesc			@3
-	LibVersion			@4
-SECTIONS
-	.data READ WRITE

+ 0 - 21
pandatool/src/maxprogs/maxImportRes.h

@@ -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

+ 0 - 122
pandatool/src/maxprogs/maxImportRes.rc

@@ -1,122 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "maxImportRes.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "WinResrc.h"
-#define IDC_STATIC -1
-////////////////////////////////////////////////////////////////////
-#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
-