Pārlūkot izejas kodu

new stuff from CMU

David Rose 21 gadi atpakaļ
vecāks
revīzija
0cc932301d
47 mainītis faili ar 12065 papildinājumiem un 331 dzēšanām
  1. 1 0
      direct/src/dcparser/dcPython.h
  2. 219 0
      direct/src/directbase/ppython.cxx
  3. 47 0
      direct/src/ffi/jGenPyCode.py
  4. 0 9
      doc/README
  5. 1 3
      doc/SceneEditor/seTree.py
  6. 0 202
      doc/build
  7. 6 2
      doc/doc/Config.pp.sample
  8. 8 10
      doc/doc/Config.prc
  9. 180 0
      doc/doc/INSTALL-MK
  10. 8 1
      doc/doc/INSTALL-PP
  11. 176 0
      doc/doc/InstallerNotes
  12. 98 98
      doc/doc/LICENSE
  13. 32 0
      doc/doc/README
  14. 0 0
      doc/doc/ReleaseNotes
  15. 5877 0
      doc/makepanda/makepanda.py
  16. 21 0
      doc/makepanda/makepanda.sln
  17. 40 0
      doc/makepanda/makepanda.vcproj
  18. 148 0
      doc/makepanda/maketarball.py
  19. 3 5
      dtool/metalibs/dtoolconfig/pydtool.cxx
  20. 2 1
      dtool/src/interrogate/interfaceMakerPython.cxx
  21. 1 0
      dtool/src/interrogate/interrogate_module.cxx
  22. 28 0
      dtool/src/parser-inc/Max.h
  23. 28 0
      dtool/src/parser-inc/iparamb2.h
  24. 28 0
      dtool/src/parser-inc/iparamm2.h
  25. 28 0
      dtool/src/parser-inc/iskin.h
  26. 28 0
      dtool/src/parser-inc/istdplug.h
  27. 28 0
      dtool/src/parser-inc/phyexp.h
  28. 28 0
      dtool/src/parser-inc/stdmat.h
  29. 79 0
      pandatool/src/maxegg/DllEntry.cpp
  30. 369 0
      pandatool/src/maxegg/Logger.cpp
  31. 121 0
      pandatool/src/maxegg/Logger.h
  32. 410 0
      pandatool/src/maxegg/MaxEgg.cpp
  33. 8 0
      pandatool/src/maxegg/MaxEgg.def
  34. 92 0
      pandatool/src/maxegg/MaxEgg.h
  35. 180 0
      pandatool/src/maxegg/MaxEgg.rc
  36. 88 0
      pandatool/src/maxegg/MaxToEgg.cpp
  37. 58 0
      pandatool/src/maxegg/MaxToEgg.h
  38. 189 0
      pandatool/src/maxegg/MaxToEggConverter.h
  39. 226 0
      pandatool/src/maxegg/maxNodeDesc.cxx
  40. 111 0
      pandatool/src/maxegg/maxNodeDesc.h
  41. 466 0
      pandatool/src/maxegg/maxNodeTree.cxx
  42. 73 0
      pandatool/src/maxegg/maxNodeTree.h
  43. 2418 0
      pandatool/src/maxegg/maxToEggConverter.cxx
  44. 24 0
      pandatool/src/maxegg/post_max_include.h
  45. 35 0
      pandatool/src/maxegg/pre_max_include.h
  46. 48 0
      pandatool/src/maxegg/resource.h
  47. 6 0
      ppremake/BUILD_FROM_CVS.txt

+ 1 - 0
direct/src/dcparser/dcPython.h

@@ -25,6 +25,7 @@
 #ifdef HAVE_PYTHON
 
 #undef HAVE_LONG_LONG  // NSPR and Python both define this.
+#undef _POSIX_C_SOURCE
 #include <Python.h>
 
 // Several interfaces in this module that use Python also require

+ 219 - 0
direct/src/directbase/ppython.cxx

@@ -0,0 +1,219 @@
+
+///////////////////////////////////////////////////////////////////////
+//
+// This simple program merely sets up the python environment
+// variables and then runs python:
+//
+//    PYTHONPATH
+//    PATH
+//    PANDAROOT
+//
+// Note that 'genpycode' is just a slight variant of 'ppython':
+//
+// genpycode xyz -->
+// ppython direct\\src\\ffi\\jGenPyCode.py xyz
+//
+///////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////
+//
+// Windows Version
+//
+///////////////////////////////////////////////////////////////////////
+
+#ifdef WIN32
+
+#ifdef BUILDING_PPYTHON
+#define LINK_SOURCE "\\bin\\ppython.exe"
+#define LINK_TARGET "\\python\\python.exe"
+#define GENPYCODE 0
+#endif
+
+#ifdef BUILDING_GENPYCODE
+#define LINK_SOURCE "\\bin\\genpycode.exe"
+#define LINK_TARGET "\\python\\python.exe"
+#define GENPYCODE 1
+#endif
+
+#include <windows.h>
+#include <winuser.h>
+#include <stdlib.h>
+#include <process.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <signal.h>
+#define PATH_MAX 1024
+
+void pathfail(void)
+{
+  fprintf(stderr, "Cannot locate the root of the panda tree\n");
+  exit(1);
+}
+
+int main(int argc, char **argv)
+{
+  char fnbuf[PATH_MAX],ppbuf[PATH_MAX],pabuf[PATH_MAX],prbuf[PATH_MAX],modcmd[PATH_MAX];
+  int fnlen;
+
+  // Ask windows for the file name of this executable.
+
+  fnlen = GetModuleFileName(NULL, fnbuf, 1023);  
+  if ((fnlen <= 0)||(fnlen >= 1023)) pathfail();
+  fnbuf[fnlen] = 0;
+
+  // Make sure that the executable's name ends in LINK_SOURCE
+  
+  int srclen = strlen(LINK_SOURCE);
+  if (fnlen < srclen + 4) pathfail();
+  if (stricmp(fnbuf + fnlen - srclen, LINK_SOURCE)) pathfail();
+  fnlen -= srclen; fnbuf[fnlen] = 0;
+  
+  // Fetch the command line and trim the first word.
+  
+  char *args = GetCommandLine();
+  char *firstspace = strchr(args,' ');
+  if (firstspace) args = firstspace+1;
+  else args="";
+
+  // Calculate MODCMD
+  
+  if (GENPYCODE) {
+    sprintf(ppbuf,"%s\\direct\\src\\ffi\\jGenPyCode.py",fnbuf);
+    FILE *f = fopen(ppbuf,"r");
+    if (f) {
+      fclose(f);
+      sprintf(modcmd,"python %s\\direct\\src\\ffi\\jGenPyCode.py %s",fnbuf,args);
+    } else {
+      sprintf(modcmd,"python %s\\..\\direct\\src\\ffi\\jGenPyCode.py %s",fnbuf,args);
+    }
+  } else sprintf(modcmd,"python %s",args);
+  
+  // Set the PANDAROOT, PYTHONPATH and PATH
+  
+  char *pp = getenv("PYTHONPATH");
+  if (pp) sprintf(ppbuf,"PYTHONPATH=%s;%s\\bin;%s\\lib;%s",fnbuf,fnbuf,fnbuf,pp);
+  else    sprintf(ppbuf,"PYTHONPATH=%s;%s\\bin;%s\\lib",fnbuf,fnbuf,fnbuf);
+  putenv(ppbuf);
+  char *path = getenv("PATH");
+  if (path) sprintf(pabuf,"PATH=%s\\bin;%s",fnbuf,path);
+  else      sprintf(pabuf,"PATH=%s\\bin",fnbuf);
+  putenv(pabuf);
+  sprintf(prbuf,"PANDAROOT=%s",fnbuf);
+  putenv(prbuf);
+  
+  // Append LINK_TARGET to the file name.
+  
+  if (fnlen + strlen(LINK_TARGET) > 1023) pathfail();
+  strcat(fnbuf, LINK_TARGET);
+  
+  // Run it.
+
+  signal(SIGINT, SIG_IGN);
+  PROCESS_INFORMATION pinfo;
+  STARTUPINFO sinfo;
+  GetStartupInfo(&sinfo);
+  BOOL ok = CreateProcess(fnbuf,modcmd,NULL,NULL,TRUE,NULL,NULL,NULL,&sinfo,&pinfo);
+  if (ok) WaitForSingleObject(pinfo.hProcess,INFINITE);
+}
+
+#endif /* WIN32 */
+
+///////////////////////////////////////////////////////////////////////
+//
+// Linux Version
+//
+// This would probably work on most unixes, with the possible
+// exception of the /proc/self/exe bit.
+//
+///////////////////////////////////////////////////////////////////////
+
+#ifdef __linux__
+
+#ifdef BUILDING_PPYTHON
+#define LINK_SOURCE "/bin/ppython"
+#define GENPYCODE 0
+#endif
+
+#ifdef BUILDING_GENPYCODE
+#define LINK_SOURCE "/bin/genpycode"
+#define GENPYCODE 1
+#endif
+
+#include <stdlib.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/param.h>
+
+void errorexit(char *s)
+{
+  fprintf(stderr,"%s\n");
+  exit(1);
+}
+
+void pathfail(void)
+{
+  fprintf(stderr, "Cannot locate the root of the panda tree\n");
+  exit(1);
+}
+
+int main(int argc, char **argv)
+{
+  char fnbuf[PATH_MAX],ppbuf[PATH_MAX],pabuf[PATH_MAX],prbuf[PATH_MAX],genpyc[PATH_MAX];
+  char *modargv[1024];
+  int fnlen,modargc;
+
+  // Ask linux for the file name of this executable.
+
+  int ok = readlink("/proc/self/exe", fnbuf, PATH_MAX-1);
+  if (ok<0) errorexit("Cannot read /proc/sys/exe");
+  fnbuf[PATH_MAX-1] = 0;
+  fnlen = strlen(fnbuf);
+
+  // Make sure that the executable's name ends in LINK_SOURCE
+  
+  int srclen = strlen(LINK_SOURCE);
+  if (fnlen < srclen + 4) pathfail();
+  if (strcmp(fnbuf + fnlen - srclen, LINK_SOURCE)) pathfail();
+  fnlen -= srclen; fnbuf[fnlen] = 0;
+
+  // Calculate GENPYC
+  
+  if (GENPYCODE) {
+    sprintf(ppbuf,"%s/direct/src/ffi/jGenPyCode.py",fnbuf);
+    FILE *f = fopen(ppbuf,"r");
+    if (f) {
+      fclose(f);
+      sprintf(genpyc,"%s/direct/src/ffi/jGenPyCode.py",fnbuf);
+    } else {
+      sprintf(genpyc,"%s/../direct/src/ffi/jGenPyCode.py",fnbuf);
+    }
+  }
+  
+  // Set the PANDAROOT, PYTHONPATH and PATH
+  
+  char *pp = getenv("PYTHONPATH");
+  if (pp) sprintf(ppbuf,"PYTHONPATH=%s:%s/lib:%s",fnbuf,fnbuf,pp);
+  else    sprintf(ppbuf,"PYTHONPATH=%s:%s/lib",fnbuf,fnbuf);
+  putenv(ppbuf);
+  char *path = getenv("PATH");
+  if (path) sprintf(pabuf,"PATH=%s/bin;%s",fnbuf,path);
+  else      sprintf(pabuf,"PATH=%s/bin",fnbuf);
+  putenv(pabuf);
+  sprintf(prbuf,"PANDAROOT=%s",fnbuf);
+  putenv(prbuf);
+  
+  // Calculate MODARGV
+  modargc=0;
+  modargv[modargc++]="python";
+  if (GENPYCODE) modargv[modargc++] = genpyc;
+  for (int i=1; i<argc; i++) modargv[modargc++] = argv[i];
+  modargv[modargc] = 0;
+  
+  // Run it.
+  execv("/usr/bin/python", modargv);
+}
+
+#endif /* LINUX */

+ 47 - 0
direct/src/ffi/jGenPyCode.py

@@ -0,0 +1,47 @@
+##############################################################
+#
+# This module should be invoked by a shell-script that says:
+#
+#    python direct\\src\\ffi\\jGenPyCode.py <arguments>
+#
+# Before invoking python, the shell-script may need to set
+# these environment variables, to make sure that everything
+# can be located appropriately.
+#
+#    PYTHONPATH
+#    PANDAROOT
+#    PATH
+#
+##############################################################
+
+import sys,os;
+
+if (os.environ.has_key("PANDAROOT")==0):
+  print "jGenPyCode was not invoked correctly"
+  sys.exit(1)
+
+pandaroot = os.environ["PANDAROOT"]
+if (os.path.isdir(os.path.join(pandaroot,"direct","src"))):
+  directsrc=os.path.join(pandaroot,"direct","src")
+elif (os.path.isdir(os.path.join(os.path.dirname(pandaroot),"direct","src"))):
+  directsrc=os.path.join(os.path.dirname(pandaroot),"direct","src")
+else:
+  print "jGenPyCode cannot locate the 'direct' tree"
+  sys.exit(1)
+
+from direct.ffi import DoGenPyCode
+from direct.ffi import FFIConstants
+DoGenPyCode.outputDir = os.path.join(pandaroot,"lib","pandac")
+DoGenPyCode.extensionsDir = os.path.join(directsrc,"extensions")
+DoGenPyCode.interrogateLib = r'libdtoolconfig'
+DoGenPyCode.codeLibs = ['libpandaexpress','libpanda','libpandaphysics','libpandafx','libdirect']
+DoGenPyCode.etcPath = [os.path.join(pandaroot,"etc")]
+
+#print "outputDir = ",DoGenPyCode.outputDir
+#print "extensionsDir = ",DoGenPyCode.extensionsDir
+#print "interrogateLib = ",DoGenPyCode.interrogateLib
+#print "codeLibs = ",DoGenPyCode.codeLibs
+#print "etcPath = ",DoGenPyCode.etcPath
+
+DoGenPyCode.run()
+

+ 0 - 9
doc/README

@@ -1,9 +0,0 @@
-Panda3D Read Me
-
-Panda3D is a powerful rendering engine for SGI, Linux, Sun, and Windows.
-The core of the engine is in C++. Panda3D/DIRECT provides a Python
-scripting interface and utility code. Panda3D can be used with or without
-Python.
-
-Panda is a complex project and is not trivial to install.  Please read
-the INSTALL document in this directory before starting.

+ 1 - 3
doc/SceneEditor/seTree.py

@@ -19,9 +19,7 @@ from direct.showbase.TkGlobal import *
 from direct.showbase.PandaObject import *
 
 # Initialize icon directory
-f = Filename('icons')
-f.resolveFilename(getModelPath())
-ICONDIR = f.toOsSpecific()
+ICONDIR = getModelPath().findFile(Filename('icons')).toOsSpecific()
 if not os.path.isdir(ICONDIR):
     raise RuntimeError, "can't find DIRECT icon directory (%s)" % `ICONDIR`
 

+ 0 - 202
doc/build

@@ -1,202 +0,0 @@
-#!/bin/bash
-
-# This script is an experiment.  It is designed to automate the
-# Panda3D build process for Linux or Unix users, or for Windows users
-# who have Cygwin installed.  If you want to build Panda3D on a
-# Windows machine without Cygwin, please refer to the INSTALL document
-# instead of attempting to run this script.
-
-# Before you run this script, you must set up your Config.pp file and
-# Config.prc files as described in the INSTALL document, and you must
-# build and install ppremake (or ppremake.exe), before running this
-# script.  
-
-# You should ensure that the install bin directory,
-# e.g. /usr/local/panda/bin, is on your PATH, and that the install lib
-# directory, /usr/local/panda/lib, is on your LD_LIBRARY_PATH (for
-# Unix) or your PATH (for Windows).  If you are building Python
-# interfaces, you should also ensure that /usr/local/panda/lib is on
-# your PYTHONPATH.
-
-# Finally, you must have write permission to the /usr/local/panda
-# directory hierarchy in order for this script to run successfully.
-
-# As with any automatic process, this script may not work in every
-# environment.  An effort has been made to make the script as
-# trouble-free as possible, but things can always go wrong.  If you
-# have difficulty running this script, you are encouraged to follow
-# the step-by-step instructions in the INSTALL document to build
-# Panda3D by hand.
-
-
-usage="build [\"\"|new|uninstall|install|clean|only|genpy [\"\"|dtool|panda|direct|<relative path>] ]"
-usage=$(cat <<-EOS
-Usage: ./$(basename $0) [ mode [ module [ package ] ] ]
-  
-  [Be sure to cd to the panda3d directory first.]
-  
-  mode      ""|new|uninstall|install|clean|only|genpy|--help
-  module    ""|dtool|panda|direct|<relative path>
-  package   one of the */src/* directories.
-
-  Examples:
-    ./build new
-    ./build install
-    ./build install panda
-    ./build clean
-    ./build clean panda
-    ./build genpy
-    ./build only panda express
-    ./build quick panda express
-
-EOS
-)
-
-mode=$1
-module=$2
-base=$(pwd)
-wantGenPy=1
-
-#trap "exit" INT
-if [ "$mode" == "--help" ]; then
-    echo "$usage"
-    exit
-fi
-
-echo -e "\nSetting up build environment\n"
-if [ -f ./build_env ]; then
-  source ./build_env || exit
-fi
-
-modules="dtool panda pandatool direct $modules"
-
-if [ "$module" != "" ]; then
-    modules="$module"
-fi
-
-case "$mode" in
-( only )
-    cd $base/$module        || exit
-    ppremake                || exit
-    make uninstall install  || exit
-    modules_ppremake=""
-    modules_clean=""
-    modules_uninstall=""
-    modules_install=""
-    ;;
-( quick )
-    cd $base/$module/src/$3 || exit
-    make                    || exit
-    cd $base/$module        || exit
-    make install            || exit
-    wantGenPy=0
-    modules_ppremake=""
-    modules_clean=""
-    modules_uninstall=""
-    modules_install=""
-    ;;
-( new )
-    # ...build the newest version of the code:
-    echo -e "\nUpdating cvs\n"
-    cd "$base"   || exit
-    ./cvs_update || exit
-    cd "$base"   || exit
-    # This next command is allowed to fail (no || exit):
-    echo -e "\nBuilding tags file\n"
-    ctags -nR -h '+.I' --langmap='c:+.I' -h '+.T' --langmap='c:+.T' --fields=fmisS
-    modules_ppremake=$modules
-    modules_clean="direct $modules_clean"
-    modules_uninstall=$modules
-    modules_install=$modules
-    ;;
-( ppremake )
-    wantGenPy=0
-    modules_ppremake=$modules
-    modules_clean=""
-    modules_uninstall=""
-    modules_install=""
-    ;;
-( clean )
-    wantGenPy=0
-    modules_ppremake=$modules
-    modules_clean=$modules
-    modules_uninstall=""
-    modules_install=""
-    ;;
-( uninstall )
-    wantGenPy=0
-    modules_ppremake=$modules
-    modules_clean=""
-    modules_uninstall=$modules
-    modules_install=""
-    ;;
-( install )
-    modules_ppremake=$modules
-    modules_clean=""
-    modules_uninstall=$modules
-    modules_install=$modules
-    ;;
-( "" )
-    modules_ppremake=$modules
-    # Some modules are small enough that we clean them for good measure:
-    modules_clean="direct $modules_clean"
-    modules_uninstall=$modules
-    modules_install=$modules
-    ;;
-( genpy )
-    wantGenPy=1
-    modules_ppremake=""
-    modules_clean=""
-    modules_uninstall=""
-    modules_install=""
-    ;;
-( * )
-    echo -e "\nThat mode is not recognized ($mode)"
-    echo "$usage"
-    exit 1
-    ;;
-esac
-
-echo "    modules_ppremake  =$modules_ppremake"
-echo "    modules_clean     =$modules_clean"
-echo "    modules_uninstall =$modules_uninstall"
-echo "    modules_install   =$modules_install"
-
-for i in $modules_ppremake; do
-    echo -e "\nStarting Ppremake of $i\n"
-    cd "$base/$i"            || exit
-    ppremake $ppremake_args  || exit
-done
-for i in $modules_clean; do
-    echo -e "\nStarting Clean of $i\n"
-    cd "$base/$i"   || exit
-    make clean      || exit
-done
-for i in $modules_uninstall; do
-    echo -e "\nStarting Uninstall of $i\n"
-    cd "$base/$i"   || exit
-    make uninstall  || exit
-done
-for i in $modules_install; do
-    echo -e "\nStarting Install (build) of $i\n"
-    cd "$base/$i"   || exit
-    make install    || exit
-done
-
-cd "$base"
-
-if (($wantGenPy)); then
-    # Generate Python code:
-    echo "Generating Python/C++ interface code"
-    #cd $base || exit
-    genPyCode || exit
-fi
-
-if [ ! -f "$INSTALL_DIR/etc/config.prc" -a -f "$HOME/config.prc" ]; then
-    echo ""
-    echo "A .prc file was found at '$HOME/config.prc' creating a hard link from '$INSTALL_DIR/etc/'"
-    ( cd "$INSTALL_DIR/etc" && ln "$HOME/config.prc" . );
-fi
-
-echo "done"
-

+ 6 - 2
doc/Config.pp.sample → doc/doc/Config.pp.sample

@@ -1,9 +1,13 @@
+///////////////////////////////////////////////////////////////////////
+// Caution: there are two separate, independent build systems:
+// 'makepanda', and 'ppremake'.  Use one or the other, do not attempt
+// to use both.  This file is part of the 'ppremake' system.
+///////////////////////////////////////////////////////////////////////
+
 // This is a sample Config.pp that you may wish to use for your own
 // needs.  For a longer list of configuration variables that you may
 // set in your own Config.pp file, see dtool/Config.pp.
 
-
-
 // What level of compiler optimization/debug symbols should we build?
 // The various optimize levels are defined as follows:
 //

+ 8 - 10
doc/Config.prc → doc/doc/Config.prc

@@ -40,16 +40,13 @@ framebuffer-mode rgba double-buffer depth multisample hardware software
 
 
 # These specify where model files may be loaded from.  You probably
-# want to set this to a sensible path for yourself.  Note the use of
-# the Panda convention of forward slashes (instead of backslash)
-# separating directory names.  (You may also use Windows-native paths
-# here if you prefer.)
+# want to set this to a sensible path for yourself.  $THIS_PRC_DIR is
+# a special variable that indicates the same directory as this
+# particular Config.prc file.
 model-path  .
-model-path  $PRC_DIR
-model-path  $PRC_DIR/..
+model-path  $THIS_PRC_DIR
 sound-path  .
-sound-path  $PRC_DIR
-sound-path  $PRC_DIR/..
+sound-path  $THIS_PRC_DIR
 
 # This makes the egg loader available to load egg files.
 load-file-type pandaegg
@@ -60,8 +57,9 @@ load-file-type pandaegg
 # Lightwave) directly into Panda.
 # load-file-type ptloader
 
-# Turn off audio:
-audio-library-name null
+# Enable audio using the FMod audio library by default:
+audio-library-name fmod_audio
+#audio-library-name miles_audio
 
 # This enable the automatic creation of a TK window when running
 # Direct.

+ 180 - 0
doc/doc/INSTALL-MK

@@ -0,0 +1,180 @@
+
+///////////////////////////////////////////////////////////////////////
+// Caution: there are two separate, independent build systems:
+// 'makepanda', and 'ppremake'.  Use one or the other, do not attempt
+// to use both.  This file is part of the 'makepanda' system.
+///////////////////////////////////////////////////////////////////////
+
+Panda3D Install --- using the 'makepanda' system.
+
+INVOKING MAKEPANDA
+
+Makepanda is a script that builds panda, all the way through. To
+invoke it under windows, type this:
+
+	makepanda
+
+To invoke it under Linux, you need to type the 'py' extension
+explicitly:
+
+	makepanda.py
+
+From this point forward, I will not be including the 'py' extension
+in my examples, I will simply assume that you know to add it if your
+OS requires it.
+
+
+BUILDING PANDA: QUICK START
+
+The easy way to build panda is to type:
+
+	makepanda --default
+
+This will compile panda with all the default options.  The default is
+to compile every feature, every subsystem, and every tool that can
+possibly be built.  It can take several hours, depending on the speed
+of your machine.
+
+The resulting copy of panda will be found in a subdirectory 'built'
+inside the source tree.  You can invoke panda programs directly out of
+the built subdirectory.
+
+You can also move the built subdirectory elsewhere on your machine.
+If you choose to do so, you must first copy the subdirectories
+'models', 'samples', and 'SceneEditor' into the built subdirectory,
+and 'direct/src' into 'built/direct/src'.
+
+
+BUILDING PANDA: COMMAND-LINE OPTIONS
+
+The default invocation of makepanda is a good way to test panda on
+your machine.  However, it compiles several features that you probably
+don't need.  To disable the extra features, you need to specify
+command-line options to makepanda.  If you invoke:
+
+	makepanda --help
+
+it will show you the available command-line options:
+
+  --compiler X      (currently, compiler can only be MSVC7,LINUXA)
+  --optimize X      (optimization level can be 1,2,3,4)
+  --thirdparty X    (directory containing third-party software)
+  --complete        (copy models, samples, direct into the build)
+  --no-installer    (don't bother building the executable installer)
+  --v1 X            (set the major version number)
+  --v2 X            (set the minor version number)
+  --v3 X            (set the sequence version number)
+  --lzma            (use lzma compression when building installer)
+
+  --no-zlib         (disable the use of ZLIB)
+  --no-png          (disable the use of PNG)
+  --no-jpeg         (disable the use of JPEG)
+  --no-tiff         (disable the use of TIFF)
+  --no-vrpn         (disable the use of VRPN)
+  --no-fmod         (disable the use of FMOD)
+  --no-nvidiacg     (disable the use of NVIDIACG)
+  --no-helix        (disable the use of HELIX)
+  --no-nspr         (disable the use of NSPR)
+  --no-openssl      (disable the use of OPENSSL)
+  --no-freetype     (disable the use of FREETYPE)
+  --no-fftw         (disable the use of FFTW)
+  --no-miles        (disable the use of MILES)
+  --no-maya5        (disable the use of MAYA5)
+  --no-maya6        (disable the use of MAYA6)
+  --no-max5         (disable the use of MAX5)
+  --no-max6         (disable the use of MAX6)
+  --no-max7         (disable the use of MAX7)
+
+  --no-nothing      (don't use any of the third-party packages)
+  --default         (use default options for everything not specified)
+
+Makepanda shows you all the available options, not all of which may be
+relevant to your operating system.  For example, makepanda can build a
+plugin for 3D Studio Max 5.  However, there is no 3D Studio Max for
+linux, so the option --no-max5 is largely irrelevant under Linux.
+
+Note that 'makepanda' is a new tool.  The panda3d team has not had
+time to test all the options.  It is very likely that several do not
+work.  However, we have thoroughly tested the --default configuration,
+which works flawlessly on the machines we own.
+
+The options you are most likely to be interested in are:
+
+--no-installer: Under Windows, makepanda builds an installer --- a
+neatly packaged EXE file containing a panda distribution.  This takes
+time and disk space, and you probably don't need to build your own
+installer.  This option is only relevant under Windows.
+
+--no-helix: Helix is realmedia's library of subroutines for playing
+realvideo files, realaudio files, and streaming video and audio.  It's
+a large library, and unless you're planning on using this feature, you
+might be able to shave several megabytes off your panda tree.  This
+option is only relevant under Windows.
+
+--no-openssl: Panda3D can download resources from encrypted websites.
+Again, this is a large library, and unless you're planning on using
+this feature, you might be able to shave several megabytes off your
+panda tree.  This option is much less useful under Linux, where openssl
+is normally provided as a shared library, and therefore doesn't really
+cost any disk space.
+
+--thirdparty: Panda3D uses a number of third-party libraries: libpng,
+fftw, nspr, etc.  Panda3D obtains these libraries from the host
+operating system where possible, so if your OS comes with a copy of
+libpng, Panda3D uses that.  Those libraries which are not provided by
+the host operating system are included in the source tar-ball under a
+subdirectory 'thirdparty'.  If you are not satisfied with the versions
+of the libraries we have provided, you may supply your own versions.
+To do so, duplicate the 'thirdparty' tree, substitute your own
+libraries, and then use the --thirdparty option to point makepanda to
+your libraries.
+
+
+THE EDIT-COMPILE-DEBUG CYCLE
+
+A small caution: if you invoke 'makepanda' with one set of options,
+and then invoke 'makepanda' using the *exact same* set of options, the
+second time will be fast.  It will see that everything has already
+been built, and it will do no actual compilation.  As a result,
+makepanda can be used as part of an edit-compile-debug cycle.
+
+However, if you invoke makepanda with a *different* set of options,
+makepanda may need to recompile and relink a lot of files.  This is
+because several of those options change the values of '#define'
+headers, so changing the options requires a recompilation.
+
+It is all too easy to accidentally invoke 'makepanda' with the wrong
+options, thereby triggering an hour-long recompilation.  To avoid this
+situation, we recommend that you write a short script containing the
+options you intend to use regularly.  For example, I regularly compile
+panda without helix and without the installer.  I have a very short
+Windows BAT file called "mkp.bat" that looks like this:
+
+	@echo off
+	makepanda --no-installer --no-helix
+
+This helps me avoid accidentally typing makepanda with the wrong
+options.
+
+We have included a Visual Studio project file that simply invokes
+'makepanda' whenever you click 'compile', and it runs ppython when you
+click 'run'.  This is a handy way to edit, compile, and debug the
+panda3d sources.
+
+
+BUILDING THE SOURCE TAR-BALL AND THE RPM
+
+If you want to build an RPM, it is fairly easy to do so.  First, you
+need a panda source tar-ball.  If you do not already have one, build
+one using 'maketarball.py'.  You will need to specify a version
+number.
+
+	maketarball.py --v1 58 --v2 23 --v3 95
+
+This builds panda3d-58.23.95.tar.gz.  Once you have the tar-ball,
+it is easy to turn it into a binary RPM:
+
+	rpmbuild -tb panda3d-58.23.95.tar.gz
+
+Before you use rpmbuild, you need to set up an RPM workspace.  Doing
+so is beyond the scope of this document.

+ 8 - 1
doc/INSTALL → doc/doc/INSTALL-PP

@@ -1,4 +1,11 @@
-Panda3D Install
+
+///////////////////////////////////////////////////////////////////////
+// Caution: there are two separate, independent build systems:
+// 'makepanda', and 'ppremake'.  Use one or the other, do not attempt
+// to use both.  This file is part of the 'ppremake' system.
+///////////////////////////////////////////////////////////////////////
+
+Panda3D Install --- using the 'ppremake' system.
 
 This document describes how to compile and install Panda 3D on a
 system for the first time.  Panda is a complex project and is not

+ 176 - 0
doc/doc/InstallerNotes

@@ -0,0 +1,176 @@
+------------------------  RELEASE 1.1.0  ---------------------------------
+
+	* We now have working exporters for Max5, Max6, Max7, Maya5, Maya6
+
+	* The Max exporter is dramatically improved:
+
+	  - it now includes support for character studio.
+	  - the polygon winding bug has been fixed.
+
+	* Panda no longer requires any registry keys or environment
+	variables. This means it is now possible to:
+
+	     - run panda directly from a compact disc
+	     - install multiple copies of panda on a single machine
+	     - install panda by copying the tree from another computer
+
+        Note that the installer does add the panda 'bin' directory to
+	your PATH, and it does store an uninstall key in the registry,
+	but neither of these is needed for panda to function.
+
+	* All of the sample programs have been tested.  The ones that didn't
+	work have been removed, the ones that do work have been (lightly)
+	documented.
+
+	* This is the first release to include not just a binary installer
+	for windows, but:
+
+	    - a binary installer (RPM) for Fedora 2
+	    - a binary installer (RPM) for Fedora 3
+	    - a binary installer (RPM) for Redhat 9
+	    - a binary installer for windows, as always
+	    - a source tar-ball for linux
+	    - a source zip-file for windows
+
+------------------------  RELEASE 2004-12-13  ---------------------------------
+
+	* Basic server-client networking support is back in Panda3D. There is a
+	networking sample in the samples directory. This uses the Panda3d
+	distributed object system.The README file will explain how to run this.
+	Documentation of this if forthcoming.
+
+	* Panda3d now reduces the number of environment variables such that only 2
+	are needed now - PRC_PATH and PLAYER.
+
+	* GraphicsChannel and GraphicsLayer class have been removed from the
+	panda/src/display directory. Most Panda applications won't need to be
+	changed, since most applications simply use ShowBase.py (which has been
+	adjustedappropriately) to open a window and do the initial setup.  For
+	those rare applications where you need to create your own DisplayRegions,
+	the makeDisplayRegion() interface has been moved from GraphicsLayer to
+	GraphicsWindow (actually, to GraphicsOutput, which is the base class of
+	GraphicsWindow).  You can modify your application to call
+	base.win.makeDisplayRegion() accordingly.  If you have something like
+	displayRegion.getLayer(), replace it with displayRegion.getWindow()
+	instead.
+
+	* Effective with the current version of Panda, the way that HPR angles are
+	calculated will be changing. The change will make a difference to existing
+	code or databases that store a hard-coded rotation as a HPR, but only when
+	R is involved, or both H and P are involved together.  That is to say more
+	precisely, HPR angles with (R != 0 || (H != 0 && P != 0)) now represent a
+	different rotation than they used to. If you find some legacy code that no
+	longer works correctly (e.g. it introduces crazy rotations), try putting
+	the following in your Config.prc file:
+
+		  temp-hpr-fix 0
+
+	To turn off the correct behavior and return to the old, broken behavior.
+	Note that a longer-term solution will be to represent the HPR angles
+	correctly in all legacy code.  The function oldToNewHpr() is provided to
+	aid this transition.
+
+	* PandaNode definition has been changed to support setting an
+	into_collide_mask for any arbitrary node, in particular for any GeomNode.
+	It used to be that only CollisionNodes had an into_collide_mask.  This
+	change obviates the need for CollisionNode::set_collide_geom(), which is
+	now a deprecated interface and will be removed at some point in the future.
+
+	Details:
+	There's now a NodePath::set_collide_mask() and
+	NodePath::get_collide_mask(), which operate on all CollisionNodes and
+	GeomNodes at and below the current node. By default, set_collide_mask()
+	will replace the entire collide mask, but you may also specify (via a
+	second parameter) the subset of bits that are to be changed; other bits
+	will be left alone.  You can also specify a particular type of node to
+	modify via a third parameter, e.g. you can adjust the masks for GeomNodes
+	or CollisionNodes only.
+
+	The NodePath set_collide_mask() interface changes the into_collide_mask.
+	Those familiar with the collision system will recall that a CollisionNode
+	(but only a CollisionNode) also has a from_collide_mask.  The
+	from_collide_mask of the active mover is compared with the into_collide_mask
+	of each object in the world; a collision is only possible if there are some
+	bits in common.
+
+	It used to be that only other CollisionNodes had an into_collide_mask.  A
+	mover would only test for collisions with CollisionNodes that matched its
+	collide_mask. If you wanted to make your mover detect collisions with
+	visible geometry which had no into_collide_mask, you had to call
+	set_collide_geom(1). This allowed the mover to detect collisions with *all*
+	visible geometry; it was either an all-or-none thing.
+
+	Now that GeomNodes also have an into_collide_mask, there's no longer a need
+	for set_collide_geom().  A mover will detect collisions with any
+	CollisionNodes or GeomNodes that match its collide_mask.  This means, for
+	the purposes of collision detection, you can use CollisionNodes and
+	GeomNodes pretty much interchangeably; simply set the appropriate bits on
+	the objects you want to collide with, regardless of whether they are
+	invisible collision solids or visible geometry.
+
+	(This should not be taken as a license to avoid using CollisionNodes
+	altogether. The intersection computation with visible geometry is still
+	less efficient than the same computation with collision solids. And visible
+	geometry tends to be many times more complex than is strictly necessary for
+	collisions.)
+
+	There's one more detail: every GeomNode, by default, has one bit set on in
+	its collide_mask, unless it is explicitly turned off.  This bit is
+	GeomNode::get_default_collide_mask().  This bit is provided for the
+	convenience of programmers who still want the old behavior of
+	set_collide_geom(): it allows you to easily create a CollisionNode that
+	will collide with all visible geometry in the world.
+
+	Along the same lines, there's also CollisionNode::get_default_collide_mask(),
+	which is 0x000fffff.  This is the default mask that is created for a new
+	CollisionNode (and it does not include the bit reserved for GeomNodes, 
+	above). Previously, a new CollisionNode would have all bits on by default.
+
+
+
+------------------------  RELEASE 2004-11-11  -----------------------------------
+
+	* Multiple mice can now be used with Panda3D. showbase has a list called
+	pointerWatcherNodes. The first mouse on this list is the system mouse. The
+	getMouseX() and getMouseY() will return coordinates relative to the
+	application window. The rest of the mice on the list will give raw mouse
+	positions and will change when they are moved on the screen.
+
+	In addition there are new events for mouse buttons. Each mouse will be have
+	a corresponding event. mouse1 will send mousedev1-mouse1, mousedev1-mouse2
+	and mousedev1-mouse3 events. mouse2 and any other mouse attached
+	will send similar events mousedev2-mouse1 etc.
+
+	The old mouse buttons work too. mouse1, mouse2, mouse3 events will be
+	triggered if that button is pressed on any mouse
+
+------------------------  RELEASE 2004-10-13  -----------------------------------
+
+General
+
+	* Release notes: Each release will now have an entry associated with
+	it in this document. This will be updated in reverse-chronological order.
+
+Panda3D
+	* Distributed with this release is a working version of the SceneEditor
+	created in Spring 2004 at the ETC. Documentation will be forthcoming on the
+	website. This can be found in <InstallPath>/SceneEditor
+
+	* The latest version of FMOD is distributed with this release. The latest
+	version is 3.73.
+
+	* AudioSound object now allows more types of sound. These include wma and 
+	ogg vorbis formats. This is valid when using the fmod sound system. Midi, 
+	Mod, s3m, it, xm and such sequencer type file formats are not supported. 
+	Exception - Midi files can be played. This is not fully implemented.
+
+	* A bug in SoundInterval is fixed. SoundInterval looping would incorrectly 
+	add a minimum of 1.5 seconds to the sound. This has been fixed. Sound 
+	looping problems in general should be fixed. Midi's still don't support 
+	looping through the AudioSound object. They should loop through 
+	SoundIntervals though.
+
+	* Cg support has been added to Panda3D. Documentation for this is 
+	forthcoming.
+
+

+ 98 - 98
doc/LICENSE → doc/doc/LICENSE

@@ -1,98 +1,98 @@
-IMPORTANT:
-READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
-ALL USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS:
-
-
-PANDA 3D SOFTWARE LICENSE AND DOWNLOAD TERMS
-
-1. The accompanying Panda 3D Software and associated documentation
-files (the "Software") is licensed to you, the recipient of the
-Software ("You") by Walt Disney Imagineering (the "Licensor") subject
-these terms and to the terms of the Panda 3D Public License Version
-1.0 (the "License") and You may not use this Software except in
-compliance with these terms and the terms of the License.  See the
-License for the specific language governing rights and limitations
-under the License.  You may obtain a copy of the License at
-http://www.panda3d.org/license.txt .  ANY DOWNLOADING, INSTALLING,
-USE, REPRODUCTION OR DISTRIBUTION OF THE SOFTWARE CONSTITUTES THE
-RECIPIENT'S ACCEPTANCE OF THESE TERMS AND THE LICENSE.  IF YOU DO NOT
-AGREE TO THIS LICENSE, DO NOT DOWNLOAD, INSTALL, COPY OR USE THE
-SOFTWARE.
-
-2. Licensor hereby grants to any person obtaining a copy of the
-Software a nonexclusive license to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, on an "AS
-IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-implied, subject to these terms and the License.
-
-3. All copies made of the Software source code must retain the
-following copyright notice and these terms and disclaimers in a
-conspicuous location in the Software.  Copies made of the Software in
-binary form or redistribution of this Software in binary form must
-reproduce the following copyright notice and these terms and
-disclaimers in a conspicuous location in the documentation and/or
-other materials provided with the distribution of the Software.
-
-PANDA 3D SOFTWARE
-Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
-
-4. Any modifications which You create or which You contribute to the
-Software are governed by these terms and the License.  The source code
-version of the Software may be distributed only under these terms and
-the License or a future version of the License released by Licensor,
-and You must include a copy of these terms with every copy of the
-source code or Software that You distribute.  You may not offer or
-impose any terms on any source code version that alters or restricts
-the applicable version of these terms or the License.  In addition,
-You must identify Yourself as the originator of the modifications or
-contributions You made to the Software, if any, in a manner that
-reasonably allows subsequent recipients to identify You as the
-originator of the modifications or contributions.  Further You must
-cause the Software to contain a file documenting the changes You made
-to create the modifications and the date of any change.  You must
-include a prominent statement describing the modifications made to the
-Software.  An electronic copy of the source code for all modifications
-made to the Software are to be forwarded to Licensor at
[email protected] within 90 days of the date of the
-modifications.
-
-5. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL LICENSOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF GOODWILL; LOSS OF USE, DATA, OR PROFITS; WORK
-STOPPAGE, COMPUTER FAILURE, OR MALFUNCTION, OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-6. The names "Walt Disney Imagineering" or "Disney" may not be used to
-endorse or promote this Software or any products derived from this
-Software and may not be used in any advertising, publicity or
-promotion or other disclosures, or to express or imply any endorsement
-of anyone's products or services, or in any manner or for any purpose
-whatsoever without specific prior written permission from Licensor.
-
-7. Licensor may publish new versions (including revisions) of the
-License from time to time.  Each new version of the License will be
-given a distinguishing version number and will be available at
-http://www.panda3d.org/license.txt .
-
-8. The License and the rights to use the Software granted hereunder
-will terminate automatically if You fail to comply with the License or
-the terms herein and fail to cure such breach within 30 days of
-becoming aware of the breach.  All sublicenses to the Software which
-are properly granted shall survive any termination of the License.
-Provisions which, by their nature, must remain in effect beyond the
-termination of the License shall survive.
-
-9. These terms shall be governed by California law, excluding its
-conflict-of-law provisions.
-
-Copyright (c) 2000, Disney Enterprises, Inc.  All Rights Reserved.
-
-
+IMPORTANT:
+READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+ALL USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS:
+
+
+PANDA 3D SOFTWARE LICENSE AND DOWNLOAD TERMS
+
+1. The accompanying Panda 3D Software and associated documentation
+files (the "Software") is licensed to you, the recipient of the
+Software ("You") by Walt Disney Imagineering (the "Licensor") subject
+these terms and to the terms of the Panda 3D Public License Version
+1.0 (the "License") and You may not use this Software except in
+compliance with these terms and the terms of the License.  See the
+License for the specific language governing rights and limitations
+under the License.  You may obtain a copy of the License at
+http://www.panda3d.org/license.txt .  ANY DOWNLOADING, INSTALLING,
+USE, REPRODUCTION OR DISTRIBUTION OF THE SOFTWARE CONSTITUTES THE
+RECIPIENT'S ACCEPTANCE OF THESE TERMS AND THE LICENSE.  IF YOU DO NOT
+AGREE TO THIS LICENSE, DO NOT DOWNLOAD, INSTALL, COPY OR USE THE
+SOFTWARE.
+
+2. Licensor hereby grants to any person obtaining a copy of the
+Software a nonexclusive license to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, on an "AS
+IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+implied, subject to these terms and the License.
+
+3. All copies made of the Software source code must retain the
+following copyright notice and these terms and disclaimers in a
+conspicuous location in the Software.  Copies made of the Software in
+binary form or redistribution of this Software in binary form must
+reproduce the following copyright notice and these terms and
+disclaimers in a conspicuous location in the documentation and/or
+other materials provided with the distribution of the Software.
+
+PANDA 3D SOFTWARE
+Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+
+4. Any modifications which You create or which You contribute to the
+Software are governed by these terms and the License.  The source code
+version of the Software may be distributed only under these terms and
+the License or a future version of the License released by Licensor,
+and You must include a copy of these terms with every copy of the
+source code or Software that You distribute.  You may not offer or
+impose any terms on any source code version that alters or restricts
+the applicable version of these terms or the License.  In addition,
+You must identify Yourself as the originator of the modifications or
+contributions You made to the Software, if any, in a manner that
+reasonably allows subsequent recipients to identify You as the
+originator of the modifications or contributions.  Further You must
+cause the Software to contain a file documenting the changes You made
+to create the modifications and the date of any change.  You must
+include a prominent statement describing the modifications made to the
+Software.  An electronic copy of the source code for all modifications
+made to the Software are to be forwarded to Licensor at
[email protected] within 90 days of the date of the
+modifications.
+
+5. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL LICENSOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF GOODWILL; LOSS OF USE, DATA, OR PROFITS; WORK
+STOPPAGE, COMPUTER FAILURE, OR MALFUNCTION, OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+6. The names "Walt Disney Imagineering" or "Disney" may not be used to
+endorse or promote this Software or any products derived from this
+Software and may not be used in any advertising, publicity or
+promotion or other disclosures, or to express or imply any endorsement
+of anyone's products or services, or in any manner or for any purpose
+whatsoever without specific prior written permission from Licensor.
+
+7. Licensor may publish new versions (including revisions) of the
+License from time to time.  Each new version of the License will be
+given a distinguishing version number and will be available at
+http://www.panda3d.org/license.txt .
+
+8. The License and the rights to use the Software granted hereunder
+will terminate automatically if You fail to comply with the License or
+the terms herein and fail to cure such breach within 30 days of
+becoming aware of the breach.  All sublicenses to the Software which
+are properly granted shall survive any termination of the License.
+Provisions which, by their nature, must remain in effect beyond the
+termination of the License shall survive.
+
+9. These terms shall be governed by California law, excluding its
+conflict-of-law provisions.
+
+Copyright (c) 2000, Disney Enterprises, Inc.  All Rights Reserved.
+
+

+ 32 - 0
doc/doc/README

@@ -0,0 +1,32 @@
+Panda3D is an open source 3D Engine originally developed, and still
+actively maintained, by the Walt Disney VR Studio.  Additional
+development and support for the open source community is provided by
+the Entertainment Technology Center of Carnegie-Mellon University.
+
+At the present, we are providing two completely unrelated systems for
+building Panda.  The original build system, ppremake, is still in
+active use by the VR Studio, but will probably eventually be phased
+out in favor of the new build system, makepanda.
+
+The ppremake system is a makefile generator, and allows you to
+configure your build environment to a high degree of customization.
+It is a fairly complex build system, and it requires some comfort with
+using the command-line make utilities.
+
+The makepanda system is a Python script that directly invokes the
+compiler to build the Panda sources.  Its emphasis is on providing a
+hands-off, simple approach to building Panda.
+
+Both systems may require you to first install a number of third-party
+tools if you would like to make them available for Panda, such as
+FreeType or OpenSSL.  You may also download a zip file that contains
+precompiled versions of these third-party libraries from the Panda
+website, which is especially useful when used in conjunction with the
+makepanda system.
+
+If you are interested in compiling Panda for yourself, you are welcome
+to use either build system.  Please refer to the documents INSTALL-PP
+or INSTALL-MK, in this directory, for build instructions for ppremake
+and makepanda, respectively.  You may also be interested in
+downloading the prebuilt Panda3D binaries from the Panda website at
+http://panda3d.etc.cmu.edu/ .

+ 0 - 0
doc/ReleaseNotes → doc/doc/ReleaseNotes


+ 5877 - 0
doc/makepanda/makepanda.py

@@ -0,0 +1,5877 @@
+#!/usr/bin/python
+########################################################################
+#
+# Caution: there are two separate, independent build systems:
+# 'makepanda', and 'ppremake'.  Use one or the other, do not attempt
+# to use both.  This file is part of the 'makepanda' system.
+#
+# To build panda using this script, type 'makepanda.py' on unix
+# or 'makepanda.bat' on windows, and examine the help-text.
+# Then run the script again with the appropriate options to compile
+# panda3d.
+#
+########################################################################
+
+import sys,os,time,stat,string,re,getopt,cPickle;
+
+########################################################################
+##
+## Utility Routines
+##
+## filedate(f) - returns the last modified date of the specified file.
+## youngest(f1,f2...) - returns date of most recently modified file.
+## older(f,f1,f2...) - return true if f is older than all the others.
+## xpaths(pre,pathlist,suf) - appends prefix and suffix to every path.
+##
+########################################################################
+
+global FileDateCache
+FileDateCache = {}
+
+def filedate(path) :
+  global FileDateCache
+  if (FileDateCache.has_key(path)):
+    return(FileDateCache[path]);
+  try : date = os.path.getmtime(path)
+  except : date = 0;
+  FileDateCache[path] = date;
+  return(date);
+
+def updatefiledate(path) :
+  global FileDateCache
+  try : date = os.path.getmtime(path)
+  except : date = 0;
+  FileDateCache[path] = date;
+
+def youngest(files):
+  if (type(files) == str):
+    source = filedate(files);
+    if (source==0): sys.exit("Error: source file not readable: "+files);
+    return(source);
+  result = 0;
+  for sfile in files:
+    source = youngest(sfile);
+    if (source > result): result = source;
+  return(result);
+
+def older(file,others):
+  return (filedate(file)<youngest(others));
+
+def xpaths(prefix,base,suffix):
+  if (type(base) == str):
+    return(prefix + base + suffix);
+  result = [];
+  for x in base:
+    result.append(xpaths(prefix,x,suffix));
+  return(result);
+
+if (sys.platform == "win32"):
+
+  import _winreg;
+  def GetRegistryKey(path, subkey):
+    k1=0
+    key=0
+    try:
+      key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, path, 0, _winreg.KEY_READ);
+      k1, k2 = _winreg.QueryValueEx(key, subkey)
+    except: pass;
+    if (key!=0): _winreg.CloseKey(key);
+    return k1;
+
+  def backslashify(exp):
+    if (type(exp) == str):
+      return(string.replace(exp,"/","\\"))
+    result = []
+    for x in exp: result.append(backslashify(x))
+    return(result)
+
+else:
+
+  def backslashify(exp):
+    return(exp)
+
+def oscmd(cmd):
+  print cmd;
+  sys.stdout.flush();
+  if (os.system(cmd)): sys.exit("Failed");
+
+def buildingwhat(opts):
+  building = 0
+  for x in opts:
+    if (x[:9]=="BUILDING_"): building = x[9:]
+  return(building)
+
+def ConditionalWriteFile(dest,desiredcontents):
+  wdest = backslashify(dest)
+  try:
+    rfile = open(wdest, 'rb');
+    contents = rfile.read(-1);
+    rfile.close();
+  except: contents=0;
+  if (contents != desiredcontents):
+    print "Regenerating file: "+dest
+    sys.stdout.flush()
+    try:
+      wfile = open(wdest, 'wb');
+      wfile.write(desiredcontents);
+      wfile.close();
+    except: sys.exit("Cannot write to "+wdest);
+
+########################################################################
+##
+## Default options:
+##
+## You might be tempted to change the defaults by editing them
+## here.  Don't do it.  Instead, create a script that compiles
+## panda with your preferred options.
+## 
+########################################################################
+
+if (sys.platform == "win32"): COMPILERS=["MSVC7"]
+if (sys.platform == "linux2"): COMPILERS=["LINUXA"]
+COMPILER=COMPILERS[0]
+OPTIMIZE="3"
+INSTALLER=1
+COMPLETE=0
+OMIT=["MILES"]
+THIRDPARTY=""
+VERSION1=1
+VERSION2=0
+VERSION3=0
+COMPRESSOR="zlib"
+
+PACKAGES=["ZLIB","PNG","JPEG","TIFF","VRPN","FMOD","NVIDIACG","HELIX","NSPR",
+          "OPENSSL","FREETYPE","FFTW","MILES","MAYA5","MAYA6","MAX5","MAX6","MAX7"]
+WARNINGS=[]
+
+if (sys.platform != "win32"):
+  OMIT.append("HELIX")
+
+########################################################################
+##
+## Command-line parser.
+##
+## You can type "makepanda --help" to see all the options.
+##
+########################################################################
+
+def usage(problem):
+  if (problem):
+    print ""
+    print problem
+  print ""
+  print "By default, makepanda generates a 'built' subdirectory and"
+  print "an executable panda installer.  Command-line arguments are:"
+  print ""
+  print "  --compiler X      (currently, compiler can only be MSVC7,LINUXA)"
+  print "  --optimize X      (optimization level can be 1,2,3,4)"
+  print "  --thirdparty X    (directory containing third-party software)"
+  print "  --complete        (copy models, samples, direct into the build)"
+  print "  --no-installer    (don't bother building the executable installer)"
+  print "  --v1 X            (set the major version number)"
+  print "  --v2 X            (set the minor version number)"
+  print "  --v3 X            (set the sequence version number)"
+  print "  --lzma            (use lzma compression when building installer)"
+  print ""
+  for pkg in PACKAGES: print "  --no-"+pkg.lower()+"             "[len(pkg.lower()):]+"(disable the use of "+pkg+")"
+  print ""
+  print "  --no-nothing      (don't use any of the third-party packages)"
+  print "  --default         (use default options for everything not specified)"
+  print ""
+  print "The simplest way to compile panda is to just type:"
+  print ""
+  print "  makepanda --default"
+  print ""
+  sys.exit(1)
+
+def parseopts(args):
+  global COMPILER,OPTIMIZE,OMIT,THIRDPARTY,INSTALLER,COPYEXTRAS,VERSION1,VERSION2,VERSION3,COMPRESSOR
+  longopts = ["compiler=","thirdparty=","optimize=","no-nothing","no-installer","complete","default","v1=","v2=","v3=","lzma"]
+  anything = 0
+  for pkg in PACKAGES: longopts.append("no-"+pkg.lower())
+  try:
+    opts, extras = getopt.getopt(args, "", longopts)
+    for option,value in opts:
+      if (option=="--compiler"): COMPILER=value
+      if (option=="--thirdparty"): THIRDPARTY=value
+      if (option=="--optimize"): OPTIMIZE=value
+      if (option=="--no-installer"): INSTALLER=0
+      if (option=="--complete"): COMPLETE=1
+      if (option=="--no-nothing"): OMIT=PACKAGES[:]
+      if (option=="--v1"): VERSION1=int(value)
+      if (option=="--v2"): VERSION2=int(value)
+      if (option=="--v3"): VERSION3=int(value)
+      if (option=="--lzma"): COMPRESSOR="lzma"
+      for pkg in PACKAGES:
+        if (option=="--no-"+pkg.lower()): OMIT.append(pkg)
+      anything = 1
+  except: usage(0)
+  if (anything==0): usage(0)
+  if   (OPTIMIZE=="1"): OPTIMIZE=1
+  elif (OPTIMIZE=="2"): OPTIMIZE=2
+  elif (OPTIMIZE=="3"): OPTIMIZE=3
+  elif (OPTIMIZE=="4"): OPTIMIZE=4
+  else: usage("Invalid setting for OPTIMIZE");
+  if (COMPILERS.count(COMPILER)==0): usage("Invalid setting for COMPILER: "+COMPILER);
+
+parseopts(sys.argv[1:])
+
+########################################################################
+#
+# Locate the root of the panda tree, sanity check for presence of files.
+#
+########################################################################
+
+PANDASOURCE=os.path.dirname(os.path.abspath(sys.argv[0]))
+
+if ((os.path.exists(os.path.join(PANDASOURCE,"makepanda.py"))==0) or
+    (os.path.exists(os.path.join(PANDASOURCE,"makepanda.sln"))==0) or
+    (os.path.exists(os.path.join(PANDASOURCE,"dtool","src","dtoolbase","dtoolbase.h"))==0) or
+    (os.path.exists(os.path.join(PANDASOURCE,"panda","src","pandabase","pandabase.h"))==0)):
+  sys.exit("I am unable to locate the root of the panda source tree.")
+  os.chdir(PANDASOURCE)
+
+########################################################################
+##
+## Locate the Directory containing the precompiled third-party software,
+## if it wasn't specified on the command-line.
+##
+########################################################################
+
+if (THIRDPARTY == ""):
+  if (COMPILER == "MSVC7"): THIRDPARTY="thirdparty\\win-libs-vc7\\"
+  if (COMPILER == "LINUXA"): THIRDPARTY="thirdparty/linux-libs-a/"
+STDTHIRDPARTY = THIRDPARTY.replace("\\","/")
+
+########################################################################
+##
+## Locate the DirectX SDK
+##
+########################################################################
+
+if (sys.platform == "win32"):
+  dxdir = GetRegistryKey("SOFTWARE\\Microsoft\\DirectX SDK", "DX9SDK Samples Path")
+  if (dxdir != 0): DirectXSDK = os.path.dirname(dxdir)
+  else:
+    dxdir = GetRegistryKey("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment","DXSDK_DIR")
+    if (dxdir != 0): DirectXSDK=dxdir
+    else:
+      sys.exit("The registry does not appear to contain a pointer to the DirectX 9.0 SDK.");
+
+########################################################################
+##
+## Locate the Python SDK (unix only)
+##
+########################################################################
+
+if (sys.platform != "win32"):
+  if   (os.path.isdir("/usr/include/python2.2")): PythonSDK = "/usr/include/python2.2"
+  elif (os.path.isdir("/usr/include/python2.3")): PythonSDK = "/usr/include/python2.3"
+  elif (os.path.isdir("/usr/include/python2.4")): PythonSDK = "/usr/include/python2.4"
+  elif (os.path.isdir("/usr/include/python2.5")): PythonSDK = "/usr/include/python2.5"
+  else: sys.exit("Cannot find the python SDK")
+
+########################################################################
+##
+## Locate the Maya 5.0 SDK
+##
+########################################################################
+
+if (OMIT.count("MAYA5")==0):
+  if (sys.platform == "win32"):
+    Maya5SDK = GetRegistryKey("SOFTWARE\\Alias|Wavefront\\Maya\\5.0\\Setup\\InstallPath", "MAYA_INSTALL_LOCATION")
+    if (Maya5SDK == 0):
+      WARNINGS.append("The registry does not appear to contain a pointer to the Maya 5 SDK.")
+      WARNINGS.append("I have automatically added this command-line option: --no-maya5")
+      OMIT.append("MAYA5")
+  else:
+    WARNINGS.append("MAYA5 not yet supported under linux")
+    WARNINGS.append("I have automatically added this command-line option: --no-maya5")
+    OMIT.append("MAYA5")
+
+########################################################################
+##
+## Locate the Maya 6.0 SDK
+##
+########################################################################
+
+if (OMIT.count("MAYA6")==0):
+  if (sys.platform == "win32"):
+    Maya6SDK = GetRegistryKey("SOFTWARE\\Alias|Wavefront\\Maya\\6.0\\Setup\\InstallPath", "MAYA_INSTALL_LOCATION")
+    if (Maya6SDK == 0):
+      WARNINGS.append("The registry does not appear to contain a pointer to the Maya 6 SDK.")
+      WARNINGS.append("I have automatically added this command-line option: --no-maya6")
+      OMIT.append("MAYA6")
+  else:
+    WARNINGS.append("MAYA6 not yet supported under linux")
+    WARNINGS.append("I have automatically added this command-line option: --no-maya6")
+    OMIT.append("MAYA6")
+
+########################################################################
+##
+## Locate the 3D Studio Max and Character Studio SDKs
+##
+########################################################################
+
+MAXVERSIONS = [("MAX5", "SOFTWARE\\Autodesk\\3DSMAX\\5.0\\MAX-1:409", "uninstallpath", "Cstudio\\Sdk"),
+               ("MAX6", "SOFTWARE\\Autodesk\\3DSMAX\\6.0",            "installdir",    "maxsdk\\cssdk\\include"),
+               ("MAX7", "SOFTWARE\\Autodesk\\3DSMAX\\7.0",            "Installdir",    "maxsdk\\include\\CS")]
+MAXSDK = {}
+MAXSDKCS = {}
+for version,key1,key2,subdir in MAXVERSIONS:
+  if (OMIT.count(version)==0):
+    if (sys.platform == "win32"):
+      top = GetRegistryKey(key1,key2)
+      if (top == 0):
+        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())
+        OMIT.append(version)
+      else:
+        if (os.path.isdir(top + "\\" + subdir)==0):
+          WARNINGS.append("Your copy of "+version+" does not include the character studio SDK")
+          WARNINGS.append("I have automatically added this command-line option: --no-"+version.lower())
+          OMIT.append(version)
+        else:
+          MAXSDK[version] = top + "maxsdk\\"
+          MAXSDKCS[version] = top + subdir
+    else:
+      WARNINGS.append(version+" not yet supported under linux")
+      WARNINGS.append("I have automatically added this command-line option: --no-"+version.lower())
+      OMIT.append(version)
+
+########################################################################
+##
+## Locate Visual Studio 7.0 or 7.1
+##
+## The visual studio compiler doesn't work unless you set up a
+## couple of environment variables to point at the compiler.
+##
+########################################################################
+
+if (COMPILER == "MSVC7"):
+  vcdir = GetRegistryKey("SOFTWARE\\Microsoft\\VisualStudio\\7.1", "InstallDir");
+  if ((vcdir == 0) or (vcdir[-13:] != "\\Common7\\IDE\\")):
+    vcdir = GetRegistryKey("SOFTWARE\\Microsoft\\VisualStudio\\7.0", "InstallDir");
+    if ((vcdir == 0) or (vcdir[-13:] != "\\Common7\\IDE\\")):
+      sys.exit("The registry does not appear to contain a pointer to the Visual Studio 7 install directory");
+  vcdir = vcdir[:-12]
+  old_env_path    = ""
+  old_env_include = ""
+  old_env_lib     = ""
+  if (os.environ.has_key("PATH")):    old_env_path    = os.environ["PATH"]
+  if (os.environ.has_key("INCLUDE")): old_env_include = os.environ["INCLUDE"]
+  if (os.environ.has_key("LIB")):     old_env_lib     = os.environ["LIB"]
+  os.environ["PATH"] = vcdir + "vc7\\bin;" + vcdir + "Common7\\IDE;" + vcdir + "Common7\\Tools;" + vcdir + "Common7\\Tools\\bin\\prerelease;" + vcdir + "Common7\\Tools\\bin;" + old_env_path
+  os.environ["INCLUDE"] = vcdir + "vc7\\ATLMFC\\INCLUDE;" + vcdir + "vc7\\include;" + vcdir + "vc7\\PlatformSDK\\include\\prerelease;" + vcdir + "vc7\\PlatformSDK\\include;" + old_env_include
+  os.environ["LIB"] = vcdir + "vc7\\ATLMFC\\LIB;" + vcdir + "vc7\\LIB;" + vcdir + "vc7\\PlatformSDK\\lib\\prerelease;" + vcdir + "vc7\\PlatformSDK\\lib;" + old_env_lib
+  sys.stdout.flush()
+
+##########################################################################################
+#
+# Verify that LD_LIBRARY_PATH contains the built/lib directory.
+#
+# If not, add it on a temporary basis, and issue a warning.
+#
+##########################################################################################
+
+if (sys.platform != "win32"):
+  BUILTLIB = os.path.abspath("built/lib")
+  try:
+    LDPATH = []
+    f = file("/etc/ld.so.conf","r")
+    for line in f: LDPATH.append(line.rstrip())
+    f.close()
+  except: LDPATH = []
+  if (os.environ.has_key("LD_LIBRARY_PATH")):
+    LDPATH = LDPATH + os.environ["LD_LIBRARY_PATH"].split(":")
+  if (LDPATH.count(BUILTLIB)==0):
+    WARNINGS.append("Caution: the built/lib directory is not in LD_LIBRARY_PATH")
+    WARNINGS.append("or /etc/ld.so.conf.  You must add it before using panda.")
+    if (os.environ.has_key("LD_LIBRARY_PATH")):
+      os.environ["LD_LIBRARY_PATH"] = BUILTLIB + ":" + os.environ["LD_LIBRARY_PATH"]
+    else:
+      os.environ["LD_LIBRARY_PATH"] = BUILTLIB
+
+########################################################################
+##
+## Give a Status Report on Command-Line Options
+##
+########################################################################
+
+def printStatus(header,warnings):
+  print ""
+  print "-------------------------------------------------------------------"
+  print header
+  tkeep = ""
+  tomit = ""
+  for x in PACKAGES:
+    if (OMIT.count(x)==0): tkeep = tkeep + x + " "
+    else                 : tomit = tomit + x + " "
+  print "Makepanda: Compiler:",COMPILER
+  print "Makepanda: Optimize:",OPTIMIZE
+  print "Makepanda: Keep Pkg:",tkeep
+  print "Makepanda: Omit Pkg:",tomit
+  print "Makepanda: Thirdparty dir:",STDTHIRDPARTY
+  print "Makepanda: Build installer:",INSTALLER,COMPRESSOR
+  print "Makepanda: Version ID: "+str(VERSION1)+"."+str(VERSION2)+"."+str(VERSION3)
+  for x in warnings: print "Makepanda: "+x
+  print "-------------------------------------------------------------------"
+  print ""
+  sys.stdout.flush()
+
+printStatus("Makepanda Initial Status Report", WARNINGS)
+
+########################################################################
+##
+## PkgSelected(package-list,package)
+##
+## This function returns true if the package-list contains the
+## package, AND the OMIT list does not contain the package.
+##
+########################################################################
+
+def PkgSelected(pkglist, pkg):
+  if (pkglist.count(pkg)==0): return(0);
+  if (OMIT.count(pkg)): return(0);
+  return(1);
+
+########################################################################
+##
+## These two globals accumulate a global list of everything compiled.
+##
+########################################################################
+
+ALLIN=[]
+ALLTARGETS=[]
+
+########################################################################
+##
+## The CXX include-cache.
+##
+## Dictionary: for each CXX source file, a list of all the
+## include-directives inside that file.
+##
+## Makepanda analyzes include-directives to determine the dependencies
+## of C source files.  This requires us to read the C source files,
+## a time-consuming process.  This means that doing a 'makepanda'
+## takes quite a bit of time, even if there's nothing to compile.
+##
+## To accelerate this process, we store the list of include-directives
+## in each source file in the "CXX include-cache".  This cache is
+## preserved (using the 'cPickle' module) from execution to execution
+## of makepanda.  The use of file dates in the cache makes it very
+## unlikely for the cache to get out-of-sync with the source tree.
+##
+########################################################################
+
+global CxxIncludeCache
+CxxIncludeCache = {}
+
+try: icache = open("makepanda-icache",'rb')
+except: icache = 0
+if (icache!=0):
+  CxxIncludeCache = cPickle.load(icache)
+  icache.close()
+
+########################################################################
+##
+## CxxGetIncludes
+##
+## return a list of the include-directives in a given source file
+##
+########################################################################
+
+global CxxIncludeRegex
+CxxIncludeRegex = re.compile('^[ \t]*[#][ \t]*include[ \t]+"([^"]+)"[ \t\r\n]*$')
+
+def CxxGetIncludes(path):
+  date = filedate(path)
+  if (CxxIncludeCache.has_key(path)):
+    cached = CxxIncludeCache[path]
+    if (cached[0]==date): return cached[1]
+  wpath = backslashify(path)
+  try: sfile = open(wpath, 'rb')
+  except: sys.exit("Cannot open source file "+wpath+" for reading.");
+  include = []
+  for line in sfile:
+    match = CxxIncludeRegex.match(line,0);
+    if (match):
+      incname = match.group(1)
+      include.append(incname)
+  sfile.close();
+  CxxIncludeCache[path] = [date, include]
+  return include
+
+########################################################################
+##
+## CxxFindSource
+##
+## given a source file name and a directory list, searches the
+## directory list for the given source file.  Returns the full
+## pathname of the located file.
+##
+########################################################################
+
+def CxxFindSource(name, ipath):
+  for dir in ipath:
+    if (dir == "."): full = name;
+    else: full = dir + "/" + name;
+    if (filedate(backslashify(full)) > 0): return(full);
+  return(0);
+
+########################################################################
+##
+## CxxFindHeader
+##
+## given a source file name and an include directive in that source
+## file, locates the relevant header file.
+##
+########################################################################
+
+def CxxFindHeader(srcfile, incfile, ipath):
+  if (incfile[:1]=="."):
+    last = srcfile.rfind("/")
+    if (last < 0): sys.exit("CxxFindHeader cannot handle this case #1")
+    srcdir = srcfile[:last+1]
+    while (incfile[:1]=="."):
+      if (incfile[:2]=="./"):
+        incfile = incfile[2:]
+      elif (incfile[:3]=="../"):
+	incfile = incfile[3:]
+	last = srcdir[:-1].rfind("/")
+	if (last < 0): sys.exit("CxxFindHeader cannot handle this case #2")
+	srcdir = srcdir[:last+1]
+      else: sys.exit("CxxFindHeader cannot handle this case #3")
+    full = srcdir + incfile;
+    if (filedate(backslashify(full)) > 0): return(full);
+    return(0);
+  else: return CxxFindSource(incfile, ipath)
+
+########################################################################
+##
+## CxxCalcDependencies(srcfile, ipath, ignore)
+##
+## Calculate the dependencies of a source file given a
+## particular include-path.  Any file in the list of files to
+## ignore is not considered.
+##
+########################################################################
+
+global CxxIgnoreHeader
+global CxxDependencyCache
+CxxIgnoreHeader = {}
+CxxDependencyCache = {}
+
+def CxxCalcDependencies(srcfile, ipath, ignore):
+  if (CxxDependencyCache.has_key(srcfile)):
+    return CxxDependencyCache[srcfile]
+  if (ignore.count(srcfile)): return([]);
+  dep = {}
+  dep[srcfile] = 1
+  includes = CxxGetIncludes(srcfile)
+  for include in includes:
+    if (CxxIgnoreHeader.has_key(include)==0):
+      header = CxxFindHeader(srcfile, include, ipath)
+      if (header==0):
+	print "CAUTION: header file "+include+" cannot be found."
+      else:
+        if (ignore.count(header)==0):
+          hdeps = CxxCalcDependencies(header, ipath, [srcfile]+ignore)
+          for x in hdeps: dep[x] = 1
+  result = dep.keys();
+  CxxDependencyCache[srcfile] = result
+  return result
+
+def CxxCalcDependenciesAll(srcfiles, ipath):
+  dep = {}
+  for srcfile in srcfiles:
+    for x in CxxCalcDependencies(srcfile, ipath, []):
+      dep[x] = 1
+  return dep.keys()
+
+########################################################################
+##
+## MakeDirectory
+##
+## Make a directory in the build tree
+##
+########################################################################
+
+def MakeDirectory(path):
+  wpath = backslashify(path)
+  if (os.path.isdir(wpath)): return(0);
+  os.mkdir(wpath)
+
+########################################################################
+##
+## CopyFile
+##
+## Copy a file into the build tree.
+##
+########################################################################
+
+def CopyFile(dstfile,srcfile):
+  if (dstfile[-1]=='/'):
+    dstdir = dstfile
+    fnl = srcfile.rfind("/")
+    if (fnl < 0): fn = srcfile
+    else: fn = srcfile[fnl+1:]
+    dstfile = dstdir + fn;
+  wdstfile = backslashify(dstfile)
+  wsrcfile = backslashify(srcfile)
+  if (older(wdstfile,wsrcfile)):
+    print "Copying "+srcfile+" -> "+dstfile+"..."
+    try:
+      srchandle = open(wsrcfile, "rb")
+      dsthandle = open(wdstfile, "wb")
+      data = " "
+      while (len(data) > 0):
+        data = srchandle.read(100000);
+  	dsthandle.write(data)
+      srchandle.close()
+      dsthandle.close()
+      updatefiledate(wdstfile);
+    except: sys.exit("Cannot copy data from "+wsrcfile+" to "+wdstfile)
+  ALLTARGETS.append(dstfile)
+
+########################################################################
+##
+## CopyAllFiles
+##
+## Copy the contents of an entire directory into the build tree.
+##
+########################################################################
+
+def CopyAllFiles(dstdir,srcdir):
+  wdstdir = backslashify(dstdir)
+  wsrcdir = backslashify(srcdir)
+  files = os.listdir(wsrcdir)
+  for x in files:
+    if (os.path.isfile(srcdir+x)):
+      CopyFile(dstdir+x, srcdir+x)
+
+########################################################################
+##
+## CopyTree
+##
+## Copy a directory into the build tree.
+##
+########################################################################
+
+def CopyTree(dstdir,srcdir):
+  wdstdir = backslashify(dstdir)
+  wsrcdir = backslashify(srcdir)
+  if (os.path.isdir(wdstdir)): return(0);
+  if (COMPILER=="MSVC7"): cmd = "xcopy /I/Y/E/Q "+wsrcdir+" "+wdstdir
+  if (COMPILER=="LINUXA"): cmd = "cp --recursive --force "+wsrcdir+" "+wdstdir
+  oscmd(cmd)
+  updatefiledate(wdstdir)
+
+########################################################################
+##
+## CompileBison
+##
+## Generate a CXX file from a source YXX file.
+##
+########################################################################
+
+def CompileBison(pre,dstc,dsth,src):
+  last = src.rfind("/")
+  fn = src[last+1:]
+  wdstc = backslashify("built/tmp/"    +dstc)
+  wdsth = backslashify("built/include/"+dsth)
+  wsrc = backslashify(src)
+  if (older(wdstc,wsrc) | older(wdsth,wsrc)):
+    CopyFile("built/tmp/", src)
+    if (COMPILER=="MSVC7"):
+      CopyFile("built/tmp/", "thirdparty/win-util/bison.simple")
+      oscmd("cd built\\tmp & ..\\..\\thirdparty\\win-util\\bison.exe -y -d -p " + pre + " " + fn)
+      oscmd("move /y built\\tmp\\y_tab.c " + wdstc + " & move /y built\\tmp\\y_tab.h " + wdsth)
+    if (COMPILER=="LINUXA"):
+      oscmd("cd built/tmp ; bison -y -d -p "+pre+" "+fn)
+      oscmd("mv built/tmp/y.tab.c "+wdstc)
+      oscmd("mv built/tmp/y.tab.h "+wdsth)
+    updatefiledate(wdstc);
+    updatefiledate(wdsth);
+
+########################################################################
+##
+## CompileFlex
+##
+## Generate a CXX file from a source LXX file.
+##
+########################################################################
+
+def CompileFlex(pre,dst,src,dashi):
+  last = src.rfind("/")
+  fn = src[last+1:]
+  wdst = backslashify("built/tmp/"+dst)
+  wsrc = backslashify(src)
+  wfn = backslashify(fn)
+  if (older(wdst,wsrc)):
+    CopyFile("built/tmp/", src)
+    if (COMPILER=="MSVC7"):
+      if (dashi): oscmd("cd built\\tmp & ..\\..\\thirdparty\\win-util\\flex.exe -i -P" + pre + " -olex.yy.c " + wfn)
+      else      : oscmd("cd built\\tmp & ..\\..\\thirdparty\\win-util\\flex.exe    -P" + pre + " -olex.yy.c " + wfn)
+      oscmd('cd built\\tmp & ..\\..\\thirdparty\\win-util\\sed -e "s/#include <unistd.h>//" < lex.yy.c > ..\\..\\'+wdst)
+    if (COMPILER=="LINUXA"):
+      if (dashi): oscmd("cd built/tmp ; flex -i -P" + pre + " -olex.yy.c " + wfn)
+      else      : oscmd("cd built/tmp ; flex    -P" + pre + " -olex.yy.c " + wfn)
+      oscmd('cp built/tmp/lex.yy.c '+wdst)
+    updatefiledate(wdst)
+
+########################################################################
+##
+## CompileC
+##
+## Generate an OBJ file from a source CXX file.
+##
+########################################################################
+
+def CompileC(obj=0,src=0,ipath=[],opts=[]):
+  if ((obj==0)|(src==0)): sys.exit("syntax error in CompileC directive");
+  ipath = ["built/tmp"] + ipath + ["built/include"]
+  fullsrc = CxxFindSource(src, ipath)
+  if (fullsrc == 0): sys.exit("Cannot find source file "+src)
+  dep = CxxCalcDependencies(fullsrc, ipath, [])
+  
+  if (COMPILER=="MSVC7"):
+    wobj = backslashify("built/tmp/"+obj);
+    if (older(wobj, backslashify(dep))):
+      cmd = 'cl.exe /Fo' + wobj + ' /nologo /c';
+      cmd = cmd + ' /I"built\\python\\include"'
+      if (opts.count("DXSDK")): cmd = cmd + ' /I"' + DirectXSDK + '\\include"'
+      if (opts.count("MAYA5")): cmd = cmd + ' /I"' + Maya5SDK + 'include"'
+      if (opts.count("MAYA6")): cmd = cmd + ' /I"' + Maya6SDK + 'include"'
+      for max in ["MAX5","MAX6","MAX7"]:
+        if (PkgSelected(opts,max)):
+          cmd = cmd + ' /I"' + MAXSDK[max] + 'include" /I"' + MAXSDKCS[max] + '" /D' + max
+      for pkg in PACKAGES: 
+	if (pkg != "MAYA5") and (pkg != "MAYA6") and PkgSelected(opts,pkg):
+	  cmd = cmd + ' /I"' + THIRDPARTY + pkg.lower() + "\\include" + '"'
+      for x in backslashify(ipath): cmd = cmd + " /I " + x;
+      if (opts.count('NOFLOATWARN')): cmd = cmd + ' /wd4244 /wd4305'
+      if (opts.count("WITHINPANDA")): cmd = cmd + ' /DWITHIN_PANDA'
+      if (OPTIMIZE==1): cmd = cmd + " /D_DEBUG /Zc:forScope /MDd /Zi /RTCs /GS "
+      if (OPTIMIZE==2): cmd = cmd + " /D_DEBUG /Zc:forScope /MDd /Zi /RTCs /GS "
+      if (OPTIMIZE==3): cmd = cmd + " /Zc:forScope /MD /O2 /Ob2 /G6 /Zi /DFORCE_INLINING "
+      if (OPTIMIZE==4): cmd = cmd + " /Zc:forScope /MD /O2 /Ob2 /G6 /GL /Zi /DFORCE_INLINING /DNDEBUG "
+      cmd = cmd + " /Fd" + wobj[:-4] + ".pdb";
+      building = buildingwhat(opts)
+      if (building): cmd = cmd + " /DBUILDING_"+building
+      cmd = cmd + " /EHsc /Zm300 /DWIN32_VC /DWIN32 /W3 " + backslashify(fullsrc)
+      oscmd(cmd)
+      updatefiledate(wobj)
+    
+  if (COMPILER=="LINUXA"):
+    wobj = "built/tmp/" + obj[:-4] + ".o"
+    if (older(wobj, dep)):
+      if (src[-2:]==".c"): cmd = "gcc -c -o "+wobj
+      else:                cmd = "g++ -ftemplate-depth-30 -c -o "+wobj
+      cmd = cmd + ' -I"' + PythonSDK + '"'
+      if (PkgSelected(opts,"VRPN")):     cmd = cmd + ' -I"' + THIRDPARTY + 'vrpn/include"'
+      if (PkgSelected(opts,"FFTW")):     cmd = cmd + ' -I"' + THIRDPARTY + 'fftw/include"'
+      if (PkgSelected(opts,"FMOD")):     cmd = cmd + ' -I"' + THIRDPARTY + 'fmod/include"'
+      if (PkgSelected(opts,"NVIDIACG")): cmd = cmd + ' -I"' + THIRDPARTY + 'nvidiacg/include"'
+      if (PkgSelected(opts,"NSPR")):     cmd = cmd + ' -I"' + THIRDPARTY + 'nspr/include"'
+      if (PkgSelected(opts,"FREETYPE")): cmd = cmd + ' -I/usr/include/freetype2'
+      for x in ipath: cmd = cmd + ' -I"' + x + '"'
+      if (opts.count("WITHINPANDA")): cmd = cmd + ' -DWITHIN_PANDA'
+      if (OPTIMIZE==1): cmd = cmd + " -g"
+      if (OPTIMIZE==2): cmd = cmd + " -O1"
+      if (OPTIMIZE==3): cmd = cmd + " -O2"
+      if (OPTIMIZE==4): cmd = cmd + " -O2"
+      building = buildingwhat(opts)
+      if (building): cmd = cmd + " -DBUILDING_" + building
+      cmd = cmd + " " + fullsrc
+      oscmd(cmd)
+      updatefiledate(wobj)
+
+########################################################################
+##
+## CompileRES
+##
+## Generate an RES file from a source RC file.
+##
+########################################################################
+
+def CompileRES(obj=0,src=0,ipath=[],opts=[]):
+  if ((obj==0)|(src==0)): sys.exit("syntax error in CompileRES directive");
+  fullsrc = CxxFindSource(src, ipath)
+  if (fullsrc == 0): sys.exit("Cannot find source file "+src)
+  wobj = backslashify("built/tmp/"+obj)
+  wsrc = backslashify(fullsrc)
+  wdep = backslashify(CxxCalcDependencies(fullsrc, ipath, []))
+  wipath = backslashify(ipath)
+  
+  if (COMPILER=="MSVC7"):
+    if (older(wobj, wdep)):
+      cmd = 'rc.exe /d "NDEBUG" /l 0x409'
+      for x in wipath: cmd = cmd + " /I " + x;
+      cmd = cmd + ' /fo"' + wobj + '"'
+      cmd = cmd + ' "'+ wsrc + '"'
+      oscmd(cmd)
+      updatefiledate(wobj)
+      
+  if (COMPILER=="LINUXA"):
+    sys.exit("Can only compile RES files on Windows.")
+
+########################################################################
+##
+## Interrogate
+##
+## Generate an IN file and a CXX-stub file from CXX source files
+##
+########################################################################
+
+def Interrogate(ipath=0, opts=0, outd=0, outc=0, src=0, module=0, library=0, files=0):
+  if ((ipath==0)|(opts==0)|(outd==0)|(outc==0)|(src==0)|(module==0)|(library==0)|(files==0)):
+    sys.exit("syntax error in Interrogate directive");
+  ipath = ["built/tmp"] + ipath + ["built/include"]
+  wipath = backslashify(ipath)
+  woutd = backslashify("built/etc/"+outd)
+  woutc = backslashify("built/tmp/"+outc)
+  wsrc = backslashify(src)
+  wfiles = backslashify(files)
+  paths = xpaths(src+"/",files,"")
+  dep = CxxCalcDependenciesAll(paths, ipath)
+  wdep = backslashify(dep)
+  dotdots = ""
+  for i in range(0,src.count("/")+1): dotdots = dotdots + "../"
+  wdotdots = backslashify(dotdots)
+  ALLIN.append(outd)
+  building = 0;
+  for x in opts:
+    if (x[:9]=="BUILDING_"): building = x[9:]
+  if (older(woutc, wdep) | older(woutd, wdep)):
+    if (COMPILER=="MSVC7"):
+      cmd = "cd " + wsrc + " & " + wdotdots + "built\\bin\\interrogate.exe"
+      cmd = cmd + ' -DCPPPARSER -D__STDC__=1 -D__cplusplus -longlong __int64 -D_X86_ -DWIN32_VC -D_WIN32'
+      cmd = cmd + ' -D"_declspec(param)=" -D_near -D_far -D__near -D__far -D__stdcall'
+      if (OPTIMIZE==1): cmd = cmd + ' '
+      if (OPTIMIZE==2): cmd = cmd + ' '
+      if (OPTIMIZE==3): cmd = cmd + ' -DFORCE_INLINING'
+      if (OPTIMIZE==4): cmd = cmd + ' -DFORCE_INLINING'
+      cmd = cmd + ' -S"' + wdotdots + 'built\\include\\parser-inc"'
+      cmd = cmd + ' -I"' + wdotdots + 'built\\python\\include"'
+    if (COMPILER=="LINUXA"):
+      cmd = "cd " + wsrc + " ; " + wdotdots + "built/bin/interrogate"
+      cmd = cmd + ' -DCPPPARSER -D__STDC__=1 -D__cplusplus -D__i386__ -D__const=const'
+      if (OPTIMIZE==1): cmd = cmd + ' '
+      if (OPTIMIZE==2): cmd = cmd + ' '
+      if (OPTIMIZE==3): cmd = cmd + ' '
+      if (OPTIMIZE==4): cmd = cmd + ' '
+      cmd = cmd + ' -S"' + wdotdots + 'built/include/parser-inc" -S"/usr/include"'
+      cmd = cmd + ' -I"' + wdotdots + 'built/python/include"'
+    cmd = cmd + " -oc "+wdotdots+woutc+" -od "+wdotdots+woutd
+    cmd = cmd + ' -fnames -string -refcount -assert -python'
+    for x in wipath: cmd = cmd + ' -I"' + wdotdots + x + '"'
+    if (building): cmd = cmd + " -DBUILDING_"+building
+    if (opts.count("WITHINPANDA")): cmd = cmd + " -DWITHIN_PANDA"
+    for pkg in PACKAGES: 
+      if (PkgSelected(opts,pkg)):
+        cmd = cmd + ' -I"' + wdotdots + backslashify(STDTHIRDPARTY + pkg.lower() + "/include") + '"'
+    cmd = cmd + ' -module "' + module + '" -library "' + library + '"'
+    if ((COMPILER=="MSVC7") and opts.count("DXSDK")): cmd = cmd + ' -I"' + DirectXSDK + '\\include"'
+    if ((COMPILER=="MSVC7") and opts.count("MAYA5")): cmd = cmd + ' -I"' + Maya5SDK + 'include"'
+    if ((COMPILER=="MSVC7") and opts.count("MAYA6")): cmd = cmd + ' -I"' + Maya6SDK + 'include"'
+    for x in wfiles: cmd = cmd + ' ' + x
+    oscmd(cmd)
+    updatefiledate(woutd)
+    updatefiledate(woutc)
+
+########################################################################
+##
+## InterrogateModule
+##
+## Generate a python-stub CXX file from a bunch of IN files.
+##
+########################################################################
+
+def InterrogateModule(outc=0, module=0, library=0, files=0):
+  if ((outc==0)|(module==0)|(library==0)|(files==0)):
+    sys.exit("syntax error in InterrogateModule directive");
+  woutc = backslashify("built/tmp/"+outc)
+  wfiles = backslashify(xpaths("built/etc/",files,""))
+  if (older(woutc, wfiles)):
+    if (COMPILER=="MSVC7"): cmd = "built\\bin\\interrogate_module.exe "
+    if (COMPILER=="LINUXA"): cmd = "built/bin/interrogate_module "
+    cmd = cmd + " -oc " + woutc + ' -module "' + module + '" -library "' + library + '" -python '
+    for x in wfiles: cmd = cmd + ' ' + x
+    oscmd(cmd)
+    updatefiledate(woutc);
+ 
+########################################################################
+##
+## CompileLIB
+##
+## Generate a LIB file from a bunch of OBJ files.
+##
+########################################################################
+
+def CompileLIB(lib=0, obj=[], opts=[]):
+  if (lib==0): sys.exit("syntax error in CompileLIB directive");
+
+  if (COMPILER=="MSVC7"):
+    wlib = "built\\lib\\" + lib
+    wobj = xpaths("built\\tmp\\",obj,"")
+    ALLTARGETS.append(wlib)
+    if (older(wlib, wobj)):
+      cmd = 'lib.exe /nologo /OUT:'+wlib;
+      if (OPTIMIZE==4): cmd = cmd + " /LTCG "
+      for x in wobj: cmd=cmd+" "+x;
+      oscmd(cmd)
+      updatefiledate(wlib);
+      
+  if (COMPILER=="LINUXA"):
+    wlib = "built/lib/" + lib[:-4] + ".a"
+    wobj = []
+    for x in obj: wobj.append("built/tmp/" + x[:-4] + ".o")
+    if (older(wlib, wobj)):
+      cmd = "ar cru " + wlib
+      for x in wobj: cmd=cmd+" "+x;
+      oscmd(cmd)
+      updatefiledate(wlib);
+
+########################################################################
+##
+## CompileLink
+##
+## Generate a DLL or EXE file from a bunch of OBJ and LIB files.
+##
+########################################################################
+
+def CompileLink(dll=0, obj=[], opts=[], xdep=[]):
+  if (dll==0): sys.exit("Syntax error in CompileLink directive");
+
+  if (COMPILER=="MSVC7"):
+    ALLTARGETS.append("built/bin/"+dll)
+    wdll = backslashify("built/bin/"+dll)
+    wlib = backslashify("built/lib/"+dll[:-4]+".lib")
+    wobj = []
+    for x in obj:
+      suffix = x[-4:]
+      if   (suffix==".obj"): wobj.append("built\\tmp\\"+x)
+      elif (suffix==".dll"): wobj.append("built\\lib\\"+x[:-4]+".lib")
+      elif (suffix==".lib"): wobj.append("built\\lib\\"+x)
+      elif (suffix==".res"): wobj.append("built\\tmp\\"+x)
+      else: sys.exit("unknown suffix in object list.")
+    if (older(wdll, wobj+backslashify(xdep))):
+      cmd = 'link.exe /nologo /NODEFAULTLIB:LIBCI.LIB'
+      if (dll[-4:-1]==".dl"): cmd = cmd + " /DLL"
+      if (OPTIMIZE==1): cmd = cmd + " /DEBUG /NODEFAULTLIB:MSVCRT.LIB "
+      if (OPTIMIZE==2): cmd = cmd + " /DEBUG /NODEFAULTLIB:MSVCRT.LIB "
+      if (OPTIMIZE==3): cmd = cmd + " /DEBUG /NODEFAULTLIB:MSVCRTD.LIB /OPT:REF "
+      if (OPTIMIZE==4): cmd = cmd + " /DEBUG /NODEFAULTLIB:MSVCRTD.LIB /OPT:REF /LTCG "
+      cmd = cmd + " /MAP /MAPINFO:EXPORTS /MAPINFO:LINES /fixed:no /incremental:no /stack:4194304 "
+      if (opts.count("NOLIBCI")): cmd = cmd + " /NODEFAULTLIB:LIBCI.LIB ";
+      if (PkgSelected(opts,"MAX5") or PkgSelected(opts,"MAX6")
+          or PkgSelected(opts,"MAX7")):
+        cmd = cmd + ' /DEF:".\\pandatool\\src\\maxegg\\MaxEgg.def" '
+      cmd = cmd + " /OUT:" + wdll + " /IMPLIB:" + wlib + " /MAP:NUL"
+      cmd = cmd + " /LIBPATH:built\\python\\libs "
+      for x in wobj: cmd = cmd + " " + x
+      if (opts.count("D3D8") or opts.count("D3D9") or opts.count("DXDRAW") or opts.count("DXSOUND") or opts.count("DXGUID")):
+        cmd = cmd + ' /LIBPATH:"' + DirectXSDK + 'lib\\x86"'
+        cmd = cmd + ' /LIBPATH:"' + DirectXSDK + 'lib"'
+      if (opts.count("D3D8")):        cmd = cmd + ' d3d8.lib d3dx8.lib dxerr8.lib'
+      if (opts.count("D3D9")):        cmd = cmd + ' d3d9.lib d3dx9.lib dxerr9.lib'
+      if (opts.count("DXDRAW")):      cmd = cmd + ' ddraw.lib'
+      if (opts.count("DXSOUND")):     cmd = cmd + ' dsound.lib'
+      if (opts.count("DXGUID")):      cmd = cmd + ' dxguid.lib'
+      if (opts.count("WINSOCK")):     cmd = cmd + " wsock32.lib"
+      if (opts.count("WINSOCK2")):    cmd = cmd + " wsock32.lib ws2_32.lib"
+      if (opts.count("WINCOMCTL")):   cmd = cmd + ' comctl32.lib'
+      if (opts.count("WINUSER")):     cmd = cmd + " user32.lib"
+      if (opts.count("WINMM")):       cmd = cmd + " winmm.lib"
+      if (opts.count("WINIMM")):      cmd = cmd + " imm32.lib"
+      if (opts.count("WINKERNEL")):   cmd = cmd + " kernel32.lib"
+      if (opts.count("WINOLDNAMES")): cmd = cmd + " oldnames.lib"
+      if (opts.count("WINGDI")):      cmd = cmd + " gdi32.lib"
+      if (opts.count("ADVAPI")):      cmd = cmd + " advapi32.lib"
+      if (opts.count("GLUT")):        cmd = cmd + " opengl32.lib glu32.lib"
+      if (PkgSelected(opts,"ZLIB")):     cmd = cmd + " " + THIRDPARTY + 'zlib\\lib\\libz.lib'
+      if (PkgSelected(opts,"PNG")):      cmd = cmd + " " + THIRDPARTY + 'png\\lib\\libpng.lib'
+      if (PkgSelected(opts,"JPEG")):     cmd = cmd + " " + THIRDPARTY + 'jpeg\\lib\\libjpeg.lib'
+      if (PkgSelected(opts,"TIFF")):     cmd = cmd + " " + THIRDPARTY + 'tiff\\lib\\libtiff.lib'
+      if (PkgSelected(opts,"VRPN")):     cmd = cmd + " " + THIRDPARTY + 'vrpn\\lib\\vrpn.lib'
+      if (PkgSelected(opts,"VRPN")):     cmd = cmd + " " + THIRDPARTY + 'vrpn\\lib\\quat.lib'
+      if (PkgSelected(opts,"FMOD")):     cmd = cmd + " " + THIRDPARTY + 'fmod\\lib\\fmod.lib'
+      if (PkgSelected(opts,"NVIDIACG")):
+        if (opts.count("CGGL")): cmd = cmd + " " + THIRDPARTY + 'nvidiacg\\lib\\cgGL.lib'
+        cmd = cmd + " " + THIRDPARTY + 'nvidiacg\\lib\\cg.lib'
+      if (PkgSelected(opts,"HELIX")):    cmd = cmd + " " + THIRDPARTY + 'helix\\lib\\runtlib.lib'
+      if (PkgSelected(opts,"HELIX")):    cmd = cmd + " " + THIRDPARTY + 'helix\\lib\\syslib.lib'
+      if (PkgSelected(opts,"HELIX")):    cmd = cmd + " " + THIRDPARTY + 'helix\\lib\\contlib.lib'
+      if (PkgSelected(opts,"HELIX")):    cmd = cmd + " " + THIRDPARTY + 'helix\\lib\\debuglib.lib'
+      if (PkgSelected(opts,"HELIX")):    cmd = cmd + " " + THIRDPARTY + 'helix\\lib\\utillib.lib'
+      if (PkgSelected(opts,"HELIX")):    cmd = cmd + " " + THIRDPARTY + 'helix\\lib\\stlport_vc7.lib'
+      if (PkgSelected(opts,"NSPR")):     cmd = cmd + " " + THIRDPARTY + 'nspr\\lib\\libnspr4.lib'
+      if (PkgSelected(opts,"OPENSSL")):  cmd = cmd + " " + THIRDPARTY + 'openssl\\lib\\ssleay32.lib'
+      if (PkgSelected(opts,"OPENSSL")):  cmd = cmd + " " + THIRDPARTY + 'openssl\\lib\\libeay32.lib'
+      if (PkgSelected(opts,"FREETYPE")): cmd = cmd + " " + THIRDPARTY + 'freetype\\lib\\libfreetype.lib'
+      if (PkgSelected(opts,"FFTW")):     cmd = cmd + " " + THIRDPARTY + 'fftw\\lib\\rfftw.lib'
+      if (PkgSelected(opts,"FFTW")):     cmd = cmd + " " + THIRDPARTY + 'fftw\\lib\\fftw.lib'
+      if (PkgSelected(opts,"MAYA5")):    cmd = cmd + ' "' + Maya5SDK +  'lib\\Foundation.lib"'
+      if (PkgSelected(opts,"MAYA5")):    cmd = cmd + ' "' + Maya5SDK +  'lib\\OpenMaya.lib"'
+      if (PkgSelected(opts,"MAYA5")):    cmd = cmd + ' "' + Maya5SDK +  'lib\\OpenMayaAnim.lib"'
+      if (PkgSelected(opts,"MAYA6")):    cmd = cmd + ' "' + Maya6SDK +  'lib\\Foundation.lib"'
+      if (PkgSelected(opts,"MAYA6")):    cmd = cmd + ' "' + Maya6SDK +  'lib\\OpenMaya.lib"'
+      if (PkgSelected(opts,"MAYA6")):    cmd = cmd + ' "' + Maya6SDK +  'lib\\OpenMayaAnim.lib"'
+      for max in ["MAX5","MAX6","MAX7"]:
+        if PkgSelected(opts,max):
+          cmd = cmd + ' "' + MAXSDK[max] +  'lib\\core.lib"'
+          cmd = cmd + ' "' + MAXSDK[max] +  'lib\\mesh.lib"'
+          cmd = cmd + ' "' + MAXSDK[max] +  'lib\\maxutil.lib"'
+          cmd = cmd + ' "' + MAXSDK[max] +  'lib\\paramblk2.lib"'
+      oscmd(cmd)
+      updatefiledate(wdll);
+      if ((OPTIMIZE == 1) and (dll[-4:]==".dll")):
+        CopyFile(dll[:-4]+"_d.dll", dll);
+
+  if (COMPILER=="LINUXA"):
+    ALLTARGETS.append("built/lib/"+dll[:-4]+".so")
+    if (dll[-4:]==".exe"): wdll = "built/bin/"+dll[:-4]
+    else: wdll = "built/lib/"+dll[:-4]+".so"
+    wobj = []
+    for x in obj:
+      suffix = x[-4:]
+      if   (suffix==".obj"): wobj.append("built/tmp/"+x[:-4]+".o")
+      elif (suffix==".dll"): wobj.append("built/lib/"+x[:-4]+".so")
+      elif (suffix==".lib"): wobj.append("built/lib/"+x[:-4]+".a")
+      else: sys.exit("unknown suffix in object list.")
+    if (older(wdll, wobj+xdep)):
+      if (dll[-4:]==".exe"): cmd = "g++ -o " + wdll + " -Lbuilt/lib"
+      else:                  cmd = "g++ -shared -o " + wdll + " -Lbuilt/lib"
+      for x in obj:
+        suffix = x[-4:]
+        if   (suffix==".obj"): cmd = cmd + " built/tmp/"+x[:-4]+".o"
+        elif (suffix==".dll"): cmd = cmd + " -l" + x[3:-4]
+        elif (suffix==".lib"): cmd = cmd + " built/lib/"+x[:-4]+".a"
+      if (PkgSelected(opts,"FMOD")):     cmd = cmd + ' -L"' + THIRDPARTY + 'fmod/lib" -lfmod-3.74'
+      if (PkgSelected(opts,"NVIDIACG")):
+        cmd = cmd + ' -L"' + THIRDPARTY + 'nvidiacg/lib" '
+        if (opts.count("CGGL")): cmd = cmd + " -lCgGL"
+        cmd = cmd + " -lCg"
+      if (PkgSelected(opts,"NSPR")):     cmd = cmd + ' -L"' + THIRDPARTY + 'nspr/lib" -lnspr4'
+      if (PkgSelected(opts,"ZLIB")):     cmd = cmd + " -lz"
+      if (PkgSelected(opts,"PNG")):      cmd = cmd + " -lpng"
+      if (PkgSelected(opts,"JPEG")):     cmd = cmd + " -ljpeg"
+      if (PkgSelected(opts,"TIFF")):     cmd = cmd + " -ltiff"
+      if (PkgSelected(opts,"OPENSSL")):  cmd = cmd + " -lssl"
+      if (PkgSelected(opts,"FREETYPE")): cmd = cmd + " -lfreetype"
+      if (PkgSelected(opts,"VRPN")):     cmd = cmd + ' -L"' + THIRDPARTY + 'vrpn/lib" -lvrpn -lquat'
+      if (PkgSelected(opts,"FFTW")):     cmd = cmd + ' -L"' + THIRDPARTY + 'fftw/lib" -lrfftw -lfftw'
+      if (opts.count("GLUT")):           cmd = cmd + " -lGL -lGLU"
+      oscmd(cmd)
+      updatefiledate(wdll);
+
+##########################################################################################
+#
+# If the 'make depend' process discovers an 'include'
+# directive that includes one of the following files,
+# the specified file is not added as a dependency,
+# nor is it traversed.
+#
+##########################################################################################
+
+CxxIgnoreHeader["Python.h"] = 1;
+CxxIgnoreHeader["Python/Python.h"] = 1;
+CxxIgnoreHeader["alloc.h"] = 1;
+CxxIgnoreHeader["ctype.h"] = 1;
+CxxIgnoreHeader["stdlib.h"] = 1;
+CxxIgnoreHeader["ipc_thread.h"] = 1;
+CxxIgnoreHeader["platform/symbian/symbian_print.h"] = 1;
+CxxIgnoreHeader["hxtypes.h"] = 1;
+CxxIgnoreHeader["hxcom.h"] = 1;
+CxxIgnoreHeader["hxiids.h"] = 1;
+CxxIgnoreHeader["hxpiids.h"] = 1;
+CxxIgnoreHeader["dsound.h"] = 1;
+CxxIgnoreHeader["hlxosstr.h"] = 1;
+CxxIgnoreHeader["ddraw.h"] = 1;
+CxxIgnoreHeader["mss.h"] = 1;
+CxxIgnoreHeader["MacSocket.h"] = 1;
+CxxIgnoreHeader["textureTransition.h"] = 1;
+CxxIgnoreHeader["transformTransition.h"] = 1;
+CxxIgnoreHeader["billboardTransition.h"] = 1;
+CxxIgnoreHeader["transformTransition.h"] = 1;
+CxxIgnoreHeader["transparencyTransition.h"] = 1;
+CxxIgnoreHeader["allTransitionsWrapper.h"] = 1;
+CxxIgnoreHeader["allTransitionsWrapper.h"] = 1;
+CxxIgnoreHeader["namedNode.h"] = 1;
+CxxIgnoreHeader["renderRelation.h"] = 1;
+CxxIgnoreHeader["renderTraverser.h"] = 1;
+CxxIgnoreHeader["get_rel_pos.h"] = 1;
+CxxIgnoreHeader["Max.h"] = 1;
+CxxIgnoreHeader["iparamb2.h"] = 1;
+CxxIgnoreHeader["iparamm2.h"] = 1;
+CxxIgnoreHeader["istdplug.h"] = 1;
+CxxIgnoreHeader["iskin.h"] = 1;
+CxxIgnoreHeader["stdmat.h"] = 1;
+CxxIgnoreHeader["phyexp.h"] = 1;
+CxxIgnoreHeader["bipexp.h"] = 1;
+CxxIgnoreHeader["windows.h"] = 1;
+CxxIgnoreHeader["windef.h"] = 1;
+CxxIgnoreHeader["modstack.h"] = 1;
+CxxIgnoreHeader["afxres.h"] = 1;
+
+
+##########################################################################################
+#
+# Create the directory tree
+#
+##########################################################################################
+
+MakeDirectory("built")
+MakeDirectory("built/bin")
+MakeDirectory("built/lib")
+MakeDirectory("built/etc")
+MakeDirectory("built/include")
+MakeDirectory("built/include/parser-inc")
+MakeDirectory("built/include/parser-inc/openssl")
+MakeDirectory("built/include/parser-inc/Cg")
+MakeDirectory("built/include/openssl")
+MakeDirectory("built/direct")
+MakeDirectory("built/tmp")
+
+##########################################################################################
+#
+# Generate pandaVersion.h
+#
+##########################################################################################
+
+conf="""
+#define PANDA_MAJOR_VERSION VERSION1
+#define PANDA_MINOR_VERSION VERSION2
+#define PANDA_SEQUENCE_VERSION VERSION2
+#undef  PANDA_OFFICIAL_VERSION
+#define PANDA_VERSION NVERSION
+#define PANDA_VERSION_STR "VERSION1.VERSION2.VERSION3"
+#define PANDA_DISTRIBUTOR "makepanda"
+"""
+
+conf = conf.replace("VERSION1",str(VERSION1))
+conf = conf.replace("VERSION2",str(VERSION2))
+conf = conf.replace("VERSION3",str(VERSION3))
+conf = conf.replace("NVERSION",str(VERSION1*1000000+VERSION2*1000+VERSION3))
+
+ConditionalWriteFile('built/include/pandaVersion.h',conf);
+
+conf="""
+# include "dtoolbase.h"
+EXPCL_DTOOL int panda_version_VERSION1_VERSION2_VERSION3 = 0;
+"""
+
+conf = conf.replace("VERSION1",str(VERSION1))
+conf = conf.replace("VERSION2",str(VERSION2))
+conf = conf.replace("VERSION3",str(VERSION3))
+conf = conf.replace("NVERSION",str(VERSION1*1000000+VERSION2*1000+VERSION3))
+
+ConditionalWriteFile('built/include/checkPandaVersion.cxx',conf);
+
+conf="""
+# include "dtoolbase.h"
+extern EXPCL_DTOOL int panda_version_VERSION1_VERSION2_VERSION3;
+# ifndef WIN32
+/* For Windows, exporting the symbol from the DLL is sufficient; the
+   DLL will not load unless all expected public symbols are defined.
+   Other systems may not mind if the symbol is absent unless we
+   explictly write code that references it. */
+static int check_panda_version = panda_version_VERSION1_VERSION2_VERSION3;
+# endif
+"""
+
+conf = conf.replace("VERSION1",str(VERSION1))
+conf = conf.replace("VERSION2",str(VERSION2))
+conf = conf.replace("VERSION3",str(VERSION3))
+conf = conf.replace("NVERSION",str(VERSION1*1000000+VERSION2*1000+VERSION3))
+
+ConditionalWriteFile('built/include/checkPandaVersion.h',conf);
+
+##########################################################################################
+#
+# Generate direct/__init__.py
+#
+##########################################################################################
+
+DIRECTINIT="""
+import os,sys
+srcdir1 = os.path.join(__path__[0], 'src')
+srcdir2 = os.path.join(__path__[0], '..', '..', 'direct', 'src')
+if    (os.path.isdir(srcdir1)): __path__[0] = srcdir1
+elif  (os.path.isdir(srcdir2)): __path__[0] = srcdir2
+else: sys.exit("Cannot find the 'direct' tree")
+"""
+ConditionalWriteFile('built/direct/__init__.py', DIRECTINIT)
+
+##########################################################################################
+#
+# Generate dtool_have_xxx.dat
+#
+##########################################################################################
+
+for x in PACKAGES:
+  if (OMIT.count(x)): ConditionalWriteFile('built/tmp/dtool_have_'+x.lower()+'.dat',"0\n")
+  else:               ConditionalWriteFile('built/tmp/dtool_have_'+x.lower()+'.dat',"1\n")
+
+##########################################################################################
+#
+# Generate dtool_config.h
+#
+##########################################################################################
+
+conf = ""
+conf=conf+'\n/* dtool_config.h.  Generated automatically by makepanda.py */'
+conf=conf+'\n'
+if (OMIT.count("ZLIB")==0):     conf=conf+'\n#define HAVE_ZLIB 1'
+if (OMIT.count("PNG")==0):      conf=conf+'\n#define HAVE_PNG 1'
+if (OMIT.count("JPEG")==0):     conf=conf+'\n#define HAVE_JPEG 1'
+if (OMIT.count("TIFF")==0):     conf=conf+'\n#define HAVE_TIFF 1'
+if (OMIT.count("VRPN")==0):     conf=conf+'\n#define HAVE_VRPN 1'
+if (OMIT.count("FMOD")==0):     conf=conf+'\n#define HAVE_FMOD 1'
+if (OMIT.count("NVIDIACG")==0): conf=conf+'\n#define HAVE_CG 1'
+if (OMIT.count("NVIDIACG")==0): conf=conf+'\n#define HAVE_CGGL 1'
+if (OMIT.count("HELIX")==0):    pass
+if (OMIT.count("NSPR")==0):     conf=conf+'\n#define HAVE_NSPR 1'
+if (OMIT.count("OPENSSL")==0):  conf=conf+'\n#define HAVE_SSL 1'
+if (OMIT.count("FREETYPE")==0): conf=conf+'\n#define HAVE_FREETYPE 1'
+if (OMIT.count("FFTW")==0):     conf=conf+'\n#define HAVE_FFTW 1'
+if (OMIT.count("MILES")==0):    conf=conf+'\n#define HAVE_RAD_MSS 1'
+if (OMIT.count("MAYA5")==0):    pass
+if (OMIT.count("MAYA6")==0):    pass
+if (OMIT.count("MAX5")==0):     pass
+if (OMIT.count("MAX6")==0):     pass
+if (OMIT.count("MAX7")==0):     pass
+
+if (COMPILER=="MSVC7"): conf = conf + """
+#define HAVE_PYTHON 1
+#undef  PYTHON_FRAMEWORK
+#define COMPILE_IN_DEFAULT_FONT 1
+#define HAVE_MAYA 1
+#undef  MAYA_PRE_5_0
+#undef  HAVE_SOFTIMAGE
+#define SSL_097
+#define REPORT_OPENSSL_ERRORS 1
+#define HAVE_GL 1
+#undef  HAVE_MESA
+#undef  MESA_MGL
+#undef  HAVE_SGIGL
+#undef  HAVE_GLX
+#define HAVE_WGL 1
+#define HAVE_DX 1
+#undef  HAVE_CHROMIUM
+#undef  HAVE_THREADS
+#define HAVE_NET 1
+#define HAVE_AUDIO 1
+#define DO_PSTATS 1
+#define DO_COLLISION_RECORDING 1
+#undef  TRACK_IN_INTERPRETER
+#define DO_MEMORY_USAGE 1
+#undef  DO_PIPELINING
+#define NOTIFY_DEBUG 1
+#define EXPORT_TEMPLATES yes
+#undef  LINK_IN_GL
+#undef  LINK_IN_PHYSICS
+#define DEFAULT_PATHSEP ";"
+
+#define DEFAULT_PRC_DIR "<auto>"
+#define PRC_DIR_ENVVARS "PRC_DIR"
+#define PRC_PATH_ENVVARS "PRC_PATH"
+#define PRC_PATTERNS "*.prc"
+#define PRC_EXECUTABLE_PATTERNS ""
+#define PRC_EXECUTABLE_ARGS_ENVVAR "PRC_EXECUTABLE_ARGS"
+#define PRC_PUBLIC_KEYS_FILENAME ""
+#undef  PRC_RESPECT_TRUST_LEVEL
+#define PRC_SAVE_DESCRIPTIONS 1
+
+#undef  WORDS_BIGENDIAN
+#define HAVE_NAMESPACE 1
+#undef  HAVE_OPEN_MASK
+#define HAVE_WCHAR_T 1
+#define HAVE_WSTRING 1
+#define HAVE_TYPENAME 1
+#define SIMPLE_STRUCT_POINTERS 1
+#undef HAVE_DINKUM
+#undef HAVE_STL_HASH
+
+#undef  HAVE_GETTIMEOFDAY
+#undef  GETTIMEOFDAY_ONE_PARAM
+#undef  HAVE_GETOPT
+#undef  HAVE_GETOPT_LONG_ONLY
+#undef  HAVE_GETOPT_H
+#undef  IOCTL_TERMINAL_WIDTH
+#define HAVE_STREAMSIZE 1
+#define HAVE_IOS_TYPEDEFS 1
+#define HAVE_IOS_BINARY 1
+#define STATIC_INIT_GETENV 1
+
+#undef  HAVE_PROC_SELF_ENVIRON
+#define HAVE_GLOBAL_ARGV 1
+#undef  PROTOTYPE_GLOBAL_ARGV
+#define GLOBAL_ARGV __argv
+#define GLOBAL_ARGC __argc
+#undef  HAVE_PROC_SELF_CMDLINE
+#define HAVE_IO_H 1
+#define HAVE_IOSTREAM 1
+#define HAVE_MALLOC_H 1
+#undef  HAVE_SYS_MALLOC_H
+#undef  HAVE_ALLOCA_H
+#undef  HAVE_LOCALE_H
+#define HAVE_MINMAX_H 1
+#define HAVE_SSTREAM 1
+#define HAVE_NEW 1
+#define HAVE_SYS_TYPES_H 1
+#undef  HAVE_SYS_TIME_H
+#undef  HAVE_UNISTD_H
+#undef  HAVE_UTIME_H
+#undef  HAVE_GLOB_H
+#undef  HAVE_DIRENT_H
+#undef  HAVE_SYS_SOUNDCARD_H
+
+#define HAVE_RTTI 1
+#undef  GLOBAL_OPERATOR_NEW_EXCEPTIONS
+#undef  OLD_STYLE_ALLOCATOR
+#undef  GNU_STYLE_ALLOCATOR
+#undef  VC6_STYLE_ALLOCATOR
+#undef  MODERN_STYLE_ALLOCATOR
+#define NO_STYLE_ALLOCATOR 1
+"""
+
+
+if (COMPILER=="LINUXA"): conf = conf + """
+#define HAVE_PYTHON 1
+#undef  PYTHON_FRAMEWORK
+#define COMPILE_IN_DEFAULT_FONT 1
+#define HAVE_MAYA 1
+#undef  MAYA_PRE_5_0
+#undef  HAVE_SOFTIMAGE
+#undef  SSL_097
+#define REPORT_OPENSSL_ERRORS 1
+#define HAVE_GL /usr/lib/libGL.so
+#undef  HAVE_MESA
+#undef  MESA_MGL
+#undef  HAVE_SGIGL
+#define HAVE_GLX 1
+#undef  HAVE_WGL
+#undef  HAVE_DX
+#undef  HAVE_CHROMIUM
+#undef  HAVE_THREADS
+#define HAVE_NET 1
+#define HAVE_AUDIO 1
+#define DO_PSTATS 1
+#define DO_COLLISION_RECORDING 1
+#undef  TRACK_IN_INTERPRETER
+#define DO_MEMORY_USAGE 1
+#undef  DO_PIPELINING
+#define NOTIFY_DEBUG 1
+#define EXPORT_TEMPLATES yes
+#undef  LINK_IN_GL
+#undef  LINK_IN_PHYSICS
+#define DEFAULT_PATHSEP ":"
+
+#define DEFAULT_PRC_DIR "<auto>"
+#define PRC_DIR_ENVVARS "PRC_DIR"
+#define PRC_PATH_ENVVARS "PRC_PATH"
+#define PRC_PATTERNS "*.prc"
+#define PRC_EXECUTABLE_PATTERNS ""
+#define PRC_EXECUTABLE_ARGS_ENVVAR "PRC_EXECUTABLE_ARGS"
+#define PRC_PUBLIC_KEYS_FILENAME ""
+#undef  PRC_RESPECT_TRUST_LEVEL
+#define PRC_SAVE_DESCRIPTIONS 1
+
+#undef WORDS_BIGENDIAN
+#define HAVE_NAMESPACE 1
+#undef HAVE_OPEN_MASK
+#define HAVE_WCHAR_T 1
+#define HAVE_WSTRING 1
+#define HAVE_TYPENAME 1
+#undef SIMPLE_STRUCT_POINTERS
+#undef HAVE_DINKUM
+#undef HAVE_STL_HASH
+
+#define HAVE_GETTIMEOFDAY 1
+#undef GETTIMEOFDAY_ONE_PARAM
+#define HAVE_GETOPT 1
+#define HAVE_GETOPT_LONG_ONLY 1
+#define HAVE_GETOPT_H 1
+#define IOCTL_TERMINAL_WIDTH 1
+#define HAVE_STREAMSIZE 1
+#define HAVE_IOS_TYPEDEFS 1
+#define HAVE_IOS_BINARY 1
+#undef STATIC_INIT_GETENV
+
+#define HAVE_PROC_SELF_ENVIRON 1
+#undef HAVE_GLOBAL_ARGV
+#undef PROTOTYPE_GLOBAL_ARGV
+#undef GLOBAL_ARGV
+#undef GLOBAL_ARGC
+#define HAVE_PROC_SELF_CMDLINE 1
+#undef HAVE_IO_H
+#define HAVE_IOSTREAM 1
+#define HAVE_MALLOC_H 1
+#undef HAVE_SYS_MALLOC_H
+#define HAVE_ALLOCA_H 1
+#define HAVE_LOCALE_H 1
+#undef HAVE_MINMAX_H
+#define HAVE_SSTREAM 1
+#define HAVE_NEW 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_UTIME_H 1
+#define HAVE_GLOB_H 1
+#define HAVE_DIRENT_H 1
+#define HAVE_SYS_SOUNDCARD_H 1
+
+#define HAVE_RTTI 1
+#define GLOBAL_OPERATOR_NEW_EXCEPTIONS 1
+#undef OLD_STYLE_ALLOCATOR
+#define GNU_STYLE_ALLOCATOR 1
+#undef VC6_STYLE_ALLOCATOR
+#undef MODERN_STYLE_ALLOCATOR
+#undef NO_STYLE_ALLOCATOR
+"""
+
+ConditionalWriteFile('built/include/dtool_config.h',conf);
+
+##########################################################################################
+#
+# Copy the config file into the build
+#
+##########################################################################################
+
+CopyFile('built/', 'Config.prc')
+
+##########################################################################################
+#
+# Copy the precompiled binaries and DLLs into the build.
+#
+##########################################################################################
+
+for pkg in PACKAGES:
+  if (OMIT.count(pkg)==0):
+    if (sys.platform == "win32"):
+      if (os.path.exists(backslashify(STDTHIRDPARTY + pkg.lower() + "/bin"))):
+        CopyAllFiles("built/bin/", STDTHIRDPARTY + pkg.lower() + "/bin/")
+    else:
+      if (os.path.exists(STDTHIRDPARTY + pkg.lower() + "/lib")):
+        CopyAllFiles("built/lib/", STDTHIRDPARTY + pkg.lower() + "/lib/")
+
+if (os.path.exists(backslashify(STDTHIRDPARTY + "extras/bin"))):
+  CopyAllFiles("built/bin/", STDTHIRDPARTY + "extras/bin/")
+if (sys.platform == "win32"):
+  CopyTree('built/python', 'thirdparty/win-python')
+  CopyFile('built/bin/', 'thirdparty/win-python/python22.dll')
+
+########################################################################
+##
+## Compile the 'ppython' executable and 'genpycode' executables
+##
+########################################################################
+
+IPATH=['direct/src/directbase']
+CompileC(ipath=IPATH, opts=['BUILDING_PPYTHON'], src='ppython.cxx', obj='ppython.obj')
+CompileLink(opts=['WINUSER'], dll='ppython.exe', obj=['ppython.obj'])
+IPATH=['direct/src/directbase']
+CompileC(ipath=IPATH, opts=['BUILDING_GENPYCODE'], src='ppython.cxx', obj='genpycode.obj')
+CompileLink(opts=['WINUSER'], dll='genpycode.exe', obj=['genpycode.obj'])
+
+########################################################################
+#
+# Copy header files to the built/include directory.
+#
+# Are we just copying *ALL* headers into the include directory?
+# If so, let's automate this.
+#
+########################################################################
+
+ConditionalWriteFile('built/include/ctl3d.h', '/* dummy file to make MAX happy */')
+
+CopyAllFiles('built/include/parser-inc/','dtool/src/parser-inc/')
+CopyAllFiles('built/include/parser-inc/openssl/','dtool/src/parser-inc/')
+CopyFile('built/include/parser-inc/Cg/','dtool/src/parser-inc/cg.h')
+CopyFile('built/include/parser-inc/Cg/','dtool/src/parser-inc/cgGL.h')
+
+CopyFile('built/include/','dtool/src/dtoolbase/cmath.I')
+CopyFile('built/include/','dtool/src/dtoolbase/cmath.h')
+CopyFile('built/include/','dtool/src/dtoolbase/dallocator.T')
+CopyFile('built/include/','dtool/src/dtoolbase/dallocator.h')
+CopyFile('built/include/','dtool/src/dtoolbase/dtoolbase.h')
+CopyFile('built/include/','dtool/src/dtoolbase/dtoolbase_cc.h')
+CopyFile('built/include/','dtool/src/dtoolbase/dtoolsymbols.h')
+CopyFile('built/include/','dtool/src/dtoolbase/fakestringstream.h')
+CopyFile('built/include/','dtool/src/dtoolbase/nearly_zero.h')
+CopyFile('built/include/','dtool/src/dtoolbase/stl_compares.I')
+CopyFile('built/include/','dtool/src/dtoolbase/stl_compares.h')
+CopyFile('built/include/','dtool/src/dtoolbase/pallocator.T')
+CopyFile('built/include/','dtool/src/dtoolbase/pallocator.h')
+CopyFile('built/include/','dtool/src/dtoolbase/pdeque.h')
+CopyFile('built/include/','dtool/src/dtoolbase/plist.h')
+CopyFile('built/include/','dtool/src/dtoolbase/pmap.h')
+CopyFile('built/include/','dtool/src/dtoolbase/pset.h')
+CopyFile('built/include/','dtool/src/dtoolbase/pvector.h')
+CopyFile('built/include/','dtool/src/dtoolutil/executionEnvironment.I')
+CopyFile('built/include/','dtool/src/dtoolutil/executionEnvironment.h')
+CopyFile('built/include/','dtool/src/dtoolutil/filename.I')
+CopyFile('built/include/','dtool/src/dtoolutil/filename.h')
+CopyFile('built/include/','dtool/src/dtoolutil/load_dso.h')
+CopyFile('built/include/','dtool/src/dtoolutil/dSearchPath.I')
+CopyFile('built/include/','dtool/src/dtoolutil/dSearchPath.h')
+CopyFile('built/include/','dtool/src/dtoolutil/pfstream.h')
+CopyFile('built/include/','dtool/src/dtoolutil/pfstream.I')
+CopyFile('built/include/','dtool/src/dtoolutil/vector_string.h')
+CopyFile('built/include/','dtool/src/dtoolutil/gnu_getopt.h')
+CopyFile('built/include/','dtool/src/dtoolutil/pfstreamBuf.h')
+CopyFile('built/include/','dtool/src/dtoolutil/vector_src.cxx')
+CopyFile('built/include/','dtool/src/dtoolutil/vector_src.h')
+CopyFile('built/include/','dtool/src/dtoolutil/pandaSystem.h')
+CopyFile('built/include/','dtool/src/prc/config_prc.h')
+CopyFile('built/include/','dtool/src/prc/configDeclaration.I')
+CopyFile('built/include/','dtool/src/prc/configDeclaration.h')
+CopyFile('built/include/','dtool/src/prc/configFlags.I')
+CopyFile('built/include/','dtool/src/prc/configFlags.h')
+CopyFile('built/include/','dtool/src/prc/configPage.I')
+CopyFile('built/include/','dtool/src/prc/configPage.h')
+CopyFile('built/include/','dtool/src/prc/configPageManager.I')
+CopyFile('built/include/','dtool/src/prc/configPageManager.h')
+CopyFile('built/include/','dtool/src/prc/configVariable.I')
+CopyFile('built/include/','dtool/src/prc/configVariable.h')
+CopyFile('built/include/','dtool/src/prc/configVariableBase.I')
+CopyFile('built/include/','dtool/src/prc/configVariableBase.h')
+CopyFile('built/include/','dtool/src/prc/configVariableBool.I')
+CopyFile('built/include/','dtool/src/prc/configVariableBool.h')
+CopyFile('built/include/','dtool/src/prc/configVariableCore.I')
+CopyFile('built/include/','dtool/src/prc/configVariableCore.h')
+CopyFile('built/include/','dtool/src/prc/configVariableDouble.I')
+CopyFile('built/include/','dtool/src/prc/configVariableDouble.h')
+CopyFile('built/include/','dtool/src/prc/configVariableEnum.I')
+CopyFile('built/include/','dtool/src/prc/configVariableEnum.h')
+CopyFile('built/include/','dtool/src/prc/configVariableFilename.I')
+CopyFile('built/include/','dtool/src/prc/configVariableFilename.h')
+CopyFile('built/include/','dtool/src/prc/configVariableInt.I')
+CopyFile('built/include/','dtool/src/prc/configVariableInt.h')
+CopyFile('built/include/','dtool/src/prc/configVariableList.I')
+CopyFile('built/include/','dtool/src/prc/configVariableList.h')
+CopyFile('built/include/','dtool/src/prc/configVariableManager.I')
+CopyFile('built/include/','dtool/src/prc/configVariableManager.h')
+CopyFile('built/include/','dtool/src/prc/configVariableSearchPath.I')
+CopyFile('built/include/','dtool/src/prc/configVariableSearchPath.h')
+CopyFile('built/include/','dtool/src/prc/configVariableString.I')
+CopyFile('built/include/','dtool/src/prc/configVariableString.h')
+CopyFile('built/include/','dtool/src/prc/globPattern.I')
+CopyFile('built/include/','dtool/src/prc/globPattern.h')
+CopyFile('built/include/','dtool/src/prc/notify.I')
+CopyFile('built/include/','dtool/src/prc/notify.h')
+CopyFile('built/include/','dtool/src/prc/notifyCategory.I')
+CopyFile('built/include/','dtool/src/prc/notifyCategory.h')
+CopyFile('built/include/','dtool/src/prc/notifyCategoryProxy.I')
+CopyFile('built/include/','dtool/src/prc/notifyCategoryProxy.h')
+CopyFile('built/include/','dtool/src/prc/notifySeverity.h')
+CopyFile('built/include/','dtool/src/prc/prcKeyRegistry.I')
+CopyFile('built/include/','dtool/src/prc/prcKeyRegistry.h')
+CopyFile('built/include/','dtool/src/dconfig/configTable.I')
+CopyFile('built/include/','dtool/src/dconfig/configTable.h')
+CopyFile('built/include/','dtool/src/dconfig/config_dconfig.h')
+CopyFile('built/include/','dtool/src/dconfig/config_setup.h')
+CopyFile('built/include/','dtool/src/dconfig/dconfig.I')
+CopyFile('built/include/','dtool/src/dconfig/dconfig.h')
+CopyFile('built/include/','dtool/src/dconfig/serialization.I')
+CopyFile('built/include/','dtool/src/dconfig/serialization.h')
+CopyFile('built/include/','dtool/src/dconfig/symbolEnt.I')
+CopyFile('built/include/','dtool/src/dconfig/symbolEnt.h')
+CopyFile('built/include/','dtool/src/interrogatedb/interrogate_interface.h')
+CopyFile('built/include/','dtool/src/interrogatedb/interrogate_request.h')
+CopyFile('built/include/','dtool/src/interrogatedb/vector_int.h')
+CopyFile('built/include/','dtool/src/interrogatedb/config_interrogatedb.h')
+CopyFile('built/include/','dtool/src/pystub/pystub.h')
+CopyFile('built/include/','dtool/src/prckeys/signPrcFile_src.cxx')
+CopyFile('built/include/','panda/src/pandabase/pandabase.h')
+CopyFile('built/include/','panda/src/pandabase/pandasymbols.h')
+CopyFile('built/include/','panda/src/express/atomicAdjustDummyImpl.h')
+CopyFile('built/include/','panda/src/express/atomicAdjustDummyImpl.I')
+CopyFile('built/include/','panda/src/express/atomicAdjust.h')
+CopyFile('built/include/','panda/src/express/atomicAdjust.I')
+CopyFile('built/include/','panda/src/express/atomicAdjustImpl.h')
+CopyFile('built/include/','panda/src/express/atomicAdjustNsprImpl.h')
+CopyFile('built/include/','panda/src/express/atomicAdjustNsprImpl.I')
+CopyFile('built/include/','panda/src/express/bigEndian.h')
+CopyFile('built/include/','panda/src/express/buffer.I')
+CopyFile('built/include/','panda/src/express/buffer.h')
+CopyFile('built/include/','panda/src/express/checksumHashGenerator.I')
+CopyFile('built/include/','panda/src/express/checksumHashGenerator.h')
+CopyFile('built/include/','panda/src/express/circBuffer.I')
+CopyFile('built/include/','panda/src/express/circBuffer.h')
+CopyFile('built/include/','panda/src/express/clockObject.I')
+CopyFile('built/include/','panda/src/express/clockObject.h')
+CopyFile('built/include/','panda/src/express/conditionVarDummyImpl.h')
+CopyFile('built/include/','panda/src/express/conditionVarDummyImpl.I')
+CopyFile('built/include/','panda/src/express/conditionVar.h')
+CopyFile('built/include/','panda/src/express/conditionVar.I')
+CopyFile('built/include/','panda/src/express/conditionVarImpl.h')
+CopyFile('built/include/','panda/src/express/conditionVarNsprImpl.h')
+CopyFile('built/include/','panda/src/express/conditionVarNsprImpl.I')
+CopyFile('built/include/','panda/src/express/config_express.h')
+CopyFile('built/include/','panda/src/express/datagram.I')
+CopyFile('built/include/','panda/src/express/datagram.h')
+CopyFile('built/include/','panda/src/express/datagramGenerator.I')
+CopyFile('built/include/','panda/src/express/datagramGenerator.h')
+CopyFile('built/include/','panda/src/express/datagramIterator.I')
+CopyFile('built/include/','panda/src/express/datagramIterator.h')
+CopyFile('built/include/','panda/src/express/datagramSink.I')
+CopyFile('built/include/','panda/src/express/datagramSink.h')
+CopyFile('built/include/','panda/src/express/dcast.T')
+CopyFile('built/include/','panda/src/express/dcast.h')
+CopyFile('built/include/','panda/src/express/encryptStreamBuf.h')
+CopyFile('built/include/','panda/src/express/encryptStreamBuf.I')
+CopyFile('built/include/','panda/src/express/encryptStream.h')
+CopyFile('built/include/','panda/src/express/encryptStream.I')
+CopyFile('built/include/','panda/src/express/error_utils.h')
+CopyFile('built/include/','panda/src/express/hashGeneratorBase.I')
+CopyFile('built/include/','panda/src/express/hashGeneratorBase.h')
+CopyFile('built/include/','panda/src/express/hashVal.I')
+CopyFile('built/include/','panda/src/express/hashVal.h')
+CopyFile('built/include/','panda/src/express/indent.I')
+CopyFile('built/include/','panda/src/express/indent.h')
+CopyFile('built/include/','panda/src/express/indirectLess.I')
+CopyFile('built/include/','panda/src/express/indirectLess.h')
+CopyFile('built/include/','panda/src/express/littleEndian.h')
+CopyFile('built/include/','panda/src/express/memoryInfo.I')
+CopyFile('built/include/','panda/src/express/memoryInfo.h')
+CopyFile('built/include/','panda/src/express/memoryUsage.I')
+CopyFile('built/include/','panda/src/express/memoryUsage.h')
+CopyFile('built/include/','panda/src/express/memoryUsagePointerCounts.I')
+CopyFile('built/include/','panda/src/express/memoryUsagePointerCounts.h')
+CopyFile('built/include/','panda/src/express/memoryUsagePointers.I')
+CopyFile('built/include/','panda/src/express/memoryUsagePointers.h')
+CopyFile('built/include/','panda/src/express/multifile.I')
+CopyFile('built/include/','panda/src/express/multifile.h')
+CopyFile('built/include/','panda/src/express/mutexDummyImpl.h')
+CopyFile('built/include/','panda/src/express/mutexDummyImpl.I')
+CopyFile('built/include/','panda/src/express/pmutex.h')
+CopyFile('built/include/','panda/src/express/mutexHolder.h')
+CopyFile('built/include/','panda/src/express/mutexHolder.I')
+CopyFile('built/include/','panda/src/express/pmutex.I')
+CopyFile('built/include/','panda/src/express/mutexImpl.h')
+CopyFile('built/include/','panda/src/express/mutexNsprImpl.h')
+CopyFile('built/include/','panda/src/express/mutexNsprImpl.I')
+CopyFile('built/include/','panda/src/express/namable.I')
+CopyFile('built/include/','panda/src/express/namable.h')
+CopyFile('built/include/','panda/src/express/nativeNumericData.I')
+CopyFile('built/include/','panda/src/express/nativeNumericData.h')
+CopyFile('built/include/','panda/src/express/numeric_types.h')
+CopyFile('built/include/','panda/src/express/ordered_vector.h')
+CopyFile('built/include/','panda/src/express/ordered_vector.I')
+CopyFile('built/include/','panda/src/express/ordered_vector.T')
+CopyFile('built/include/','panda/src/express/password_hash.h')
+CopyFile('built/include/','panda/src/express/patchfile.I')
+CopyFile('built/include/','panda/src/express/patchfile.h')
+CopyFile('built/include/','panda/src/express/pointerTo.I')
+CopyFile('built/include/','panda/src/express/pointerTo.h')
+CopyFile('built/include/','panda/src/express/pointerToArray.I')
+CopyFile('built/include/','panda/src/express/pointerToArray.h')
+CopyFile('built/include/','panda/src/express/pointerToBase.I')
+CopyFile('built/include/','panda/src/express/pointerToBase.h')
+CopyFile('built/include/','panda/src/express/pointerToVoid.I')
+CopyFile('built/include/','panda/src/express/pointerToVoid.h')
+CopyFile('built/include/','panda/src/express/profileTimer.I')
+CopyFile('built/include/','panda/src/express/profileTimer.h')
+CopyFile('built/include/','panda/src/express/pta_uchar.h')
+CopyFile('built/include/','panda/src/express/ramfile.I')
+CopyFile('built/include/','panda/src/express/ramfile.h')
+CopyFile('built/include/','panda/src/express/referenceCount.I')
+CopyFile('built/include/','panda/src/express/referenceCount.h')
+CopyFile('built/include/','panda/src/express/register_type.I')
+CopyFile('built/include/','panda/src/express/register_type.h')
+CopyFile('built/include/','panda/src/express/reversedNumericData.I')
+CopyFile('built/include/','panda/src/express/reversedNumericData.h')
+CopyFile('built/include/','panda/src/express/selectThreadImpl.h')
+CopyFile('built/include/','panda/src/express/streamReader.I')
+CopyFile('built/include/','panda/src/express/streamReader.h')
+CopyFile('built/include/','panda/src/express/streamWriter.I')
+CopyFile('built/include/','panda/src/express/streamWriter.h')
+CopyFile('built/include/','panda/src/express/stringDecoder.h')
+CopyFile('built/include/','panda/src/express/stringDecoder.I')
+CopyFile('built/include/','panda/src/express/subStream.I')
+CopyFile('built/include/','panda/src/express/subStream.h')
+CopyFile('built/include/','panda/src/express/subStreamBuf.h')
+CopyFile('built/include/','panda/src/express/textEncoder.h')
+CopyFile('built/include/','panda/src/express/textEncoder.I')
+CopyFile('built/include/','panda/src/express/threadDummyImpl.h')
+CopyFile('built/include/','panda/src/express/threadDummyImpl.I')
+CopyFile('built/include/','panda/src/express/thread.h')
+CopyFile('built/include/','panda/src/express/thread.I')
+CopyFile('built/include/','panda/src/express/threadImpl.h')
+CopyFile('built/include/','panda/src/express/threadNsprImpl.h')
+CopyFile('built/include/','panda/src/express/threadNsprImpl.I')
+CopyFile('built/include/','panda/src/express/threadPriority.h')
+CopyFile('built/include/','panda/src/express/tokenBoard.I')
+CopyFile('built/include/','panda/src/express/tokenBoard.h')
+CopyFile('built/include/','panda/src/express/trueClock.I')
+CopyFile('built/include/','panda/src/express/trueClock.h')
+CopyFile('built/include/','panda/src/express/typeHandle.I')
+CopyFile('built/include/','panda/src/express/typeHandle.h')
+CopyFile('built/include/','panda/src/express/typedObject.I')
+CopyFile('built/include/','panda/src/express/typedObject.h')
+CopyFile('built/include/','panda/src/express/typedReferenceCount.I')
+CopyFile('built/include/','panda/src/express/typedReferenceCount.h')
+CopyFile('built/include/','panda/src/express/typedef.h')
+CopyFile('built/include/','panda/src/express/typeRegistry.I')
+CopyFile('built/include/','panda/src/express/typeRegistry.h')
+CopyFile('built/include/','panda/src/express/typeRegistryNode.I')
+CopyFile('built/include/','panda/src/express/typeRegistryNode.h')
+CopyFile('built/include/','panda/src/express/unicodeLatinMap.h')
+CopyFile('built/include/','panda/src/express/vector_uchar.h')
+CopyFile('built/include/','panda/src/express/virtualFileComposite.h')
+CopyFile('built/include/','panda/src/express/virtualFileComposite.I')
+CopyFile('built/include/','panda/src/express/virtualFile.h')
+CopyFile('built/include/','panda/src/express/virtualFile.I')
+CopyFile('built/include/','panda/src/express/virtualFileList.I')
+CopyFile('built/include/','panda/src/express/virtualFileList.h')
+CopyFile('built/include/','panda/src/express/virtualFileMount.h')
+CopyFile('built/include/','panda/src/express/virtualFileMount.I')
+CopyFile('built/include/','panda/src/express/virtualFileMountMultifile.h')
+CopyFile('built/include/','panda/src/express/virtualFileMountMultifile.I')
+CopyFile('built/include/','panda/src/express/virtualFileMountSystem.h')
+CopyFile('built/include/','panda/src/express/virtualFileMountSystem.I')
+CopyFile('built/include/','panda/src/express/virtualFileSimple.h')
+CopyFile('built/include/','panda/src/express/virtualFileSimple.I')
+CopyFile('built/include/','panda/src/express/virtualFileSystem.h')
+CopyFile('built/include/','panda/src/express/virtualFileSystem.I')
+CopyFile('built/include/','panda/src/express/weakPointerTo.I')
+CopyFile('built/include/','panda/src/express/weakPointerTo.h')
+CopyFile('built/include/','panda/src/express/weakPointerToBase.I')
+CopyFile('built/include/','panda/src/express/weakPointerToBase.h')
+CopyFile('built/include/','panda/src/express/weakPointerToVoid.I')
+CopyFile('built/include/','panda/src/express/weakPointerToVoid.h')
+CopyFile('built/include/','panda/src/express/weakReferenceList.I')
+CopyFile('built/include/','panda/src/express/weakReferenceList.h')
+CopyFile('built/include/','panda/src/express/windowsRegistry.h')
+CopyFile('built/include/','panda/src/express/zStream.I')
+CopyFile('built/include/','panda/src/express/zStream.h')
+CopyFile('built/include/','panda/src/express/zStreamBuf.h')
+CopyFile('built/include/','panda/src/downloader/asyncUtility.h')
+CopyFile('built/include/','panda/src/downloader/asyncUtility.I')
+CopyFile('built/include/','panda/src/downloader/bioPtr.I')
+CopyFile('built/include/','panda/src/downloader/bioPtr.h')
+CopyFile('built/include/','panda/src/downloader/bioStreamPtr.I')
+CopyFile('built/include/','panda/src/downloader/bioStreamPtr.h')
+CopyFile('built/include/','panda/src/downloader/bioStream.I')
+CopyFile('built/include/','panda/src/downloader/bioStream.h')
+CopyFile('built/include/','panda/src/downloader/bioStreamBuf.h')
+CopyFile('built/include/','panda/src/downloader/chunkedStream.I')
+CopyFile('built/include/','panda/src/downloader/chunkedStream.h')
+CopyFile('built/include/','panda/src/downloader/chunkedStreamBuf.h')
+CopyFile('built/include/','panda/src/downloader/config_downloader.h')
+CopyFile('built/include/','panda/src/downloader/decompressor.h')
+CopyFile('built/include/','panda/src/downloader/decompressor.I')
+CopyFile('built/include/','panda/src/downloader/documentSpec.h')
+CopyFile('built/include/','panda/src/downloader/documentSpec.I')
+CopyFile('built/include/','panda/src/downloader/download_utils.h')
+CopyFile('built/include/','panda/src/downloader/downloadDb.h')
+CopyFile('built/include/','panda/src/downloader/downloadDb.I')
+CopyFile('built/include/','panda/src/downloader/extractor.h')
+CopyFile('built/include/','panda/src/downloader/httpAuthorization.I')
+CopyFile('built/include/','panda/src/downloader/httpAuthorization.h')
+CopyFile('built/include/','panda/src/downloader/httpBasicAuthorization.I')
+CopyFile('built/include/','panda/src/downloader/httpBasicAuthorization.h')
+CopyFile('built/include/','panda/src/downloader/httpChannel.I')
+CopyFile('built/include/','panda/src/downloader/httpChannel.h')
+CopyFile('built/include/','panda/src/downloader/httpClient.I')
+CopyFile('built/include/','panda/src/downloader/httpClient.h')
+CopyFile('built/include/','panda/src/downloader/httpCookie.I')
+CopyFile('built/include/','panda/src/downloader/httpCookie.h')
+CopyFile('built/include/','panda/src/downloader/httpDate.I')
+CopyFile('built/include/','panda/src/downloader/httpDate.h')
+CopyFile('built/include/','panda/src/downloader/httpDigestAuthorization.I')
+CopyFile('built/include/','panda/src/downloader/httpDigestAuthorization.h')
+CopyFile('built/include/','panda/src/downloader/httpEntityTag.I')
+CopyFile('built/include/','panda/src/downloader/httpEntityTag.h')
+CopyFile('built/include/','panda/src/downloader/httpEnum.h')
+CopyFile('built/include/','panda/src/downloader/identityStream.I')
+CopyFile('built/include/','panda/src/downloader/identityStream.h')
+CopyFile('built/include/','panda/src/downloader/identityStreamBuf.h')
+CopyFile('built/include/','panda/src/downloader/multiplexStream.I')
+CopyFile('built/include/','panda/src/downloader/multiplexStream.h')
+CopyFile('built/include/','panda/src/downloader/multiplexStreamBuf.I')
+CopyFile('built/include/','panda/src/downloader/multiplexStreamBuf.h')
+CopyFile('built/include/','panda/src/downloader/patcher.h')
+CopyFile('built/include/','panda/src/downloader/patcher.I')
+CopyFile('built/include/','panda/src/downloader/socketStream.h')
+CopyFile('built/include/','panda/src/downloader/socketStream.I')
+CopyFile('built/include/','panda/src/downloader/ssl_utils.h')
+CopyFile('built/include/','panda/src/downloader/urlSpec.h')
+CopyFile('built/include/','panda/src/downloader/urlSpec.I')
+CopyFile('built/include/','panda/src/putil/bam.h')
+CopyFile('built/include/','panda/src/putil/bamReader.I')
+CopyFile('built/include/','panda/src/putil/bamReader.h')
+CopyFile('built/include/','panda/src/putil/bamReaderParam.I')
+CopyFile('built/include/','panda/src/putil/bamReaderParam.h')
+CopyFile('built/include/','panda/src/putil/bamWriter.I')
+CopyFile('built/include/','panda/src/putil/bamWriter.h')
+CopyFile('built/include/','panda/src/putil/bitMask.I')
+CopyFile('built/include/','panda/src/putil/bitMask.h')
+CopyFile('built/include/','panda/src/putil/buttonHandle.I')
+CopyFile('built/include/','panda/src/putil/buttonHandle.h')
+CopyFile('built/include/','panda/src/putil/buttonRegistry.I')
+CopyFile('built/include/','panda/src/putil/buttonRegistry.h')
+CopyFile('built/include/','panda/src/putil/collideMask.h')
+CopyFile('built/include/','panda/src/putil/portalMask.h')
+CopyFile('built/include/','panda/src/putil/compareTo.I')
+CopyFile('built/include/','panda/src/putil/compareTo.h')
+CopyFile('built/include/','panda/src/putil/config_util.h')
+CopyFile('built/include/','panda/src/putil/configurable.h')
+CopyFile('built/include/','panda/src/putil/factory.I')
+CopyFile('built/include/','panda/src/putil/factory.h')
+CopyFile('built/include/','panda/src/putil/cachedTypedWritableReferenceCount.h')
+CopyFile('built/include/','panda/src/putil/cachedTypedWritableReferenceCount.I')
+CopyFile('built/include/','panda/src/putil/cycleData.h')
+CopyFile('built/include/','panda/src/putil/cycleData.I')
+CopyFile('built/include/','panda/src/putil/cycleDataReader.h')
+CopyFile('built/include/','panda/src/putil/cycleDataReader.I')
+CopyFile('built/include/','panda/src/putil/cycleDataWriter.h')
+CopyFile('built/include/','panda/src/putil/cycleDataWriter.I')
+CopyFile('built/include/','panda/src/putil/datagramInputFile.I')
+CopyFile('built/include/','panda/src/putil/datagramInputFile.h')
+CopyFile('built/include/','panda/src/putil/datagramOutputFile.I')
+CopyFile('built/include/','panda/src/putil/datagramOutputFile.h')
+CopyFile('built/include/','panda/src/putil/drawMask.h')
+CopyFile('built/include/','panda/src/putil/factoryBase.I')
+CopyFile('built/include/','panda/src/putil/factoryBase.h')
+CopyFile('built/include/','panda/src/putil/factoryParam.I')
+CopyFile('built/include/','panda/src/putil/factoryParam.h')
+CopyFile('built/include/','panda/src/putil/factoryParams.I')
+CopyFile('built/include/','panda/src/putil/factoryParams.h')
+CopyFile('built/include/','panda/src/putil/firstOfPairCompare.I')
+CopyFile('built/include/','panda/src/putil/firstOfPairCompare.h')
+CopyFile('built/include/','panda/src/putil/firstOfPairLess.I')
+CopyFile('built/include/','panda/src/putil/firstOfPairLess.h')
+CopyFile('built/include/','panda/src/putil/globalPointerRegistry.I')
+CopyFile('built/include/','panda/src/putil/globalPointerRegistry.h')
+CopyFile('built/include/','panda/src/putil/indirectCompareNames.I')
+CopyFile('built/include/','panda/src/putil/indirectCompareNames.h')
+CopyFile('built/include/','panda/src/putil/indirectCompareTo.I')
+CopyFile('built/include/','panda/src/putil/indirectCompareTo.h')
+CopyFile('built/include/','panda/src/putil/ioPtaDatagramFloat.h')
+CopyFile('built/include/','panda/src/putil/ioPtaDatagramInt.h')
+CopyFile('built/include/','panda/src/putil/ioPtaDatagramShort.h')
+CopyFile('built/include/','panda/src/putil/iterator_types.h')
+CopyFile('built/include/','panda/src/putil/keyboardButton.h')
+CopyFile('built/include/','panda/src/putil/lineStream.I')
+CopyFile('built/include/','panda/src/putil/lineStream.h')
+CopyFile('built/include/','panda/src/putil/lineStreamBuf.I')
+CopyFile('built/include/','panda/src/putil/lineStreamBuf.h')
+CopyFile('built/include/','panda/src/putil/load_prc_file.h')
+CopyFile('built/include/','panda/src/putil/modifierButtons.I')
+CopyFile('built/include/','panda/src/putil/modifierButtons.h')
+CopyFile('built/include/','panda/src/putil/mouseButton.h')
+CopyFile('built/include/','panda/src/putil/mouseData.I')
+CopyFile('built/include/','panda/src/putil/mouseData.h')
+CopyFile('built/include/','panda/src/putil/nameUniquifier.I')
+CopyFile('built/include/','panda/src/putil/nameUniquifier.h')
+CopyFile('built/include/','panda/src/putil/pipeline.h')
+CopyFile('built/include/','panda/src/putil/pipeline.I')
+CopyFile('built/include/','panda/src/putil/pipelineCycler.h')
+CopyFile('built/include/','panda/src/putil/pipelineCycler.I')
+CopyFile('built/include/','panda/src/putil/pipelineCyclerBase.h')
+CopyFile('built/include/','panda/src/putil/pipelineCyclerBase.I')
+CopyFile('built/include/','panda/src/putil/pta_double.h')
+CopyFile('built/include/','panda/src/putil/pta_float.h')
+CopyFile('built/include/','panda/src/putil/pta_int.h')
+CopyFile('built/include/','panda/src/putil/pta_ushort.h')
+CopyFile('built/include/','panda/src/putil/string_utils.I')
+CopyFile('built/include/','panda/src/putil/string_utils.h')
+CopyFile('built/include/','panda/src/putil/timedCycle.I')
+CopyFile('built/include/','panda/src/putil/timedCycle.h')
+CopyFile('built/include/','panda/src/putil/typedWritable.I')
+CopyFile('built/include/','panda/src/putil/typedWritable.h')
+CopyFile('built/include/','panda/src/putil/typedWritableReferenceCount.I')
+CopyFile('built/include/','panda/src/putil/typedWritableReferenceCount.h')
+CopyFile('built/include/','panda/src/putil/updateSeq.I')
+CopyFile('built/include/','panda/src/putil/updateSeq.h')
+CopyFile('built/include/','panda/src/putil/uniqueIdAllocator.h')
+CopyFile('built/include/','panda/src/putil/vector_double.h')
+CopyFile('built/include/','panda/src/putil/vector_float.h')
+CopyFile('built/include/','panda/src/putil/vector_typedWritable.h')
+CopyFile('built/include/','panda/src/putil/vector_ushort.h')
+CopyFile('built/include/','panda/src/putil/vector_writable.h')
+CopyFile('built/include/','panda/src/putil/writableConfigurable.h')
+CopyFile('built/include/','panda/src/putil/writableParam.I')
+CopyFile('built/include/','panda/src/putil/writableParam.h')
+CopyFile('built/include/','panda/src/audio/config_audio.h')
+CopyFile('built/include/','panda/src/audio/audio.h')
+CopyFile('built/include/','panda/src/audio/audioManager.h')
+CopyFile('built/include/','panda/src/audio/audioSound.h')
+CopyFile('built/include/','panda/src/audio/nullAudioManager.h')
+CopyFile('built/include/','panda/src/audio/nullAudioSound.h')
+CopyFile('built/include/','panda/src/event/buttonEvent.I')
+CopyFile('built/include/','panda/src/event/buttonEvent.h')
+CopyFile('built/include/','panda/src/event/buttonEventList.I')
+CopyFile('built/include/','panda/src/event/buttonEventList.h')
+CopyFile('built/include/','panda/src/event/event.I')
+CopyFile('built/include/','panda/src/event/event.h')
+CopyFile('built/include/','panda/src/event/eventHandler.h')
+CopyFile('built/include/','panda/src/event/eventHandler.I')
+CopyFile('built/include/','panda/src/event/eventParameter.I')
+CopyFile('built/include/','panda/src/event/eventParameter.h')
+CopyFile('built/include/','panda/src/event/eventQueue.I')
+CopyFile('built/include/','panda/src/event/eventQueue.h')
+CopyFile('built/include/','panda/src/event/eventReceiver.h')
+CopyFile('built/include/','panda/src/event/pt_Event.h')
+CopyFile('built/include/','panda/src/event/throw_event.I')
+CopyFile('built/include/','panda/src/event/throw_event.h')
+CopyFile('built/include/','panda/src/linmath/compose_matrix.h')
+CopyFile('built/include/','panda/src/linmath/compose_matrix_src.I')
+CopyFile('built/include/','panda/src/linmath/compose_matrix_src.h')
+CopyFile('built/include/','panda/src/linmath/config_linmath.h')
+CopyFile('built/include/','panda/src/linmath/coordinateSystem.h')
+CopyFile('built/include/','panda/src/linmath/dbl2fltnames.h')
+CopyFile('built/include/','panda/src/linmath/dblnames.h')
+CopyFile('built/include/','panda/src/linmath/deg_2_rad.h')
+CopyFile('built/include/','panda/src/linmath/flt2dblnames.h')
+CopyFile('built/include/','panda/src/linmath/fltnames.h')
+CopyFile('built/include/','panda/src/linmath/ioPtaDatagramLinMath.I')
+CopyFile('built/include/','panda/src/linmath/ioPtaDatagramLinMath.h')
+CopyFile('built/include/','panda/src/linmath/lcast_to.h')
+CopyFile('built/include/','panda/src/linmath/lcast_to_src.I')
+CopyFile('built/include/','panda/src/linmath/lcast_to_src.h')
+CopyFile('built/include/','panda/src/linmath/lmat_ops.h')
+CopyFile('built/include/','panda/src/linmath/lmat_ops_src.I')
+CopyFile('built/include/','panda/src/linmath/lmat_ops_src.h')
+CopyFile('built/include/','panda/src/linmath/lmatrix.h')
+CopyFile('built/include/','panda/src/linmath/lmatrix3.h')
+CopyFile('built/include/','panda/src/linmath/lmatrix3_src.I')
+CopyFile('built/include/','panda/src/linmath/lmatrix3_src.h')
+CopyFile('built/include/','panda/src/linmath/lmatrix4.h')
+CopyFile('built/include/','panda/src/linmath/lmatrix4_src.I')
+CopyFile('built/include/','panda/src/linmath/lmatrix4_src.h')
+CopyFile('built/include/','panda/src/linmath/lorientation.h')
+CopyFile('built/include/','panda/src/linmath/lorientation_src.I')
+CopyFile('built/include/','panda/src/linmath/lorientation_src.h')
+CopyFile('built/include/','panda/src/linmath/lpoint2.h')
+CopyFile('built/include/','panda/src/linmath/lpoint2_src.I')
+CopyFile('built/include/','panda/src/linmath/lpoint2_src.h')
+CopyFile('built/include/','panda/src/linmath/lpoint3.h')
+CopyFile('built/include/','panda/src/linmath/lpoint3_src.I')
+CopyFile('built/include/','panda/src/linmath/lpoint3_src.h')
+CopyFile('built/include/','panda/src/linmath/lpoint4.h')
+CopyFile('built/include/','panda/src/linmath/lpoint4_src.I')
+CopyFile('built/include/','panda/src/linmath/lpoint4_src.h')
+CopyFile('built/include/','panda/src/linmath/lquaternion.h')
+CopyFile('built/include/','panda/src/linmath/lquaternion_src.I')
+CopyFile('built/include/','panda/src/linmath/lquaternion_src.h')
+CopyFile('built/include/','panda/src/linmath/lrotation.h')
+CopyFile('built/include/','panda/src/linmath/lrotation_src.I')
+CopyFile('built/include/','panda/src/linmath/lrotation_src.h')
+CopyFile('built/include/','panda/src/linmath/luse.I')
+CopyFile('built/include/','panda/src/linmath/luse.h')
+CopyFile('built/include/','panda/src/linmath/lvec2_ops.h')
+CopyFile('built/include/','panda/src/linmath/lvec2_ops_src.I')
+CopyFile('built/include/','panda/src/linmath/lvec2_ops_src.h')
+CopyFile('built/include/','panda/src/linmath/lvec3_ops.h')
+CopyFile('built/include/','panda/src/linmath/lvec3_ops_src.I')
+CopyFile('built/include/','panda/src/linmath/lvec3_ops_src.h')
+CopyFile('built/include/','panda/src/linmath/lvec4_ops.h')
+CopyFile('built/include/','panda/src/linmath/lvec4_ops_src.I')
+CopyFile('built/include/','panda/src/linmath/lvec4_ops_src.h')
+CopyFile('built/include/','panda/src/linmath/lvecBase2.h')
+CopyFile('built/include/','panda/src/linmath/lvecBase2_src.I')
+CopyFile('built/include/','panda/src/linmath/lvecBase2_src.h')
+CopyFile('built/include/','panda/src/linmath/lvecBase3.h')
+CopyFile('built/include/','panda/src/linmath/lvecBase3_src.I')
+CopyFile('built/include/','panda/src/linmath/lvecBase3_src.h')
+CopyFile('built/include/','panda/src/linmath/lvecBase4.h')
+CopyFile('built/include/','panda/src/linmath/lvecBase4_src.I')
+CopyFile('built/include/','panda/src/linmath/lvecBase4_src.h')
+CopyFile('built/include/','panda/src/linmath/lvector2.h')
+CopyFile('built/include/','panda/src/linmath/lvector2_src.I')
+CopyFile('built/include/','panda/src/linmath/lvector2_src.h')
+CopyFile('built/include/','panda/src/linmath/lvector3.h')
+CopyFile('built/include/','panda/src/linmath/lvector3_src.I')
+CopyFile('built/include/','panda/src/linmath/lvector3_src.h')
+CopyFile('built/include/','panda/src/linmath/lvector4.h')
+CopyFile('built/include/','panda/src/linmath/lvector4_src.I')
+CopyFile('built/include/','panda/src/linmath/lvector4_src.h')
+CopyFile('built/include/','panda/src/linmath/mathNumbers.h')
+CopyFile('built/include/','panda/src/linmath/mathNumbers.I')
+CopyFile('built/include/','panda/src/linmath/pta_Colorf.h')
+CopyFile('built/include/','panda/src/linmath/pta_Normalf.h')
+CopyFile('built/include/','panda/src/linmath/pta_TexCoordf.h')
+CopyFile('built/include/','panda/src/linmath/pta_Vertexf.h')
+CopyFile('built/include/','panda/src/linmath/vector_Colorf.h')
+CopyFile('built/include/','panda/src/linmath/vector_LPoint2f.h')
+CopyFile('built/include/','panda/src/linmath/vector_LVecBase3f.h')
+CopyFile('built/include/','panda/src/linmath/vector_Normalf.h')
+CopyFile('built/include/','panda/src/linmath/vector_TexCoordf.h')
+CopyFile('built/include/','panda/src/linmath/vector_Vertexf.h')
+CopyFile('built/include/','panda/src/mathutil/boundingHexahedron.I')
+CopyFile('built/include/','panda/src/mathutil/boundingHexahedron.h')
+CopyFile('built/include/','panda/src/mathutil/boundingLine.I')
+CopyFile('built/include/','panda/src/mathutil/boundingLine.h')
+CopyFile('built/include/','panda/src/mathutil/boundingSphere.I')
+CopyFile('built/include/','panda/src/mathutil/boundingSphere.h')
+CopyFile('built/include/','panda/src/mathutil/boundingVolume.I')
+CopyFile('built/include/','panda/src/mathutil/boundingVolume.h')
+CopyFile('built/include/','panda/src/mathutil/config_mathutil.h')
+CopyFile('built/include/','panda/src/mathutil/fftCompressor.h')
+CopyFile('built/include/','panda/src/mathutil/finiteBoundingVolume.h')
+CopyFile('built/include/','panda/src/mathutil/frustum.h')
+CopyFile('built/include/','panda/src/mathutil/frustum_src.I')
+CopyFile('built/include/','panda/src/mathutil/frustum_src.h')
+CopyFile('built/include/','panda/src/mathutil/geometricBoundingVolume.I')
+CopyFile('built/include/','panda/src/mathutil/geometricBoundingVolume.h')
+CopyFile('built/include/','panda/src/mathutil/look_at.h')
+CopyFile('built/include/','panda/src/mathutil/look_at_src.I')
+CopyFile('built/include/','panda/src/mathutil/look_at_src.h')
+CopyFile('built/include/','panda/src/mathutil/linmath_events.h')
+CopyFile('built/include/','panda/src/mathutil/mathHelpers.I')
+CopyFile('built/include/','panda/src/mathutil/mathHelpers.h')
+CopyFile('built/include/','panda/src/mathutil/omniBoundingVolume.I')
+CopyFile('built/include/','panda/src/mathutil/omniBoundingVolume.h')
+CopyFile('built/include/','panda/src/mathutil/plane.h')
+CopyFile('built/include/','panda/src/mathutil/plane_src.I')
+CopyFile('built/include/','panda/src/mathutil/plane_src.h')
+CopyFile('built/include/','panda/src/mathutil/rotate_to.h')
+CopyFile('built/include/','panda/src/gsgbase/graphicsStateGuardianBase.h')
+CopyFile('built/include/','panda/src/pnmimage/config_pnmimage.h')
+CopyFile('built/include/','panda/src/pnmimage/pnmFileType.h')
+CopyFile('built/include/','panda/src/pnmimage/pnmFileTypeRegistry.h')
+CopyFile('built/include/','panda/src/pnmimage/pnmImage.I')
+CopyFile('built/include/','panda/src/pnmimage/pnmImage.h')
+CopyFile('built/include/','panda/src/pnmimage/pnmImageHeader.I')
+CopyFile('built/include/','panda/src/pnmimage/pnmImageHeader.h')
+CopyFile('built/include/','panda/src/pnmimage/pnmReader.I')
+CopyFile('built/include/','panda/src/pnmimage/pnmReader.h')
+CopyFile('built/include/','panda/src/pnmimage/pnmWriter.I')
+CopyFile('built/include/','panda/src/pnmimage/pnmWriter.h')
+CopyFile('built/include/','panda/src/pnmimage/pnmimage_base.h')
+CopyFile('built/include/','panda/src/pnmimagetypes/sgi.h')
+CopyFile('built/include/','panda/src/net/config_net.h')
+CopyFile('built/include/','panda/src/net/connection.h')
+CopyFile('built/include/','panda/src/net/connectionListener.h')
+CopyFile('built/include/','panda/src/net/connectionManager.h')
+CopyFile('built/include/','panda/src/net/connectionReader.h')
+CopyFile('built/include/','panda/src/net/connectionWriter.h')
+CopyFile('built/include/','panda/src/net/datagramQueue.h')
+CopyFile('built/include/','panda/src/net/datagramTCPHeader.I')
+CopyFile('built/include/','panda/src/net/datagramTCPHeader.h')
+CopyFile('built/include/','panda/src/net/datagramUDPHeader.I')
+CopyFile('built/include/','panda/src/net/datagramUDPHeader.h')
+CopyFile('built/include/','panda/src/net/netAddress.h')
+CopyFile('built/include/','panda/src/net/netDatagram.I')
+CopyFile('built/include/','panda/src/net/netDatagram.h')
+CopyFile('built/include/','panda/src/net/pprerror.h')
+CopyFile('built/include/','panda/src/net/queuedConnectionListener.I')
+CopyFile('built/include/','panda/src/net/queuedConnectionListener.h')
+CopyFile('built/include/','panda/src/net/queuedConnectionManager.h')
+CopyFile('built/include/','panda/src/net/queuedConnectionReader.h')
+CopyFile('built/include/','panda/src/net/queuedReturn.I')
+CopyFile('built/include/','panda/src/net/queuedReturn.h')
+CopyFile('built/include/','panda/src/net/recentConnectionReader.h')
+CopyFile('built/include/','panda/src/pstatclient/config_pstats.h')
+CopyFile('built/include/','panda/src/pstatclient/pStatClient.I')
+CopyFile('built/include/','panda/src/pstatclient/pStatClient.h')
+CopyFile('built/include/','panda/src/pstatclient/pStatClientImpl.I')
+CopyFile('built/include/','panda/src/pstatclient/pStatClientImpl.h')
+CopyFile('built/include/','panda/src/pstatclient/pStatClientVersion.I')
+CopyFile('built/include/','panda/src/pstatclient/pStatClientVersion.h')
+CopyFile('built/include/','panda/src/pstatclient/pStatClientControlMessage.h')
+CopyFile('built/include/','panda/src/pstatclient/pStatCollector.I')
+CopyFile('built/include/','panda/src/pstatclient/pStatCollector.h')
+CopyFile('built/include/','panda/src/pstatclient/pStatCollectorDef.h')
+CopyFile('built/include/','panda/src/pstatclient/pStatFrameData.I')
+CopyFile('built/include/','panda/src/pstatclient/pStatFrameData.h')
+CopyFile('built/include/','panda/src/pstatclient/pStatProperties.h')
+CopyFile('built/include/','panda/src/pstatclient/pStatServerControlMessage.h')
+CopyFile('built/include/','panda/src/pstatclient/pStatThread.I')
+CopyFile('built/include/','panda/src/pstatclient/pStatThread.h')
+CopyFile('built/include/','panda/src/pstatclient/pStatTimer.I')
+CopyFile('built/include/','panda/src/pstatclient/pStatTimer.h')
+CopyFile('built/include/','panda/src/gobj/boundedObject.I')
+CopyFile('built/include/','panda/src/gobj/boundedObject.h')
+CopyFile('built/include/','panda/src/gobj/config_gobj.h')
+CopyFile('built/include/','panda/src/gobj/drawable.h')
+CopyFile('built/include/','panda/src/gobj/geom.I')
+CopyFile('built/include/','panda/src/gobj/geom.h')
+CopyFile('built/include/','panda/src/gobj/textureContext.I')
+CopyFile('built/include/','panda/src/gobj/textureContext.h')
+CopyFile('built/include/','panda/src/gobj/geomLine.h')
+CopyFile('built/include/','panda/src/gobj/geomLinestrip.h')
+CopyFile('built/include/','panda/src/gobj/geomPoint.h')
+CopyFile('built/include/','panda/src/gobj/geomPolygon.h')
+CopyFile('built/include/','panda/src/gobj/geomQuad.h')
+CopyFile('built/include/','panda/src/gobj/geomSphere.h')
+CopyFile('built/include/','panda/src/gobj/geomSprite.I')
+CopyFile('built/include/','panda/src/gobj/geomSprite.h')
+CopyFile('built/include/','panda/src/gobj/geomTri.h')
+CopyFile('built/include/','panda/src/gobj/geomTrifan.h')
+CopyFile('built/include/','panda/src/gobj/geomTristrip.h')
+CopyFile('built/include/','panda/src/gobj/geomprimitives.h')
+CopyFile('built/include/','panda/src/gobj/imageBuffer.I')
+CopyFile('built/include/','panda/src/gobj/imageBuffer.h')
+CopyFile('built/include/','panda/src/gobj/material.I')
+CopyFile('built/include/','panda/src/gobj/material.h')
+CopyFile('built/include/','panda/src/gobj/materialPool.I')
+CopyFile('built/include/','panda/src/gobj/materialPool.h')
+CopyFile('built/include/','panda/src/gobj/matrixLens.I')
+CopyFile('built/include/','panda/src/gobj/matrixLens.h')
+CopyFile('built/include/','panda/src/gobj/orthographicLens.I')
+CopyFile('built/include/','panda/src/gobj/orthographicLens.h')
+CopyFile('built/include/','panda/src/gobj/perspectiveLens.I')
+CopyFile('built/include/','panda/src/gobj/perspectiveLens.h')
+CopyFile('built/include/','panda/src/gobj/pixelBuffer.I')
+CopyFile('built/include/','panda/src/gobj/pixelBuffer.h')
+CopyFile('built/include/','panda/src/gobj/preparedGraphicsObjects.I')
+CopyFile('built/include/','panda/src/gobj/preparedGraphicsObjects.h')
+CopyFile('built/include/','panda/src/gobj/lens.h')
+CopyFile('built/include/','panda/src/gobj/lens.I')
+CopyFile('built/include/','panda/src/gobj/savedContext.I')
+CopyFile('built/include/','panda/src/gobj/savedContext.h')
+CopyFile('built/include/','panda/src/gobj/texture.I')
+CopyFile('built/include/','panda/src/gobj/texture.h')
+CopyFile('built/include/','panda/src/gobj/texturePool.I')
+CopyFile('built/include/','panda/src/gobj/texturePool.h')
+CopyFile('built/include/','panda/src/gobj/texCoordName.I')
+CopyFile('built/include/','panda/src/gobj/texCoordName.h')
+CopyFile('built/include/','panda/src/gobj/textureStage.I')
+CopyFile('built/include/','panda/src/gobj/textureStage.h')
+CopyFile('built/include/','panda/src/lerp/lerp.h')
+CopyFile('built/include/','panda/src/lerp/lerpblend.h')
+CopyFile('built/include/','panda/src/lerp/lerpfunctor.h')
+CopyFile('built/include/','panda/src/pgraph/accumulatedAttribs.I')
+CopyFile('built/include/','panda/src/pgraph/accumulatedAttribs.h')
+CopyFile('built/include/','panda/src/pgraph/alphaTestAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/alphaTestAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/antialiasAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/antialiasAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/ambientLight.I')
+CopyFile('built/include/','panda/src/pgraph/ambientLight.h')
+CopyFile('built/include/','panda/src/pgraph/auxSceneData.I')
+CopyFile('built/include/','panda/src/pgraph/auxSceneData.h')
+CopyFile('built/include/','panda/src/pgraph/bamFile.I')
+CopyFile('built/include/','panda/src/pgraph/bamFile.h')
+CopyFile('built/include/','panda/src/pgraph/billboardEffect.I')
+CopyFile('built/include/','panda/src/pgraph/billboardEffect.h')
+CopyFile('built/include/','panda/src/pgraph/binCullHandler.I')
+CopyFile('built/include/','panda/src/pgraph/binCullHandler.h')
+CopyFile('built/include/','panda/src/pgraph/camera.I')
+CopyFile('built/include/','panda/src/pgraph/camera.h')
+CopyFile('built/include/','panda/src/pgraph/clipPlaneAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/clipPlaneAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/colorAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/colorAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/colorBlendAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/colorBlendAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/colorScaleAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/colorScaleAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/colorWriteAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/colorWriteAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/compassEffect.I')
+CopyFile('built/include/','panda/src/pgraph/compassEffect.h')
+CopyFile('built/include/','panda/src/pgraph/config_pgraph.h')
+CopyFile('built/include/','panda/src/pgraph/cullBin.I')
+CopyFile('built/include/','panda/src/pgraph/cullBin.h')
+CopyFile('built/include/','panda/src/pgraph/cullBinAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/cullBinAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/cullBinBackToFront.I')
+CopyFile('built/include/','panda/src/pgraph/cullBinBackToFront.h')
+CopyFile('built/include/','panda/src/pgraph/cullBinFixed.I')
+CopyFile('built/include/','panda/src/pgraph/cullBinFixed.h')
+CopyFile('built/include/','panda/src/pgraph/cullBinFrontToBack.I')
+CopyFile('built/include/','panda/src/pgraph/cullBinFrontToBack.h')
+CopyFile('built/include/','panda/src/pgraph/cullBinManager.I')
+CopyFile('built/include/','panda/src/pgraph/cullBinManager.h')
+CopyFile('built/include/','panda/src/pgraph/cullBinUnsorted.I')
+CopyFile('built/include/','panda/src/pgraph/cullBinUnsorted.h')
+CopyFile('built/include/','panda/src/pgraph/cullFaceAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/cullFaceAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/cullHandler.I')
+CopyFile('built/include/','panda/src/pgraph/cullHandler.h')
+CopyFile('built/include/','panda/src/pgraph/cullResult.I')
+CopyFile('built/include/','panda/src/pgraph/cullResult.h')
+CopyFile('built/include/','panda/src/pgraph/cullTraverser.I')
+CopyFile('built/include/','panda/src/pgraph/cullTraverser.h')
+CopyFile('built/include/','panda/src/pgraph/cullTraverserData.I')
+CopyFile('built/include/','panda/src/pgraph/cullTraverserData.h')
+CopyFile('built/include/','panda/src/pgraph/cullableObject.I')
+CopyFile('built/include/','panda/src/pgraph/cullableObject.h')
+CopyFile('built/include/','panda/src/pgraph/decalEffect.I')
+CopyFile('built/include/','panda/src/pgraph/decalEffect.h')
+CopyFile('built/include/','panda/src/pgraph/depthOffsetAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/depthOffsetAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/depthTestAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/depthTestAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/depthWriteAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/depthWriteAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/directionalLight.I')
+CopyFile('built/include/','panda/src/pgraph/directionalLight.h')
+CopyFile('built/include/','panda/src/pgraph/drawCullHandler.I')
+CopyFile('built/include/','panda/src/pgraph/drawCullHandler.h')
+CopyFile('built/include/','panda/src/pgraph/fadeLodNode.I')
+CopyFile('built/include/','panda/src/pgraph/fadeLodNode.h')
+CopyFile('built/include/','panda/src/pgraph/fadeLodNodeData.h')
+CopyFile('built/include/','panda/src/pgraph/fog.I')
+CopyFile('built/include/','panda/src/pgraph/fog.h')
+CopyFile('built/include/','panda/src/pgraph/fogAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/fogAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/geomNode.I')
+CopyFile('built/include/','panda/src/pgraph/geomNode.h')
+CopyFile('built/include/','panda/src/pgraph/geomTransformer.I')
+CopyFile('built/include/','panda/src/pgraph/geomTransformer.h')
+CopyFile('built/include/','panda/src/pgraph/lensNode.I')
+CopyFile('built/include/','panda/src/pgraph/lensNode.h')
+CopyFile('built/include/','panda/src/pgraph/light.I')
+CopyFile('built/include/','panda/src/pgraph/light.h')
+CopyFile('built/include/','panda/src/pgraph/lightAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/lightAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/lightLensNode.I')
+CopyFile('built/include/','panda/src/pgraph/lightLensNode.h')
+CopyFile('built/include/','panda/src/pgraph/lightNode.I')
+CopyFile('built/include/','panda/src/pgraph/lightNode.h')
+CopyFile('built/include/','panda/src/pgraph/loader.I')
+CopyFile('built/include/','panda/src/pgraph/loader.h')
+CopyFile('built/include/','panda/src/pgraph/loaderFileType.h')
+CopyFile('built/include/','panda/src/pgraph/loaderFileTypeBam.h')
+CopyFile('built/include/','panda/src/pgraph/loaderFileTypeRegistry.h')
+CopyFile('built/include/','panda/src/pgraph/lodNode.I')
+CopyFile('built/include/','panda/src/pgraph/lodNode.h')
+CopyFile('built/include/','panda/src/pgraph/materialAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/materialAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/modelNode.I')
+CopyFile('built/include/','panda/src/pgraph/modelNode.h')
+CopyFile('built/include/','panda/src/pgraph/modelPool.I')
+CopyFile('built/include/','panda/src/pgraph/modelPool.h')
+CopyFile('built/include/','panda/src/pgraph/modelRoot.I')
+CopyFile('built/include/','panda/src/pgraph/modelRoot.h')
+CopyFile('built/include/','panda/src/pgraph/nodePath.I')
+CopyFile('built/include/','panda/src/pgraph/nodePath.h')
+CopyFile('built/include/','panda/src/pgraph/nodePathCollection.I')
+CopyFile('built/include/','panda/src/pgraph/nodePathCollection.h')
+CopyFile('built/include/','panda/src/pgraph/nodePathComponent.I')
+CopyFile('built/include/','panda/src/pgraph/nodePathComponent.h')
+CopyFile('built/include/','panda/src/pgraph/nodePathLerps.h')
+CopyFile('built/include/','panda/src/pgraph/pandaNode.I')
+CopyFile('built/include/','panda/src/pgraph/pandaNode.h')
+CopyFile('built/include/','panda/src/pgraph/planeNode.I')
+CopyFile('built/include/','panda/src/pgraph/planeNode.h')
+CopyFile('built/include/','panda/src/pgraph/pointLight.I')
+CopyFile('built/include/','panda/src/pgraph/pointLight.h')
+CopyFile('built/include/','panda/src/pgraph/polylightNode.I')
+CopyFile('built/include/','panda/src/pgraph/polylightNode.h')
+CopyFile('built/include/','panda/src/pgraph/polylightEffect.I')
+CopyFile('built/include/','panda/src/pgraph/polylightEffect.h')
+CopyFile('built/include/','panda/src/pgraph/portalNode.I')
+CopyFile('built/include/','panda/src/pgraph/portalNode.h')
+CopyFile('built/include/','panda/src/pgraph/portalClipper.I')
+CopyFile('built/include/','panda/src/pgraph/portalClipper.h')
+CopyFile('built/include/','panda/src/pgraph/renderAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/renderAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/renderEffect.I')
+CopyFile('built/include/','panda/src/pgraph/renderEffect.h')
+CopyFile('built/include/','panda/src/pgraph/renderEffects.I')
+CopyFile('built/include/','panda/src/pgraph/renderEffects.h')
+CopyFile('built/include/','panda/src/pgraph/renderModeAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/renderModeAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/renderState.I')
+CopyFile('built/include/','panda/src/pgraph/renderState.h')
+CopyFile('built/include/','panda/src/pgraph/rescaleNormalAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/rescaleNormalAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/sceneGraphAnalyzer.h')
+CopyFile('built/include/','panda/src/pgraph/sceneGraphReducer.I')
+CopyFile('built/include/','panda/src/pgraph/sceneGraphReducer.h')
+CopyFile('built/include/','panda/src/pgraph/sceneSetup.I')
+CopyFile('built/include/','panda/src/pgraph/sceneSetup.h')
+CopyFile('built/include/','panda/src/pgraph/selectiveChildNode.I')
+CopyFile('built/include/','panda/src/pgraph/selectiveChildNode.h')
+CopyFile('built/include/','panda/src/pgraph/sequenceNode.I')
+CopyFile('built/include/','panda/src/pgraph/sequenceNode.h')
+CopyFile('built/include/','panda/src/pgraph/showBoundsEffect.I')
+CopyFile('built/include/','panda/src/pgraph/showBoundsEffect.h')
+CopyFile('built/include/','panda/src/pgraph/spotlight.I')
+CopyFile('built/include/','panda/src/pgraph/spotlight.h')
+CopyFile('built/include/','panda/src/pgraph/switchNode.I')
+CopyFile('built/include/','panda/src/pgraph/switchNode.h')
+CopyFile('built/include/','panda/src/pgraph/texMatrixAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/texMatrixAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/texProjectorEffect.I')
+CopyFile('built/include/','panda/src/pgraph/texProjectorEffect.h')
+CopyFile('built/include/','panda/src/pgraph/textureApplyAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/textureApplyAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/textureAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/textureAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/texGenAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/texGenAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/textureCollection.I')
+CopyFile('built/include/','panda/src/pgraph/textureCollection.h')
+CopyFile('built/include/','panda/src/pgraph/textureStageCollection.I')
+CopyFile('built/include/','panda/src/pgraph/textureStageCollection.h')
+CopyFile('built/include/','panda/src/pgraph/transformState.I')
+CopyFile('built/include/','panda/src/pgraph/transformState.h')
+CopyFile('built/include/','panda/src/pgraph/transparencyAttrib.I')
+CopyFile('built/include/','panda/src/pgraph/transparencyAttrib.h')
+CopyFile('built/include/','panda/src/pgraph/weakNodePath.I')
+CopyFile('built/include/','panda/src/pgraph/weakNodePath.h')
+CopyFile('built/include/','panda/src/pgraph/workingNodePath.I')
+CopyFile('built/include/','panda/src/pgraph/workingNodePath.h')
+CopyFile('built/include/','panda/src/chan/animBundle.I')
+CopyFile('built/include/','panda/src/chan/animBundle.h')
+CopyFile('built/include/','panda/src/chan/animBundleNode.I')
+CopyFile('built/include/','panda/src/chan/animBundleNode.h')
+CopyFile('built/include/','panda/src/chan/animChannel.I')
+CopyFile('built/include/','panda/src/chan/animChannel.h')
+CopyFile('built/include/','panda/src/chan/animChannelBase.I')
+CopyFile('built/include/','panda/src/chan/animChannelBase.h')
+CopyFile('built/include/','panda/src/chan/animChannelFixed.I')
+CopyFile('built/include/','panda/src/chan/animChannelFixed.h')
+CopyFile('built/include/','panda/src/chan/animChannelMatrixDynamic.I')
+CopyFile('built/include/','panda/src/chan/animChannelMatrixDynamic.h')
+CopyFile('built/include/','panda/src/chan/animChannelMatrixXfmTable.I')
+CopyFile('built/include/','panda/src/chan/animChannelMatrixXfmTable.h')
+CopyFile('built/include/','panda/src/chan/animChannelScalarDynamic.I')
+CopyFile('built/include/','panda/src/chan/animChannelScalarDynamic.h')
+CopyFile('built/include/','panda/src/chan/animChannelScalarTable.I')
+CopyFile('built/include/','panda/src/chan/animChannelScalarTable.h')
+CopyFile('built/include/','panda/src/chan/animControl.I')
+CopyFile('built/include/','panda/src/chan/animControl.h')
+CopyFile('built/include/','panda/src/chan/animControlCollection.I')
+CopyFile('built/include/','panda/src/chan/animControlCollection.h')
+CopyFile('built/include/','panda/src/chan/animGroup.I')
+CopyFile('built/include/','panda/src/chan/animGroup.h')
+CopyFile('built/include/','panda/src/chan/auto_bind.h')
+CopyFile('built/include/','panda/src/chan/config_chan.h')
+CopyFile('built/include/','panda/src/chan/movingPart.I')
+CopyFile('built/include/','panda/src/chan/movingPart.h')
+CopyFile('built/include/','panda/src/chan/movingPartBase.I')
+CopyFile('built/include/','panda/src/chan/movingPartBase.h')
+CopyFile('built/include/','panda/src/chan/movingPartMatrix.I')
+CopyFile('built/include/','panda/src/chan/movingPartMatrix.h')
+CopyFile('built/include/','panda/src/chan/movingPartScalar.I')
+CopyFile('built/include/','panda/src/chan/movingPartScalar.h')
+CopyFile('built/include/','panda/src/chan/partBundle.I')
+CopyFile('built/include/','panda/src/chan/partBundle.h')
+CopyFile('built/include/','panda/src/chan/partBundleNode.I')
+CopyFile('built/include/','panda/src/chan/partBundleNode.h')
+CopyFile('built/include/','panda/src/chan/partGroup.I')
+CopyFile('built/include/','panda/src/chan/partGroup.h')
+CopyFile('built/include/','panda/src/chan/vector_PartGroupStar.h')
+CopyFile('built/include/','panda/src/char/character.I')
+CopyFile('built/include/','panda/src/char/character.h')
+CopyFile('built/include/','panda/src/char/characterJoint.h')
+CopyFile('built/include/','panda/src/char/characterJointBundle.I')
+CopyFile('built/include/','panda/src/char/characterJointBundle.h')
+CopyFile('built/include/','panda/src/char/characterSlider.h')
+CopyFile('built/include/','panda/src/char/computedVertices.I')
+CopyFile('built/include/','panda/src/char/computedVertices.h')
+CopyFile('built/include/','panda/src/char/computedVerticesMorph.I')
+CopyFile('built/include/','panda/src/char/computedVerticesMorph.h')
+CopyFile('built/include/','panda/src/char/config_char.h')
+CopyFile('built/include/','panda/src/char/dynamicVertices.h')
+CopyFile('built/include/','panda/src/dgraph/config_dgraph.h')
+CopyFile('built/include/','panda/src/dgraph/dataGraphTraverser.I')
+CopyFile('built/include/','panda/src/dgraph/dataGraphTraverser.h')
+CopyFile('built/include/','panda/src/dgraph/dataNode.I')
+CopyFile('built/include/','panda/src/dgraph/dataNode.h')
+CopyFile('built/include/','panda/src/dgraph/dataNodeTransmit.I')
+CopyFile('built/include/','panda/src/dgraph/dataNodeTransmit.h')
+CopyFile('built/include/','panda/src/display/config_display.h')
+CopyFile('built/include/','panda/src/display/drawableRegion.I')
+CopyFile('built/include/','panda/src/display/drawableRegion.h')
+CopyFile('built/include/','panda/src/display/displayRegion.I')
+CopyFile('built/include/','panda/src/display/displayRegion.h')
+CopyFile('built/include/','panda/src/display/displayRegionStack.I')
+CopyFile('built/include/','panda/src/display/displayRegionStack.h')
+CopyFile('built/include/','panda/src/display/frameBufferProperties.I')
+CopyFile('built/include/','panda/src/display/frameBufferProperties.h')
+CopyFile('built/include/','panda/src/display/frameBufferStack.I')
+CopyFile('built/include/','panda/src/display/frameBufferStack.h')
+CopyFile('built/include/','panda/src/display/graphicsEngine.I')
+CopyFile('built/include/','panda/src/display/graphicsEngine.h')
+CopyFile('built/include/','panda/src/display/graphicsOutput.I')
+CopyFile('built/include/','panda/src/display/graphicsOutput.h')
+CopyFile('built/include/','panda/src/display/graphicsBuffer.I')
+CopyFile('built/include/','panda/src/display/graphicsBuffer.h')
+CopyFile('built/include/','panda/src/display/graphicsPipe.I')
+CopyFile('built/include/','panda/src/display/graphicsPipe.h')
+CopyFile('built/include/','panda/src/display/graphicsPipeSelection.I')
+CopyFile('built/include/','panda/src/display/graphicsPipeSelection.h')
+CopyFile('built/include/','panda/src/display/graphicsStateGuardian.I')
+CopyFile('built/include/','panda/src/display/graphicsStateGuardian.h')
+CopyFile('built/include/','panda/src/display/graphicsWindow.I')
+CopyFile('built/include/','panda/src/display/graphicsWindow.h')
+CopyFile('built/include/','panda/src/display/graphicsThreadingModel.I')
+CopyFile('built/include/','panda/src/display/graphicsThreadingModel.h')
+CopyFile('built/include/','panda/src/display/graphicsWindowInputDevice.I')
+CopyFile('built/include/','panda/src/display/graphicsWindowInputDevice.h')
+CopyFile('built/include/','panda/src/display/graphicsDevice.I')
+CopyFile('built/include/','panda/src/display/graphicsDevice.h')
+CopyFile('built/include/','panda/src/display/parasiteBuffer.I')
+CopyFile('built/include/','panda/src/display/parasiteBuffer.h')
+CopyFile('built/include/','panda/src/display/windowProperties.I')
+CopyFile('built/include/','panda/src/display/windowProperties.h')
+CopyFile('built/include/','panda/src/display/lensStack.I')
+CopyFile('built/include/','panda/src/display/lensStack.h')
+CopyFile('built/include/','panda/src/display/renderBuffer.h')
+CopyFile('built/include/','panda/src/display/savedFrameBuffer.I')
+CopyFile('built/include/','panda/src/display/savedFrameBuffer.h')
+CopyFile('built/include/','panda/src/device/analogNode.I')
+CopyFile('built/include/','panda/src/device/analogNode.h')
+CopyFile('built/include/','panda/src/device/buttonNode.I')
+CopyFile('built/include/','panda/src/device/buttonNode.h')
+CopyFile('built/include/','panda/src/device/clientAnalogDevice.I')
+CopyFile('built/include/','panda/src/device/clientAnalogDevice.h')
+CopyFile('built/include/','panda/src/device/clientBase.I')
+CopyFile('built/include/','panda/src/device/clientBase.h')
+CopyFile('built/include/','panda/src/device/clientButtonDevice.I')
+CopyFile('built/include/','panda/src/device/clientButtonDevice.h')
+CopyFile('built/include/','panda/src/device/clientDevice.I')
+CopyFile('built/include/','panda/src/device/clientDevice.h')
+CopyFile('built/include/','panda/src/device/clientDialDevice.I')
+CopyFile('built/include/','panda/src/device/clientDialDevice.h')
+CopyFile('built/include/','panda/src/device/clientTrackerDevice.I')
+CopyFile('built/include/','panda/src/device/clientTrackerDevice.h')
+CopyFile('built/include/','panda/src/device/config_device.h')
+CopyFile('built/include/','panda/src/device/mouseAndKeyboard.h')
+CopyFile('built/include/','panda/src/device/dialNode.I')
+CopyFile('built/include/','panda/src/device/dialNode.h')
+CopyFile('built/include/','panda/src/device/trackerData.I')
+CopyFile('built/include/','panda/src/device/trackerData.h')
+CopyFile('built/include/','panda/src/device/trackerNode.I')
+CopyFile('built/include/','panda/src/device/trackerNode.h')
+CopyFile('built/include/','panda/src/device/virtualMouse.h')
+CopyFile('built/include/','panda/src/tform/buttonThrower.I')
+CopyFile('built/include/','panda/src/tform/buttonThrower.h')
+CopyFile('built/include/','panda/src/tform/driveInterface.I')
+CopyFile('built/include/','panda/src/tform/driveInterface.h')
+CopyFile('built/include/','panda/src/tform/mouseInterfaceNode.I')
+CopyFile('built/include/','panda/src/tform/mouseInterfaceNode.h')
+CopyFile('built/include/','panda/src/tform/mouseWatcher.I')
+CopyFile('built/include/','panda/src/tform/mouseWatcher.h')
+CopyFile('built/include/','panda/src/tform/mouseWatcherGroup.h')
+CopyFile('built/include/','panda/src/tform/mouseWatcherParameter.I')
+CopyFile('built/include/','panda/src/tform/mouseWatcherParameter.h')
+CopyFile('built/include/','panda/src/tform/mouseWatcherRegion.I')
+CopyFile('built/include/','panda/src/tform/mouseWatcherRegion.h')
+CopyFile('built/include/','panda/src/tform/trackball.h')
+CopyFile('built/include/','panda/src/tform/transform2sg.h')
+CopyFile('built/include/','panda/src/collide/collisionEntry.I')
+CopyFile('built/include/','panda/src/collide/collisionEntry.h')
+CopyFile('built/include/','panda/src/collide/collisionHandler.h')
+CopyFile('built/include/','panda/src/collide/collisionHandlerEvent.I')
+CopyFile('built/include/','panda/src/collide/collisionHandlerEvent.h')
+CopyFile('built/include/','panda/src/collide/collisionHandlerFloor.I')
+CopyFile('built/include/','panda/src/collide/collisionHandlerFloor.h')
+CopyFile('built/include/','panda/src/collide/collisionHandlerGravity.I')
+CopyFile('built/include/','panda/src/collide/collisionHandlerGravity.h')
+CopyFile('built/include/','panda/src/collide/collisionHandlerPhysical.I')
+CopyFile('built/include/','panda/src/collide/collisionHandlerPhysical.h')
+CopyFile('built/include/','panda/src/collide/collisionHandlerPusher.I')
+CopyFile('built/include/','panda/src/collide/collisionHandlerPusher.h')
+CopyFile('built/include/','panda/src/collide/collisionHandlerQueue.h')
+CopyFile('built/include/','panda/src/collide/collisionInvSphere.I')
+CopyFile('built/include/','panda/src/collide/collisionInvSphere.h')
+CopyFile('built/include/','panda/src/collide/collisionLevelState.I')
+CopyFile('built/include/','panda/src/collide/collisionLevelState.h')
+CopyFile('built/include/','panda/src/collide/collisionLine.I')
+CopyFile('built/include/','panda/src/collide/collisionLine.h')
+CopyFile('built/include/','panda/src/collide/collisionNode.I')
+CopyFile('built/include/','panda/src/collide/collisionNode.h')
+CopyFile('built/include/','panda/src/collide/collisionPlane.I')
+CopyFile('built/include/','panda/src/collide/collisionPlane.h')
+CopyFile('built/include/','panda/src/collide/collisionPolygon.I')
+CopyFile('built/include/','panda/src/collide/collisionPolygon.h')
+CopyFile('built/include/','panda/src/collide/collisionRay.I')
+CopyFile('built/include/','panda/src/collide/collisionRay.h')
+CopyFile('built/include/','panda/src/collide/collisionRecorder.I')
+CopyFile('built/include/','panda/src/collide/collisionRecorder.h')
+CopyFile('built/include/','panda/src/collide/collisionSegment.I')
+CopyFile('built/include/','panda/src/collide/collisionSegment.h')
+CopyFile('built/include/','panda/src/collide/collisionSolid.I')
+CopyFile('built/include/','panda/src/collide/collisionSolid.h')
+CopyFile('built/include/','panda/src/collide/collisionSphere.I')
+CopyFile('built/include/','panda/src/collide/collisionSphere.h')
+CopyFile('built/include/','panda/src/collide/collisionTraverser.I')
+CopyFile('built/include/','panda/src/collide/collisionTraverser.h')
+CopyFile('built/include/','panda/src/collide/collisionTube.I')
+CopyFile('built/include/','panda/src/collide/collisionTube.h')
+CopyFile('built/include/','panda/src/collide/collisionVisualizer.I')
+CopyFile('built/include/','panda/src/collide/collisionVisualizer.h')
+CopyFile('built/include/','panda/src/collide/config_collide.h')
+CopyFile('built/include/','panda/src/pnmtext/config_pnmtext.h')
+CopyFile('built/include/','panda/src/pnmtext/freetypeFont.h')
+CopyFile('built/include/','panda/src/pnmtext/freetypeFont.I')
+CopyFile('built/include/','panda/src/pnmtext/pnmTextGlyph.h')
+CopyFile('built/include/','panda/src/pnmtext/pnmTextGlyph.I')
+CopyFile('built/include/','panda/src/pnmtext/pnmTextMaker.h')
+CopyFile('built/include/','panda/src/pnmtext/pnmTextMaker.I')
+CopyFile('built/include/','panda/src/text/config_text.h')
+CopyFile('built/include/','panda/src/text/dynamicTextFont.I')
+CopyFile('built/include/','panda/src/text/dynamicTextFont.h')
+CopyFile('built/include/','panda/src/text/dynamicTextGlyph.I')
+CopyFile('built/include/','panda/src/text/dynamicTextGlyph.h')
+CopyFile('built/include/','panda/src/text/dynamicTextPage.I')
+CopyFile('built/include/','panda/src/text/dynamicTextPage.h')
+CopyFile('built/include/','panda/src/text/fontPool.I')
+CopyFile('built/include/','panda/src/text/fontPool.h')
+CopyFile('built/include/','panda/src/text/geomTextGlyph.I')
+CopyFile('built/include/','panda/src/text/geomTextGlyph.h')
+CopyFile('built/include/','panda/src/text/staticTextFont.I')
+CopyFile('built/include/','panda/src/text/staticTextFont.h')
+CopyFile('built/include/','panda/src/text/textAssembler.I')
+CopyFile('built/include/','panda/src/text/textAssembler.h')
+CopyFile('built/include/','panda/src/text/textFont.I')
+CopyFile('built/include/','panda/src/text/textFont.h')
+CopyFile('built/include/','panda/src/text/textGlyph.I')
+CopyFile('built/include/','panda/src/text/textGlyph.h')
+CopyFile('built/include/','panda/src/text/textNode.I')
+CopyFile('built/include/','panda/src/text/textNode.h')
+CopyFile('built/include/','panda/src/text/textProperties.I')
+CopyFile('built/include/','panda/src/text/textProperties.h')
+CopyFile('built/include/','panda/src/text/textPropertiesManager.I')
+CopyFile('built/include/','panda/src/text/textPropertiesManager.h')
+CopyFile('built/include/','panda/src/grutil/cardMaker.I')
+CopyFile('built/include/','panda/src/grutil/cardMaker.h')
+CopyFile('built/include/','panda/src/grutil/frameRateMeter.I')
+CopyFile('built/include/','panda/src/grutil/frameRateMeter.h')
+CopyFile('built/include/','panda/src/grutil/lineSegs.I')
+CopyFile('built/include/','panda/src/grutil/lineSegs.h')
+CopyFile('built/include/','panda/src/grutil/multitexReducer.I')
+CopyFile('built/include/','panda/src/grutil/multitexReducer.h')
+CopyFile('built/include/','panda/src/gsgmisc/geomIssuer.I')
+CopyFile('built/include/','panda/src/gsgmisc/geomIssuer.h')
+CopyFile('built/include/','panda/src/helix/config_helix.h')
+CopyFile('built/include/','panda/src/helix/HelixClient.h')
+CopyFile('built/include/','panda/src/parametrics/classicNurbsCurve.I')
+CopyFile('built/include/','panda/src/parametrics/classicNurbsCurve.h')
+CopyFile('built/include/','panda/src/parametrics/config_parametrics.h')
+CopyFile('built/include/','panda/src/parametrics/cubicCurveseg.h')
+CopyFile('built/include/','panda/src/parametrics/parametricCurveDrawer.I')
+CopyFile('built/include/','panda/src/parametrics/parametricCurveDrawer.h')
+CopyFile('built/include/','panda/src/parametrics/curveFitter.I')
+CopyFile('built/include/','panda/src/parametrics/curveFitter.h')
+CopyFile('built/include/','panda/src/parametrics/hermiteCurve.h')
+CopyFile('built/include/','panda/src/parametrics/nurbsCurve.h')
+CopyFile('built/include/','panda/src/parametrics/nurbsCurveDrawer.I')
+CopyFile('built/include/','panda/src/parametrics/nurbsCurveDrawer.h')
+CopyFile('built/include/','panda/src/parametrics/nurbsCurveEvaluator.I')
+CopyFile('built/include/','panda/src/parametrics/nurbsCurveEvaluator.h')
+CopyFile('built/include/','panda/src/parametrics/nurbsCurveInterface.I')
+CopyFile('built/include/','panda/src/parametrics/nurbsCurveInterface.h')
+CopyFile('built/include/','panda/src/parametrics/nurbsCurveResult.I')
+CopyFile('built/include/','panda/src/parametrics/nurbsCurveResult.h')
+CopyFile('built/include/','panda/src/parametrics/nurbsBasisVector.I')
+CopyFile('built/include/','panda/src/parametrics/nurbsBasisVector.h')
+CopyFile('built/include/','panda/src/parametrics/nurbsSurfaceEvaluator.I')
+CopyFile('built/include/','panda/src/parametrics/nurbsSurfaceEvaluator.h')
+CopyFile('built/include/','panda/src/parametrics/nurbsSurfaceResult.I')
+CopyFile('built/include/','panda/src/parametrics/nurbsSurfaceResult.h')
+CopyFile('built/include/','panda/src/parametrics/nurbsVertex.h')
+CopyFile('built/include/','panda/src/parametrics/nurbsVertex.I')
+CopyFile('built/include/','panda/src/parametrics/nurbsPPCurve.h')
+CopyFile('built/include/','panda/src/parametrics/parametricCurve.h')
+CopyFile('built/include/','panda/src/parametrics/parametricCurveCollection.I')
+CopyFile('built/include/','panda/src/parametrics/parametricCurveCollection.h')
+CopyFile('built/include/','panda/src/parametrics/piecewiseCurve.h')
+CopyFile('built/include/','panda/src/parametrics/ropeNode.I')
+CopyFile('built/include/','panda/src/parametrics/ropeNode.h')
+CopyFile('built/include/','panda/src/parametrics/sheetNode.I')
+CopyFile('built/include/','panda/src/parametrics/sheetNode.h')
+CopyFile('built/include/','panda/src/pgui/pgButton.I')
+CopyFile('built/include/','panda/src/pgui/pgButton.h')
+CopyFile('built/include/','panda/src/pgui/pgSliderButton.I')
+CopyFile('built/include/','panda/src/pgui/pgSliderButton.h')
+CopyFile('built/include/','panda/src/pgui/pgCullTraverser.I')
+CopyFile('built/include/','panda/src/pgui/pgCullTraverser.h')
+CopyFile('built/include/','panda/src/pgui/pgEntry.I')
+CopyFile('built/include/','panda/src/pgui/pgEntry.h')
+CopyFile('built/include/','panda/src/pgui/pgMouseWatcherGroup.I')
+CopyFile('built/include/','panda/src/pgui/pgMouseWatcherGroup.h')
+CopyFile('built/include/','panda/src/pgui/pgMouseWatcherParameter.I')
+CopyFile('built/include/','panda/src/pgui/pgMouseWatcherParameter.h')
+CopyFile('built/include/','panda/src/pgui/pgFrameStyle.I')
+CopyFile('built/include/','panda/src/pgui/pgFrameStyle.h')
+CopyFile('built/include/','panda/src/pgui/pgItem.I')
+CopyFile('built/include/','panda/src/pgui/pgItem.h')
+CopyFile('built/include/','panda/src/pgui/pgMouseWatcherBackground.h')
+CopyFile('built/include/','panda/src/pgui/pgMouseWatcherRegion.I')
+CopyFile('built/include/','panda/src/pgui/pgMouseWatcherRegion.h')
+CopyFile('built/include/','panda/src/pgui/pgTop.I')
+CopyFile('built/include/','panda/src/pgui/pgTop.h')
+CopyFile('built/include/','panda/src/pgui/pgWaitBar.I')
+CopyFile('built/include/','panda/src/pgui/pgWaitBar.h')
+CopyFile('built/include/','panda/src/pgui/pgSliderBar.I')
+CopyFile('built/include/','panda/src/pgui/pgSliderBar.h')
+CopyFile('built/include/','panda/src/pnmimagetypes/config_pnmimagetypes.h')
+CopyFile('built/include/','panda/src/recorder/mouseRecorder.h')
+CopyFile('built/include/','panda/src/recorder/recorderBase.h')
+CopyFile('built/include/','panda/src/recorder/recorderBase.I')
+CopyFile('built/include/','panda/src/recorder/recorderController.h')
+CopyFile('built/include/','panda/src/recorder/recorderController.I')
+CopyFile('built/include/','panda/src/recorder/recorderFrame.h')
+CopyFile('built/include/','panda/src/recorder/recorderFrame.I')
+CopyFile('built/include/','panda/src/recorder/recorderHeader.h')
+CopyFile('built/include/','panda/src/recorder/recorderHeader.I')
+CopyFile('built/include/','panda/src/recorder/recorderTable.h')
+CopyFile('built/include/','panda/src/recorder/recorderTable.I')
+CopyFile('built/include/','panda/src/recorder/socketStreamRecorder.h')
+CopyFile('built/include/','panda/src/recorder/socketStreamRecorder.I')
+CopyFile('built/include/','panda/src/vrpn/config_vrpn.h')
+CopyFile('built/include/','panda/src/vrpn/vrpnClient.I')
+CopyFile('built/include/','panda/src/vrpn/vrpnClient.h')
+CopyFile('built/include/','panda/metalibs/panda/panda.h')
+CopyFile('built/include/','panda/src/builder/builder.I')
+CopyFile('built/include/','panda/src/builder/builder.h')
+CopyFile('built/include/','panda/src/builder/builder_compare.I')
+CopyFile('built/include/','panda/src/builder/builder_compare.h')
+CopyFile('built/include/','panda/src/builder/builderAttrib.I')
+CopyFile('built/include/','panda/src/builder/builderAttrib.h')
+CopyFile('built/include/','panda/src/builder/builderAttribTempl.I')
+CopyFile('built/include/','panda/src/builder/builderAttribTempl.h')
+CopyFile('built/include/','panda/src/builder/builderBucket.I')
+CopyFile('built/include/','panda/src/builder/builderBucket.h')
+CopyFile('built/include/','panda/src/builder/builderBucketNode.I')
+CopyFile('built/include/','panda/src/builder/builderBucketNode.h')
+CopyFile('built/include/','panda/src/builder/builderNormalVisualizer.I')
+CopyFile('built/include/','panda/src/builder/builderNormalVisualizer.h')
+CopyFile('built/include/','panda/src/builder/builderPrim.I')
+CopyFile('built/include/','panda/src/builder/builderPrim.h')
+CopyFile('built/include/','panda/src/builder/builderPrimTempl.I')
+CopyFile('built/include/','panda/src/builder/builderPrimTempl.h')
+CopyFile('built/include/','panda/src/builder/builderProperties.h')
+CopyFile('built/include/','panda/src/builder/builderTypes.h')
+CopyFile('built/include/','panda/src/builder/builderVertex.I')
+CopyFile('built/include/','panda/src/builder/builderVertex.h')
+CopyFile('built/include/','panda/src/builder/builderVertexTempl.I')
+CopyFile('built/include/','panda/src/builder/builderVertexTempl.h')
+CopyFile('built/include/','panda/src/builder/config_builder.h')
+CopyFile('built/include/','panda/src/windisplay/config_windisplay.h')
+CopyFile('built/include/','panda/src/windisplay/winGraphicsPipe.I')
+CopyFile('built/include/','panda/src/windisplay/winGraphicsPipe.h')
+CopyFile('built/include/','panda/src/windisplay/winGraphicsWindow.I')
+CopyFile('built/include/','panda/src/windisplay/winGraphicsWindow.h')
+CopyFile('built/include/','panda/src/dxgsg7/config_dxgsg7.h')
+CopyFile('built/include/','panda/src/dxgsg7/dxGraphicsStateGuardian7.I')
+CopyFile('built/include/','panda/src/dxgsg7/dxGraphicsStateGuardian7.h')
+CopyFile('built/include/','panda/src/dxgsg7/dxTextureContext7.h')
+CopyFile('built/include/','panda/src/dxgsg7/dxgsg7base.h')
+CopyFile('built/include/','panda/src/dxgsg8/dxgsg8base.h')
+CopyFile('built/include/','panda/src/dxgsg8/config_dxgsg8.h')
+CopyFile('built/include/','panda/src/dxgsg8/dxGraphicsStateGuardian8.I')
+CopyFile('built/include/','panda/src/dxgsg8/dxGraphicsStateGuardian8.h')
+CopyFile('built/include/','panda/src/dxgsg8/dxTextureContext8.h')
+CopyFile('built/include/','panda/src/dxgsg8/d3dfont8.h')
+CopyFile('built/include/','panda/src/dxgsg8/dxGraphicsDevice8.h')
+CopyFile('built/include/','panda/src/dxgsg9/dxgsg9base.h')
+CopyFile('built/include/','panda/src/dxgsg9/config_dxgsg9.h')
+CopyFile('built/include/','panda/src/dxgsg9/dxGraphicsStateGuardian9.I')
+CopyFile('built/include/','panda/src/dxgsg9/dxGraphicsStateGuardian9.h')
+CopyFile('built/include/','panda/src/dxgsg9/dxTextureContext9.h')
+CopyFile('built/include/','panda/src/dxgsg9/d3dfont9.h')
+CopyFile('built/include/','panda/src/dxgsg9/dxGraphicsDevice9.h')
+CopyFile('built/include/','panda/src/effects/config_effects.h')
+CopyFile('built/include/','panda/src/effects/cgShader.I')
+CopyFile('built/include/','panda/src/effects/cgShader.h')
+CopyFile('built/include/','panda/src/effects/cgShaderAttrib.I')
+CopyFile('built/include/','panda/src/effects/cgShaderAttrib.h')
+CopyFile('built/include/','panda/src/effects/cgShaderContext.I')
+CopyFile('built/include/','panda/src/effects/cgShaderContext.h')
+CopyFile('built/include/','panda/src/effects/lensFlareNode.I')
+CopyFile('built/include/','panda/src/effects/lensFlareNode.h')
+CopyFile('built/include/','panda/src/egg/eggAnimData.I')
+CopyFile('built/include/','panda/src/egg/eggAnimData.h')
+CopyFile('built/include/','panda/src/egg/eggAttributes.I')
+CopyFile('built/include/','panda/src/egg/eggAttributes.h')
+CopyFile('built/include/','panda/src/egg/eggBin.h')
+CopyFile('built/include/','panda/src/egg/eggBinMaker.h')
+CopyFile('built/include/','panda/src/egg/eggComment.I')
+CopyFile('built/include/','panda/src/egg/eggComment.h')
+CopyFile('built/include/','panda/src/egg/eggCoordinateSystem.I')
+CopyFile('built/include/','panda/src/egg/eggCoordinateSystem.h')
+CopyFile('built/include/','panda/src/egg/eggCurve.I')
+CopyFile('built/include/','panda/src/egg/eggCurve.h')
+CopyFile('built/include/','panda/src/egg/eggData.I')
+CopyFile('built/include/','panda/src/egg/eggData.h')
+CopyFile('built/include/','panda/src/egg/eggExternalReference.I')
+CopyFile('built/include/','panda/src/egg/eggExternalReference.h')
+CopyFile('built/include/','panda/src/egg/eggFilenameNode.I')
+CopyFile('built/include/','panda/src/egg/eggFilenameNode.h')
+CopyFile('built/include/','panda/src/egg/eggGroup.I')
+CopyFile('built/include/','panda/src/egg/eggGroup.h')
+CopyFile('built/include/','panda/src/egg/eggGroupNode.I')
+CopyFile('built/include/','panda/src/egg/eggGroupNode.h')
+CopyFile('built/include/','panda/src/egg/eggGroupUniquifier.h')
+CopyFile('built/include/','panda/src/egg/eggLine.I')
+CopyFile('built/include/','panda/src/egg/eggLine.h')
+CopyFile('built/include/','panda/src/egg/eggMaterial.I')
+CopyFile('built/include/','panda/src/egg/eggMaterial.h')
+CopyFile('built/include/','panda/src/egg/eggMaterialCollection.I')
+CopyFile('built/include/','panda/src/egg/eggMaterialCollection.h')
+CopyFile('built/include/','panda/src/egg/eggMorph.I')
+CopyFile('built/include/','panda/src/egg/eggMorph.h')
+CopyFile('built/include/','panda/src/egg/eggMorphList.I')
+CopyFile('built/include/','panda/src/egg/eggMorphList.h')
+CopyFile('built/include/','panda/src/egg/eggNamedObject.I')
+CopyFile('built/include/','panda/src/egg/eggNamedObject.h')
+CopyFile('built/include/','panda/src/egg/eggNameUniquifier.h')
+CopyFile('built/include/','panda/src/egg/eggNode.I')
+CopyFile('built/include/','panda/src/egg/eggNode.h')
+CopyFile('built/include/','panda/src/egg/eggNurbsCurve.I')
+CopyFile('built/include/','panda/src/egg/eggNurbsCurve.h')
+CopyFile('built/include/','panda/src/egg/eggNurbsSurface.I')
+CopyFile('built/include/','panda/src/egg/eggNurbsSurface.h')
+CopyFile('built/include/','panda/src/egg/eggObject.I')
+CopyFile('built/include/','panda/src/egg/eggObject.h')
+CopyFile('built/include/','panda/src/egg/eggParameters.h')
+CopyFile('built/include/','panda/src/egg/eggPoint.I')
+CopyFile('built/include/','panda/src/egg/eggPoint.h')
+CopyFile('built/include/','panda/src/egg/eggPolygon.I')
+CopyFile('built/include/','panda/src/egg/eggPolygon.h')
+CopyFile('built/include/','panda/src/egg/eggPolysetMaker.h')
+CopyFile('built/include/','panda/src/egg/eggPoolUniquifier.h')
+CopyFile('built/include/','panda/src/egg/eggPrimitive.I')
+CopyFile('built/include/','panda/src/egg/eggPrimitive.h')
+CopyFile('built/include/','panda/src/egg/eggRenderMode.I')
+CopyFile('built/include/','panda/src/egg/eggRenderMode.h')
+CopyFile('built/include/','panda/src/egg/eggSAnimData.I')
+CopyFile('built/include/','panda/src/egg/eggSAnimData.h')
+CopyFile('built/include/','panda/src/egg/eggSurface.I')
+CopyFile('built/include/','panda/src/egg/eggSurface.h')
+CopyFile('built/include/','panda/src/egg/eggSwitchCondition.h')
+CopyFile('built/include/','panda/src/egg/eggTable.I')
+CopyFile('built/include/','panda/src/egg/eggTable.h')
+CopyFile('built/include/','panda/src/egg/eggTexture.I')
+CopyFile('built/include/','panda/src/egg/eggTexture.h')
+CopyFile('built/include/','panda/src/egg/eggTextureCollection.I')
+CopyFile('built/include/','panda/src/egg/eggTextureCollection.h')
+CopyFile('built/include/','panda/src/egg/eggTransform3d.I')
+CopyFile('built/include/','panda/src/egg/eggTransform3d.h')
+CopyFile('built/include/','panda/src/egg/eggUserData.I')
+CopyFile('built/include/','panda/src/egg/eggUserData.h')
+CopyFile('built/include/','panda/src/egg/eggUtilities.I')
+CopyFile('built/include/','panda/src/egg/eggUtilities.h')
+CopyFile('built/include/','panda/src/egg/eggVertex.I')
+CopyFile('built/include/','panda/src/egg/eggVertex.h')
+CopyFile('built/include/','panda/src/egg/eggVertexPool.I')
+CopyFile('built/include/','panda/src/egg/eggVertexPool.h')
+CopyFile('built/include/','panda/src/egg/eggVertexUV.I')
+CopyFile('built/include/','panda/src/egg/eggVertexUV.h')
+CopyFile('built/include/','panda/src/egg/eggXfmAnimData.I')
+CopyFile('built/include/','panda/src/egg/eggXfmAnimData.h')
+CopyFile('built/include/','panda/src/egg/eggXfmSAnim.I')
+CopyFile('built/include/','panda/src/egg/eggXfmSAnim.h')
+CopyFile('built/include/','panda/src/egg/pt_EggMaterial.h')
+CopyFile('built/include/','panda/src/egg/vector_PT_EggMaterial.h')
+CopyFile('built/include/','panda/src/egg/pt_EggTexture.h')
+CopyFile('built/include/','panda/src/egg/vector_PT_EggTexture.h')
+CopyFile('built/include/','panda/src/egg/pt_EggVertex.h')
+CopyFile('built/include/','panda/src/egg/vector_PT_EggVertex.h')
+CopyFile('built/include/','panda/src/egg2pg/egg_parametrics.h')
+CopyFile('built/include/','panda/src/egg2pg/load_egg_file.h')
+CopyFile('built/include/','panda/src/egg2pg/config_egg2pg.h')
+CopyFile('built/include/','panda/src/framework/pandaFramework.I')
+CopyFile('built/include/','panda/src/framework/pandaFramework.h')
+CopyFile('built/include/','panda/src/framework/windowFramework.I')
+CopyFile('built/include/','panda/src/framework/windowFramework.h')
+CopyFile('built/include/','panda/src/glstuff/glext.h')
+CopyFile('built/include/','panda/src/glstuff/glmisc_src.cxx')
+CopyFile('built/include/','panda/src/glstuff/glmisc_src.h')
+CopyFile('built/include/','panda/src/glstuff/glstuff_src.cxx')
+CopyFile('built/include/','panda/src/glstuff/glstuff_src.h')
+CopyFile('built/include/','panda/src/glstuff/glstuff_undef_src.h')
+CopyFile('built/include/','panda/src/glstuff/glGeomContext_src.cxx')
+CopyFile('built/include/','panda/src/glstuff/glGeomContext_src.I')
+CopyFile('built/include/','panda/src/glstuff/glGeomContext_src.h')
+CopyFile('built/include/','panda/src/glstuff/glGraphicsStateGuardian_src.cxx')
+CopyFile('built/include/','panda/src/glstuff/glGraphicsStateGuardian_src.I')
+CopyFile('built/include/','panda/src/glstuff/glGraphicsStateGuardian_src.h')
+CopyFile('built/include/','panda/src/glstuff/glSavedFrameBuffer_src.cxx')
+CopyFile('built/include/','panda/src/glstuff/glSavedFrameBuffer_src.I')
+CopyFile('built/include/','panda/src/glstuff/glSavedFrameBuffer_src.h')
+CopyFile('built/include/','panda/src/glstuff/glTextureContext_src.cxx')
+CopyFile('built/include/','panda/src/glstuff/glTextureContext_src.I')
+CopyFile('built/include/','panda/src/glstuff/glTextureContext_src.h')
+CopyFile('built/include/','panda/src/glstuff/glCgShaderContext_src.cxx')
+CopyFile('built/include/','panda/src/glstuff/glCgShaderContext_src.h')
+CopyFile('built/include/','panda/src/glstuff/glCgShaderContext_src.I')
+CopyFile('built/include/','panda/src/glgsg/config_glgsg.h')
+CopyFile('built/include/','panda/src/glgsg/glgsg.h')
+CopyFile('built/include/','panda/metalibs/pandaegg/pandaegg.h')
+CopyFile('built/include/','panda/src/wgldisplay/config_wgldisplay.h')
+CopyFile('built/include/','panda/src/wgldisplay/wglGraphicsBuffer.I')
+CopyFile('built/include/','panda/src/wgldisplay/wglGraphicsBuffer.h')
+CopyFile('built/include/','panda/src/wgldisplay/wglGraphicsPipe.I')
+CopyFile('built/include/','panda/src/wgldisplay/wglGraphicsPipe.h')
+CopyFile('built/include/','panda/src/wgldisplay/wglGraphicsStateGuardian.I')
+CopyFile('built/include/','panda/src/wgldisplay/wglGraphicsStateGuardian.h')
+CopyFile('built/include/','panda/src/wgldisplay/wglGraphicsWindow.I')
+CopyFile('built/include/','panda/src/wgldisplay/wglGraphicsWindow.h')
+CopyFile('built/include/','panda/src/wgldisplay/wglext.h')
+CopyFile('built/include/','panda/metalibs/pandagl/pandagl.h')
+CopyFile('built/include/','panda/src/physics/actorNode.I')
+CopyFile('built/include/','panda/src/physics/actorNode.h')
+CopyFile('built/include/','panda/src/physics/angularEulerIntegrator.h')
+CopyFile('built/include/','panda/src/physics/angularForce.h')
+CopyFile('built/include/','panda/src/physics/angularIntegrator.h')
+CopyFile('built/include/','panda/src/physics/angularVectorForce.I')
+CopyFile('built/include/','panda/src/physics/angularVectorForce.h')
+CopyFile('built/include/','panda/src/physics/baseForce.I')
+CopyFile('built/include/','panda/src/physics/baseForce.h')
+CopyFile('built/include/','panda/src/physics/baseIntegrator.I')
+CopyFile('built/include/','panda/src/physics/baseIntegrator.h')
+CopyFile('built/include/','panda/src/physics/config_physics.h')
+CopyFile('built/include/','panda/src/physics/forceNode.I')
+CopyFile('built/include/','panda/src/physics/forceNode.h')
+CopyFile('built/include/','panda/src/physics/forces.h')
+CopyFile('built/include/','panda/src/physics/linearCylinderVortexForce.I')
+CopyFile('built/include/','panda/src/physics/linearCylinderVortexForce.h')
+CopyFile('built/include/','panda/src/physics/linearDistanceForce.I')
+CopyFile('built/include/','panda/src/physics/linearDistanceForce.h')
+CopyFile('built/include/','panda/src/physics/linearEulerIntegrator.h')
+CopyFile('built/include/','panda/src/physics/linearForce.I')
+CopyFile('built/include/','panda/src/physics/linearForce.h')
+CopyFile('built/include/','panda/src/physics/linearFrictionForce.I')
+CopyFile('built/include/','panda/src/physics/linearFrictionForce.h')
+CopyFile('built/include/','panda/src/physics/linearIntegrator.h')
+CopyFile('built/include/','panda/src/physics/linearJitterForce.h')
+CopyFile('built/include/','panda/src/physics/linearNoiseForce.I')
+CopyFile('built/include/','panda/src/physics/linearNoiseForce.h')
+CopyFile('built/include/','panda/src/physics/linearRandomForce.I')
+CopyFile('built/include/','panda/src/physics/linearRandomForce.h')
+CopyFile('built/include/','panda/src/physics/linearSinkForce.h')
+CopyFile('built/include/','panda/src/physics/linearSourceForce.h')
+CopyFile('built/include/','panda/src/physics/linearUserDefinedForce.I')
+CopyFile('built/include/','panda/src/physics/linearUserDefinedForce.h')
+CopyFile('built/include/','panda/src/physics/linearVectorForce.I')
+CopyFile('built/include/','panda/src/physics/linearVectorForce.h')
+CopyFile('built/include/','panda/src/physics/physical.I')
+CopyFile('built/include/','panda/src/physics/physical.h')
+CopyFile('built/include/','panda/src/physics/physicalNode.I')
+CopyFile('built/include/','panda/src/physics/physicalNode.h')
+CopyFile('built/include/','panda/src/physics/physicsCollisionHandler.I')
+CopyFile('built/include/','panda/src/physics/physicsCollisionHandler.h')
+CopyFile('built/include/','panda/src/physics/physicsManager.I')
+CopyFile('built/include/','panda/src/physics/physicsManager.h')
+CopyFile('built/include/','panda/src/physics/physicsObject.I')
+CopyFile('built/include/','panda/src/physics/physicsObject.h')
+CopyFile('built/include/','panda/src/particlesystem/baseParticle.I')
+CopyFile('built/include/','panda/src/particlesystem/baseParticle.h')
+CopyFile('built/include/','panda/src/particlesystem/baseParticleEmitter.I')
+CopyFile('built/include/','panda/src/particlesystem/baseParticleEmitter.h')
+CopyFile('built/include/','panda/src/particlesystem/baseParticleFactory.I')
+CopyFile('built/include/','panda/src/particlesystem/baseParticleFactory.h')
+CopyFile('built/include/','panda/src/particlesystem/baseParticleRenderer.I')
+CopyFile('built/include/','panda/src/particlesystem/baseParticleRenderer.h')
+CopyFile('built/include/','panda/src/particlesystem/boxEmitter.I')
+CopyFile('built/include/','panda/src/particlesystem/boxEmitter.h')
+CopyFile('built/include/','panda/src/particlesystem/config_particlesystem.h')
+CopyFile('built/include/','panda/src/particlesystem/discEmitter.I')
+CopyFile('built/include/','panda/src/particlesystem/discEmitter.h')
+CopyFile('built/include/','panda/src/particlesystem/emitters.h')
+CopyFile('built/include/','panda/src/particlesystem/geomParticleRenderer.I')
+CopyFile('built/include/','panda/src/particlesystem/geomParticleRenderer.h')
+CopyFile('built/include/','panda/src/particlesystem/lineEmitter.I')
+CopyFile('built/include/','panda/src/particlesystem/lineEmitter.h')
+CopyFile('built/include/','panda/src/particlesystem/lineParticleRenderer.I')
+CopyFile('built/include/','panda/src/particlesystem/lineParticleRenderer.h')
+CopyFile('built/include/','panda/src/particlesystem/particleSystem.I')
+CopyFile('built/include/','panda/src/particlesystem/particleSystem.h')
+CopyFile('built/include/','panda/src/particlesystem/particleSystemManager.I')
+CopyFile('built/include/','panda/src/particlesystem/particleSystemManager.h')
+CopyFile('built/include/','panda/src/particlesystem/particlefactories.h')
+CopyFile('built/include/','panda/src/particlesystem/particles.h')
+CopyFile('built/include/','panda/src/particlesystem/pointEmitter.I')
+CopyFile('built/include/','panda/src/particlesystem/pointEmitter.h')
+CopyFile('built/include/','panda/src/particlesystem/pointParticle.h')
+CopyFile('built/include/','panda/src/particlesystem/pointParticleFactory.h')
+CopyFile('built/include/','panda/src/particlesystem/pointParticleRenderer.I')
+CopyFile('built/include/','panda/src/particlesystem/pointParticleRenderer.h')
+CopyFile('built/include/','panda/src/particlesystem/rectangleEmitter.I')
+CopyFile('built/include/','panda/src/particlesystem/rectangleEmitter.h')
+CopyFile('built/include/','panda/src/particlesystem/ringEmitter.I')
+CopyFile('built/include/','panda/src/particlesystem/ringEmitter.h')
+CopyFile('built/include/','panda/src/particlesystem/sparkleParticleRenderer.I')
+CopyFile('built/include/','panda/src/particlesystem/sparkleParticleRenderer.h')
+CopyFile('built/include/','panda/src/particlesystem/sphereSurfaceEmitter.I')
+CopyFile('built/include/','panda/src/particlesystem/sphereSurfaceEmitter.h')
+CopyFile('built/include/','panda/src/particlesystem/sphereVolumeEmitter.I')
+CopyFile('built/include/','panda/src/particlesystem/sphereVolumeEmitter.h')
+CopyFile('built/include/','panda/src/particlesystem/spriteParticleRenderer.I')
+CopyFile('built/include/','panda/src/particlesystem/spriteParticleRenderer.h')
+CopyFile('built/include/','panda/src/particlesystem/tangentRingEmitter.I')
+CopyFile('built/include/','panda/src/particlesystem/tangentRingEmitter.h')
+CopyFile('built/include/','panda/src/particlesystem/zSpinParticle.I')
+CopyFile('built/include/','panda/src/particlesystem/zSpinParticle.h')
+CopyFile('built/include/','panda/src/particlesystem/zSpinParticleFactory.I')
+CopyFile('built/include/','panda/src/particlesystem/zSpinParticleFactory.h')
+CopyFile('built/include/','panda/src/particlesystem/particleCommonFuncs.h')
+CopyFile('built/include/','panda/metalibs/pandaphysics/pandaphysics.h')
+CopyFile('built/include/','direct/src/directbase/directbase.h')
+CopyFile('built/include/','direct/src/directbase/directsymbols.h')
+CopyFile('built/include/','direct/src/deadrec/smoothMover.h')
+CopyFile('built/include/','direct/src/deadrec/smoothMover.I')
+CopyFile('built/include/','direct/src/interval/config_interval.h')
+CopyFile('built/include/','direct/src/interval/cInterval.I')
+CopyFile('built/include/','direct/src/interval/cInterval.h')
+CopyFile('built/include/','direct/src/interval/cIntervalManager.I')
+CopyFile('built/include/','direct/src/interval/cIntervalManager.h')
+CopyFile('built/include/','direct/src/interval/cLerpInterval.I')
+CopyFile('built/include/','direct/src/interval/cLerpInterval.h')
+CopyFile('built/include/','direct/src/interval/cLerpNodePathInterval.I')
+CopyFile('built/include/','direct/src/interval/cLerpNodePathInterval.h')
+CopyFile('built/include/','direct/src/interval/cLerpAnimEffectInterval.I')
+CopyFile('built/include/','direct/src/interval/cLerpAnimEffectInterval.h')
+CopyFile('built/include/','direct/src/interval/cMetaInterval.I')
+CopyFile('built/include/','direct/src/interval/cMetaInterval.h')
+CopyFile('built/include/','direct/src/interval/hideInterval.I')
+CopyFile('built/include/','direct/src/interval/hideInterval.h')
+CopyFile('built/include/','direct/src/interval/showInterval.I')
+CopyFile('built/include/','direct/src/interval/showInterval.h')
+CopyFile('built/include/','direct/src/interval/waitInterval.I')
+CopyFile('built/include/','direct/src/interval/waitInterval.h')
+CopyFile('built/include/','pandatool/src/pandatoolbase/animationConvert.h')
+CopyFile('built/include/','pandatool/src/pandatoolbase/config_pandatoolbase.h')
+CopyFile('built/include/','pandatool/src/pandatoolbase/distanceUnit.h')
+CopyFile('built/include/','pandatool/src/pandatoolbase/pandatoolbase.h')
+CopyFile('built/include/','pandatool/src/pandatoolbase/pandatoolsymbols.h')
+CopyFile('built/include/','pandatool/src/pandatoolbase/pathReplace.I')
+CopyFile('built/include/','pandatool/src/pandatoolbase/pathReplace.h')
+CopyFile('built/include/','pandatool/src/pandatoolbase/pathStore.h')
+CopyFile('built/include/','pandatool/src/converter/somethingToEggConverter.I')
+CopyFile('built/include/','pandatool/src/converter/somethingToEggConverter.h')
+CopyFile('built/include/','pandatool/src/progbase/programBase.I')
+CopyFile('built/include/','pandatool/src/progbase/programBase.h')
+CopyFile('built/include/','pandatool/src/progbase/withOutputFile.I')
+CopyFile('built/include/','pandatool/src/progbase/withOutputFile.h')
+CopyFile('built/include/','pandatool/src/progbase/wordWrapStream.h')
+CopyFile('built/include/','pandatool/src/progbase/wordWrapStreamBuf.I')
+CopyFile('built/include/','pandatool/src/progbase/wordWrapStreamBuf.h')
+CopyFile('built/include/','pandatool/src/eggbase/eggBase.h')
+CopyFile('built/include/','pandatool/src/eggbase/eggConverter.h')
+CopyFile('built/include/','pandatool/src/eggbase/eggFilter.h')
+CopyFile('built/include/','pandatool/src/eggbase/eggMakeSomething.h')
+CopyFile('built/include/','pandatool/src/eggbase/eggMultiBase.h')
+CopyFile('built/include/','pandatool/src/eggbase/eggMultiFilter.h')
+CopyFile('built/include/','pandatool/src/eggbase/eggReader.h')
+CopyFile('built/include/','pandatool/src/eggbase/eggSingleBase.h')
+CopyFile('built/include/','pandatool/src/eggbase/eggToSomething.h')
+CopyFile('built/include/','pandatool/src/eggbase/eggWriter.h')
+CopyFile('built/include/','pandatool/src/eggbase/somethingToEgg.h')
+CopyFile('built/include/','pandatool/src/cvscopy/cvsCopy.h')
+CopyFile('built/include/','pandatool/src/dxf/dxfFile.h')
+CopyFile('built/include/','pandatool/src/dxf/dxfLayer.h')
+CopyFile('built/include/','pandatool/src/dxf/dxfLayerMap.h')
+CopyFile('built/include/','pandatool/src/dxf/dxfVertex.h')
+CopyFile('built/include/','pandatool/src/dxfegg/dxfToEggConverter.h')
+CopyFile('built/include/','pandatool/src/dxfegg/dxfToEggLayer.h')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggBackPointer.h')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggCharacterCollection.I')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggCharacterCollection.h')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggCharacterData.I')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggCharacterData.h')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggCharacterFilter.h')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggComponentData.I')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggComponentData.h')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggJointData.h')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggJointData.I')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggJointPointer.h')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggJointPointer.I')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggJointNodePointer.h')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggMatrixTablePointer.h')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggScalarTablePointer.h')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggSliderData.I')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggSliderData.h')
+CopyFile('built/include/','pandatool/src/eggcharbase/eggVertexPointer.h')
+CopyFile('built/include/','pandatool/src/flt/fltBead.h')
+CopyFile('built/include/','pandatool/src/flt/fltBeadID.h')
+CopyFile('built/include/','pandatool/src/flt/fltCurve.I')
+CopyFile('built/include/','pandatool/src/flt/fltCurve.h')
+CopyFile('built/include/','pandatool/src/flt/fltError.h')
+CopyFile('built/include/','pandatool/src/flt/fltExternalReference.h')
+CopyFile('built/include/','pandatool/src/flt/fltEyepoint.h')
+CopyFile('built/include/','pandatool/src/flt/fltFace.I')
+CopyFile('built/include/','pandatool/src/flt/fltFace.h')
+CopyFile('built/include/','pandatool/src/flt/fltGeometry.I')
+CopyFile('built/include/','pandatool/src/flt/fltGeometry.h')
+CopyFile('built/include/','pandatool/src/flt/fltGroup.h')
+CopyFile('built/include/','pandatool/src/flt/fltHeader.h')
+CopyFile('built/include/','pandatool/src/flt/fltInstanceDefinition.h')
+CopyFile('built/include/','pandatool/src/flt/fltInstanceRef.h')
+CopyFile('built/include/','pandatool/src/flt/fltLOD.h')
+CopyFile('built/include/','pandatool/src/flt/fltLightSourceDefinition.h')
+CopyFile('built/include/','pandatool/src/flt/fltLocalVertexPool.I')
+CopyFile('built/include/','pandatool/src/flt/fltLocalVertexPool.h')
+CopyFile('built/include/','pandatool/src/flt/fltMaterial.h')
+CopyFile('built/include/','pandatool/src/flt/fltMesh.I')
+CopyFile('built/include/','pandatool/src/flt/fltMesh.h')
+CopyFile('built/include/','pandatool/src/flt/fltMeshPrimitive.I')
+CopyFile('built/include/','pandatool/src/flt/fltMeshPrimitive.h')
+CopyFile('built/include/','pandatool/src/flt/fltObject.h')
+CopyFile('built/include/','pandatool/src/flt/fltOpcode.h')
+CopyFile('built/include/','pandatool/src/flt/fltPackedColor.I')
+CopyFile('built/include/','pandatool/src/flt/fltPackedColor.h')
+CopyFile('built/include/','pandatool/src/flt/fltRecord.I')
+CopyFile('built/include/','pandatool/src/flt/fltRecord.h')
+CopyFile('built/include/','pandatool/src/flt/fltRecordReader.h')
+CopyFile('built/include/','pandatool/src/flt/fltRecordWriter.h')
+CopyFile('built/include/','pandatool/src/flt/fltTexture.h')
+CopyFile('built/include/','pandatool/src/flt/fltTrackplane.h')
+CopyFile('built/include/','pandatool/src/flt/fltTransformGeneralMatrix.h')
+CopyFile('built/include/','pandatool/src/flt/fltTransformPut.h')
+CopyFile('built/include/','pandatool/src/flt/fltTransformRecord.h')
+CopyFile('built/include/','pandatool/src/flt/fltTransformRotateAboutEdge.h')
+CopyFile('built/include/','pandatool/src/flt/fltTransformRotateAboutPoint.h')
+CopyFile('built/include/','pandatool/src/flt/fltTransformRotateScale.h')
+CopyFile('built/include/','pandatool/src/flt/fltTransformScale.h')
+CopyFile('built/include/','pandatool/src/flt/fltTransformTranslate.h')
+CopyFile('built/include/','pandatool/src/flt/fltUnsupportedRecord.h')
+CopyFile('built/include/','pandatool/src/flt/fltVectorRecord.h')
+CopyFile('built/include/','pandatool/src/flt/fltVertex.I')
+CopyFile('built/include/','pandatool/src/flt/fltVertex.h')
+CopyFile('built/include/','pandatool/src/flt/fltVertexList.h')
+CopyFile('built/include/','pandatool/src/fltegg/fltToEggConverter.I')
+CopyFile('built/include/','pandatool/src/fltegg/fltToEggConverter.h')
+CopyFile('built/include/','pandatool/src/fltegg/fltToEggLevelState.I')
+CopyFile('built/include/','pandatool/src/fltegg/fltToEggLevelState.h')
+CopyFile('built/include/','pandatool/src/imagebase/imageBase.h')
+CopyFile('built/include/','pandatool/src/imagebase/imageFilter.h')
+CopyFile('built/include/','pandatool/src/imagebase/imageReader.h')
+CopyFile('built/include/','pandatool/src/imagebase/imageWriter.I')
+CopyFile('built/include/','pandatool/src/imagebase/imageWriter.h')
+CopyFile('built/include/','pandatool/src/lwo/iffChunk.I')
+CopyFile('built/include/','pandatool/src/lwo/iffChunk.h')
+CopyFile('built/include/','pandatool/src/lwo/iffGenericChunk.I')
+CopyFile('built/include/','pandatool/src/lwo/iffGenericChunk.h')
+CopyFile('built/include/','pandatool/src/lwo/iffId.I')
+CopyFile('built/include/','pandatool/src/lwo/iffId.h')
+CopyFile('built/include/','pandatool/src/lwo/iffInputFile.I')
+CopyFile('built/include/','pandatool/src/lwo/iffInputFile.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoBoundingBox.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoChunk.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoClip.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoDiscontinuousVertexMap.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoGroupChunk.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoHeader.I')
+CopyFile('built/include/','pandatool/src/lwo/lwoHeader.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoInputFile.I')
+CopyFile('built/include/','pandatool/src/lwo/lwoInputFile.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoLayer.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoPoints.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoPolygons.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoPolygonTags.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoTags.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoStillImage.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurface.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlock.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockAxis.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockChannel.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockCoordSys.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockEnabled.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockImage.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockOpacity.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockProjection.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockHeader.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockRefObj.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockRepeat.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockTMap.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockTransform.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockVMapName.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceBlockWrap.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceColor.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceParameter.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceSidedness.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoSurfaceSmoothingAngle.h')
+CopyFile('built/include/','pandatool/src/lwo/lwoVertexMap.h')
+CopyFile('built/include/','pandatool/src/lwoegg/lwoToEggConverter.I')
+CopyFile('built/include/','pandatool/src/lwoegg/lwoToEggConverter.h')
+CopyFile('built/include/','pandatool/src/vrmlegg/indexedFaceSet.h')
+CopyFile('built/include/','pandatool/src/vrmlegg/vrmlAppearance.h')
+CopyFile('built/include/','pandatool/src/vrmlegg/vrmlToEggConverter.h')
+CopyFile('built/include/','pandatool/src/ptloader/config_ptloader.h')
+CopyFile('built/include/','pandatool/src/ptloader/loaderFileTypePandatool.h')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatClientData.h')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatGraph.I')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatGraph.h')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatListener.h')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatMonitor.I')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatMonitor.h')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatPianoRoll.I')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatPianoRoll.h')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatReader.h')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatServer.h')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatStripChart.I')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatStripChart.h')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatThreadData.I')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatThreadData.h')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatView.I')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatView.h')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatViewLevel.I')
+CopyFile('built/include/','pandatool/src/pstatserver/pStatViewLevel.h')
+CopyFile('built/include/','pandaapp/src/pandaappbase/pandaappbase.h')
+CopyFile('built/include/','pandaapp/src/pandaappbase/pandaappsymbols.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/config_stitch.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/fadeImagePool.I')
+CopyFile('built/include/','pandaapp/src/stitchbase/fadeImagePool.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/fixedPoint.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/layeredImage.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/morphGrid.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchCommand.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchCommandReader.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchCylindricalLens.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchFile.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchFisheyeLens.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchImage.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchImageCommandOutput.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchImageOutputter.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchImageRasterizer.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchLens.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchLexerDefs.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchPSphereLens.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchParserDefs.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchPerspectiveLens.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchPoint.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitcher.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/triangle.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/triangleRasterizer.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchCylindricalScreen.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchFlatScreen.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchMultiScreen.h')
+CopyFile('built/include/','pandaapp/src/stitchbase/stitchScreen.h')
+
+########################################################################
+#
+# This file contains a list of all the files that need to be compiled.
+#
+########################################################################
+
+#
+# DIRECTORY: dtool/src/dtoolbase/
+#
+
+IPATH=['dtool/src/dtoolbase']
+OPTS=['BUILDING_DTOOL', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='dtoolbase.cxx', obj='dtoolbase_dtoolbase.obj')
+
+#
+# DIRECTORY: dtool/src/dtoolutil/
+#
+
+IPATH=['dtool/src/dtoolutil']
+OPTS=['BUILDING_DTOOL', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='gnu_getopt.c',             obj='dtoolutil_gnu_getopt.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='gnu_getopt1.c',            obj='dtoolutil_gnu_getopt1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='dtoolutil_composite1.cxx', obj='dtoolutil_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='dtoolutil_composite2.cxx', obj='dtoolutil_composite2.obj')
+
+#
+# DIRECTORY: dtool/metalibs/dtool/
+#
+
+IPATH=['dtool/metalibs/dtool']
+OPTS=['BUILDING_DTOOL', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='dtool.cxx', obj='dtool_dtool.obj')
+CompileLink(opts=['ADVAPI', 'NSPR'], dll='libdtool.dll', obj=[
+             'dtool_dtool.obj',
+             'dtoolutil_gnu_getopt.obj',
+             'dtoolutil_gnu_getopt1.obj',
+             'dtoolutil_composite1.obj',
+             'dtoolutil_composite2.obj',
+             'dtoolbase_dtoolbase.obj',
+])
+
+#
+# DIRECTORY: dtool/src/cppparser/
+#
+
+IPATH=['dtool/src/cppparser']
+CompileBison(pre='cppyy', dstc='cppBison.cxx', dsth='cppBison.h', src='dtool/src/cppparser/cppBison.yxx')
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='cppParser_composite1.cxx', obj='cppParser_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='cppParser_composite2.cxx', obj='cppParser_composite2.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='cppBison.cxx', obj='cppParser_cppBison.obj')
+CompileLIB(lib='libcppParser.lib', obj=[
+             'cppParser_composite1.obj',
+             'cppParser_composite2.obj',
+             'cppParser_cppBison.obj',
+])
+
+#
+# DIRECTORY: dtool/src/prc/
+#
+
+IPATH=['dtool/src/prc']
+OPTS=['BUILDING_DTOOLCONFIG', 'OPENSSL', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='prc_composite1.cxx', obj='prc_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='prc_composite2.cxx', obj='prc_composite2.obj')
+
+#
+# DIRECTORY: dtool/src/dconfig/
+#
+
+IPATH=['dtool/src/dconfig']
+OPTS=['BUILDING_DTOOLCONFIG', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='dconfig_composite1.cxx', obj='dconfig_composite1.obj')
+
+#
+# DIRECTORY: dtool/src/interrogatedb/
+#
+
+IPATH=['dtool/src/interrogatedb']
+OPTS=['BUILDING_DTOOLCONFIG', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='interrogatedb_composite1.cxx', obj='interrogatedb_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='interrogatedb_composite2.cxx', obj='interrogatedb_composite2.obj')
+
+#
+# DIRECTORY: dtool/metalibs/dtoolconfig/
+#
+
+IPATH=['dtool/metalibs/dtoolconfig']
+OPTS=['BUILDING_DTOOLCONFIG', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='dtoolconfig.cxx', obj='dtoolconfig_dtoolconfig.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pydtool.cxx', obj='dtoolconfig_pydtool.obj')
+CompileLink(opts=['ADVAPI', 'NSPR', 'OPENSSL'], dll='libdtoolconfig.dll', obj=[
+             'dtoolconfig_dtoolconfig.obj',
+             'dtoolconfig_pydtool.obj',
+             'interrogatedb_composite1.obj',
+             'interrogatedb_composite2.obj',
+             'dconfig_composite1.obj',
+             'prc_composite1.obj',
+             'prc_composite2.obj',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: dtool/src/pystub/
+#
+
+IPATH=['dtool/src/pystub']
+OPTS=['BUILDING_DTOOLCONFIG', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pystub.cxx', obj='pystub_pystub.obj')
+CompileLink(opts=['ADVAPI', 'NSPR'], dll='libpystub.dll', obj=[
+             'pystub_pystub.obj',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: dtool/src/interrogate/
+#
+
+IPATH=['dtool/src/interrogate', 'dtool/src/cppparser', 'dtool/src/interrogatedb']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='interrogate_composite1.cxx', obj='interrogate_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='interrogate_composite2.cxx', obj='interrogate_composite2.obj')
+CompileLink(opts=['ADVAPI', 'NSPR', 'OPENSSL'], dll='interrogate.exe', obj=[
+             'interrogate_composite1.obj',
+             'interrogate_composite2.obj',
+             'libcppParser.lib',
+             'libpystub.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+CompileC(ipath=IPATH, opts=OPTS, src='interrogate_module.cxx', obj='interrogate_module_interrogate_module.obj')
+CompileLink(opts=['ADVAPI', 'NSPR', 'OPENSSL'], dll='interrogate_module.exe', obj=[
+             'interrogate_module_interrogate_module.obj',
+             'libcppParser.lib',
+             'libpystub.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+CompileC(ipath=IPATH, opts=OPTS, src='parse_file.cxx', obj='parse_file_parse_file.obj')
+CompileLink(opts=['ADVAPI', 'NSPR', 'OPENSSL'], dll='parse_file.exe', obj=[
+             'parse_file_parse_file.obj',
+             'libcppParser.lib',
+             'libpystub.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: dtool/src/prckeys/
+#
+
+IPATH=['dtool/src/prckeys']
+OPTS=['OPENSSL', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='makePrcKey.cxx', obj='make-prc-key_makePrcKey.obj')
+CompileLink(opts=['ADVAPI', 'NSPR', 'OPENSSL'], dll='make-prc-key.exe', obj=[
+             'make-prc-key_makePrcKey.obj',
+             'libpystub.dll',
+             'libdtool.dll',
+             'libdtoolconfig.dll',
+])
+
+#
+# DIRECTORY: dtool/src/test_interrogate/
+#
+
+IPATH=['dtool/src/test_interrogate']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='test_interrogate.cxx', obj='test_interrogate_test_interrogate.obj')
+CompileLink(opts=['ADVAPI', 'NSPR', 'OPENSSL'], dll='test_interrogate.exe', obj=[
+             'test_interrogate_test_interrogate.obj',
+             'libpystub.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: panda/src/pandabase/
+#
+
+IPATH=['panda/src/pandabase']
+OPTS=['BUILDING_PANDAEXPRESS', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pandabase.cxx', obj='pandabase_pandabase.obj')
+
+#
+# DIRECTORY: panda/src/express/
+#
+
+IPATH=['panda/src/express']
+OPTS=['BUILDING_PANDAEXPRESS', 'OPENSSL', 'ZLIB', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='express_composite1.cxx', obj='express_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='express_composite2.cxx', obj='express_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libexpress.in', outc='libexpress_igate.cxx',
+            src='panda/src/express',  module='pandaexpress', library='libexpress',
+            files=['atomicAdjustDummyImpl.h', 'atomicAdjust.h', 'atomicAdjustImpl.h', 'atomicAdjustNsprImpl.h', 'bigEndian.h', 'buffer.h', 'checksumHashGenerator.h', 'circBuffer.h', 'clockObject.h', 'conditionVarDummyImpl.h', 'conditionVar.h', 'conditionVarImpl.h', 'conditionVarNsprImpl.h', 'config_express.h', 'datagram.h', 'datagramGenerator.h', 'datagramIterator.h', 'datagramSink.h', 'dcast.h', 'encryptStreamBuf.h', 'encryptStream.h', 'error_utils.h', 'hashGeneratorBase.h', 'hashVal.h', 'indent.h', 'indirectLess.h', 'littleEndian.h', 'memoryInfo.h', 'memoryUsage.h', 'memoryUsagePointerCounts.h', 'memoryUsagePointers.h', 'multifile.h', 'mutexDummyImpl.h', 'pmutex.h', 'mutexHolder.h', 'mutexImpl.h', 'mutexNsprImpl.h', 'namable.h', 'nativeNumericData.h', 'numeric_types.h', 'ordered_vector.h', 'password_hash.h', 'patchfile.h', 'pointerTo.h', 'pointerToArray.h', 'pointerToBase.h', 'pointerToVoid.h', 'profileTimer.h', 'pta_uchar.h', 'ramfile.h', 'referenceCount.h', 'register_type.h', 'reversedNumericData.h', 'selectThreadImpl.h', 'streamReader.h', 'streamWriter.h', 'stringDecoder.h', 'subStream.h', 'subStreamBuf.h', 'textEncoder.h', 'threadDummyImpl.h', 'thread.h', 'threadImpl.h', 'threadNsprImpl.h', 'threadPriority.h', 'tokenBoard.h', 'trueClock.h', 'typeHandle.h', 'typedObject.h', 'typedReferenceCount.h', 'typedef.h', 'typeRegistry.h', 'typeRegistryNode.h', 'unicodeLatinMap.h', 'vector_uchar.h', 'virtualFileComposite.h', 'virtualFile.h', 'virtualFileList.h', 'virtualFileMount.h', 'virtualFileMountMultifile.h', 'virtualFileMountSystem.h', 'virtualFileSimple.h', 'virtualFileSystem.h', 'weakPointerTo.h', 'weakPointerToBase.h', 'weakPointerToVoid.h', 'weakReferenceList.h', 'windowsRegistry.h', 'zStream.h', 'zStreamBuf.h', 'express_composite1.cxx', 'express_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libexpress_igate.cxx', obj='libexpress_igate.obj')
+
+#
+# DIRECTORY: panda/src/downloader/
+#
+
+IPATH=['panda/src/downloader']
+OPTS=['BUILDING_PANDAEXPRESS', 'OPENSSL', 'ZLIB', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='downloader_composite1.cxx', obj='downloader_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='downloader_composite2.cxx', obj='downloader_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libdownloader.in', outc='libdownloader_igate.cxx',
+            src='panda/src/downloader',  module='pandaexpress', library='libdownloader', files=[
+	    'config_downloader.h', 'asyncUtility.h', 'bioPtr.h', 'bioStreamPtr.h', 'bioStream.h', 'bioStreamBuf.h',
+            'chunkedStream.h', 'chunkedStreamBuf.h', 'decompressor.h', 'documentSpec.h', 'downloadDb.h',
+	    'download_utils.h', 'extractor.h', 'httpAuthorization.h', 'httpBasicAuthorization.h', 'httpChannel.h',
+	    'httpClient.h', 'httpCookie.h', 'httpDate.h', 'httpDigestAuthorization.h', 'httpEntityTag.h',
+	    'httpEnum.h', 'identityStream.h', 'identityStreamBuf.h', 'multiplexStream.h', 'multiplexStreamBuf.h',
+	    'patcher.h', 'socketStream.h', 'ssl_utils.h', 'urlSpec.h',
+	    'downloader_composite1.cxx', 'downloader_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libdownloader_igate.cxx', obj='libdownloader_igate.obj')
+
+#
+# DIRECTORY: panda/metalibs/pandaexpress/
+#
+
+IPATH=['panda/metalibs/pandaexpress']
+OPTS=['BUILDING_PANDAEXPRESS', 'ZLIB', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pandaexpress.cxx', obj='pandaexpress_pandaexpress.obj')
+InterrogateModule(outc='libpandaexpress_module.cxx', module='pandaexpress', library='libpandaexpress',
+                  files=['libdownloader.in', 'libexpress.in'])
+CompileC(ipath=IPATH, opts=OPTS, src='libpandaexpress_module.cxx', obj='libpandaexpress_module.obj')
+CompileLink(opts=['ADVAPI', 'WINSOCK2', 'NSPR', 'OPENSSL', 'ZLIB'], dll='libpandaexpress.dll', obj=[
+             'pandaexpress_pandaexpress.obj',
+             'libpandaexpress_module.obj',
+             'downloader_composite1.obj',
+             'downloader_composite2.obj',
+             'libdownloader_igate.obj',
+             'express_composite1.obj',
+             'express_composite2.obj',
+             'libexpress_igate.obj',
+             'pandabase_pandabase.obj',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: panda/src/putil/
+#
+
+IPATH=['panda/src/putil']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='putil_composite1.cxx', obj='putil_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='putil_composite2.cxx', obj='putil_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libputil.in', outc='libputil_igate.cxx',
+            src='panda/src/putil',  module='panda', library='libputil', files=[
+	    'bam.h', 'bamReader.h', 'bamReaderParam.h', 'bamWriter.h', 'bitMask.h', 'buttonHandle.h',
+	    'buttonRegistry.h', 'cachedTypedWritableReferenceCount.h', 'collideMask.h', 'portalMask.h',
+	    'compareTo.h', 'config_util.h', 'configurable.h', 'cycleData.h', 'cycleDataReader.h',
+            'cycleDataWriter.h', 'datagramInputFile.h', 'datagramOutputFile.h', 'drawMask.h', 'factoryBase.h',
+            'factoryParam.h', 'factoryParams.h', 'firstOfPairCompare.h', 'firstOfPairLess.h',
+	    'globalPointerRegistry.h', 'indirectCompareNames.h', 'indirectCompareTo.h', 'ioPtaDatagramFloat.h',
+	    'ioPtaDatagramInt.h', 'ioPtaDatagramShort.h', 'keyboardButton.h', 'lineStream.h', 'lineStreamBuf.h',
+	    'load_prc_file.h', 'modifierButtons.h', 'mouseButton.h', 'mouseData.h', 'nameUniquifier.h',
+	    'pipeline.h', 'pipelineCycler.h', 'pipelineCyclerBase.h', 'pta_double.h', 'pta_float.h',
+	    'pta_int.h', 'string_utils.h', 'timedCycle.h', 'typedWritable.h', 'typedWritableReferenceCount.h',
+	    'updateSeq.h', 'uniqueIdAllocator.h', 'vector_double.h', 'vector_float.h', 'vector_typedWritable.h',
+	    'vector_ushort.h', 'vector_writable.h', 'writableConfigurable.h', 'writableParam.h',
+	    'putil_composite1.cxx', 'putil_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libputil_igate.cxx', obj='libputil_igate.obj')
+
+#
+# DIRECTORY: panda/src/audio/
+#
+
+IPATH=['panda/src/audio']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='audio_composite1.cxx', obj='audio_composite1.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libaudio.in', outc='libaudio_igate.cxx',
+            src='panda/src/audio',  module='panda', library='libaudio',
+            files=['audio.h'])
+CompileC(ipath=IPATH, opts=OPTS, src='libaudio_igate.cxx', obj='libaudio_igate.obj')
+
+#
+# DIRECTORY: panda/src/event/
+#
+
+IPATH=['panda/src/event']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='event_composite1.cxx', obj='event_composite1.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libevent.in', outc='libevent_igate.cxx',
+            src='panda/src/event',  module='panda', library='libevent', files=[
+	    'config_event.h', 'buttonEvent.h', 'buttonEventList.h', 'event.h', 'eventHandler.h',
+	    'eventParameter.h', 'eventQueue.h', 'eventReceiver.h', 'pt_Event.h', 'throw_event.h', 'event_composite1.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libevent_igate.cxx', obj='libevent_igate.obj')
+
+#
+# DIRECTORY: panda/src/linmath/
+#
+
+IPATH=['panda/src/linmath']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='linmath_composite1.cxx', obj='linmath_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='linmath_composite2.cxx', obj='linmath_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='liblinmath.in', outc='liblinmath_igate.cxx',
+            src='panda/src/linmath',  module='panda', library='liblinmath', files=[
+	    'compose_matrix.h', 'compose_matrix_src.h', 'config_linmath.h', 'coordinateSystem.h', 'dbl2fltnames.h', 'dblnames.h', 'deg_2_rad.h', 'flt2dblnames.h', 'fltnames.h', 'ioPtaDatagramLinMath.h', 'lcast_to.h', 'lcast_to_src.h', 'lmatrix.h', 'lmatrix3.h', 'lmatrix3_src.h', 'lmatrix4.h', 'lmatrix4_src.h', 'lorientation.h', 'lorientation_src.h', 'lpoint2.h', 'lpoint2_src.h', 'lpoint3.h', 'lpoint3_src.h', 'lpoint4.h', 'lpoint4_src.h', 'lquaternion.h', 'lquaternion_src.h', 'lrotation.h', 'lrotation_src.h', 'luse.h', 'lvec2_ops.h', 'lvec2_ops_src.h', 'lvec3_ops.h', 'lvec3_ops_src.h', 'lvec4_ops.h', 'lvec4_ops_src.h', 'lvecBase2.h', 'lvecBase2_src.h', 'lvecBase3.h', 'lvecBase3_src.h', 'lvecBase4.h', 'lvecBase4_src.h', 'lvector2.h', 'lvector2_src.h', 'lvector3.h', 'lvector3_src.h', 'lvector4.h', 'lvector4_src.h', 'mathNumbers.h', 'pta_Colorf.h', 'pta_Normalf.h', 'pta_TexCoordf.h', 'pta_Vertexf.h', 'vector_Colorf.h', 'vector_LPoint2f.h', 'vector_LVecBase3f.h', 'vector_Normalf.h', 'vector_TexCoordf.h', 'vector_Vertexf.h', 'linmath_composite1.cxx', 'linmath_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='liblinmath_igate.cxx', obj='liblinmath_igate.obj')
+
+#
+# DIRECTORY: panda/src/mathutil/
+#
+
+IPATH=['panda/src/mathutil']
+OPTS=['BUILDING_PANDA', 'FFTW', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='mathutil_composite1.cxx', obj='mathutil_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='mathutil_composite2.cxx', obj='mathutil_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libmathutil.in', outc='libmathutil_igate.cxx',
+            src='panda/src/mathutil',  module='panda', library='libmathutil', files=[
+	    'boundingHexahedron.h', 'boundingLine.h', 'boundingSphere.h', 'boundingVolume.h', 'config_mathutil.h', 'fftCompressor.h', 'finiteBoundingVolume.h', 'frustum.h', 'frustum_src.h', 'geometricBoundingVolume.h', 'linmath_events.h', 'look_at.h', 'look_at_src.h', 'omniBoundingVolume.h', 'plane.h', 'plane_src.h', 'rotate_to.h', 'mathutil_composite1.cxx', 'mathutil_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libmathutil_igate.cxx', obj='libmathutil_igate.obj')
+
+#
+# DIRECTORY: panda/src/gsgbase/
+#
+
+IPATH=['panda/src/gsgbase']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='gsgbase_composite1.cxx', obj='gsgbase_composite1.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libgsgbase.in', outc='libgsgbase_igate.cxx',
+            src='panda/src/gsgbase',  module='panda', library='libgsgbase', files=[
+	    'config_gsgbase.h', 'graphicsStateGuardianBase.h', 'gsgbase_composite1.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libgsgbase_igate.cxx', obj='libgsgbase_igate.obj')
+
+#
+# DIRECTORY: panda/src/pnmimage/
+#
+
+IPATH=['panda/src/pnmimage']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pnmimage_composite1.cxx', obj='pnmimage_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pnmimage_composite2.cxx', obj='pnmimage_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libpnmimage.in', outc='libpnmimage_igate.cxx',
+            src='panda/src/pnmimage',  module='panda', library='libpnmimage', files=[
+	    'config_pnmimage.h', 'pnmbitio.h', 'pnmFileType.h', 'pnmFileTypeRegistry.h', 'pnmImage.h', 'pnmImageHeader.h', 'pnmReader.h', 'pnmWriter.h', 'pnmimage_base.h', 'ppmcmap.h', 'pnmimage_composite1.cxx', 'pnmimage_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libpnmimage_igate.cxx', obj='libpnmimage_igate.obj')
+
+#
+# DIRECTORY: panda/src/net/
+#
+
+IPATH=['panda/src/net']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='net_composite1.cxx', obj='net_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='net_composite2.cxx', obj='net_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libnet.in', outc='libnet_igate.cxx',
+            src='panda/src/net',  module='panda', library='libnet', files=[
+	    'config_net.h', 'connection.h', 'connectionListener.h', 'connectionManager.h', 'connectionReader.h', 'connectionWriter.h', 'datagramQueue.h', 'datagramTCPHeader.h', 'datagramUDPHeader.h', 'netAddress.h', 'netDatagram.h', 'pprerror.h', 'queuedConnectionListener.h', 'queuedConnectionManager.h', 'queuedConnectionReader.h', 'recentConnectionReader.h', 'queuedReturn.h', 'net_composite1.cxx', 'net_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libnet_igate.cxx', obj='libnet_igate.obj')
+
+#
+# DIRECTORY: panda/src/pstatclient/
+#
+
+IPATH=['panda/src/pstatclient']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pstatclient_composite1.cxx', obj='pstatclient_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pstatclient_composite2.cxx', obj='pstatclient_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libpstatclient.in', outc='libpstatclient_igate.cxx',
+            src='panda/src/pstatclient',  module='panda', library='libpstatclient', files=[
+	    'config_pstats.h', 'pStatClient.h', 'pStatClientImpl.h', 'pStatClientVersion.h', 'pStatClientControlMessage.h', 'pStatCollector.h', 'pStatCollectorDef.h', 'pStatFrameData.h', 'pStatProperties.h', 'pStatServerControlMessage.h', 'pStatThread.h', 'pStatTimer.h', 'pstatclient_composite1.cxx', 'pstatclient_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libpstatclient_igate.cxx', obj='libpstatclient_igate.obj')
+
+#
+# DIRECTORY: panda/src/gobj/
+#
+
+IPATH=['panda/src/gobj']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='gobj_composite1.cxx', obj='gobj_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='gobj_composite2.cxx', obj='gobj_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libgobj.in', outc='libgobj_igate.cxx',
+            src='panda/src/gobj',  module='panda', library='libgobj', files=[
+	    'boundedObject.h', 'config_gobj.h', 'drawable.h', 'geom.h', 'geomContext.h', 'geomLine.h', 'geomLinestrip.h', 'geomPoint.h', 'geomPolygon.h', 'geomQuad.h', 'geomSphere.h', 'geomSprite.h', 'geomTri.h', 'geomTrifan.h', 'geomTristrip.h', 'imageBuffer.h', 'material.h', 'materialPool.h', 'matrixLens.h', 'orthographicLens.h', 'perspectiveLens.h', 'pixelBuffer.h', 'preparedGraphicsObjects.h', 'lens.h', 'savedContext.h', 'texture.h', 'textureContext.h', 'texturePool.h', 'texCoordName.h', 'textureStage.h', 'gobj_composite1.cxx', 'gobj_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libgobj_igate.cxx', obj='libgobj_igate.obj')
+
+#
+# DIRECTORY: panda/src/lerp/
+#
+
+IPATH=['panda/src/lerp']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='lerp_composite1.cxx', obj='lerp_composite1.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='liblerp.in', outc='liblerp_igate.cxx',
+            src='panda/src/lerp',  module='panda', library='liblerp', files=[
+	    'config_lerp.h', 'lerp.h', 'lerpblend.h', 'lerpfunctor.h', 'lerp_composite1.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='liblerp_igate.cxx', obj='liblerp_igate.obj')
+
+#
+# DIRECTORY: panda/src/pgraph/
+#
+
+IPATH=['panda/src/pgraph']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='nodePath.cxx', obj='pgraph_nodePath.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pgraph_composite1.cxx', obj='pgraph_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pgraph_composite2.cxx', obj='pgraph_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libpgraph.in', outc='libpgraph_igate.cxx',
+            src='panda/src/pgraph',  module='panda', library='libpgraph', files=[
+	    'accumulatedAttribs.h', 'alphaTestAttrib.h', 'ambientLight.h', 'auxSceneData.h', 'bamFile.h', 'billboardEffect.h', 'binCullHandler.h', 'camera.h', 'clipPlaneAttrib.h', 'colorAttrib.h', 'colorBlendAttrib.h', 'colorScaleAttrib.h', 'colorWriteAttrib.h', 'compassEffect.h', 'config_pgraph.h', 'cullBin.h', 'cullBinAttrib.h', 'cullBinBackToFront.h', 'cullBinFixed.h', 'cullBinFrontToBack.h', 'cullBinManager.h', 'cullBinUnsorted.h', 'cullFaceAttrib.h', 'cullHandler.h', 'cullResult.h', 'cullTraverser.h', 'cullTraverserData.h', 'cullableObject.h', 'decalEffect.h', 'depthOffsetAttrib.h', 'depthTestAttrib.h', 'depthWriteAttrib.h', 'directionalLight.h', 'drawCullHandler.h', 'fadeLodNode.h', 'fadeLodNodeData.h', 'findApproxLevelEntry.h', 'findApproxPath.h', 'fog.h', 'fogAttrib.h', 'geomNode.h', 'geomTransformer.h', 'lensNode.h', 'light.h', 'lightAttrib.h', 'lightLensNode.h', 'lightNode.h', 'loader.h', 'loaderFileType.h', 'loaderFileTypeBam.h', 'loaderFileTypeRegistry.h', 'lodNode.h', 'materialAttrib.h', 'modelNode.h', 'modelPool.h', 'modelRoot.h', 'nodePath.h', 'nodePath.cxx', 'nodePathCollection.h', 'nodePathComponent.h', 'nodePathLerps.h', 'pandaNode.h', 'planeNode.h', 'pointLight.h', 'polylightNode.h', 'polylightEffect.h', 'portalNode.h', 'portalClipper.h', 'renderAttrib.h', 'renderEffect.h', 'renderEffects.h', 'renderModeAttrib.h', 'renderState.h', 'rescaleNormalAttrib.h', 'sceneGraphAnalyzer.h', 'sceneGraphReducer.h', 'sceneSetup.h', 'selectiveChildNode.h', 'sequenceNode.h', 'showBoundsEffect.h', 'spotlight.h', 'switchNode.h', 'texMatrixAttrib.h', 'texProjectorEffect.h', 'textureApplyAttrib.h', 'textureAttrib.h', 'texGenAttrib.h', 'textureCollection.h', 'textureStageCollection.h', 'transformState.h', 'transparencyAttrib.h', 'weakNodePath.h', 'workingNodePath.h', 'pgraph_composite1.cxx', 'pgraph_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libpgraph_igate.cxx', obj='libpgraph_igate.obj')
+
+#
+# DIRECTORY: panda/src/chan/
+#
+
+IPATH=['panda/src/chan']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='chan_composite1.cxx', obj='chan_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='chan_composite2.cxx', obj='chan_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libchan.in', outc='libchan_igate.cxx',
+            src='panda/src/chan',  module='panda', library='libchan', files=[
+	    'animBundle.h', 'animBundleNode.h', 'animChannel.h', 'animChannelBase.h', 'animChannelMatrixDynamic.h', 'animChannelMatrixXfmTable.h', 'animChannelScalarDynamic.h', 'animChannelScalarTable.h', 'animControl.h', 'animControlCollection.h', 'animGroup.h', 'auto_bind.h', 'config_chan.h', 'movingPartBase.h', 'movingPartMatrix.h', 'movingPartScalar.h', 'partBundle.h', 'partBundleNode.h', 'partGroup.h', 'vector_PartGroupStar.h', 'chan_composite1.cxx', 'chan_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libchan_igate.cxx', obj='libchan_igate.obj')
+
+#
+# DIRECTORY: panda/src/char/
+#
+
+IPATH=['panda/src/char']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='char_composite1.cxx', obj='char_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='char_composite2.cxx', obj='char_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libchar.in', outc='libchar_igate.cxx',
+            src='panda/src/char',  module='panda', library='libchar', files=[
+	    'character.h', 'characterJoint.h', 'characterJointBundle.h', 'characterSlider.h', 'computedVertices.h', 'computedVerticesMorph.h', 'config_char.h', 'dynamicVertices.h', 'char_composite1.cxx', 'char_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libchar_igate.cxx', obj='libchar_igate.obj')
+
+#
+# DIRECTORY: panda/src/dgraph/
+#
+
+IPATH=['panda/src/dgraph']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='dgraph_composite1.cxx', obj='dgraph_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='dgraph_composite2.cxx', obj='dgraph_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libdgraph.in', outc='libdgraph_igate.cxx',
+            src='panda/src/dgraph',  module='panda', library='libdgraph', files=[
+	    'config_dgraph.h', 'dataGraphTraverser.h', 'dataNode.h', 'dataNodeTransmit.h', 'dgraph_composite1.cxx', 'dgraph_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libdgraph_igate.cxx', obj='libdgraph_igate.obj')
+
+#
+# DIRECTORY: panda/src/display/
+#
+
+IPATH=['panda/src/display']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='display_composite1.cxx', obj='display_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='display_composite2.cxx', obj='display_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libdisplay.in', outc='libdisplay_igate.cxx',
+            src='panda/src/display',  module='panda', library='libdisplay', files=[
+	    'config_display.h', 'drawableRegion.h', 'displayRegion.h', 'displayRegionStack.h', 'frameBufferProperties.h', 'frameBufferStack.h', 'graphicsEngine.h', 'graphicsOutput.h', 'graphicsBuffer.h', 'graphicsPipe.h', 'graphicsPipeSelection.h', 'graphicsStateGuardian.h', 'graphicsThreadingModel.h', 'graphicsWindow.h', 'graphicsWindowInputDevice.h', 'graphicsDevice.h', 'parasiteBuffer.h', 'windowProperties.h', 'lensStack.h', 'savedFrameBuffer.h', 'display_composite1.cxx', 'display_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libdisplay_igate.cxx', obj='libdisplay_igate.obj')
+
+#
+# DIRECTORY: panda/src/device/
+#
+
+IPATH=['panda/src/device']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='device_composite1.cxx', obj='device_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='device_composite2.cxx', obj='device_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libdevice.in', outc='libdevice_igate.cxx',
+            src='panda/src/device',  module='panda', library='libdevice', files=[
+	    'analogNode.h', 'buttonNode.h', 'clientAnalogDevice.h', 'clientBase.h', 'clientButtonDevice.h', 'clientDevice.h', 'clientDialDevice.h', 'clientTrackerDevice.h', 'config_device.h', 'dialNode.h', 'mouseAndKeyboard.h', 'trackerData.h', 'trackerNode.h', 'virtualMouse.h', 'device_composite1.cxx', 'device_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libdevice_igate.cxx', obj='libdevice_igate.obj')
+
+#
+# DIRECTORY: panda/src/tform/
+#
+
+IPATH=['panda/src/tform']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='tform_composite1.cxx', obj='tform_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='tform_composite2.cxx', obj='tform_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libtform.in', outc='libtform_igate.cxx',
+            src='panda/src/tform',  module='panda', library='libtform', files=[
+	    'buttonThrower.h', 'config_tform.h', 'driveInterface.h', 'mouseInterfaceNode.h', 'mouseWatcher.h', 'mouseWatcherGroup.h', 'mouseWatcherParameter.h', 'mouseWatcherRegion.h', 'trackball.h', 'transform2sg.h', 'tform_composite1.cxx', 'tform_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libtform_igate.cxx', obj='libtform_igate.obj')
+
+#
+# DIRECTORY: panda/src/collide/
+#
+
+IPATH=['panda/src/collide']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='collide_composite1.cxx', obj='collide_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='collide_composite2.cxx', obj='collide_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libcollide.in', outc='libcollide_igate.cxx',
+            src='panda/src/collide',  module='panda', library='libcollide', files=[
+	    'collisionEntry.h', 'collisionHandler.h', 'collisionHandlerEvent.h', 'collisionHandlerFloor.h', 'collisionHandlerGravity.h', 'collisionHandlerPhysical.h', 'collisionHandlerPusher.h', 'collisionHandlerQueue.h', 'collisionInvSphere.h', 'collisionLine.h', 'collisionLevelState.h', 'collisionNode.h', 'collisionPlane.h', 'collisionPolygon.h', 'collisionRay.h', 'collisionRecorder.h', 'collisionSegment.h', 'collisionSolid.h', 'collisionSphere.h', 'collisionTraverser.h', 'collisionTube.h', 'collisionVisualizer.h', 'config_collide.h', 'collide_composite1.cxx', 'collide_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libcollide_igate.cxx', obj='libcollide_igate.obj')
+
+#
+# DIRECTORY: panda/src/pnmtext/
+#
+
+IPATH=['panda/src/pnmtext']
+OPTS=['BUILDING_PANDA', 'NSPR', 'FREETYPE']
+CompileC(ipath=IPATH, opts=OPTS, src='config_pnmtext.cxx', obj='pnmtext_config_pnmtext.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='freetypeFont.cxx', obj='pnmtext_freetypeFont.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pnmTextGlyph.cxx', obj='pnmtext_pnmTextGlyph.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pnmTextMaker.cxx', obj='pnmtext_pnmTextMaker.obj')
+
+#
+# DIRECTORY: panda/src/text/
+#
+
+IPATH=['panda/src/text']
+OPTS=['BUILDING_PANDA', 'ZLIB', 'NSPR', 'FREETYPE']
+CompileC(ipath=IPATH, opts=OPTS, src='text_composite1.cxx', obj='text_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='text_composite2.cxx', obj='text_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libtext.in', outc='libtext_igate.cxx',
+            src='panda/src/text',  module='panda', library='libtext', files=[
+	    'config_text.h', 'default_font.h', 'dynamicTextFont.h', 'dynamicTextGlyph.h', 'dynamicTextPage.h', 'fontPool.h', 'geomTextGlyph.h', 'staticTextFont.h', 'textAssembler.h', 'textFont.h', 'textGlyph.h', 'textNode.h', 'textProperties.h', 'textPropertiesManager.h', 'text_composite1.cxx', 'text_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libtext_igate.cxx', obj='libtext_igate.obj')
+
+#
+# DIRECTORY: panda/src/grutil/
+#
+
+IPATH=['panda/src/grutil']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='multitexReducer.cxx', obj='grutil_multitexReducer.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='grutil_composite1.cxx', obj='grutil_composite1.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libgrutil.in', outc='libgrutil_igate.cxx',
+            src='panda/src/grutil',  module='panda', library='libgrutil', files=[
+	    'cardMaker.h', 'config_grutil.h', 'frameRateMeter.h', 'lineSegs.h', 'multitexReducer.h', 'multitexReducer.cxx', 'grutil_composite1.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libgrutil_igate.cxx', obj='libgrutil_igate.obj')
+
+#
+# DIRECTORY: panda/src/gsgmisc/
+#
+
+IPATH=['panda/src/gsgmisc']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='geomIssuer.cxx', obj='gsgmisc_geomIssuer.obj')
+
+#
+# DIRECTORY: panda/src/helix/
+#
+
+if (OMIT.count("HELIX")==0):
+  IPATH=['panda/src/helix']
+  OPTS=['BUILDING_PANDA', 'NSPR', 'HELIX']
+  CompileC(ipath=IPATH, opts=OPTS, src='config_helix.cxx', obj='helix_config_helix.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='fivemmap.cxx', obj='helix_fivemmap.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='HelixClient.cxx', obj='helix_HelixClient.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='HxAdviseSink.cxx', obj='helix_HxAdviseSink.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='HxAuthenticationManager.cxx', obj='helix_HxAuthenticationManager.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='HxClientContext.cxx', obj='helix_HxClientContext.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='HxErrorSink.cxx', obj='helix_HxErrorSink.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='HxSiteSupplier.cxx', obj='helix_HxSiteSupplier.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='iids.cxx', obj='helix_iids.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='print.cxx', obj='helix_print.obj')
+  Interrogate(ipath=IPATH, opts=OPTS, outd='libhelix.in', outc='libhelix_igate.cxx',
+              src='panda/src/helix',  module='panda', library='libhelix', files=['HelixClient.cxx'])
+  CompileC(ipath=IPATH, opts=OPTS, src='libhelix_igate.cxx', obj='libhelix_igate.obj')
+  CompileLIB(lib='libhelix.lib', obj=[
+             'helix_config_helix.obj',
+             'helix_fivemmap.obj',
+             'helix_HelixClient.obj',
+             'helix_HxAdviseSink.obj',
+             'helix_HxAuthenticationManager.obj',
+             'helix_HxClientContext.obj',
+             'helix_HxErrorSink.obj',
+             'helix_HxSiteSupplier.obj',
+             'helix_iids.obj',
+             'helix_print.obj',
+             'libhelix_igate.obj'])
+  
+#
+# DIRECTORY: panda/src/parametrics/
+#
+  
+IPATH=['panda/src/parametrics']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='parametrics_composite1.cxx', obj='parametrics_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='parametrics_composite2.cxx', obj='parametrics_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libparametrics.in', outc='libparametrics_igate.cxx',
+            src='panda/src/parametrics',  module='panda', library='libparametrics', files=[
+	    'classicNurbsCurve.h', 'config_parametrics.h', 'cubicCurveseg.h', 'parametricCurveDrawer.h',
+            'curveFitter.h', 'hermiteCurve.h', 'nurbsCurve.h', 'nurbsCurveDrawer.h', 'nurbsCurveEvaluator.h',
+            'nurbsCurveInterface.h', 'nurbsCurveResult.h', 'nurbsBasisVector.h', 'nurbsSurfaceEvaluator.h',
+            'nurbsSurfaceResult.h', 'nurbsVertex.h', 'parametricCurve.h', 'parametricCurveCollection.h',
+            'piecewiseCurve.h', 'ropeNode.h', 'sheetNode.h', 'parametrics_composite1.cxx', 'parametrics_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libparametrics_igate.cxx', obj='libparametrics_igate.obj')
+
+#
+# DIRECTORY: panda/src/pgui/
+#
+
+IPATH=['panda/src/pgui']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pgui_composite1.cxx', obj='pgui_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pgui_composite2.cxx', obj='pgui_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libpgui.in', outc='libpgui_igate.cxx',
+            src='panda/src/pgui',  module='panda', library='libpgui', files=[
+	    'config_pgui.h', 'pgButton.h', 'pgSliderButton.h', 'pgCullTraverser.h', 'pgEntry.h',
+            'pgMouseWatcherGroup.h', 'pgMouseWatcherParameter.h', 'pgFrameStyle.h', 'pgItem.h',
+            'pgMouseWatcherBackground.h', 'pgMouseWatcherRegion.h', 'pgTop.h', 'pgWaitBar.h', 'pgSliderBar.h',
+            'pgui_composite1.cxx', 'pgui_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libpgui_igate.cxx', obj='libpgui_igate.obj')
+
+#
+# DIRECTORY: panda/src/pnmimagetypes/
+#
+
+IPATH=['panda/src/pnmimagetypes', 'panda/src/pnmimage']
+OPTS=['BUILDING_PANDA', 'PNG', 'ZLIB', 'JPEG', 'ZLIB', 'NSPR', 'JPEG', 'TIFF']
+CompileC(ipath=IPATH, opts=OPTS, src='pnmFileTypePNG.cxx', obj='pnmimagetypes_pnmFileTypePNG.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pnmFileTypeTIFF.cxx', obj='pnmimagetypes_pnmFileTypeTIFF.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pnmimagetypes_composite1.cxx', obj='pnmimagetypes_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pnmimagetypes_composite2.cxx', obj='pnmimagetypes_composite2.obj')
+
+#
+# DIRECTORY: panda/src/recorder/
+#
+
+IPATH=['panda/src/recorder']
+OPTS=['BUILDING_PANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='recorder_composite1.cxx', obj='recorder_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='recorder_composite2.cxx', obj='recorder_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='librecorder.in', outc='librecorder_igate.cxx',
+            src='panda/src/recorder',  module='panda', library='librecorder', files=[
+	    'config_recorder.h', 'mouseRecorder.h', 'recorderBase.h', 'recorderController.h', 'recorderFrame.h', 'recorderHeader.h', 'recorderTable.h', 'socketStreamRecorder.h', 'recorder_composite1.cxx', 'recorder_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='librecorder_igate.cxx', obj='librecorder_igate.obj')
+
+#
+# DIRECTORY: panda/src/vrpn/
+#
+
+IPATH=['panda/src/vrpn']
+OPTS=['BUILDING_PANDA', 'NSPR', 'VRPN']
+CompileC(ipath=IPATH, opts=OPTS, src='config_vrpn.cxx', obj='pvrpn_config_vrpn.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrpnClient.cxx', obj='pvrpn_vrpnClient.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrpnAnalog.cxx', obj='pvrpn_vrpnAnalog.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrpnAnalogDevice.cxx', obj='pvrpn_vrpnAnalogDevice.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrpnButton.cxx', obj='pvrpn_vrpnButton.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrpnButtonDevice.cxx', obj='pvrpn_vrpnButtonDevice.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrpnDial.cxx', obj='pvrpn_vrpnDial.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrpnDialDevice.cxx', obj='pvrpn_vrpnDialDevice.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrpnTracker.cxx', obj='pvrpn_vrpnTracker.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrpnTrackerDevice.cxx', obj='pvrpn_vrpnTrackerDevice.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libpvrpn.in', outc='libpvrpn_igate.cxx',
+            src='panda/src/vrpn',  module='panda', library='libpvrpn', files=[
+	    'config_vrpn.cxx', 'config_vrpn.h', 'vrpnClient.cxx', 'vrpnAnalog.cxx', 'vrpnAnalog.h',
+            'vrpnAnalogDevice.cxx', 'vrpnAnalogDevice.h', 'vrpnButton.cxx', 'vrpnButton.h',
+            'vrpnButtonDevice.cxx', 'vrpnButtonDevice.h', 'vrpnClient.h', 'vrpnDial.cxx', 'vrpnDial.h',
+            'vrpnDialDevice.cxx', 'vrpnDialDevice.h', 'vrpnTracker.cxx', 'vrpnTracker.h', 'vrpnTrackerDevice.cxx',
+            'vrpnTrackerDevice.h', 'vrpn_interface.h'])
+CompileC(ipath=IPATH, opts=OPTS, src='libpvrpn_igate.cxx', obj='libpvrpn_igate.obj')
+
+#
+# DIRECTORY: panda/metalibs/panda/
+#
+
+IPATH=['panda/metalibs/panda']
+OPTS=['BUILDING_PANDA', 'ZLIB', 'NSPR', 'HELIX', 'VRPN', 'JPEG', 'TIFF', 'FREETYPE']
+INFILES=['librecorder.in', 'libpgraph.in', 'libpvrpn.in', 'libgrutil.in', 'libchan.in', 'libpstatclient.in',
+         'libchar.in', 'libcollide.in', 'libdevice.in', 'libdgraph.in', 'libdisplay.in', 'libevent.in',
+         'libgobj.in', 'libgsgbase.in', 'liblinmath.in', 'libmathutil.in', 'libnet.in', 'libparametrics.in',
+         'libpnmimage.in', 'libtext.in', 'libtform.in', 'liblerp.in', 'libputil.in', 'libaudio.in',
+         'libpgui.in']
+OBJFILES=['panda_panda.obj', 'libpanda_module.obj', 'recorder_composite1.obj', 'recorder_composite2.obj', 'librecorder_igate.obj',
+          'pgraph_nodePath.obj', 'pgraph_composite1.obj', 'pgraph_composite2.obj', 'libpgraph_igate.obj', 'pvrpn_config_vrpn.obj',
+          'pvrpn_vrpnClient.obj', 'pvrpn_vrpnAnalog.obj', 'pvrpn_vrpnAnalogDevice.obj', 'pvrpn_vrpnButton.obj', 'pvrpn_vrpnButtonDevice.obj',
+          'pvrpn_vrpnDial.obj', 'pvrpn_vrpnDialDevice.obj', 'pvrpn_vrpnTracker.obj', 'pvrpn_vrpnTrackerDevice.obj', 'libpvrpn_igate.obj',
+          'grutil_multitexReducer.obj', 'grutil_composite1.obj', 'libgrutil_igate.obj', 'chan_composite1.obj', 'chan_composite2.obj',
+          'libchan_igate.obj', 'pstatclient_composite1.obj', 'pstatclient_composite2.obj', 'libpstatclient_igate.obj', 'char_composite1.obj',
+          'char_composite2.obj', 'libchar_igate.obj', 'collide_composite1.obj', 'collide_composite2.obj', 'libcollide_igate.obj',
+          'device_composite1.obj', 'device_composite2.obj', 'libdevice_igate.obj', 'dgraph_composite1.obj', 'dgraph_composite2.obj',
+          'libdgraph_igate.obj', 'display_composite1.obj', 'display_composite2.obj', 'libdisplay_igate.obj', 'event_composite1.obj',
+          'libevent_igate.obj', 'gobj_composite1.obj', 'gobj_composite2.obj', 'libgobj_igate.obj', 'gsgbase_composite1.obj',
+          'libgsgbase_igate.obj', 'gsgmisc_geomIssuer.obj', 'linmath_composite1.obj', 'linmath_composite2.obj', 'liblinmath_igate.obj',
+          'mathutil_composite1.obj', 'mathutil_composite2.obj', 'libmathutil_igate.obj', 'net_composite1.obj', 'net_composite2.obj',
+          'libnet_igate.obj', 'parametrics_composite1.obj', 'parametrics_composite2.obj', 'libparametrics_igate.obj',
+          'pnmimagetypes_pnmFileTypePNG.obj', 'pnmimagetypes_pnmFileTypeTIFF.obj', 'pnmimagetypes_composite1.obj',
+          'pnmimagetypes_composite2.obj', 'pnmimage_composite1.obj', 'pnmimage_composite2.obj', 'libpnmimage_igate.obj',
+          'pnmtext_config_pnmtext.obj', 'pnmtext_freetypeFont.obj', 'pnmtext_pnmTextGlyph.obj', 'pnmtext_pnmTextMaker.obj',
+          'text_composite1.obj', 'text_composite2.obj', 'libtext_igate.obj', 'tform_composite1.obj', 'tform_composite2.obj',
+          'libtform_igate.obj', 'lerp_composite1.obj', 'liblerp_igate.obj', 'putil_composite1.obj', 'putil_composite2.obj',
+          'libputil_igate.obj', 'audio_composite1.obj', 'libaudio_igate.obj', 'pgui_composite1.obj', 'pgui_composite2.obj',
+          'libpgui_igate.obj', 'pandabase_pandabase.obj', 'libpandaexpress.dll', 'libdtoolconfig.dll', 'libdtool.dll']
+if (OMIT.count("HELIX")==0):
+  OBJFILES.append("libhelix.lib")
+  INFILES.append("libhelix.in")
+InterrogateModule(outc='libpanda_module.cxx', module='panda', library='libpanda', files=INFILES)
+CompileC(ipath=IPATH, opts=OPTS, src='panda.cxx', obj='panda_panda.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='libpanda_module.cxx', obj='libpanda_module.obj')
+CompileLink(opts=['ADVAPI', 'WINSOCK2', 'WINUSER', 'WINMM', 'HELIX', 'VRPN', 'NSPR',
+		  'ZLIB', 'JPEG', 'PNG', 'TIFF', 'FFTW', 'FREETYPE'],
+            xdep=['built/tmp/dtool_have_helix.dat'],
+            dll='libpanda.dll', obj=OBJFILES)
+
+#
+# DIRECTORY: panda/src/audiotraits/
+#
+
+IPATH=['panda/src/audiotraits']
+OPTS=['BUILDING_FMOD_AUDIO', 'NSPR', 'FMOD']
+CompileC(ipath=IPATH, opts=OPTS, src='fmod_audio_composite1.cxx', obj='fmod_audio_fmod_audio_composite1.obj')
+CompileLink(opts=['ADVAPI', 'WINUSER', 'WINMM', 'FMOD', 'NSPR'], dll='libfmod_audio.dll', obj=[
+             'fmod_audio_fmod_audio_composite1.obj',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+IPATH=['panda/src/audiotraits']
+OPTS=['BUILDING_MILES_AUDIO', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='miles_audio_composite1.cxx', obj='miles_audio_miles_audio_composite1.obj')
+CompileLink(opts=['ADVAPI', 'WINUSER', 'WINMM', 'NSPR'], dll='libmiles_audio.dll', obj=[
+             'miles_audio_miles_audio_composite1.obj',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: panda/src/builder/
+#
+
+IPATH=['panda/src/builder']
+OPTS=['BUILDING_PANDAEGG', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='builder_composite1.cxx', obj='builder_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='builder_composite2.cxx', obj='builder_composite2.obj')
+
+#
+# DIRECTORY: panda/src/distort/
+#
+
+IPATH=['panda/src/distort']
+OPTS=['BUILDING_PANDAFX', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='distort_composite1.cxx', obj='distort_composite1.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libdistort.in', outc='libdistort_igate.cxx',
+            src='panda/src/distort',  module='pandafx', library='libdistort',
+            files=['config_distort.h', 'projectionScreen.h', 'cylindricalLens.h', 'fisheyeLens.h', 'nonlinearImager.h', 'pSphereLens.h', 'distort_composite1.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libdistort_igate.cxx', obj='libdistort_igate.obj')
+
+#
+# DIRECTORY: panda/src/downloadertools/
+#
+
+IPATH=['panda/src/downloadertools']
+OPTS=['OPENSSL', 'ZLIB', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='apply_patch.cxx', obj='apply_patch_apply_patch.obj')
+CompileLink(dll='apply_patch.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'apply_patch_apply_patch.obj',
+             'libpandaexpress.dll',
+             'libpanda.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='build_patch.cxx', obj='build_patch_build_patch.obj')
+CompileLink(dll='build_patch.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'build_patch_build_patch.obj',
+             'libpandaexpress.dll',
+             'libpanda.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+IPATH=['panda/src/downloadertools']
+OPTS=['OPENSSL', 'ZLIB', 'ZLIB', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='check_adler.cxx', obj='check_adler_check_adler.obj')
+CompileLink(dll='check_adler.exe', opts=['ADVAPI', 'NSPR', 'ZLIB'], obj=[
+             'check_adler_check_adler.obj',
+             'libpandaexpress.dll',
+             'libpanda.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='check_crc.cxx', obj='check_crc_check_crc.obj')
+CompileLink(dll='check_crc.exe', opts=['ADVAPI', 'NSPR', 'ZLIB'], obj=[
+             'check_crc_check_crc.obj',
+             'libpandaexpress.dll',
+             'libpanda.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+IPATH=['panda/src/downloadertools']
+OPTS=['OPENSSL', 'ZLIB', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='check_md5.cxx', obj='check_md5_check_md5.obj')
+CompileLink(dll='check_md5.exe', opts=['ADVAPI', 'NSPR', 'OPENSSL'], obj=[
+             'check_md5_check_md5.obj',
+             'libpandaexpress.dll',
+             'libpanda.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='multify.cxx', obj='multify_multify.obj')
+CompileLink(dll='multify.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'multify_multify.obj',
+             'libpandaexpress.dll',
+             'libpanda.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+IPATH=['panda/src/downloadertools']
+OPTS=['OPENSSL', 'ZLIB', 'ZLIB', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pcompress.cxx', obj='pcompress_pcompress.obj')
+CompileLink(dll='pcompress.exe', opts=['ADVAPI', 'NSPR', 'ZLIB'], obj=[
+             'pcompress_pcompress.obj',
+             'libpandaexpress.dll',
+             'libpanda.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='pdecompress.cxx', obj='pdecompress_pdecompress.obj')
+CompileLink(dll='pdecompress.exe', opts=['ADVAPI', 'NSPR', 'ZLIB'], obj=[
+             'pdecompress_pdecompress.obj',
+             'libpandaexpress.dll',
+             'libpanda.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+IPATH=['panda/src/downloadertools']
+OPTS=['OPENSSL', 'ZLIB', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pdecrypt.cxx', obj='pdecrypt_pdecrypt.obj')
+CompileLink(dll='pdecrypt.exe', opts=['ADVAPI', 'NSPR', 'OPENSSL'], obj=[
+             'pdecrypt_pdecrypt.obj',
+             'libpandaexpress.dll',
+             'libpanda.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='pencrypt.cxx', obj='pencrypt_pencrypt.obj')
+CompileLink(dll='pencrypt.exe', opts=['ADVAPI', 'NSPR', 'OPENSSL'], obj=[
+             'pencrypt_pencrypt.obj',
+             'libpandaexpress.dll',
+             'libpanda.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='show_ddb.cxx', obj='show_ddb_show_ddb.obj')
+CompileLink(dll='show_ddb.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'show_ddb_show_ddb.obj',
+             'libpandaexpress.dll',
+             'libpanda.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: panda/src/glgsg/
+#
+
+IPATH=['panda/src/glgsg', 'panda/src/glstuff', 'panda/src/gobj']
+OPTS=['BUILDING_PANDAGL', 'NSPR', 'NVIDIACG']
+CompileC(ipath=IPATH, opts=OPTS, src='config_glgsg.cxx', obj='glgsg_config_glgsg.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='glgsg.cxx', obj='glgsg_glgsg.obj')
+
+#
+# DIRECTORY: panda/src/effects/
+#
+
+IPATH=['panda/src/effects']
+OPTS=['BUILDING_PANDAFX', 'NSPR', 'NVIDIACG']
+CompileC(ipath=IPATH, opts=OPTS, src='effects_composite1.cxx', obj='effects_composite1.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libeffects.in', outc='libeffects_igate.cxx',
+            src='panda/src/effects',  module='pandafx', library='libeffects',
+            files=['config_effects.h', 'cgShader.h', 'cgShaderAttrib.h', 'cgShaderContext.h', 'lensFlareNode.h', 'effects_composite1.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libeffects_igate.cxx', obj='libeffects_igate.obj')
+
+#
+# DIRECTORY: panda/metalibs/pandafx/
+#
+
+IPATH=['panda/metalibs/pandafx', 'panda/src/distort']
+OPTS=['BUILDING_PANDAFX', 'NSPR', 'NVIDIACG']
+CompileC(ipath=IPATH, opts=OPTS, src='pandafx.cxx', obj='pandafx_pandafx.obj')
+InterrogateModule(outc='libpandafx_module.cxx', module='pandafx', library='libpandafx',
+                  files=['libdistort.in', 'libeffects.in'])
+CompileC(ipath=IPATH, opts=OPTS, src='libpandafx_module.cxx', obj='libpandafx_module.obj')
+CompileLink(dll='libpandafx.dll', opts=['ADVAPI', 'NSPR', 'NVIDIACG'], obj=[
+             'pandafx_pandafx.obj',
+             'libpandafx_module.obj',
+             'distort_composite1.obj',
+             'libdistort_igate.obj',
+             'effects_composite1.obj',
+             'libeffects_igate.obj',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: panda/src/glstuff/
+#
+
+IPATH=['panda/src/glstuff']
+OPTS=['NSPR', 'NVIDIACG', 'CGGL']
+CompileC(ipath=IPATH, opts=OPTS, src='glpure.cxx', obj='glstuff_glpure.obj')
+CompileLink(dll='libglstuff.dll', opts=['ADVAPI', 'GLUT', 'NSPR', 'NVIDIACG', 'CGGL'], obj=[
+             'glstuff_glpure.obj',
+             'libpanda.dll',
+             'libpandafx.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: panda/src/windisplay/
+#
+
+if (sys.platform == "win32"):
+
+  IPATH=['panda/src/windisplay']
+  OPTS=['BUILDING_PANDAWIN', 'NSPR']
+  CompileC(ipath=IPATH, opts=OPTS, src='winGraphicsWindow.cxx', obj='windisplay_winGraphicsWindow.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='config_windisplay.cxx', obj='windisplay_config_windisplay.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='winGraphicsPipe.cxx', obj='windisplay_winGraphicsPipe.obj')
+  CompileLink(opts=['WINIMM', 'WINGDI', 'WINKERNEL', 'WINOLDNAMES', 'WINUSER', 'WINMM', 'NSPR'],
+              dll='libwindisplay.dll', obj=[
+    'windisplay_winGraphicsWindow.obj',
+    'windisplay_config_windisplay.obj',
+    'windisplay_winGraphicsPipe.obj',
+    'libpanda.dll',
+    'libpandaexpress.dll',
+    'libdtoolconfig.dll',
+    'libdtool.dll',
+    ])
+
+#
+# DIRECTORY: panda/src/glxdisplay/
+#
+
+if (sys.platform != "win32"):
+
+  IPATH=['panda/src/glxdisplay', 'panda/src/gobj']
+  OPTS=['BUILDING_PANDAGLUT', 'NSPR', 'GLUT', 'NVIDIACG', 'CGGL']
+  CompileC(ipath=IPATH, opts=OPTS, src='config_glxdisplay.cxx',        obj='glxdisplay_config_glxdisplay.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='glxGraphicsBuffer.cxx',        obj='glxdisplay_glxGraphicsBuffer.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='glxGraphicsPipe.cxx',          obj='glxdisplay_glxGraphicsPipe.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='glxGraphicsStateGuardian.cxx', obj='glxdisplay_glxGraphicsStateGuardian.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='glxGraphicsWindow.cxx',        obj='glxdisplay_glxGraphicsWindow.obj')
+  Interrogate(ipath=IPATH, opts=OPTS, outd='libglxdisplay.in', outc='libglxdisplay_igate.cxx',
+              src='panda/src/glxdisplay',  module='pandagl', library='libglxdisplay', files=['glxGraphicsPipe.h'])
+  CompileC(ipath=IPATH, opts=OPTS, src='libglxdisplay_igate.cxx',      obj='libglxdisplay_igate.obj')
+
+  IPATH=['panda/metalibs/pandagl']
+  OPTS=['BUILDING_PANDAGL', 'NSPR', 'NVIDIACG', 'CGGL']
+  CompileC(ipath=IPATH, opts=OPTS, src='pandagl.cxx', obj='pandagl_pandagl.obj')
+  CompileLink(opts=['GLUT', 'NVIDIACG', 'CGGL', 'NSPR'], dll='libpandagl.dll', obj=[
+    'pandagl_pandagl.obj',
+    'glgsg_config_glgsg.obj',
+    'glgsg_glgsg.obj',
+    'glxdisplay_config_glxdisplay.obj',
+    'glxdisplay_glxGraphicsBuffer.obj',
+    'glxdisplay_glxGraphicsPipe.obj',
+    'glxdisplay_glxGraphicsStateGuardian.obj',
+    'glxdisplay_glxGraphicsWindow.obj',
+    'libglxdisplay_igate.obj',
+    'libpanda.dll',
+    'libpandaexpress.dll',
+    'libglstuff.dll',
+    'libpandafx.dll',
+    'libdtoolconfig.dll',
+    'libdtool.dll',
+    ])
+
+#
+# DIRECTORY: panda/src/wgldisplay/
+#
+
+if (sys.platform == "win32"):
+  
+  IPATH=['panda/src/wgldisplay', 'panda/src/glstuff', 'panda/src/gobj']
+  OPTS=['BUILDING_PANDAGL', 'NSPR', 'NVIDIACG', 'CGGL']
+  CompileC(ipath=IPATH, opts=OPTS, src='wgldisplay_composite1.cxx', obj='wgldisplay_composite1.obj')
+
+  IPATH=['panda/metalibs/pandagl']
+  OPTS=['BUILDING_PANDAGL', 'NSPR', 'NVIDIACG', 'CGGL']
+  CompileC(ipath=IPATH, opts=OPTS, src='pandagl.cxx', obj='pandagl_pandagl.obj')
+  CompileLink(opts=['WINGDI', 'GLUT', 'WINKERNEL', 'WINOLDNAMES', 'WINUSER', 'WINMM', 'NSPR', 'NVIDIACG', 'CGGL'],
+              dll='libpandagl.dll', obj=[
+    'pandagl_pandagl.obj',
+    'glgsg_config_glgsg.obj',
+    'glgsg_glgsg.obj',
+    'wgldisplay_composite1.obj',
+    'libwindisplay.dll',
+    'libpanda.dll',
+    'libpandaexpress.dll',
+    'libglstuff.dll',
+    'libpandafx.dll',
+    'libdtoolconfig.dll',
+    'libdtool.dll',
+    ])
+
+#
+# DIRECTORY: panda/metalibs/pandadx7/
+#
+
+if (sys.platform == "win32"):
+
+  IPATH=['panda/src/dxgsg7']
+  OPTS=['BUILDING_PANDADX', 'DXSDK', 'NSPR']
+  CompileC(ipath=IPATH, opts=OPTS, src='dxGraphicsStateGuardian7.cxx', obj='dxgsg7_dxGraphicsStateGuardian7.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='dxgsg7_composite1.cxx', obj='dxgsg7_composite1.obj')
+  
+  IPATH=['panda/metalibs/pandadx7']
+  OPTS=['BUILDING_PANDADX', 'DXSDK', 'NSPR']
+  CompileC(ipath=IPATH, opts=OPTS, src='pandadx7.cxx', obj='pandadx7_pandadx7.obj')
+  CompileLink(dll='libpandadx7.dll', opts=['ADVAPI', 'WINGDI', 'WINKERNEL', 'WINUSER', 'WINMM', 'DXDRAW', 'DXGUID', 'D3D8', 'NSPR'], obj=[
+    'pandadx7_pandadx7.obj',
+    'dxgsg7_dxGraphicsStateGuardian7.obj',
+    'dxgsg7_composite1.obj',
+    'libpanda.dll',
+    'libpandaexpress.dll',
+    'libwindisplay.dll',
+    'libdtoolconfig.dll',
+    'libdtool.dll',
+    ])
+  
+#
+# DIRECTORY: panda/metalibs/pandadx8/
+#
+
+if (sys.platform == "win32"):
+  IPATH=['panda/src/dxgsg8']
+  OPTS=['BUILDING_PANDADX', 'DXSDK', 'NSPR']
+  CompileC(ipath=IPATH, opts=OPTS, src='dxGraphicsStateGuardian8.cxx', obj='dxgsg8_dxGraphicsStateGuardian8.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='dxgsg8_composite1.cxx', obj='dxgsg8_composite1.obj')
+  
+  IPATH=['panda/metalibs/pandadx8']
+  OPTS=['BUILDING_PANDADX', 'DXSDK', 'NSPR']
+  CompileC(ipath=IPATH, opts=OPTS, src='pandadx8.cxx', obj='pandadx8_pandadx8.obj')
+  CompileLink(dll='libpandadx8.dll', opts=['ADVAPI', 'WINGDI', 'WINKERNEL', 'WINUSER', 'WINMM', 'DXDRAW', 'DXGUID', 'D3D8', 'NSPR'], obj=[
+    'pandadx8_pandadx8.obj',
+    'dxgsg8_dxGraphicsStateGuardian8.obj',
+    'dxgsg8_composite1.obj',
+    'libpanda.dll',
+    'libpandaexpress.dll',
+    'libwindisplay.dll',
+    'libdtoolconfig.dll',
+    'libdtool.dll',
+    ])
+
+#
+# DIRECTORY: panda/metalibs/pandadx9/
+#
+
+if (sys.platform == "win32"):
+
+  IPATH=['panda/src/dxgsg9']
+  OPTS=['BUILDING_PANDADX', 'DXSDK', 'NSPR']
+  CompileC(ipath=IPATH, opts=OPTS, src='dxGraphicsStateGuardian9.cxx', obj='dxgsg9_dxGraphicsStateGuardian9.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='dxgsg9_composite1.cxx', obj='dxgsg9_composite1.obj')
+  
+  IPATH=['panda/metalibs/pandadx9']
+  OPTS=['BUILDING_PANDADX', 'DXSDK', 'NSPR']
+  CompileC(ipath=IPATH, opts=OPTS, src='pandadx9.cxx', obj='pandadx9_pandadx9.obj')
+  CompileLink(dll='libpandadx9.dll', opts=['ADVAPI', 'WINGDI', 'WINKERNEL', 'WINUSER', 'WINMM', 'DXDRAW', 'DXGUID', 'D3D9', 'NSPR'], obj=[
+    'pandadx9_pandadx9.obj',
+    'dxgsg9_dxGraphicsStateGuardian9.obj',
+    'dxgsg9_composite1.obj',
+    'libpanda.dll',
+    'libpandaexpress.dll',
+    'libwindisplay.dll',
+    'libdtoolconfig.dll',
+    'libdtool.dll',
+    ])
+
+#
+# DIRECTORY: panda/src/egg/
+#
+
+IPATH=['panda/src/egg']
+CompileBison(pre='eggyy', dstc='parser.cxx', dsth='parser.h', src='panda/src/egg/parser.yxx')
+CompileFlex(pre='eggyy', dst='lexer.cxx', src='panda/src/egg/lexer.lxx', dashi=1)
+OPTS=['BUILDING_PANDAEGG', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='egg_composite1.cxx', obj='egg_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='egg_composite2.cxx', obj='egg_composite2.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='parser.cxx', obj='egg_parser.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='lexer.cxx', obj='egg_lexer.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libegg.in', outc='libegg_igate.cxx',
+            src='panda/src/egg',  module='pandaegg', library='libegg', files=[
+            'config_egg.h', 'eggAnimData.h', 'eggAttributes.h', 'eggBin.h', 'eggBinMaker.h', 'eggComment.h',
+            'eggCoordinateSystem.h', 'eggCurve.h', 'eggData.h', 'eggExternalReference.h', 'eggFilenameNode.h',
+            'eggGroup.h', 'eggGroupNode.h', 'eggGroupUniquifier.h', 'eggLine.h', 'eggMaterial.h',
+            'eggMaterialCollection.h', 'eggMiscFuncs.h', 'eggMorph.h', 'eggMorphList.h', 'eggNamedObject.h',
+            'eggNameUniquifier.h', 'eggNode.h', 'eggNurbsCurve.h', 'eggNurbsSurface.h', 'eggObject.h',
+            'eggParameters.h', 'eggPoint.h', 'eggPolygon.h', 'eggPolysetMaker.h', 'eggPoolUniquifier.h',
+            'eggPrimitive.h', 'eggRenderMode.h', 'eggSAnimData.h', 'eggSurface.h', 'eggSwitchCondition.h',
+            'eggTable.h', 'eggTexture.h', 'eggTextureCollection.h', 'eggTransform3d.h', 'eggUserData.h',
+            'eggUtilities.h', 'eggVertex.h', 'eggVertexPool.h', 'eggVertexUV.h', 'eggXfmAnimData.h',
+            'eggXfmSAnim.h', 'parserDefs.h', 'lexerDefs.h', 'pt_EggMaterial.h', 'vector_PT_EggMaterial.h',
+            'pt_EggTexture.h', 'vector_PT_EggTexture.h', 'pt_EggVertex.h', 'vector_PT_EggVertex.h',
+            'egg_composite1.cxx', 'egg_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libegg_igate.cxx', obj='libegg_igate.obj')
+
+#
+# DIRECTORY: panda/src/egg2pg/
+#
+
+IPATH=['panda/src/egg2pg']
+OPTS=['BUILDING_PANDAEGG', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='egg2pg_composite1.cxx', obj='egg2pg_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='egg2pg_composite2.cxx', obj='egg2pg_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libegg2pg.in', outc='libegg2pg_igate.cxx',
+            src='panda/src/egg2pg',  module='pandaegg', library='libegg2pg', files=['load_egg_file.h'])
+CompileC(ipath=IPATH, opts=OPTS, src='libegg2pg_igate.cxx', obj='libegg2pg_igate.obj')
+
+#
+# DIRECTORY: panda/src/framework/
+#
+
+IPATH=['panda/src/framework']
+OPTS=['BUILDING_FRAMEWORK', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='config_framework.cxx', obj='framework_config_framework.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pandaFramework.cxx', obj='framework_pandaFramework.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='windowFramework.cxx', obj='framework_windowFramework.obj')
+CompileLink(dll='libframework.dll', opts=['ADVAPI', 'NSPR'], obj=[
+             'framework_config_framework.obj',
+             'framework_pandaFramework.obj',
+             'framework_windowFramework.obj',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             ])
+
+#
+# DIRECTORY: panda/metalibs/pandaegg/
+#
+
+IPATH=['panda/metalibs/pandaegg', 'panda/src/egg']
+OPTS=['BUILDING_PANDAEGG', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pandaegg.cxx', obj='pandaegg_pandaegg.obj')
+InterrogateModule(outc='libpandaegg_module.cxx', module='pandaegg', library='libpandaegg',
+                  files=['libegg2pg.in', 'libegg.in'])
+CompileC(ipath=IPATH, opts=OPTS, src='libpandaegg_module.cxx', obj='libpandaegg_module.obj')
+CompileLink(dll='libpandaegg.dll', opts=['ADVAPI', 'NSPR'], obj=[
+             'pandaegg_pandaegg.obj',
+             'libpandaegg_module.obj',
+             'egg2pg_composite1.obj',
+             'egg2pg_composite2.obj',
+             'libegg2pg_igate.obj',
+             'egg_composite1.obj',
+             'egg_composite2.obj',
+             'egg_parser.obj',
+             'egg_lexer.obj',
+             'libegg_igate.obj',
+             'builder_composite1.obj',
+             'builder_composite2.obj',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: panda/src/physics/
+#
+
+IPATH=['panda/src/physics']
+OPTS=['BUILDING_PANDAPHYSICS', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='physics_composite1.cxx', obj='physics_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='physics_composite2.cxx', obj='physics_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libphysics.in', outc='libphysics_igate.cxx',
+            src='panda/src/physics',  module='pandaphysics', library='libphysics',
+            files=['actorNode.h', 'angularEulerIntegrator.h', 'angularForce.h', 'angularIntegrator.h', 'angularVectorForce.h', 'baseForce.h', 'baseIntegrator.h', 'config_physics.h', 'forceNode.h', 'linearCylinderVortexForce.h', 'linearDistanceForce.h', 'linearEulerIntegrator.h', 'linearForce.h', 'linearFrictionForce.h', 'linearIntegrator.h', 'linearJitterForce.h', 'linearNoiseForce.h', 'linearRandomForce.h', 'linearSinkForce.h', 'linearSourceForce.h', 'linearUserDefinedForce.h', 'linearVectorForce.h', 'physical.h', 'physicalNode.h', 'physicsCollisionHandler.h', 'physicsManager.h', 'physicsObject.h', 'physics_composite1.cxx', 'physics_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libphysics_igate.cxx', obj='libphysics_igate.obj')
+
+#
+# DIRECTORY: panda/src/particlesystem/
+#
+
+IPATH=['panda/src/particlesystem']
+OPTS=['BUILDING_PANDAPHYSICS', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='particlesystem_composite1.cxx', obj='particlesystem_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='particlesystem_composite2.cxx', obj='particlesystem_composite2.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libparticlesystem.in', outc='libparticlesystem_igate.cxx',
+            src='panda/src/particlesystem',  module='pandaphysics', library='libparticlesystem',
+            files=['baseParticle.h', 'baseParticleEmitter.h', 'baseParticleFactory.h', 'baseParticleRenderer.h', 'boxEmitter.h', 'config_particlesystem.h', 'discEmitter.h', 'geomParticleRenderer.h', 'lineEmitter.h', 'lineParticleRenderer.h', 'particleSystem.h', 'particleSystemManager.h', 'pointEmitter.h', 'pointParticle.h', 'pointParticleFactory.h', 'pointParticleRenderer.h', 'rectangleEmitter.h', 'ringEmitter.h', 'sparkleParticleRenderer.h', 'sphereSurfaceEmitter.h', 'sphereVolumeEmitter.h', 'spriteParticleRenderer.h', 'tangentRingEmitter.h', 'zSpinParticle.h', 'zSpinParticleFactory.h', 'particleCommonFuncs.h', 'particlesystem_composite1.cxx', 'particlesystem_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libparticlesystem_igate.cxx', obj='libparticlesystem_igate.obj')
+
+#
+# DIRECTORY: panda/metalibs/pandaphysics/
+#
+
+IPATH=['panda/metalibs/pandaphysics']
+OPTS=['BUILDING_PANDAPHYSICS', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pandaphysics.cxx', obj='pandaphysics_pandaphysics.obj')
+InterrogateModule(outc='libpandaphysics_module.cxx', module='pandaphysics', library='libpandaphysics',
+                  files=['libphysics.in', 'libparticlesystem.in'])
+CompileC(ipath=IPATH, opts=OPTS, src='libpandaphysics_module.cxx', obj='libpandaphysics_module.obj')
+CompileLink(dll='libpandaphysics.dll', opts=['ADVAPI', 'NSPR'], obj=[
+             'pandaphysics_pandaphysics.obj',
+             'libpandaphysics_module.obj',
+             'physics_composite1.obj',
+             'physics_composite2.obj',
+             'libphysics_igate.obj',
+             'particlesystem_composite1.obj',
+             'particlesystem_composite2.obj',
+             'libparticlesystem_igate.obj',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: panda/src/testbed/
+#
+
+IPATH=['panda/src/testbed']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pview.cxx', obj='pview_pview.obj')
+CompileLink(dll='pview.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'pview_pview.obj',
+             'libframework.dll',
+             'libpanda.dll',
+             'libpandafx.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: direct/src/directbase/
+#
+
+IPATH=['direct/src/directbase']
+OPTS=['BUILDING_DIRECT', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='directbase.cxx', obj='directbase_directbase.obj')
+
+#
+# DIRECTORY: direct/src/dcparser/
+#
+
+CompileBison(pre='dcyy', dstc='dcParser.cxx', dsth='dcParser.h', src='direct/src/dcparser/dcParser.yxx')
+CompileFlex(pre='dcyy', dst='dcLexer.cxx', src='direct/src/dcparser/dcLexer.lxx', dashi=0)
+IPATH=['direct/src/dcparser']
+OPTS=['WITHINPANDA', 'BUILDING_DIRECT', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='dcparser_composite1.cxx', obj='dcparser_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='dcparser_composite2.cxx', obj='dcparser_composite2.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='dcParser.cxx', obj='dcparser_dcParser.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='dcLexer.cxx', obj='dcparser_dcLexer.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libdcparser.in', outc='libdcparser_igate.cxx',
+            src='direct/src/dcparser',  module='direct', library='libdcparser',
+            files=['dcAtomicField.h', 'dcClass.h', 'dcDeclaration.h', 'dcField.h', 'dcFile.h', 'dcLexerDefs.h', 'dcMolecularField.h', 'dcParserDefs.h', 'dcSubatomicType.h', 'dcPackData.h', 'dcPacker.h', 'dcPackerCatalog.h', 'dcPackerInterface.h', 'dcParameter.h', 'dcClassParameter.h', 'dcArrayParameter.h', 'dcSimpleParameter.h', 'dcSwitchParameter.h', 'dcNumericRange.h', 'dcSwitch.h', 'dcTypedef.h', 'dcPython.h', 'dcbase.h', 'dcindent.h', 'hashGenerator.h', 'primeNumberGenerator.h', 'dcparser_composite1.cxx', 'dcparser_composite2.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libdcparser_igate.cxx', obj='libdcparser_igate.obj')
+
+#
+# DIRECTORY: direct/src/deadrec/
+#
+
+IPATH=['direct/src/deadrec']
+OPTS=['BUILDING_DIRECT', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='deadrec_composite1.cxx', obj='deadrec_composite1.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libdeadrec.in', outc='libdeadrec_igate.cxx',
+            src='direct/src/deadrec',  module='direct', library='libdeadrec',
+            files=['smoothMover.h', 'deadrec_composite1.cxx'])
+CompileC(ipath=IPATH, opts=OPTS, src='libdeadrec_igate.cxx', obj='libdeadrec_igate.obj')
+
+#
+# DIRECTORY: direct/src/distributed/
+#
+
+IPATH=['direct/src/distributed', 'direct/src/dcparser']
+OPTS=['WITHINPANDA', 'BUILDING_DIRECT', 'OPENSSL', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='config_distributed.cxx', obj='distributed_config_distributed.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='cConnectionRepository.cxx', obj='distributed_cConnectionRepository.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='cDistributedSmoothNodeBase.cxx', obj='distributed_cDistributedSmoothNodeBase.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libdistributed.in', outc='libdistributed_igate.cxx',
+            src='direct/src/distributed',  module='direct', library='libdistributed',
+            files=['config_distributed.cxx', 'config_distributed.h', 'cConnectionRepository.cxx', 'cConnectionRepository.h', 'cDistributedSmoothNodeBase.cxx', 'cDistributedSmoothNodeBase.h'])
+CompileC(ipath=IPATH, opts=OPTS, src='libdistributed_igate.cxx', obj='libdistributed_igate.obj')
+
+#
+# DIRECTORY: direct/src/interval/
+#
+
+IPATH=['direct/src/interval']
+OPTS=['BUILDING_DIRECT', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='config_interval.cxx', obj='interval_config_interval.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='cInterval.cxx', obj='interval_cInterval.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='cIntervalManager.cxx', obj='interval_cIntervalManager.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='cLerpInterval.cxx', obj='interval_cLerpInterval.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='cLerpNodePathInterval.cxx', obj='interval_cLerpNodePathInterval.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='cLerpAnimEffectInterval.cxx', obj='interval_cLerpAnimEffectInterval.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='cMetaInterval.cxx', obj='interval_cMetaInterval.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='hideInterval.cxx', obj='interval_hideInterval.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='showInterval.cxx', obj='interval_showInterval.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='waitInterval.cxx', obj='interval_waitInterval.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libinterval.in', outc='libinterval_igate.cxx',
+            src='direct/src/interval',  module='direct', library='libinterval',
+            files=['config_interval.cxx', 'config_interval.h', 'cInterval.cxx', 'cInterval.h', 'cIntervalManager.cxx', 'cIntervalManager.h', 'cLerpInterval.cxx', 'cLerpInterval.h', 'cLerpNodePathInterval.cxx', 'cLerpNodePathInterval.h', 'cLerpAnimEffectInterval.cxx', 'cLerpAnimEffectInterval.h', 'cMetaInterval.cxx', 'cMetaInterval.h', 'hideInterval.cxx', 'hideInterval.h', 'showInterval.cxx', 'showInterval.h', 'waitInterval.cxx', 'waitInterval.h', 'lerp_helpers.h'])
+CompileC(ipath=IPATH, opts=OPTS, src='libinterval_igate.cxx', obj='libinterval_igate.obj')
+
+#
+# DIRECTORY: direct/src/showbase/
+#
+
+IPATH=['direct/src/showbase']
+OPTS=['BUILDING_DIRECT', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='showBase.cxx', obj='showbase_showBase.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='mersenne.cxx', obj='showbase_mersenne.obj')
+Interrogate(ipath=IPATH, opts=OPTS, outd='libshowbase.in', outc='libshowbase_igate.cxx',
+            src='direct/src/showbase', module='direct', library='libshowbase',
+            files=['showBase.cxx', 'showBase.h', 'mersenne.cxx', 'mersenne.h'])
+CompileC(ipath=IPATH, opts=OPTS, src='libshowbase_igate.cxx', obj='libshowbase_igate.obj')
+
+#
+# DIRECTORY: direct/metalibs/direct/
+#
+
+IPATH=['direct/metalibs/direct']
+OPTS=['BUILDING_DIRECT', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='direct.cxx', obj='direct_direct.obj')
+InterrogateModule(outc='libdirect_module.cxx', module='direct', library='libdirect',
+                  files=['libdcparser.in', 'libshowbase.in', 'libdeadrec.in', 'libinterval.in', 'libdistributed.in'])
+CompileC(ipath=IPATH, opts=OPTS, src='libdirect_module.cxx', obj='libdirect_module.obj')
+CompileLink(dll='libdirect.dll', opts=['ADVAPI', 'NSPR', 'OPENSSL'], obj=[
+             'direct_direct.obj',
+             'libdirect_module.obj',
+             'directbase_directbase.obj',
+             'dcparser_composite1.obj',
+             'dcparser_composite2.obj',
+             'dcparser_dcParser.obj',
+             'dcparser_dcLexer.obj',
+             'libdcparser_igate.obj',
+             'showbase_showBase.obj',
+             'showbase_mersenne.obj',
+             'libshowbase_igate.obj',
+             'deadrec_composite1.obj',
+             'libdeadrec_igate.obj',
+             'interval_config_interval.obj',
+             'interval_cInterval.obj',
+             'interval_cIntervalManager.obj',
+             'interval_cLerpInterval.obj',
+             'interval_cLerpNodePathInterval.obj',
+             'interval_cLerpAnimEffectInterval.obj',
+             'interval_cMetaInterval.obj',
+             'interval_hideInterval.obj',
+             'interval_showInterval.obj',
+             'interval_waitInterval.obj',
+             'libinterval_igate.obj',
+             'distributed_config_distributed.obj',
+             'distributed_cConnectionRepository.obj',
+             'distributed_cDistributedSmoothNodeBase.obj',
+             'libdistributed_igate.obj',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: direct/src/dcparse/
+#
+
+IPATH=['direct/src/dcparse', 'direct/src/dcparser']
+OPTS=['WITHINPANDA', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='dcparse.cxx', obj='dcparse_dcparse.obj')
+CompileLink(dll='dcparse.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'dcparse_dcparse.obj',
+             'libdirect.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: direct/src/heapq/
+#
+
+IPATH=['direct/src/heapq']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='heapq.cxx', obj='heapq_heapq.obj')
+CompileLink(dll='libheapq.dll', opts=['ADVAPI', 'NSPR'], obj=[
+             'heapq_heapq.obj',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/pandatoolbase/
+#
+
+IPATH=['pandatool/src/pandatoolbase']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='animationConvert.cxx', obj='pandatoolbase_animationConvert.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='config_pandatoolbase.cxx', obj='pandatoolbase_config_pandatoolbase.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='distanceUnit.cxx', obj='pandatoolbase_distanceUnit.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pandatoolbase.cxx', obj='pandatoolbase_pandatoolbase.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pathReplace.cxx', obj='pandatoolbase_pathReplace.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pathStore.cxx', obj='pandatoolbase_pathStore.obj')
+CompileLIB(lib='libpandatoolbase.lib', obj=[
+             'pandatoolbase_animationConvert.obj',
+             'pandatoolbase_config_pandatoolbase.obj',
+             'pandatoolbase_distanceUnit.obj',
+             'pandatoolbase_pandatoolbase.obj',
+             'pandatoolbase_pathReplace.obj',
+             'pandatoolbase_pathStore.obj',
+])
+
+#
+# DIRECTORY: pandatool/src/converter/
+#
+
+IPATH=['pandatool/src/converter']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='somethingToEggConverter.cxx', obj='converter_somethingToEggConverter.obj')
+CompileLIB(lib='libconverter.lib', obj=['converter_somethingToEggConverter.obj'])
+
+#
+# DIRECTORY: pandatool/src/progbase/
+#
+
+IPATH=['pandatool/src/progbase']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='progbase_composite1.cxx', obj='progbase_composite1.obj')
+CompileLIB(lib='libprogbase.lib', obj=['progbase_composite1.obj'])
+
+#
+# DIRECTORY: pandatool/src/eggbase/
+#
+
+IPATH=['pandatool/src/eggbase']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='eggbase_composite1.cxx', obj='eggbase_composite1.obj')
+CompileLIB(lib='libeggbase.lib', obj=['eggbase_composite1.obj'])
+
+#
+# DIRECTORY: pandatool/src/bam/
+#
+
+IPATH=['pandatool/src/bam']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='bamInfo.cxx', obj='bam-info_bamInfo.obj')
+CompileLink(dll='bam-info.exe', opts=['ADVAPI', 'NSPR', 'FFTW'], obj=[
+             'bam-info_bamInfo.obj',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='bamToEgg.cxx', obj='bam2egg_bamToEgg.obj')
+CompileLink(dll='bam2egg.exe', opts=['ADVAPI', 'NSPR', 'FFTW'], obj=[
+             'bam2egg_bamToEgg.obj',
+             'libconverter.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='eggToBam.cxx', obj='egg2bam_eggToBam.obj')
+CompileLink(dll='egg2bam.exe', opts=['ADVAPI', 'NSPR', 'FFTW'], obj=[
+             'egg2bam_eggToBam.obj',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libconverter.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/cvscopy/
+#
+
+IPATH=['pandatool/src/cvscopy']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='cvscopy_composite1.cxx', obj='cvscopy_composite1.obj')
+CompileLIB(lib='libcvscopy.lib', obj=['cvscopy_composite1.obj'])
+
+#
+# DIRECTORY: pandatool/src/dxf/
+#
+
+IPATH=['pandatool/src/dxf']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='dxfFile.cxx', obj='dxf_dxfFile.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='dxfLayer.cxx', obj='dxf_dxfLayer.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='dxfLayerMap.cxx', obj='dxf_dxfLayerMap.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='dxfVertex.cxx', obj='dxf_dxfVertex.obj')
+CompileLIB(lib='libdxf.lib', obj=[
+             'dxf_dxfFile.obj',
+             'dxf_dxfLayer.obj',
+             'dxf_dxfLayerMap.obj',
+             'dxf_dxfVertex.obj',
+])
+
+#
+# DIRECTORY: pandatool/src/dxfegg/
+#
+
+IPATH=['pandatool/src/dxfegg']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='dxfToEggConverter.cxx', obj='dxfegg_dxfToEggConverter.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='dxfToEggLayer.cxx', obj='dxfegg_dxfToEggLayer.obj')
+CompileLIB(lib='libdxfegg.lib', obj=[
+             'dxfegg_dxfToEggConverter.obj',
+             'dxfegg_dxfToEggLayer.obj',
+])
+
+#
+# DIRECTORY: pandatool/src/dxfprogs/
+#
+
+IPATH=['pandatool/src/dxfprogs']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='dxfPoints.cxx', obj='dxf-points_dxfPoints.obj')
+CompileLink(dll='dxf-points.exe', opts=['ADVAPI', 'NSPR', 'FFTW'], obj=[
+             'dxf-points_dxfPoints.obj',
+             'libprogbase.lib',
+             'libdxf.lib',
+             'libpandatoolbase.lib',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='dxfToEgg.cxx', obj='dxf2egg_dxfToEgg.obj')
+CompileLink(dll='dxf2egg.exe', opts=['ADVAPI', 'NSPR', 'FFTW'], obj=[
+             'dxf2egg_dxfToEgg.obj',
+             'libdxfegg.lib',
+             'libdxf.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libconverter.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='eggToDXF.cxx', obj='egg2dxf_eggToDXF.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='eggToDXFLayer.cxx', obj='egg2dxf_eggToDXFLayer.obj')
+CompileLink(dll='egg2dxf.exe', opts=['ADVAPI', 'NSPR', 'FFTW'], obj=[
+             'egg2dxf_eggToDXF.obj',
+             'egg2dxf_eggToDXFLayer.obj',
+             'libdxf.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libconverter.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/palettizer/
+#
+
+IPATH=['pandatool/src/palettizer']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='palettizer_composite1.cxx', obj='palettizer_composite1.obj')
+CompileLIB(lib='libpalettizer.lib', obj=['palettizer_composite1.obj'])
+
+#
+# DIRECTORY: pandatool/src/egg-mkfont/
+#
+
+IPATH=['pandatool/src/egg-mkfont', 'pandatool/src/palettizer']
+OPTS=['NSPR', 'FREETYPE']
+CompileC(ipath=IPATH, opts=OPTS, src='eggMakeFont.cxx', obj='egg-mkfont_eggMakeFont.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='rangeDescription.cxx', obj='egg-mkfont_rangeDescription.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='rangeIterator.cxx', obj='egg-mkfont_rangeIterator.obj')
+CompileLink(dll='egg-mkfont.exe', opts=['ADVAPI', 'NSPR', 'FREETYPE'], obj=[
+             'egg-mkfont_eggMakeFont.obj',
+             'egg-mkfont_rangeDescription.obj',
+             'egg-mkfont_rangeIterator.obj',
+             'libpalettizer.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libconverter.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/eggcharbase/
+#
+
+IPATH=['pandatool/src/eggcharbase']
+OPTS=['ZLIB', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='eggcharbase_composite1.cxx', obj='eggcharbase_composite1.obj')
+CompileLIB(lib='libeggcharbase.lib', obj=['eggcharbase_composite1.obj'])
+
+#
+# DIRECTORY: pandatool/src/egg-optchar/
+#
+
+IPATH=['pandatool/src/egg-optchar']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='config_egg_optchar.cxx', obj='egg-optchar_config_egg_optchar.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='eggOptchar.cxx', obj='egg-optchar_eggOptchar.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='eggOptcharUserData.cxx', obj='egg-optchar_eggOptcharUserData.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vertexMembership.cxx', obj='egg-optchar_vertexMembership.obj')
+CompileLink(dll='egg-optchar.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'egg-optchar_config_egg_optchar.obj',
+             'egg-optchar_eggOptchar.obj',
+             'egg-optchar_eggOptcharUserData.obj',
+             'egg-optchar_vertexMembership.obj',
+             'libeggcharbase.lib',
+             'libconverter.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/egg-palettize/
+#
+
+IPATH=['pandatool/src/egg-palettize', 'pandatool/src/palettizer']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='eggPalettize.cxx', obj='egg-palettize_eggPalettize.obj')
+CompileLink(dll='egg-palettize.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'egg-palettize_eggPalettize.obj',
+             'libpalettizer.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libconverter.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/egg-qtess/
+#
+
+IPATH=['pandatool/src/egg-qtess']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='egg-qtess_composite1.cxx', obj='egg-qtess_composite1.obj')
+CompileLink(dll='egg-qtess.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'egg-qtess_composite1.obj',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libconverter.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/eggprogs/
+#
+
+IPATH=['pandatool/src/eggprogs']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='eggCrop.cxx', obj='egg-crop_eggCrop.obj')
+CompileLink(dll='egg-crop.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'egg-crop_eggCrop.obj',
+             'libconverter.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='eggMakeTube.cxx', obj='egg-make-tube_eggMakeTube.obj')
+CompileLink(dll='egg-make-tube.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'egg-make-tube_eggMakeTube.obj',
+             'libconverter.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='eggTextureCards.cxx', obj='egg-texture-cards_eggTextureCards.obj')
+CompileLink(dll='egg-texture-cards.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'egg-texture-cards_eggTextureCards.obj',
+             'libconverter.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='eggTopstrip.cxx', obj='egg-topstrip_eggTopstrip.obj')
+CompileLink(dll='egg-topstrip.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'egg-topstrip_eggTopstrip.obj',
+             'libeggcharbase.lib',
+             'libconverter.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='eggTrans.cxx', obj='egg-trans_eggTrans.obj')
+CompileLink(dll='egg-trans.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'egg-trans_eggTrans.obj',
+             'libconverter.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='eggToC.cxx', obj='egg2c_eggToC.obj')
+CompileLink(dll='egg2c.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'egg2c_eggToC.obj',
+             'libconverter.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/flt/
+#
+
+IPATH=['pandatool/src/flt']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='fltVectorRecord.cxx', obj='flt_fltVectorRecord.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='flt_composite1.cxx', obj='flt_composite1.obj')
+CompileLIB(lib='libflt.lib', obj=['flt_fltVectorRecord.obj', 'flt_composite1.obj'])
+
+#
+# DIRECTORY: pandatool/src/fltegg/
+#
+
+IPATH=['pandatool/src/fltegg']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='fltToEggConverter.cxx', obj='fltegg_fltToEggConverter.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='fltToEggLevelState.cxx', obj='fltegg_fltToEggLevelState.obj')
+CompileLIB(lib='libfltegg.lib', obj=['fltegg_fltToEggConverter.obj', 'fltegg_fltToEggLevelState.obj'])
+
+#
+# DIRECTORY: pandatool/src/fltprogs/
+#
+
+IPATH=['pandatool/src/fltprogs', 'pandatool/src/flt', 'pandatool/src/cvscopy']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='eggToFlt.cxx', obj='egg2flt_eggToFlt.obj')
+CompileLink(dll='egg2flt.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'egg2flt_eggToFlt.obj',
+             'libflt.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libconverter.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='fltInfo.cxx', obj='flt-info_fltInfo.obj')
+CompileLink(dll='flt-info.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'flt-info_fltInfo.obj',
+             'libprogbase.lib',
+             'libflt.lib',
+             'libpandatoolbase.lib',
+             'libconverter.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='fltTrans.cxx', obj='flt-trans_fltTrans.obj')
+CompileLink(dll='flt-trans.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'flt-trans_fltTrans.obj',
+             'libprogbase.lib',
+             'libflt.lib',
+             'libpandatoolbase.lib',
+             'libconverter.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='fltToEgg.cxx', obj='flt2egg_fltToEgg.obj')
+CompileLink(dll='flt2egg.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'flt2egg_fltToEgg.obj',
+             'libflt.lib',
+             'libfltegg.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libconverter.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+CompileC(ipath=IPATH, opts=OPTS, src='fltCopy.cxx', obj='fltcopy_fltCopy.obj')
+CompileLink(dll='fltcopy.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'fltcopy_fltCopy.obj',
+             'libcvscopy.lib',
+             'libflt.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libconverter.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/imagebase/
+#
+
+IPATH=['pandatool/src/imagebase']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='imagebase_composite1.cxx', obj='imagebase_composite1.obj')
+CompileLIB(lib='libimagebase.lib', obj=['imagebase_composite1.obj'])
+
+#
+# DIRECTORY: pandatool/src/imageprogs/
+#
+
+IPATH=['pandatool/src/imageprogs']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='imageInfo.cxx', obj='image-info_imageInfo.obj')
+CompileLink(dll='image-info.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'image-info_imageInfo.obj',
+             'libimagebase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+CompileC(ipath=IPATH, opts=OPTS, src='imageResize.cxx', obj='image-resize_imageResize.obj')
+CompileLink(dll='image-resize.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'image-resize_imageResize.obj',
+             'libimagebase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+CompileC(ipath=IPATH, opts=OPTS, src='imageTrans.cxx', obj='image-trans_imageTrans.obj')
+CompileLink(dll='image-trans.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'image-trans_imageTrans.obj',
+             'libimagebase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/lwo/
+#
+
+IPATH=['pandatool/src/lwo']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='lwo_composite1.cxx', obj='lwo_composite1.obj')
+CompileLIB(lib='liblwo.lib', obj=['lwo_composite1.obj'])
+
+#
+# DIRECTORY: pandatool/src/lwoegg/
+#
+
+IPATH=['pandatool/src/lwoegg']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='lwoegg_composite1.cxx', obj='lwoegg_composite1.obj')
+CompileLIB(lib='liblwoegg.lib', obj=['lwoegg_composite1.obj'])
+
+#
+# DIRECTORY: pandatool/src/lwoprogs/
+#
+
+IPATH=['pandatool/src/lwoprogs', 'pandatool/src/lwo']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='lwoScan.cxx', obj='lwo-scan_lwoScan.obj')
+CompileLink(dll='lwo-scan.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'lwo-scan_lwoScan.obj',
+             'liblwo.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+CompileC(ipath=IPATH, opts=OPTS, src='lwoToEgg.cxx', obj='lwo2egg_lwoToEgg.obj')
+CompileLink(dll='lwo2egg.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'lwo2egg_lwoToEgg.obj',
+             'liblwo.lib',
+             'liblwoegg.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libconverter.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/maya/
+#
+
+
+for VER in ["5","6"]:
+  if (OMIT.count("MAYA"+VER)==0):
+    IPATH=['pandatool/src/maya']
+    OPTS=['MAYA'+VER, 'NSPR']
+    CompileC(ipath=IPATH, opts=OPTS, src='config_maya.cxx',        obj='maya'+VER+'_config_maya.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaApi.cxx',            obj='maya'+VER+'_mayaApi.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaShader.cxx',         obj='maya'+VER+'_mayaShader.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaShaderColorDef.cxx', obj='maya'+VER+'_mayaShaderColorDef.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaShaders.cxx',        obj='maya'+VER+'_mayaShaders.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='maya_funcs.cxx',         obj='maya'+VER+'_funcs.obj')
+    CompileLIB(lib='libmaya'+VER+'.lib', obj=[
+                 'maya'+VER+'_config_maya.obj',
+                 'maya'+VER+'_mayaApi.obj',
+                 'maya'+VER+'_mayaShader.obj',
+                 'maya'+VER+'_mayaShaderColorDef.obj',
+                 'maya'+VER+'_mayaShaders.obj',
+                 'maya'+VER+'_funcs.obj',
+    ])
+
+#
+# DIRECTORY: pandatool/src/mayaegg/
+#
+
+for VER in ["5","6"]:
+  if (OMIT.count("MAYA"+VER)==0):
+    IPATH=['pandatool/src/mayaegg', 'pandatool/src/maya']
+    OPTS=['MAYA'+VER, 'NSPR']
+    CompileC(ipath=IPATH, opts=OPTS, src='config_mayaegg.cxx',       obj='mayaegg'+VER+'_config_mayaegg.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaEggGroupUserData.cxx', obj='mayaegg'+VER+'_mayaEggGroupUserData.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaBlendDesc.cxx',        obj='mayaegg'+VER+'_mayaBlendDesc.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaNodeDesc.cxx',         obj='mayaegg'+VER+'_mayaNodeDesc.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaNodeTree.cxx',         obj='mayaegg'+VER+'_mayaNodeTree.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaToEggConverter.cxx',   obj='mayaegg'+VER+'_mayaToEggConverter.obj')
+    CompileLIB(lib='libmayaegg'+VER+'.lib', obj=[
+                 'mayaegg'+VER+'_config_mayaegg.obj',
+                 'mayaegg'+VER+'_mayaEggGroupUserData.obj',
+                 'mayaegg'+VER+'_mayaBlendDesc.obj',
+                 'mayaegg'+VER+'_mayaNodeDesc.obj',
+                 'mayaegg'+VER+'_mayaNodeTree.obj',
+                 'mayaegg'+VER+'_mayaToEggConverter.obj'
+    ])
+
+#
+# DIRECTORY: pandatool/src/maxegg/
+#
+
+for VER in ["5", "6", "7"]:
+  if (OMIT.count("MAX"+VER)==0):
+    IPATH=['pandatool/src/maxegg']
+    OPTS=['MAX'+VER, 'NSPR', "WINCOMCTL", "WINUSER"]
+    CompileC(ipath=IPATH, opts=OPTS, src='DllEntry.cpp',         obj='maxegg'+VER+'_DllEntry.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='Logger.cpp',           obj='maxegg'+VER+'_Logger.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='MaxEgg.cpp',           obj='maxegg'+VER+'_MaxEgg.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='maxNodeDesc.cxx',      obj='maxegg'+VER+'_maxNodeDesc.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='MaxNodeTree.cxx',      obj='maxegg'+VER+'_MaxNodeTree.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='MaxToEgg.cpp',         obj='maxegg'+VER+'_MaxToEgg.obj')
+    CompileC(ipath=IPATH, opts=OPTS, src='MaxToEggConverter.cxx',obj='maxegg'+VER+'_MaxToEggConverter.obj')
+    CompileRES(ipath=IPATH, opts=OPTS, src='MaxEgg.rc',          obj='maxegg'+VER+'_MaxEgg.res')
+
+    CompileLink(opts = OPTS, dll='maxegg'+VER+'.dle', obj=[
+                'maxegg'+VER+'_DllEntry.obj',
+                'maxegg'+VER+'_Logger.obj',
+                'maxegg'+VER+'_MaxEgg.obj',
+                'maxegg'+VER+'_maxNodeDesc.obj',
+                'maxegg'+VER+'_MaxNodeTree.obj',
+                'maxegg'+VER+'_MaxToEgg.obj',
+                'maxegg'+VER+'_MaxToEggConverter.obj',
+                'maxegg'+VER+'_MaxEgg.res',
+                'libeggbase.lib',
+                'libprogbase.lib',
+                'libpandatoolbase.lib',
+                'libconverter.lib',
+                'libpandaegg.dll',
+                'libpanda.dll',
+                'libpandaexpress.dll',
+                'libdtoolconfig.dll',
+                'libdtool.dll',
+                'libpystub.dll'
+               ])
+
+#
+# DIRECTORY: pandatool/src/vrml/
+#
+
+CompileBison(pre='vrmlyy', dstc='vrmlParser.cxx', dsth='vrmlParser.h', src='pandatool/src/vrml/vrmlParser.yxx')
+CompileFlex(pre='vrmlyy', dst='vrmlLexer.cxx', src='pandatool/src/vrml/vrmlLexer.lxx', dashi=0)
+IPATH=['pandatool/src/vrml']
+OPTS=['ZLIB', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='parse_vrml.cxx', obj='pvrml_parse_vrml.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='standard_nodes.cxx', obj='pvrml_standard_nodes.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrmlNode.cxx', obj='pvrml_vrmlNode.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrmlNodeType.cxx', obj='pvrml_vrmlNodeType.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrmlParser.cxx', obj='pvrml_vrmlParser.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrmlLexer.cxx', obj='pvrml_vrmlLexer.obj')
+CompileLIB(lib='libpvrml.lib', obj=[
+             'pvrml_parse_vrml.obj',
+             'pvrml_standard_nodes.obj',
+             'pvrml_vrmlNode.obj',
+             'pvrml_vrmlNodeType.obj',
+             'pvrml_vrmlParser.obj',
+             'pvrml_vrmlLexer.obj',
+])
+
+#
+# DIRECTORY: pandatool/src/vrmlegg/
+#
+
+IPATH=['pandatool/src/vrmlegg', 'pandatool/src/vrml']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='indexedFaceSet.cxx', obj='vrmlegg_indexedFaceSet.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrmlAppearance.cxx', obj='vrmlegg_vrmlAppearance.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='vrmlToEggConverter.cxx', obj='vrmlegg_vrmlToEggConverter.obj')
+CompileLIB(lib='libvrmlegg.lib', obj=[
+             'vrmlegg_indexedFaceSet.obj',
+             'vrmlegg_vrmlAppearance.obj',
+             'vrmlegg_vrmlToEggConverter.obj',
+])
+
+#
+# DIRECTORY: pandatool/src/xfile/
+#
+
+CompileBison(pre='xyy', dstc='xParser.cxx', dsth='xParser.h', src='pandatool/src/xfile/xParser.yxx')
+CompileFlex(pre='xyy', dst='xLexer.cxx', src='pandatool/src/xfile/xLexer.lxx', dashi=1)
+IPATH=['pandatool/src/xfile']
+OPTS=['ZLIB', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='xfile_composite1.cxx', obj='xfile_composite1.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='xParser.cxx', obj='xfile_xParser.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='xLexer.cxx', obj='xfile_xLexer.obj')
+CompileLIB(lib='libxfile.lib', obj=[
+             'xfile_composite1.obj',
+             'xfile_xParser.obj',
+             'xfile_xLexer.obj',
+])
+
+#
+# DIRECTORY: pandatool/src/xfileegg/
+#
+
+IPATH=['pandatool/src/xfileegg', 'pandatool/src/xfile']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='xfileegg_composite1.cxx', obj='xfileegg_composite1.obj')
+CompileLIB(lib='libxfileegg.lib', obj=[
+             'xfileegg_composite1.obj',
+])
+
+#
+# DIRECTORY: pandatool/src/ptloader/
+#
+
+IPATH=['pandatool/src/ptloader', 'pandatool/src/flt', 'pandatool/src/lwo', 'pandatool/src/xfile', 'pandatool/src/xfileegg']
+OPTS=['BUILDING_PTLOADER', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='config_ptloader.cxx', obj='ptloader_config_ptloader.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='loaderFileTypePandatool.cxx', obj='ptloader_loaderFileTypePandatool.obj')
+CompileLink(dll='libptloader.dll', opts=['ADVAPI', 'NSPR'], obj=[
+             'ptloader_config_ptloader.obj',
+             'ptloader_loaderFileTypePandatool.obj',
+             'libfltegg.lib',
+             'libflt.lib',
+             'liblwoegg.lib',
+             'liblwo.lib',
+             'libdxfegg.lib',
+             'libdxf.lib',
+             'libvrmlegg.lib',
+             'libpvrml.lib',
+             'libxfileegg.lib',
+             'libxfile.lib',
+             'libconverter.lib',
+             'libpandatoolbase.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/mayaprogs/
+#
+
+for VER in ["5","6"]:
+  if (OMIT.count('MAYA'+VER)==0):  
+    IPATH=['pandatool/src/mayaprogs', 'pandatool/src/maya', 'pandatool/src/mayaegg',
+           'pandatool/src/cvscopy']
+    OPTS=['BUILDING_MISC', 'MAYA'+VER, 'NSPR']
+    CompileC(ipath=IPATH, opts=OPTS, src='config_mayaloader.cxx', obj='mayaloader'+VER+'_config_mayaloader.obj')
+    CompileLink(dll='libmayaloader'+VER+'.dll',                 opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
+                 'mayaloader'+VER+'_config_mayaloader.obj',
+                 'libmayaegg'+VER+'.lib',
+                 'libptloader.lib',
+                 'libconverter.lib',
+                 'libpandatoolbase.lib',
+                 'libmaya'+VER+'.lib',
+                 'libfltegg.lib',
+                 'libflt.lib',
+                 'liblwoegg.lib',
+                 'liblwo.lib',
+                 'libdxfegg.lib',
+                 'libdxf.lib',
+                 'libvrmlegg.lib',
+                 'libpvrml.lib',
+                 'libxfileegg.lib',
+                 'libxfile.lib',
+                 'libeggbase.lib',
+                 'libprogbase.lib',
+                 'libpandaegg.dll',
+                 'libpanda.dll',
+                 'libpandaexpress.dll',
+                 'libdtoolconfig.dll',
+                 'libdtool.dll',
+    ])
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaPview.cxx', obj='mayapview'+VER+'_mayaPview.obj')
+    CompileLink(dll='libmayapview'+VER+'.dll',                 opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
+                 'mayapview'+VER+'_mayaPview.obj',
+                 'libmayaegg'+VER+'.lib',
+                 'libmaya'+VER+'.lib',
+                 'libconverter.lib',
+                 'libpandatoolbase.lib',
+                 'libpandaegg.dll',
+                 'libframework.dll',
+                 'libpanda.dll',
+                 'libpandaexpress.dll',
+                 'libdtoolconfig.dll',
+                 'libdtool.dll',
+                 'libpystub.dll',
+    ])
+    IPATH=['pandatool/src/mayaprogs', 'pandatool/src/maya', 'pandatool/src/mayaegg',
+           'pandatool/src/cvscopy']
+    OPTS=['MAYA'+VER, 'NSPR']
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaSavePview.cxx', obj='mayasavepview'+VER+'_mayaSavePview.obj')
+    CompileLink(dll='libmayasavepview.dll',                 opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
+                 'mayasavepview'+VER+'_mayaSavePview.obj',
+    ])
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaToEgg.cxx', obj='maya2egg'+VER+'_mayaToEgg.obj')
+    CompileLink(dll='maya2egg'+VER+'.exe',                 opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
+                 'maya2egg'+VER+'_mayaToEgg.obj',
+                 'libmayaegg'+VER+'.lib',
+                 'libmaya'+VER+'.lib',
+                 'libeggbase.lib',
+                 'libprogbase.lib',
+                 'libconverter.lib',
+                 'libpandatoolbase.lib',
+                 'libpandaegg.dll',
+                 'libpanda.dll',
+                 'libpandaexpress.dll',
+                 'libdtoolconfig.dll',
+                 'libdtool.dll',
+                 'libpystub.dll',
+    ])
+    CompileC(ipath=IPATH, opts=OPTS, src='mayaCopy.cxx', obj='mayacopy'+VER+'_mayaCopy.obj')
+    CompileLink(dll='mayacopy'+VER+'.exe',                 opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
+                 'mayacopy'+VER+'_mayaCopy.obj',
+                 'libcvscopy.lib',
+                 'libmaya'+VER+'.lib',
+                 'libprogbase.lib',
+                 'libpandatoolbase.lib',
+                 'libconverter.lib',
+                 'libpandaegg.dll',
+                 'libpanda.dll',
+                 'libpandaexpress.dll',
+                 'libdtoolconfig.dll',
+                 'libdtool.dll',
+                 'libpystub.dll',
+    ])
+
+#
+# DIRECTORY: pandatool/src/miscprogs/
+#
+
+IPATH=['pandatool/src/miscprogs']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='binToC.cxx', obj='bin2c_binToC.obj')
+CompileLink(dll='bin2c.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'bin2c_binToC.obj',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/pstatserver/
+#
+
+IPATH=['pandatool/src/pstatserver']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pStatClientData.cxx', obj='pstatserver_pStatClientData.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pStatGraph.cxx', obj='pstatserver_pStatGraph.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pStatListener.cxx', obj='pstatserver_pStatListener.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pStatMonitor.cxx', obj='pstatserver_pStatMonitor.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pStatPianoRoll.cxx', obj='pstatserver_pStatPianoRoll.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pStatReader.cxx', obj='pstatserver_pStatReader.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pStatServer.cxx', obj='pstatserver_pStatServer.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pStatStripChart.cxx', obj='pstatserver_pStatStripChart.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pStatThreadData.cxx', obj='pstatserver_pStatThreadData.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pStatView.cxx', obj='pstatserver_pStatView.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='pStatViewLevel.cxx', obj='pstatserver_pStatViewLevel.obj')
+CompileLIB(lib='libpstatserver.lib', obj=[
+             'pstatserver_pStatClientData.obj',
+             'pstatserver_pStatGraph.obj',
+             'pstatserver_pStatListener.obj',
+             'pstatserver_pStatMonitor.obj',
+             'pstatserver_pStatPianoRoll.obj',
+             'pstatserver_pStatReader.obj',
+             'pstatserver_pStatServer.obj',
+             'pstatserver_pStatStripChart.obj',
+             'pstatserver_pStatThreadData.obj',
+             'pstatserver_pStatView.obj',
+             'pstatserver_pStatViewLevel.obj',
+])
+
+#
+# DIRECTORY: pandatool/src/softprogs/
+#
+
+IPATH=['pandatool/src/softprogs']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='softCVS.cxx', obj='softcvs_softCVS.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='softFilename.cxx', obj='softcvs_softFilename.obj')
+CompileLink(opts=['ADVAPI', 'NSPR'], dll='softcvs.exe', obj=[
+             'softcvs_softCVS.obj',
+             'softcvs_softFilename.obj',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/text-stats/
+#
+
+IPATH=['pandatool/src/text-stats']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='textMonitor.cxx', obj='text-stats_textMonitor.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='textStats.cxx', obj='text-stats_textStats.obj')
+CompileLink(opts=['ADVAPI', 'NSPR'], dll='text-stats.exe', obj=[
+             'text-stats_textMonitor.obj',
+             'text-stats_textStats.obj',
+             'libprogbase.lib',
+             'libpstatserver.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/vrmlprogs/
+#
+
+IPATH=['pandatool/src/vrmlprogs', 'pandatool/src/vrml', 'pandatool/src/vrmlegg']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='vrmlTrans.cxx', obj='vrml-trans_vrmlTrans.obj')
+CompileLink(opts=['ADVAPI', 'NSPR'], dll='vrml-trans.exe', obj=[
+             'vrml-trans_vrmlTrans.obj',
+             'libprogbase.lib',
+             'libpvrml.lib',
+             'libpandatoolbase.lib',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+CompileC(ipath=IPATH, opts=OPTS, src='vrmlToEgg.cxx', obj='vrml2egg_vrmlToEgg.obj')
+CompileLink(opts=['ADVAPI', 'NSPR'], dll='vrml2egg.exe', obj=[
+             'vrml2egg_vrmlToEgg.obj',
+             'libvrmlegg.lib',
+             'libpvrml.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libconverter.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandatool/src/win-stats/
+#
+
+if (sys.platform == "win32"):
+  IPATH=['pandatool/src/win-stats']
+  OPTS=['NSPR']
+  CompileC(ipath=IPATH, opts=OPTS, src='winStats.cxx', obj='pstats_winStats.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='winStatsChartMenu.cxx', obj='pstats_winStatsChartMenu.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='winStatsGraph.cxx', obj='pstats_winStatsGraph.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='winStatsLabel.cxx', obj='pstats_winStatsLabel.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='winStatsLabelStack.cxx', obj='pstats_winStatsLabelStack.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='winStatsMonitor.cxx', obj='pstats_winStatsMonitor.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='winStatsPianoRoll.cxx', obj='pstats_winStatsPianoRoll.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='winStatsServer.cxx', obj='pstats_winStatsServer.obj')
+  CompileC(ipath=IPATH, opts=OPTS, src='winStatsStripChart.cxx', obj='pstats_winStatsStripChart.obj')
+  CompileLink(opts=['WINSOCK', 'WINIMM', 'WINGDI', 'WINKERNEL', 'WINOLDNAMES', 'WINUSER', 'WINMM', 'NSPR'], 
+              dll='pstats.exe', obj=[
+              'pstats_winStats.obj',
+              'pstats_winStatsChartMenu.obj',
+              'pstats_winStatsGraph.obj',
+              'pstats_winStatsLabel.obj',
+              'pstats_winStatsLabelStack.obj',
+              'pstats_winStatsMonitor.obj',
+              'pstats_winStatsPianoRoll.obj',
+              'pstats_winStatsServer.obj',
+              'pstats_winStatsStripChart.obj',
+              'libprogbase.lib',
+              'libpstatserver.lib',
+              'libpandatoolbase.lib',
+              'libpandaexpress.dll',
+              'libpanda.dll',
+              'libdtoolconfig.dll',
+              'libdtool.dll',
+              'libpystub.dll',
+              ])
+
+#
+# DIRECTORY: pandatool/src/xfileprogs/
+#
+
+IPATH=['pandatool/src/xfileprogs', 'pandatool/src/xfile', 'pandatool/src/xfileegg']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='eggToX.cxx', obj='egg2x_eggToX.obj')
+CompileLink(dll='egg2x.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'egg2x_eggToX.obj',
+             'libxfileegg.lib',
+             'libxfile.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libconverter.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+CompileC(ipath=IPATH, opts=OPTS, src='xFileTrans.cxx', obj='x-trans_xFileTrans.obj')
+CompileLink(dll='x-trans.exe', opts=['ADVAPI', 'NSPR'], obj=[
+             'x-trans_xFileTrans.obj',
+             'libprogbase.lib',
+             'libxfile.lib',
+             'libpandatoolbase.lib',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+CompileC(ipath=IPATH, opts=OPTS, src='xFileToEgg.cxx', obj='x2egg_xFileToEgg.obj')
+CompileLink(opts=['ADVAPI', 'NSPR'], dll='x2egg.exe', obj=[
+             'x2egg_xFileToEgg.obj',
+             'libxfileegg.lib',
+             'libxfile.lib',
+             'libconverter.lib',
+             'libeggbase.lib',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpandaegg.dll',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandaapp/src/pandaappbase/
+#
+
+IPATH=['pandaapp/src/pandaappbase']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='pandaappbase.cxx', obj='pandaappbase_pandaappbase.obj')
+CompileLIB(lib='libpandaappbase.lib', obj=['pandaappbase_pandaappbase.obj'])
+
+#
+# DIRECTORY: pandaapp/src/httpbackup/
+#
+
+IPATH=['pandaapp/src/httpbackup', 'pandaapp/src/pandaappbase']
+OPTS=['OPENSSL', 'NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='backupCatalog.cxx', obj='httpbackup_backupCatalog.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='httpBackup.cxx', obj='httpbackup_httpBackup.obj')
+CompileLink(opts=['ADVAPI', 'NSPR', 'OPENSSL'], dll='httpbackup.exe', obj=[
+             'httpbackup_backupCatalog.obj',
+             'httpbackup_httpBackup.obj',
+             'libpandaappbase.lib',
+             'libpandaexpress.dll',
+             'libpanda.dll',
+             'libdtool.dll',
+             'libdtoolconfig.dll',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandaapp/src/indexify/
+#
+
+IPATH=['pandaapp/src/indexify']
+OPTS=['NSPR', 'FREETYPE']
+CompileC(ipath=IPATH, opts=OPTS, src='default_font.cxx', obj='font-samples_default_font.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='fontSamples.cxx', obj='font-samples_fontSamples.obj')
+CompileLink(opts=['ADVAPI', 'NSPR', 'FREETYPE'], dll='font-samples.exe', obj=[
+             'font-samples_default_font.obj',
+             'font-samples_fontSamples.obj',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtool.dll',
+             'libdtoolconfig.dll',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpystub.dll',
+])
+
+CompileC(ipath=IPATH, opts=OPTS, src='default_index_icons.cxx', obj='indexify_default_index_icons.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='default_font.cxx', obj='indexify_default_font.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='indexImage.cxx', obj='indexify_indexImage.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='indexParameters.cxx', obj='indexify_indexParameters.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='indexify.cxx', obj='indexify_indexify.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='photo.cxx', obj='indexify_photo.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='rollDirectory.cxx', obj='indexify_rollDirectory.obj')
+CompileLink(opts=['ADVAPI', 'NSPR', 'FREETYPE'], dll='indexify.exe', obj=[
+             'indexify_default_index_icons.obj',
+             'indexify_default_font.obj',
+             'indexify_indexImage.obj',
+             'indexify_indexParameters.obj',
+             'indexify_indexify.obj',
+             'indexify_photo.obj',
+             'indexify_rollDirectory.obj',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtool.dll',
+             'libdtoolconfig.dll',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libpystub.dll',
+])
+
+#
+# DIRECTORY: pandaapp/src/stitchbase/
+#
+
+CompileBison(pre='stitchyy', dstc='stitchParser.cxx', dsth='stitchParser.h', src='pandaapp/src/stitchbase/stitchParser.yxx')
+CompileFlex(pre='stitchyy', dst='stitchLexer.cxx', src='pandaapp/src/stitchbase/stitchLexer.lxx', dashi=1)
+IPATH=['pandaapp/src/stitchbase', 'pandaapp/src/pandaappbase']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='config_stitch.cxx', obj='stitchbase_config_stitch.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='fadeImagePool.cxx', obj='stitchbase_fadeImagePool.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='layeredImage.cxx', obj='stitchbase_layeredImage.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='morphGrid.cxx', obj='stitchbase_morphGrid.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchCommand.cxx', obj='stitchbase_stitchCommand.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchCommandReader.cxx', obj='stitchbase_stitchCommandReader.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchCylindricalLens.cxx', obj='stitchbase_stitchCylindricalLens.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchFile.cxx', obj='stitchbase_stitchFile.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchFisheyeLens.cxx', obj='stitchbase_stitchFisheyeLens.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchImage.cxx', obj='stitchbase_stitchImage.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchImageCommandOutput.cxx', obj='stitchbase_stitchImageCommandOutput.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchImageOutputter.cxx', obj='stitchbase_stitchImageOutputter.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchImageRasterizer.cxx', obj='stitchbase_stitchImageRasterizer.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchLens.cxx', obj='stitchbase_stitchLens.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchPSphereLens.cxx', obj='stitchbase_stitchPSphereLens.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchPerspectiveLens.cxx', obj='stitchbase_stitchPerspectiveLens.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchPoint.cxx', obj='stitchbase_stitchPoint.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitcher.cxx', obj='stitchbase_stitcher.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='triangle.cxx', obj='stitchbase_triangle.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='triangleRasterizer.cxx', obj='stitchbase_triangleRasterizer.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchCylindricalScreen.cxx', obj='stitchbase_stitchCylindricalScreen.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchFlatScreen.cxx', obj='stitchbase_stitchFlatScreen.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchMultiScreen.cxx', obj='stitchbase_stitchMultiScreen.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchScreen.cxx', obj='stitchbase_stitchScreen.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchParser.cxx', obj='stitchbase_stitchParser.obj')
+CompileC(ipath=IPATH, opts=OPTS, src='stitchLexer.cxx', obj='stitchbase_stitchLexer.obj')
+CompileLIB(lib='libstitchbase.lib', obj=[
+             'stitchbase_config_stitch.obj',
+             'stitchbase_fadeImagePool.obj',
+             'stitchbase_layeredImage.obj',
+             'stitchbase_morphGrid.obj',
+             'stitchbase_stitchCommand.obj',
+             'stitchbase_stitchCommandReader.obj',
+             'stitchbase_stitchCylindricalLens.obj',
+             'stitchbase_stitchFile.obj',
+             'stitchbase_stitchFisheyeLens.obj',
+             'stitchbase_stitchImage.obj',
+             'stitchbase_stitchImageCommandOutput.obj',
+             'stitchbase_stitchImageOutputter.obj',
+             'stitchbase_stitchImageRasterizer.obj',
+             'stitchbase_stitchLens.obj',
+             'stitchbase_stitchPSphereLens.obj',
+             'stitchbase_stitchPerspectiveLens.obj',
+             'stitchbase_stitchPoint.obj',
+             'stitchbase_stitcher.obj',
+             'stitchbase_triangle.obj',
+             'stitchbase_triangleRasterizer.obj',
+             'stitchbase_stitchCylindricalScreen.obj',
+             'stitchbase_stitchFlatScreen.obj',
+             'stitchbase_stitchMultiScreen.obj',
+             'stitchbase_stitchScreen.obj',
+             'stitchbase_stitchParser.obj',
+             'stitchbase_stitchLexer.obj',
+])
+
+#
+# DIRECTORY: pandaapp/src/stitch/
+#
+
+IPATH=['pandaapp/src/stitch', 'pandaapp/src/stitchbase', 'pandaapp/src/pandaappbase']
+OPTS=['NSPR']
+CompileC(ipath=IPATH, opts=OPTS, src='stitchCommandProgram.cxx', obj='stitch-command_stitchCommandProgram.obj')
+CompileLink(opts=['ADVAPI', 'NSPR', 'FFTW'], dll='stitch-command.exe', obj=[
+             'stitch-command_stitchCommandProgram.obj',
+             'libstitchbase.lib',
+             'libpandaappbase.lib',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libconverter.lib',
+             'libpystub.dll',
+])
+
+CompileC(ipath=IPATH, opts=OPTS, src='stitchImageProgram.cxx', obj='stitch-image_stitchImageProgram.obj')
+CompileLink(opts=['ADVAPI', 'NSPR', 'FFTW'], dll='stitch-image.exe', obj=[
+             'stitch-image_stitchImageProgram.obj',
+             'libstitchbase.lib',
+             'libpandaappbase.lib',
+             'libpanda.dll',
+             'libpandaexpress.dll',
+             'libdtoolconfig.dll',
+             'libdtool.dll',
+             'libprogbase.lib',
+             'libpandatoolbase.lib',
+             'libconverter.lib',
+             'libpystub.dll',
+])
+
+##########################################################################################
+#
+# Run genpycode
+#
+##########################################################################################
+
+if (older('built/lib/pandac/PandaModules.pyz',xpaths("built/etc/",ALLIN,""))):
+  ALLTARGETS.append('built/lib/pandac/PandaModules.pyz')
+  oscmd(backslashify("built/bin/genpycode"))
+  updatefiledate('built/lib/pandac/PandaModules.pyz')
+
+########################################################################
+##
+## Save the CXX include-cache for next time.
+##
+########################################################################
+
+try: icache = open("makepanda-icache",'wb')
+except: icache = 0
+if (icache!=0):
+  cPickle.dump(CxxIncludeCache, icache, 1)
+  icache.close()
+
+##########################################################################################
+#
+# 'Complete' mode. 
+#
+# Copies the samples, models, and direct into the build. Note that
+# this isn't usually what you want.  It is usually better to let the
+# compiled panda load this stuff directly from the source tree.
+# The only time you really want to do this is if you plan to move
+# the build somewhere and leave the source tree behind.
+#
+##########################################################################################
+
+if (COMPLETE):
+  CopyFile('built/', 'InstallerNotes')
+  CopyFile('built/', 'LICENSE')
+  CopyFile('built/', 'README')
+  CopyTree('built/samples', 'samples')
+  CopyTree('built/models', 'models')
+  CopyTree('built/direct/src', 'direct/src')
+  CopyTree('built/SceneEditor', 'SceneEditor')
+
+##########################################################################################
+#
+# The Installer
+#
+##########################################################################################
+
+if (INSTALLER):
+  if (sys.platform == "win32"):
+    if (older('panda3d-install.exe', ALLTARGETS)):
+      VERSION = str(VERSION1)+"-"+str(VERSION2)+"-"+str(VERSION3)
+      print("Building installer. This can take up to an hour.")
+      if (COMPRESSOR != "lzma"): print("Note: you are using zlib, which is faster, but lzma gives better compression.")
+      oscmd("if exist panda3d-"+VERSION+".exe del panda3d-"+VERSION+".exe")
+      oscmd("thirdparty\\win-nsis\\makensis.exe /V2 /DCOMPRESSOR="+COMPRESSOR+" /DVERSION="+VERSION+" thirdparty\\win-nsis\\panda.nsi")
+      oscmd("rename panda3d-install-TMP.exe panda3d-"+VERSION+".exe")
+  else:
+    # Do an rpmbuild or something like that.
+    pass
+
+##########################################################################################
+#
+# Print final status report.
+#
+##########################################################################################
+
+printStatus("Makepanda Final Status Report", WARNINGS)
+

+ 21 - 0
doc/makepanda/makepanda.sln

@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 7.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makepanda", "makepanda.vcproj", "{F4935D7A-20AD-4132-B3CB-ADFF4F928D25}"
+EndProject
+Global
+	GlobalSection(SolutionConfiguration) = preSolution
+		ConfigName.0 = Debug
+		ConfigName.1 = Release
+	EndGlobalSection
+	GlobalSection(ProjectDependencies) = postSolution
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{F4935D7A-20AD-4132-B3CB-ADFF4F928D25}.Debug.ActiveCfg = Debug|Win32
+		{F4935D7A-20AD-4132-B3CB-ADFF4F928D25}.Debug.Build.0 = Debug|Win32
+		{F4935D7A-20AD-4132-B3CB-ADFF4F928D25}.Release.ActiveCfg = Release|Win32
+		{F4935D7A-20AD-4132-B3CB-ADFF4F928D25}.Release.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+	EndGlobalSection
+	GlobalSection(ExtensibilityAddIns) = postSolution
+	EndGlobalSection
+EndGlobal

+ 40 - 0
doc/makepanda/makepanda.vcproj

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.00"
+	Name="makepanda"
+	ProjectGUID="{F4935D7A-20AD-4132-B3CB-ADFF4F928D25}"
+	Keyword="MakeFileProj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="0">
+			<Tool
+				Name="VCNMakeTool"
+				BuildCommandLine="makepanda"
+				Output="built\python\python.exe"/>
+		</Configuration>
+	</Configurations>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc">
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

+ 148 - 0
doc/makepanda/maketarball.py

@@ -0,0 +1,148 @@
+#!/usr/bin/python
+
+########################################################################
+##
+## This script builds the panda source tarball.
+##
+##
+## The source tarball contains a hardwired version-number.  You specify
+## the version number using the options --v1, --v2, --v3.
+##
+## The source tarball contains most of what is in CVS, but some of the
+## control files (like the CVS directories themselves) are stripped out.
+##
+## The source tarball contains an rpmbuild 'spec' file so that you can
+## easily build a binary RPM: rpmbuild -tb panda3d-version.tar.GZ
+##
+## The 'spec' file included in the tarball uses the 'makepanda' build
+## system to compile panda.
+##
+########################################################################
+
+import sys,os,time,stat,string,re,getopt,cPickle;
+
+def oscmd(cmd):
+  print cmd
+  sys.stdout.flush()
+  if (os.system(cmd)): sys.exit("Failed")
+
+def writefile(dest,desiredcontents):
+  print "Generating file: "+dest
+  sys.stdout.flush()
+  try:
+    wfile = open(dest, 'wb');
+    wfile.write(desiredcontents);
+    wfile.close();
+  except: sys.exit("Cannot write to "+dest);
+
+########################################################################
+##
+## Parse the command-line arguments.
+##
+########################################################################
+
+VERSION1=1
+VERSION2=0
+VERSION3=0
+
+def parseopts(args):
+  global VERSION1,VERSION2,VERSION3
+  longopts = ["v1=","v2=","v3="]
+  try:
+    opts, extras = getopt.getopt(args, "", longopts)
+    for option,value in opts:
+      if (option=="--v1"): VERSION1=int(value)
+      if (option=="--v2"): VERSION2=int(value)
+      if (option=="--v3"): VERSION3=int(value)
+  except: usage(0)
+
+parseopts(sys.argv[1:])
+
+########################################################################
+##
+## Which files go into the source-archive?
+##
+########################################################################
+
+ARCHIVE=["dtool","panda","direct","pandatool","pandaapp",
+         "ppremake","SceneEditor","models","samples",
+         "Config.pp.sample","Config.prc","LICENSE","README",
+         "INSTALL-PP","INSTALL-MK","makepanda.bat","makepanda.py","maketarball.py",
+         "InstallerNotes","ReleaseNotes","makepanda.sln","makepanda.vcproj"]
+
+########################################################################
+##
+## The SPEC File
+##
+########################################################################
+
+SPEC="""Summary: Panda 3D Engine
+Name: panda3d
+Version: VERSION1.VERSION2.VERSION3
+Release: 1
+Source0: %{name}-%{version}.tar.gz
+License: Panda3D License
+Group: Development/Libraries
+BuildRoot: %{_builddir}/%{name}-%{version}/BUILDROOT
+%description
+The Panda3D engine.
+%prep
+%setup -q
+%build
+makepanda.py --v1 VERSION1 --v2 VERSION2 --v3 VERSION3 --no-installer
+%install
+rm -rf $RPM_BUILD_ROOT
+PANDA=$RPM_BUILD_ROOT/usr/share/panda3d
+mkdir -p $PANDA
+mkdir -p $RPM_BUILD_ROOT/etc/ld.so.conf.d
+mkdir -p $RPM_BUILD_ROOT/usr/bin
+cp --recursive built/bin     $PANDA/bin
+cp --recursive built/lib     $PANDA/lib
+cp --recursive built/etc     $PANDA/etc
+cp --recursive built/include $PANDA/include
+cp --recursive direct        $PANDA/direct
+cp built/direct/__init__.py  $PANDA/direct/__init__.py
+cp --recursive models        $PANDA/models
+cp --recursive samples       $PANDA/samples
+cp --recursive SceneEditor   $PANDA/SceneEditor
+cp --recursive Config.prc    $PANDA/Config.prc
+cp --recursive LICENSE       $PANDA/LICENSE
+echo "/usr/share/panda3d/lib" > $RPM_BUILD_ROOT/etc/ld.so.conf.d/panda3d
+for x in $PANDA/bin/* ; do
+  base=`basename $x`
+  ln -sf /usr/share/panda3d/bin/$base $RPM_BUILD_ROOT/usr/bin
+done
+%post
+/sbin/ldconfig
+%postun
+/sbin/ldconfig
+%clean
+rm -rf $RPM_BUILD_ROOT
+%files
+%defattr(-,root,root)
+/usr/share/panda3d
+/etc/ld.so.conf.d/panda3d
+/usr/bin
+"""
+
+SPEC=SPEC.replace("VERSION1",str(VERSION1))
+SPEC=SPEC.replace("VERSION2",str(VERSION2))
+SPEC=SPEC.replace("VERSION3",str(VERSION3))
+
+########################################################################
+##
+## Build the tar-ball
+##
+########################################################################
+
+TARDIR="panda3d-"+str(VERSION1)+"."+str(VERSION2)+"."+str(VERSION3)
+oscmd("rm -rf "+TARDIR)
+oscmd("mkdir -p "+TARDIR)
+oscmd("mkdir -p "+TARDIR+"/thirdparty")
+for x in ARCHIVE: oscmd("ln -sf ../"+x+" "+TARDIR+"/"+x)
+oscmd("ln -sf ../../thirdparty/linux-libs-a "+TARDIR+"/thirdparty/linux-libs-a")
+writefile(TARDIR+'/panda3d.spec',SPEC)
+oscmd("tar --exclude CVS -chzf "+TARDIR+".tar.gz "+TARDIR)
+oscmd("rm -rf "+TARDIR)
+
+

+ 3 - 5
dtool/metalibs/dtoolconfig/pydtool.cxx

@@ -5,17 +5,15 @@
  */
 
 
-#include "../../src/interrogatedb/interrogate_interface.h"
-#include "dtoolbase.h"
-
-#undef HAVE_LONG_LONG
-
 #if PYTHON_FRAMEWORK
   #include "Python/Python.h"
 #else
   #include "Python.h"
 #endif
+#undef HAVE_LONG_LONG
 
+#include "../../src/interrogatedb/interrogate_interface.h"
+#include "dtoolbase.h"
 
 static PyObject *_inPfd5RtbRf(PyObject *self, PyObject *args);
 static PyObject *_inPfd5R4RgX(PyObject *self, PyObject *args);

+ 2 - 1
dtool/src/interrogate/interfaceMakerPython.cxx

@@ -41,7 +41,8 @@ InterfaceMakerPython(InterrogateModuleDef *def) :
 void InterfaceMakerPython::
 write_includes(ostream &out) {
   InterfaceMaker::write_includes(out);
-  out << "#undef HAVE_LONG_LONG\n\n"
+  out << "#undef HAVE_LONG_LONG\n"
+      << "#undef _POSIX_C_SOURCE\n\n"
       << "#if PYTHON_FRAMEWORK\n"
       << "  #include \"Python/Python.h\"\n"
       << "#else\n"

+ 1 - 0
dtool/src/interrogate/interrogate_module.cxx

@@ -82,6 +82,7 @@ int
 write_python_table(ostream &out) {
   out << "\n#include \"dtoolbase.h\"\n"
       << "#include \"interrogate_request.h\"\n\n"
+      << "#undef _POSIX_C_SOURCE\n"
       << "#include \"Python.h\"\n\n";
 
   int count = 0;

+ 28 - 0
dtool/src/parser-inc/Max.h

@@ -0,0 +1,28 @@
+// Filename: zlib.h
+// Created by:  drose (14Sep00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+// This file, and all the other files in this directory, aren't
+// intended to be compiled--they're just parsed by CPPParser (and
+// interrogate) in lieu of the actual system headers, to generate the
+// interrogate database.
+
+#ifndef MAX_H
+#define MAX_H
+
+#endif
+

+ 28 - 0
dtool/src/parser-inc/iparamb2.h

@@ -0,0 +1,28 @@
+// Filename: zlib.h
+// Created by:  drose (14Sep00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+// This file, and all the other files in this directory, aren't
+// intended to be compiled--they're just parsed by CPPParser (and
+// interrogate) in lieu of the actual system headers, to generate the
+// interrogate database.
+
+#ifndef IPARAMB2_H
+#define IPARAMB2_H
+
+#endif
+

+ 28 - 0
dtool/src/parser-inc/iparamm2.h

@@ -0,0 +1,28 @@
+// Filename: zlib.h
+// Created by:  drose (14Sep00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+// This file, and all the other files in this directory, aren't
+// intended to be compiled--they're just parsed by CPPParser (and
+// interrogate) in lieu of the actual system headers, to generate the
+// interrogate database.
+
+#ifndef IPARAMM2_H
+#define IPARAMM2_H
+
+#endif
+

+ 28 - 0
dtool/src/parser-inc/iskin.h

@@ -0,0 +1,28 @@
+// Filename: zlib.h
+// Created by:  drose (14Sep00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+// This file, and all the other files in this directory, aren't
+// intended to be compiled--they're just parsed by CPPParser (and
+// interrogate) in lieu of the actual system headers, to generate the
+// interrogate database.
+
+#ifndef ISKIN_H
+#define ISKIN_H
+
+#endif
+

+ 28 - 0
dtool/src/parser-inc/istdplug.h

@@ -0,0 +1,28 @@
+// Filename: zlib.h
+// Created by:  drose (14Sep00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+// This file, and all the other files in this directory, aren't
+// intended to be compiled--they're just parsed by CPPParser (and
+// interrogate) in lieu of the actual system headers, to generate the
+// interrogate database.
+
+#ifndef ISTDPLUG_H
+#define ISTDPLUG_H
+
+#endif
+

+ 28 - 0
dtool/src/parser-inc/phyexp.h

@@ -0,0 +1,28 @@
+// Filename: zlib.h
+// Created by:  drose (14Sep00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+// This file, and all the other files in this directory, aren't
+// intended to be compiled--they're just parsed by CPPParser (and
+// interrogate) in lieu of the actual system headers, to generate the
+// interrogate database.
+
+#ifndef PHYEXP_H
+#define PHYEXP_H
+
+#endif
+

+ 28 - 0
dtool/src/parser-inc/stdmat.h

@@ -0,0 +1,28 @@
+// Filename: zlib.h
+// Created by:  drose (14Sep00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+// This file, and all the other files in this directory, aren't
+// intended to be compiled--they're just parsed by CPPParser (and
+// interrogate) in lieu of the actual system headers, to generate the
+// interrogate database.
+
+#ifndef STDMAT_H
+#define STDMAT_H
+
+#endif
+

+ 79 - 0
pandatool/src/maxegg/DllEntry.cpp

@@ -0,0 +1,79 @@
+/**********************************************************************
+ *<
+	FILE: DllEntry.cpp
+
+	DESCRIPTION: Contains the Dll Entry stuff
+
+	CREATED BY: 
+
+	HISTORY: 
+
+ *>	Copyright (c) 2000, All Rights Reserved.
+ **********************************************************************/
+
+#include "MaxEgg.h"
+
+extern ClassDesc2* 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;
+		InitCustomControls(hInstance);	// Initialize MAX's custom controls
+		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 NULL;
+	}
+}
+
+// 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 : NULL;
+	return NULL;
+}
+

+ 369 - 0
pandatool/src/maxegg/Logger.cpp

@@ -0,0 +1,369 @@
+#include "Logger.h"
+
+/*	Globals & Static Members
+ */
+
+Logger *Logger::globalLoggingInstance = 0;
+
+/*	Error Logger Member Functions 
+ */
+
+Logger::Logger()
+{
+	VoidEverything();
+	LogInstance( LLOGGING, SAT_MEDIUM_LEVEL, "A new, void Logging instance has been created." );
+}
+
+Logger::Logger( LoggingPipeType toWhere, char *additionalStringInfo )
+{
+	VoidEverything();
+	SetPipeInstance( toWhere, additionalStringInfo );
+	
+	sprintf( GetLogString(), "A new, piped logging instance has been created with data '%s'.", additionalStringInfo );
+	LogInstance( LLOGGING, SAT_MEDIUM_LEVEL, GetLogString() );
+}
+
+Logger::~Logger()
+{
+	//Send message telling everyone we're going away.
+	LogInstance( LLOGGING, SAT_MEDIUM_LEVEL, "Error logger shutting down!" );
+	//If we've got an open file, close that muthafugga!
+	if ( ( myLogDestination == PIPE_TO_FILE ) && myFileOutputLog.is_open() )
+		myFileOutputLog.close();
+	VoidEverything();
+}
+
+/*	Public, Static Member Functions
+ */
+
+void Logger::FunctionEntry( char *newFunctionName )
+{
+	if ( !globalLoggingInstance )
+		globalLoggingInstance = new Logger();
+	if ( globalLoggingInstance )
+		globalLoggingInstance->FunctionEntryInstance( newFunctionName );
+}
+
+void Logger::FunctionExit()
+{
+	if ( !globalLoggingInstance )
+		globalLoggingInstance = new Logger();
+	if ( globalLoggingInstance )
+		globalLoggingInstance->FunctionExitInstance();
+}
+
+int Logger::GetHierarchyLevel()
+{
+	if ( !globalLoggingInstance )
+		globalLoggingInstance = new Logger();
+	if ( globalLoggingInstance )
+		return globalLoggingInstance->GetHierarchyLevelInstance();
+	else return 0;
+}
+
+char * Logger::GetLogString()
+{
+	if ( !globalLoggingInstance )
+		globalLoggingInstance = new Logger();
+	if ( globalLoggingInstance )
+		return globalLoggingInstance->GetLogStringInstance();
+	else return 0;
+}
+
+void Logger::Log( SystemType whichSystem, SystemAspectType whichErrorKind, char *errorDescription )
+{
+	if ( !globalLoggingInstance )
+		globalLoggingInstance = new Logger();
+	if ( globalLoggingInstance )
+		globalLoggingInstance->LogInstance( whichSystem, whichErrorKind, errorDescription );
+}
+
+void Logger::SetCurrentFunctionName( char *newFunctionName )
+{
+	if ( !globalLoggingInstance )
+		globalLoggingInstance = new Logger();
+	if ( globalLoggingInstance )
+		globalLoggingInstance->SetCurrentFunctionNameInstance( newFunctionName );
+}
+
+void Logger::SetHierarchyLevel( unsigned int newIndentLevel )
+{
+	if ( !globalLoggingInstance )
+		globalLoggingInstance = new Logger();
+	if ( globalLoggingInstance )
+		globalLoggingInstance->SetHierarchyLevelInstance( newIndentLevel );
+}
+
+void Logger::SetOneErrorMask( SystemType whichType, long int whichErrors )
+{
+	if ( !globalLoggingInstance )
+		globalLoggingInstance = new Logger();
+	if ( globalLoggingInstance )
+		globalLoggingInstance->SetOneErrorMaskInstance( whichType, whichErrors );
+}
+
+void Logger::SetPipe( LoggingPipeType toWhere, char *additionalStringInfo )
+{
+	if ( !globalLoggingInstance )
+		globalLoggingInstance = new Logger();
+	if ( globalLoggingInstance )
+		globalLoggingInstance->SetPipeInstance( toWhere, additionalStringInfo );
+}
+
+/*	Private Member Functions
+ */
+
+void Logger::FunctionEntryInstance( char *newFunctionName )
+{
+	SetCurrentFunctionNameInstance( newFunctionName );
+	SetHierarchyLevelInstance( GetHierarchyLevelInstance() + 1 );
+}
+
+void Logger::FunctionExitInstance()
+{
+	char endMsg[64];
+
+	SetHierarchyLevelInstance( GetHierarchyLevelInstance() - 1 );
+	if ( myFunctionNames.back() )
+	{
+		if ( myWrittenHierarchyLevel >= myHierarchyLevel )
+		{
+			sprintf( endMsg, "#END {%s}", myFunctionNames.back() );
+			WriteToPipe( endMsg );
+			//LogInstance( LLOGGING, this->SAT_HIGH_LEVEL, GetLogStringInstance());
+			--myWrittenHierarchyLevel;
+		}
+		free( (void *)myFunctionNames.back() );
+		myFunctionNames.pop_back();
+	}
+}
+
+int Logger::GetHierarchyLevelInstance()
+{
+	return myHierarchyLevel;
+}
+
+char * Logger::GetLogStringInstance()
+{
+	return myLogString;
+}
+
+void Logger::LogInstance( SystemType whichSystem, SystemAspectType whichErrorKind, char *errorDescription )
+{
+	unsigned int i;
+	char *typeBuf;
+	char beginMsg[64];
+
+	if ( !errorDescription )
+		return;
+	if ( !( (int)whichErrorKind & myErrorMasks[(int)whichSystem] ) )
+		return;
+	typeBuf = (char *)malloc( strlen( errorDescription ) + 64 );
+	if ( !typeBuf )
+		return;
+	typeBuf = strcpy( typeBuf, errorDescription );
+	switch( whichErrorKind )
+	{
+	case SAT_NONE:
+		break;
+	case SAT_NULL_ERROR:
+		strcat( typeBuf, " - (***!!!NULL ERROR!!!***, " );
+		break;
+	case SAT_CRITICAL_ERROR: 
+		strcat( typeBuf, " - (***!!!CRITICAL ERROR!!!***, " );
+		break;
+	case SAT_PARAMETER_INVALID_ERROR:
+		strcat( typeBuf, " - (***PARAMETER ERROR***, " );
+		break;
+	case SAT_OTHER_ERROR:
+		strcat( typeBuf, " - (***OTHER ERROR***, " );
+		break;
+	case SAT_HIGH_LEVEL:
+		strcat( typeBuf, " - (---HIGH LEVEL---, " );
+		break;
+	case SAT_MEDIUM_LEVEL:
+		strcat( typeBuf, " - (MEDIUM LEVEL, " );
+		break;
+	case SAT_LOW_LEVEL: 
+		strcat( typeBuf, " - (LOW LEVEL, " );
+		break;
+	case SAT_DEBUG_SPAM_LEVEL:
+		strcat( typeBuf, " - (SPAM LEVEL, " );
+		break;
+	case SAT_ALL:
+		strcat( typeBuf, " - (ALL INCLUSIVE, " );
+		break;
+	}
+	switch( whichSystem )
+	{
+	case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM1: 
+		strcat( typeBuf, "SYS_ONE)" );
+		break;
+	case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM2: 
+		strcat( typeBuf, "SYS_TWO)" );
+		break;
+	case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM3:  
+		strcat( typeBuf, "SYS_THREE)" );
+		break;
+	case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM4: 
+		strcat( typeBuf, "SYS_FOUR)" );
+		break;
+	case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM5: 
+		strcat( typeBuf, "SYS_FIVE)" );
+		break;
+	case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM6: 
+		strcat( typeBuf, "SYS_SIX)" );
+		break;
+	case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM7: 
+		strcat( typeBuf, "SYS_SEVEN)" );
+		break;
+	case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM8: 
+		strcat( typeBuf, "SYS_EIGHT)" );
+		break;
+	}
+	
+	//Now that we've created the correct logging line to print, we need to worry
+	//about function entries and exits. Only do this if we're not writing to a dialog box.
+	if ( myLogDestination != PIPE_TO_DIALOG_BOX )
+	{
+		unsigned int tempHierarchyLevel = myHierarchyLevel;
+
+		i = 0;
+		for( CharStarVectorIterator hierarchyDepthIterator = myFunctionNames.begin(); 
+			hierarchyDepthIterator != myFunctionNames.end(); 
+			++hierarchyDepthIterator )
+		{
+			++i;
+			//Since we're writing some output, we need to print all function headings
+			//leading up to this output, bumping up our written hierarchy level to match
+			//the "actual" level. 
+			//If we've reached a function level that's deeper than what we've written out already...
+			if ( i > myWrittenHierarchyLevel )
+			{
+				myHierarchyLevel = myWrittenHierarchyLevel;
+				sprintf( beginMsg, "#BEGIN {%s}", *hierarchyDepthIterator );
+				WriteToPipe( beginMsg );	
+				myHierarchyLevel = tempHierarchyLevel;
+				++myWrittenHierarchyLevel;
+			}
+		}
+	}
+	WriteToPipe( typeBuf );
+	free(typeBuf);
+}
+
+void Logger::SetCurrentFunctionNameInstance( char *newFunctionName )
+{
+	char *newBuf;
+
+	//No FunctionEntry Instance allowed...that function uses this!
+	if ( !newFunctionName )
+	{
+		LogInstance( LLOGGING, SAT_NULL_ERROR, "newFunctionName is null!" );
+		return;
+	}
+	newBuf = strdup( newFunctionName );
+	myFunctionNames.push_back( newBuf );
+}
+
+void Logger::SetHierarchyLevelInstance( unsigned int newIndentLevel )
+{
+	myHierarchyLevel = newIndentLevel;
+}
+
+void Logger::SetOneErrorMaskInstance( SystemType whichType, long int whichErrors )
+{
+	if ( ( (int)whichType < 0 ) || ( (int)whichType >= MY_MAX_NUM_SYSTEMS ) )
+	{
+		LogInstance( LLOGGING, SAT_PARAMETER_INVALID_ERROR, "whichType is out of bounds!" );
+		return;
+	}
+	//Now that the sanity check is out of the way, let us change the error mask!
+	myErrorMasks[(int)whichType] = whichErrors;
+	sprintf( GetLogStringInstance(), "Set error mask for system with ID %x to %x.", (int)whichType, whichErrors );
+	LogInstance( LLOGGING, SAT_LOW_LEVEL, GetLogStringInstance() );
+}
+
+void Logger::SetPipeInstance( LoggingPipeType toWhere, char *additionalStringInfo )
+{
+	myLogDestination = toWhere;
+	switch( myLogDestination )
+	{
+	case PIPE_TO_FILE:
+		if ( myFileOutputLog.is_open() )
+			myFileOutputLog.close();
+		if ( additionalStringInfo )
+			myFileOutputLog.open( additionalStringInfo, ofstream::out | ofstream::trunc );
+		else
+			myFileOutputLog.open( "Kens_Logger_Log_File.txt", ofstream::out | ofstream::trunc );
+		LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to file." );
+		break;
+	case PIPE_TO_COUT:
+		LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to cout." );
+		break;
+	case PIPE_TO_CERR:
+		LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to cerr." );
+		break;
+	case PIPE_TO_DIALOG_BOX:
+		LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to dialog box." );
+		break;
+	case PIPE_TO_DEV_NULL:
+		LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to dev null." );
+		break;
+	}
+}
+
+void Logger::VoidEverything()
+{
+	myLogDestination = PIPE_TO_DEV_NULL;
+	myHierarchyLevel = 0;
+	myWrittenHierarchyLevel = 0;
+	//(Get rid of the stack of called functions.)
+	for (CharStarVectorIterator it = myFunctionNames.begin(); it < myFunctionNames.end(); it++) {
+	  if (*it)
+		 free ((void *)(*it));
+	}
+	myFunctionNames.erase( myFunctionNames.begin(), myFunctionNames.end() );
+	//Make it so that our logger blindly accepts all logs...
+	for( int i = 0; i < MY_MAX_NUM_SYSTEMS; ++i )
+		SetOneErrorMaskInstance( (SystemType)i, (long int)SAT_ALL );
+	//...but pipes them all to /dev/null. Mwahaha! The irony!
+	strncpy( myLogString, "No Error", LOGGER_STRING_BUFFER_SIZE - 1 );
+}
+
+void Logger::WriteToPipe( char *textToPipe )
+{
+	switch( myLogDestination )
+	{
+	case PIPE_TO_FILE:
+		if ( myFileOutputLog.is_open() )
+		{
+			for ( int i = 0; i < myHierarchyLevel; ++i )
+				myFileOutputLog << "  ";
+			myFileOutputLog << textToPipe << endl;
+			myFileOutputLog.flush();
+		}
+		break;
+	case PIPE_TO_COUT:
+		cout << "("  << textToPipe << ")" << endl;
+		break;
+	case PIPE_TO_CERR:
+		cerr << "(" << textToPipe << ")" << endl;
+		break;
+	case PIPE_TO_DIALOG_BOX:
+		MessageBox( NULL, textToPipe, "Logger", MB_OK );
+		break;
+	case PIPE_TO_DEV_NULL:
+		break;
+	}
+}
+
+
+
+
+
+
+
+
+
+

+ 121 - 0
pandatool/src/maxegg/Logger.h

@@ -0,0 +1,121 @@
+#ifndef __Kens_Logger__H
+#define __Kens_Logger__H
+
+/*	Standard C++ Includes for file and stream output
+ */
+
+//For file IO and cmd line output
+#include <iostream>
+#include <fstream>
+
+//For MessageBox
+#include "windows.h"
+
+#define MY_MAX_NUM_SYSTEMS 8
+#define LOGGER_STRING_BUFFER_SIZE 128
+
+#include <vector>
+using namespace std;
+
+/*	Vector definitions
+ */
+
+typedef vector<char *> CharStarVector;
+typedef CharStarVector::iterator CharStarVectorIterator;
+
+/*	Class Defintions
+ */
+
+class Logger
+{
+public:
+	enum SystemAspectType
+	{
+		SAT_NONE = 0x0000,
+		SAT_NULL_ERROR = 0x0001, 
+		SAT_CRITICAL_ERROR = 0x0002, 
+		SAT_PARAMETER_INVALID_ERROR = 0x0004, 
+		SAT_OTHER_ERROR = 0x0008,
+		SAT_HIGH_LEVEL = 0x0010, 
+		SAT_MEDIUM_LEVEL = 0x0020, 
+		SAT_LOW_LEVEL = 0x0040, 
+		SAT_DEBUG_SPAM_LEVEL = 0x0080,
+		SAT_ALL = 0x00FF
+	};
+
+	enum SystemType
+	{
+		ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM1 = 0x0000, 
+		ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM2 = 0x0001, 
+		ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM3 = 0x0002, 
+		ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM4 = 0x0003,
+		ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM5 = 0x0004, 
+		ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM6 = 0x0005, 
+		ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM7 = 0x0006, 
+		ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM8 = 0x0007		
+	};
+
+	enum LoggingPipeType
+	{
+		PIPE_TO_FILE, PIPE_TO_COUT, PIPE_TO_CERR, PIPE_TO_DIALOG_BOX, PIPE_TO_DEV_NULL
+	};
+
+private:
+	//Which errors to display
+	long int			myErrorMasks[MY_MAX_NUM_SYSTEMS];
+	//For use when the the logger is set to pipe to a file.
+	ofstream			myFileOutputLog;
+	//The stack of called functions.
+	CharStarVector		myFunctionNames;
+	//For formatting purposes, in the file, cerr, or cout versions, add n whitespace to the front, where n is this.
+	unsigned int		myHierarchyLevel;
+	//A memory of which state we're in, as far as output is concerned
+	LoggingPipeType		myLogDestination;
+	//A pre-allocated string to use with sprintf, or when error logging just needs a little scratch space.
+	char				myLogString[LOGGER_STRING_BUFFER_SIZE];
+	//An integer that keeps track of how far down into the indent hierarchy we've actually written.
+	unsigned int		myWrittenHierarchyLevel;
+	
+public:
+	//A static pointer to an active errorLogger that any class can get to.
+	static Logger *globalLoggingInstance;
+
+	//Constructors & Destructor
+	Logger();
+	Logger( LoggingPipeType toWhere, char *additionalStringInfo );
+	~Logger();
+	//Static functions that constitute the main interface to this class.
+	static void		FunctionEntry( char *newFunctionName );
+	static void		FunctionExit();
+	static int		GetHierarchyLevel();
+	static char *	GetLogString();
+	static void		Log( SystemType whichSystem, SystemAspectType whichErrorKind, char *errorDescription );
+	static void		SetCurrentFunctionName( char *newFunctionName );
+	static void		SetHierarchyLevel( unsigned int newIndentLevel );
+	static void		SetOneErrorMask( SystemType whichType, long int whichErrors );
+	static void		SetPipe( LoggingPipeType toWhere, char *additionalStringInfo );
+	
+private:
+	//Private functions called by the static versions if a globalLogging instance exists.
+	void			FunctionEntryInstance( char *newFunctionName );
+	void			FunctionExitInstance();
+	int				GetHierarchyLevelInstance();
+	char *			GetLogStringInstance();
+	void			LogInstance( SystemType whichSystem, SystemAspectType whichErrorKind, char *errorDescription );
+	void			SetCurrentFunctionNameInstance( char *newFunctionName );
+	void			SetHierarchyLevelInstance( unsigned int newIndentLevel );
+	void			SetOneErrorMaskInstance( SystemType whichType, long int whichErrors );
+	void			SetPipeInstance( LoggingPipeType toWhere, char *additionalStringInfo );
+	void			VoidEverything();
+	void			WriteToPipe( char *textToPipe );
+};
+
+/*	Subsystem defs for logger.
+ */
+
+#define LLOGGING Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM1
+
+/*	Externed Globals
+ */
+
+#endif

+ 410 - 0
pandatool/src/maxegg/MaxEgg.cpp

@@ -0,0 +1,410 @@
+/*
+  MaxEgg.cpp 
+  Created by Steven "Sauce" Osman, 01/??/03
+  odified and maintained by Ken Strickland, (02/25/03)-(Present)
+  Carnegie Mellon University, Entetainment Technology Center
+
+  This file implements the classes that are used in the Panda 3D file 
+  exporter for 3D Studio Max.
+*/
+
+//Includes & Defines
+#include "MaxEgg.h"
+//Types and structures from windows system-level calls
+#include <sys/types.h>
+#include <sys/stat.h>
+//Controls used in fopen
+#include <fcntl.h>
+//C Debugging
+#include <crtdbg.h>
+
+// Discreet-Generated ID for this app.
+#define MaxEggPlugin_CLASS_ID	Class_ID(0x7ac0d6b7, 0x55731ef6)
+// Our version number * 100
+#define MAX_EGG_VERSION_NUMBER 100 
+#define MNEG Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM2
+#define MNEG_GEOMETRY_GENERATION Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM3
+
+/* MaxEggPluginClassDesc - A class that describes 3DS Plugin support.
+   This basically says "Yes, I can export files. Use me!"
+*/
+class MaxEggPluginClassDesc:public ClassDesc2 
+{
+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 SCENE_EXPORT_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"); }
+  // returns owning module handle
+  HINSTANCE HInstance() { return hInstance; }
+};
+
+// Our static instance of the above class
+static MaxEggPluginClassDesc MaxEggPluginDesc;
+
+// The function that I believe Max calls, when looking for information as
+// to what this plugin does.
+ClassDesc2* GetMaxEggPluginDesc() { return &MaxEggPluginDesc; }
+
+/* MaxEggPluginOptionsDlgProc() - This is the callback function for the
+   dialog box that appears at the beginning of the conversion process.
+ */
+BOOL CALLBACK MaxEggPluginOptionsDlgProc( HWND hWnd, UINT message, 
+					  WPARAM wParam, LPARAM lParam ) 
+{
+  //We pass in our plugin through the lParam variable. Let's convert it back.
+  MaxEggPlugin *imp = (MaxEggPlugin*)GetWindowLongPtr(hWnd,GWLP_USERDATA); 
+
+  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); 
+      CenterWindow(hWnd,GetParent(hWnd));
+      return TRUE;
+      break;
+    // Closing the window is equivalent to canceling the export
+    case WM_CLOSE:
+      imp->confirmExport = false;
+      EndDialog(hWnd, 0);
+      return TRUE;
+      break;
+    // If we get here, this means thatone of our controls was modified.
+    case WM_COMMAND:
+      //The control in question will be found in the lower word of the wParam 
+      // long.
+      switch( LOWORD(wParam) ) 
+	{
+	// The checkbox for toggling whether this model has animations
+	case IDC_ANIMATION:
+	  // sets the plugin's animation parameter
+	  imp->animation = !imp->animation;
+	  CheckDlgButton( hWnd, IDC_ANIMATION, 
+			  imp->animation ? BST_CHECKED : BST_UNCHECKED );
+	  
+	  // Enables/disables the animation options depending on how the 
+	  // animation checkbox is checked
+	  EnableWindow(GetDlgItem(hWnd, IDC_MODEL), imp->animation);
+	  EnableWindow(GetDlgItem(hWnd, IDC_CHAN), imp->animation);
+	  EnableWindow(GetDlgItem(hWnd, IDC_POSE), imp->animation);
+	  EnableWindow(GetDlgItem(hWnd, IDC_STROBE), imp->animation);
+	  EnableWindow(GetDlgItem(hWnd, IDC_BOTH), imp->animation);
+	  EnableWindow(GetDlgItem(hWnd, IDC_SF), imp->animation);
+	  EnableWindow(GetDlgItem(hWnd, IDC_EF), imp->animation);
+
+	  // if this is the first time the animation checkbox has been checked,
+	  // then there is no animation type set, so set the animation type to
+	  // "model" 
+	  if (imp->anim_type == MaxEggPlugin::AT_none) {
+	    CheckDlgButton( hWnd, IDC_MODEL, BST_CHECKED );
+	    imp->anim_type = MaxEggPlugin::AT_model;
+	  }
+	  return TRUE;
+	  break;
+
+	// The radio buttons for what type of animation will exported
+	// The animation type is set by these buttons
+	case IDC_MODEL:
+	  imp->anim_type = MaxEggPlugin::AT_model;
+	  break;
+	case IDC_CHAN:
+	  imp->anim_type = MaxEggPlugin::AT_chan;
+	  break;
+	case IDC_POSE:
+	  imp->anim_type = MaxEggPlugin::AT_pose;
+	  break;
+	case IDC_STROBE:
+	  imp->anim_type = MaxEggPlugin::AT_strobe;
+	  break;
+	case IDC_BOTH:
+	  imp->anim_type = MaxEggPlugin::AT_both;
+	  break;
+	  
+	//The checkbox that toggles wether to make a .BAM file or not.
+	case IDC_MAKE_BAM:
+	  imp->makeBam = !imp->makeBam; 
+	  CheckDlgButton( hWnd, IDC_MAKE_BAM,
+			  imp->makeBam ? BST_CHECKED : BST_UNCHECKED );
+	  return TRUE;
+	  break;
+	// Ckicking the cancel button obviously cancels the export
+	case IDC_CANCEL:
+	  imp->confirmExport = false;
+	  EndDialog(hWnd, 0);
+	  return TRUE;
+	  break;
+	// Clicking the done button is the only way to continue with the export
+	case IDC_DONE:
+	  imp->confirmExport = true;
+	  EndDialog(hWnd, 0);
+	  return TRUE;
+	  break;
+	}
+      break;
+    }
+  return FALSE;
+}
+
+/* MaxEggPlugin() - Uninteresting constructor.
+ */
+MaxEggPlugin::MaxEggPlugin() 
+{
+  makeBam = false;
+  animation = false;
+  anim_type = AT_none;
+}
+
+/* ~MaxEggPlugin() - Uninteresting destructor.
+ */
+MaxEggPlugin::~MaxEggPlugin() 
+{
+}
+
+/* ExtCount() - Returns the number of extensions this exporter produces. 
+   That's only one, .EGG files.
+ */
+int MaxEggPlugin::ExtCount() 
+{
+  return 1;
+}
+
+/* Ext(int) - Returns the nth extension. Since there's only one, it always 
+   returns "egg"
+*/
+const TCHAR *MaxEggPlugin::Ext(int n) 
+{
+  return _T("egg");
+}
+
+/* LongDesc() - A long description of the files we export.  Curiously, this 
+   isn't for the nth extension, rather a one-description-fits-all thing.
+*/
+const TCHAR *MaxEggPlugin::LongDesc() 
+{
+  return _T("Panda3D .egg file");
+}
+
+/**
+ * A short description of the files we export.  Curiously, this isn't
+ * for the nth extension, rather a one-description-fits-all thing.
+ */
+const TCHAR *MaxEggPlugin::ShortDesc() 
+{			
+  return _T("Panda3D");
+}
+
+/**
+ * Who wrote this.
+ */
+const TCHAR *MaxEggPlugin::AuthorName() 
+{			
+  return _T("Steven \"Sauce\" Osman");
+}
+
+/**
+ * Who owns this.
+ */
+const TCHAR *MaxEggPlugin::CopyrightMessage() 
+{	
+  return _T("Copyright (C) 2003 Carnegie Mellon University, Entertainment Technology Center");
+}
+
+/**
+ * Who cares?
+ */
+const TCHAR *MaxEggPlugin::OtherMessage1() 
+{
+  return _T("Modified by Ken Strickland");
+}
+
+/**
+ * Who knows?
+ */
+const TCHAR *MaxEggPlugin::OtherMessage2() 
+{		
+  return _T("Who's got the funk? We do!");
+}
+
+/**
+ * Returns version * 100.  defined in MAX_EGG_VERSION_NUMBER
+ */
+unsigned int MaxEggPlugin::Version() 
+{				
+  return MAX_EGG_VERSION_NUMBER;
+}
+
+/**
+ * No about dialog box right now.
+ */
+void MaxEggPlugin::ShowAbout(HWND hWnd) 
+{			
+}
+
+/**
+ * We'll support all options by default.
+ */
+BOOL MaxEggPlugin::SupportsOptions(int ext, DWORD options) 
+{
+  // According to the maxsdk help, there is only one option which is 
+  // SCENE_EXPORT_SELECTED.  This should return false until the code
+  // for converting only selected objects to egg is written
+  
+  return false;
+}
+
+/*!
+ * This method creates and triggers the exporter.  Basically it takes the
+ * user's options and builds a command-line parameter list from it.
+ * It then invokes the converter pretending it was invoked as a standalone
+ * program.  BIG WARNING:  The converter stuff often does exit() if the
+ * command line arguments are displeasing.
+ */
+int MaxEggPlugin::DoExport(const TCHAR *ptcOutputFilename,ExpInterface *ei,
+			   Interface *pMaxInterface,
+			   BOOL suppressPrompts, DWORD options) 
+{
+  MaxToEgg *pmteConverter = new MaxToEgg();
+  char *apcParameters[64];
+  char acOutputFilename[MAX_PATH];
+  int iParameterCount=0;
+
+  //Initialize our global error logger
+  Logger::globalLoggingInstance = new Logger( Logger::PIPE_TO_FILE, 
+					      "MaxEggLog.txt" );
+
+  //Set the various logging levels for the subsystems.
+  Logger::SetOneErrorMask( ME, Logger::SAT_ALL );
+  Logger::SetOneErrorMask( MTE, Logger::SAT_NULL_ERROR | 
+			   Logger::SAT_CRITICAL_ERROR | 
+			   Logger::SAT_PARAMETER_INVALID_ERROR | 
+			   Logger::SAT_OTHER_ERROR | Logger::SAT_HIGH_LEVEL );
+  Logger::SetOneErrorMask( MTEC, Logger::SAT_NULL_ERROR | 
+			   Logger::SAT_CRITICAL_ERROR |
+			   Logger::SAT_PARAMETER_INVALID_ERROR | 
+			   Logger::SAT_OTHER_ERROR | Logger::SAT_HIGH_LEVEL |
+			   Logger::SAT_MEDIUM_LEVEL | Logger::SAT_LOW_LEVEL |
+			   Logger::SAT_DEBUG_SPAM_LEVEL );
+  Logger::SetOneErrorMask( MNEG, Logger::SAT_NULL_ERROR |
+			   Logger::SAT_CRITICAL_ERROR |
+			   Logger::SAT_PARAMETER_INVALID_ERROR | 
+			   Logger::SAT_OTHER_ERROR | Logger::SAT_HIGH_LEVEL |
+			   Logger::SAT_MEDIUM_LEVEL | Logger::SAT_LOW_LEVEL );
+  Logger::SetOneErrorMask( MNEG_GEOMETRY_GENERATION, Logger::SAT_NULL_ERROR |
+			   Logger::SAT_CRITICAL_ERROR |
+			   Logger::SAT_PARAMETER_INVALID_ERROR | 
+			   Logger::SAT_OTHER_ERROR | Logger::SAT_HIGH_LEVEL |
+			   Logger::SAT_MEDIUM_LEVEL | Logger::SAT_LOW_LEVEL );
+  Logger::SetOneErrorMask( LLOGGING, Logger::SAT_ALL );
+	
+  Logger::FunctionEntry( "MaxEggPlugin::DoExport" );
+
+  // Copy the output filename so that it can be modified if necessary
+  strncpy(acOutputFilename,ptcOutputFilename,MAX_PATH-1);
+  acOutputFilename[MAX_PATH-1]=0;
+
+  // Panda reaaaaaaaaly wants the extension to be in lower case.
+  // So if we see a .egg at the end, lower case it.
+  if ((strlen(acOutputFilename)>4) &&
+      (stricmp(acOutputFilename+strlen(acOutputFilename)-4,".egg")==0)) {
+    strlwr(acOutputFilename+strlen(acOutputFilename)-4);
+  }
+  
+  pmteConverter->SetMaxInterface(pMaxInterface);
+  
+  // Set the command-line arguments
+  // ARGV[0] = program name
+  apcParameters[iParameterCount++]="MaxEggPlugin";
+  
+  confirmExport = false;
+  if(!suppressPrompts)
+    // Displays the dialog box that retrieves the export options
+    DialogBoxParam(hInstance, 
+		   MAKEINTRESOURCE(IDD_PANEL), 
+		   pMaxInterface->GetMAXHWnd(), 
+		   MaxEggPluginOptionsDlgProc, (LPARAM)this);
+  
+  // Stops the export if the user chooses to cancel
+  if (!confirmExport)
+    return true;
+  
+  // ARGV[1] = Input file
+  // Use a bogus input filename that exists
+  apcParameters[iParameterCount++]="nul.max";
+  
+  // ARGV[2,3] = Output file
+  // Pass in the output filename
+  // Output file has to be passed in with the -o parameter in order to be able 
+  // to overwrite an existing file
+  apcParameters[iParameterCount++]="-o";
+  apcParameters[iParameterCount++]=acOutputFilename;
+  
+  // ARGV[4,5] = Animation options (if animation is checked)
+  // Check if there is an animation to be saved and what type of animation it
+  // will be saved as.  Then set the animation option.
+  if (animation) {
+    apcParameters[iParameterCount++]="-a";
+    switch (anim_type) 
+      {
+      case AT_model:
+	apcParameters[iParameterCount++]="model";
+	break;
+      case AT_chan:
+	apcParameters[iParameterCount++]="chan";
+	break;
+      case AT_pose:
+	apcParameters[iParameterCount++]="pose";
+	break;
+      case AT_strobe:
+	apcParameters[iParameterCount++]="strobe";
+	break;
+      case AT_both:
+	apcParameters[iParameterCount++]="both";
+	break;
+      default:
+	apcParameters[iParameterCount++]="none";
+	break;
+      }
+  }
+  apcParameters[iParameterCount]=0;
+
+  // Parse the command line and run the converter
+  pmteConverter->parse_command_line(iParameterCount, apcParameters);
+  pmteConverter->Run();
+  
+  bool bSuccessful = pmteConverter->IsSuccessful();
+  
+  // Display a message box telling that the export is completed
+  if (bSuccessful)
+    MessageBox(pMaxInterface->GetMAXHWnd(), 
+	       "Export to EGG completed successfully.", "Panda3D Converter",
+	       MB_OK);
+  else
+    MessageBox(pMaxInterface->GetMAXHWnd(), "Export unsuccessful.", 
+	       "Panda3D Converter", MB_OK);
+		Logger::Log(MTEC, Logger::SAT_MEDIUM_LEVEL, "After finished mbox");
+
+  // This was put in try block because originally deleting pmteConverter 
+  // would throw an exception.  That no longer happens, but this is still
+  // here for good measure
+  try {
+		Logger::Log(MTEC, Logger::SAT_MEDIUM_LEVEL, "before deleting pmteconverter");
+    delete pmteConverter; 
+  } catch (...) {
+		Logger::Log(MTEC, Logger::SAT_MEDIUM_LEVEL, "before error message window");
+    MessageBox(pMaxInterface->GetMAXHWnd(), "I just got an unknown exception.",
+	       "Panda3D Converter", MB_OK);
+  }
+		Logger::Log(MTEC, Logger::SAT_MEDIUM_LEVEL, "before logger function exit");
+  Logger::FunctionExit();
+  //Free the error logger
+  if ( Logger::globalLoggingInstance )
+    delete Logger::globalLoggingInstance;
+ 
+  return bSuccessful;
+}

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

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

+ 92 - 0
pandatool/src/maxegg/MaxEgg.h

@@ -0,0 +1,92 @@
+/*
+  MaxEgg.h 
+  Created by Steven "Sauce" Osman, 01/??/03
+  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 __MaxEggPlugin__H
+#define __MaxEggPlugin__H
+
+#pragma conform(forScope, off)
+
+#include "pandatoolbase.h"
+
+//Includes & Definitions
+#include "MaxToEgg.h"
+#include "windef.h"
+
+/* Error-Reporting Includes
+ */
+#include "Logger.h"
+#define ME Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM6
+
+/* 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.
+*/
+class MaxEggPlugin : public SceneExport 
+{
+ public:
+  static HWND hParams;
+  bool confirmExport;
+  bool makeBam;
+  bool animation;
+  enum Anim_Type {
+    AT_none,
+    AT_model,
+    AT_chan,
+    AT_pose,
+    AT_strobe,
+    AT_both
+  };
+  Anim_Type anim_type;
+  
+  // Number of extensions supported
+  int ExtCount();
+  // Extension #n (i.e. "3DS")
+  const TCHAR *Ext(int n);					
+  // Long ASCII description (i.e. "Autodesk 3D Studio File")
+  const TCHAR *LongDesc();
+  // Short ASCII description (i.e. "3D Studio")
+  const TCHAR *ShortDesc();
+  // ASCII Author name
+  const TCHAR *AuthorName();
+  // ASCII Copyright message
+  const TCHAR *CopyrightMessage();
+  // Other message #1
+  const TCHAR *OtherMessage1();
+  // Other message #2
+  const TCHAR *OtherMessage2();
+  // Version number * 100 (i.e. v3.01 = 301)
+  unsigned int Version();
+  // Show DLL's "About..." box
+  void ShowAbout(HWND hWnd);
+
+  BOOL SupportsOptions(int ext, DWORD options);
+  int DoExport(const TCHAR *name,ExpInterface *ei,
+	       Interface *i, BOOL suppressPrompts=FALSE, DWORD options=0);
+
+  //Constructor/Destructor
+  MaxEggPlugin();
+  virtual ~MaxEggPlugin();
+};
+
+#endif // __MaxEggPlugin__H

+ 180 - 0
pandatool/src/maxegg/MaxEgg.rc

@@ -0,0 +1,180 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_PANEL DIALOGEX 0, 0, 374, 169
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | 
+    WS_SYSMENU
+EXSTYLE WS_EX_TOOLWINDOW
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+    CTEXT           "MaxToEgg Exporter",IDC_STATIC,7,7,360,10
+    CTEXT           "By Corey Revilla, Ken Strickland, and Steve Osman.",
+                    IDC_STATIC,7,21,360,19
+    CONTROL         "Also create .BAM file",IDC_MAKE_BAM,"Button",
+                    BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,35,138,81,10
+    PUSHBUTTON      "Done",IDC_DONE,303,139,50,14
+    GROUPBOX        "",IDC_STATIC,21,38,333,93
+    CONTROL         "Animation",IDC_ANIMATION,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,27,38,49,10
+    CONTROL         "model only",IDC_MODEL,"Button",BS_AUTORADIOBUTTON | 
+                    WS_DISABLED | WS_GROUP | WS_TABSTOP,35,51,60,12
+    CONTROL         "animation channel only",IDC_CHAN,"Button",
+                    BS_AUTORADIOBUTTON | WS_DISABLED | WS_TABSTOP,35,65,92,
+                    12
+    CONTROL         "pose",IDC_POSE,"Button",BS_AUTORADIOBUTTON | 
+                    WS_DISABLED | WS_TABSTOP,35,80,60,12
+    CONTROL         "strobe",IDC_STROBE,"Button",BS_AUTORADIOBUTTON | 
+                    WS_DISABLED | WS_TABSTOP,35,95,60,12
+    CONTROL         "model and animation channel",IDC_BOTH,"Button",
+                    BS_AUTORADIOBUTTON | WS_DISABLED | WS_TABSTOP,35,110,110,
+                    12
+    EDITTEXT        IDC_CN,254,54,71,12,ES_AUTOHSCROLL | WS_DISABLED
+    EDITTEXT        IDC_SF,303,70,22,12,ES_AUTOHSCROLL | WS_DISABLED
+    EDITTEXT        IDC_IF,303,103,22,12,ES_AUTOHSCROLL | WS_DISABLED
+    EDITTEXT        IDC_EF,303,87,22,12,ES_AUTOHSCROLL | WS_DISABLED
+    LTEXT           "Character Name",IDC_CN_LABEL,187,56,54,10,WS_DISABLED
+    LTEXT           "Start Frame",IDC_SF_LABEL,187,72,48,10,WS_DISABLED
+    LTEXT           "End Frame",IDC_EF_LABEL,187,88,45,10,WS_DISABLED
+    LTEXT           "Frame Increment",IDC_IF_LABEL,187,105,64,10,WS_DISABLED
+    PUSHBUTTON      "Cancel",IDC_CANCEL,250,139,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_PANEL, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 367
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 162
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,0,0,0
+ PRODUCTVERSION 3,0,0,0
+ FILEFLAGSMASK 0x3fL
+#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
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE 
+BEGIN
+    IDS_LIBDESCRIPTION      "Panda3D .egg exporter"
+    IDS_CATEGORY            "egg"
+    IDS_CLASS_NAME          "MaxEgg"
+    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
+

+ 88 - 0
pandatool/src/maxegg/MaxToEgg.cpp

@@ -0,0 +1,88 @@
+/*
+  MaxToEgg.cpp
+  Created by Ken Strickland 02/24/03
+  Modified and maintained by Corey Revilla, (05/22/03)-(Present)
+  Carnegie Mellon University, Entetainment Technology Center
+*/
+
+//Our headers, which in turn includes some Max headers. 
+#include "MaxToEgg.h"
+
+//Member Function Definitions
+/* ~MaxToEgg() - Uninteresting destructor.
+ */
+MaxToEgg::~MaxToEgg() 
+{
+}
+
+/* MaxToEgg() - Constructs a MaxToEgg "application."  It sets the types of
+   options this converter can take and sets up a description of the program.
+ */
+MaxToEgg::MaxToEgg() : SomethingToEgg("3D Studio Max",".max") 
+{
+  add_path_replace_options();
+  add_path_store_options();
+  add_animation_options();
+  add_units_options();
+  add_normals_options();
+  add_transform_options();
+
+  set_program_description("This program converts 3D Studio Max model files to egg.");
+  add_option("p", "", 0,
+	     "Generate polygon output only.  Convert scene to triangle mesh "
+	     "before converting.", &MaxToEgg::dispatch_none, &alertOnBegin);
+  //Fill in the member variables.
+  pMaxInterface = null;
+  successfulOutput = false;
+  alertOnBegin = false;
+}
+
+/* IsSuccessful() - Indicates if conversion was successful.
+ */
+bool MaxToEgg::IsSuccessful() 
+{
+  return successfulOutput;
+}
+
+char *MaxToEgg::MyClassName()
+{
+  return "MaxToEgg";
+}
+
+/* Run() - Runs the conversion.  Creates a MaxToEggConverter, populates it
+   with the scene graph, and then writes out the egg file.
+*/
+void MaxToEgg::Run() 
+{
+  MaxToEggConverter converter;
+
+  Logger::FunctionEntry( "MaxToEgg::Run" );
+  // Now, we fill out the necessary fields of the converter, which does all
+  // the necessary work.
+  Logger::Log( MTE, Logger::SAT_DEBUG_SPAM_LEVEL, "Setting Max Interface." );
+  converter.setMaxInterface( pMaxInterface );
+  Logger::Log( MTE, Logger::SAT_DEBUG_SPAM_LEVEL,
+	       "Setting converter's egg data." );
+  converter.set_egg_data( &_data, false );
+  // applies the parameters from the command line options
+  apply_parameters(converter);
+  
+  //Now, do the actual file conversion.
+  if (converter.convert_file(_input_filename)) {
+    successfulOutput=true;
+    write_egg_file();
+    Logger::Log( MTE, Logger::SAT_DEBUG_SPAM_LEVEL, "Egg file written!" );
+  }
+
+  Logger::FunctionExit();
+}
+
+
+/* SetMaxInterface(Interface *) - This is how we know how to traverse the Max
+   scene graph.  For this to be	a standalone application, we'd want to be able
+   to build one of these interfaces for the input file.
+*/
+void MaxToEgg::SetMaxInterface(Interface *pInterface) 
+{
+  pMaxInterface = pInterface;
+}

+ 58 - 0
pandatool/src/maxegg/MaxToEgg.h

@@ -0,0 +1,58 @@
+/*
+  MaxToEgg.h 
+  Created by Ken Strickland, 02/24/03
+  Modified + Maintained by Corey Revilla, (05/22/03-Present)
+  CMU's Entertainment Technology Center
+  
+  This file defines the MaxToEgg class, a class derived from SomethingToEgg,
+  which means it was designed to be a standalone application that would get
+  called by Ppremake during compilation to convert models of the appropriate
+  type. As there doesn't seem to be a way get at the 3dsMax API without going
+  the plug-in route, however, this class is actually run by another wrapper
+  class, MaxEggPlugin. This class, in turn, is a wrapper about the 
+  MaxToEggConverter class, which actually twiddles the bits, as they say.
+*/
+#ifndef __MaxToEgg__H
+#define __MaxToEgg__H
+
+#pragma conform(forScope, off)
+
+#include "pandatoolbase.h"
+
+#include "MaxToEggConverter.h"
+
+/* Error-Reporting Includes
+ */
+#include "Logger.h"
+#define MTE Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM5
+
+/**
+ * This class defines a "converter" between Max files and eggs.  All it
+ * does is define the output file, call MaxToEggConverter to actually
+ * convert the geometry, and then write out the output file.
+ */
+class MaxToEgg : public SomethingToEgg 
+{
+ protected:
+  // If true, various windows pop-up alerts will announce when certain tasks
+  // begin.
+  bool alertOnBegin;
+  // The local pointer to the 3ds max interface we keep around to get the
+  // scene graph. If we ever get this to run standalone, we'll need an
+  // alternate way to set this other than through MaxEggPlugin. 
+  Interface *pMaxInterface;
+  // False initially, but premanently switches to true when a file is 
+  // sucessfully converted.
+  bool successfulOutput;
+
+ public:
+  MaxToEgg();
+  ~MaxToEgg();
+  bool IsSuccessful();
+  //Returns a pointer to the class name.
+  char *MyClassName();
+  void Run();
+  void SetMaxInterface(Interface *pInterface);
+};
+
+#endif

+ 189 - 0
pandatool/src/maxegg/MaxToEggConverter.h

@@ -0,0 +1,189 @@
+// Filename: mayaToEggConverter.h
+// Created by:  drose (10Nov99)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef __MaxToEggConverter__H
+#define __MaxToEggConverter__H
+
+#pragma conform(forScope, off)
+
+#include "pandatoolbase.h"
+
+/* 3ds Max Includes, with bonus(!) memory protection
+ */
+#ifdef MAX5
+#include "pre_max_include.h"
+#endif
+#include "Max.h"
+#include "iparamb2.h"
+#include "iparamm2.h"
+#include "istdplug.h"
+#include "iskin.h"
+#include "resource.h"
+#include "stdmat.h"
+#include "phyexp.h"
+#ifdef MAX5
+#include "post_max_include.h"
+#endif
+
+/* Panda Includes
+ */
+#include "eggCoordinateSystem.h"
+#include "eggGroup.h"
+#include "eggPolygon.h"
+#include "eggTextureCollection.h"
+#include "eggTexture.h"
+#include "eggVertex.h"
+#include "eggVertexPool.h"
+#include "pandatoolbase.h"
+#include "somethingToEgg.h"
+#include "somethingToEggConverter.h"
+#include "eggXfmSAnim.h"
+
+/* Local Includes
+ */
+#include "maxNodeTree.h"
+
+/* Error-Reporting Includes
+ */
+#include "Logger.h"
+#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);
+
+////////////////////////////////////////////////////////////////////
+//       Class : MaxToEggConverter
+// Description : This class supervises the construction of an EggData
+//               structure from a Max model
+////////////////////////////////////////////////////////////////////
+class MaxToEggConverter : public SomethingToEggConverter {
+ public:
+  MaxToEggConverter(const string &program_name = "");
+  MaxToEggConverter(const MaxToEggConverter &copy);
+  virtual ~MaxToEggConverter();
+
+  virtual SomethingToEggConverter *make_copy();
+
+  virtual string get_name() const;
+  virtual string get_extension() const;
+
+  virtual bool convert_file(const Filename &filename);
+  bool convert_max(bool from_selection);
+
+  //Sets the interface to 3dsMax.
+  void setMaxInterface(Interface *pInterface);
+
+ private:
+  double _current_frame;
+
+  bool convert_flip(double start_frame, double end_frame, 
+                    double frame_inc, double output_frame_rate);
+
+  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);
+
+  // *** Leaving out these functions til there use/support in Max is determined
+  /*
+  void make_nurbs_surface(const MDagPath &dag_path, 
+                          MFnNurbsSurface &surface,
+                          EggGroup *group);
+  EggNurbsCurve *make_trim_curve(const MFnNurbsCurve &curve,
+                                 const string &nurbs_name,
+                                 EggGroupNode *egg_group,
+                                 int trim_curve_index);
+  void make_nurbs_curve(const MDagPath &dag_path, 
+                        const MFnNurbsCurve &curve,
+                        EggGroup *group);
+  */
+  void make_polyset(INode *max_node,
+                    Mesh *mesh,
+                    EggGroup *egg_group,
+                    Shader *default_shader = NULL);
+  /*
+  void make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
+                    EggGroup *egg_group);
+  */
+
+  //Gets the vertex normal for a given face and vertex. Go figure.
+  Point3 get_max_vertex_normal(Mesh *mesh, int faceNo, int vertNo);
+  
+  void get_vertex_weights(INode *max_node, EggVertexPool *vpool);
+  /*
+  void set_shader_attributes(EggPrimitive &primitive,
+                             const MayaShader &shader);
+  */
+  void set_material_attributes(EggPrimitive &primitive, INode *max_node);
+
+  void set_material_attributes(EggPrimitive &primitive, Mtl *maxMaterial, Face *face);
+
+  void apply_texture_properties(EggTexture &tex, 
+                                StdMat *maxMaterial);
+  /*
+  bool compare_texture_properties(EggTexture &tex, 
+                                  const MayaShaderColorDef &color_def);
+  */
+
+  bool reparent_decals(EggGroupNode *egg_parent);
+
+  string _program_name;
+  bool _from_selection;
+
+  MaxNodeTree _tree;
+  
+  int _cur_tref;
+
+ public:
+  //MayaShaders _shaders;
+  EggTextureCollection _textures;
+  Interface *maxInterface;
+  
+  bool _polygon_output;
+  double _polygon_tolerance;
+
+  enum TransformType {
+    TT_invalid,
+    TT_all,
+    TT_model,
+    TT_dcs,
+    TT_none,
+  };
+  TransformType _transform_type;
+
+  static TransformType string_transform_type(const string &arg);
+
+  Modifier* FindSkinModifier (INode* node, const Class_ID &type);
+};
+
+
+#endif

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

@@ -0,0 +1,226 @@
+// Filename: maxNodeDesc.cxx
+// Created by:  crevilla
+// from mayaNodeDesc.cxx created by:  drose (06Jun03)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "maxNodeDesc.h"
+#include "Logger.h"
+#define MTEC Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM4
+
+TypeHandle MaxNodeDesc::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeDesc::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+MaxNodeDesc::
+MaxNodeDesc(MaxNodeDesc *parent, const string &name) :
+  Namable(name),
+  _parent(parent)
+{
+  _max_node = (INode *)NULL;
+  _egg_group = (EggGroup *)NULL;
+  _egg_table = (EggTable *)NULL;
+  _anim = (EggXfmSAnim *)NULL;
+  _joint_type = JT_none;
+  _joint_entry = NULL;
+
+  // Add ourselves to our parent.
+  if (_parent != (MaxNodeDesc *)NULL) {
+    _parent->_children.push_back(this);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeDesc::Destructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+MaxNodeDesc::
+~MaxNodeDesc() {}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeDesc::from_INode
+//       Access: Public
+//  Description: Indicates an associated between the MaxNodeDesc and
+//               some Max Node instance.
+////////////////////////////////////////////////////////////////////
+void MaxNodeDesc::
+from_INode(INode *max_node) {
+  if (_max_node == (INode *)NULL) {
+    _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)))) {
+      Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "Found a joint." );
+      
+      // This node is a joint.
+      _joint_type = JT_node_joint;
+      if (_parent != (MaxNodeDesc *)NULL) {
+        _parent->mark_joint_parent();
+      }
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeDesc::has_max_node
+//       Access: Public
+//  Description: Returns true if a Max INode has been associated
+//               with this node, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool MaxNodeDesc::
+has_max_node() const {
+  return (_max_node != (INode *)NULL);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeDesc::get_max_node
+//       Access: Public
+//  Description: 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 != (INode *)NULL, _max_node);
+  return _max_node;
+}
+
+
+void MaxNodeDesc::
+set_joint(bool onoff) {
+  if (onoff)
+    _joint_type = JT_joint;
+  else
+    _joint_type = JT_none;
+}
+    
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeDesc::is_joint
+//       Access: Private
+//  Description: 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;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeDesc::is_joint_parent
+//       Access: Private
+//  Description: 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;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeDesc::is_joint_parent
+//       Access: Private
+//  Description: 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;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeDesc::clear_egg
+//       Access: Private
+//  Description: Recursively clears the egg pointers from this node
+//               and all children.
+////////////////////////////////////////////////////////////////////
+void MaxNodeDesc::
+clear_egg() {
+  _egg_group = (EggGroup *)NULL;
+  _egg_table = (EggTable *)NULL;
+  _anim = (EggXfmSAnim *)NULL;
+
+  Children::const_iterator ci;
+  for (ci = _children.begin(); ci != _children.end(); ++ci) {
+    MaxNodeDesc *child = (*ci);
+    child->clear_egg();
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeDesc::mark_joint_parent
+//       Access: Private
+//  Description: 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 != (MaxNodeDesc *)NULL) {
+      _parent->mark_joint_parent();
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeDesc::check_pseudo_joints
+//       Access: Private
+//  Description: 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);
+    }
+  }
+}

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

@@ -0,0 +1,111 @@
+// Filename: maxNodeDesc.h
+// Created by: crevilla
+// from mayaNodeDesc.h created by:  drose (06Jun03)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef MAXNODEDESC_H
+#define MAXNODEDESC_H
+
+#pragma conform(forScope, off)
+
+#include "pandatoolbase.h"
+
+#include "referenceCount.h"
+#include "pointerTo.h"
+#include "namable.h"
+
+#ifdef MAX5
+#include "pre_max_include.h"
+#endif
+#include <Max.h>
+#include "bipexp.h"
+#ifdef MAX5
+#include "post_max_include.h"
+#endif
+
+class EggGroup;
+class EggTable;
+class EggXfmSAnim;
+
+////////////////////////////////////////////////////////////////////
+//       Class : MaxNodeDesc
+// Description : 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 = NULL, const string &name = string());
+  ~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

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

@@ -0,0 +1,466 @@
+// Filename: maxNodeTree.cxx
+// Created by: crevilla
+// from mayaNodeTree.cxx created by:  drose (06Jun03)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "maxNodeTree.h"
+#include "eggGroup.h"
+#include "eggTable.h"
+#include "eggXfmSAnim.h"
+#include "eggData.h"
+
+#include "pre_max_include.h"
+#include "Max.h"
+#include "post_max_include.h"
+#include "maxToEggConverter.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+MaxNodeTree::
+MaxNodeTree() {
+  _root = new MaxNodeDesc;
+  _fps = 0.0;
+  _egg_data = (EggData *)NULL;
+  _egg_root = (EggGroupNode *)NULL;
+  _skeleton_node = (EggGroupNode *)NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::build_node
+//       Access: Public
+//  Description: 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;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::build_node
+//       Access: Public
+//  Description: 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::
+r_build_hierarchy(INode *root) {
+  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));
+  }
+  return true;
+}
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::build_complete_hierarchy
+//       Access: Public
+//  Description: Walks through the complete Max hierarchy and builds
+//               up the corresponding tree.
+////////////////////////////////////////////////////////////////////
+bool MaxNodeTree::
+build_complete_hierarchy(INode *root) {
+
+  // Get the entire Max scene.
+  if (root == NULL) {
+    // *** Log an error
+    return false;
+  }
+    
+  bool all_ok = true;
+  r_build_hierarchy(root);
+
+  if (all_ok) {
+    _root->check_pseudo_joints(false);
+  }
+
+  Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, 
+	       "finished building complete hierarchy" );
+  
+  return all_ok;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::build_selected_hierarchy
+//       Access: Public
+//  Description: Walks through the selected subset of the Max
+//               hierarchy (or the complete hierarchy, if nothing is
+//               selected) and builds up the corresponding tree.
+////////////////////////////////////////////////////////////////////
+bool MaxNodeTree::
+build_selected_hierarchy(INode *root) {
+  // *** Write this later when it's time to do selection
+  /*
+  MStatus status;
+
+  MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
+  if (!status) {
+    status.perror("MItDag constructor");
+    return false;
+  }
+
+  // Get only the selected geometry.
+  MSelectionList selection;
+  status = MGlobal::getActiveSelectionList(selection);
+  if (!status) {
+    status.perror("MGlobal::getActiveSelectionList");
+    return false;
+  }
+  
+  // Get the selected geometry only if the selection is nonempty;
+  // otherwise, get the whole scene anyway.
+  if (selection.isEmpty()) {
+    mayaegg_cat.info()
+      << "Selection list is empty.\n";
+    return build_complete_hierarchy();
+  }
+  */
+  bool all_ok = true;
+  /*
+  unsigned int length = selection.length();
+  for (unsigned int i = 0; i < length; i++) {
+    MDagPath root_path;
+    status = selection.getDagPath(i, root_path);
+    if (!status) {
+      status.perror("MSelectionList::getDagPath");
+    } else {
+      // Now traverse through the selected dag path and all nested
+      // dag paths.
+      dag_iterator.reset(root_path);
+      while (!dag_iterator.isDone()) {
+        MDagPath dag_path;
+        status = dag_iterator.getPath(dag_path);
+        if (!status) {
+          status.perror("MItDag::getPath");
+        } else {
+          build_node(dag_path);
+        }
+        
+        dag_iterator.next();
+      }
+    }
+  }
+
+  if (all_ok) {
+    _root->check_pseudo_joints(false);
+  }
+  */
+  return all_ok;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::get_num_nodes
+//       Access: Public
+//  Description: Returns the total number of nodes in the hierarchy,
+//               not counting the root node.
+////////////////////////////////////////////////////////////////////
+int MaxNodeTree::
+get_num_nodes() const {
+  return _nodes.size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::get_node
+//       Access: Public
+//  Description: 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(), NULL);
+  return _nodes[n];
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::clear_egg
+//       Access: Public
+//  Description: 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;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::get_egg_group
+//       Access: Public
+//  Description: 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 != (EggGroupNode *)NULL, NULL);
+
+  if (node_desc->_egg_group == (EggGroup *)NULL) {
+    // We need to make a new group node.
+    EggGroup *egg_group;
+
+    nassertr(node_desc->_parent != (MaxNodeDesc *)NULL, NULL);
+    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.
+      _egg_root->add_child(egg_group);
+
+    } else {
+      // The parent is another node.
+      EggGroup *parent_egg_group = get_egg_group(node_desc->_parent);
+      parent_egg_group->add_child(egg_group);
+    }
+
+    // *** This is probably something that a Max plugin would need to be 
+    //     written for.  May want to ask Disney about it
+    /*
+    if (node_desc->has_dag_path()) {
+      // Check for an object type setting, from Oliver's plug-in.
+      MObject dag_object = node_desc->get_dag_path().node();
+      string object_type;
+      if (get_enum_attribute(dag_object, "eggObjectTypes1", object_type)) {
+        egg_group->add_object_type(object_type);
+      }
+      if (get_enum_attribute(dag_object, "eggObjectTypes2", object_type)) {
+        egg_group->add_object_type(object_type);
+      }
+      if (get_enum_attribute(dag_object, "eggObjectTypes3", object_type)) {
+        egg_group->add_object_type(object_type);
+      }
+
+      // We treat the object type "billboard" as a special case: we
+      // apply this one right away and also flag the group as an
+      // instance.
+      if (egg_group->has_object_type("billboard")) {    
+        egg_group->remove_object_type("billboard");
+        egg_group->set_group_type(EggGroup::GT_instance);
+        egg_group->set_billboard_type(EggGroup::BT_axis);
+        
+      } else if (egg_group->has_object_type("billboard-point")) {    
+        egg_group->remove_object_type("billboard-point");
+        egg_group->set_group_type(EggGroup::GT_instance);
+        egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
+      }
+      
+      // We also treat the object type "dcs" and "model" as a special
+      // case, so we can test for these flags later.
+      if (egg_group->has_object_type("dcs")) {
+        egg_group->remove_object_type("dcs");
+        egg_group->set_dcs_type(EggGroup::DC_default);
+      }
+      if (egg_group->has_object_type("model")) {
+        egg_group->remove_object_type("model");
+        egg_group->set_model_flag(true);
+      }
+      
+      // And "vertex-color" has meaning only to this converter.
+      if (egg_group->has_object_type("vertex-color")) {
+        egg_group->remove_object_type("vertex-color");
+        MaxEggGroupUserData *user_data = new MaxEggGroupUserData;
+        user_data->_vertex_color = true;
+        egg_group->set_user_data(user_data);
+      }
+    }
+    */
+    node_desc->_egg_group = egg_group;
+  }
+
+  return node_desc->_egg_group;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::get_egg_table
+//       Access: Public
+//  Description: 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 != (EggGroupNode *)NULL, NULL);
+  nassertr(node_desc->is_joint(), NULL);
+
+  if (node_desc->_egg_table == (EggTable *)NULL) {
+    // We need to make a new table node.
+    nassertr(node_desc->_parent != (MaxNodeDesc *)NULL, NULL);
+
+    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;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::get_egg_anim
+//       Access: Public
+//  Description: 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;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::r_build_node
+//       Access: Private
+//  Description: 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; 
+    string local_name = max_node->GetName();
+    if (max_node->IsRootNode()) {
+      parent_node = NULL;
+    } else {
+      parent_node = max_node->GetParentNode();
+    }
+
+    MaxNodeDesc *parent_node_desc = r_build_node(parent_node);
+    node_desc = new MaxNodeDesc(parent_node_desc, local_name);
+    _nodes.push_back(node_desc);
+  }
+
+  _nodes_by_path.insert(NodesByPath::value_type(node_handle, node_desc));
+  return node_desc;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::r_build_joint
+//       Access: Private
+//  Description: 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->GetName());
+    _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->GetName());
+    _nodes.push_back(node_joint);
+	return node_joint;
+  } else {
+	return r_build_joint(node_desc->_parent, max_node);	  
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::find_node
+//       Access: Private
+//  Description: 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 NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxNodeTree::find_joint
+//       Access: Private
+//  Description: The recursive implementation of build_node().
+////////////////////////////////////////////////////////////////////
+MaxNodeDesc *MaxNodeTree::
+find_joint(INode* max_node) 
+{
+  return find_node(max_node)->_joint_entry;
+}

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

@@ -0,0 +1,73 @@
+// Filename: maxNodeTree.h
+// Created by: crevilla
+// from mayaNodeTree.h created by:  drose (06Jun03)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef MAXNODETREE_H
+#define MAXNODETREE_H
+
+#include "pandatoolbase.h"
+
+#include "maxNodeDesc.h"
+
+class EggData;
+class EggGroupNode;
+
+////////////////////////////////////////////////////////////////////
+//       Class : MaxNodeTree
+// Description : 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);
+  bool build_selected_hierarchy(INode *root);
+  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;
+  float _fps;
+
+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 r_build_hierarchy(INode *root);
+
+  typedef pmap<ULONG, MaxNodeDesc *> NodesByPath;
+  NodesByPath _nodes_by_path;
+
+  typedef pvector<MaxNodeDesc *> Nodes;
+  Nodes _nodes;
+};
+
+#endif

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

@@ -0,0 +1,2418 @@
+// Filename: maxToEggConverter.cxx
+// Created by Corey Revilla and Ken Strickland (6/22/03)
+// from mayaToEggConverter.cxx created by drose (10Nov99)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "maxToEggConverter.h"
+#include "modstack.h"
+#include "eggtable.h"
+
+#define MNEG Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM2
+#define MNEG_GEOMETRY_GENERATION Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM3
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+MaxToEggConverter::
+MaxToEggConverter(const string &program_name) :
+  _program_name(program_name)
+{
+  _from_selection = false;
+  _polygon_output = false;
+  _polygon_tolerance = 0.01;
+  _transform_type = TT_model;
+  _cur_tref = 0;
+  _current_frame = 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+MaxToEggConverter::
+MaxToEggConverter(const MaxToEggConverter &copy) :
+  maxInterface(copy.maxInterface)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::Destructor
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+MaxToEggConverter::
+~MaxToEggConverter() 
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::make_copy
+//       Access: Public, Virtual
+//  Description: Allocates and returns a new copy of the converter.
+////////////////////////////////////////////////////////////////////
+SomethingToEggConverter *MaxToEggConverter::
+make_copy() 
+{
+  return new MaxToEggConverter(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::get_name
+//       Access: Public, Virtual
+//  Description: Returns the English name of the file type this
+//               converter supports.
+////////////////////////////////////////////////////////////////////
+string MaxToEggConverter::
+get_name() const 
+{
+  return "Max";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::get_extension
+//       Access: Public, Virtual
+//  Description: Returns the common extension of the file type this
+//               converter supports.
+////////////////////////////////////////////////////////////////////
+string MaxToEggConverter::
+get_extension() const 
+{
+  return "max";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::convert_file
+//       Access: Public, Virtual
+//  Description: Handles the reading of the input file and converting
+//               it to egg.  Returns true if successful, false
+//               otherwise.
+//
+//               This is designed to be as generic as possible,
+//               generally in support of run-time loading.
+//               Also see convert_max().
+////////////////////////////////////////////////////////////////////
+bool MaxToEggConverter::
+convert_file(const Filename &filename) 
+{
+
+  //If there is no Max interface to speak of, we log an error and exit.
+  if ( !maxInterface ) {
+    Logger::Log( MTEC, Logger::SAT_NULL_ERROR, "pMaxInterface is null!" );
+    //    Logger::FunctionExit();
+    return false;
+  }
+  
+  if (_character_name.empty()) {
+    _character_name = Filename(maxInterface->GetCurFileName()).get_basename_wo_extension();
+  }
+
+  return convert_max(false);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::convert_max
+//       Access: Public
+//  Description: 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_max(bool from_selection) {
+
+  _from_selection = from_selection;
+  _textures.clear();
+  // *** I don't know if we're going to handle shaders in Max
+  //_shaders.clear();
+
+  if ( !maxInterface ) {
+    Logger::Log( MTEC, Logger::SAT_NULL_ERROR, "pMaxInterface is null!" );
+    //    Logger::FunctionExit();
+    return false;
+  }
+  // *** Should probably figure out how to use the progress bar effectively 
+  //     and also figure out why it is having linkage errors
+  //maxInterface->ProgressStart( "Exporting", TRUE, ProgressBarFunction, NULL );
+
+  // *** May want to make this something that is calculated as apposed to 
+  //     set explicitly, but it's not a priority
+  if (_egg_data->get_coordinate_system() == CS_default) {
+    _egg_data->set_coordinate_system(CS_zup_right);
+  }
+
+  // Figure out the animation parameters.
+  double start_frame, end_frame, frame_inc, input_frame_rate, output_frame_rate;
+
+  // Get the start and end frames and the animation frame rate from Max
+  Interval anim_range = maxInterface->GetAnimRange();
+  start_frame = anim_range.Start()/GetTicksPerFrame();
+  end_frame = anim_range.End()/GetTicksPerFrame();
+  frame_inc = 1;
+  input_frame_rate = GetFrameRate();
+
+  if (has_start_frame() && get_start_frame() > start_frame) {
+    start_frame = get_start_frame();
+  } 
+
+  if (has_end_frame() && get_end_frame() < end_frame) {
+    end_frame = get_end_frame();
+  } 
+
+  if (has_frame_inc()) {
+    frame_inc = get_frame_inc();
+  } 
+
+  if (has_input_frame_rate()) {
+    input_frame_rate = get_input_frame_rate();
+  } 
+
+  if (has_output_frame_rate()) {
+    output_frame_rate = get_output_frame_rate();
+  } else {
+    output_frame_rate = input_frame_rate;
+  }
+
+  bool all_ok = true;
+
+  if (_from_selection) {
+    all_ok = _tree.build_selected_hierarchy(maxInterface->GetRootNode());
+  } else {
+    all_ok = _tree.build_complete_hierarchy(maxInterface->GetRootNode());
+  }
+
+  if (all_ok) {
+    switch (get_animation_convert()) {
+    case AC_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() );
+	  _current_frame = start_frame;
+      // fall through
+      
+    case AC_none:
+      // none: just get out a static model, no animation.
+      Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "Converting static model." );
+      all_ok = convert_hierarchy(&get_egg_data());
+      break;
+      
+    case AC_flip:
+    case AC_strobe:
+      // flip or strobe: get out a series of static models, one per
+      // frame, under a sequence node for AC_flip.
+      all_ok = convert_flip(start_frame, end_frame, frame_inc,
+                            output_frame_rate);
+      break;
+
+    case AC_model:
+      // model: get out an animatable model with joints and vertex
+      // membership.
+      all_ok = convert_char_model();
+      break;
+
+    case AC_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 AC_both:
+      // both: Put a model and its animation into the same egg file.
+      _animation_convert = AC_model;
+      if (!convert_char_model()) {
+        all_ok = false;
+      }
+      _animation_convert = AC_chan;
+      if (!convert_char_chan(start_frame, end_frame, frame_inc,
+                             output_frame_rate)) {
+        all_ok = false;
+      }
+      break;
+    };
+
+    reparent_decals(&get_egg_data());
+  }
+
+  if (all_ok) {
+    Logger::Log(MTEC, Logger::SAT_MEDIUM_LEVEL, "Converted, no errors." );
+  } else {
+    Logger::Log(MTEC, Logger::SAT_MEDIUM_LEVEL,
+		"Errors encountered in conversion." );
+  }
+
+  maxInterface->ProgressEnd();
+
+  //  Logger::FunctionExit();
+  return all_ok;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::setMaxInterface
+//       Access: Public
+//  Description: Sets the interface to 3D Studio Max through
+//               which the scene graph is read.
+////////////////////////////////////////////////////////////////////
+/* setMaxInterface(Interface *) - Sets the interface to 3D Studio Max through 
+ * which the scene graph is read.
+ */
+void MaxToEggConverter::setMaxInterface(Interface *pInterface) 
+{
+  maxInterface = pInterface;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::convert_flip
+//       Access: Private
+//  Description: Converts the animation as a series of models that
+//               cycle (flip) from one to the next at the appropriate
+//               frame rate.  This is the most likely to convert
+//               precisely (since we ask Maya to tell us the vertex
+//               position each time) but it is the most wasteful in
+//               terms of memory utilization (since a complete of the
+//               model is stored for each frame).
+////////////////////////////////////////////////////////////////////
+bool MaxToEggConverter::
+convert_flip(double start_frame, double end_frame, double frame_inc,
+             double output_frame_rate) {
+  bool all_ok = true;
+
+  EggGroup *sequence_node = new EggGroup(_character_name);
+  get_egg_data().add_child(sequence_node);
+  if (_animation_convert == AC_flip) { 
+    sequence_node->set_switch_flag(true);
+    sequence_node->set_switch_fps(output_frame_rate / frame_inc);
+  }
+
+  double frame = start_frame;
+  double frame_stop = end_frame;
+  while (frame <= frame_stop) {
+    sprintf(Logger::GetLogString(), "Extracting geometry from frame #%lf.",
+	    frame); 
+    Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, Logger::GetLogString() );
+    ostringstream name_strm;
+    name_strm << "frame" << frame;
+    EggGroup *frame_root = new EggGroup(name_strm.str());
+    sequence_node->add_child(frame_root);
+
+    // Set the frame and then export that frame
+    _current_frame = frame;
+    if (!convert_hierarchy(frame_root)) {
+      all_ok = false;
+    }
+
+    frame += frame_inc;
+  }
+
+  return all_ok;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::convert_char_model
+//       Access: Private
+//  Description: Converts the file as an animatable character
+//               model, with joints and vertex membership.
+////////////////////////////////////////////////////////////////////
+bool MaxToEggConverter::
+convert_char_model() {
+  if (has_neutral_frame()) {
+    _current_frame = get_neutral_frame();
+  }
+
+  EggGroup *char_node = new EggGroup(_character_name);
+  get_egg_data().add_child(char_node);
+  char_node->set_dart_type(EggGroup::DT_default);
+
+  return convert_hierarchy(char_node);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::convert_char_chan
+//       Access: Private
+//  Description: 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) {
+
+  EggTable *root_table_node = new EggTable();
+  get_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(&get_egg_data(), NULL, 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;
+
+  sprintf(Logger::GetLogString(), 
+	  "sf %lf ef %lf inc %lf ofr %lf.", 
+	  start_frame, end_frame, frame_inc, output_frame_rate );
+  Logger::Log(MNEG_GEOMETRY_GENERATION, Logger::SAT_LOW_LEVEL, 
+	      Logger::GetLogString() );
+
+  TimeValue frame = start_frame;
+  TimeValue frame_stop = end_frame;
+  while (frame <= frame_stop) {
+    _current_frame = frame;
+    sprintf(Logger::GetLogString(), 
+	    "Current frame: %lf.", 
+	    _current_frame );
+    Logger::Log(MNEG_GEOMETRY_GENERATION, Logger::SAT_LOW_LEVEL, 
+		Logger::GetLogString() );
+
+    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, NULL, tgroup);
+	}
+        EggXfmSAnim *anim = _tree.get_egg_anim(node_desc);
+        if (!anim->add_data(tgroup->get_transform())) {
+	  // *** 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;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::convert_hierarchy
+//       Access: Private
+//  Description: 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(&get_egg_data(), egg_root, NULL);
+  for (int i = 0; i < num_nodes; i++) {
+    if (!process_model_node(_tree.get_node(i))) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::process_model_node
+//       Access: Private
+//  Description: 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()) {
+    // Don't bother with joints unless we're getting an animatable
+    // model.
+    if (_animation_convert == AC_model) { 
+      EggGroup *egg_group = _tree.get_egg_group(node_desc);
+      get_joint_transform(max_node, egg_group);
+    }
+  } else {
+    if (state.obj) {
+      EggGroup *egg_group;
+      TriObject *myMaxTriObject;
+      Mesh max_mesh;
+      //Call the correct exporter based on what type of object this is.
+      switch( state.obj->SuperClassID() ){
+	//A geometric object.
+        case GEOMOBJECT_CLASS_ID:
+	  Logger::Log( MTEC, Logger::SAT_HIGH_LEVEL, 
+		       "Found a geometric object in the hierarchy!" );
+	  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))) {
+	    Logger::Log(MTEC, Logger::SAT_OTHER_ERROR, 
+			"Cannot create geometry from state.obj!");
+	    // Logger::FunctionExit();
+	    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();
+	  Logger::Log( MTEC, Logger::SAT_LOW_LEVEL, 
+		       "TriObject attached and mesh generated!" );
+	  
+	  make_polyset(max_node, &max_mesh, egg_group);
+	  
+	  if (myMaxTriObject != state.obj)
+	    delete myMaxTriObject;
+	  break;
+	  
+        case CAMERA_CLASS_ID:
+	  Logger::Log( MTEC, Logger::SAT_HIGH_LEVEL, 
+		       "Found a camera object in the hierarchy!" );
+	  break;
+
+        case LIGHT_CLASS_ID:
+	  Logger::Log( MTEC, Logger::SAT_HIGH_LEVEL, 
+		       "Found a light object in the hierarchy!" );
+	  break;
+
+        case HELPER_CLASS_ID:
+	  Logger::Log( MTEC, Logger::SAT_HIGH_LEVEL, 
+		       "Found a helper object in the hierarchy!" );
+	  break;
+      }
+    }
+  }
+
+  // *** Check if any of these Maya options have a Max equivalent
+  /*
+  } else if (dag_node.inUnderWorld()) {
+    if (mayaegg_cat.is_debug()) {
+      mayaegg_cat.debug()
+        << "Ignoring underworld node " << path
+        << "\n";
+    }
+
+  } else if (dag_node.isIntermediateObject()) {
+    if (mayaegg_cat.is_debug()) {
+      mayaegg_cat.debug()
+        << "Ignoring intermediate object " << path
+        << "\n";
+    }
+
+  } else if (dag_path.hasFn(MFn::kNurbsSurface)) {
+    EggGroup *egg_group = _tree.get_egg_group(node_desc);
+    get_transform(dag_path, egg_group);
+    
+    MFnNurbsSurface surface(dag_path, &status);
+    if (!status) {
+      mayaegg_cat.info()
+        << "Error in node " << path
+        << ":\n"
+        << "  it appears to have a NURBS surface, but does not.\n";
+    } else {
+      make_nurbs_surface(dag_path, surface, egg_group);
+    }
+
+  } else if (dag_path.hasFn(MFn::kNurbsCurve)) {
+    // Only convert NurbsCurves if we aren't making an animated model.
+    // Animated models, as a general rule, don't want these sorts of
+    // things in them.
+    if (_animation_convert != AC_model) {
+      EggGroup *egg_group = _tree.get_egg_group(node_desc);
+      get_transform(dag_path, egg_group);
+      
+      MFnNurbsCurve curve(dag_path, &status);
+      if (!status) {
+        mayaegg_cat.info()
+          << "Error in node " << path << ":\n"
+          << "  it appears to have a NURBS curve, but does not.\n";
+      } else {
+        make_nurbs_curve(dag_path, curve, egg_group);
+      }
+    }
+      
+  } else if (dag_path.hasFn(MFn::kMesh)) {
+    EggGroup *egg_group = _tree.get_egg_group(node_desc);
+    get_transform(dag_path, egg_group);
+
+    MFnMesh mesh(dag_path, &status);
+    if (!status) {
+      mayaegg_cat.info()
+        << "Error in node " << path << ":\n"
+        << "  it appears to have a polygon mesh, but does not.\n";
+    } else {
+      make_polyset(dag_path, mesh, egg_group);
+    }
+
+  } else if (dag_path.hasFn(MFn::kLocator)) {
+    EggGroup *egg_group = _tree.get_egg_group(node_desc);
+
+    if (mayaegg_cat.is_debug()) {
+      mayaegg_cat.debug()
+        << "Locator at " << path << "\n";
+    }
+    
+    // Presumably, the locator's position has some meaning to the
+    // end-user, so we will implicitly tag it with the DCS flag so it
+    // won't get flattened out.
+    if (_animation_convert != AC_model) {
+      // For now, don't set the DCS flag on locators within
+      // character models, since egg-optchar doesn't understand
+      // this.  Perhaps there's no reason to ever change this, since
+      // locators within character models may not be meaningful.
+      egg_group->set_dcs_type(EggGroup::DC_net);
+    }
+    get_transform(dag_path, egg_group);
+    make_locator(dag_path, dag_node, egg_group);
+
+  } else {
+    // Just a generic node.
+    EggGroup *egg_group = _tree.get_egg_group(node_desc);
+    get_transform(dag_path, egg_group);
+  }
+  */
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::get_transform
+//       Access: Private
+//  Description: 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 (_animation_convert == AC_model) {
+    // When we're getting an animated model, we only get transforms
+    // for joints.
+    return;
+  }
+
+  // The 3dsMax-style matrix that contains the pivot matrix...this pivot matrix
+  // encapsulates all the scales, rotates, and transforms it takes
+  // to "get to" the pivot point.
+  Matrix3 pivot;
+  //This is the Panda-flava-flav-style matrix we'll be exporting to.
+  Point3 row0;
+  Point3 row1;
+  Point3 row2;
+  Point3 row3;
+
+  Logger::FunctionEntry("MaxNodeEggGroup::ApplyTransformFromMaxNodeToEggGroup");
+  if ( !egg_group ) {
+    Logger::Log( MNEG_GEOMETRY_GENERATION, Logger::SAT_NULL_ERROR, 
+		 "Destination EggGroup is null!" );
+    Logger::FunctionExit();
+    return;
+  }
+
+  // *** A special case that I don't think we're supporting in Max
+  /*
+  // A special case: if the group is a billboard, we center the
+  // transform on the rotate pivot and ignore whatever transform might
+  // be there.
+  if (egg_group->get_billboard_type() != EggGroup::BT_none) {
+    MFnTransform transform(transformNode, &status);
+    if (!status) {
+      status.perror("MFnTransform constructor");
+      return;
+    }
+
+    MPoint pivot = transform.rotatePivot(MSpace::kObject, &status);
+    if (!status) {
+      status.perror("Can't get rotate pivot");
+      return;
+    }
+
+    // We need to convert the pivot to world coordinates.
+    // Unfortunately, Maya can only tell it to us in local
+    // coordinates.
+    MMatrix mat = dag_path.inclusiveMatrix(&status);
+    if (!status) {
+      status.perror("Can't get coordinate space for pivot");
+      return;
+    }
+    LMatrix4d n2w(mat[0][0], mat[0][1], mat[0][2], mat[0][3],
+                  mat[1][0], mat[1][1], mat[1][2], mat[1][3],
+                  mat[2][0], mat[2][1], mat[2][2], mat[2][3],
+                  mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
+    LPoint3d p3d(pivot[0], pivot[1], pivot[2]);
+    p3d = p3d * n2w;
+
+    if (egg_group->get_parent() != (EggGroupNode *)NULL) {
+      // Now convert the pivot point into the group's parent's space.
+      p3d = p3d * egg_group->get_parent()->get_vertex_frame_inv();
+    }
+
+    egg_group->clear_transform();
+    egg_group->add_translate(p3d);
+    return;
+  }
+  */
+
+  // *** Make sure this is happening correctly; I'm not sure at the moment
+  //     how these flags get specified
+/*
+  switch (_transform_type) {
+  case TT_all:
+    break;
+    
+  case TT_model:
+    if (!egg_group->get_model_flag() &&
+        egg_group->get_dcs_type() == EggGroup::DC_none) {
+      return;
+    }
+    break;
+    
+  case TT_dcs: 
+    if (egg_group->get_dcs_type() == EggGroup::DC_none) {
+      return;
+    }
+    break;
+    
+  case TT_none:
+  case TT_invalid:
+    return;
+  }
+*/
+
+  // Gets the TM for this node, a matrix which encapsulates all transformations
+  // it takes to get to the current node, including parent transformations.
+  pivot = max_node->GetNodeTM(_current_frame * GetTicksPerFrame());
+  row0 = pivot.GetRow(0);
+  row1 = pivot.GetRow(1);
+  row2 = pivot.GetRow(2);
+  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_matrix(m4d);
+    Logger::Log( MNEG_GEOMETRY_GENERATION, Logger::SAT_DEBUG_SPAM_LEVEL, 
+		 "Non-identity matrix applied to node!" );
+  } else {
+    Logger::Log( MNEG_GEOMETRY_GENERATION, Logger::SAT_DEBUG_SPAM_LEVEL, 
+		 "Resultant matrix too close to identity; no transformation applied!" );
+  }
+  Logger::FunctionExit();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::get_object_transform
+//       Access: Private
+//  Description: Extracts the transform on the indicated Maya node,
+//               and applies it to the corresponding Egg node.
+////////////////////////////////////////////////////////////////////
+LMatrix4d MaxToEggConverter::
+get_object_transform(INode *max_node) {
+
+  // The 3dsMax-style matrix that contains the pivot matrix...this pivot matrix
+  // encapsulates all the scales, rotates, and transforms it takes
+  // to "get to" the pivot point.
+  Matrix3 pivot;
+  //This is the Panda-flava-flav-style matrix we'll be exporting to.
+  Point3 row0;
+  Point3 row1;
+  Point3 row2;
+  Point3 row3;
+
+  Logger::FunctionEntry("MaxNodeEggGroup::ApplyTransformFromMaxNodeToEggGroup");
+
+  // Gets the TM for this node, a matrix which encapsulates all transformations
+  // it takes to get to the current node, including parent transformations.
+  pivot = max_node->GetObjectTM(_current_frame * GetTicksPerFrame());
+  row0 = pivot.GetRow(0);
+  row1 = pivot.GetRow(1);
+  row2 = pivot.GetRow(2);
+  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 );
+  Logger::FunctionExit();
+  return m4d;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::get_joint_transform
+//       Access: Private
+//  Description: 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) {
+
+  // The 3dsMax-style matrix that contains the pivot matrix...this pivot matrix
+  // encapsulates all the scales, rotates, and transforms it takes
+  // to "get to" the pivot point.
+  Matrix3 pivot;
+  //This is the Panda-flava-flav-style matrix we'll be exporting to.
+  Point3 row0;
+  Point3 row1;
+  Point3 row2;
+  Point3 row3;
+
+  Logger::FunctionEntry("MaxNodeEggGroup::ApplyTransformFromMaxNodeToEggGroup");
+  if ( !egg_group ) {
+    Logger::Log( MNEG_GEOMETRY_GENERATION, Logger::SAT_NULL_ERROR, 
+		 "Destination EggGroup is null!" );
+    Logger::FunctionExit();
+    return;
+  }
+
+  // Gets the TM for this node, a matrix which encapsulates all transformations
+  // it takes to get to the current node, including parent transformations.
+  pivot = max_node->GetNodeTM(_current_frame * GetTicksPerFrame());
+  row0 = pivot.GetRow(0);
+  row1 = pivot.GetRow(1);
+  row2 = pivot.GetRow(2);
+  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_matrix(m4d);
+    Logger::Log( MNEG_GEOMETRY_GENERATION, Logger::SAT_DEBUG_SPAM_LEVEL, 
+		 "Non-identity matrix applied to node!" );
+  } else {
+    Logger::Log( MNEG_GEOMETRY_GENERATION, Logger::SAT_DEBUG_SPAM_LEVEL, 
+		 "Resultant matrix too close to identity; no transformation applied!" );
+  }
+  Logger::FunctionExit();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::get_joint_transform
+//       Access: Private
+//  Description: 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) {
+
+  // The 3dsMax-style matrix that contains the pivot matrix...this pivot matrix
+  // encapsulates all the scales, rotates, and transforms it takes
+  // to "get to" the pivot point.
+  Matrix3 pivot;
+  Matrix3 parent_pivot;
+  //This is the Panda-flava-flav-style matrix we'll be exporting to.
+  Point3 row0;
+  Point3 row1;
+  Point3 row2;
+  Point3 row3;
+
+  Logger::FunctionEntry("MaxNodeEggGroup::ApplyTransformFromMaxNodeToEggGroup");
+  if ( !egg_group ) {
+    Logger::Log( MNEG_GEOMETRY_GENERATION, Logger::SAT_NULL_ERROR, 
+		 "Destination EggGroup is null!" );
+    Logger::FunctionExit();
+    return;
+  }
+
+  // Gets the TM for this node, a matrix which encapsulates all transformations
+  // it takes to get to the current node, including parent transformations.
+  pivot = max_node->GetNodeTM(_current_frame * GetTicksPerFrame());
+  row0 = pivot.GetRow(0);
+  row1 = pivot.GetRow(1);
+  row2 = pivot.GetRow(2);
+  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) {
+  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_matrix(m4d);
+    Logger::Log( MNEG_GEOMETRY_GENERATION, Logger::SAT_DEBUG_SPAM_LEVEL, 
+		 "Non-identity matrix applied to node!" );
+  } else {
+    Logger::Log( MNEG_GEOMETRY_GENERATION, Logger::SAT_DEBUG_SPAM_LEVEL, 
+		 "Resultant matrix too close to identity; no transformation applied!" );
+  }
+  Logger::FunctionExit();
+}
+
+// *** I am skipping all NURBS stuff until I figure if Max can/needs to support
+//     it 
+/*
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::make_nurbs_surface
+//       Access: Private
+//  Description: Converts the indicated Maya NURBS surface to a
+//               corresponding egg structure, and attaches it to the
+//               indicated egg group.
+////////////////////////////////////////////////////////////////////
+void MaxToEggConverter::
+make_nurbs_surface(const MDagPath &dag_path, MFnNurbsSurface &surface,
+                   EggGroup *egg_group) {
+  MStatus status;
+  string name = surface.name().asChar();
+
+  if (mayaegg_cat.is_spam()) {
+    mayaegg_cat.spam()
+      << "  numCVs: "
+      << surface.numCVsInU()
+      << " * "
+      << surface.numCVsInV()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numKnots: "
+      << surface.numKnotsInU()
+      << " * "
+      << surface.numKnotsInV()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numSpans: "
+      << surface.numSpansInU()
+      << " * "
+      << surface.numSpansInV()
+      << "\n";
+  }
+
+  MayaShader *shader = _shaders.find_shader_for_node(surface.object());
+
+  if (_polygon_output) {
+    // If we want polygon output only, tesselate the NURBS and output
+    // that.
+    MTesselationParams params;
+    params.setFormatType(MTesselationParams::kStandardFitFormat);
+    params.setOutputType(MTesselationParams::kQuads);
+    params.setStdFractionalTolerance(_polygon_tolerance);
+
+    // We'll create the tesselation as a sibling of the NURBS surface.
+    // That way we inherit all of the transformations.
+    MDagPath polyset_path = dag_path;
+    MObject polyset_parent = polyset_path.node();
+    MObject polyset =
+      surface.tesselate(params, polyset_parent, &status);
+    if (!status) {
+      status.perror("MFnNurbsSurface::tesselate");
+      return;
+    }
+
+    status = polyset_path.push(polyset);
+    if (!status) {
+      status.perror("MDagPath::push");
+    }
+
+    MFnMesh polyset_fn(polyset, &status);
+    if (!status) {
+      status.perror("MFnMesh constructor");
+      return;
+    }
+    make_polyset(polyset_path, polyset_fn, egg_group, shader);
+
+    // Now remove the polyset we created.
+    MFnDagNode parent_node(polyset_parent, &status);
+    if (!status) {
+      status.perror("MFnDagNode constructor");
+      return;
+    }
+    status = parent_node.removeChild(polyset);
+    if (!status) {
+      status.perror("MFnDagNode::removeChild");
+    }
+
+    return;
+  }
+
+  MPointArray cv_array;
+  status = surface.getCVs(cv_array, MSpace::kWorld);
+  if (!status) {
+    status.perror("MFnNurbsSurface::getCVs");
+    return;
+  }
+  MDoubleArray u_knot_array, v_knot_array;
+  status = surface.getKnotsInU(u_knot_array);
+  if (!status) {
+    status.perror("MFnNurbsSurface::getKnotsInU");
+    return;
+  }
+  status = surface.getKnotsInV(v_knot_array);
+  if (!status) {
+    status.perror("MFnNurbsSurface::getKnotsInV");
+    return;
+  }
+
+  
+  //  We don't use these variables currently.
+  //MFnNurbsSurface::Form u_form = surface.formInU();
+  //MFnNurbsSurface::Form v_form = surface.formInV();
+ 
+
+  int u_degree = surface.degreeU();
+  int v_degree = surface.degreeV();
+
+  int u_cvs = surface.numCVsInU();
+  int v_cvs = surface.numCVsInV();
+
+  int u_knots = surface.numKnotsInU();
+  int v_knots = surface.numKnotsInV();
+
+  assert(u_knots == u_cvs + u_degree - 1);
+  assert(v_knots == v_cvs + v_degree - 1);
+
+  string vpool_name = name + ".cvs";
+  EggVertexPool *vpool = new EggVertexPool(vpool_name);
+  egg_group->add_child(vpool);
+
+  EggNurbsSurface *egg_nurbs = new EggNurbsSurface(name);
+  egg_nurbs->setup(u_degree + 1, v_degree + 1,
+                   u_knots + 2, v_knots + 2);
+
+  int i;
+
+  egg_nurbs->set_u_knot(0, u_knot_array[0]);
+  for (i = 0; i < u_knots; i++) {
+    egg_nurbs->set_u_knot(i + 1, u_knot_array[i]);
+  }
+  egg_nurbs->set_u_knot(u_knots + 1, u_knot_array[u_knots - 1]);
+
+  egg_nurbs->set_v_knot(0, v_knot_array[0]);
+  for (i = 0; i < v_knots; i++) {
+    egg_nurbs->set_v_knot(i + 1, v_knot_array[i]);
+  }
+  egg_nurbs->set_v_knot(v_knots + 1, v_knot_array[v_knots - 1]);
+
+  LMatrix4d vertex_frame_inv = egg_group->get_vertex_frame_inv();
+
+  for (i = 0; i < egg_nurbs->get_num_cvs(); i++) {
+    int ui = egg_nurbs->get_u_index(i);
+    int vi = egg_nurbs->get_v_index(i);
+
+    double v[4];
+    MStatus status = cv_array[v_cvs * ui + vi].get(v);
+    if (!status) {
+      status.perror("MPoint::get");
+    } else {
+      EggVertex vert;
+      LPoint4d p4d(v[0], v[1], v[2], v[3]);
+      p4d = p4d * vertex_frame_inv;
+      vert.set_pos(p4d);
+      egg_nurbs->add_vertex(vpool->create_unique_vertex(vert));
+    }
+  }
+
+  // Now consider the trim curves, if any.
+  unsigned num_trims = surface.numRegions();
+  int trim_curve_index = 0;
+  for (unsigned ti = 0; ti < num_trims; ti++) {
+    unsigned num_loops = surface.numBoundaries(ti);
+
+    if (num_loops > 0) {
+      egg_nurbs->_trims.push_back(EggNurbsSurface::Trim());
+      EggNurbsSurface::Trim &egg_trim = egg_nurbs->_trims.back();
+
+      for (unsigned li = 0; li < num_loops; li++) {
+        egg_trim.push_back(EggNurbsSurface::Loop());
+        EggNurbsSurface::Loop &egg_loop = egg_trim.back();
+        
+        MFnNurbsSurface::BoundaryType type =
+          surface.boundaryType(ti, li, &status);
+        bool keep_loop = false;
+        
+        if (!status) {
+          status.perror("MFnNurbsSurface::BoundaryType");
+        } else {
+          keep_loop = (type == MFnNurbsSurface::kInner ||
+                       type == MFnNurbsSurface::kOuter);
+        }
+        
+        if (keep_loop) {
+          unsigned num_edges = surface.numEdges(ti, li);
+          for (unsigned ei = 0; ei < num_edges; ei++) {
+            MObjectArray edge = surface.edge(ti, li, ei, true, &status);
+            if (!status) {
+              status.perror("MFnNurbsSurface::edge");
+            } else {
+              unsigned num_segs = edge.length();
+              for (unsigned si = 0; si < num_segs; si++) {
+                MObject segment = edge[si];
+                if (segment.hasFn(MFn::kNurbsCurve)) {
+                  MFnNurbsCurve curve(segment, &status);
+                  if (!status) {
+                    mayaegg_cat.error()
+                      << "Trim curve appears to be a nurbs curve, but isn't.\n";
+                  } else {
+                    // Finally, we have a valid curve!
+                    EggNurbsCurve *egg_curve =
+                      make_trim_curve(curve, name, egg_group, trim_curve_index);
+                    trim_curve_index++;
+                    if (egg_curve != (EggNurbsCurve *)NULL) {
+                      egg_loop.push_back(egg_curve);
+                    }
+                  }
+                } else {
+                  mayaegg_cat.error()
+                    << "Trim curve segment is not a nurbs curve.\n";
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // We add the NURBS to the group down here, after all of the vpools
+  // for the trim curves have been added.
+  egg_group->add_child(egg_nurbs);
+
+  if (shader != (MayaShader *)NULL) {
+    set_shader_attributes(*egg_nurbs, *shader);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::make_trim_curve
+//       Access: Private
+//  Description: Converts the indicated Maya NURBS trim curve to a
+//               corresponding egg structure, and returns it, or NULL
+//               if there is a problem.
+////////////////////////////////////////////////////////////////////
+EggNurbsCurve *MaxToEggConverter::
+make_trim_curve(const MFnNurbsCurve &curve, const string &nurbs_name,
+                EggGroupNode *egg_group, int trim_curve_index) {
+  if (mayaegg_cat.is_spam()) {
+    mayaegg_cat.spam()
+      << "Trim curve:\n";
+    mayaegg_cat.spam()
+      << "  numCVs: "
+      << curve.numCVs()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numKnots: "
+      << curve.numKnots()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numSpans: "
+      << curve.numSpans()
+      << "\n";
+  }
+
+  MStatus status;
+
+  MPointArray cv_array;
+  status = curve.getCVs(cv_array, MSpace::kWorld);
+  if (!status) {
+    status.perror("MFnNurbsCurve::getCVs");
+    return (EggNurbsCurve *)NULL;
+  }
+  MDoubleArray knot_array;
+  status = curve.getKnots(knot_array);
+  if (!status) {
+    status.perror("MFnNurbsCurve::getKnots");
+    return (EggNurbsCurve *)NULL;
+  }
+
+  //  MFnNurbsCurve::Form form = curve.form();
+
+  int degree = curve.degree();
+  int cvs = curve.numCVs();
+  int knots = curve.numKnots();
+
+  assert(knots == cvs + degree - 1);
+
+  string trim_name = "trim" + format_string(trim_curve_index);
+
+  string vpool_name = nurbs_name + "." + trim_name;
+  EggVertexPool *vpool = new EggVertexPool(vpool_name);
+  egg_group->add_child(vpool);
+
+  EggNurbsCurve *egg_curve = new EggNurbsCurve(trim_name);
+  egg_curve->setup(degree + 1, knots + 2);
+
+  int i;
+
+  egg_curve->set_knot(0, knot_array[0]);
+  for (i = 0; i < knots; i++) {
+    egg_curve->set_knot(i + 1, knot_array[i]);
+  }
+  egg_curve->set_knot(knots + 1, knot_array[knots - 1]);
+
+  for (i = 0; i < egg_curve->get_num_cvs(); i++) {
+    double v[4];
+    MStatus status = cv_array[i].get(v);
+    if (!status) {
+      status.perror("MPoint::get");
+    } else {
+      EggVertex vert;
+      vert.set_pos(LPoint3d(v[0], v[1], v[3]));
+      egg_curve->add_vertex(vpool->create_unique_vertex(vert));
+    }
+  }
+
+  return egg_curve;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::make_nurbs_curve
+//       Access: Private
+//  Description: 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.
+////////////////////////////////////////////////////////////////////
+void MaxToEggConverter::
+make_nurbs_curve(const MDagPath &, const MFnNurbsCurve &curve,
+                 EggGroup *egg_group) {
+  MStatus status;
+  string name = curve.name().asChar();
+
+  if (mayaegg_cat.is_spam()) {
+    mayaegg_cat.spam()
+      << "  numCVs: "
+      << curve.numCVs()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numKnots: "
+      << curve.numKnots()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numSpans: "
+      << curve.numSpans()
+      << "\n";
+  }
+
+  MPointArray cv_array;
+  status = curve.getCVs(cv_array, MSpace::kWorld);
+  if (!status) {
+    status.perror("MFnNurbsCurve::getCVs");
+    return;
+  }
+  MDoubleArray knot_array;
+  status = curve.getKnots(knot_array);
+  if (!status) {
+    status.perror("MFnNurbsCurve::getKnots");
+    return;
+  }
+
+  //  MFnNurbsCurve::Form form = curve.form();
+
+  int degree = curve.degree();
+  int cvs = curve.numCVs();
+  int knots = curve.numKnots();
+
+  assert(knots == cvs + degree - 1);
+
+  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 + 1, knots + 2);
+
+  int i;
+
+  egg_curve->set_knot(0, knot_array[0]);
+  for (i = 0; i < knots; i++) {
+    egg_curve->set_knot(i + 1, knot_array[i]);
+  }
+  egg_curve->set_knot(knots + 1, knot_array[knots - 1]);
+
+  LMatrix4d vertex_frame_inv = egg_group->get_vertex_frame_inv();
+
+  for (i = 0; i < egg_curve->get_num_cvs(); i++) {
+    double v[4];
+    MStatus status = cv_array[i].get(v);
+    if (!status) {
+      status.perror("MPoint::get");
+    } else {
+      EggVertex vert;
+      LPoint4d p4d(v[0], v[1], v[2], v[3]);
+      p4d = p4d * vertex_frame_inv;
+      vert.set_pos(p4d);
+      egg_curve->add_vertex(vpool->create_unique_vertex(vert));
+    }
+  }
+
+  MayaShader *shader = _shaders.find_shader_for_node(curve.object());
+  if (shader != (MayaShader *)NULL) {
+    set_shader_attributes(*egg_curve, *shader);
+  }
+}
+*/
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::make_polyset
+//       Access: Private
+//  Description: 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) {
+	Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "Entered make_poly_set." );
+
+  bool double_sided = false;
+
+  // *** I think this needs to have a plugin written to support
+  /*
+  MObject mesh_object = mesh.object();
+  bool double_sided = false;
+  get_bool_attribute(mesh_object, "doubleSided", double_sided);
+  */
+
+  mesh->buildNormals();
+
+  if (mesh->getNumFaces() == 0) {
+    Logger::Log(MNEG_GEOMETRY_GENERATION, Logger::SAT_MEDIUM_LEVEL, 
+		"Ignoring empty mesh ");
+    return;
+  }
+
+  string vpool_name = string(max_node->GetName()) + ".verts";
+  EggVertexPool *vpool = new EggVertexPool(vpool_name);
+  egg_group->add_child(vpool);
+
+  // 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 and/or
+  // 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.
+
+  // *** Need to find out if I even need to deal with shaders
+  /*
+  MObjectArray shaders;
+  MIntArray poly_shader_indices;
+
+  status = mesh.getConnectedShaders(dag_path.instanceNumber(),
+                                    shaders, poly_shader_indices);
+  if (!status) {
+    status.perror("MFnMesh::getConnectedShaders");
+  }
+  */
+
+  // 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.
+ 	Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "Before obtaining transform." );
+ LMatrix4d vertex_frame = get_object_transform(max_node) * 
+                           egg_group->get_vertex_frame_inv();
+	Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "After obtaining transform." );
+
+
+  // *** Not quite sure how this vertex color flag is handled.  Check on later
+  /*
+  // Save this modeling flag for the vertex color check later (see the
+  // comment below).
+  bool egg_vertex_color = false;
+  if (egg_group->has_user_data(MayaEggGroupUserData::get_class_type())) {
+    egg_vertex_color = 
+      DCAST(MayaEggGroupUserData, egg_group->get_user_data())->_vertex_color;
+  }
+  */
+
+  for ( int iFace=0; iFace < mesh->getNumFaces(); iFace++ ) {
+ 	Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "Getting face." );
+   EggPolygon *egg_poly = new EggPolygon;
+    egg_group->add_child(egg_poly);
+
+    egg_poly->set_bface_flag(double_sided);
+
+    Face face = mesh->faces[iFace];
+
+    // *** Once again skipping shaders until I determine if I need them
+    /*
+    // Determine the shader for this particular polygon.
+    MayaShader *shader = NULL;
+    int index = pi.index();
+    nassertv(index >= 0 && index < (int)poly_shader_indices.length());
+    int shader_index = poly_shader_indices[index];
+    if (shader_index != -1) {
+      nassertv(shader_index >= 0 && shader_index < (int)shaders.length());
+      MObject engine = shaders[shader_index];
+      shader =
+        _shaders.find_shader_for_shading_engine(engine);
+
+    } else if (default_shader != (MayaShader *)NULL) {
+      shader = default_shader;
+    }
+
+    const MayaShaderColorDef &color_def = shader->_color;
+    */
+
+    // Should we extract the color from the vertices?  Normally, in
+    // Maya a texture completely replaces the vertex color, so we
+    // should ignore the vertex color if we have a texture. 
+
+    // However, this is an inconvenient property of Maya; sometimes we
+    // really do want both vertex color and texture applied to the
+    // same object.  To allow this, we define the special egg flag
+    // "vertex-color", which when set indicates that we should
+    // respect the vertex color anyway.
+
+    // *** Ignoring vertex colors for now
+    bool ignore_vertex_color = true;
+    /*
+    bool ignore_vertex_color = false;
+    if (shader != (MayaShader *)NULL) {
+      ignore_vertex_color = color_def._has_texture && !egg_vertex_color;
+    }
+    */
+
+    // *** More shader stuff to ignore
+    /*
+    LPoint3d centroid(0.0, 0.0, 0.0);
+
+    if (shader != (MayaShader *)NULL && color_def.has_projection()) {
+      // If the shader has a projection, we may need to compute the
+      // polygon's centroid to avoid seams at the edges.
+      for (i = 0; i < num_verts; i++) {
+        MPoint p = pi.point(i, MSpace::kWorld);
+        LPoint3d p3d(p[0], p[1], p[2]);
+        p3d = p3d * vertex_frame_inv;
+        centroid += p3d;
+      }
+      centroid /= (double)num_verts;
+    }
+    */
+
+   // Get the vertices for the polygon.
+	Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "Before getting vertices." );
+
+	for ( int iVertex=0; iVertex < 3; iVertex++ ) {
+	Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "Getting vertex." );
+
+		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);
+	Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "After getting vertex pos before getting normal." );
+
+
+      // 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);
+	Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "After getting normal." );
+
+      // *** More shader stuff to ignore for now
+      /*
+      if (shader != (MayaShader *)NULL && color_def.has_projection()) {
+        // If the shader has a projection, use it instead of the
+        // polygon's built-in UV's.
+        vert.set_uv(color_def.project_uv(p3d, centroid));
+
+      } else if (pi.hasUVs()) {
+        // Get the UV's from the polygon.
+        float2 uvs;
+        status = pi.getUV(i, uvs);
+        if (!status) {
+          status.perror("MItMeshPolygon::getUV");
+        } else {
+          vert.set_uv(TexCoordd(uvs[0], uvs[1]));
+        }
+      }
+      */
+
+      // Get the UVs for this vertex
+      if (mesh->getNumTVerts()) {
+	UVVert vertTexCoord = mesh->getTVert(mesh->tvFace[iFace].t[iVertex]);
+	vert.set_uv( TexCoordd(vertTexCoord.x, vertTexCoord.y));
+	sprintf(Logger::GetLogString(), 
+		"Got tex vertex %d of %d from local tex data.", 
+		iVertex, mesh->getNumTVerts() );
+	Logger::Log(MNEG_GEOMETRY_GENERATION, Logger::SAT_LOW_LEVEL, 
+		    Logger::GetLogString() );
+      }
+	Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "after getting TVerts." );
+
+
+      // *** Leaving out vertex colors for now
+      /*
+      if (pi.hasColor() && !ignore_vertex_color) {
+        MColor c;
+        status = pi.getColor(c, i);
+        if (!status) {
+          status.perror("MItMeshPolygon::getColor");
+        } else {
+          vert.set_color(Colorf(c.r, c.g, c.b, 1.0));
+        }
+      }
+      */
+
+      vert.set_external_index(face.v[iVertex]);
+
+      egg_poly->add_vertex(vpool->create_unique_vertex(vert));
+    }
+
+  Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "Fixing windings" );
+  //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]);
+  }
+
+	// *** More shader stuff to ignore
+	/*
+    // Now apply the shader.
+    if (shader != (MayaShader *)NULL) {
+      set_shader_attributes(*egg_poly, *shader);
+    }
+	*/
+	Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "Before set_material_attributes" );
+	
+    set_material_attributes(*egg_poly, max_node->GetMtl(), &face);
+  }
+   
+  // 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 (_animation_convert == AC_model) {
+      get_vertex_weights(max_node, vpool);
+  }
+
+}
+
+// *** I don't know if there is a Max equivalent to this.  I will implement 
+//     this if I find one
+/*
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::make_locator
+//       Access: Private
+//  Description: Locators are used in Maya to indicate a particular
+//               position in space to the user or the modeler.  We
+//               represent that in egg with an ordinary Group node,
+//               which we transform by the locator's position, so that
+//               the indicated point becomes the origin at this node
+//               and below.
+////////////////////////////////////////////////////////////////////
+void MaxToEggConverter::
+make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
+             EggGroup *egg_group) {
+  MStatus status;
+
+  unsigned int num_children = dag_node.childCount();
+  MObject locator;
+  bool found_locator = false;
+  for (unsigned int ci = 0; ci < num_children && !found_locator; ci++) {
+    locator = dag_node.child(ci);
+    found_locator = (locator.apiType() == MFn::kLocator);
+  }
+
+  if (!found_locator) {
+    mayaegg_cat.error()
+      << "Couldn't find locator within locator node " 
+      << dag_path.fullPathName().asChar() << "\n";
+    return;
+  }
+
+  LPoint3d p3d;
+  if (!get_vec3d_attribute(locator, "localPosition", p3d)) {
+    mayaegg_cat.error()
+      << "Couldn't get position of locator " 
+      << dag_path.fullPathName().asChar() << "\n";
+    return;
+  }
+
+  // We need to convert the position to world coordinates.  For some
+  // reason, Maya can only tell it to us in local coordinates.
+  MMatrix mat = dag_path.inclusiveMatrix(&status);
+  if (!status) {
+    status.perror("Can't get coordinate space for locator");
+    return;
+  }
+  LMatrix4d n2w(mat[0][0], mat[0][1], mat[0][2], mat[0][3],
+                mat[1][0], mat[1][1], mat[1][2], mat[1][3],
+                mat[2][0], mat[2][1], mat[2][2], mat[2][3],
+                mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
+  p3d = p3d * n2w;
+
+  // Now convert the locator point into the group's space.
+  p3d = p3d * egg_group->get_node_frame_inv();
+
+  egg_group->add_translate(p3d);
+}
+*/
+
+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;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::get_vertex_weights
+//       Access: Private
+//  Description: 
+////////////////////////////////////////////////////////////////////
+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 != (EggGroup *)NULL)
+                  joint->ref_vertex(vert, 1.0f);
+                else
+                  Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, bone_node->GetName() );
+              }
+            }
+            else if(vertexType == RIGID_BLENDED_TYPE) {
+              // typecast to blended vertex
+              IPhyBlendedRigidVertex *pTypeVertex = (IPhyBlendedRigidVertex *)pVertexExport;
+
+              for (int ji = 0; ji < pTypeVertex->GetNumberNodes(); ++ji) {
+                float 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 != (EggGroup *)NULL)
+                      joint->ref_vertex(vert, weight);
+                    else
+                      Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, bone_node->GetName() );
+                  }
+                }
+              }
+            }
+            //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) {
+              float 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 != (EggGroup *)NULL) {
+                    joint->ref_vertex(vert, weight);
+                  } else {
+                    Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, bone_node->GetName() );
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+// *** More ignored shader stuff.  I am replacing this with 
+//     set_material_attributes for now
+/*
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShader::set_shader_attributes
+//       Access: Private
+//  Description: Applies the known shader attributes to the indicated
+//               egg primitive.
+////////////////////////////////////////////////////////////////////
+void MaxToEggConverter::
+set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader) {
+  // In Maya, a polygon is either textured or colored.  The texture,
+  // if present, replaces the color.
+  const MayaShaderColorDef &color_def = shader._color;
+  const MayaShaderColorDef &trans_def = shader._transparency;
+  if (color_def._has_texture || trans_def._has_texture) {
+    EggTexture tex(shader.get_name(), "");
+
+    if (color_def._has_texture) {
+      // If we have a texture on color, apply it as the filename.
+      Filename filename = Filename::from_os_specific(color_def._texture);
+      Filename fullpath = 
+        _path_replace->match_path(filename, get_texture_path());
+      tex.set_filename(_path_replace->store_path(fullpath));
+      tex.set_fullpath(fullpath);
+      apply_texture_properties(tex, color_def);
+
+      // If we also have a texture on transparency, apply it as the
+      // alpha filename.
+      if (trans_def._has_texture) {
+        if (color_def._wrap_u != trans_def._wrap_u ||
+            color_def._wrap_u != trans_def._wrap_u) {
+          mayaegg_cat.warning()
+            << "Shader " << shader.get_name()
+            << " has contradictory wrap modes on color and texture.\n";
+        }
+          
+        if (!compare_texture_properties(tex, trans_def)) {
+          // Only report each broken shader once.
+          static pset<string> bad_shaders;
+          if (bad_shaders.insert(shader.get_name()).second) {
+            mayaegg_cat.error()
+              << "Color and transparency texture properties differ on shader "
+              << shader.get_name() << "\n";
+          }
+        }
+        tex.set_format(EggTexture::F_rgba);
+          
+        // We should try to be smarter about whether the transparency
+        // value is connected to the texture's alpha channel or to its
+        // grayscale channel.  However, I'm not sure how to detect
+        // this at the moment; rather than spending days trying to
+        // figure out, for now I'll just assume that if the same
+        // texture image is used for both color and transparency, then
+        // the artist meant to use the alpha channel for transparency.
+        if (trans_def._texture == color_def._texture) {
+          // That means that we don't need to do anything special: use
+          // all the channels of the texture.
+
+        } else {
+          // Otherwise, pull the alpha channel from the other image
+          // file.  Ideally, we should figure out which channel from
+          // the other image supplies alpha (and specify this via
+          // set_alpha_file_channel()), but for now we assume it comes
+          // from the grayscale data.
+          filename = Filename::from_os_specific(trans_def._texture);
+          fullpath = _path_replace->match_path(filename, get_texture_path());
+          tex.set_alpha_filename(_path_replace->store_path(fullpath));
+          tex.set_alpha_fullpath(fullpath);
+        }
+
+      } else {
+        // If there is no transparency texture specified, we don't
+        // have any transparency, so tell the egg format to ignore any
+        // alpha channel that might be on the color texture.
+        tex.set_format(EggTexture::F_rgb);
+      }
+
+    } else {  // trans_def._has_texture
+      // We have a texture on transparency only.  Apply it as the
+      // primary filename, and set the format accordingly.
+      Filename filename = Filename::from_os_specific(trans_def._texture);
+      Filename fullpath = 
+        _path_replace->match_path(filename, get_texture_path());
+      tex.set_filename(_path_replace->store_path(fullpath));
+      tex.set_fullpath(fullpath);
+      tex.set_format(EggTexture::F_alpha);
+      apply_texture_properties(tex, trans_def);
+    }
+  
+    EggTexture *new_tex =
+      _textures.create_unique_texture(tex, ~EggTexture::E_tref_name);
+    
+    primitive.set_texture(new_tex);
+
+  }
+
+  // Also apply an overall color to the primitive.
+  Colorf rgba = shader.get_rgba();
+
+  // The existence of a texture on either color channel completely
+  // replaces the corresponding flat color.
+  if (color_def._has_texture) {
+    rgba[0] = 1.0f;
+    rgba[1] = 1.0f;
+    rgba[2] = 1.0f;
+  }
+  if (trans_def._has_texture) {
+    rgba[3] = 1.0f;
+  }
+
+  // But the color gain always gets applied.
+  rgba[0] *= color_def._color_gain[0];
+  rgba[1] *= color_def._color_gain[1];
+  rgba[2] *= color_def._color_gain[2];
+  rgba[3] *= color_def._color_gain[3];
+
+  primitive.set_color(rgba);
+}
+*/
+
+/*
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShader::set_material_attributes
+//       Access: Private
+//  Description: Applies the known shader attributes to the indicated
+//               egg primitive.
+////////////////////////////////////////////////////////////////////
+void MaxToEggConverter::
+set_material_attributes(EggPrimitive &primitive, Mtl *maxMaterial, Face *face) {
+  Bitmap *maxBitmap;
+  BitmapTex *maxBitmapTex;
+//  Mtl *maxMaterial;
+  StdMat *maxStandardMaterial;
+  Texmap *maxTexmap;
+  EggTexture *myEggTexture = null;
+  string outString;
+  string outHandle;
+  bool has_diffuse_texture = false;
+  bool has_trans_texture = false;
+  
+  Point3 diffuseColor = Point3(1, 1, 1);
+	
+  Logger::FunctionEntry( "MaxToEggConverter::CreateEggTextureFromINode" );
+
+  //First, get the material data associated with this node.
+//  maxMaterial = max_node->GetMtl();	
+  if ( !maxMaterial ) {
+    Logger::Log(MTEC, Logger::SAT_NULL_ERROR, "maxMaterial is null!");
+    Logger::FunctionExit();
+    return;
+  }
+
+  //Now, determine wether it's a standard or multi material
+  if ( maxMaterial->ClassID() == Class_ID(DMTL_CLASS_ID, 0 )) {
+      
+    // Access the Diffuse map and see if it's a Bitmap texture
+    maxStandardMaterial = (StdMat *)maxMaterial;
+    maxTexmap = maxMaterial->GetSubTexmap(ID_DI);
+    //Determine whether this texture is a bitmap.
+    if (maxTexmap && (maxTexmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0))) {
+     ostringstream name_strm;
+      name_strm << "Tex" << ++_cur_tref;
+      EggTexture tex(name_strm.str(), "");
+
+      // It is! 
+      has_diffuse_texture = true;
+
+      maxBitmapTex = (BitmapTex *) maxTexmap;
+      Filename filename = Filename::from_os_specific(maxBitmapTex->GetMapName());
+      Filename fullpath = 
+        _path_replace->match_path(filename, get_texture_path());
+      tex.set_filename(_path_replace->store_path(fullpath));
+      tex.set_fullpath(fullpath);
+      apply_texture_properties(tex, maxStandardMaterial);
+      // *** Must add stuff here for looking for transparencies
+      maxBitmap = maxBitmapTex->GetBitmap(0);
+      //Query some parameters of the bitmap to get the format option.
+      if ( maxBitmap && maxBitmap->HasAlpha() ) {
+	has_trans_texture = true;
+	tex.set_format(EggTexture::F_rgba);
+      } else {
+	tex.set_format(EggTexture::F_rgb);
+      }
+      EggTexture *new_tex =
+	_textures.create_unique_texture(tex, ~EggTexture::E_tref_name);
+    
+      primitive.set_texture(new_tex);
+    }
+
+    // Also apply an overall color to the primitive.
+    Colorf rgba(1.0f, 1.0f, 1.0f, 1.0f);
+
+    // The existence of a texture on either color channel completely
+    // replaces the corresponding flat color.
+    if (!has_diffuse_texture) {
+      // Get the default diffuse color of the material without the texture map
+      diffuseColor = Point3(maxMaterial->GetDiffuse());
+      rgba[0] = diffuseColor.x;
+      rgba[1] = diffuseColor.y;
+      rgba[2] = diffuseColor.z;
+    }
+    if (!has_trans_texture) {
+      // *** Figure out how to actually get the opacity here
+      rgba[3] = 1.0f;
+    }
+
+    // *** May need color gain, but I don't know what it is
+    /*
+    // But the color gain always gets applied.
+    rgba[0] *= color_def._color_gain[0];
+    rgba[1] *= color_def._color_gain[1];
+    rgba[2] *= color_def._color_gain[2];
+    rgba[3] *= color_def._color_gain[3];
+    */
+/*
+    primitive.set_color(rgba);
+
+  } else if ( maxMaterial->ClassID() == Class_ID(MULTI_CLASS_ID, 0 )) {
+	// It's a multi-material.  Find the submaterial for this face.
+    // and call set_material_attributes again on the submaterial.
+	MtlID matID = face->getMatID();
+	if (matID < maxMaterial->NumSubMtls()) {
+	  set_material_attributes(primitive, maxMaterial->GetSubMtl(matID), face);
+	} else {
+		sprintf(Logger::GetLogString(),
+			    "SubMaterial ID %d is greater than the total submaterial for this material",
+				matID);
+	  Logger::Log(MTEC, Logger::SAT_NULL_ERROR, "maxMaterial is null!");
+	}
+  } else {
+    // It's non-standard material. At the moment, let's just 
+    // return
+    Logger::FunctionExit();
+    return;
+  }
+
+  Logger::FunctionExit();
+}
+*/
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaxToEggConverter::set_material_attributes
+//       Access: Private
+//  Description: Applies the known material attributes to the indicated
+//               egg primitive.
+////////////////////////////////////////////////////////////////////
+void MaxToEggConverter::
+set_material_attributes(EggPrimitive &primitive, Mtl *maxMaterial, Face *face) {
+  Bitmap *diffuseBitmap;
+  BitmapTex *diffuseBitmapTex;
+  BitmapTex *transBitmapTex;
+//  Mtl *maxMaterial;
+  StdMat *maxStandardMaterial;
+  Texmap *diffuseTexmap;
+  Texmap *transTexmap;
+  EggTexture *myEggTexture = null;
+  string outString;
+  string outHandle;
+  bool has_diffuse_texture = false;
+  bool has_trans_texture = false;
+  
+  Point3 diffuseColor = Point3(1, 1, 1);
+	
+  Logger::FunctionEntry( "MaxToEggConverter::CreateEggTextureFromINode" );
+
+  //First, get the material data associated with this node.
+//  maxMaterial = max_node->GetMtl();	
+  if ( !maxMaterial ) {
+    Logger::Log(MTEC, Logger::SAT_NULL_ERROR, "maxMaterial is null!");
+    Logger::FunctionExit();
+    return;
+  }
+
+  //Now, determine wether it's a standard or multi material
+  if ( maxMaterial->ClassID() == Class_ID(DMTL_CLASS_ID, 0 )) {
+    // *** Eventuall we should probably deal with multi-materials
+     
+    maxStandardMaterial = (StdMat *)maxMaterial;
+
+	// Access the Diffuse map and see if it's a Bitmap texture
+    diffuseTexmap = maxMaterial->GetSubTexmap(ID_DI);
+	if (diffuseTexmap && (diffuseTexmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0))) {
+      has_diffuse_texture = true;
+	  diffuseBitmapTex = (BitmapTex *) diffuseTexmap;
+	}
+
+    // Access the Opacity map and see if it's a Bitmap texture
+	transTexmap = maxMaterial->GetSubTexmap(ID_OP);
+	if (transTexmap && (transTexmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0))) {
+      has_trans_texture = true;
+	  transBitmapTex = (BitmapTex *) transTexmap;
+	}
+
+    if (has_diffuse_texture || has_trans_texture) {
+      ostringstream name_strm;
+      name_strm << "Tex" << ++_cur_tref;
+      EggTexture tex(name_strm.str(), "");
+
+	  if (has_diffuse_texture) {
+	  // It is! 
+	  	
+		Filename filename = Filename::from_os_specific(diffuseBitmapTex->GetMapName());
+		Filename fullpath = 
+          _path_replace->match_path(filename, get_texture_path());
+		tex.set_filename(_path_replace->store_path(fullpath));
+		tex.set_fullpath(fullpath);
+		apply_texture_properties(tex, maxStandardMaterial);
+		// *** Must add stuff here for looking for transparencies
+		diffuseBitmap = diffuseBitmapTex->GetBitmap(0);
+		//Query some parameters of the bitmap to get the format option.
+		if ( has_trans_texture ) {
+		  tex.set_format(EggTexture::F_rgba);
+		  if (stricmp(diffuseBitmapTex->GetMapName(),
+					  transBitmapTex->GetMapName()) == 0) {
+			// nothing more needs to be done
+		  } else {
+            filename = Filename::from_os_specific(transBitmapTex->GetMapName());
+            fullpath = _path_replace->match_path(filename, get_texture_path());
+            tex.set_alpha_filename(_path_replace->store_path(fullpath));
+            tex.set_alpha_fullpath(fullpath);
+		  }
+		} else {
+		  if ( diffuseBitmap && diffuseBitmap->HasAlpha()) {
+		    tex.set_format(EggTexture::F_rgba);
+		  } else {
+		    tex.set_format(EggTexture::F_rgb);
+		  }
+        }
+	  } else {
+        // We have a texture on transparency only.  Apply it as the
+        // primary filename, and set the format accordingly.
+        Filename filename = Filename::from_os_specific(transBitmapTex->GetMapName());
+        Filename fullpath = 
+          _path_replace->match_path(filename, get_texture_path());
+        tex.set_filename(_path_replace->store_path(fullpath));
+        tex.set_fullpath(fullpath);
+        tex.set_format(EggTexture::F_alpha);
+        apply_texture_properties(tex, maxStandardMaterial);
+	  }
+	  EggTexture *new_tex =
+	    _textures.create_unique_texture(tex, ~EggTexture::E_tref_name);
+    
+      primitive.set_texture(new_tex);
+    }
+
+    // Also apply an overall color to the primitive.
+    Colorf rgba(1.0f, 1.0f, 1.0f, 1.0f);
+
+    // The existence of a texture on either color channel completely
+    // replaces the corresponding flat color.
+    if (!has_diffuse_texture) {
+      // Get the default diffuse color of the material without the texture map
+      diffuseColor = Point3(maxMaterial->GetDiffuse());
+      rgba[0] = diffuseColor.x;
+      rgba[1] = diffuseColor.y;
+      rgba[2] = diffuseColor.z;
+    }
+    if (!has_trans_texture) {
+      // *** Figure out how to actually get the opacity here
+      rgba[3] = maxStandardMaterial->GetOpacity(_current_frame * GetTicksPerFrame());
+    }
+
+    // *** May need color gain, but I don't know what it is
+    /*
+    // But the color gain always gets applied.
+    rgba[0] *= color_def._color_gain[0];
+    rgba[1] *= color_def._color_gain[1];
+    rgba[2] *= color_def._color_gain[2];
+    rgba[3] *= color_def._color_gain[3];
+    */
+
+    primitive.set_color(rgba);
+    
+  } else if ( maxMaterial->ClassID() == Class_ID(MULTI_CLASS_ID, 0 )) {
+	// It's a multi-material.  Find the submaterial for this face.
+    // and call set_material_attributes again on the submaterial.
+	MtlID matID = face->getMatID();
+	if (matID < maxMaterial->NumSubMtls()) {
+	  set_material_attributes(primitive, maxMaterial->GetSubMtl(matID), face);
+	} else {
+		sprintf(Logger::GetLogString(),
+			    "SubMaterial ID %d is greater than the total submaterial for this material",
+				matID);
+	  Logger::Log(MTEC, Logger::SAT_NULL_ERROR, "maxMaterial is null!");
+	}
+  } else {
+	// It's another non-standard material. At the moment, let's just 
+    // return
+    Logger::FunctionExit();
+    return;
+  }
+
+  Logger::FunctionExit();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShader::apply_texture_properties
+//       Access: Private
+//  Description: Applies all the appropriate texture properties to the
+//               EggTexture object, including wrap modes and texture
+//               matrix.
+////////////////////////////////////////////////////////////////////
+void MaxToEggConverter::
+apply_texture_properties(EggTexture &tex, StdMat *maxMaterial) {
+  // Let's mipmap all textures by default.
+  tex.set_minfilter(EggTexture::FT_linear_mipmap_linear);
+  tex.set_magfilter(EggTexture::FT_linear);
+
+  
+  // *** Need to figure out how to get the wrap options from Max
+  EggTexture::WrapMode wrap_u = EggTexture::WM_repeat;
+  EggTexture::WrapMode wrap_v = EggTexture::WM_repeat;
+  
+  /*
+  EggTexture::WrapMode wrap_u = color_def._wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp;
+  EggTexture::WrapMode wrap_v = color_def._wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp;
+  */
+
+  tex.set_wrap_u(wrap_u);
+  tex.set_wrap_v(wrap_v);
+  
+  // *** I may need to find this too
+  /*
+  LMatrix3d mat = color_def.compute_texture_matrix();
+  if (!mat.almost_equal(LMatrix3d::ident_mat())) {
+    tex.set_transform(mat);
+  }
+  */
+}
+
+// *** I don't think I need this right now
+/*
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShader::compare_texture_properties
+//       Access: Private
+//  Description: Compares the texture properties already on the
+//               texture (presumably set by a previous call to
+//               apply_texture_properties()) and returns false if they
+//               differ from that specified by the indicated color_def
+//               object, or true if they match.
+////////////////////////////////////////////////////////////////////
+bool MaxToEggConverter::
+compare_texture_properties(EggTexture &tex, 
+                           const MayaShaderColorDef &color_def) {
+  bool okflag = true;
+
+  EggTexture::WrapMode wrap_u = color_def._wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp;
+  EggTexture::WrapMode wrap_v = color_def._wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp;
+  
+  if (wrap_u != tex.determine_wrap_u()) {
+    // Choose the more general of the two.
+    if (wrap_u == EggTexture::WM_repeat) {
+      tex.set_wrap_u(wrap_u);
+    }
+    okflag = false;
+  }
+  if (wrap_v != tex.determine_wrap_v()) {
+    if (wrap_v == EggTexture::WM_repeat) {
+      tex.set_wrap_v(wrap_v);
+    }
+    okflag = false;
+  }
+  
+  LMatrix3d mat = color_def.compute_texture_matrix();
+  if (!mat.almost_equal(tex.get_transform())) {
+    okflag = false;
+  }
+
+  return okflag;
+}
+*/
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShader::reparent_decals
+//       Access: Private
+//  Description: 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 = (EggGroup *)NULL;
+  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 != (EggNode *)NULL) {
+	  // 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 == (EggGroup *)NULL) {
+    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;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShader::string_transform_type
+//       Access: Public, Static
+//  Description: Returns the TransformType value corresponding to the
+//               indicated string, or TT_invalid.
+////////////////////////////////////////////////////////////////////
+MaxToEggConverter::TransformType MaxToEggConverter::
+string_transform_type(const string &arg) {
+  if (strcmp(arg.c_str(), "all") == 0) {
+    return TT_all;
+  } else if (strcmp(arg.c_str(), "model") == 0) {
+    return TT_model;
+  } else if (strcmp(arg.c_str(), "dcs") == 0) {
+    return TT_dcs;
+  } else if (strcmp(arg.c_str(), "none") == 0) {
+    return TT_none;
+  } else {
+    return TT_invalid;
+  }
+}
+
+Modifier* MaxToEggConverter::FindSkinModifier (INode* node, const Class_ID &type)
+{
+  // Get object from node. Abort if no object.
+  Object* pObj = node->GetObjectRef();
+  if (!pObj) return NULL;
+
+  // 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 NULL;
+}

+ 24 - 0
pandatool/src/maxegg/post_max_include.h

@@ -0,0 +1,24 @@
+// Filename: post_maya_include.h
+// Created by:  drose (11Apr02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+// This header file works in conjunction with pre_maya_include.h; it
+// cleans up some of the definitions that it left open.
+
+// Remove the symbols defined from pre_maya_include.h.
+#undef ostream
+#undef istream

+ 35 - 0
pandatool/src/maxegg/pre_max_include.h

@@ -0,0 +1,35 @@
+// Filename: pre_maya_include.h
+// Created by:  drose (11Apr02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+// This header file defines a few things that are necessary to define
+// before including any Maya headers, just to work around some of
+// Max's assumptions about the compiler.  It must not try to protect
+// itself from multiple inclusion with #ifdef .. #endif, since it must
+// be used each time it is included.
+
+// Max will try to typedef bool unless this symbol is defined.
+#ifndef _BOOL
+#define _BOOL 1
+#endif
+
+// Max tries to make a forward declaration for class ostream, but
+// this is not necessarily a class!  Curses.  We can't use any of the
+// built-in Max stream operators, and we have to protect ourselves
+// from them.
+#define ostream max_ostream
+#define istream max_istream

+ 48 - 0
pandatool/src/maxegg/resource.h

@@ -0,0 +1,48 @@
+//{{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 IDC_CLOSEBUTTON                 1000
+#define IDC_DOSTUFF                     1000
+#define IDC_CHECK1                      1001
+#define IDC_MAKE_BAM                    1001
+#define IDC_DONE                        1002
+#define IDC_ANIMATION                   1003
+#define IDC_MODEL                       1004
+#define IDC_CHAN                        1005
+#define IDC_POSE                        1006
+#define IDC_STROBE                      1007
+#define IDC_BOTH                        1008
+#define IDC_EDIT1                       1009
+#define IDC_CN                          1009
+#define IDC_SF                          1010
+#define IDC_IF                          1011
+#define IDC_EF                          1012
+#define IDC_SF_LABEL                    1013
+#define IDC_EF_LABEL                    1014
+#define IDC_IF_LABEL                    1015
+#define IDC_CN_LABEL                    1016
+#define IDC_RADIO1                      1017
+#define IDC_DONE2                       1017
+#define IDC_CANCEL                      1017
+#define IDC_RADIO2                      1018
+#define IDC_COLOR                       1456
+#define IDC_EDIT                        1490
+#define IDC_SPIN                        1496
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        101
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1019
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif

+ 6 - 0
ppremake/BUILD_FROM_CVS.txt

@@ -1,3 +1,9 @@
+///////////////////////////////////////////////////////////////////////
+// Caution: there are two separate, independent build systems:
+// 'makepanda', and 'ppremake'.  Use one or the other, do not attempt
+// to use both.  This file is part of the 'ppremake' system.
+///////////////////////////////////////////////////////////////////////
+
 To build ppremake on Unix (or Windows Cygwin) using autoconf, follow
 the following steps.