Merge branch 'master' into input-overhaul

This commit is contained in:
rdb
2017-12-17 13:04:15 +01:00
1095 changed files with 31203 additions and 17566 deletions
+10 -1
View File
@@ -8,6 +8,7 @@
core
core.*
vgcore.*
*.core
# Editor files/directories
*.save
@@ -22,6 +23,9 @@ vgcore.*
*.o
*.gch
*.pch
/+DESC
/+MANIFEST
/pkg-plist
# Produced installer/executables
/*.exe
@@ -31,6 +35,7 @@ vgcore.*
/*.pkg
/*.dmg
/*.whl
/*.txz
# CMake
/build/
@@ -47,6 +52,10 @@ Thumbs.db
ehthumbs.db
# Python
__pycache__
__pycache__/
*.pyc
*.pyo
# Test tool cache directories
.tox/
.cache/
+18 -3
View File
@@ -2,15 +2,22 @@ language: cpp
sudo: false
matrix:
include:
- compiler: gcc
env: PYTHONV=python2.7 FLAGS=--optimize=4
- compiler: clang
env: PYTHONV=python3 FLAGS=--installer
- compiler: clang
env: PYTHONV=python2.7 FLAGS=--override=STDFLOAT_DOUBLE=1
- compiler: gcc
env: PYTHONV=python2.7 FLAGS=--optimize=4
before_install:
- export CC=gcc-4.7
- export CXX=g++-4.7
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.7
- g++-4.7
- bison
- flex
- libfreetype6-dev
@@ -27,8 +34,16 @@ addons:
- nvidia-cg-toolkit
- python-dev
- python3-dev
- python-virtualenv
- zlib1g-dev
script: $PYTHONV makepanda/makepanda.py --everything --git-commit $TRAVIS_COMMIT $FLAGS --threads 4 && LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV makepanda/test_imports.py
- fakeroot
install:
- virtualenv --python=$PYTHONV venv && source venv/bin/activate
- $PYTHONV -m pip install pytest
script:
- $PYTHONV makepanda/makepanda.py --everything --git-commit $TRAVIS_COMMIT $FLAGS --threads 4
- LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV makepanda/test_imports.py
- LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV -m pytest tests
notifications:
irc:
channels:
+62 -9
View File
@@ -18,6 +18,23 @@ resources. If you get stuck, ask for help from our active
Panda3D is licensed under the Modified BSD License. See the LICENSE file for
more details.
Installing Panda3D
==================
By far, the easiest way to install the latest development build of Panda3D
into an existing Python installation is using the following command:
```bash
pip install --pre --extra-index-url https://archive.panda3d.org/ panda3d
```
If you prefer to install the full SDK with all tools, the latest development
builds can be obtained from this page:
https://www.panda3d.org/download.php?sdk&version=devel
These are automatically kept up-to-date with the latest GitHub version of Panda.
Building Panda3D
================
@@ -31,8 +48,8 @@ are included as part of the Windows 7.1 SDK.
You will also need to have the third-party dependency libraries available for
the build scripts to use. These are available from one of these two URLs,
depending on whether you are on a 32-bit or 64-bit system:
https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-win32.zip
https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-win64.zip
https://www.panda3d.org/download/panda3d-1.9.4/panda3d-1.9.4-tools-win32.zip
https://www.panda3d.org/download/panda3d-1.9.4/panda3d-1.9.4-tools-win64.zip
After acquiring these dependencies, you may simply build Panda3D from the
command prompt using the following command:
@@ -64,7 +81,7 @@ for you to install, depending on your distribution).
The following command illustrates how to build Panda3D with some common
options:
```bash
python2.7 makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-gles2
python makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-gles2 --no-opencv
```
You will probably see some warnings saying that it's unable to find several
@@ -93,11 +110,14 @@ may have to use the installpanda.py script instead, which will directly copy the
files into the appropriate locations on your computer. You may have to run the
`ldconfig` tool in order to update your library cache after installing Panda3D.
Mac OS X
--------
Alternatively, you can add the `--wheel` option, which will produce a .whl
file that can be installed into a Python installation using `pip`.
On Mac OS X, you will need to download a set of precompiled thirdparty packages in order to
compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-mac.tar.gz).
macOS
-----
On macOS, you will need to download a set of precompiled thirdparty packages in order to
compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.9.4/panda3d-1.9.4-tools-mac.tar.gz).
After placing the thirdparty directory inside the panda3d source directory,
you may build Panda3D using a command like the following:
@@ -107,20 +127,53 @@ python makepanda/makepanda.py --everything --installer
```
In order to make a universal build, pass the --universal flag. You may also
target a specific minimum Mac OS X version using the --osxtarget flag followed
target a specific minimum macOS version using the --osxtarget flag followed
by the release number, eg. 10.6 or 10.7.
If the build was successful, makepanda will have generated a .dmg file in
the source directory containing the installer. Simply open it and run the
package file in order to install the SDK onto your system.
FreeBSD
-------
Building on FreeBSD is very similar to building on Linux. You will need to
install the requisite packages using the system package manager. To install
the recommended set of dependencies, you can use this command:
```bash
pkg install pkgconf png jpeg-turbo tiff freetype2 eigen squish openal opusfile libvorbis libX11 libGL ode bullet assimp openexr
```
You will also need to choose which version of Python you want to use.
Install the appropriate package for it (such as `python2` or `python36`) and
run the makepanda script with your chosen Python version:
```bash
python3.6 makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-gles2
```
If successful, this will produce a .pkg file in the root of the source
directory which you can install using `pkg install`.
Running Tests
=============
Install [PyTest](https://docs.pytest.org/en/latest/getting-started.html#installation)
and run the `pytest` command. If you have not installed Panda3D, you will
need to configure your enviroment by pointing the `PYTHONPATH` variable at
the `built` directory. On Linux, you will also need to point the
`LD_LIBRARY_PATH` variable at the `built/lib` directory.
As a convenience, you can alternatively pass the `--tests` option to makepanda.
Reporting Issues
================
If you encounter any bugs when using Panda3D, please report them in the bug
tracker. This is hosted at:
https://bugs.launchpad.net/panda3d
https://github.com/panda3d/panda3d/issues
Make sure to first use the search function to see if the bug has already been
reported. When filling out a bug report, make sure that you include as much
+1 -1
View File
@@ -62,7 +62,7 @@ PUBLISHED:
// This function is used to enable or disable the guides for path finding.
void set_pf_guide(bool pf_guide);
AICharacter(string model_name, NodePath model_np, double mass, double movt_force, double max_force);
explicit AICharacter(string model_name, NodePath model_np, double mass, double movt_force, double max_force);
~AICharacter();
};
+1 -1
View File
@@ -66,7 +66,7 @@ public:
AINode *_next;
PUBLISHED:
AINode(int grid_x, int grid_y, LVecBase3 pos, float w, float l, float h);
explicit AINode(int grid_x, int grid_y, LVecBase3 pos, float w, float l, float h);
~AINode();
bool contains(float x, float y);
+1 -1
View File
@@ -44,7 +44,7 @@ public:
AICharList _ai_char_list;
PUBLISHED:
Flock(unsigned int flock_id, double vcone_angle, double vcone_radius, unsigned int separation_wt = 2,
explicit Flock(unsigned int flock_id, double vcone_angle, double vcone_radius, unsigned int separation_wt = 2,
unsigned int cohesion_wt = 4, unsigned int alignment_wt = 1);
~Flock();
-10
View File
@@ -1,10 +0,0 @@
/**
* @file direct.cxx
* @author drose
* @date 2000-05-18
*/
// This is a dummy file whose sole purpose is to give the compiler something
// to compile when making libdirect.so in NO_DEFER mode, which generates an
// empty library that itself links with all the other shared libraries that
// make up libdirect.
+95 -1
View File
@@ -50,6 +50,10 @@ class Actor(DirectObject, NodePath):
def __repr__(self):
return 'Actor.PartDef(%s, %s)' % (repr(self.partBundleNP), repr(self.partModel))
#snake_case alias:
get_bundle = getBundle
class AnimDef:
"""Instances of this class are stored within the
@@ -72,6 +76,10 @@ class Actor(DirectObject, NodePath):
def __repr__(self):
return 'Actor.AnimDef(%s)' % (repr(self.filename))
#snake_case alias:
make_copy = makeCopy
class SubpartDef:
"""Instances of this class are stored within the SubpartDict
@@ -889,7 +897,7 @@ class Actor(DirectObject, NodePath):
return ((toFrame+1)-fromFrame) / animControl.getFrameRate()
def getNumFrames(self, animName=None, partName=None):
lodName = next(iter(self.__animControlDict))
#lodName = next(iter(self.__animControlDict))
controls = self.getAnimControls(animName, partName)
if len(controls) == 0:
return None
@@ -2549,3 +2557,89 @@ class Actor(DirectObject, NodePath):
for partBundleDict in self.__partBundleDict.values():
partDef = partBundleDict.get(subpartDef.truePartName)
partDef.getBundle().setName(newBundleName)
#snake_case alias:
control_joint = controlJoint
set_lod_animation = setLODAnimation
get_anim_control_dict = getAnimControlDict
get_actor_info = getActorInfo
clear_lod_animation = clearLODAnimation
reset_lod = resetLOD
fix_bounds = fixBounds
get_anim_filename = getAnimFilename
get_subparts_complete = getSubpartsComplete
verify_subparts_complete = verifySubpartsComplete
get_play_rate = getPlayRate
clear_python_data = clearPythonData
load_anims = loadAnims
set_subparts_complete = setSubpartsComplete
draw_in_front = drawInFront
get_lod_node = getLODNode
hide_part = hidePart
get_joint_transform_state = getJointTransformState
set_control_effect = setControlEffect
get_anim_controls = getAnimControls
release_joint = releaseJoint
print_anim_blends = printAnimBlends
get_lod = getLOD
disable_blend = disableBlend
show_part = showPart
get_joint_transform = getJointTransform
face_away_from_viewer = faceAwayFromViewer
set_lod = setLOD
osd_anim_blends = osdAnimBlends
get_current_frame = getCurrentFrame
set_play_rate = setPlayRate
bind_all_anims = bindAllAnims
unload_anims = unloadAnims
remove_part = removePart
use_lod = useLOD
get_anim_blends = getAnimBlends
get_lod_index = getLODIndex
get_num_frames = getNumFrames
post_flatten = postFlatten
get_lod_names = getLODNames
list_joints = listJoints
make_subpart = makeSubpart
get_anim_control = getAnimControl
get_part_bundle = getPartBundle
get_part_bundle_dict = getPartBundleDict
get_duration = getDuration
has_lod = hasLOD
print_lod = printLOD
fix_bounds_old = fixBounds_old
get_anim_names = getAnimNames
get_part_bundles = getPartBundles
anim_panel = animPanel
stop_joint = stopJoint
actor_interval = actorInterval
hide_all_bounds = hideAllBounds
show_all_bounds = showAllBounds
init_anims_on_all_lods = initAnimsOnAllLODs
get_part = getPart
add_lod = addLOD
show_all_parts = showAllParts
get_joints = getJoints
get_overlapping_joints = getOverlappingJoints
enable_blend = enableBlend
face_towards_viewer = faceTowardsViewer
bind_anim = bindAnim
set_blend = setBlend
get_frame_time = getFrameTime
remove_node = removeNode
wait_pending = waitPending
expose_joint = exposeJoint
set_lod_node = setLODNode
get_frame_rate = getFrameRate
get_current_anim = getCurrentAnim
get_part_names = getPartNames
freeze_joint = freezeJoint
set_center = setCenter
rename_part_bundles = renamePartBundles
get_geom_node = getGeomNode
set_geom_node = setGeomNode
load_model = loadModel
copy_actor = copyActor
get_base_frame_rate = getBaseFrameRate
remove_anim_control_dict = removeAnimControlDict
load_anims_on_all_lods = loadAnimsOnAllLODs
+7
View File
@@ -0,0 +1,7 @@
"""
This package contains the :class:`.Actor` class as well as a
distributed variant thereof. Actor is a high-level interface around
the lower-level :class:`panda3d.core.Character` implementation.
It loads and controls an animated character and manages the animations
playing on it.
"""
+13
View File
@@ -21,6 +21,9 @@ class InputStateToken:
def __hash__(self):
return self._hash
#snake_case alias:
is_valid = isValid
class InputStateWatchToken(InputStateToken, DirectObject.DirectObject):
def release(self):
self._inputState._ignore(self)
@@ -39,6 +42,9 @@ class InputStateTokenGroup:
token.release()
self._tokens = []
#snake_case alias:
add_token = addToken
class InputState(DirectObject.DirectObject):
"""
InputState is for tracking the on/off state of some events.
@@ -235,3 +241,10 @@ class InputState(DirectObject.DirectObject):
"""for debugging"""
return self.notify.debug(
"%s (%s) %s"%(id(self), len(self._state), message))
#snake_case alias:
watch_with_modifiers = watchWithModifiers
is_set = isSet
get_event_name = getEventName
debug_print = debugPrint
release_inputs = releaseInputs
+4
View File
@@ -0,0 +1,4 @@
"""
This package contains various types of character controllers, handling basic
control mechanics and setting up collisions for them.
"""
+1 -1
View File
@@ -708,7 +708,7 @@ pack_object(PyObject *object) {
pack_int64(PyLong_AsLongLong(object));
#if PY_MAJOR_VERSION >= 3
} else if (PyUnicode_Check(object)) {
char *buffer;
const char *buffer;
Py_ssize_t length;
buffer = PyUnicode_AsUTF8AndSize(object, &length);
if (buffer) {
+16 -1
View File
@@ -1,4 +1,19 @@
""" This is a deprecated module that creates a global instance of ShowBase. """
"""
This is a shortcut that instantiates ShowBase automatically on import,
opening a graphical window and setting up the scene graph.
This example demonstrates its use:
import direct.directbase.DirectStart
run()
While it may be considered useful for quick prototyping in the interactive
Python shell, using it in applications is not considered good style.
As such, it has been deprecated starting with Panda3D 1.9. It is equivalent
to and may be replaced by the following code:
from direct.showbase.ShowBase import ShowBase
base = ShowBase()
"""
__all__ = []
+12
View File
@@ -0,0 +1,12 @@
"""
This package contains modules to quickly set up a Panda environment for
quick prototyping in the interactive Python shell. Merely importing
one of these modules will create a :class:`.ShowBase` instance, opening
a graphical window and setting up the scene graph.
The most commonly used module from this package is :mod:`.DirectStart`,
importing which executes the following code::
from direct.showbase.ShowBase import ShowBase
base = ShowBase()
"""
-106
View File
@@ -1,106 +0,0 @@
// This is a little wrapper to make it easy to run a python program from the
// command line. Basically, it just interfaces to the Python API and imports
// the module that was specified by the IMPORT_MODULE preprocessor definition
// when it was compiled.
#include "dtoolbase.h"
#undef _POSIX_C_SOURCE
#undef _XOPEN_SOURCE
#include <Python.h>
#if PY_MAJOR_VERSION >= 3
#include <wchar.h>
#endif
#ifndef IMPORT_MODULE
#error IMPORT_MODULE must be defined when compiling ppython.cxx !
#endif
#define _STRINGIFY(s) #s
#define STRINGIFY(s) _STRINGIFY(s)
#define IMPORT_MODULE_STR STRINGIFY(IMPORT_MODULE)
#if defined(_WIN32) && PY_MAJOR_VERSION >= 3
// As Py_SetProgramName expects a wchar_t*, it's easiest to just use the wmain
// entry point.
int wmain(int argc, wchar_t *argv[]) {
Py_SetProgramName(argv[0]);
#elif PY_MAJOR_VERSION >= 3
// Convert from UTF-8 to wchar_t*.
int main(int argc, char *mb_argv[]) {
wchar_t **argv = new wchar_t*[argc + 1];
for (int i = 0; i < argc; ++i) {
size_t len = mbstowcs(NULL, mb_argv[i], 0);
argv[i] = new wchar_t[len + 1];
mbstowcs(argv[i], mb_argv[i], len);
argv[i][len] = 0;
}
// Just for good measure
argv[argc] = NULL;
Py_SetProgramName(argv[0]);
#else
// Python 2.
int main(int argc, char *argv[]) {
Py_SetProgramName(argv[0]);
#endif
// On Windows, we need to set pythonhome correctly. We'll try to find
// ppython.exe on the path and set pythonhome to its location.
#ifdef _WIN32
#if PY_MAJOR_VERSION >= 3
// Py_SetPythonHome expects a wchar_t in Python 3.
wchar_t *path = _wgetenv(L"PATH");
wchar_t *result = wcstok(path, L";");
while (result != NULL) {
struct _stat st;
wchar_t *ppython = (wchar_t*) malloc(wcslen(result) * 2 + 26);
wcscpy(ppython, result);
wcscat(ppython, L"\\python.exe");
if (_wstat(ppython, &st) == 0) {
Py_SetPythonHome(result);
free(ppython);
break;
}
result = wcstok(NULL, L";");
free(ppython);
}
#else
char *path = getenv("PATH");
char *result = strtok(path, ";");
while (result != NULL) {
struct stat st;
char *ppython = (char*) malloc(strlen(result) + 13);
strcpy(ppython, result);
strcat(ppython, "\\ppython.exe");
if (stat(ppython, &st) == 0) {
Py_SetPythonHome(result);
free(ppython);
break;
}
result = strtok(NULL, ";");
free(ppython);
}
#endif
#endif
Py_Initialize();
if (Py_VerboseFlag) {
fprintf(stderr, "Python %s\\n%s\\n", Py_GetVersion(), Py_GetCopyright());
}
PySys_SetArgv(argc, argv);
int sts = 0;
PyObject* m = PyImport_ImportModule(IMPORT_MODULE_STR);
if (m <= 0) {
PyErr_Print();
sts = 1;
}
Py_Finalize();
return sts;
}
+53 -30
View File
@@ -9,10 +9,6 @@ ANALOG_MAX = 0.95
ANALOG_DEADBAND = 0.125
ANALOG_CENTER = 0.0
try:
myBase = base
except:
myBase = simbase
class DirectDeviceManager(VrpnClient, DirectObject):
def __init__(self, server = None):
@@ -52,8 +48,13 @@ class DirectButtons(ButtonNode, DirectObject):
ButtonNode.__init__(self, vrpnClient, device)
# Create a unique name for this button object
self.name = 'DirectButtons-' + repr(DirectButtons.buttonCount)
# Attach node to data graph
self.nodePath = myBase.dataRoot.attachNewNode(self)
try:
self._base = base
except:
self._base = simbase
self.nodePath = self._base.dataRoot.attachNewNode(self)
def __getitem__(self, index):
if (index < 0) or (index >= self.getNumButtons()):
@@ -64,10 +65,10 @@ class DirectButtons(ButtonNode, DirectObject):
return self.getNumButtons()
def enable(self):
self.nodePath.reparentTo(myBase.dataRoot)
self.nodePath.reparentTo(self._base.dataRoot)
def disable(self):
self.nodePath.reparentTo(myBase.dataUnused)
self.nodePath.reparentTo(self._base.dataUnused)
def getName(self):
return self.name
@@ -83,6 +84,12 @@ class DirectButtons(ButtonNode, DirectObject):
class DirectAnalogs(AnalogNode, DirectObject):
analogCount = 0
_analogDeadband = ConfigVariableDouble('vrpn-analog-deadband', ANALOG_DEADBAND)
_analogMin = ConfigVariableDouble('vrpn-analog-min', ANALOG_MIN)
_analogMax = ConfigVariableDouble('vrpn-analog-max', ANALOG_MAX)
_analogCenter = ConfigVariableDouble('vrpn-analog-center', ANALOG_CENTER)
def __init__(self, vrpnClient, device):
# Keep track of number of analogs created
DirectAnalogs.analogCount += 1
@@ -90,19 +97,20 @@ class DirectAnalogs(AnalogNode, DirectObject):
AnalogNode.__init__(self, vrpnClient, device)
# Create a unique name for this analog object
self.name = 'DirectAnalogs-' + repr(DirectAnalogs.analogCount)
# Attach node to data graph
self.nodePath = myBase.dataRoot.attachNewNode(self)
# See if any of the general analog parameters are dconfig'd
self.analogDeadband = myBase.config.GetFloat('vrpn-analog-deadband',
ANALOG_DEADBAND)
self.analogMin = myBase.config.GetFloat('vrpn-analog-min',
ANALOG_MIN)
self.analogMax = myBase.config.GetFloat('vrpn-analog-max',
ANALOG_MAX)
self.analogCenter = myBase.config.GetFloat('vrpn-analog-center',
ANALOG_CENTER)
self.analogRange = self.analogMax - self.analogMin
# Attach node to data graph
try:
self._base = base
except:
self._base = simbase
self.nodePath = self._base.dataRoot.attachNewNode(self)
# See if any of the general analog parameters are dconfig'd
self.analogDeadband = self._analogDeadband.getValue()
self.analogMin = self._analogMin.getValue()
self.analogMax = self._analogMax.getValue()
self.analogCenter = self._analogCenter.getValue()
self.analogRange = self.analogMax - self.analogMin
def __getitem__(self, index):
if (index < 0) or (index >= self.getNumControls()):
@@ -113,10 +121,10 @@ class DirectAnalogs(AnalogNode, DirectObject):
return self.getNumControls()
def enable(self):
self.nodePath.reparentTo(myBase.dataRoot)
self.nodePath.reparentTo(self._base.dataRoot)
def disable(self):
self.nodePath.reparentTo(myBase.dataUnused)
self.nodePath.reparentTo(self._base.dataUnused)
def normalizeWithoutCentering(self, val, minVal = -1, maxVal = 1):
#
@@ -186,14 +194,19 @@ class DirectTracker(TrackerNode, DirectObject):
TrackerNode.__init__(self, vrpnClient, device)
# Create a unique name for this tracker object
self.name = 'DirectTracker-' + repr(DirectTracker.trackerCount)
# Attach node to data graph
self.nodePath = myBase.dataRoot.attachNewNode(self)
try:
self._base = base
except:
self._base = simbase
self.nodePath = self._base.dataRoot.attachNewNode(self)
def enable(self):
self.nodePath.reparentTo(myBase.dataRoot)
self.nodePath.reparentTo(self._base.dataRoot)
def disable(self):
self.nodePath.reparentTo(myBase.dataUnused)
self.nodePath.reparentTo(self._base.dataUnused)
def getName(self):
return self.name
@@ -213,8 +226,13 @@ class DirectDials(DialNode, DirectObject):
DialNode.__init__(self, vrpnClient, device)
# Create a unique name for this dial object
self.name = 'DirectDials-' + repr(DirectDials.dialCount)
# Attach node to data graph
self.nodePath = myBase.dataRoot.attachNewNode(self)
try:
self._base = base
except:
self._base = simbase
self.nodePath = self._base.dataRoot.attachNewNode(self)
def __getitem__(self, index):
"""
@@ -227,10 +245,10 @@ class DirectDials(DialNode, DirectObject):
return self.getNumDials()
def enable(self):
self.nodePath.reparentTo(myBase.dataRoot)
self.nodePath.reparentTo(self._base.dataRoot)
def disable(self):
self.nodePath.reparentTo(myBase.dataUnused)
self.nodePath.reparentTo(self._base.dataUnused)
def getName(self):
return self.name
@@ -259,14 +277,19 @@ class DirectTimecodeReader(AnalogNode, DirectObject):
self.seconds = 0
self.minutes = 0
self.hours = 0
# Attach node to data graph
self.nodePath = myBase.dataRoot.attachNewNode(self)
try:
self._base = base
except:
self._base = simbase
self.nodePath = self._base.dataRoot.attachNewNode(self)
def enable(self):
self.nodePath.reparentTo(myBase.dataRoot)
self.nodePath.reparentTo(self._base.dataRoot)
def disable(self):
self.nodePath.reparentTo(myBase.dataUnused)
self.nodePath.reparentTo(self._base.dataUnused)
def getName(self):
return self.name
+1 -1
View File
@@ -21,7 +21,7 @@ class DirectRadamec(DirectObject):
radamecCount = 0
notify = DirectNotifyGlobal.directNotify.newCategory('DirectRadamec')
def __init__(self, device = 'Analog0', nodePath = base.direct.camera):
def __init__(self, device = 'Analog0', nodePath = None):
# See if device manager has been initialized
if base.direct.deviceManager == None:
base.direct.deviceManager = DirectDeviceManager()
+5
View File
@@ -0,0 +1,5 @@
"""
This package contains a high-level interface for VRPN devices.
Also see the :mod:`panda3d.vprn` module.
"""
+3
View File
@@ -0,0 +1,3 @@
"""
This package contains notification and logging utilities for Python code.
"""
+8 -3
View File
@@ -87,8 +87,13 @@ class EggCacher:
TexturePool.releaseAllTextures()
progress += size
cacher = EggCacher(sys.argv[1:])
# Dummy main function so this can be added to console_scripts.
def main():
def main(args=None):
if args is None:
args = sys.argv[1:]
cacher = EggCacher(args)
return 0
if __name__ == '__main__':
sys.exit(main())
-831
View File
@@ -1,831 +0,0 @@
; Panda3D installation script for the Nullsoft Installation System (NSIS).
; Jon Parise <jparise@cmu.edu>
; with Ben Johnson <bkj@andrew.cmu.edu>
; with Jason Pratt <pratt@andrew.cmu.edu>
; mangled by Josh Yelon <jyelon@andrew.cmu.edu>
; Caller needs to define these variables:
;
; COMPRESSOR - either zlib or lzma
; NAME - name of what we're building (ie, "Panda3D" or "Airblade")
; SMDIRECTORY - where to put this in the start menu (ie, "Panda3D 1.1.0" or "Airblade 1.1.0")
; INSTALLDIR - where to install the program (ie, "C:\Program Files\Panda3D-1.1.0")
; OUTFILE - where to put the output file (ie, "..\nsis-output.exe")
; LICENSE - location of the license file (ie, "C:\Airblade\LICENSE.TXT")
; LANGUAGE - name of the Language file to use (ie, "English" or "Panda3DEnglish")
; RUNTEXT - text for run-box at end of installation (ie, "Run the Panda Greeting Card")
; IBITMAP - name of installer bitmap (ie, "C:\Airblade\Airblade.bmp")
; UBITMAP - name of uninstaller bitmap (ie, "C:\Airblade\Airblade.bmp")
;
; PANDA - location of panda install tree.
; PYVER - version of Python that Panda was built with (ie, "2.7")
; PANDACONF - name of panda config directory - usually $PANDA\etc
; PSOURCE - location of the panda source-tree if available, OR location of panda install tree.
; PYEXTRAS - directory containing python extras, if any.
; REGVIEW - either 32 or 64, depending on the build architecture.
;
; PPGAME - directory containing prepagaged game, if any (ie, "C:\My Games\Airblade")
; PPMAIN - python program containing prepackaged game, if any (ie, "Airblade.py")
; PPICON - file containing icon of prepackaged game.
;
!include "MUI.nsh"
!include "WinMessages.nsh"
Name "${NAME}"
InstallDir "${INSTALLDIR}"
OutFile "${OUTFILE}"
SetCompress auto
SetCompressor ${COMPRESSOR}
!define MUI_WELCOMEFINISHPAGE_BITMAP "${IBITMAP}"
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "${UBITMAP}"
!define MUI_ABORTWARNING
!define MUI_FINISHPAGE_NOREBOOTSUPPORT
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_FUNCTION runFunction
!define MUI_FINISHPAGE_RUN_TEXT "${RUNTEXT}"
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "${LICENSE}"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
!insertmacro MUI_LANGUAGE "${LANGUAGE}"
ShowInstDetails nevershow
ShowUninstDetails nevershow
LicenseData "${LICENSE}"
InstType "Typical"
!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
var READABLE
var MANPAGE
var TUTNAME
Function runFunction
!ifdef PPGAME
ExecShell "open" "$SMPROGRAMS\${SMDIRECTORY}\Play ${NAME}.lnk"
!else
ExecShell "open" "$SMPROGRAMS\${SMDIRECTORY}\Panda Manual.lnk"
!endif
FunctionEnd
Section "${SMDIRECTORY}" SecCore
SectionIn 1 2 3 RO
SetDetailsPrint none
SetOutPath $INSTDIR
SetOverwrite try
SetOutPath $INSTDIR
File "${PANDA}\LICENSE"
SetOutPath $INSTDIR\bin
File /r "${PANDA}\bin\*.dll"
File /nonfatal /r "${PANDA}\bin\*.pyd"
File /nonfatal /r "${PANDA}\bin\Microsoft.*.manifest"
SetOutPath $INSTDIR\etc
File /r "${PANDACONF}\*"
SetOutPath $INSTDIR\direct\directscripts
File /r /x CVS /x Opt?-Win32 "${PANDA}\direct\directscripts\*"
SetOutPath $INSTDIR\direct\filter
File /r /x CVS /x Opt?-Win32 "${PANDA}\direct\filter\*.sha"
SetOutPath $INSTDIR\direct
File /r /x CVS /x Opt?-Win32 "${PANDA}\direct\*.py"
Delete "$INSTDIR\panda3d.py"
Delete "$INSTDIR\panda3d.pyc"
Delete "$INSTDIR\panda3d.pyo"
SetOutPath $INSTDIR\pandac
File /r "${PANDA}\pandac\*.py"
SetOutPath $INSTDIR\panda3d
File /r "${PANDA}\panda3d\*.py"
File /r "${PANDA}\panda3d\*.pyd"
SetOutPath $INSTDIR\python
File /r "${PANDA}\python\*"
RMDir /r "$SMPROGRAMS\${SMDIRECTORY}"
CreateDirectory "$SMPROGRAMS\${SMDIRECTORY}"
!ifdef PPGAME
SetOutPath $INSTDIR\models
File /r /x CVS "${PANDA}\models\*"
SetOutPath $INSTDIR\bin
File /r "${PANDA}\bin\eggcacher.exe"
SetOutpath $INSTDIR\game
File /r "${PPGAME}\*"
CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Play ${NAME}.lnk" "$INSTDIR\python\ppython.exe" "-E ${PPMAIN}" "$INSTDIR\${PPICON}" 0 SW_SHOWMINIMIZED "" "Play ${NAME}"
# Preload all EGG files into the model-cache
SetOutPath $INSTDIR
SetDetailsPrint textonly
SetDetailsView show
nsExec::ExecToLog '"$INSTDIR\bin\eggcacher.exe" --concise game'
SetDetailsPrint none
SetDetailsView hide
!else
SetOutPath $INSTDIR\plugins
File /nonfatal /r "${PANDA}\plugins\*.dle"
File /nonfatal /r "${PANDA}\plugins\*.dlo"
File /nonfatal /r "${PANDA}\plugins\*.mll"
File /nonfatal /r "${PANDA}\plugins\*.mel"
File /nonfatal /r "${PANDA}\plugins\*.ms"
File "${PSOURCE}\doc\INSTALLING-PLUGINS.TXT"
SetOutPath $INSTDIR\pandac\input
File /r "${PANDA}\pandac\input\*"
SetOutPath $INSTDIR\bin
File /r "${PANDA}\bin\*.exe"
File /nonfatal /r "${PANDA}\bin\*.p3d"
SetOutPath $INSTDIR\lib
File /r /x *.exp "${PANDA}\lib\*"
SetOutPath $INSTDIR\include
File /r /x *.exp "${PANDA}\include\*"
SetOutPath $INSTDIR\Pmw
File /r /x CVS "${PANDA}\Pmw\*"
SetOutPath $INSTDIR\NSIS
File /r /x CVS "${NSISDIR}\*"
SetOutPath $INSTDIR
File /r /x CVS "${PANDA}\ReleaseNotes"
!ifdef PYEXTRAS
SetOutPath $INSTDIR\python\lib
File /nonfatal /r "${PYEXTRAS}\*"
!endif
SetOutPath $INSTDIR\models
File /r /x CVS "${PANDA}\models\*"
SetOutPath $INSTDIR\samples
File /nonfatal /r /x CVS "${PSOURCE}\samples\*"
MessageBox MB_YESNO|MB_ICONQUESTION \
"EGG caching is about to begin.$\nThis process may take a couple minute and approximately 270 MB of RAM.$\nWARNING : It might stuck if your computer resources are low.$\n$\nDo you really want to do this optional step ?" \
IDNO SkipCaching
# Preload all EGG files into the model-cache
SetOutPath $INSTDIR
SetDetailsPrint both
SetDetailsView show
nsExec::ExecToLog '"$INSTDIR\bin\eggcacher.exe" --concise models samples'
SetDetailsPrint none
SetDetailsView hide
SkipCaching:
SetOutPath $INSTDIR
WriteINIStr $INSTDIR\Website.url "InternetShortcut" "URL" "http://panda3d.org/"
WriteINIStr $INSTDIR\Manual.url "InternetShortcut" "URL" "http://panda3d.org/wiki/index.php"
WriteINIStr $INSTDIR\Samples.url "InternetShortcut" "URL" "http://panda3d.org/wiki/index.php/Sample_Programs_in_the_Distribution"
SetOutPath $INSTDIR
CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Panda Manual.lnk" "$INSTDIR\Manual.url" "" "$INSTDIR\bin\eggcacher.exe" 0 "" "" "Panda Manual"
CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Panda Website.lnk" "$INSTDIR\Website.url" "" "$INSTDIR\bin\eggcacher.exe" 0 "" "" "Panda Website"
CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Sample Program Manual.lnk" "$INSTDIR\Samples.url" "" "$INSTDIR\bin\eggcacher.exe" 0 "" "" "Sample Program Manual"
FindFirst $0 $1 $INSTDIR\samples\*
loop:
StrCmp $1 "" done
StrCmp $1 "." next
StrCmp $1 ".." next
Push $1
Push "-"
Push " "
Call StrRep
Pop $R0
StrCpy $READABLE $R0
Push $1
Push "-"
Push "_"
Call StrRep
Pop $R0
StrCpy $MANPAGE $R0
CreateDirectory "$SMPROGRAMS\${SMDIRECTORY}\Sample Programs\$READABLE"
SetOutPath $INSTDIR\samples\$1
WriteINIStr $INSTDIR\samples\$1\ManualPage.url "InternetShortcut" "URL" "http://panda3d.org/wiki/index.php/Sample_Programs:_$MANPAGE"
CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Sample Programs\$READABLE\Manual Page.lnk" "$INSTDIR\samples\$1\ManualPage.url" "" "$INSTDIR\bin\eggcacher.exe" 0 "" "" "Manual Entry on this Sample Program"
CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Sample Programs\$READABLE\View Source Code.lnk" "$INSTDIR\samples\$1"
FindFirst $2 $3 $INSTDIR\samples\$1\Tut-*.py
iloop:
StrCmp $3 "" idone
StrCpy $TUTNAME $3 -3 4
Push $TUTNAME
Push "-"
Push " "
Call StrRep
Pop $R0
StrCpy $TUTNAME $R0
CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Sample Programs\$READABLE\Run $TUTNAME.lnk" "$INSTDIR\python\python.exe" "-E $3" "$INSTDIR\bin\eggcacher.exe" 0 SW_SHOWMINIMIZED "" "Run $TUTNAME"
CreateShortCut "$INSTDIR\samples\$1\Run $TUTNAME.lnk" "$INSTDIR\python\python.exe" "-E $3" "$INSTDIR\bin\eggcacher.exe" 0 SW_SHOWMINIMIZED "" "Run $TUTNAME"
FindNext $2 $3
goto iloop
idone:
next:
FindNext $0 $1
Goto loop
done:
!endif
SectionEnd
Section -post
!ifdef REGVIEW
SetRegView ${REGVIEW}
!endif
!ifndef PPGAME
# Add the "bin" directory to the PATH.
Push "$INSTDIR\python"
Call RemoveFromPath
Push "$INSTDIR\python\Scripts"
Call RemoveFromPath
Push "$INSTDIR\bin"
Call RemoveFromPath
Push "$INSTDIR\python"
Call AddToPath
Push "$INSTDIR\python\Scripts"
Call AddToPath
Push "$INSTDIR\bin"
Call AddToPath
ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
StrCmp $0 "$INSTDIR\python" RegPath 0
StrCmp $0 "" RegPath 0
MessageBox MB_YESNO|MB_ICONQUESTION \
"Your system already has a copy of Python installed. Panda3D installs its own copy of Python ${PYVER}, which will install alongside your existing copy. Would you like to make Panda's copy the default Python? If you choose 'No', you will have to configure your existing copy of Python to use the Panda3D libraries, keeping in mind that this version of Panda3D can only run with Python ${PYVER}." \
IDNO SkipRegPath
RegPath:
DetailPrint "Adding registry keys for python..."
WriteRegStr HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" "" "$INSTDIR\python"
SkipRegPath:
!endif
DetailPrint "Adding the uninstaller ..."
Delete "$INSTDIR\uninst.exe"
WriteUninstaller "$INSTDIR\uninst.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SMDIRECTORY}" "DisplayName" "${SMDIRECTORY}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SMDIRECTORY}" "UninstallString" '"$INSTDIR\uninst.exe"'
SetOutPath $INSTDIR
CreateShortcut "$SMPROGRAMS\${SMDIRECTORY}\Uninstall ${NAME}.lnk" "$INSTDIR\uninst.exe" ""
SectionEnd
Section Uninstall
!ifdef REGVIEW
SetRegView ${REGVIEW}
!endif
!ifndef PPGAME
Push "$INSTDIR\python"
Call un.RemoveFromPath
Push "$INSTDIR\python\Scripts"
Call un.RemoveFromPath
Push "$INSTDIR\bin"
Call un.RemoveFromPath
ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
StrCmp $0 "$INSTDIR\python" 0 SkipUnReg
DeleteRegKey HKLM "Software\Python\PythonCore\${PYVER}"
SkipUnReg:
!endif
Delete "$INSTDIR\uninst.exe"
RMDir /r "$SMPROGRAMS\${SMDIRECTORY}"
RMDir /r "$INSTDIR"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SMDIRECTORY}"
SectionEnd
# --[ Utility Functions ]------------------------------------------------------
; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
Function IsNT
Push $0
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
StrCmp $0 "" 0 IsNT_yes
; we are not NT.
Pop $0
Push 0
Return
IsNT_yes:
; NT!!!
Pop $0
Push 1
FunctionEnd
; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
Function un.IsNT
Push $0
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
StrCmp $0 "" 0 unIsNT_yes
; we are not NT.
Pop $0
Push 0
Return
unIsNT_yes:
; NT!!!
Pop $0
Push 1
FunctionEnd
; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
Function StrStr
Push $0
Exch
Pop $0 ; $0 now have the string to find
Push $1
Exch 2
Pop $1 ; $1 now have the string to find in
Exch
Push $2
Push $3
Push $4
Push $5
StrCpy $2 -1
StrLen $3 $0
StrLen $4 $1
IntOp $4 $4 - $3
unStrStr_loop:
IntOp $2 $2 + 1
IntCmp $2 $4 0 0 unStrStrReturn_notFound
StrCpy $5 $1 $3 $2
StrCmp $5 $0 unStrStr_done unStrStr_loop
unStrStrReturn_notFound:
StrCpy $2 -1
unStrStr_done:
Pop $5
Pop $4
Pop $3
Exch $2
Exch 2
Pop $0
Pop $1
FunctionEnd
; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
Function un.StrStr
Push $0
Exch
Pop $0 ; $0 now have the string to find
Push $1
Exch 2
Pop $1 ; $1 now have the string to find in
Exch
Push $2
Push $3
Push $4
Push $5
StrCpy $2 -1
StrLen $3 $0
StrLen $4 $1
IntOp $4 $4 - $3
unStrStr_loop:
IntOp $2 $2 + 1
IntCmp $2 $4 0 0 unStrStrReturn_notFound
StrCpy $5 $1 $3 $2
StrCmp $5 $0 unStrStr_done unStrStr_loop
unStrStrReturn_notFound:
StrCpy $2 -1
unStrStr_done:
Pop $5
Pop $4
Pop $3
Exch $2
Exch 2
Pop $0
Pop $1
FunctionEnd
; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
; Commentary and smarter ';' checking by Jon Parise <jparise@cmu.edu>
Function AddToPath
Exch $0
Push $1
Push $2
Push $3
Call IsNT
Pop $1
StrCmp $1 1 AddToPath_NT
; We're not on NT, so modify the AUTOEXEC.BAT file.
StrCpy $1 $WINDIR 2
FileOpen $1 "$1\autoexec.bat" a
FileSeek $1 0 END
GetFullPathName /SHORT $0 $0
FileWrite $1 "$\r$\nSET PATH=%PATH%;$0$\r$\n"
FileClose $1
Goto AddToPath_done
AddToPath_NT:
ReadRegStr $1 HKCU "Environment" "PATH"
Call IsUserAdmin
Pop $3
; If this is an Admin user, use the System env. variable instead of the user's env. variable
StrCmp $3 1 0 +2
ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
; If the PATH string is empty, jump over the mangling routines.
StrCmp $1 "" AddToPath_NTdoIt
; Pull off the last character of the PATH string. If it's a semicolon,
; we don't need to add another one, so jump to the section where we
; append the new PATH component(s).
StrCpy $2 $1 1 -1
StrCmp $2 ";" AddToPath_NTAddPath AddToPath_NTAddSemi
AddToPath_NTAddSemi:
StrCpy $1 "$1;"
Goto AddToPath_NTAddPath
AddToPath_NTAddPath:
StrCpy $0 "$1$0"
Goto AddToPath_NTdoIt
AddToPath_NTdoIt:
Call IsUserAdmin
Pop $3
StrCmp $3 1 0 NotAdmin
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $0
Goto AddToPath_done
NotAdmin:
WriteRegExpandStr HKCU "Environment" "PATH" $0
AddToPath_done:
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
Function RemoveFromPath
Exch $0
Push $1
Push $2
Push $3
Push $4
Push $5
Call IsNT
Pop $1
StrCmp $1 1 unRemoveFromPath_NT
; Not on NT
StrCpy $1 $WINDIR 2
FileOpen $1 "$1\autoexec.bat" r
GetTempFileName $4
FileOpen $2 $4 w
GetFullPathName /SHORT $0 $0
StrCpy $0 "SET PATH=%PATH%;$0"
SetRebootFlag true
Goto unRemoveFromPath_dosLoop
unRemoveFromPath_dosLoop:
FileRead $1 $3
StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoop
StrCmp $3 "$0$\n" unRemoveFromPath_dosLoop
StrCmp $3 "$0" unRemoveFromPath_dosLoop
StrCmp $3 "" unRemoveFromPath_dosLoopEnd
FileWrite $2 $3
Goto unRemoveFromPath_dosLoop
unRemoveFromPath_dosLoopEnd:
FileClose $2
FileClose $1
StrCpy $1 $WINDIR 2
Delete "$1\autoexec.bat"
CopyFiles /SILENT $4 "$1\autoexec.bat"
Delete $4
Goto unRemoveFromPath_done
unRemoveFromPath_NT:
StrLen $2 $0
Call IsUserAdmin
Pop $5
StrCmp $5 1 0 NotAdmin
ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
Push $1
Push $0
Call StrStr ; Find $0 in $1
Pop $0 ; pos of our dir
IntCmp $0 -1 unRemoveFromPath_done
; else, it is in path
StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
StrLen $0 $1
StrCpy $1 $1 $0 $2
StrCpy $3 "$3$1"
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
Goto unRemoveFromPath_done
NotAdmin:
ReadRegStr $1 HKCU "Environment" "PATH"
Push $1
Push $0
Call StrStr ; Find $0 in $1
Pop $0 ; pos of our dir
IntCmp $0 -1 unRemoveFromPath_done
; else, it is in path
StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
StrLen $0 $1
StrCpy $1 $1 $0 $2
StrCpy $3 "$3$1"
WriteRegExpandStr HKCU "Environment" "PATH" $3
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
unRemoveFromPath_done:
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
Function un.RemoveFromPath
Exch $0
Push $1
Push $2
Push $3
Push $4
Push $5
Call un.IsNT
Pop $1
StrCmp $1 1 unRemoveFromPath_NT
; Not on NT
StrCpy $1 $WINDIR 2
FileOpen $1 "$1\autoexec.bat" r
GetTempFileName $4
FileOpen $2 $4 w
GetFullPathName /SHORT $0 $0
StrCpy $0 "SET PATH=%PATH%;$0"
SetRebootFlag true
Goto unRemoveFromPath_dosLoop
unRemoveFromPath_dosLoop:
FileRead $1 $3
StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoop
StrCmp $3 "$0$\n" unRemoveFromPath_dosLoop
StrCmp $3 "$0" unRemoveFromPath_dosLoop
StrCmp $3 "" unRemoveFromPath_dosLoopEnd
FileWrite $2 $3
Goto unRemoveFromPath_dosLoop
unRemoveFromPath_dosLoopEnd:
FileClose $2
FileClose $1
StrCpy $1 $WINDIR 2
Delete "$1\autoexec.bat"
CopyFiles /SILENT $4 "$1\autoexec.bat"
Delete $4
Goto unRemoveFromPath_done
unRemoveFromPath_NT:
StrLen $2 $0
Call un.IsUserAdmin
Pop $5
StrCmp $5 1 0 NotAdmin
ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
Push $1
Push $0
Call un.StrStr ; Find $0 in $1
Pop $0 ; pos of our dir
IntCmp $0 -1 unRemoveFromPath_done
; else, it is in path
StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
StrLen $0 $1
StrCpy $1 $1 $0 $2
StrCpy $3 "$3$1"
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
Goto unRemoveFromPath_done
NotAdmin:
ReadRegStr $1 HKCU "Environment" "PATH"
Push $1
Push $0
Call un.StrStr ; Find $0 in $1
Pop $0 ; pos of our dir
IntCmp $0 -1 unRemoveFromPath_done
; else, it is in path
StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
StrLen $0 $1
StrCpy $1 $1 $0 $2
StrCpy $3 "$3$1"
WriteRegExpandStr HKCU "Environment" "PATH" $3
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
unRemoveFromPath_done:
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
; From: http://nsis.sourceforge.net/archive/nsisweb.php?page=329&instances=0,11
; Localized by Ben Johnson (bkj@andrew.cmu.edu)
Function IsUserAdmin
Push $0
Push $1
Push $2
Push $3
Call IsNT
Pop $1
ClearErrors
UserInfo::GetName
;IfErrors Win9x
Pop $2
UserInfo::GetAccountType
Pop $3
; Compare results of IsNT with "1"
StrCmp $1 1 0 NotNT
;This is NT
StrCmp $3 "Admin" 0 NotAdmin
; Observation: I get here when running Win98SE. (Lilla)
; The functions UserInfo.dll looks for are there on Win98 too,
; but just don't work. So UserInfo.dll, knowing that admin isn't required
; on Win98, returns admin anyway. (per kichik)
; MessageBox MB_OK 'User "$R1" is in the Administrators group'
Pop $3
Pop $2
Pop $1
Pop $0
Push 1
Return
NotAdmin:
; You should still check for an empty string because the functions
; UserInfo.dll looks for may not be present on Windows 95. (per kichik)
#StrCmp $2 "" Win9x
#StrCpy $0 0
;MessageBox MB_OK 'User "$2" is in the "$3" group'
Pop $3
Pop $2
Pop $1
Pop $0
Push 0
Return
;Because we use IsNT, this is redundant.
#Win9x:
# ; comment/message below is by UserInfo.nsi author:
# ; This one means you don't need to care about admin or
# ; not admin because Windows 9x doesn't either
# ;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!"
# StrCpy $0 0
NotNT:
;We are not NT
;Win9x doesn't have "admin" users.
;Let the user do whatever.
Pop $3
Pop $2
Pop $1
Pop $0
Push 1
FunctionEnd
Function un.IsUserAdmin
Push $0
Push $1
Push $2
Push $3
Call un.IsNT
Pop $1
ClearErrors
UserInfo::GetName
;IfErrors Win9x
Pop $2
UserInfo::GetAccountType
Pop $3
; Compare results of IsNT with "1"
StrCmp $1 1 0 NotNT
;This is NT
StrCmp $3 "Admin" 0 NotAdmin
; Observation: I get here when running Win98SE. (Lilla)
; The functions UserInfo.dll looks for are there on Win98 too,
; but just don't work. So UserInfo.dll, knowing that admin isn't required
; on Win98, returns admin anyway. (per kichik)
; MessageBox MB_OK 'User "$R1" is in the Administrators group'
Pop $3
Pop $2
Pop $1
Pop $0
Push 1
Return
NotAdmin:
; You should still check for an empty string because the functions
; UserInfo.dll looks for may not be present on Windows 95. (per kichik)
#StrCmp $2 "" Win9x
#StrCpy $0 0
;MessageBox MB_OK 'User "$2" is in the "$3" group'
Pop $3
Pop $2
Pop $1
Pop $0
Push 0
Return
;Because we use IsNT, this is redundant.
#Win9x:
# ; comment/message below is by UserInfo.nsi author:
# ; This one means you don't need to care about admin or
# ; not admin because Windows 9x doesn't either
# ;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!"
# StrCpy $0 0
NotNT:
;We are not NT
;Win9x doesn't have "admin" users.
;Let the user do whatever.
Pop $3
Pop $2
Pop $1
Pop $0
Push 1
FunctionEnd
Function StrRep
;Written by dirtydingus 2003-02-20 04:30:09
; USAGE
;Push String to do replacement in (haystack)
;Push String to replace (needle)
;Push Replacement
;Call StrRep
;Pop $R0 result
;StrCpy $Result STR $R0
Exch $R4 ; $R4 = Replacement String
Exch
Exch $R3 ; $R3 = String to replace (needle)
Exch 2
Exch $R1 ; $R1 = String to do replacement in (haystack)
Push $R2 ; Replaced haystack
Push $R5 ; Len (needle)
Push $R6 ; len (haystack)
Push $R7 ; Scratch reg
StrCpy $R2 ""
StrLen $R5 $R3
StrLen $R6 $R1
loop:
StrCpy $R7 $R1 $R5
StrCmp $R7 $R3 found
StrCpy $R7 $R1 1 ; - optimization can be removed if U know len needle=1
StrCpy $R2 "$R2$R7"
StrCpy $R1 $R1 $R6 1
StrCmp $R1 "" done loop
found:
StrCpy $R2 "$R2$R4"
StrCpy $R1 $R1 $R6 $R5
StrCmp $R1 "" done loop
done:
StrCpy $R3 $R2
Pop $R7
Pop $R6
Pop $R5
Pop $R2
Pop $R1
Pop $R4
Exch $R3
FunctionEnd
-424
View File
@@ -1,424 +0,0 @@
#############################################################################
#
# packpanda - this is a tool that packages up a panda game into a
# convenient, easily-downloaded windows executable. Packpanda runs on linux
# and windows - on linux, it builds .debs and .rpms, on windows it relies on
# NSIS, the nullsoft scriptable install system, to do the hard work.
#
# This is intentionally a very simplistic game-packer with very
# limited options. The goal is simplicity, not feature richness.
# There are dozens of complex, powerful packaging tools already out
# there. This one is for people who just want to do it quick and
# easy.
#
##############################################################################
import sys, os, getopt, shutil, py_compile, subprocess
OPTIONLIST = [
("dir", 1, "Name of directory containing game"),
("name", 1, "Human-readable name of the game"),
("version", 1, "Version number to add to game name"),
("rmdir", 2, "Delete all directories with given name"),
("rmext", 2, "Delete all files with given extension"),
("fast", 0, "Use fast compression instead of good compression"),
("bam", 0, "Generate BAM files, change default-model-extension to BAM"),
("pyc", 0, "Generate PYC files"),
]
def ParseFailure():
print("")
print("packpanda usage:")
print("")
for (opt, hasval, explanation) in OPTIONLIST:
if (hasval):
print(" --%-10s %s"%(opt+" x", explanation))
else:
print(" --%-10s %s"%(opt+" ", explanation))
sys.exit(1)
def ParseOptions(args):
try:
options = {}
longopts = []
for (opt, hasval, explanation) in OPTIONLIST:
if (hasval==2):
longopts.append(opt+"=")
options[opt] = []
elif (hasval==1):
longopts.append(opt+"=")
options[opt] = ""
else:
longopts.append(opt)
options[opt] = 0
opts, extras = getopt.getopt(args, "", longopts)
for option, value in opts:
for (opt, hasval, explanation) in OPTIONLIST:
if (option == "--"+opt):
if (hasval==2): options[opt].append(value)
elif (hasval==1): options[opt] = value
else: options[opt] = 1
return options
except: ParseFailure();
OPTIONS = ParseOptions(sys.argv[1:])
##############################################################################
#
# Locate the relevant trees.
#
##############################################################################
PANDA=None
for dir in sys.path:
if (dir != "") and os.path.exists(os.path.join(dir,"direct")) and os.path.exists(os.path.join(dir,"pandac")):
PANDA=os.path.abspath(dir)
if (PANDA is None):
sys.exit("Cannot locate the panda root directory in the python path (cannot locate directory containing direct and pandac).")
print("PANDA located at "+PANDA)
if (os.path.exists(os.path.join(PANDA,"..","makepanda","makepanda.py"))) and (sys.platform != "win32" or os.path.exists(os.path.join(PANDA,"..","thirdparty","win-nsis","makensis.exe"))):
PSOURCE=os.path.abspath(os.path.join(PANDA,".."))
if (sys.platform == "win32"):
NSIS=os.path.abspath(os.path.join(PANDA,"..","thirdparty","win-nsis"))
else:
PSOURCE=PANDA
if (sys.platform == "win32"):
NSIS=os.path.join(PANDA,"nsis")
##############################################################################
#
# Identify the main parts of the game: DIR, NAME, MAIN, ICON, BITMAP, etc
#
##############################################################################
VER=OPTIONS["version"]
DIR=OPTIONS["dir"]
if (DIR==""):
print("You must specify the --dir option.")
ParseFailure()
DIR=os.path.abspath(DIR)
MYDIR=os.path.abspath(os.getcwd())
BASENAME=os.path.basename(DIR)
if (OPTIONS["name"] != ""):
NAME=OPTIONS["name"]
else:
NAME=BASENAME
SMDIRECTORY=NAME
if (VER!=""): SMDIRECTORY=SMDIRECTORY+" "+VER
PYTHONV="python"+sys.version[:3]
LICENSE=os.path.join(DIR, "license.txt")
OUTFILE=os.path.basename(DIR)
if (VER!=""): OUTFILE=OUTFILE+"-"+VER
if (sys.platform == "win32"):
ICON=os.path.join(DIR, "icon.ico")
BITMAP=os.path.join(DIR, "installer.bmp")
OUTFILE=os.path.abspath(OUTFILE+".exe")
INSTALLDIR='C:\\'+os.path.basename(DIR)
if (VER!=""): INSTALLDIR=INSTALLDIR+"-"+VER
COMPRESS="lzma"
if (OPTIONS["fast"]): COMPRESS="zlib"
if (OPTIONS["pyc"]): MAIN="main.pyc"
else: MAIN="main.py"
def PrintFileStatus(label, file):
if (os.path.exists(file)):
print("%-15s: %s"%(label, file))
else:
print("%-15s: %s (MISSING)"%(label, file))
PrintFileStatus("Dir", DIR)
print("%-15s: %s"%("Name", NAME))
print("%-15s: %s"%("Start Menu", SMDIRECTORY))
PrintFileStatus("Main", os.path.join(DIR, MAIN))
if (sys.platform == "win32"):
PrintFileStatus("Icon", ICON)
PrintFileStatus("Bitmap", BITMAP)
PrintFileStatus("License", LICENSE)
print("%-15s: %s"%("Output", OUTFILE))
if (sys.platform == "win32"):
print("%-15s: %s"%("Install Dir", INSTALLDIR))
if (os.path.isdir(DIR)==0):
sys.exit("Difficulty reading "+DIR+". Cannot continue.")
if (os.path.isfile(os.path.join(DIR, "main.py"))==0):
sys.exit("Difficulty reading main.py. Cannot continue.")
if (os.path.isfile(LICENSE)==0):
LICENSE=os.path.join(PANDA,"LICENSE")
if (sys.platform == "win32") and (os.path.isfile(BITMAP)==0):
BITMAP=os.path.join(NSIS,"Contrib","Graphics","Wizard","nsis.bmp")
if (sys.platform == "win32"):
if (os.path.isfile(ICON)==0):
PPICON="bin\\ppython.exe"
else:
PPICON="game\\icon.ico"
##############################################################################
#
# Copy the game to a temporary directory, so we can modify it safely.
#
##############################################################################
def limitedCopyTree(src, dst, rmdir):
if (os.path.isdir(src)):
if (os.path.basename(src) in rmdir):
return
if (not os.path.isdir(dst)): os.mkdir(dst)
for x in os.listdir(src):
limitedCopyTree(os.path.join(src,x), os.path.join(dst,x), rmdir)
else:
shutil.copyfile(src, dst)
TMPDIR=os.path.abspath("packpanda-TMP")
if (sys.platform == "win32"):
TMPGAME=os.path.join(TMPDIR,"game")
TMPETC=os.path.join(TMPDIR,"etc")
else:
TMPGAME=os.path.join(TMPDIR,"usr","share","games",BASENAME,"game")
TMPETC=os.path.join(TMPDIR,"usr","share","games",BASENAME,"etc")
print("")
print("Copying the game to "+TMPDIR+"...")
if (os.path.exists(TMPDIR)):
try: shutil.rmtree(TMPDIR)
except: sys.exit("Cannot delete "+TMPDIR)
try:
os.mkdir(TMPDIR)
rmdir = {}
for x in OPTIONS["rmdir"]:
rmdir[x] = 1
if not os.path.isdir( TMPGAME ):
os.makedirs(TMPGAME)
limitedCopyTree(DIR, TMPGAME, rmdir)
if not os.path.isdir( TMPETC ):
os.makedirs(TMPETC)
if sys.platform == "win32":
limitedCopyTree(os.path.join(PANDA, "etc"), TMPETC, {})
else:
shutil.copyfile("/etc/Config.prc", os.path.join(TMPETC, "Config.prc"))
shutil.copyfile("/etc/Confauto.prc", os.path.join(TMPETC, "Confauto.prc"))
except: sys.exit("Cannot copy game to "+TMPDIR)
##############################################################################
#
# If --bam requested, change default-model-extension .egg to bam.
#
##############################################################################
def ReadFile(wfile):
try:
srchandle = open(wfile, "rb")
data = srchandle.read()
srchandle.close()
return data
except: exit("Cannot read "+wfile)
def WriteFile(wfile,data):
try:
dsthandle = open(wfile, "wb")
dsthandle.write(data)
dsthandle.close()
except: exit("Cannot write "+wfile)
if OPTIONS["bam"]:
CONF=ReadFile(os.path.join(TMPETC,"Confauto.prc"))
CONF=CONF.replace("default-model-extension .egg","default-model-extension .bam")
WriteFile(os.path.join(TMPETC,"Confauto.prc"), CONF)
##############################################################################
#
# Compile all py files, convert all egg files.
#
# We do this as a sanity check, even if the user
# hasn't requested that his files be compiled.
#
##############################################################################
if (sys.platform == "win32"):
EGG2BAM=os.path.join(PANDA,"bin","egg2bam.exe")
else:
EGG2BAM=os.path.join(PANDA,"bin","egg2bam")
def egg2bam(file,bam):
present = os.path.exists(bam)
if (present): bam = "packpanda-TMP.bam";
cmd = 'egg2bam -noabs -ps rel -pd . "'+file+'" -o "'+bam+'"'
print("Executing: "+cmd)
if (sys.platform == "win32"):
res = os.spawnl(os.P_WAIT, EGG2BAM, cmd)
else:
res = os.system(cmd)
if (res != 0): sys.exit("Problem in egg file: "+file)
if (present) or (OPTIONS["bam"]==0):
os.unlink(bam)
def py2pyc(file):
print("Compiling python "+file)
pyc = file[:-3]+'.pyc'
pyo = file[:-3]+'.pyo'
if (os.path.exists(pyc)): os.unlink(pyc)
if (os.path.exists(pyo)): os.unlink(pyo)
try: py_compile.compile(file)
except: sys.exit("Cannot compile "+file)
if (OPTIONS["pyc"]==0):
if (os.path.exists(pyc)):
os.unlink(pyc)
if (os.path.exists(pyo)):
os.unlink(pyo)
def CompileFiles(file):
if (os.path.isfile(file)):
if (file.endswith(".egg")):
egg2bam(file, file[:-4]+'.bam')
elif (file.endswith(".egg.pz") or file.endswith(".egg.gz")):
egg2bam(file, file[:-7]+'.bam')
elif (file.endswith(".py")):
py2pyc(file)
else: pass
elif (os.path.isdir(file)):
for x in os.listdir(file):
CompileFiles(os.path.join(file, x))
def DeleteFiles(file):
base = os.path.basename(file).lower()
if (os.path.isdir(file)):
for pattern in OPTIONS["rmdir"]:
if pattern.lower() == base:
print("Deleting "+file)
shutil.rmtree(file)
return
for x in os.listdir(file):
DeleteFiles(os.path.join(file, x))
else:
for ext in OPTIONS["rmext"]:
if base[-(len(ext) + 1):] == ("." + ext).lower():
print("Deleting "+file)
os.unlink(file)
return
print("")
print("Compiling BAM and PYC files...")
os.chdir(TMPGAME)
CompileFiles(".")
DeleteFiles(".")
##############################################################################
#
# Now make the installer. Yay!
#
##############################################################################
INSTALLER_DEB_FILE="""
Package: BASENAME
Version: VERSION
Section: games
Priority: optional
Architecture: ARCH
Essential: no
Depends: PYTHONV
Provides: BASENAME
Description: NAME
Maintainer: Unknown
"""
INSTALLER_SPEC_FILE="""
Summary: NAME
Name: BASENAME
Version: VERSION
Release: 1
Group: Amusement/Games
License: See license file
BuildRoot: TMPDIR
BuildRequires: PYTHONV
%description
NAME
%files
%defattr(-,root,root)
/usr/bin/BASENAME
/usr/lib/games/BASENAME
/usr/share/games/BASENAME
"""
RUN_SCRIPT="""
#!/bin/sh
cd /usr/share/games/BASENAME/game
PYTHONPATH=/usr/lib/games/BASENAME:/usr/share/games/BASENAME
LD_LIBRARY_PATH=/usr/lib/games/BASENAME
PYTHONV MAIN
"""
if (sys.platform == "win32"):
CMD="\""+NSIS+"\\makensis.exe\" /V2 "
CMD=CMD+'/DCOMPRESSOR="'+COMPRESS+'" '
CMD=CMD+'/DNAME="'+NAME+'" '
CMD=CMD+'/DSMDIRECTORY="'+SMDIRECTORY+'" '
CMD=CMD+'/DINSTALLDIR="'+INSTALLDIR+'" '
CMD=CMD+'/DOUTFILE="'+OUTFILE+'" '
CMD=CMD+'/DLICENSE="'+LICENSE+'" '
CMD=CMD+'/DLANGUAGE="English" '
CMD=CMD+'/DRUNTEXT="Play '+NAME+'" '
CMD=CMD+'/DIBITMAP="'+BITMAP+'" '
CMD=CMD+'/DUBITMAP="'+BITMAP+'" '
CMD=CMD+'/DPANDA="'+PANDA+'" '
CMD=CMD+'/DPANDACONF="'+TMPETC+'" '
CMD=CMD+'/DPSOURCE="'+PSOURCE+'" '
CMD=CMD+'/DPPGAME="'+TMPGAME+'" '
CMD=CMD+'/DPPMAIN="'+MAIN+'" '
CMD=CMD+'/DPPICON="'+PPICON+'" '
CMD=CMD+'"'+PSOURCE+'\\direct\\directscripts\\packpanda.nsi"'
print("")
print(CMD)
print("packing...")
subprocess.call(CMD)
else:
os.chdir(MYDIR)
os.system("mkdir -p %s/usr/bin" % TMPDIR)
os.system("mkdir -p %s/usr/share/games/%s" % (TMPDIR, BASENAME))
os.system("mkdir -p %s/usr/lib/games/%s" % (TMPDIR, BASENAME))
os.system("cp --recursive %s/direct %s/usr/share/games/%s/direct" % (PANDA, TMPDIR, BASENAME))
os.system("cp --recursive %s/pandac %s/usr/share/games/%s/pandac" % (PANDA, TMPDIR, BASENAME))
os.system("cp --recursive %s/models %s/usr/share/games/%s/models" % (PANDA, TMPDIR, BASENAME))
os.system("cp --recursive %s/Pmw %s/usr/share/games/%s/Pmw" % (PANDA, TMPDIR, BASENAME))
os.system("cp %s %s/usr/share/games/%s/LICENSE" % (LICENSE, TMPDIR, BASENAME))
os.system("cp --recursive /usr/lib/panda3d/* %s/usr/lib/games/%s/" % (TMPDIR, BASENAME))
# Make the script to run the game
txt = RUN_SCRIPT[1:].replace("BASENAME",BASENAME).replace("PYTHONV",PYTHONV).replace("MAIN",MAIN)
WriteFile(TMPDIR+"/usr/bin/"+BASENAME, txt)
os.system("chmod +x "+TMPDIR+"/usr/bin/"+BASENAME)
if (os.path.exists("/usr/bin/rpmbuild")):
os.system("rm -rf %s/DEBIAN" % TMPDIR)
os.system("rpm -E '%_target_cpu' > packpanda-TMP.txt")
ARCH=ReadFile("packpanda-TMP.txt").strip()
os.remove("packpanda-TMP.txt")
txt = INSTALLER_SPEC_FILE[1:].replace("VERSION",VER).replace("TMPDIR",TMPDIR)
txt = txt.replace("BASENAME",BASENAME).replace("NAME",NAME).replace("PYTHONV",PYTHONV)
WriteFile("packpanda-TMP.spec", txt)
os.system("rpmbuild --define '_rpmdir "+TMPDIR+"' -bb packpanda-TMP.spec")
os.system("mv "+ARCH+"/"+BASENAME+"-"+VER+"-1."+ARCH+".rpm .")
os.rmdir(ARCH)
os.remove("packpanda-TMP.spec")
if (os.path.exists("/usr/bin/dpkg-deb")):
os.system("dpkg --print-architecture > packpanda-TMP.txt")
ARCH=ReadFile("packpanda-TMP.txt").strip()
os.remove("packpanda-TMP.txt")
txt = INSTALLER_DEB_FILE[1:].replace("VERSION",str(VER)).replace("PYTHONV",PYTHONV)
txt = txt.replace("BASENAME",BASENAME).replace("NAME",NAME).replace("ARCH",ARCH)
os.system("mkdir -p %s/DEBIAN" % TMPDIR)
os.system("cd %s ; (find usr -type f -exec md5sum {} \;) > DEBIAN/md5sums" % TMPDIR)
WriteFile(TMPDIR+"/DEBIAN/control",txt)
os.system("dpkg-deb -b "+TMPDIR+" "+BASENAME+"_"+VER+"_"+ARCH+".deb")
if not(os.path.exists("/usr/bin/rpmbuild") or os.path.exists("/usr/bin/dpkg-deb")):
exit("To build an installer, either rpmbuild or dpkg-deb must be present on your system!")
# Dummy main function so this can be added to console_scripts.
def main():
return 0
@@ -413,7 +413,7 @@ class DirectCameraControl(DirectObject):
np = NodePath('temp')
np.setPos(base.direct.camera, hitPt)
self.coaMarkerPos = np.getPos()
np.remove()
np.removeNode()
self.coaMarker.setPos(self.coaMarkerPos)
iRay.collisionNodePath.removeNode()
+3 -3
View File
@@ -186,7 +186,7 @@ class DirectManipulationControl(DirectObject):
def drawMarquee(self, startX, startY):
if self.marquee:
self.marquee.remove()
self.marquee.removeNode()
self.marquee = None
if base.direct.cameraControl.useMayaCamControls and base.direct.fAlt:
@@ -228,7 +228,7 @@ class DirectManipulationControl(DirectObject):
skipFlags |= SKIP_CAMERA * (1 - base.getControl())
if self.marquee:
self.marquee.remove()
self.marquee.removeNode()
self.marquee = None
base.direct.deselectAll()
@@ -1691,7 +1691,7 @@ class ObjectHandles(NodePath, DirectObject):
np.setPos(base.direct.camera, hitPt)
resultPt = Point3(0)
resultPt.assign(np.getPos())
np.remove()
np.removeNode()
del iRay
return resultPt
+1 -1
View File
@@ -900,7 +900,7 @@ class DirectSession(DirectObject):
# If nothing specified, try selected node path
nodePath = self.selected.last
if nodePath:
nodePath.remove()
nodePath.removeNode()
def removeAllSelected(self):
self.selected.removeAll()
+8
View File
@@ -0,0 +1,8 @@
"""
This package contains the DIRECT tools, a set of tkinter tools for exploring
and manipulating the Panda3D scene graph. By default, these are disabled,
but they can be explicitly enabled using the following PRC configuration::
want-directtools true
want-tk true
"""
+3
View File
@@ -0,0 +1,3 @@
"""
This package contains assorted utility classes.
"""
+4 -2
View File
@@ -4,7 +4,6 @@ from panda3d.core import *
from panda3d.direct import *
from direct.directnotify.DirectNotifyGlobal import directNotify
from direct.distributed.DistributedObjectBase import DistributedObjectBase
from direct.showbase.PythonUtil import StackTrace
#from PyDatagram import PyDatagram
#from PyDatagramIterator import PyDatagramIterator
@@ -259,7 +258,10 @@ class DistributedObject(DistributedObjectBase):
def _destroyDO(self):
# after this is called, the object is no longer a DistributedObject
# but may still be used as a DelayDeleted object
self.destroyDoStackTrace = StackTrace()
if __debug__:
# StackTrace is omitted in packed versions
from direct.showbase.PythonUtil import StackTrace
self.destroyDoStackTrace = StackTrace()
# check for leftover cached data that was not retrieved or flushed by this object
# this will catch typos in the data name in calls to get/setCachedData
if hasattr(self, '_cachedData'):
@@ -7,19 +7,21 @@ from . import DistributedNode
from . import DistributedSmoothNodeBase
from direct.task.Task import cont
config = get_config_showbase()
# This number defines our tolerance for out-of-sync telemetry packets.
# If a packet appears to have originated from more than MaxFuture
# seconds in the future, assume we're out of sync with the other
# avatar and suggest a resync for both.
MaxFuture = base.config.GetFloat("smooth-max-future", 0.2)
MaxFuture = config.GetFloat("smooth-max-future", 0.2)
# How frequently can we suggest a resynchronize with another client?
MinSuggestResync = base.config.GetFloat("smooth-min-suggest-resync", 15)
MinSuggestResync = config.GetFloat("smooth-min-suggest-resync", 15)
# These flags indicate whether global smoothing and/or prediction is
# allowed or disallowed.
EnableSmoothing = base.config.GetBool("smooth-enable-smoothing", 1)
EnablePrediction = base.config.GetBool("smooth-enable-prediction", 1)
EnableSmoothing = config.GetBool("smooth-enable-smoothing", 1)
EnablePrediction = config.GetBool("smooth-enable-prediction", 1)
# These values represent the amount of time, in seconds, to delay the
# apparent position of other avatars, when non-predictive and
@@ -27,8 +29,8 @@ EnablePrediction = base.config.GetBool("smooth-enable-prediction", 1)
# addition to the automatic delay of the observed average latency from
# each avatar, which is intended to compensate for relative clock
# skew.
Lag = base.config.GetDouble("smooth-lag", 0.2)
PredictionLag = base.config.GetDouble("smooth-prediction-lag", 0.0)
Lag = config.GetDouble("smooth-lag", 0.2)
PredictionLag = config.GetDouble("smooth-prediction-lag", 0.0)
GlobalSmoothing = 0
@@ -312,7 +312,6 @@ class DoCollectionManager:
else:
self.notify.warning('handleSetLocation: object %s not present' % self.getMsgChannel())
@exceptionLogged()
def storeObjectLocation(self, object, parentId, zoneId):
oldParentId = object.parentId
oldZoneId = object.zoneId
-7
View File
@@ -17,7 +17,6 @@ class StagedObject:
call any "handle" functions.
"""
self.__state = initState
pass
def goOnStage(self, *args, **kw):
"""
@@ -29,8 +28,6 @@ class StagedObject:
if not self.isOnStage():
self.handleOnStage(*args, **kw)
pass
pass
def handleOnStage(self):
"""
@@ -39,7 +36,6 @@ class StagedObject:
Don't forget to call down to this one, though.
"""
self.__state = StagedObject.ON
pass
def goOffStage(self, *args, **kw):
"""
@@ -51,8 +47,6 @@ class StagedObject:
if not self.isOffStage():
self.handleOffStage(*args, **kw)
pass
pass
def handleOffStage(self):
"""
@@ -61,7 +55,6 @@ class StagedObject:
Don't forget to call down to this one, though.
"""
self.__state = StagedObject.OFF
pass
def isOnStage(self):
return self.__state == StagedObject.ON
+5
View File
@@ -0,0 +1,5 @@
"""
This package contains an implementation of the Distributed Networking
API, a high-level networking system that automatically propagates
changes made on distributed objects to interested clients.
"""
@@ -55,8 +55,8 @@ class SocketStream;
*/
class EXPCL_DIRECT CConnectionRepository {
PUBLISHED:
CConnectionRepository(bool has_owner_view = false,
bool threaded_net = false);
explicit CConnectionRepository(bool has_owner_view = false,
bool threaded_net = false);
~CConnectionRepository();
/*
+4 -1
View File
@@ -1 +1,4 @@
"""
This package contains various Python methods that extend some of Panda's
underlying C++ classes.
"""
+21
View File
@@ -536,3 +536,24 @@ class CommonFilters:
del self.configuration["GammaAdjust"]
return self.reconfigure((old_gamma != 1.0), "GammaAdjust")
return True
#snake_case alias:
del_cartoon_ink = delCartoonInk
set_half_pixel_shift = setHalfPixelShift
del_half_pixel_shift = delHalfPixelShift
set_inverted = setInverted
del_inverted = delInverted
del_view_glow = delViewGlow
set_volumetric_lighting = setVolumetricLighting
del_gamma_adjust = delGammaAdjust
set_bloom = setBloom
set_view_glow = setViewGlow
set_ambient_occlusion = setAmbientOcclusion
set_cartoon_ink = setCartoonInk
del_bloom = delBloom
del_ambient_occlusion = delAmbientOcclusion
load_shader = loadShader
set_blur_sharpen = setBlurSharpen
del_blur_sharpen = delBlurSharpen
del_volumetric_lighting = delVolumetricLighting
set_gamma_adjust = setGammaAdjust
+12
View File
@@ -349,3 +349,15 @@ class FilterManager(DirectObject):
self.nextsort = self.win.getSort() - 1000
self.basex = 0
self.basey = 0
#snake_case alias:
is_fullscreen = isFullscreen
resize_buffers = resizeBuffers
set_stacked_clears = setStackedClears
render_scene_into = renderSceneInto
get_scaled_size = getScaledSize
render_quad_into = renderQuadInto
get_clears = getClears
set_clears = setClears
create_buffer = createBuffer
window_event = windowEvent
+11
View File
@@ -0,0 +1,11 @@
"""
This package contains functionality for applying post-processing
filters to the result of rendering a 3-D scene. This is done by
rendering the scene to an off-screen buffer, and then applying this to
a full-screen card that has a shader applied which manipulates the
texture values as desired.
The :class:`.CommonFilters` class contains various filters that are
provided out of the box, whereas the :class:`.FilterManager` class
is a lower-level class that allows you to set up your own filters.
"""
+3 -2
View File
@@ -12,8 +12,9 @@ void vshader(float4 vtx_position : POSITION,
l_position=mul(mat_modelproj, vtx_position);
float2 c=(vtx_position.xz * texpad_src.xy) + texpad_src.xy;
float offset = texpix_src.x;
l_texcoord0 = float4(c.x-offset* -4, c.x-offset* -3, c.x-offset* -2, c.y);
l_texcoord1 = float4(c.x-offset* -1, c.x-offset* 0, c.x-offset* 1, c.y);
float pad = texpad_src.x * 2;
l_texcoord0 = float4(min(c.x-offset* -4, pad), min(c.x-offset* -3, pad), min(c.x-offset* -2, pad), c.y);
l_texcoord1 = float4(min(c.x-offset* -1, pad), c.x-offset* 0, c.x-offset* 1, c.y);
l_texcoord2 = float4(c.x-offset* 2, c.x-offset* 3, c.x-offset* 4, c.y);
}
+3 -2
View File
@@ -12,8 +12,9 @@ void vshader(float4 vtx_position : POSITION,
l_position=mul(mat_modelproj, vtx_position);
float2 c=(vtx_position.xz * texpad_src.xy) + texpad_src.xy;
float offset = texpix_src.y;
l_texcoord0 = float4(c.y-offset* -4, c.y-offset* -3, c.y-offset* -2, c.x);
l_texcoord1 = float4(c.y-offset* -1, c.y-offset* 0, c.y-offset* 1, c.x);
float pad = texpad_src.y * 2;
l_texcoord0 = float4(min(c.y-offset* -4, pad), min(c.y-offset* -3, pad), min(c.y-offset* -2, pad), c.x);
l_texcoord1 = float4(min(c.y-offset* -1, pad), c.y-offset* 0, c.y-offset* 1, c.x);
l_texcoord2 = float4(c.y-offset* 2, c.y-offset* 3, c.y-offset* 4, c.x);
}
+6 -4
View File
@@ -2,7 +2,7 @@
//
//Cg profile arbvp1 arbfp1
void vshader(float4 vtx_position : POSITION,
void vshader(float4 vtx_position : POSITION,
float2 vtx_texcoord0 : TEXCOORD0,
out float4 l_position : POSITION,
out float2 l_texcoord0 : TEXCOORD0,
@@ -17,16 +17,18 @@ void vshader(float4 vtx_position : POSITION,
void fshader(float2 l_texcoord0 : TEXCOORD0,
out float4 o_color : COLOR,
uniform float2 texpix_src,
uniform float4 texpad_src,
uniform sampler2D k_src : TEXUNIT0)
{
float pad = texpad_src.x * 2;
float3 offset = float3(1.0*texpix_src.x, 2.0*texpix_src.x, 3.0*texpix_src.x);
o_color = tex2D(k_src, l_texcoord0);
o_color += tex2D(k_src, float2(l_texcoord0.x - offset.z, l_texcoord0.y));
o_color += tex2D(k_src, float2(l_texcoord0.x - offset.y, l_texcoord0.y));
o_color += tex2D(k_src, float2(l_texcoord0.x - offset.x, l_texcoord0.y));
o_color += tex2D(k_src, float2(l_texcoord0.x + offset.x, l_texcoord0.y));
o_color += tex2D(k_src, float2(l_texcoord0.x + offset.y, l_texcoord0.y));
o_color += tex2D(k_src, float2(l_texcoord0.x + offset.z, l_texcoord0.y));
o_color += tex2D(k_src, float2(min(l_texcoord0.x + offset.x, pad), l_texcoord0.y));
o_color += tex2D(k_src, float2(min(l_texcoord0.x + offset.y, pad), l_texcoord0.y));
o_color += tex2D(k_src, float2(min(l_texcoord0.x + offset.z, pad), l_texcoord0.y));
o_color /= 7;
o_color.w = 1;
}
+6 -4
View File
@@ -2,7 +2,7 @@
//
//Cg profile arbvp1 arbfp1
void vshader(float4 vtx_position : POSITION,
void vshader(float4 vtx_position : POSITION,
float2 vtx_texcoord0 : TEXCOORD0,
out float4 l_position : POSITION,
out float2 l_texcoord0 : TEXCOORD0,
@@ -17,16 +17,18 @@ void vshader(float4 vtx_position : POSITION,
void fshader(float2 l_texcoord0 : TEXCOORD0,
out float4 o_color : COLOR,
uniform float2 texpix_src,
uniform float4 texpad_src,
uniform sampler2D k_src : TEXUNIT0)
{
float pad = texpad_src.y * 2;
float3 offset = float3(1.0*texpix_src.y, 2.0*texpix_src.y, 3.0*texpix_src.y);
o_color = tex2D(k_src, l_texcoord0);
o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.z));
o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.y));
o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.x));
o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y + offset.x));
o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y + offset.y));
o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y + offset.z));
o_color += tex2D(k_src, float2(l_texcoord0.x, min(l_texcoord0.y + offset.x, pad)));
o_color += tex2D(k_src, float2(l_texcoord0.x, min(l_texcoord0.y + offset.y, pad)));
o_color += tex2D(k_src, float2(l_texcoord0.x, min(l_texcoord0.y + offset.z, pad)));
o_color /= 7;
o_color.w = 1;
}
+6 -6
View File
@@ -1,13 +1,13 @@
"""Undocumented Module"""
__all__ = ['ClassicFSM']
"""Finite State Machine module: contains the ClassicFSM class.
This module and class exist only for backward compatibility with
existing code. New code should use the FSM module instead.
.. note::
This module and class exist only for backward compatibility with
existing code. New code should use the :mod:`.FSM` module instead.
"""
__all__ = ['ClassicFSM']
from direct.directnotify.DirectNotifyGlobal import directNotify
from direct.showbase.DirectObject import DirectObject
import weakref
+1 -1
View File
@@ -1,5 +1,5 @@
"""The new Finite State Machine module. This replaces the module
previously called FSM.py (now called ClassicFSM.py).
previously called FSM (now called :mod:`.ClassicFSM`).
"""
__all__ = ['FSMException', 'FSM']
+19 -21
View File
@@ -1,9 +1,7 @@
"""Undocumented Module"""
"""Contains the FourState class."""
__all__ = ['FourState']
from direct.directnotify import DirectNotifyGlobal
#import DistributedObject
from . import ClassicFSM
@@ -20,7 +18,7 @@ class FourState:
Inherit from FourStateFSM and pass in your states. Two of
the states should be oposites of each other and the other
two should be the transition states between the first two.
E.g.
E.g::
+--------+
-->| closed | --
@@ -90,7 +88,8 @@ class FourState:
off (and so is state 2 which is oposite of 4 and therefore
oposite of 'on').
"""
assert self.debugPrint("FourState(names=%s)"%(names))
self.stateIndex = 0
assert self.__debugPrint("FourState(names=%s)"%(names))
self.track = None
self.stateTime = 0.0
self.names = names
@@ -120,7 +119,6 @@ class FourState:
self.exitState4,
[names[1]]),
}
self.stateIndex = 0
self.fsm = ClassicFSM.ClassicFSM('FourState',
list(self.states.values()),
# Initial State
@@ -131,7 +129,7 @@ class FourState:
self.fsm.enterInitialState()
def setTrack(self, track):
assert self.debugPrint("setTrack(track=%s)"%(track,))
assert self.__debugPrint("setTrack(track=%s)"%(track,))
if self.track is not None:
self.track.pause()
self.track = None
@@ -147,27 +145,27 @@ class FourState:
# If the client wants the state changed it needs to
# send a request to the AI.
#def setIsOn(self, isOn):
# assert self.debugPrint("setIsOn(isOn=%s)"%(isOn,))
# assert self.__debugPrint("setIsOn(isOn=%s)"%(isOn,))
# pass
def isOn(self):
assert self.debugPrint("isOn() returning %s (stateIndex=%s)"%(self.stateIndex==4, self.stateIndex))
assert self.__debugPrint("isOn() returning %s (stateIndex=%s)"%(self.stateIndex==4, self.stateIndex))
return self.stateIndex==4
def changedOnState(self, isOn):
"""
Allow derived classes to overide this.
"""
assert self.debugPrint("changedOnState(isOn=%s)"%(isOn,))
assert self.__debugPrint("changedOnState(isOn=%s)"%(isOn,))
##### state 0 #####
def enterState0(self):
assert self.debugPrint("enter0()")
assert self.__debugPrint("enter0()")
self.enterStateN(0)
def exitState0(self):
assert self.debugPrint("exit0()")
assert self.__debugPrint("exit0()")
# It's important for FourStates to broadcast their state
# when they are generated on the client. Before I put this in,
# if a door was generated and went directly to an 'open' state,
@@ -177,43 +175,43 @@ class FourState:
##### state 1 #####
def enterState1(self):
assert self.debugPrint("enterState1()")
assert self.__debugPrint("enterState1()")
self.enterStateN(1)
def exitState1(self):
assert self.debugPrint("exitState1()")
assert self.__debugPrint("exitState1()")
##### state 2 #####
def enterState2(self):
assert self.debugPrint("enterState2()")
assert self.__debugPrint("enterState2()")
self.enterStateN(2)
def exitState2(self):
assert self.debugPrint("exitState2()")
assert self.__debugPrint("exitState2()")
##### state 3 #####
def enterState3(self):
assert self.debugPrint("enterState3()")
assert self.__debugPrint("enterState3()")
self.enterStateN(3)
def exitState3(self):
assert self.debugPrint("exitState3()")
assert self.__debugPrint("exitState3()")
##### state 4 #####
def enterState4(self):
assert self.debugPrint("enterState4()")
assert self.__debugPrint("enterState4()")
self.enterStateN(4)
self.changedOnState(1)
def exitState4(self):
assert self.debugPrint("exitState4()")
assert self.__debugPrint("exitState4()")
self.changedOnState(0)
if __debug__:
def debugPrint(self, message):
def __debugPrint(self, message):
"""for debugging"""
return self.notify.debug("%d (%d) %s"%(
id(self), self.stateIndex==4, message))
+25 -27
View File
@@ -1,9 +1,7 @@
"""Undocumented Module"""
"""Contains the FourStateAI class. See also :mod:`.FourState`."""
__all__ = ['FourStateAI']
from direct.directnotify import DirectNotifyGlobal
#import DistributedObjectAI
from . import ClassicFSM
@@ -21,7 +19,7 @@ class FourStateAI:
Inherit from FourStateFSM and pass in your states. Two of
the states should be oposites of each other and the other
two should be the transition states between the first two.
E.g.
E.g::
+--------+
-->| closed | --
@@ -93,11 +91,11 @@ class FourStateAI:
off (and so is state 2 which is oposite of state 4 and therefore
oposite of 'on').
"""
assert self.debugPrint(
self.stateIndex = 0
assert self.__debugPrint(
"FourStateAI(names=%s, durations=%s)"
%(names, durations))
self.doLaterTask = None
self.stateIndex = 0
assert len(names) == 5
assert len(names) == len(durations)
self.names = names
@@ -137,7 +135,7 @@ class FourStateAI:
self.fsm.enterInitialState()
def delete(self):
assert self.debugPrint("delete()")
assert self.__debugPrint("delete()")
if self.doLaterTask is not None:
self.doLaterTask.remove()
del self.doLaterTask
@@ -145,15 +143,15 @@ class FourStateAI:
del self.fsm
def getState(self):
assert self.debugPrint("getState() returning %s"%(self.stateIndex,))
assert self.__debugPrint("getState() returning %s"%(self.stateIndex,))
return [self.stateIndex]
def sendState(self):
assert self.debugPrint("sendState()")
assert self.__debugPrint("sendState()")
self.sendUpdate('setState', self.getState())
def setIsOn(self, isOn):
assert self.debugPrint("setIsOn(isOn=%s)"%(isOn,))
assert self.__debugPrint("setIsOn(isOn=%s)"%(isOn,))
if isOn:
if self.stateIndex != 4:
# ...if it's not On; request turning on:
@@ -170,7 +168,7 @@ class FourStateAI:
# self.fsm.request(self.states[nextState])
def isOn(self):
assert self.debugPrint("isOn() returning %s (stateIndex=%s)"%(self.stateIndex==4, self.stateIndex))
assert self.__debugPrint("isOn() returning %s (stateIndex=%s)"%(self.stateIndex==4, self.stateIndex))
return self.stateIndex==4
def changedOnState(self, isOn):
@@ -179,12 +177,12 @@ class FourStateAI:
The self.isOn value has toggled. Call getIsOn() to
get the current state.
"""
assert self.debugPrint("changedOnState(isOn=%s)"%(isOn,))
assert self.__debugPrint("changedOnState(isOn=%s)"%(isOn,))
##### states #####
def switchToNextStateTask(self, task):
assert self.debugPrint("switchToNextStateTask()")
assert self.__debugPrint("switchToNextStateTask()")
self.fsm.request(self.states[self.nextStateIndex])
return Task.done
@@ -193,11 +191,11 @@ class FourStateAI:
This function is intentionaly simple so that derived classes
may easily alter the network message.
"""
assert self.debugPrint("distributeStateChange()")
assert self.__debugPrint("distributeStateChange()")
self.sendState()
def enterStateN(self, stateIndex, nextStateIndex):
assert self.debugPrint(
assert self.__debugPrint(
"enterStateN(stateIndex=%s, nextStateIndex=%s)"%
(stateIndex, nextStateIndex))
self.stateIndex = stateIndex
@@ -211,7 +209,7 @@ class FourStateAI:
"enterStateN-timer-%s"%id(self))
def exitStateN(self):
assert self.debugPrint("exitStateN()")
assert self.__debugPrint("exitStateN()")
if self.doLaterTask:
taskMgr.remove(self.doLaterTask)
self.doLaterTask=None
@@ -219,56 +217,56 @@ class FourStateAI:
##### state 0 #####
def enterState0(self):
assert self.debugPrint("enter0()")
assert self.__debugPrint("enter0()")
self.enterStateN(0, 0)
def exitState0(self):
assert self.debugPrint("exit0()")
assert self.__debugPrint("exit0()")
##### state 1 #####
def enterState1(self):
#assert self.debugPrint("enterState1()")
#assert self.__debugPrint("enterState1()")
self.enterStateN(1, 2)
def exitState1(self):
assert self.debugPrint("exitState1()")
assert self.__debugPrint("exitState1()")
self.exitStateN()
##### state 2 #####
def enterState2(self):
#assert self.debugPrint("enterState2()")
#assert self.__debugPrint("enterState2()")
self.enterStateN(2, 3)
def exitState2(self):
assert self.debugPrint("exitState2()")
assert self.__debugPrint("exitState2()")
self.exitStateN()
##### state 3 #####
def enterState3(self):
#assert self.debugPrint("enterState3()")
#assert self.__debugPrint("enterState3()")
self.enterStateN(3, 4)
def exitState3(self):
assert self.debugPrint("exitState3()")
assert self.__debugPrint("exitState3()")
self.exitStateN()
##### state 4 #####
def enterState4(self):
assert self.debugPrint("enterState4()")
assert self.__debugPrint("enterState4()")
self.enterStateN(4, 1)
self.changedOnState(1)
def exitState4(self):
assert self.debugPrint("exitState4()")
assert self.__debugPrint("exitState4()")
self.exitStateN()
self.changedOnState(0)
if __debug__:
def debugPrint(self, message):
def __debugPrint(self, message):
"""for debugging"""
return self.notify.debug("%d (%d) %s"%(
id(self), self.stateIndex==4, message))
+6
View File
@@ -0,0 +1,6 @@
"""
This package contains implementations of a Finite State Machine, an
abstract construct that holds a particular state and can transition
between several defined states. These are useful for a range of logic
programming tasks.
"""
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""This module contains the DirectButton class."""
__all__ = ['DirectButton']
+3 -1
View File
@@ -1,4 +1,6 @@
"""Undocumented Module"""
"""A DirectCheckButton is a type of button that toggles between two states
when clicked. It also has a separate indicator that can be modified
separately."""
__all__ = ['DirectCheckButton']
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""This module defines various dialog windows for the DirectGUI system."""
__all__ = ['findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog', 'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog']
+2 -1
View File
@@ -1,4 +1,5 @@
"""Undocumented Module"""
"""Contains the DirectEntry class, a type of DirectGUI widget that accepts
text entered using the keyboard."""
__all__ = ['DirectEntry']
+14 -9
View File
@@ -1,4 +1,17 @@
"""Undocumented Module"""
"""A DirectFrame is a basic DirectGUI component that acts as the base
class for various other components, and can also serve as a basic
container to hold other DirectGUI components.
A DirectFrame can have:
* A background texture (pass in path to image, or Texture Card)
* A midground geometry item (pass in geometry)
* A foreground text Node (pass in text string or OnscreenText)
Each of these has 1 or more states. The same object can be used for
all states or each state can have a different text/geom/image (for
radio button and check button indicators, for example).
"""
__all__ = ['DirectFrame']
@@ -19,14 +32,6 @@ class DirectFrame(DirectGuiWidget):
DefDynGroups = ('text', 'geom', 'image')
def __init__(self, parent = None, **kw):
# Inherits from DirectGuiWidget
# A Direct Frame can have:
# - A background texture (pass in path to image, or Texture Card)
# - A midground geometry item (pass in geometry)
# - A foreground text Node (pass in text string or Onscreen Text)
# Each of these has 1 or more states
# The same object can be used for all states or each
# state can have a different text/geom/image (for radio button
# and check button indicators, for example).
optiondefs = (
# Define type of DirectGuiWidget
('pgFunc', PGItem, None),
+24 -25
View File
@@ -1,32 +1,7 @@
"""Undocumented Module"""
__all__ = ['DirectGuiBase', 'DirectGuiWidget']
from panda3d.core import *
from panda3d.direct import get_config_showbase
from . import DirectGuiGlobals as DGG
from .OnscreenText import *
from .OnscreenGeom import *
from .OnscreenImage import *
from direct.directtools.DirectUtil import ROUND_TO
from direct.showbase import DirectObject
from direct.task import Task
import sys
if sys.version_info >= (3, 0):
stringType = str
else:
stringType = basestring
guiObjectCollector = PStatCollector("Client::GuiObjects")
"""
Base class for all Direct Gui items. Handles composite widgets and
command line argument parsing.
"""
"""
Code Overview:
1 Each widget defines a set of options (optiondefs) as a list of tuples
@@ -101,7 +76,31 @@ Code Overview:
are left unused. If so, an error is raised.
"""
__all__ = ['DirectGuiBase', 'DirectGuiWidget']
from panda3d.core import *
from panda3d.direct import get_config_showbase
from . import DirectGuiGlobals as DGG
from .OnscreenText import *
from .OnscreenGeom import *
from .OnscreenImage import *
from direct.directtools.DirectUtil import ROUND_TO
from direct.showbase import DirectObject
from direct.task import Task
import sys
if sys.version_info >= (3, 0):
stringType = str
else:
stringType = basestring
guiObjectCollector = PStatCollector("Client::GuiObjects")
class DirectGuiBase(DirectObject.DirectObject):
"""Base class of all DirectGUI widgets."""
def __init__(self):
# Default id of all gui object, subclasses should override this
self.guiId = 'guiObject'
+3 -5
View File
@@ -1,12 +1,10 @@
"""Undocumented Module"""
__all__ = []
"""
Global definitions used by Direct Gui Classes and handy constants
that can be used during widget construction
"""
__all__ = []
from panda3d.core import *
defaultFont = None
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Contains the DirectLabel class."""
__all__ = ['DirectLabel']
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Implements a pop-up menu containing multiple clickable options."""
__all__ = ['DirectOptionMenu']
+4 -1
View File
@@ -1,4 +1,7 @@
"""Undocumented Module"""
"""A DirectRadioButton is a type of button that, similar to a
DirectCheckButton, has a separate indicator and can be toggled between
two states. However, only one DirectRadioButton in a group can be enabled
at a particular time."""
__all__ = ['DirectRadioButton']
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Defines the DirectScrollBar class."""
__all__ = ['DirectScrollBar']
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Contains the DirectScrolledFrame class."""
__all__ = ['DirectScrolledFrame']
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Contains the DirectScrolledList class."""
__all__ = ['DirectScrolledListItem', 'DirectScrolledList']
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Defines the DirectSlider class."""
__all__ = ['DirectSlider']
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Contains the DirectWaitBar class, a progress bar widget."""
__all__ = ['DirectWaitBar']
+16 -1
View File
@@ -35,7 +35,8 @@ class OnscreenText(NodePath):
font = None,
parent = None,
sort = 0,
mayChange = True):
mayChange = True,
direction = None):
"""
Make a text node from string, put it into the 2d sg and set it
up with all the indicated parameters.
@@ -95,6 +96,9 @@ class OnscreenText(NodePath):
mayChange: pass true if the text or its properties may need
to be changed at runtime, false if it is static once
created (which leads to better memory optimization).
direction: this can be set to 'ltr' or 'rtl' to override the
direction of the text.
"""
if parent == None:
parent = aspect2d
@@ -192,6 +196,17 @@ class OnscreenText(NodePath):
textNode.setFrameColor(frame[0], frame[1], frame[2], frame[3])
textNode.setFrameAsMargin(0.1, 0.1, 0.1, 0.1)
if direction is not None:
if isinstance(direction, str):
direction = direction.lower()
if direction == 'rtl':
direction = TextProperties.D_rtl
elif direction == 'ltr':
direction = TextProperties.D_ltr
else:
raise ValueError('invalid direction')
textNode.setDirection(direction)
# Create a transform for the text for our scale and position.
# We'd rather do it here, on the text itself, rather than on
# our NodePath, so we have one fewer transforms in the scene
+12
View File
@@ -0,0 +1,12 @@
"""
This package contains the DirectGui system, a set of classes
responsible for drawing graphical widgets to the 2-D scene graph.
It is based on the lower-level PGui system, which is implemented in
C++.
For convenience, all of the DirectGui widgets may be imported from a
single module as follows::
from direct.gui.DirectGui import *
"""
+1 -1
View File
@@ -83,7 +83,7 @@ class ActorInterval(Interval.Interval):
if startTime == None:
startTime = float(self.startFrame) / float(self.frameRate)
endTime = startTime + duration
self.endFrame = duration * self.frameRate
self.endFrame = endTime * self.frameRate
else:
# No end frame specified. Choose the maximum of all
# of the controls' numbers of frames.
+3 -1
View File
@@ -116,8 +116,9 @@ class Interval(DirectObject):
return self.currT
def start(self, startT = 0.0, endT = -1.0, playRate = 1.0):
""" Starts the interval. Returns an awaitable. """
self.setupPlay(startT, endT, playRate, 0)
self.__spawnTask()
return self.__spawnTask()
def loop(self, startT = 0.0, endT = -1.0, playRate = 1.0):
self.setupPlay(startT, endT, playRate, 1)
@@ -427,6 +428,7 @@ class Interval(DirectObject):
task = Task(self.__playTask)
task.interval = self
taskMgr.add(task, taskName)
return task
def __removeTask(self):
# Kill old task(s), including those from a similarly-named but
+4 -1
View File
@@ -1,4 +1,7 @@
"""IntervalGlobal module"""
"""
This module imports all of the other interval modules, to provide a
single convenient module from which all interval types can be imported.
"""
# In this unusual case, I'm not going to declare __all__,
# since the purpose of this module is to add up the contributions
+3 -3
View File
@@ -1,4 +1,5 @@
"""Undocumented Module"""
"""Defines the IntervalManager class as well as the global instance of
this class, ivalMgr."""
__all__ = ['IntervalManager', 'ivalMgr']
@@ -136,6 +137,5 @@ class IntervalManager(CIntervalManager):
assert self.ivals[index] == None or self.ivals[index] == interval
self.ivals[index] = interval
# The global IntervalManager object.
#: The global IntervalManager object.
ivalMgr = IntervalManager(1)
+4 -1
View File
@@ -1,4 +1,7 @@
"""Undocumented Module"""
"""
This module defines the various "meta intervals", which execute other
intervals either in parallel or in a specified sequential order.
"""
__all__ = ['MetaInterval', 'Sequence', 'Parallel', 'ParallelEndTogether', 'Track']
+2 -4
View File
@@ -1,11 +1,9 @@
"""Undocumented Module"""
__all__ = ['ParticleInterval']
"""
Contains the ParticleInterval class
"""
__all__ = ['ParticleInterval']
from panda3d.core import *
from panda3d.direct import *
from direct.directnotify.DirectNotifyGlobal import directNotify
+3 -5
View File
@@ -1,11 +1,9 @@
"""Undocumented Module"""
"""
Contains the TestInterval class
"""
__all__ = ['TestInterval']
"""
Contains the ParticleInterval class
"""
from panda3d.core import *
from panda3d.direct import *
from direct.directnotify.DirectNotifyGlobal import directNotify
+12
View File
@@ -0,0 +1,12 @@
"""
This package contains the Python implementation of the interval system,
which is a mechanism for playing back scripted actions. A range of
interval types has been defined to automate motion, animation, sounds,
color, function calls, as well as other intervals and arbitrary
properties.
All interval types can be conveniently imported from the
:mod:`.IntervalGlobal` module::
from direct.interval.IntervalGlobal import *
"""
+3 -3
View File
@@ -26,9 +26,9 @@
*/
class EXPCL_DIRECT CConstrainHprInterval : public CConstraintInterval {
PUBLISHED:
CConstrainHprInterval(const string &name, double duration,
const NodePath &node, const NodePath &target,
bool wrt, const LVecBase3 hprOffset=LVector3::zero());
explicit CConstrainHprInterval(const string &name, double duration,
const NodePath &node, const NodePath &target,
bool wrt, const LVecBase3 hprOffset=LVector3::zero());
INLINE const NodePath &get_node() const;
INLINE const NodePath &get_target() const;
@@ -26,10 +26,10 @@
*/
class EXPCL_DIRECT CConstrainPosHprInterval : public CConstraintInterval {
PUBLISHED:
CConstrainPosHprInterval(const string &name, double duration,
const NodePath &node, const NodePath &target,
bool wrt, const LVecBase3 posOffset=LVector3::zero(),
const LVecBase3 hprOffset=LVector3::zero());
explicit CConstrainPosHprInterval(const string &name, double duration,
const NodePath &node, const NodePath &target,
bool wrt, const LVecBase3 posOffset=LVector3::zero(),
const LVecBase3 hprOffset=LVector3::zero());
INLINE const NodePath &get_node() const;
INLINE const NodePath &get_target() const;
+3 -3
View File
@@ -25,9 +25,9 @@
*/
class EXPCL_DIRECT CConstrainPosInterval : public CConstraintInterval {
PUBLISHED:
CConstrainPosInterval(const string &name, double duration,
const NodePath &node, const NodePath &target,
bool wrt, const LVecBase3 posOffset=LVector3::zero());
explicit CConstrainPosInterval(const string &name, double duration,
const NodePath &node, const NodePath &target,
bool wrt, const LVecBase3 posOffset=LVector3::zero());
INLINE const NodePath &get_node() const;
INLINE const NodePath &get_target() const;
@@ -24,9 +24,9 @@
*/
class EXPCL_DIRECT CConstrainTransformInterval : public CConstraintInterval {
PUBLISHED:
CConstrainTransformInterval(const string &name, double duration,
const NodePath &node, const NodePath &target,
bool wrt);
explicit CConstrainTransformInterval(const string &name, double duration,
const NodePath &node,
const NodePath &target, bool wrt);
INLINE const NodePath &get_node() const;
INLINE const NodePath &get_target() const;
@@ -31,8 +31,8 @@
*/
class EXPCL_DIRECT CLerpAnimEffectInterval : public CLerpInterval {
PUBLISHED:
INLINE CLerpAnimEffectInterval(const string &name, double duration,
BlendType blend_type);
INLINE explicit CLerpAnimEffectInterval(const string &name, double duration,
BlendType blend_type);
INLINE void add_control(AnimControl *control, const string &name,
float begin_effect, float end_effect);
+4 -4
View File
@@ -25,10 +25,10 @@
*/
class EXPCL_DIRECT CLerpNodePathInterval : public CLerpInterval {
PUBLISHED:
CLerpNodePathInterval(const string &name, double duration,
BlendType blend_type, bool bake_in_start,
bool fluid,
const NodePath &node, const NodePath &other);
explicit CLerpNodePathInterval(const string &name, double duration,
BlendType blend_type, bool bake_in_start,
bool fluid,
const NodePath &node, const NodePath &other);
INLINE const NodePath &get_node() const;
INLINE const NodePath &get_other() const;
+1 -1
View File
@@ -31,7 +31,7 @@
*/
class EXPCL_DIRECT CMetaInterval : public CInterval {
PUBLISHED:
CMetaInterval(const string &name);
explicit CMetaInterval(const string &name);
virtual ~CMetaInterval();
enum RelativeStart {
+1 -1
View File
@@ -23,7 +23,7 @@
*/
class EXPCL_DIRECT HideInterval : public CInterval {
PUBLISHED:
HideInterval(const NodePath &node, const string &name = string());
explicit HideInterval(const NodePath &node, const string &name = string());
virtual void priv_instant();
virtual void priv_reverse_instant();
+1 -1
View File
@@ -23,7 +23,7 @@
*/
class EXPCL_DIRECT ShowInterval : public CInterval {
PUBLISHED:
ShowInterval(const NodePath &node, const string &name = string());
explicit ShowInterval(const NodePath &node, const string &name = string());
virtual void priv_instant();
virtual void priv_reverse_instant();
+1 -1
View File
@@ -23,7 +23,7 @@
*/
class EXPCL_DIRECT WaitInterval : public CInterval {
PUBLISHED:
INLINE WaitInterval(double duration);
INLINE explicit WaitInterval(double duration);
virtual void priv_step(double t);
+3
View File
@@ -0,0 +1,3 @@
"""
This package contains only the :class:`.MotionTrail` class.
"""
+5 -2
View File
@@ -1,12 +1,15 @@
"""
This module is intended to be compiled into the Panda3D runtime
distributable, to execute a packaged p3d application, but it can also
be run directly via the Python interpreter (if the current Panda3D and
Python versions match the version expected by the application). See
runp3d.py for a command-line tool to invoke this module.
The global AppRunner instance may be imported as follows::
from direct.showbase.AppRunnerGlobal import appRunner
This will be None if Panda was not run from the runtime environment.
"""
__all__ = ["AppRunner", "dummyAppRunner", "ArgumentError"]
+4
View File
@@ -0,0 +1,4 @@
"""
This package provides the Python interface to functionality relating to
the Panda3D Runtime environment.
"""
+7
View File
@@ -0,0 +1,7 @@
"""
This package contains the high-level Python interface to the particle
system.
Also see the :mod:`panda3d.physics` module, which contains the C++
implementation of the particle system.
"""
+4 -4
View File
@@ -3450,8 +3450,8 @@ paint_window_osx_port() {
int y_size = min(_wparams.get_win_height(), _swbuffer->get_y_size());
size_t rowsize = _swbuffer->get_row_size();
Rect src_rect = {0, 0, y_size, x_size};
Rect ddrc_rect = {0, 0, y_size, x_size};
Rect src_rect = {0, 0, (short)y_size, (short)x_size};
Rect ddrc_rect = {0, 0, (short)y_size, (short)x_size};
QDErr err;
@@ -3502,7 +3502,7 @@ paint_window_osx_cgcontext(CGContextRef context) {
int y_size = min(_wparams.get_win_height(), _swbuffer->get_y_size());
if (_buffer_image != NULL) {
CGRect region = { { 0, 0 }, { x_size, y_size } };
CGRect region = { { 0, 0 }, { (CGFloat)x_size, (CGFloat)y_size } };
CGContextDrawImage(context, region, _buffer_image);
}
}
@@ -3538,7 +3538,7 @@ handle_event_osx_event_record(const P3D_event_data &event) {
// First, convert the coordinates from screen coordinates to browser
// window coordinates.
WindowRef window = handle._handle._osx_cgcontext._window;
CGPoint cgpt = { pt.h, pt.v };
CGPoint cgpt = { (CGFloat)pt.h, (CGFloat)pt.v };
HIPointConvert(&cgpt, kHICoordSpaceScreenPixel, NULL,
kHICoordSpaceWindow, window);
+8 -8
View File
@@ -267,7 +267,7 @@ refresh() {
return;
}
if (_toplevel_window != NULL) {
Rect r = { 0, 0, _win_height, _win_width };
Rect r = { 0, 0, (short)_win_height, (short)_win_width };
InvalWindowRect(_toplevel_window, &r);
} else {
@@ -345,7 +345,7 @@ paint_window_osx_cgcontext(CGContextRef context) {
CGColorSpaceRef rgb_space = CGColorSpaceCreateDeviceRGB();
CGColorRef bg = CGColorCreate(rgb_space, bg_components);
CGRect region = { { 0, 0 }, { _win_width, _win_height } };
CGRect region = { { 0, 0 }, { (CGFloat)_win_width, (CGFloat)_win_height } };
CGContextSetFillColorWithColor(context, bg);
CGContextFillRect(context, region);
@@ -407,7 +407,7 @@ handle_event_osx_event_record(const P3D_event_data &event) {
// First, convert the coordinates from screen coordinates to browser
// window coordinates.
WindowRef window = handle._handle._osx_cgcontext._window;
CGPoint cgpt = { pt.h, pt.v };
CGPoint cgpt = { (CGFloat)pt.h, (CGFloat)pt.v };
HIPointConvert(&cgpt, kHICoordSpaceScreenPixel, NULL,
kHICoordSpaceWindow, window);
@@ -617,7 +617,7 @@ paint_progress_bar(CGContextRef context) {
int bar_x, bar_y, bar_width, bar_height;
get_bar_placement(bar_x, bar_y, bar_width, bar_height);
CGRect bar_rect = { { bar_x, bar_y }, { bar_width, bar_height } };
CGRect bar_rect = { { (CGFloat)bar_x, (CGFloat)bar_y }, { (CGFloat)bar_width, (CGFloat)bar_height } };
// Clear the entire progress bar to white (or the background color).
CGContextSetFillColorWithColor(context, bar_bg);
@@ -627,7 +627,7 @@ paint_progress_bar(CGContextRef context) {
if (_progress_known) {
int progress_width = (int)(bar_width * _install_progress + 0.5);
if (progress_width != 0) {
CGRect prog = { { bar_x, bar_y }, { progress_width, bar_height } };
CGRect prog = { { (CGFloat)bar_x, (CGFloat)bar_y }, { (CGFloat)progress_width, (CGFloat)bar_height } };
CGContextSetFillColorWithColor(context, bar);
CGContextFillRect(context, prog);
}
@@ -642,7 +642,7 @@ paint_progress_bar(CGContextRef context) {
progress = block_travel * 2 - progress;
}
CGRect prog = { { bar_x + progress, bar_y }, { block_width, bar_height } };
CGRect prog = { { (CGFloat)(bar_x + progress), (CGFloat)bar_y }, { (CGFloat)block_width, (CGFloat)bar_height } };
CGContextSetFillColorWithColor(context, bar);
CGContextFillRect(context, prog);
}
@@ -652,8 +652,8 @@ paint_progress_bar(CGContextRef context) {
// We offset the border by half a pixel, so we'll be drawing the one-pixel
// line through the middle of a pixel, and it won't try to antialias
// itself into a half-black two-pixel line.
CGRect border_rect = { { bar_x - 0.5, bar_y - 0.5 },
{ bar_width + 1, bar_height + 1 } };
CGRect border_rect = { { (CGFloat)(bar_x - 0.5), (CGFloat)(bar_y - 0.5) },
{ (CGFloat)(bar_width + 1), (CGFloat)(bar_height + 1) } };
CGContextBeginPath(context);
CGContextSetLineWidth(context, 1);
+2
View File
@@ -6,4 +6,6 @@ This is needed for apps that start themselves by importing
DirectStart; it provides a place for these apps to look for
the AppRunner at startup. """
#: Contains the global AppRunner instance, or None if this application
#: was not run from the runtime environment.
appRunner = None
+25 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Contains the Audio3DManager class."""
__all__ = ['Audio3DManager']
@@ -289,3 +289,27 @@ class Audio3DManager:
for sound in self.sound_dict[object]:
self.detachSound(sound)
#snake_case alias:
get_doppler_factor = getDopplerFactor
set_listener_velocity_auto = setListenerVelocityAuto
attach_listener = attachListener
set_distance_factor = setDistanceFactor
attach_sound_to_object = attachSoundToObject
get_drop_off_factor = getDropOffFactor
set_doppler_factor = setDopplerFactor
get_sounds_on_object = getSoundsOnObject
set_sound_velocity_auto = setSoundVelocityAuto
get_sound_max_distance = getSoundMaxDistance
load_sfx = loadSfx
get_distance_factor = getDistanceFactor
set_listener_velocity = setListenerVelocity
set_sound_max_distance = setSoundMaxDistance
get_sound_velocity = getSoundVelocity
get_listener_velocity = getListenerVelocity
set_sound_velocity = setSoundVelocity
set_sound_min_distance = setSoundMinDistance
get_sound_min_distance = getSoundMinDistance
detach_listener = detachListener
set_drop_off_factor = setDropOffFactor
detach_sound = detachSound
+3 -1
View File
@@ -1,4 +1,6 @@
"""Undocumented Module"""
"""Contains the BufferViewer class, which is used as a debugging aid
when debugging render-to-texture effects. It shows different views at
the bottom of the screen showing the various render targets."""
__all__ = ['BufferViewer']
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Contains the BulletinBoard class."""
__all__ = ['BulletinBoard']
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Contains the BulletinBoardWatcher class."""
__all__ = ['BulletinBoardWatcher']
+14 -1
View File
@@ -1,4 +1,5 @@
"""Undocumented Module"""
"""Defines the DirectObject class, a convenient class to inherit from if the
object needs to be able to respond to events."""
__all__ = ['DirectObject']
@@ -100,3 +101,15 @@ class DirectObject:
func = choice(getRepository()._crashOnProactiveLeakDetect,
self.notify.error, self.notify.warning)
func('destroyed %s instance is still %s%s' % (self.__class__.__name__, estr, tstr))
#snake_case alias:
add_task = addTask
do_method_later = doMethodLater
detect_leaks = detectLeaks
accept_once = acceptOnce
ignore_all = ignoreAll
get_all_accepting = getAllAccepting
is_ignoring = isIgnoring
remove_all_tasks = removeAllTasks
remove_task = removeTask
is_accepting = isAccepting
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""This module defines the EventGroup class."""
__all__ = ['EventGroup']
+2 -1
View File
@@ -1,4 +1,5 @@
"""Undocumented Module"""
"""Contains the EventManager class. See :mod:`.EventManagerGlobal` for the
global eventMgr instance."""
__all__ = ['EventManager']
+2 -1
View File
@@ -1,7 +1,8 @@
"""Undocumented Module"""
"""Contains the global :class:`.EventManager` instance."""
__all__ = ['eventMgr']
from . import EventManager
#: The global event manager.
eventMgr = EventManager.EventManager()
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Contains the Factory class."""
__all__ = ['Factory']
+2 -4
View File
@@ -1,7 +1,3 @@
"""Undocumented Module"""
__all__ = ['deCygwinify', 'getPaths']
"""This module is used only by the VR Studio programmers who are using
the ctattach tools. It is imported before any other package, and its
job is to figure out the correct paths to each of the packages.
@@ -10,6 +6,8 @@ This module is not needed if you are not using ctattach; in this case
all of the Panda packages will be collected under a common directory,
which you will presumably have already on your PYTHONPATH. """
__all__ = ['deCygwinify', 'getPaths']
import os
import sys
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Contains various utility functions."""
__all__ = ['findClass', 'rebindClass', 'copyFuncs', 'replaceMessengerFunc', 'replaceTaskMgrFunc', 'replaceStateFunc', 'replaceCRFunc', 'replaceAIRFunc', 'replaceIvalFunc']
+1 -1
View File
@@ -1,4 +1,4 @@
"""Undocumented Module"""
"""Contains utility classes for debugging memory leaks."""
__all__ = ['FakeObject', '_createGarbage', 'GarbageReport', 'GarbageLogger']

Some files were not shown because too many files have changed in this diff Show More