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