new stuff from CMU

This commit is contained in:
David Rose 2005-02-08 07:30:50 +00:00
parent 6f1811be80
commit 0cc932301d
47 changed files with 12065 additions and 331 deletions

View File

@ -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
direct/src/directbase/ppython.cxx Executable file
View File

@ -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
direct/src/ffi/jGenPyCode.py Executable file
View File

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

View File

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

View File

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

202
doc/build
View File

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

View File

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

View File

@ -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
doc/doc/INSTALL-MK Normal file
View File

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

View File

@ -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
doc/doc/InstallerNotes Normal file
View File

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

View File

@ -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
panda3d-owner@yahoogroups.com 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
panda3d-owner@yahoogroups.com 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
doc/doc/README Normal file
View File

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

5877
doc/makepanda/makepanda.py Executable file

File diff suppressed because it is too large Load Diff

21
doc/makepanda/makepanda.sln Executable file
View File

@ -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
doc/makepanda/makepanda.vcproj Executable file
View File

@ -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
doc/makepanda/maketarball.py Executable file
View File

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

View File

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

View File

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

View File

@ -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
dtool/src/parser-inc/Max.h Executable file
View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
// 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
dtool/src/parser-inc/iparamb2.h Executable file
View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
// 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
dtool/src/parser-inc/iparamm2.h Executable file
View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
// 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
dtool/src/parser-inc/iskin.h Executable file
View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
// 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
dtool/src/parser-inc/istdplug.h Executable file
View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
// 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
dtool/src/parser-inc/phyexp.h Executable file
View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
// 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
dtool/src/parser-inc/stdmat.h Executable file
View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
// 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

View File

@ -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
pandatool/src/maxegg/Logger.cpp Executable file
View File

@ -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
pandatool/src/maxegg/Logger.h Executable file
View File

@ -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
pandatool/src/maxegg/MaxEgg.cpp Executable file
View File

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

View File

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

92
pandatool/src/maxegg/MaxEgg.h Executable file
View File

@ -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
pandatool/src/maxegg/MaxEgg.rc Executable file
View File

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

View File

@ -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
pandatool/src/maxegg/MaxToEgg.h Executable file
View File

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

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#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

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#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);
}
}
}

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#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

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#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;
}

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#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

File diff suppressed because it is too large Load Diff

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
// 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

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
// 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
pandatool/src/maxegg/resource.h Executable file
View File

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

View File

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