Merge branch 'master' into astron-master

# Conflicts:
#	direct/src/dcparser/dcClass.cxx
#	direct/src/dcparser/dcClass.h
#	direct/src/distributed/ClientRepositoryBase.py
#	direct/src/distributed/ConnectionRepository.py
#	direct/src/distributed/DistributedNodeUD.py
#	direct/src/distributed/DistributedObjectAI.py
#	direct/src/distributed/DistributedObjectBase.py
#	direct/src/distributed/DistributedObjectUD.py
#	direct/src/distributed/DoInterestManager.py
#	direct/src/distributed/MsgTypes.py
#	direct/src/distributed/PyDatagram.py
#	direct/src/distributed/cDistributedSmoothNodeBase.cxx
This commit is contained in:
Sam Edwards 2016-06-27 00:25:36 -07:00
commit 18e75e2917
6088 changed files with 306714 additions and 385237 deletions

View File

@ -1,10 +1,34 @@
language: cpp
compiler:
- gcc
- clang
before_script:
- sudo apt-get install python-dev libpng-dev zlib1g-dev libssl-dev libx11-dev libgl1-mesa-dev libxrandr-dev libxxf86dga-dev libxcursor-dev bison flex libfreetype6-dev libvorbis-dev libjpeg-dev libopenal-dev libode-dev nvidia-cg-toolkit
script: python makepanda/makepanda.py --everything --verbose --git-commit $TRAVIS_COMMIT --installer --threads 2
sudo: false
matrix:
include:
- compiler: gcc
env: PYTHONV=python2.7 FLAGS=
- compiler: clang
env: PYTHONV=python3 FLAGS=--installer
- compiler: clang
env: PYTHONV=python2.7 FLAGS=--override=STDFLOAT_DOUBLE=1
addons:
apt:
packages:
- bison
- flex
- libfreetype6-dev
- libgl1-mesa-dev
- libjpeg-dev
- libode-dev
- libopenal-dev
- libpng-dev
- libssl-dev
- libvorbis-dev
- libx11-dev
- libxcursor-dev
- libxrandr-dev
- nvidia-cg-toolkit
- python-dev
- python3-dev
- 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
notifications:
irc:
channels:

View File

@ -31,8 +31,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.0/panda3d-1.9.0-tools-win32.zip
https://www.panda3d.org/download/panda3d-1.9.0/panda3d-1.9.0-tools-win64.zip
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
After acquiring these dependencies, you may simply build Panda3D from the
command prompt using the following command:
@ -97,11 +97,7 @@ Mac OS X
--------
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.0/panda3d-1.9.0-tools-mac.tar.gz).
In order to build the installer on Mac OS X you will need to install PackageMaker.
This can be obtained from the "Auxiliary Tools for Xcode" which can be downloaded
from Apple [here](https://developer.apple.com/downloads/).
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).
After placing the thirdparty directory inside the panda3d source directory,
you may build Panda3D using a command like the following:

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : aiBehaviors.cxx
// Created by : Deepak, John, Navin
// Date : 8 Sep 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file aiBehaviors.cxx
* @author Deepak, John, Navin
* @date 2009-09-08
*/
#include "aiBehaviors.h"
@ -48,15 +46,11 @@ AIBehaviors::~AIBehaviors() {
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : is_conflict
// Description : Checks for conflict between steering forces.
// If there is a conflict it returns 'true' and sets _conflict to 'true'.
// If there is no conflict it returns 'false' and sets _conflict to 'false'.
/////////////////////////////////////////////////////////////////////////////////
/**
* Checks for conflict between steering forces. If there is a conflict it
* returns 'true' and sets _conflict to 'true'. If there is no conflict it
* returns 'false' and sets _conflict to 'false'.
*/
bool AIBehaviors::is_conflict() {
int value = int(is_on(_seek)) + int(is_on(_flee)) + int(is_on(_pursue)) + int(is_on(_evade)) + int(is_on(_wander)) + int(is_on(_flock))+ int(is_on(_obstacle_avoidance));
@ -102,14 +96,11 @@ bool AIBehaviors::is_conflict() {
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : accumulate_force
// Description : This function updates the individual steering forces for each of the ai characters.
// These accumulated forces are eventually what comprise the resultant
// steering force of the character.
/////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* This function updates the individual steering forces for each of the ai
* characters. These accumulated forces are eventually what comprise the
* resultant steering force of the character.
*/
void AIBehaviors::accumulate_force(string force_type, LVecBase3 force) {
@ -159,15 +150,12 @@ void AIBehaviors::accumulate_force(string force_type, LVecBase3 force) {
}
//////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : calculate_prioritized
// Description : This function updates the main steering force for the ai character using
// the accumulate function and checks for max force and arrival force.
// It finally returns this steering force which is accessed by the update
// function in the AICharacter class.
//////////////////////////////////////////////////////////////////////////////////////////////
/**
* This function updates the main steering force for the ai character using
* the accumulate function and checks for max force and arrival force. It
* finally returns this steering force which is accessed by the update
* function in the AICharacter class.
*/
LVecBase3 AIBehaviors::calculate_prioritized() {
LVecBase3 force;
@ -313,14 +301,9 @@ LVecBase3 AIBehaviors::calculate_prioritized() {
return _steering_force;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : remove_ai
// Description : This function removes individual or all the AIs.
/////////////////////////////////////////////////////////////////////////////////
//add for path follow
/**
* This function removes individual or all the AIs.
*/
void AIBehaviors::remove_ai(string ai_type) {
switch(char_to_int(ai_type)) {
case 0: {
@ -434,14 +417,9 @@ void AIBehaviors::remove_ai(string ai_type) {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : pause_ai
// Description : This function pauses individual or all the AIs.
/////////////////////////////////////////////////////////////////////////////////
//add for path follow
/**
* This function pauses individual or all the AIs.
*/
void AIBehaviors::pause_ai(string ai_type) {
switch(char_to_int(ai_type)) {
case 0: {
@ -537,13 +515,9 @@ void AIBehaviors::pause_ai(string ai_type) {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : resume_ai
// Description : This function resumes individual or all the AIs
/////////////////////////////////////////////////////////////////////////////////
/**
* This function resumes individual or all the AIs
*/
void AIBehaviors::resume_ai(string ai_type) {
switch(char_to_int(ai_type)) {
case 0: {
@ -634,15 +608,11 @@ void AIBehaviors::resume_ai(string ai_type) {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : seek
// Description : This function activates seek and makes an object of the Seek class.
// This is the function we want the user to call for seek to be done.
// This function is overloaded to accept a NodePath or an LVecBase3.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function activates seek and makes an object of the Seek class. This
* is the function we want the user to call for seek to be done. This
* function is overloaded to accept a NodePath or an LVecBase3.
*/
void AIBehaviors::seek(NodePath target_object, float seek_wt) {
_seek_obj = new Seek(_ai_char, target_object, seek_wt);
turn_on("seek");
@ -653,14 +623,10 @@ void AIBehaviors::seek(LVecBase3 pos, float seek_wt) {
turn_on("seek");
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : flee
// Description : This function activates flee_activate and creates an object of the Flee class.
// This function is overloaded to accept a NodePath or an LVecBase3.
//////////////////////////////////////////////////////////////////////////////////////////////////
/**
* This function activates flee_activate and creates an object of the Flee
* class. This function is overloaded to accept a NodePath or an LVecBase3.
*/
void AIBehaviors::flee(NodePath target_object, double panic_distance, double relax_distance, float flee_wt) {
_flee_obj = new Flee(_ai_char, target_object, panic_distance, relax_distance, flee_wt);
_flee_list.insert(_flee_list.end(), *_flee_obj);
@ -675,27 +641,19 @@ void AIBehaviors::flee(LVecBase3 pos, double panic_distance, double relax_distan
turn_on("flee_activate");
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : pursue
// Description : This function activates pursue.
// This is the function we want the user to call for pursue to be done.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function activates pursue. This is the function we want the user to
* call for pursue to be done.
*/
void AIBehaviors::pursue(NodePath target_object, float pursue_wt) {
_pursue_obj = new Pursue(_ai_char, target_object, pursue_wt);
turn_on("pursue");
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : evade
// Description : This function activates evade_activate.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function activates evade_activate.
*/
void AIBehaviors::evade(NodePath target_object, double panic_distance, double relax_distance, float evade_wt) {
_evade_obj = new Evade(_ai_char, target_object, panic_distance, relax_distance, evade_wt);
_evade_list.insert(_evade_list.end(), *_evade_obj);
@ -703,14 +661,10 @@ void AIBehaviors::evade(NodePath target_object, double panic_distance, double re
turn_on("evade_activate");
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : arrival
// Description : This function activates arrival.
// This is the function we want the user to call for arrival to be done.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function activates arrival. This is the function we want the user to
* call for arrival to be done.
*/
void AIBehaviors::arrival(double distance) {
if(_pursue_obj) {
_arrival_obj = new Arrival(_ai_char, distance);
@ -727,14 +681,10 @@ void AIBehaviors::arrival(double distance) {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : flock
// Description : This function activates flock.
// This is the function we want the user to call for flock to be done.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function activates flock. This is the function we want the user to
* call for flock to be done.
*/
void AIBehaviors::flock(float flock_wt) {
_flock_weight = flock_wt;
@ -742,14 +692,10 @@ void AIBehaviors::flock(float flock_wt) {
turn_on("flock_activate");
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : flock_activate
// Description : This function checks whether any other behavior exists to work with flock.
// When this is true, it calls the do_flock function.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function checks whether any other behavior exists to work with flock.
* When this is true, it calls the do_flock function.
*/
void AIBehaviors::flock_activate() {
if(is_on(_seek) || is_on(_flee) || is_on(_pursue) || is_on(_evade) || is_on(_wander)) {
turn_off("flock_activate");
@ -757,21 +703,17 @@ void AIBehaviors::flock_activate() {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : do_flock
// Description : This function contains the logic for flocking behavior. This is
// an emergent behavior and is obtained by combining three other
// behaviors which are separation, cohesion and alignment based on
// Craig Reynold's algorithm. Also, this behavior does not work by
// itself. It works only when combined with other steering behaviors
// such as wander, pursue, evade, seek and flee.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function contains the logic for flocking behavior. This is an
* emergent behavior and is obtained by combining three other behaviors which
* are separation, cohesion and alignment based on Craig Reynold's algorithm.
* Also, this behavior does not work by itself. It works only when combined
* with other steering behaviors such as wander, pursue, evade, seek and flee.
*/
LVecBase3 AIBehaviors::do_flock() {
//! Initialize variables required to compute the flocking force on the ai char.
// ! Initialize variables required to compute the flocking force on the ai
// char.
unsigned int neighbor_count = 0;
LVecBase3 separation_force = LVecBase3(0.0, 0.0, 0.0);
LVecBase3 alignment_force = LVecBase3(0.0, 0.0, 0.0);
@ -781,38 +723,40 @@ LVecBase3 AIBehaviors::do_flock() {
LVecBase3 avg_center_of_mass = LVecBase3(0.0, 0.0, 0.0);
LVecBase3 total_center_of_mass = LVecBase3(0.0, 0.0, 0.0);
//! Loop through all the other AI units in the flock to check if they are neigbours.
// ! Loop through all the other AI units in the flock to check if they are
// neigbours.
for(unsigned int i = 0; i < _flock_group->_ai_char_list.size(); i++) {
if(_flock_group->_ai_char_list[i]->_name != _ai_char->_name) {
//! Using visibilty cone to detect neighbors.
// ! Using visibilty cone to detect neighbors.
LVecBase3 dist_vect = _flock_group->_ai_char_list[i]->_ai_char_np.get_pos() - _ai_char->_ai_char_np.get_pos();
LVecBase3 ai_char_heading = _ai_char->get_velocity();
ai_char_heading.normalize();
//! Check if the current unit is a neighbor.
// ! Check if the current unit is a neighbor.
if(dist_vect.dot(ai_char_heading) > ((dist_vect.length()) * (ai_char_heading.length()) * cos(_flock_group->_flock_vcone_angle * (_PI / 180)))
&& (dist_vect.length() < _flock_group->_flock_vcone_radius)) {
//! Separation force calculation.
// ! Separation force calculation.
LVecBase3 ai_char_to_units = _ai_char->_ai_char_np.get_pos() - _flock_group->_ai_char_list[i]->_ai_char_np.get_pos();
float to_units_dist = ai_char_to_units.length();
ai_char_to_units.normalize();
separation_force += (ai_char_to_units / to_units_dist);
//! Calculating the total heading and center of mass of all the neighbors.
// ! Calculating the total heading and center of mass of all the
// neighbors.
LVecBase3 neighbor_heading = _flock_group->_ai_char_list[i]->get_velocity();
neighbor_heading.normalize();
total_neighbor_heading += neighbor_heading;
total_center_of_mass += _flock_group->_ai_char_list[i]->_ai_char_np.get_pos();
//! Update the neighbor count.
// ! Update the neighbor count.
++neighbor_count;
}
}
}
if(neighbor_count > 0) {
//! Alignment force calculation
// ! Alignment force calculation
avg_neighbor_heading = total_neighbor_heading / neighbor_count;
LVector3 ai_char_heading = _ai_char->get_velocity();
ai_char_heading.normalize();
@ -820,7 +764,7 @@ LVecBase3 AIBehaviors::do_flock() {
avg_neighbor_heading.normalize();
alignment_force = avg_neighbor_heading;
//! Cohesion force calculation
// ! Cohesion force calculation
avg_center_of_mass = total_center_of_mass / neighbor_count;
LVecBase3 cohesion_dir = avg_center_of_mass - _ai_char->_ai_char_np.get_pos();
cohesion_dir.normalize();
@ -833,147 +777,105 @@ LVecBase3 AIBehaviors::do_flock() {
return(LVecBase3(0.0, 0.0, 0.0));
}
//! Calculate the resultant force on the ai character by taking into account the separation, alignment and cohesion
//! forces along with their corresponding weights.
// ! Calculate the resultant force on the ai character by taking into
// account the separation, alignment and cohesion ! forces along with their
// corresponding weights.
return (separation_force * _flock_group->_separation_wt + avg_neighbor_heading * _flock_group->_alignment_wt
+ cohesion_force * _flock_group->_cohesion_wt);
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : wander
// Description : This function activates wander.
// This is the function we want the user to call for flock to be done.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function activates wander. This is the function we want the user to
* call for flock to be done.
*/
void AIBehaviors::wander(double wander_radius, int flag, double aoe, float wander_weight) {
_wander_obj = new Wander(_ai_char, wander_radius, flag, aoe, wander_weight);
turn_on("wander");
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : obstacle avoidance
// Description : This function activates obstacle avoidance for a given character.
// This is the function we want the user to call for
// obstacle avoidance to be performed.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function activates obstacle avoidance for a given character. This is
* the function we want the user to call for obstacle avoidance to be
* performed.
*/
void AIBehaviors::obstacle_avoidance(float obstacle_avoidance_weight) {
_obstacle_avoidance_obj = new ObstacleAvoidance(_ai_char, obstacle_avoidance_weight);
turn_on("obstacle_avoidance_activate");
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : path_follow
// Description : This function activates path following.
// This is the function we want the user to call for path following.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function activates path following. This is the function we want the
* user to call for path following.
*/
void AIBehaviors::path_follow(float follow_wt) {
_path_follow_obj = new PathFollow(_ai_char, follow_wt);
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : add_to_path
// Description : This function adds positions to the path to follow.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function adds positions to the path to follow.
*/
void AIBehaviors::add_to_path(LVecBase3 pos) {
_path_follow_obj->add_to_path(pos);
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : start_follow
// Description : This function starts the path follower.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function starts the path follower.
*/
void AIBehaviors::start_follow(string type) {
_path_follow_obj->start(type);
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : init_path_find
// Description : This function activates path finding in the character.
// This function accepts the meshdata in .csv format.
//
/////////////////////////////////////////////////////////////////////////////////
/**
* This function activates path finding in the character. This function
* accepts the meshdata in .csv format.
*
*/
void AIBehaviors::init_path_find(const char* navmesh_filename) {
_path_find_obj = new PathFind(_ai_char);
_path_find_obj->set_path_find(navmesh_filename);
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : path_find_to (for pathfinding towards a static position)
// Description : This function checks for the source and target in the navigation mesh
// for its availability and then finds the best path via the A* algorithm
// Then it calls the path follower to make the object follow the path.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function checks for the source and target in the navigation mesh for
* its availability and then finds the best path via the A* algorithm Then it
* calls the path follower to make the object follow the path.
*/
void AIBehaviors::path_find_to(LVecBase3 pos, string type) {
_path_find_obj->path_find(pos, type);
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : path_find_to (for pathfinding towards a moving target (a NodePath))
// Description : This function checks for the source and target in the navigation mesh
// for its availability and then finds the best path via the A* algorithm
// Then it calls the path follower to make the object follow the path.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function checks for the source and target in the navigation mesh for
* its availability and then finds the best path via the A* algorithm Then it
* calls the path follower to make the object follow the path.
*/
void AIBehaviors::path_find_to(NodePath target, string type) {
_path_find_obj->path_find(target, type);
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : add_static_obstacle
// Description : This function allows the user to dynamically add obstacles to the
// game environment. The function will update the nodes within the
// bounding volume of the obstacle as non-traversable. Hence will not be
// considered by the pathfinding algorithm.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function allows the user to dynamically add obstacles to the game
* environment. The function will update the nodes within the bounding volume
* of the obstacle as non-traversable. Hence will not be considered by the
* pathfinding algorithm.
*/
void AIBehaviors::add_static_obstacle(NodePath obstacle) {
_path_find_obj->add_obstacle_to_mesh(obstacle);
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : add_dynamic_obstacle
// Description : This function starts the pathfinding obstacle navigation for the
// passed in obstacle.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function starts the pathfinding obstacle navigation for the passed in
* obstacle.
*/
void AIBehaviors::add_dynamic_obstacle(NodePath obstacle) {
_path_find_obj->dynamic_avoid(obstacle);
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : behavior_status
// Description : This function returns the status of an AI Type whether it is active,
// paused or disabled. It returns -1 if an invalid string is passed.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function returns the status of an AI Type whether it is active, paused
* or disabled. It returns -1 if an invalid string is passed.
*/
string AIBehaviors::behavior_status(string ai_type) {
switch(char_to_int(ai_type)) {
case 1:
@ -1184,17 +1086,14 @@ string AIBehaviors::behavior_status(string ai_type) {
default:
cout<<"Invalid value!"<<endl;
return "invalid";
}
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : char_to_int
// Description : This function is used to derive int values from the ai types strings.
// Returns -1 if an invalid string is passed.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function is used to derive int values from the ai types strings.
* Returns -1 if an invalid string is passed.
*/
int AIBehaviors::char_to_int(string ai_type) {
if(ai_type == "all") {
return 0;
@ -1251,13 +1150,9 @@ int AIBehaviors::char_to_int(string ai_type) {
return -1;
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : turn_on
// Description : This function turns on any aiBehavior which is passed as a string.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function turns on any aiBehavior which is passed as a string.
*/
void AIBehaviors::turn_on(string ai_type) {
switch(char_to_int(ai_type)) {
case 1: {
@ -1317,13 +1212,9 @@ void AIBehaviors::turn_on(string ai_type) {
}
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : turn_off
// Description : This function turns off any aiBehavior which is passed as a string.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function turns off any aiBehavior which is passed as a string.
*/
void AIBehaviors::turn_off(string ai_type) {
switch(char_to_int(ai_type)) {
case 1: {
@ -1425,24 +1316,16 @@ switch(char_to_int(ai_type)) {
}
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : is_on
// Description : This function returns true if an aiBehavior is on
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function returns true if an aiBehavior is on
*/
bool AIBehaviors::is_on(_behavior_type bt) {
return (_behaviors_flags & bt) == bt;
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : is_on
// Description : This function returns true if pathfollow or pathfinding is on
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function returns true if pathfollow or pathfinding is on
*/
bool AIBehaviors::is_on(string ai_type) {
if(ai_type == "pathfollow") {
if(_path_follow_obj) {
@ -1465,24 +1348,16 @@ bool AIBehaviors::is_on(string ai_type) {
return false;
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : is_off
// Description : This function returns true if an aiBehavior is off
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function returns true if an aiBehavior is off
*/
bool AIBehaviors::is_off(_behavior_type bt) {
return ((_behaviors_flags | bt) == bt);
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : is_off
// Description : This function returns true if pathfollow or pathfinding is off
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function returns true if pathfollow or pathfinding is off
*/
bool AIBehaviors::is_off(string ai_type) {
if(ai_type == "pathfollow") {
if(_path_follow_obj && _path_follow_obj->_start) {

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : aiBehaviors.cxx
// Created by : Deepak, John, Navin
// Date : 8 Sep 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file aiBehaviors.h
* @author Deepak, John, Navin
* @date 2009-09-08
*/
#pragma warning (disable:4996)
#pragma warning (disable:4005)
@ -22,18 +20,6 @@
#include "aiGlobals.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Class : AIBehaviors
// Description : This class implements all the steering behaviors of the AI framework, such as
// seek, flee, pursue, evade, wander and flock. Each steering behavior has a weight which is used when more than
// one type of steering behavior is acting on the same ai character. The weight decides the contribution of each
// type of steering behavior. The AICharacter class has a handle to an object of this class and this allows to
// invoke the steering behaviors via the AICharacter. This class also provides functionality such as pausing, resuming
// and removing the AI behaviors of an AI character at anytime.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class AICharacter;
class Seek;
class Flee;
@ -49,8 +35,17 @@ class ObstacleAvoidance;
typedef list<Flee, allocator<Flee> > ListFlee;
typedef list<Evade, allocator<Evade> > ListEvade;
/**
* This class implements all the steering behaviors of the AI framework, such
* as seek, flee, pursue, evade, wander and flock. Each steering behavior has
* a weight which is used when more than one type of steering behavior is
* acting on the same ai character. The weight decides the contribution of
* each type of steering behavior. The AICharacter class has a handle to an
* object of this class and this allows to invoke the steering behaviors via
* the AICharacter. This class also provides functionality such as pausing,
* resuming and removing the AI behaviors of an AI character at anytime.
*/
class EXPCL_PANDAAI AIBehaviors {
public:
enum _behavior_type {
_none = 0x00000,
@ -81,7 +76,8 @@ public:
Flee *_flee_obj;
LVecBase3 _flee_force;
//! This list is used if the ai character needs to flee from multiple onjects.
// ! This list is used if the ai character needs to flee from multiple
// onjects.
ListFlee _flee_list;
ListFlee::iterator _flee_itr;
@ -91,14 +87,16 @@ public:
Evade *_evade_obj;
LVecBase3 _evade_force;
//! This list is used if the ai character needs to evade from multiple onjects.
// ! This list is used if the ai character needs to evade from multiple
// onjects.
ListEvade _evade_list;
ListEvade::iterator _evade_itr;
Arrival *_arrival_obj;
LVecBase3 _arrival_force;
//! Since Flock is a collective behavior the variables are declared within the AIBehaviors class.
// ! Since Flock is a collective behavior the variables are declared within
// the AIBehaviors class.
float _flock_weight;
LVecBase3 _flock_force;
bool _flock_done;
@ -164,7 +162,7 @@ PUBLISHED:
void path_find_to(NodePath target, string type = "normal");
void add_static_obstacle(NodePath obstacle);
void add_dynamic_obstacle(NodePath obstacle);
//
void remove_ai(string ai_type);
void pause_ai(string ai_type);
@ -174,14 +172,3 @@ PUBLISHED:
};
#endif

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : aiCharacter.cxx
// Created by : Deepak, John, Navin
// Date : 8 Sep 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file aiCharacter.cxx
* @author Deepak, John, Navin
* @date 2009-09-08
*/
#include "aiCharacter.h"
@ -35,14 +33,11 @@ AICharacter::AICharacter(string model_name, NodePath model_np, double mass, doub
AICharacter::~AICharacter() {
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : update
// Description : Each character's update will update its ai and physics
// based on his resultant steering force.
// This also makes the character look at the direction of the force.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* Each character's update will update its AI and physics based on his
* resultant steering force. This also makes the character look in the
* direction of the force.
*/
void AICharacter::
update() {
if (!_steering->is_off(_steering->_none)) {

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : aiCharacter.h
// Created by : Deepak, John, Navin
// Date : 8 Sep 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file aiCharacter.h
* @author Deepak, John, Navin
* @date 2009-09-08
*/
#pragma warning (disable:4996)
#pragma warning (disable:4005)
@ -23,15 +21,12 @@
#include "aiBehaviors.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Class : AICharacter
// Description : This class is used for creating the ai characters. It assigns both physics and ai
// attributes to the character. It also has an update function which updates the physics and ai
// of the character. This update function is called by the AIWorld update.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* This class is used for creating the AI characters. It assigns both physics
* and AI attributes to the character. It also has an update function which
* updates the physics and AI of the character. This update function is
* called by the AIWorld update.
*/
class AIBehaviors;
class AIWorld;

View File

@ -1,18 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : aiGlobals.h
// Created by : Deepak, John, Navin
// Date: 8 Sep 09
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file aiGlobals.h
* @author Deepak, John, Navin
* @date 2009-09-08
*/
#pragma warning (disable:4996)
#pragma warning (disable:4005)

View File

@ -1,16 +1,15 @@
// Filename: aiNode.cxx
// Created by: Deepak, John, Navin (19Nov2009)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file aiNode.cxx
* @author Deepak, John, Navin
* @date 2009-11-19
*/
#include "aiNode.h"
@ -37,11 +36,10 @@ AINode::AINode(int grid_x, int grid_y, LVecBase3 pos, float w, float l, float h)
AINode::~AINode() {
}
////////////////////////////////////////////////////////////////////
// Function: contains
// Description: This is a handy function which returns true if the
// passed position is within the node's dimensions.
////////////////////////////////////////////////////////////////////
/**
* This is a handy function which returns true if the passed position is
* within the node's dimensions.
*/
bool AINode::contains(float x, float y) {
if (_position.get_x() - _width / 2 <= x && _position.get_x() + _width / 2 >= x &&
_position.get_y() - _length / 2 <= y && _position.get_y() + _length / 2 >= y) {

View File

@ -1,40 +1,33 @@
// Filename: aiNode.h
// Created by: Deepak, John, Navin (18Nov2009)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file aiNode.h
* @author Deepak, John, Navin
* @date 2009-11-18
*/
#ifndef AINODE_H
#define AINODE_H
#include "aiGlobals.h"
////////////////////////////////////////////////////////////////////
// Class : AINode
// Description : This class is used to assign the nodes on the mesh.
// It holds all the data necessary to compute A*
// algorithm. It also maintains a lot of vital
// information such as the neighbor nodes of each
// node and also its position on the mesh.
// Note: The Mesh Generator which is a standalone
// tool makes use of this class to generate the nodes
// on the mesh.
////////////////////////////////////////////////////////////////////
/**
* This class is used to assign the nodes on the mesh. It holds all the data
* necessary to compute A* algorithm. It also maintains a lot of vital
* information such as the neighbor nodes of each node and also its position
* on the mesh. Note: The Mesh Generator which is a standalone tool makes use
* of this class to generate the nodes on the mesh.
*/
class EXPCL_PANDAAI AINode {
public:
// This variable specifies the node status whether open, close
// or neutral.
// open = belongs to _open_list.
// close = belongs to _closed_list.
// neutral = unexamined node.
// This variable specifies the node status whether open, close or neutral.
// open = belongs to _open_list. close = belongs to _closed_list. neutral
// = unexamined node.
enum Status {
ST_open,
ST_close,
@ -42,15 +35,13 @@ public:
};
Status _status;
// This variable specifies whether the node is an obtacle or not.
// Used for dynamic obstacle addition to the environment.
// obstacle = false
// This variable specifies whether the node is an obtacle or not. Used for
// dynamic obstacle addition to the environment. obstacle = false
// navigational = true
bool _type;
// The score is used to compute the traversal expense to nodes
// when using A*.
// _score = _cost + heuristic
// The score is used to compute the traversal expense to nodes when using
// A*. _score = _cost + heuristic
int _score;
int _cost;
int _heuristic;
@ -64,16 +55,14 @@ public:
// Position of the node in 3D space.
LVecBase3 _position;
// Dimensions of each face / cell on the mesh.
// Height is given in case of expansion to a 3d mesh. Currently
// not used.
// Dimensions of each face cell on the mesh. Height is given in case of
// expansion to a 3d mesh. Currently not used.
float _width, _length ,_height;
AINode *_neighbours[8]; // anti-clockwise from top left corner.
// The _next pointer is used for traversal during mesh
// generation from the model.
// Note: The data in this member is discarded when mesh data
// is written into navmesh.csv file.
// The _next pointer is used for traversal during mesh generation from the
// model. Note: The data in this member is discarded when mesh data is
// written into navmesh.csv file.
AINode *_next;
PUBLISHED:

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : aiPathFinder.cxx
// Created by : Deepak, John, Navin
// Date : 10 Nov 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file aiPathFinder.cxx
* @author Deepak, John, Navin
* @date 2009-11-10
*/
#include "aiPathFinder.h"
@ -22,20 +20,17 @@ PathFinder::PathFinder(NavMesh nav_mesh) {
PathFinder::~PathFinder() {
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : find_path
// Description : This function initializes the pathfinding process by accepting the
// source and destination nodes. It then calls the generate_path().
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function initializes the pathfinding process by accepting the source
* and destination nodes. It then calls the generate_path().
*/
void PathFinder::find_path(Node *src_node, Node *dest_node) {
_src_node = src_node;
_dest_node = dest_node;
// Add a dummy node as the first element of the open list with score = -1.
// Inorder to implement a binary heap the index of the elements should never be 0.
// Inorder to implement a binary heap the index of the elements should never
// be 0.
Node *_dummy_node = new Node(-1, -1, LVecBase3(0.0, 0.0, 0.0), 0, 0, 0);
_dummy_node->_status = _dummy_node->open;
_dummy_node->_score = -1;
@ -48,17 +43,13 @@ void PathFinder::find_path(Node *src_node, Node *dest_node) {
generate_path();
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : generate_path
// Description : This function performs the pathfinding process using the A* algorithm.
// It updates the openlist and closelist.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function performs the pathfinding process using the A* algorithm. It
* updates the openlist and closelist.
*/
void PathFinder::generate_path() {
// All the A* algorithm is implemented here.
// The check is > 1 due to the existence of the dummy node.
// All the A* algorithm is implemented here. The check is > 1 due to the
// existence of the dummy node.
while(_open_list.size() > 1) {
// The first element of the open list will always be the optimal node.
// This is because the open list is a binary heap with element having the
@ -87,14 +78,10 @@ void PathFinder::generate_path() {
_closed_list.clear();
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : identify_neighbors
// Description : This function traverses through the 8 neigbors of the parent node and
// then adds the neighbors to the _open_list based on A* criteria.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function traverses through the 8 neigbors of the parent node and then
* adds the neighbors to the _open_list based on A* criteria.
*/
void PathFinder::identify_neighbors(Node *parent_node) {
// Remove the parent node from the open_list so that it is not considered
// while adding new nodes to the open list heap.
@ -114,30 +101,21 @@ void PathFinder::identify_neighbors(Node *parent_node) {
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : calc_node_score
// Description : This function calculates the score of each node.
// Score = Cost + Heuristics.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function calculates the score of each node. Score = Cost +
* Heuristics.
*/
void PathFinder::calc_node_score(Node *nd) {
nd->_cost = calc_cost_frm_src(nd);
nd->_heuristic = calc_heuristic(nd);
nd->_score = nd->_cost + nd->_heuristic;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : calc_cost_frm_src
// Description : This function calculates the cost of each node by finding out
// the number of node traversals required to reach the source node.
// Diagonal traversals have cost = 14.
// Horizontal / Vertical traversals have cost = 10.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function calculates the cost of each node by finding out the number of
* node traversals required to reach the source node. Diagonal traversals
* have cost = 14. Horizontal and vertical traversals have cost = 10.
*/
int PathFinder::calc_cost_frm_src(Node *nd) {
int cost = 0;
Node *start_node = nd;
@ -160,15 +138,11 @@ int PathFinder::calc_cost_frm_src(Node *nd) {
return cost;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : calc_heuristic
// Description : This function calculates the heuristic of the nodes using Manhattan method.
// All it does is predict the number of node traversals required to reach the target node.
// No diagonal traversals are allowed in this technique.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function calculates the heuristic of the nodes using Manhattan method.
* All it does is predict the number of node traversals required to reach the
* target node. No diagonal traversals are allowed in this technique.
*/
int PathFinder::calc_heuristic(Node *nd) {
int row_diff = abs(_dest_node->_grid_x - nd->_grid_x);
int col_diff = abs(_dest_node->_grid_y - nd->_grid_y);
@ -177,13 +151,9 @@ int PathFinder::calc_heuristic(Node *nd) {
return heuristic;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : is_diagonal_node
// Description : This function checks if the traversal from a node is diagonal.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function checks if the traversal from a node is diagonal.
*/
bool PathFinder::is_diagonal_node(Node *nd) {
// Calculate the row and column differences between child and parent nodes.
float row_diff = nd->_grid_x - nd->_prv_node->_grid_x;
@ -198,15 +168,10 @@ bool PathFinder::is_diagonal_node(Node *nd) {
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : add_to_olist
// Description : This function adds a node to the open list heap.
// A binay heap is maintained to improve the search.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function adds a node to the open list heap. A binay heap is
* maintained to improve the search.
*/
void PathFinder::add_to_olist(Node *nd) {
// Variables required to search the binary heap.
Node *child_node, *parent_node;
@ -218,9 +183,10 @@ void PathFinder::add_to_olist(Node *nd) {
_open_list.push_back(nd);
// Find the parent and child nodes and create temporary nodes out of them.
// In a binary heap the children of a parent node are always i*2 and i*2 + 1,
// where i is the index of the parent node in the heap. And hence, the parent
// of a node can be easily found out by dividing by 2 and rounding it.
// In a binary heap the children of a parent node are always i*2 and i*2 +
// 1, where i is the index of the parent node in the heap. And hence, the
// parent of a node can be easily found out by dividing by 2 and rounding
// it.
child_idx = _open_list.size() - 1;
parent_idx = child_idx / 2;
child_node = _open_list[child_idx];
@ -242,31 +208,29 @@ void PathFinder::add_to_olist(Node *nd) {
parent_node = _open_list[parent_idx];
}
// At this point the Node with the smallest score will be at the top of the heap.
// At this point the Node with the smallest score will be at the top of the
// heap.
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : remove_from_olist
// Description : This function removes a node from the open list.
// During the removal the binary heap is maintained.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function removes a node from the open list. During the removal the
* binary heap is maintained.
*/
void PathFinder::remove_from_olist() {
// Variables for maintaining the binary heap.
Node *child_node, *child_node_1, *child_node_2;
int child_idx, child_idx_1, child_idx_2;
// Remove the Node at index 1 from the open list binary heap.
// Note: Node at index 0 of open list is a dummy node.
// Remove the Node at index 1 from the open list binary heap. Note: Node at
// index 0 of open list is a dummy node.
_open_list.erase(_open_list.begin() + 1);
if(_open_list.size() > 1) {
// Store the last element in the open list to a temp_node.
Node *temp_node = _open_list[_open_list.size() - 1];
// Shift the elements of the open list to the right by 1 element circularly, excluding element at 0 index.
// Shift the elements of the open list to the right by 1 element
// circularly, excluding element at 0 index.
for(int i = _open_list.size() - 1; i > 1; --i) {
_open_list[i] = _open_list[i - 1];
}
@ -277,7 +241,8 @@ void PathFinder::remove_from_olist() {
// Set the iterator for traversing the node from index 1 in the heap.
unsigned int k = 1;
// This loop traverses down the open list till the node reaches the correct position in the binary heap.
// This loop traverses down the open list till the node reaches the
// correct position in the binary heap.
while(true) {
if((k * 2 + 1) < _open_list.size()) {
// Two children exists for the parent node.
@ -337,16 +302,13 @@ void PathFinder::remove_from_olist() {
}
}
// At this point the Node was succesfully removed and the binary heap re-arranged.
// At this point the Node was succesfully removed and the binary heap re-
// arranged.
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : add_to_clist
// Description : This function adds a node to the closed list.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function adds a node to the closed list.
*/
void PathFinder::add_to_clist(Node *nd) {
// Set the status as closed.
nd->_status = nd->close;
@ -354,13 +316,9 @@ void PathFinder::add_to_clist(Node *nd) {
_closed_list.push_back(nd);
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : remove_from_clist
// Description : This function removes a node from the closed list.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function removes a node from the closed list.
*/
void PathFinder::remove_from_clist(int r, int c) {
for(unsigned int i = 0; i < _closed_list.size(); ++i) {
if(_closed_list[i]->_grid_x == r && _closed_list[i]->_grid_y == c) {
@ -370,15 +328,11 @@ void PathFinder::remove_from_clist(int r, int c) {
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : find_in_mesh
// Description : This function allows the user to pass a position and it returns the
// corresponding node on the navigation mesh. A very useful function as
// it allows for dynamic updation of the mesh based on position.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function allows the user to pass a position and it returns the
* corresponding node on the navigation mesh. A very useful function as it
* allows for dynamic updation of the mesh based on position.
*/
Node* find_in_mesh(NavMesh nav_mesh, LVecBase3 pos, int grid_size) {
int size = grid_size;
float x = pos[0];

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : aiPathFinder.h
// Created by : Deepak, John, Navin
// Date : 10 Nov 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file aiPathFinder.h
* @author Deepak, John, Navin
* @date 2009-11-10
*/
#ifndef _PATHFINDER_H
#define _PATHFINDER_H
@ -25,14 +23,11 @@ typedef vector<NodeArray> NavMesh;
Node* find_in_mesh(NavMesh nav_mesh, LVecBase3 pos, int grid_size);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Class : PathFinder
// Description : This class implements pathfinding using A* algorithm. It also uses a Binary Heap search to
// search the open list. The heuristics are calculated using the manhattan method.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* This class implements pathfinding using A* algorithm. It also uses a
* Binary Heap search to search the open list. The heuristics are calculated
* using the manhattan method.
*/
class EXPCL_PANDAAI PathFinder {
public:
Node *_src_node;
@ -61,4 +56,3 @@ public:
};
#endif

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : aiWorld.cxx
// Created by : Deepak, John, Navin
// Date : 8 Sep 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file aiWorld.cxx
* @author Deepak, John, Navin
* @date 2009-09-08
*/
#include "aiWorld.h"
@ -56,13 +54,10 @@ void AIWorld::print_list() {
_ai_char_pool->print_list();
}
////////////////////////////////////////////////////////////////////////
// Function : update
// Description : The AIWorld update function calls the update function of all the
// AI characters which have been added to the AIWorld.
/////////////////////////////////////////////////////////////////////////////////
/**
* The AIWorld update function calls the update function of all the AI
* characters which have been added to the AIWorld.
*/
void AIWorld::update() {
AICharPool::node *ai_pool;
ai_pool = _ai_char_pool->_head;
@ -73,15 +68,11 @@ void AIWorld::update() {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : add_flock
// Description : This function adds all the AI characters in the Flock object to
// the AICharPool. This function allows adding the AI characetrs as
// part of a flock.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function adds all the AI characters in the Flock object to the
* AICharPool. This function allows adding the AI characetrs as part of a
* flock.
*/
void AIWorld::add_flock(Flock *flock) {
// Add all the ai_characters in the flock to the AIWorld.
for(unsigned int i = 0; i < flock->_ai_char_list.size(); ++i) {
@ -91,13 +82,9 @@ void AIWorld::add_flock(Flock *flock) {
_flock_pool.push_back(flock);
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : get_flock
// Description : This function returns a handle to the Flock whose id is passed.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function returns a handle to the Flock whose id is passed.
*/
Flock AIWorld::get_flock(unsigned int flock_id) {
for(unsigned int i=0; i < _flock_pool.size(); ++i) {
if(_flock_pool[i]->get_id() == flock_id) {
@ -108,13 +95,9 @@ Flock AIWorld::get_flock(unsigned int flock_id) {
return *null_flock;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : remove_flock
// Description : This function removes the flock behavior completely.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function removes the flock behavior completely.
*/
void AIWorld::remove_flock(unsigned int flock_id) {
for(unsigned int i = 0; i < _flock_pool.size(); ++i) {
if(_flock_pool[i]->get_id() == flock_id) {
@ -129,14 +112,10 @@ void AIWorld::remove_flock(unsigned int flock_id) {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : flock_off
// Description : This function turns off the flock behavior temporarily. Similar to
// pausing the behavior.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function turns off the flock behavior temporarily. Similar to pausing
* the behavior.
*/
void AIWorld::flock_off(unsigned int flock_id) {
for(unsigned int i = 0; i < _flock_pool.size(); ++i) {
if(_flock_pool[i]->get_id() == flock_id) {
@ -149,13 +128,9 @@ void AIWorld::flock_off(unsigned int flock_id) {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : flock_on
// Description : This function turns on the flock behavior.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function turns on the flock behavior.
*/
void AIWorld::flock_on(unsigned int flock_id) {
for(unsigned int i = 0; i < _flock_pool.size(); ++i) {
if(_flock_pool[i]->get_id() == flock_id) {
@ -234,14 +209,10 @@ void AICharPool::del(string name) {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : print_list
// Description : This function prints the ai characters in the AICharPool. Used for
// debugging purposes.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function prints the ai characters in the AICharPool. Used for
* debugging purposes.
*/
void AICharPool::print_list() {
node* q;
q = _head;
@ -251,26 +222,18 @@ void AICharPool::print_list() {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : add_obstacle
// Description : This function adds the nodepath as an obstacle that is needed
// by the obstacle avoidance behavior.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function adds the nodepath as an obstacle that is needed by the
* obstacle avoidance behavior.
*/
void AIWorld::add_obstacle(NodePath obstacle) {
_obstacles.push_back(obstacle);
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : remove_obstacle
// Description : This function removes the nodepath from the obstacles list that is needed
// by the obstacle avoidance behavior.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function removes the nodepath from the obstacles list that is needed
* by the obstacle avoidance behavior.
*/
void AIWorld::remove_obstacle(NodePath obstacle) {
for(unsigned int i = 0; i <= _obstacles.size(); ++i) {
if(_obstacles[i] == obstacle) {

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : aiWorld.h
// Created by : Deepak, John, Navin
// Date : 8 Sep 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file aiWorld.h
* @author Deepak, John, Navin
* @date 2009-09-08
*/
#pragma warning (disable:4996)
#pragma warning (disable:4005)
@ -28,16 +26,11 @@
class AICharacter;
class Flock;
///////////////////////////////////////////////////////////////////////
//
// Class : AICharPool
// Description : This class implements a linked list of AI Characters allowing
// the user to add and delete characters from the linked list.
// This will be used in the AIWorld class.
////////////////////////////////////////////////////////////////////////
/**
* This class implements a linked list of AI Characters allowing the user to
* add and delete characters from the linked list. This will be used in the
* AIWorld class.
*/
class EXPCL_PANDAAI AICharPool {
public:
struct node {
@ -54,18 +47,13 @@ class EXPCL_PANDAAI AICharPool {
};
///////////////////////////////////////////////////////////////////////
//
// Class : AIWorld
// Description : A class that implements the virtual AI world which keeps track
// of the AI characters active at any given time. It contains a linked
// list of AI characters, obstactle data and unique name for each
// character. It also updates each characters state. The AI characters
// can also be added to the world as flocks.
////////////////////////////////////////////////////////////////////////
/**
* A class that implements the virtual AI world which keeps track of the AI
* characters active at any given time. It contains a linked list of AI
* characters, obstactle data and unique name for each character. It also
* updates each characters state. The AI characters can also be added to the
* world as flocks.
*/
class EXPCL_PANDAAI AIWorld {
private:
AICharPool * _ai_char_pool;
@ -97,12 +85,3 @@ PUBLISHED:
};
#endif

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : arrival.cxx
// Created by : Deepak, John, Navin
// Date : 24 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file arrival.cxx
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#include "arrival.h"
@ -25,17 +23,12 @@ Arrival::Arrival(AICharacter *ai_ch, double distance) {
Arrival::~Arrival() {
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : do_arrival
// Description : This function performs the arrival and returns an arrival force which is used
// in the calculate_prioritized function.
// In case the steering force = 0, it resets to arrival_activate.
// The arrival behavior works only when seek or pursue is active.
// This function is not to be used by the user.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function performs the arrival and returns an arrival force which is
* used in the calculate_prioritized function. In case the steering force =
* 0, it resets to arrival_activate. The arrival behavior works only when
* seek or pursue is active. This function is not to be used by the user.
*/
LVecBase3 Arrival::do_arrival() {
LVecBase3 direction_to_target;
double distance;
@ -88,15 +81,11 @@ LVecBase3 Arrival::do_arrival() {
return(LVecBase3(0.0, 0.0, 0.0));
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : arrival_activate
// Description : This function checks for whether the target is within the arrival distance.
// When this is true, it calls the do_arrival function and sets the arrival direction.
// This function is not to be used by the user.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function checks for whether the target is within the arrival distance.
* When this is true, it calls the do_arrival function and sets the arrival
* direction. This function is not to be used by the user.
*/
void Arrival::arrival_activate() {
LVecBase3 dirn;
if(_arrival_type) {

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : arrival.h
// Created by : Deepak, John, Navin
// Date : 24 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file arrival.h
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#ifndef _ARRIVAL_H
#define _ARRIVAL_H
@ -32,9 +30,8 @@ public:
LVecBase3 _arrival_direction;
bool _arrival_done;
// This flag specifies if the arrival behavior is being used with seek or pursue behavior.
// True = used with pursue.
// False = used with seek.
// This flag specifies if the arrival behavior is being used with seek or
// pursue behavior. True = used with pursue. False = used with seek.
bool _arrival_type;
Arrival(AICharacter *ai_ch, double distance = 10.0);

View File

@ -1,16 +1,15 @@
// Filename: config_ai.cxx
// Created by: Pandai (13Sep09)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file config_ai.cxx
* @author Pandai
* @date 2009-09-13
*/
#include "config_ai.h"
#include "aiWorld.h"
@ -37,14 +36,12 @@ ConfigureFn(config_ai) {
init_libai();
}
////////////////////////////////////////////////////////////////////
// Function: init_libai
// Description: Initializes the library. This must be called at
// least once before any of the functions or classes in
// this library can be used. Normally it will be
// called by the static initializers and need not be
// called explicitly, but special cases exist.
////////////////////////////////////////////////////////////////////
/**
* Initializes the library. This must be called at least once before any of
* the functions or classes in this library can be used. Normally it will be
* called by the static initializers and need not be called explicitly, but
* special cases exist.
*/
void
init_libai() {
static bool initialized = false;

View File

@ -1,16 +1,15 @@
// Filename: config_ai.h
// Created by: Pandai (13Sep09)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file config_ai.h
* @author Pandai
* @date 2009-09-13
*/
#ifndef CONFIG_AI_H
#define CONFIG_AI_H
@ -23,4 +22,3 @@ NotifyCategoryDecl(ai, EXPCL_PANDAAI, EXPTP_PANDAAI);
extern EXPCL_PANDAAI void init_libai();
#endif

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : evade.cxx
// Created by : Deepak, John, Navin
// Date : 24 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file evade.cxx
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#include "evade.h"
@ -31,17 +29,12 @@ Evade::Evade(AICharacter *ai_ch, NodePath target_object, double panic_distance,
Evade::~Evade() {
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : do_evade
// Description : This function performs the evade and returns an evade force which is used
// in the calculate_prioritized function.
// In case the AICharacter is past the (panic + relax) distance,
// it resets to evade_activate.
// This function is not to be used by the user.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function performs the evade and returns an evade force which is used
* in the calculate_prioritized function. In case the AICharacter is past the
* (panic + relax) distance, it resets to evade_activate. This function is
* not to be used by the user.
*/
LVecBase3 Evade::do_evade() {
assert(_evade_target && "evade target not assigned");
@ -66,15 +59,11 @@ LVecBase3 Evade::do_evade() {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : evade_activate
// Description : This function checks for whether the target is within the panic distance.
// When this is true, it calls the do_evade function and sets the evade direction.
// This function is not to be used by the user.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function checks for whether the target is within the panic distance.
* When this is true, it calls the do_evade function and sets the evade
* direction. This function is not to be used by the user.
*/
void Evade::evade_activate() {
_evade_direction = (_ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _evade_target.get_pos(_ai_char->_window_render));
double distance = _evade_direction.length();

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : evade.h
// Created by : Deepak, John, Navin
// Date : 24 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file evade.h
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#ifndef _EVADE_H
#define _EVADE_H
@ -22,7 +20,6 @@
class AICharacter;
class EXPCL_PANDAAI Evade {
public:
AICharacter *_ai_char;

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : flee.cxx
// Created by : Deepak, John, Navin
// Date : 24 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file flee.cxx
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#include "flee.h"
@ -46,17 +44,12 @@ Flee::Flee(AICharacter *ai_ch, LVecBase3 pos, double panic_distance,
Flee::~Flee() {
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : do_flee
// Description : This function performs the flee and returns a flee force which is used
// in the calculate_prioritized function.
// In case the AICharacter is past the (panic + relax) distance,
// it resets to flee_activate.
// This function is not to be used by the user.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function performs the flee and returns a flee force which is used in
* the calculate_prioritized function. In case the AICharacter is past the
* (panic + relax) distance, it resets to flee_activate. This function is not
* to be used by the user.
*/
LVecBase3 Flee::do_flee() {
LVecBase3 dirn;
double distance;
@ -80,15 +73,11 @@ LVecBase3 Flee::do_flee() {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : flee_activate
// Description : This function checks for whether the target is within the panic distance.
// When this is true, it calls the do_flee function and sets the flee direction.
// This function is not to be used by the user.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function checks for whether the target is within the panic distance.
* When this is true, it calls the do_flee function and sets the flee
* direction. This function is not to be used by the user.
*/
void Flee::flee_activate() {
LVecBase3 dirn;
double distance;

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : flee.h
// Created by : Deepak, John, Navin
// Date : 24 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file flee.h
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#ifndef _FLEE_H
#define _FLEE_H
@ -22,7 +20,6 @@
class AICharacter;
class EXPCL_PANDAAI Flee {
public:
AICharacter *_ai_char;

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : flock.cxx
// Created by : Deepak, John, Navin
// Date : 12 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file flock.cxx
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#include "flock.h"
@ -28,13 +26,9 @@ Flock::Flock(unsigned int flock_id, double vcone_angle, double vcone_radius, uns
Flock::~Flock() {
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : add_ai_char
// Description : This function adds AI characters to the flock.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function adds AI characters to the flock.
*/
void Flock::add_ai_char(AICharacter *ai_char) {
ai_char->_ai_char_flock_id = _flock_id;
ai_char->_steering->_flock_group = this;

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : flock.h
// Created by : Deepak, John, Navin
// Date : 12 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file flock.h
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#ifndef _FLOCK_H
#define _FLOCK_H
@ -21,25 +19,22 @@
class AICharacter;
///////////////////////////////////////////////////////////////////////////////////////
//
// Class : Flock
// Description : This class is used to define the flock attributes and the AI characters
// which are part of the flock.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This class is used to define the flock attributes and the AI characters
* which are part of the flock.
*/
class EXPCL_PANDAAI Flock {
private:
unsigned int _flock_id;
public:
// Variables which will hold the parameters of the ai character's visibilty cone.
// Variables which will hold the parameters of the ai character's visibilty
// cone.
double _flock_vcone_angle;
double _flock_vcone_radius;
// Variables to specify weights of separation, cohesion and alignment behaviors and thus
// create variable flock behavior.
// Variables to specify weights of separation, cohesion and alignment
// behaviors and thus create variable flock behavior.
unsigned int _separation_wt;
unsigned int _cohesion_wt;
unsigned int _alignment_wt;

View File

@ -24,14 +24,10 @@ Node::Node(int grid_x, int grid_y, LVecBase3 pos, float w, float l, float h) {
Node::~Node() {
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : contains
// Description : This is a handy function which returns true if the passed position is
// within the node's dimensions.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This is a handy function which returns true if the passed position is
* within the node's dimensions.
*/
bool Node::contains(float x, float y) {
if(_position.get_x() - _width / 2 <= x && _position.get_x() + _width / 2 >= x &&
_position.get_y() - _length / 2 <= y && _position.get_y() + _length / 2 >= y) {
@ -40,4 +36,4 @@ bool Node::contains(float x, float y) {
else {
return false;
}
}
}

View File

@ -4,28 +4,24 @@
#include "aiGlobals.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Class : Node
// Description : This class is used to assign the nodes on the mesh. It holds all the data necessary to
// compute A* algorithm. It also maintains a lot of vital information such as the neighbor
// nodes of each node and also its position on the mesh.
// Note: The Mesh Generator which is a stand alone tool makes use of this class to generate the nodes on the
// mesh.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* This class is used to assign the nodes on the mesh. It holds all the data
* necessary to compute A* algorithm. It also maintains a lot of vital
* information such as the neighbor nodes of each node and also its position
* on the mesh.
*
* Note: The Mesh Generator which is a stand alone tool makes use of this
* class to generate the nodes on the mesh.
*/
class EXPCL_PANDAAI Node {
public:
// This variable specifies whether the node is an obtacle or not.
// Used for dynamic obstacle addition to the environment.
// obstacle = false
// This variable specifies whether the node is an obtacle or not. Used
// for dynamic obstacle addition to the environment. obstacle = false
// navigational = true
bool _type;
// This variable specifies the node status whether open, close or neutral.
// open = belongs to _open_list.
// close = belongs to _closed_list.
// open = belongs to _open_list. close = belongs to _closed_list.
// neutral = unexamined node.
enum Status {
open,
@ -34,8 +30,8 @@ public:
};
Status _status;
// The score is used to compute the traversal expense to nodes when using A*.
// _score = _cost + heuristic
// The score is used to compute the traversal expense to nodes when using
// A*. _score = _cost + heuristic
int _score;
int _cost;
int _heuristic;
@ -49,13 +45,14 @@ public:
// Position of the node in 3D space.
LVecBase3 _position;
// Dimensions of each face / cell on the mesh.
// Height is given in case of expansion to a 3d mesh. Currently not used.
// Dimensions of each face cell on the mesh. Height is given in case of
// expansion to a 3d mesh. Currently not used.
float _width, _length ,_height;
Node *_neighbours[8]; // anti-clockwise from top left corner.
// The _next pointer is used for traversal during mesh generation from the model.
// Note: The data in this member is discarded when mesh data is written into navmesh.csv file.
// The _next pointer is used for traversal during mesh generation from the
// model. Note: The data in this member is discarded when mesh data is
// written into navmesh.csv file.
Node *_next;
Node(int grid_x, int grid_y, LVecBase3 pos, float w, float l, float h);

View File

@ -1,37 +1,34 @@
////////////////////////////////////////////////////////////////////////
// Filename : obstacleAvoidance.cxx
// Created by : Deepak, John, Navin
// Date : 10 Nov 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file obstacleAvoidance.cxx
* @author Deepak, John, Navin
* @date 2009-11-10
*/
#include "obstacleAvoidance.h"
ObstacleAvoidance::ObstacleAvoidance(AICharacter *ai_char, float feeler_length) {
ObstacleAvoidance::
ObstacleAvoidance(AICharacter *ai_char, float feeler_length) {
_ai_char = ai_char;
_feeler = feeler_length;
}
ObstacleAvoidance::~ObstacleAvoidance() {
ObstacleAvoidance::
~ObstacleAvoidance() {
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : obstacle_detection
// Description : This function checks if an obstacle is near to the AICharacter and
// if an obstacle is detected returns true
/////////////////////////////////////////////////////////////////////////////////
bool ObstacleAvoidance::obstacle_detection() {
/**
* This function checks if an obstacle is near to the AICharacter and if an
* obstacle is detected returns true
*/
bool ObstacleAvoidance::
obstacle_detection() {
// Calculate the volume of the AICharacter with respect to render
PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
@ -44,53 +41,49 @@ bool ObstacleAvoidance::obstacle_detection() {
PT(BoundingVolume) bounds = _ai_char->_world->_obstacles[i].get_bounds();
CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere();
LVecBase3 near_obstacle = _ai_char->_world->_obstacles[i].get_pos() - _ai_char->get_node_path().get_pos();
// Check if it's the nearest obstacle, If so initialize as the nearest obstacle
// Check if it's the nearest obstacle, If so initialize as the nearest
// obstacle
if((near_obstacle.length() < distance) && (_ai_char->_world->_obstacles[i].get_pos() != _ai_char->get_node_path().get_pos())) {
_nearest_obstacle = _ai_char->_world->_obstacles[i];
distance = near_obstacle.length();
expanded_radius = bsphere->get_radius() + np_sphere->get_radius();
}
}
LVecBase3 feeler = _feeler * _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
feeler.normalize();
feeler *= (expanded_radius + np_sphere->get_radius()) ;
to_obstacle = _nearest_obstacle.get_pos() - _ai_char->get_node_path().get_pos();
LVector3 line_vector = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
LVecBase3 project = (to_obstacle.dot(line_vector) * line_vector) / line_vector.length_squared();
LVecBase3 perp = project - to_obstacle;
// If the nearest obstacle will collide with our AICharacter then send obstacle detection as true
if((_nearest_obstacle) && (perp.length() < expanded_radius - np_sphere->get_radius()) && (project.length() < feeler.length())) {
return true;
}
return false;
LVecBase3 feeler = _feeler * _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
feeler.normalize();
feeler *= (expanded_radius + np_sphere->get_radius()) ;
to_obstacle = _nearest_obstacle.get_pos() - _ai_char->get_node_path().get_pos();
LVector3 line_vector = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
LVecBase3 project = (to_obstacle.dot(line_vector) * line_vector) / line_vector.length_squared();
LVecBase3 perp = project - to_obstacle;
// If the nearest obstacle will collide with our AICharacter then send
// obstacle detection as true
if (_nearest_obstacle && (perp.length() < expanded_radius - np_sphere->get_radius()) && (project.length() < feeler.length())) {
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : obstacle_avoidance_activate
// Description : This function activates obstacle_avoidance if a obstacle
// is detected
/////////////////////////////////////////////////////////////////////////////////
void ObstacleAvoidance::obstacle_avoidance_activate() {
if(obstacle_detection()) {
/**
* This function activates obstacle_avoidance if a obstacle is detected
*/
void ObstacleAvoidance::
obstacle_avoidance_activate() {
if (obstacle_detection()) {
_ai_char->_steering->turn_off("obstacle_avoidance_activate");
_ai_char->_steering->turn_on("obstacle_avoidance");
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : do_obstacle_avoidance
// Description : This function returns the force necessary by the AICharacter to
// avoid the nearest obstacle detected by obstacle_detection
// function
// NOTE : This assumes the obstacles are spherical
/////////////////////////////////////////////////////////////////////////////////
LVecBase3 ObstacleAvoidance::do_obstacle_avoidance() {
/**
* This function returns the force necessary by the AICharacter to avoid the
* nearest obstacle detected by obstacle_detection function NOTE : This
* assumes the obstacles are spherical
*/
LVecBase3 ObstacleAvoidance::
do_obstacle_avoidance() {
LVecBase3 offset = _ai_char->get_node_path().get_pos() - _nearest_obstacle.get_pos();
PT(BoundingVolume) bounds =_nearest_obstacle.get_bounds();
CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere();

View File

@ -1,21 +1,19 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file obstacleAvoidance.h
* @author Deepak, John, Navin
* @date 2009-11-10
*/
#ifndef OBSTACLE_AVOIDANCE_H
#define OBSTACLE_AVOIDANCE_H
////////////////////////////////////////////////////////////////////////
// Filename : obstacleAvoidance.h
// Created by : Deepak, John, Navin
// Date : 10 Nov 2009
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "aiCharacter.h"
#include "boundingSphere.h"

View File

@ -1,3 +1,15 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file pathFind.cxx
* @author Deepak, John, Navin
* @date 2009-10-12
*/
#include "pathFind.h"
@ -18,13 +30,9 @@ PathFind::PathFind(AICharacter *ai_ch) {
PathFind::~PathFind() {
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : create_nav_mesh
// Description : This function recreates the navigation mesh from the .csv file
/////////////////////////////////////////////////////////////////////////////////
/**
* This function recreates the navigation mesh from the .csv file
*/
void PathFind::create_nav_mesh(const char* navmesh_filename) {
// Stage variables.
int grid_x, grid_y;
@ -62,8 +70,9 @@ void PathFind::create_nav_mesh(const char* navmesh_filename) {
getline(nav_mesh_file, line);
stringstream linestream (line);
// Stores all the data members in the line to the array.
// Data structure: NULL,NodeType,GridX,GridY,Length,Width,Height,PosX,PosY,PosZ
// Stores all the data members in the line to the array. Data
// structure:
// NULL,NodeType,GridX,GridY,Length,Width,Height,PosX,PosY,PosZ
for(int i = 0; i < 10; ++i) {
getline(linestream, fields[i], ',');
}
@ -86,7 +95,8 @@ void PathFind::create_nav_mesh(const char* navmesh_filename) {
// End of file reached at this point.
nav_mesh_file.close();
// Assign the neighbor nodes for each of the main nodes that just got populated into the stage mesh.
// Assign the neighbor nodes for each of the main nodes that just got
// populated into the stage mesh.
assign_neighbor_nodes(navmesh_filename);
}
}
@ -96,14 +106,10 @@ void PathFind::create_nav_mesh(const char* navmesh_filename) {
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : assign_neighbor_nodes
// Description : This function assigns the neighbor nodes for each main node present in
// _nav_mesh.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function assigns the neighbor nodes for each main node present in
* _nav_mesh.
*/
void PathFind::assign_neighbor_nodes(const char* navmesh_filename){
ifstream nav_mesh_file (navmesh_filename);
@ -137,8 +143,9 @@ void PathFind::assign_neighbor_nodes(const char* navmesh_filename){
gd_yn = atoi(fields_n[3].c_str());
if(fields_n[0] == "0" && fields_n[1] == "1") {
// Usable neighbor for main node.
// TODO: The indices of the vector are inverted when compared to the values of the nodes on actual grid. Fix this!
// Usable neighbor for main node. TODO: The indices of the vector
// are inverted when compared to the values of the nodes on actual
// grid. Fix this!
_nav_mesh[gd_y][gd_x]->_neighbours[i] = _nav_mesh[gd_yn][gd_xn];
}
else if(fields_n[0] == "1" && fields_n[1] == "1") {
@ -161,15 +168,10 @@ void PathFind::assign_neighbor_nodes(const char* navmesh_filename){
}
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : set_path_find
// Description : This function starts the path finding process after reading the given
// navigation mesh.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function starts the path finding process after reading the given
* navigation mesh.
*/
void PathFind::set_path_find(const char* navmesh_filename) {
create_nav_mesh(navmesh_filename);
@ -187,16 +189,11 @@ void PathFind::set_path_find(const char* navmesh_filename) {
_path_finder_obj = new PathFinder(_nav_mesh);
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : path_find (for pathfinding towards a static position)
// Description : This function checks for the source and target in the navigation mesh
// for its availability and then finds the best path via the A* algorithm
// Then it calls the path follower to make the object follow the path.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function checks for the source and target in the navigation mesh for
* its availability and then finds the best path via the A* algorithm Then it
* calls the path follower to make the object follow the path.
*/
void PathFind::path_find(LVecBase3 pos, string type) {
if(type == "addPath") {
if(_ai_char->_steering->_path_follow_obj) {
@ -230,15 +227,11 @@ void PathFind::path_find(LVecBase3 pos, string type) {
}
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : path_find (for pathfinding towards a moving target (a NodePath))
// Description : This function checks for the source and target in the navigation mesh
// for its availability and then finds the best path via the A* algorithm
// Then it calls the path follower to make the object follow the path.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function checks for the source and target in the navigation mesh for
* its availability and then finds the best path via the A* algorithm Then it
* calls the path follower to make the object follow the path.
*/
void PathFind::path_find(NodePath target, string type) {
if(type == "addPath") {
if(_ai_char->_steering->_path_follow_obj) {
@ -277,13 +270,9 @@ void PathFind::path_find(NodePath target, string type) {
}
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : clear_path
// Description : Helper function to restore the path and mesh to its initial state
///////////////////////////////////////////////////////////////////////////////////////
/**
* Helper function to restore the path and mesh to its initial state
*/
void PathFind::clear_path() {
// Initialize to zero
for(int i = 0; i < _grid_size; ++i) {
@ -304,15 +293,11 @@ void PathFind::clear_path() {
}
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : trace_path
// Description : This function is the function which sends the path information one by
// one to the path follower so that it can store the path needed to be
// traversed by the pathfinding object
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function is the function which sends the path information one by one
* to the path follower so that it can store the path needed to be traversed
* by the pathfinding object
*/
void PathFind::trace_path(Node* src) {
if(_ai_char->_pf_guide) {
_parent->remove_all_children();
@ -336,16 +321,12 @@ void PathFind::trace_path(Node* src) {
}
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : add_obstacle_to_mesh
// Description : This function allows the user to dynamically add obstacles to the
// game environment. The function will update the nodes within the
// bounding volume of the obstacle as non-traversable. Hence will not be
// considered by the pathfinding algorithm.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function allows the user to dynamically add obstacles to the game
* environment. The function will update the nodes within the bounding volume
* of the obstacle as non-traversable. Hence will not be considered by the
* pathfinding algorithm.
*/
void PathFind::add_obstacle_to_mesh(NodePath obstacle) {
PT(BoundingVolume) np_bounds = obstacle.get_bounds();
CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
@ -373,14 +354,10 @@ void PathFind::add_obstacle_to_mesh(NodePath obstacle) {
}
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : do_dynamic_avoid()
// Description : This function does the updation of the collisions to the mesh based
// on the new positions of the obstacles.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function does the updation of the collisions to the mesh based on the
* new positions of the obstacles.
*/
void PathFind::do_dynamic_avoid() {
clear_previous_obstacles();
_previous_obstacles.clear();
@ -389,28 +366,20 @@ void PathFind::do_dynamic_avoid() {
}
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : clear_previous_obstacles()
// Description : Helper function to reset the collisions if the obstacle is not on the
// node anymore
///////////////////////////////////////////////////////////////////////////////////////
/**
* Helper function to reset the collisions if the obstacle is not on the node
* anymore
*/
void PathFind::clear_previous_obstacles(){
for(unsigned int i = 0; i < _previous_obstacles.size(); i = i + 2) {
_nav_mesh[_previous_obstacles[i]][_previous_obstacles[i + 1]]->_type = true;
}
}
///////////////////////////////////////////////////////////////////////////////////////
//
// Function : dynamic_avoid
// Description : This function starts the pathfinding obstacle navigation for the
// passed in obstacle.
///////////////////////////////////////////////////////////////////////////////////////
/**
* This function starts the pathfinding obstacle navigation for the passed in
* obstacle.
*/
void PathFind::dynamic_avoid(NodePath obstacle) {
_dynamic_avoid = true;
_dynamic_obstacle.insert(_dynamic_obstacle.end(), obstacle);

View File

@ -1,18 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : pathFind.h
// Created by : Deepak, John, Navin
// Date : 12 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file pathFind.h
* @author Deepak, John, Navin
* @date 2009-10-12
*/
#ifndef _PATHFIND_H
#define _PATHFIND_H
@ -24,15 +21,12 @@
class AICharacter;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Class : PathFind
// Description : This class contains all the members and functions that are required to form an interface between
// the AIBehaviors class and the PathFinder class. An object (pointer) of this class is provided in the
// AIBehaviors class. It is only via this object that the user can activate pathfinding.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* This class contains all the members and functions that are required to form
* an interface between the AIBehaviors class and the PathFinder class. An
* object (pointer) of this class is provided in the AIBehaviors class. It is
* only via this object that the user can activate pathfinding.
*/
class EXPCL_PANDAAI PathFind {
public:
AICharacter *_ai_char;
@ -69,4 +63,3 @@ public:
};
#endif

View File

@ -12,25 +12,17 @@ PathFollow::PathFollow(AICharacter *ai_ch, float follow_wt) {
PathFollow::~PathFollow() {
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : add_to_path
// Description : This function adds the positions generated from a pathfind or a simple
// path follow behavior to the _path list.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function adds the positions generated from a pathfind or a simple path
* follow behavior to the _path list.
*/
void PathFollow::add_to_path(LVecBase3 pos) {
_path.push_back(pos);
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : start
// Description : This function initiates the path follow behavior.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function initiates the path follow behavior.
*/
void PathFollow::start(string type) {
_type = type;
_start = true;
@ -43,24 +35,20 @@ void PathFollow::start(string type) {
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : do_follow
// Description : This function allows continuous path finding by ai chars. There are 2
// ways in which this is implemented.
// 1. The character re-calculates the optimal path everytime the target
// changes its position. Less computationally expensive.
// 2. The character continuosly re-calculates its optimal path to the
// target. This is used in a scenario where the ai chars have to avoid
// other ai chars. More computationally expensive.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function allows continuous path finding by ai chars. There are 2 ways
* in which this is implemented. 1. The character re-calculates the optimal
* path everytime the target changes its position. Less computationally
* expensive. 2. The character continuosly re-calculates its optimal path to
* the target. This is used in a scenario where the ai chars have to avoid
* other ai chars. More computationally expensive.
*/
void PathFollow::do_follow() {
if((_myClock->get_real_time() - _time) > 0.5) {
if(_type=="pathfind") {
// This 'if' statement when 'true' causes the path to be re-calculated irrespective of target position.
// This is done when _dynamice_avoid is active. More computationally expensive.
// This 'if' statement when 'true' causes the path to be re-calculated
// irrespective of target position. This is done when _dynamice_avoid
// is active. More computationally expensive.
if(_ai_char->_steering->_path_find_obj->_dynamic_avoid) {
_ai_char->_steering->_path_find_obj->do_dynamic_avoid();
if(check_if_possible()) {
@ -77,8 +65,9 @@ void PathFollow::do_follow() {
}
}
}
// This 'if' statement causes the path to be re-calculated only when there is a change in target position.
// Less computationally expensive.
// This 'if' statement causes the path to be re-calculated only when
// there is a change in target position. Less computationally
// expensive.
else if(_ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render)
!= _ai_char->_steering->_path_find_obj->_prev_position) {
if(check_if_possible()) {
@ -109,14 +98,10 @@ void PathFollow::do_follow() {
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Function : check_if_possible
// Description : This function checks if the current positions of the ai char and the
// target char can be used to generate an optimal path.
/////////////////////////////////////////////////////////////////////////////////////////
/**
* This function checks if the current positions of the ai char and the target
* char can be used to generate an optimal path.
*/
bool PathFollow::check_if_possible() {
Node* src = find_in_mesh(_ai_char->_steering->_path_find_obj->_nav_mesh, _ai_char->_ai_char_np.get_pos(_ai_char->_window_render), _ai_char->_steering->_path_find_obj->_grid_size);
LVecBase3 _prev_position = _ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render);

View File

@ -1,21 +1,20 @@
////////////////////////////////////////////////////////////////////////
// Filename : pursue.cxx
// Created by : Deepak, John, Navin
// Date : 24 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file pursue.cxx
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#include "pursue.h"
Pursue::Pursue(AICharacter *ai_ch, NodePath target_object, float pursue_wt) {
Pursue::
Pursue(AICharacter *ai_ch, NodePath target_object, float pursue_wt) {
_ai_char = ai_ch;
_pursue_target = target_object;
@ -24,20 +23,18 @@ Pursue::Pursue(AICharacter *ai_ch, NodePath target_object, float pursue_wt) {
_pursue_done = false;
}
Pursue::~Pursue() {
Pursue::
~Pursue() {
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : do_pursue
// Description : This function performs the pursue and returns a pursue force which is used
// in the calculate_prioritized function.
// In case the target has been reached it resets the forces to 0 so that the character stops.
// This function is not to be used by the user.
/////////////////////////////////////////////////////////////////////////////////
LVecBase3 Pursue::do_pursue() {
/**
* This function performs the pursue and returns a pursue force which is used
* in the calculate_prioritized function. In case the target has been reached
* it resets the forces to 0 so that the character stops. This function is
* not to be used by the user.
*/
LVecBase3 Pursue::
do_pursue() {
assert(_pursue_target && "pursue target not assigned");
LVecBase3 present_pos = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render);
@ -47,7 +44,7 @@ LVecBase3 Pursue::do_pursue() {
_pursue_done = true;
_ai_char->_steering->_steering_force = LVecBase3(0.0, 0.0, 0.0);
_ai_char->_steering->_pursue_force = LVecBase3(0.0, 0.0, 0.0);
return(LVecBase3(0.0, 0.0, 0.0));
return LVecBase3(0.0, 0.0, 0.0);
}
else {
_pursue_done = false;
@ -57,5 +54,5 @@ LVecBase3 Pursue::do_pursue() {
_pursue_direction.normalize();
LVecBase3 desired_force = _pursue_direction * _ai_char->_movt_force;
return(desired_force);
return desired_force;
}

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : pursue.h
// Created by : Deepak, John, Navin
// Date : 24 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file pursue.h
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#ifndef _PURSUE_H
#define _PURSUE_H

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : seek.cxx
// Created by : Deepak, John, Navin
// Date : 24 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file seek.cxx
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#include "seek.h"
@ -42,15 +40,11 @@ Seek::Seek(AICharacter *ai_ch, LVecBase3 pos, float seek_wt) {
Seek::~Seek() {
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : do_seek
// Description : This function performs the seek and returns a seek force which is used
// in the calculate_prioritized function.
// This function is not to be used by the user.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function performs the seek and returns a seek force which is used in
* the calculate_prioritized function. This function is not to be used by the
* user.
*/
LVecBase3 Seek::do_seek() {
double target_distance = (_seek_position - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render)).length();

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : seek.h
// Created by : Deepak, John, Navin
// Date : 24 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file seek.h
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#ifndef _SEEK_H
#define _SEEK_H

View File

@ -1,40 +1,29 @@
////////////////////////////////////////////////////////////////////////
// Filename : wander.cxx
// Created by : Deepak, John, Navin
// Date : 24 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file wander.cxx
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#include "wander.h"
/////////////////////////////////////////////////////////////////////////////////
//
// Function : rand_float
// Description : This function creates a random float point number
/////////////////////////////////////////////////////////////////////////////////
/**
* This function creates a random float point number
*/
double rand_float() {
const static double rand_max = 0x7fff;
return ((rand()) / (rand_max + 1.0));
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : random_clamped
// Description : This function returns a random floating point number in the range
// -1 to 1.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function returns a random floating point number in the range -1 to 1.
*/
double random_clamped() {
return (rand_float() - rand_float());
}
@ -49,12 +38,9 @@ Wander::Wander(AICharacter *ai_ch, double wander_radius,int flag, double aoe, fl
// Area around which the character should wander
_area_of_effect = aoe;
_init_pos = _ai_char->get_node_path().get_pos(_ai_char->get_char_render());
// _flag is used by Wander to wander in a given axis
// Value 0 - XY axes wander
// Value 1 - YZ axes wander
// Value 2 - XZ axes wander
// Value 3 - XYZ axes wander
// default is XY axes
// _flag is used by Wander to wander in a given axis Value 0 - XY axes
// wander Value 1 - YZ axes wander Value 2 - XZ axes wander Value 3 - XYZ
// axes wander default is XY axes
switch(_flag) {
case 0: {
_wander_target = LVecBase3(_wander_radius * cos(theta), _wander_radius * sin(theta),0);
@ -82,18 +68,15 @@ Wander::Wander(AICharacter *ai_ch, double wander_radius,int flag, double aoe, fl
Wander::~Wander() {
}
/////////////////////////////////////////////////////////////////////////////////
//
// Function : do_wander
// Description : This function performs the wander and returns the wander force which is used
// in the calculate_prioritized function.
// This function is not to be used by the user.
/////////////////////////////////////////////////////////////////////////////////
/**
* This function performs the wander and returns the wander force which is
* used in the calculate_prioritized function. This function is not to be
* used by the user.
*/
LVecBase3 Wander::do_wander() {
LVecBase3 present_pos = _ai_char->get_node_path().get_pos(_ai_char->get_char_render());
// Create the random slices to enable random movement of wander for x,y,z respectively
// Create the random slices to enable random movement of wander for x,y,z
// respectively
double time_slice_1 = random_clamped() * 1.5;
double time_slice_2 = random_clamped() * 1.5;
double time_slice_3 = random_clamped() * 1.5;
@ -123,6 +106,7 @@ LVecBase3 Wander::do_wander() {
_wander_target *= _wander_radius;
LVecBase3 target = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
target.normalize();
// Project wander target onto global space
target = _wander_target + target;
LVecBase3 desired_target = present_pos + target;

View File

@ -1,17 +1,15 @@
////////////////////////////////////////////////////////////////////////
// Filename : wander.h
// Created by : Deepak, John, Navin
// Date : 24 Oct 09
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file wander.h
* @author Deepak, John, Navin
* @date 2009-10-24
*/
#ifndef _WANDER_H
#define _WANDER_H

View File

@ -1,15 +1,14 @@
// Filename: contribbase.cxx
// Created by: rdb (26Apr10)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file contribbase.cxx
* @author rdb
* @date 2010-04-26
*/
#include "contribbase.h"

View File

@ -1,8 +1,4 @@
/* Filename: contribbase.h
* Created by: rdb (30Dec09)
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
@ -10,7 +6,10 @@
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* @file contribbase.h
* @author rdb
* @date 2009-12-30
*/
/* This file is included at the beginning of every header file and/or
C or C++ file. It must be compilable for C as well as C++ files,
@ -23,4 +22,3 @@
#include "contribsymbols.h"
#endif

View File

@ -1,8 +1,4 @@
/* Filename: contribsymbols.h
* Created by: rdb (30Dec09)
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
@ -10,7 +6,10 @@
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* @file contribsymbols.h
* @author rdb
* @date 2009-12-30
*/
#ifndef CONTRIBSYMBOLS_H
#define CONTRIBSYMBOLS_H

View File

@ -62,7 +62,7 @@ UNIT_TYPES = ["mm",
"cm",
"m",
"in",
"ft",
"ft",
"yd"]
@ -229,7 +229,7 @@ class OutputDialogPaths(wx.Dialog):
self.Bind(wx.EVT_BUTTON, self.RunPaths, self.paths_done)
# end wxGlade
def setCallback(self, callback):
self.callback = callback
@ -286,7 +286,7 @@ class main(wx.Frame):
self._setupUI()
#Show the welcome message and the initial panda path
#NOTE this shoudl eventually check for an install of Panda somewhere
self.ShowInitialEnv()
def _setupUI(self):
@ -379,7 +379,7 @@ class main(wx.Frame):
self.pandaPathTxt = wx.TextCtrl(self.console_panel, -1, "", style=wx.TE_READONLY)
self.loadPandaPathBtn = wx.Button(self.console_panel, ID_CHOOSEPANDA, "Choose..")
self.ignoreModDates = wx.CheckBox(self.console_panel, -1, "Override export changed maya scene files")
# Maya2Egg Tool
self.maya2egg_panel = wx.Panel(self.tool_options_panel, -1, style=wx.NO_BORDER|wx.TAB_TRAVERSAL)
@ -694,7 +694,7 @@ class main(wx.Frame):
self.m2e_exportDestBtn.SetMinSize((-1, 23))
self.m2e_copyTexPathBtn.SetMinSize((-1, 23))
self.m2e_pathReplaceBtn.SetMinSize((-1, 23))
self.m2e_startFrameSpin.SetMinSize((-1, 21))
self.m2e_endFrameSpin.SetMinSize((-1, 21))
self.m2e_frameRateInSpin.SetMinSize((-1, 21))
@ -745,7 +745,7 @@ class main(wx.Frame):
self.e2b_eggFileTxt.SetMinSize((230, 21))
self.e2b_exportDestTxt.SetMinSize((230, 21))
self.egg2bam_panel.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE))
self.e2b_eggFileBtn.SetMinSize((-1, 23))
self.e2b_exportDestBtn.SetMinSize((-1, 23))
self.e2b_bamBatchOutputBtn.SetMinSize((-1, 23))
@ -771,7 +771,7 @@ class main(wx.Frame):
self.rename_exportDirTxt.SetMinSize((230, 21))
self.rename_exportFileTxt.SetMinSize((230, 21))
self.rename_stripPrefixTxt.SetMinSize((260, 21))
self.rename_addEggBtn.SetMinSize((-1, 23))
self.rename_addFromBatchBtn.SetMinSize((-1, 23))
self.rename_removeEggBtn.SetMinSize((-1, 23))
@ -791,7 +791,7 @@ class main(wx.Frame):
self.optchar_dropJointsTxt.SetMinSize((245, 21))
self.optchar_exposeJointsTxt.SetMinSize((245, 21))
self.optchar_flagGeometryTxt.SetMinSize((245, 21))
self.optchar_addEggBtn.SetMinSize((-1, 23))
self.optchar_addFromBatchBtn.SetMinSize((-1, 23))
self.optchar_removeEggBtn.SetMinSize((-1, 23))
@ -1394,7 +1394,7 @@ class main(wx.Frame):
# Simple Export Panel Functions
################################
def OnSimpleExport(self,e):
#This is essentially the same behavior as a batch export
#build up the dictionary that gets passed to Run Export
@ -1441,7 +1441,7 @@ class main(wx.Frame):
# Maya2Egg Panel Functions
###########################
def OnMaya2EggMayaFile(self, event):
#choose input maya scene for maya2egg
filename = ''
@ -1458,7 +1458,7 @@ class main(wx.Frame):
self.m2e_mayaFileTxt.SetValue(os.path.join(self.srcProjectFolder + os.sep , filename)) #this is for a text control
dlg.Destroy() #otherwise just kill the file dialog
self.statusBar.SetStatusText("Current Scene File is: " + self.srcProjectFolder + os.sep + filename)
def OnMaya2EggExportDest(self, event):
#choose output egg for maya2egg
filename = ''
@ -1501,7 +1501,7 @@ class main(wx.Frame):
self.m2e_copyTexPathTxt.SetValue(dlg.GetPath())
dlg.Destroy() #otherwise just kill the file dialog
#self.statusBar.SetStatusText("Current Egg File is: " + dirname + '\\' + filename)
def OnMaya2EggPathReplace(self,event):
batchList = self.GetSelectedBatchList()
for batchItem in batchList:
@ -1533,7 +1533,7 @@ class main(wx.Frame):
dlg = wx.FileDialog(self, "Choose an Egg file to load", dirname, "", "*.bam", wx.SAVE)
if dlg.ShowModal() == wx.ID_OK: #if the user clicked ok then we grabbed a file so load it
self.filename = dlg.GetFilename()
dirname = dlg.GetDirectory()
dirname = dlg.GetDirectory()
self.e2b_exportDestTxt.SetValue(os.path.join(dirname + os.sep , self.filename)) #this is for a text control duh
dlg.Destroy() #otherwise just kill the file dialog
@ -1545,7 +1545,7 @@ class main(wx.Frame):
else:
self.e2b_eggFileTxt.Disable()
self.e2b_eggFileBtn.Disable()
def OnEgg2BamBatchOutput(self, event):
for eggInfo in self.GetOutputFromBatch():
batchItemInfo = {}
@ -1622,7 +1622,7 @@ class main(wx.Frame):
self.rename_eggFilesTree.AppendItem(self.rename_eggFilesRoot, str(index) + ' ' + str(treeitem))
self.rename_eggFilesTree.ExpandAll()
self.OnRenameInPlace(None)
def OnRenameInPlace(self, event):
#check if we want to use a custom egg file or not for egg-rename panel
if (self.rename_exportInPlaceChk.GetValue()):
@ -1671,7 +1671,7 @@ class main(wx.Frame):
dlg.Destroy()
# Egg-Optchar Panel Functions
##############################
@ -1692,7 +1692,7 @@ class main(wx.Frame):
dlg.Destroy() #otherwise just kill the file dialog
self.statusBar.SetStatusText("The input egg File is: " + dirname + os.sep + filename)
self.OnOptcharInPlace(None)
def OnOptcharAddFromBatch(self, event):
for eggInfo in self.GetOutputFromBatch():
self.optchar_eggList.append(eggInfo)
@ -1710,7 +1710,7 @@ class main(wx.Frame):
self.optchar_eggFilesTree.Delete(item)
self.UpdateEggOptcharDisplay()
self.OnOptcharInPlace(None)
def OnOptcharRemoveAllEggs(self, event):
#remove all input egg files from eggs list in egg-optchar panel
self.optchar_eggFilesTree.DeleteAllItems()
@ -1768,7 +1768,7 @@ class main(wx.Frame):
if dlg.ShowModal() == wx.ID_OK: #if the user clicked ok then we grabbed a file so load it
self.optchar_exportDirTxt.SetValue(dlg.GetPath())
dlg.Destroy()
# Egg-Palettize Panel Functions
################################
@ -1789,14 +1789,14 @@ class main(wx.Frame):
dlg.Destroy() #otherwise just kill the file dialog
self.OnPalettizeInPlace(None)
def OnPalettizeAddFromBatch(self, event):
for eggInfo in self.GetOutputFromBatch():
self.palettize_eggList.append(eggInfo)
self.palettize_eggFilesTree.AppendItem(self.palettize_eggFilesRoot, str(len(self.palettize_eggList)) + ' ' + eggInfo)
self.palettize_eggFilesTree.ExpandAll()
self.OnPalettizeInPlace(None)
def OnPalettizeRemoveEgg(self,e):
#remove selected input egg file from multiple eggs panel in egg-palettize panel
item = self.palettize_eggFilesTree.GetSelection()
@ -1872,7 +1872,7 @@ class main(wx.Frame):
if dlg.ShowModal() == wx.ID_OK: #if the user clicked ok then we grabbed a file so load it
self.palettize_exportTexTxt.SetValue(dlg.GetPath())
dlg.Destroy()
def OnPalettizeLoadTxa(self, event):
dirname = ''
dlg = wx.FileDialog(self, "Choose a .txa file to use", dirname, "", "*.txa", wx.OPEN)
@ -1954,7 +1954,7 @@ class main(wx.Frame):
# Batch Related Functions
##########################
def GetSelectedBatchList(self):
batchList = []
selectedItems = self.batchTree.GetSelections()
@ -1963,7 +1963,7 @@ class main(wx.Frame):
batchList.append(self.batchList[selectedItemIndex])
if not len(batchList):
batchList = self.batchList
return batchList
def GetOutputFromBatch(self, index=-1):
@ -2226,7 +2226,7 @@ class main(wx.Frame):
return args
def BuildEgg2BamArgs(self):
#Build up all the command line arguments present in the egg2bam panel
#Build up all the command line arguments present in the egg2bam panel
args = {}
if (self.e2b_flattenChk.GetValue()):
@ -2271,7 +2271,7 @@ class main(wx.Frame):
args['dart'] = self.optchar_dartChoice.GetStringSelection()
return args
def BuildEggPalettizeArgs(self):
args = {}
@ -2355,7 +2355,7 @@ class main(wx.Frame):
def UpdateBatchDisplay(self):
#update the display of the batch list
#For now just re calculate the entire list order
self.batchTree.DeleteAllItems()
self.treeRoot = self.batchTree.AddRoot('Batch Files')
@ -2372,21 +2372,21 @@ class main(wx.Frame):
if self.batchList != []:
self.batchList = []
self.treeRoot = self.batchTree.AddRoot('Batch Files') #rather than loop through it re-add the root
def OnClearOutput(self, event):
#clear the console output content
self.consoleOutputTxt.Clear()
def OnExit(self, e):
#exit the GUI
self.Close(True)
def OnLoadPview(self, event):
#load pview
path = self.pandaPathTxt.GetValue() + os.sep + 'bin' + os.sep
self.outpview = OutputDialogpview(self)
self.outpview.Show()
def OnSortBatch(self, event):
maya2eggCommands = []
egg2bamCommands = []
@ -2435,9 +2435,9 @@ class main(wx.Frame):
if batchItem['finput'].count(inPrefix):
pass
def OnSaveBatch(self,event):
#save current batch list
#save current batch list
newdoc = Document()
top_element = newdoc.createElement('batch')
newdoc.appendChild(top_element)
@ -2795,7 +2795,7 @@ class main(wx.Frame):
self.optchar_flagGeometryChk.SetValue(batchItem['args'].has_key('flag'))
self.optchar_flagGeometryTxt.SetValue('' if not batchItem['args'].has_key('flag') else batchItem['args']['flag'])
self.optchar_dartChoice.SetStringSelection(batchItem['args']['dart'])
elif (batchItem['cmd'].count('egg-palettize')):
self.toolComboBox.SetStringSelection('egg-palettize')
self.OnTool(None)
@ -2891,7 +2891,7 @@ class main(wx.Frame):
top_element.appendChild(texitem)
top_element.appendChild(overitem)
top_element.appendChild(attributeitem)
pandadir = newdoc.createTextNode(str(self.pandaPathTxt.GetValue()))
mayaver = newdoc.createTextNode(str(self.m2e_mayaVerComboBox.GetSelection()))
pandadirElem = newdoc.createElement('pandadir')
@ -2900,7 +2900,7 @@ class main(wx.Frame):
mayaverElem.appendChild(mayaver)
envitem.appendChild(pandadirElem)
envitem.appendChild(mayaverElem)
inunits = newdoc.createTextNode(str(self.m2e_mayaUnitsComboBox.GetValue()))
outunits = newdoc.createTextNode(str(self.m2e_pandaUnitsComboBox.GetValue()))
bface = newdoc.createTextNode(str(int(self.m2e_backfaceChk.GetValue())))
@ -2909,7 +2909,7 @@ class main(wx.Frame):
subsetsval = newdoc.createTextNode(str(self.m2e_subsetsTxt.GetValue()))
excludes = newdoc.createTextNode(str(int(self.m2e_excludesChk.GetValue())))
excludesval = newdoc.createTextNode(str(self.m2e_excludesTxt.GetValue()))
inunitsElem = newdoc.createElement('inunits')
outunitsElem = newdoc.createElement('outunits')
bfaceElem = newdoc.createElement('bface')
@ -2918,7 +2918,7 @@ class main(wx.Frame):
subnamesElem = newdoc.createElement('subnames')
excludesElem = newdoc.createElement('excludes')
exnamesElem = newdoc.createElement('excludesval')
inunitsElem.appendChild(inunits)
outunitsElem.appendChild(outunits)
bfaceElem.appendChild(bface)
@ -2927,7 +2927,7 @@ class main(wx.Frame):
subnamesElem.appendChild(subsetsval)
excludesElem.appendChild(excludes)
exnamesElem.appendChild(exnamesElem)
genitem.appendChild(inunitsElem)
genitem.appendChild(outunitsElem)
genitem.appendChild(bfaceElem)
@ -2937,7 +2937,7 @@ class main(wx.Frame):
genitem.appendChild(excludesElem)
genitem.appendChild(exnamesElem)
modeloptsElem = newdoc.createElement('modelopts')
cnElem = newdoc.createElement('cn')
charnameElem = newdoc.createElement('charname')
@ -2960,7 +2960,7 @@ class main(wx.Frame):
framerangeElem.appendChild(frivalElem)
framerangeElem.appendChild(froElem)
framerangeElem.appendChild(frovalElem)
modelopts = newdoc.createTextNode(str(self.m2e_animOptChoice.GetSelection()))
cn = newdoc.createTextNode(str(int(self.m2e_charNameChk.GetValue())))
charname = newdoc.createTextNode(str(self.m2e_charNameTxt.GetValue()))
@ -2968,7 +2968,7 @@ class main(wx.Frame):
modeloptsElem.appendChild(modelopts)
cnElem.appendChild(cn)
charnameElem.appendChild(charname)
sf = newdoc.createTextNode(str(int(self.m2e_startFrameChk.GetValue())))
sfval = newdoc.createTextNode(str(self.m2e_startFrameSpin.GetValue()))
ef = newdoc.createTextNode(str(int(self.m2e_endFrameChk.GetValue())))
@ -2977,7 +2977,7 @@ class main(wx.Frame):
frival = newdoc.createTextNode(str(self.m2e_frameRateInSpin.GetValue()))
fro = newdoc.createTextNode(str(int(self.m2e_frameRateOutChk.GetValue())))
froval = newdoc.createTextNode(str(self.m2e_frameRateOutSpin.GetValue()))
sfElem.appendChild(sf)
sfvalElem.appendChild(sfval)
efElem.appendChild(ef)
@ -2986,30 +2986,30 @@ class main(wx.Frame):
frivalElem.appendChild(frival)
froElem.appendChild(fro)
frovalElem.appendChild(froval)
subroots = newdoc.createTextNode(str(int(self.m2e_subrootsChk.GetValue())))
subrnames = newdoc.createTextNode(str(self.m2e_subrootsTxt.GetValue()))
subrootsElem.appendChild(subroots)
subrnamesElem.appendChild(subrnames)
animitem.appendChild(modeloptsElem)
animitem.appendChild(cnElem)
animitem.appendChild(charnameElem)
animitem.appendChild(framerangeElem)
animitem.appendChild(subrootsElem)
animitem.appendChild(subrnamesElem)
legacy_shaderElem = newdoc.createElement('legacy-shader')
copytexElem = newdoc.createElement('copytex')
destpathElem = newdoc.createElement('path')
legacy_shader = newdoc.createTextNode(str(int(self.m2e_legacyShaderChk.GetValue())))
copytex = newdoc.createTextNode(str(int(self.m2e_copyTexChk.GetValue())))
destpath = newdoc.createTextNode(str(self.m2e_copyTexPathTxt.GetValue()))
legacy_shaderElem.appendChild(legacy_shader)
copytexElem.appendChild(copytex)
destpathElem.appendChild(destpath)
texitem.appendChild(legacy_shaderElem)
texitem.appendChild(copytexElem)
texitem.appendChild(destpathElem)
@ -3033,7 +3033,7 @@ class main(wx.Frame):
AElem = newdoc.createElement('A')
marginElem = newdoc.createElement('margin')
coverageElem = newdoc.createElement('coverage')
imagetypeElem.appendChild(imagetype)
powertwoElem.appendChild(powertwo)
RElem.appendChild(R)
@ -3042,7 +3042,7 @@ class main(wx.Frame):
AElem.appendChild(A)
marginElem.appendChild(margin)
coverageElem.appendChild(coverage)
attributeitem.appendChild(imagetypeElem)
attributeitem.appendChild(powertwoElem)
attributeitem.appendChild(RElem)
@ -3051,7 +3051,7 @@ class main(wx.Frame):
attributeitem.appendChild(AElem)
attributeitem.appendChild(marginElem)
attributeitem.appendChild(coverageElem)
filename = ''
dirname = ''
dlg = wx.FileDialog(self, "Choose a location and filename", dirname, "", "*.xml", wx.SAVE)
@ -3065,7 +3065,7 @@ class main(wx.Frame):
for line in out:
f.writelines(line)
f.close()
def OnLoadPrefs(self, event): # wxGlade: main.<event_handler>
#load preferences
dirname = ''
@ -3083,14 +3083,14 @@ class main(wx.Frame):
#parse the file of preferences
prefsDict = {}
for list in doc.getElementsByTagName('preferences'):
envlist = list.getElementsByTagName('environment')
genlist = list.getElementsByTagName('genoptions')
animlist = list.getElementsByTagName('animoptions')
texlist = list.getElementsByTagName('textureoptions')
overlist = list.getElementsByTagName('overridemod')
attributelist = list.getElementsByTagName('attribute')
for elem in envlist:
for nodes in elem.childNodes:
for val in nodes.childNodes:
@ -3112,7 +3112,7 @@ class main(wx.Frame):
for elem in animlist:
for elem2 in elem.childNodes:
for elem3 in elem2.childNodes:
data = elem3
data = elem3
parent = str(elem3.parentNode.nodeName)
if parent == 'framerange':
list = data.childNodes
@ -3134,15 +3134,15 @@ class main(wx.Frame):
for val in nodes.childNodes:
key = val.parentNode.nodeName
data = str(val.data)
prefsDict[str(key)] = data.strip()
prefsDict[str(key)] = data.strip()
return prefsDict
def updateOptions(self,prefs):
#lots of type conversions since I think XML only stores strings
#I'm not sure I have to cast the ints to bools
#but I don't want to chance it with wxPython
#other than that all we're doing here is
#but I don't want to chance it with wxPython
#other than that all we're doing here is
#setting all the options to the saved ones in the dictionary
self.pandaPathTxt.SetValue(prefs['pandadir'])
self.m2e_mayaVerComboBox.SetSelection(int(prefs['mayaver']))
@ -3180,7 +3180,7 @@ class main(wx.Frame):
self.palettize_marginTxt.SetValue(int(prefs['margin']))
self.palettize_coverageTxt.SetValue(prefs['coverage'])
if __name__ == "__main__":
app = wx.App(0)
wx.InitAllImageHandlers()

View File

@ -19,7 +19,7 @@ class AlignTool(AppShell):
padx = 0
pady = 0
def __init__(self, list = [], parent = None, nodePath = None, **kw):
# Keep nodePath Data
self.nodePath = nodePath
@ -36,14 +36,14 @@ class AlignTool(AppShell):
self.parent = Toplevel()
AppShell.__init__(self, self.parent)
self.parent.geometry('%dx%d+%d+%d' % (self.frameWidth, self.frameHeight,self.frameIniPosX,self.frameIniPosY))
self.initialiseoptions(AlignTool)
self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
def appInit(self):
return
def createInterface(self):
# The interior of the toplevel panel
interior = self.interior()
@ -77,14 +77,14 @@ class AlignTool(AppShell):
variable = self.alignHVar)
self.alignHButton.pack(side=RIGHT, expand=False)
frame.pack(side=TOP, fill = X, expand = 1,pady=5)
groupFrame.pack(side=TOP, fill = 'both', expand = 1,padx=5,pady=5)
frame = Frame(mainFrame)
Button(frame, text='Align', width = 13, command=self.Align_press).pack(side=LEFT)
Button(frame, text='OK', width = 13, command=self.ok_press).pack(side=RIGHT)
frame.pack(side=BOTTOM, fill = X, expand = 1,pady=5)
# Y and P checkbox
frame = Frame(groupFrame)
self.alignYVar = IntVar()
@ -149,14 +149,14 @@ class AlignTool(AppShell):
variable = self.alignSZVar)
self.alignSZButton.pack(side=LEFT, expand=False)
frame.pack(side=TOP, fill = X, expand = 1,pady=5)
mainFrame.pack(fill = 'both', expand = 1,padx=7,pady=7)
def createMenuBar(self):
self.menuBar.destroy()
def onDestroy(self, event):
messenger.send('ALW_close', [self.nodePath.getName()])
'''
@ -165,7 +165,7 @@ class AlignTool(AppShell):
pass
###############################
def ok_press(self):
#################################################################
# ok_press(self)

View File

@ -12,13 +12,13 @@ class MetadataPanel(AppShell,Pmw.MegaWidget):
usecommandarea = 0
usestatusarea = 0
Metatag=""
Metanode=None
Metanode=None
tag_text=None
def __init__(self,nodePath,parent=None,**kw):
# Initialise superclass
Pmw.MegaWidget.__init__(self, parent)
# Define the megawidget options.
optiondefs = (
('title', self.appname, None),
@ -31,10 +31,10 @@ class MetadataPanel(AppShell,Pmw.MegaWidget):
if parent == None:
self.parent = Toplevel()
AppShell.__init__(self, self.parent)
self.parent.resizable(False,False)
def appInit(self):
print "Metadata Panel"
@ -55,5 +55,5 @@ class MetadataPanel(AppShell,Pmw.MegaWidget):
def SetIt(self):
self.Metanode.setTag("Metadata",self.tag_text.get())

View File

@ -31,9 +31,9 @@ class sideWindow(AppShell):
backface = 0
texture = 1
wireframe = 0
enableBaseUseDrive = 0
def __init__(self, worldColor,lightEnable,ParticleEnable, basedriveEnable,collision,
backface, texture, wireframe, grid, widgetVis, enableAutoCamera, parent = None, nodePath = render, **kw):
self.worldColor = worldColor
@ -58,15 +58,15 @@ class sideWindow(AppShell):
self.parent = Toplevel()
else:
self.parent = parent
AppShell.__init__(self, self.parent)
self.parent.geometry('%dx%d+%d+%d' % (self.frameWidth, self.frameHeight,self.frameIniPosX,self.frameIniPosY))
self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
def appInit(self):
print '----SideWindow is Initialized!!'
def createInterface(self):
# The interior of the toplevel panel
interior = self.interior()
@ -212,11 +212,11 @@ class sideWindow(AppShell):
self.notebookFrame.setnaturalsize()
mainFrame.pack(fill = 'both', expand = 1)
def createMenuBar(self):
# We don't need menu bar here.
self.menuBar.destroy()
def onDestroy(self, event):
#################################################################
# onDestroy(self, event)
@ -352,7 +352,7 @@ class sideWindow(AppShell):
self.backface = (self.backface+1)%2
self.backfaceButton.toggle()
return
def toggleTexture(self):
#################################################################
# toggleTexture(self)
@ -361,7 +361,7 @@ class sideWindow(AppShell):
base.toggleTexture()
self.texture = (self.texture+1)%2
return
def toggleTextureFromMainW(self):
#################################################################
# toggleTextureFromMainW(self)
@ -373,7 +373,7 @@ class sideWindow(AppShell):
self.texture = (self.texture+1)%2
self.textureButton.toggle()
return
def toggleWireframe(self):
#################################################################
# toggleWireframe(self)
@ -428,7 +428,7 @@ class sideWindow(AppShell):
self.widgetVis = (self.widgetVis+1)%2
self.widgetVisButton.toggle()
return
def setBackgroundColorVec(self,color):
#################################################################
# setBackgroundColorVec(self,color)

View File

@ -32,12 +32,12 @@ class collisionWindow(AppShell):
'collisionSphere',
'collisionSegment',
'collisionRay']
def __init__(self, nodePath, parent = None, **kw):
self.nodePath = nodePath
self.objType = 'collisionSphere' # set default type to Collision Sphere
INITOPT = Pmw.INITOPT
optiondefs = (
('title', self.appname, None),
@ -77,7 +77,7 @@ class collisionWindow(AppShell):
frame.pack(side=TOP, fill=X, expand=True, padx=3)
self.collisionTypeEntry.selectitem('collisionSphere', setentry=True)
self.inputZone = Pmw.Group(mainFrame, tag_pyclass = None)
self.inputZone.pack(fill='both',expand=1)
settingFrame = self.inputZone.interior()
@ -101,7 +101,7 @@ class collisionWindow(AppShell):
label = Label(Interior, text='Attention! All Coordinates Are Related To Its Parent Node!')
label.pack(side=LEFT,expand=0,fill=X, padx=1)
Interior.pack(side=TOP, expand=0,fill=X)
self.createPosEntry(PolygonPage, catagory='Polygon', id='Point A')
self.createPosEntry(PolygonPage, catagory='Polygon', id='Point B')
self.createPosEntry(PolygonPage, catagory='Polygon', id='Point C')
@ -112,7 +112,7 @@ class collisionWindow(AppShell):
label = Label(Interior, text='Attention! All Coordinates Are Related To Its Parent Node!')
label.pack(side=LEFT,expand=0,fill=X, padx=1)
Interior.pack(side=TOP, expand=0,fill=X)
self.createPosEntry(SpherePage, catagory='Sphere', id='Center Point')
self.createEntryField(SpherePage,catagory='Sphere', id='Size',
@ -127,7 +127,7 @@ class collisionWindow(AppShell):
label = Label(Interior, text='Attention! All Coordinates Are Related To Its Parent Node!')
label.pack(side=LEFT,expand=0,fill=X, padx=1)
Interior.pack(side=TOP, expand=0,fill=X)
self.createPosEntry(SegmentPage, catagory='Segment', id='Point A')
self.createPosEntry(SegmentPage, catagory='Segment', id='Point B')
@ -137,12 +137,12 @@ class collisionWindow(AppShell):
label = Label(Interior, text='Attention! All Coordinates Are Related To Its Parent Node!')
label.pack(side=LEFT,expand=0,fill=X, padx=1)
Interior.pack(side=TOP, expand=0,fill=X)
self.createPosEntry(RayPage, catagory='Ray', id='Origin')
self.createPosEntry(RayPage, catagory='Ray', id='Direction')
self.objNotebook.setnaturalsize()
self.objNotebook.pack(expand = 1, fill = BOTH)
@ -175,7 +175,7 @@ class collisionWindow(AppShell):
self.objNotebook.selectpage('Segment')
elif self.objType=='collisionRay':
self.objNotebook.selectpage('Ray')
return
def updateObjInfo(self, page=None):
@ -207,13 +207,13 @@ class collisionWindow(AppShell):
float(self.widgetDict['PolygonPoint C'][1]._entry.get()),
float(self.widgetDict['PolygonPoint C'][2]._entry.get()))
collisionObject = CollisionPolygon(pointA, pointB, pointC)
elif self.objType=='collisionSphere':
collisionObject = CollisionSphere(float(self.widgetDict['SphereCenter Point'][0]._entry.get()),
float(self.widgetDict['SphereCenter Point'][1]._entry.get()),
float(self.widgetDict['SphereCenter Point'][2]._entry.get()),
float(self.widgetDict['SphereSize'].getvalue()))
elif self.objType=='collisionSegment':
pointA = Point3(float(self.widgetDict['SegmentPoint A'][0]._entry.get()),
float(self.widgetDict['SegmentPoint A'][1]._entry.get()),
@ -221,35 +221,35 @@ class collisionWindow(AppShell):
pointB = Point3(float(self.widgetDict['SegmentPoint B'][0]._entry.get()),
float(self.widgetDict['SegmentPoint B'][1]._entry.get()),
float(self.widgetDict['SegmentPoint B'][2]._entry.get()))
collisionObject = CollisionSegment()
collisionObject.setPointA(pointA)
collisionObject.setFromLens(base.cam.node(), Point2( -1, 1 )) ## You must set up the camera lensNode before you set point B....
collisionObject.setPointB(pointB)
elif self.objType=='collisionRay':
point = Point3(float(self.widgetDict['RayOrigin'][0]._entry.get()),
float(self.widgetDict['RayOrigin'][1]._entry.get()),
float(self.widgetDict['RayOrigin'][2]._entry.get()))
vector = Vec3(float(self.widgetDict['RayDirection'][0]._entry.get()),
float(self.widgetDict['RayDirection'][1]._entry.get()),
float(self.widgetDict['RayDirection'][2]._entry.get()))
print vector, point
collisionObject = CollisionRay()
collisionObject.setOrigin(point)
collisionObject.setDirection(vector)
#collisionObject.setFromLens(base.cam.node(), Point2( -1, 1 )) ## You must set up the camera lensNode before you set up others...
if self.objType=='collisionPolygon':
messenger.send('CW_addCollisionObj', [collisionObject, self.nodePath, pointA, pointB, pointC])
else:
messenger.send('CW_addCollisionObj', [collisionObject, self.nodePath])
self.quit()
return
def createPosEntry(self, contentFrame, catagory, id):
@ -261,16 +261,16 @@ class collisionWindow(AppShell):
text = 'X', relief = FLAT,
value = 0.0,
entry_width = 6)
self.posX.pack(side=LEFT,expand=0,fill=X, padx=1)
self.posY = self.createcomponent('posY'+catagory+id, (), None,
Floater.Floater, (posInterior,),
text = 'Y', relief = FLAT,
value = 0.0,
entry_width = 6)
self.posY.pack(side=LEFT, expand=0,fill=X, padx=1)
self.posZ = self.createcomponent('posZ'+catagory+id, (), None,
Floater.Floater, (posInterior,),
text = 'Z', relief = FLAT,
@ -298,5 +298,5 @@ class collisionWindow(AppShell):
widget = Button(frame, text=buttonText, font=('MSSansSerif', 10), command = defaultFunction)
widget.pack(side=LEFT, padx=3)
self.widgetDict[catagory+id+'-'+'DefaultButton']=widget
frame.pack(side = side, fill = fill, expand = expand,pady=3)

View File

@ -16,7 +16,7 @@ class controllerWindow(AppShell):
# This will open a talk window for user to set the control mechanism
# In here, user can choose to control what object by keyboard or other inputs.
#################################################################
# Override class variables
appname = 'Controller Panel'
frameWidth = 500
@ -27,11 +27,11 @@ class controllerWindow(AppShell):
# setup the type of controller we handle here.
controllerList = ['Keyboard',
'Tracker']
# Default Keyboard setting
keyboardMapDict = {}
keyboardSpeedDict = {}
def __init__(self, listOfObj, controlType , dataList, parent = None, **kw):
if controlType == 'Keyboard':
self.nodePath = dataList[0] # Default setting -> mainly used for Keyboard control now.
@ -41,10 +41,10 @@ class controllerWindow(AppShell):
self.keyboardMapDict = dataList[1]
self.keyboardSpeedDict.clear()
self.keyboardSpeedDict = dataList[2]
self.listOfObj = listOfObj
self.keepControl = False
INITOPT = Pmw.INITOPT
optiondefs = (
('title', self.appname, None),
@ -63,9 +63,9 @@ class controllerWindow(AppShell):
# Handle to the toplevels interior
interior = self.interior()
menuBar = self.menuBar
# We don't need menu bar here
self.menuBar.destroy()
self.menuBar.destroy()
# Create a frame to hold all stuff
mainFrame = Frame(interior)
@ -81,7 +81,7 @@ class controllerWindow(AppShell):
self.cotrollerTypeEntry.pack(side=Tkinter.LEFT)
frame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=False, pady = 3)
self.cotrollerTypeEntry.selectitem('Keyboard', setentry=True)
self.inputZone = Pmw.Group(mainFrame, tag_pyclass = None)
self.inputZone.pack(fill='both',expand=1)
settingFrame = self.inputZone.interior()
@ -124,11 +124,11 @@ class controllerWindow(AppShell):
inputZone = Pmw.Group(assignFrame, tag_pyclass = None)
inputZone.pack(fill='both',expand=1)
settingFrame = inputZone.interior()
Interior = Frame(settingFrame)
widget = Label(Interior, text = 'Assign a Key For:').pack(side=Tkinter.LEFT, expand = False)
Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True,pady = 6 )
Interior = Frame(settingFrame)
widget = Label(Interior, text = 'Forward :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False)
widget = self.createcomponent(
@ -531,7 +531,7 @@ class controllerWindow(AppShell):
assignFrame.pack(side=Tkinter.TOP, expand=True, fill = Tkinter.X)
keyboardPage.pack(side=Tkinter.TOP, expand=True, fill = Tkinter.X)
####################################################################
####################################################################
# End of Keyboard control page
@ -613,7 +613,7 @@ class controllerWindow(AppShell):
self.objNotebook.selectpage('Keyboard')
elif self.controllType=='Tracker':
self.objNotebook.selectpage('Tracker')
return
def updateControlInfo(self, page=None):
@ -692,4 +692,4 @@ class controllerWindow(AppShell):
messenger.send('ControlW_saveSetting', ['Keyboard', [self.nodePath, self.keyboardMapDict, self.keyboardSpeedDict]])
return

View File

@ -117,10 +117,10 @@ class dataHolder:
# Initialize the basic message formate from CollisionHandler
self.CollisionHandler.setInPattern("%fnenter%in")
self.CollisionHandler.setOutPattern("%fnexit%in")
pass
def resetAll(self):
#################################################################
# resetAll(self)
@ -149,7 +149,7 @@ class dataHolder:
self.blendAnimDict.clear()
self.particleDict.clear()
self.particleNodes.clear()
self.ModelNum=0
self.ActorNum=0
self.theScene=None
@ -167,8 +167,8 @@ class dataHolder:
## Check if there is any child node, if so, remove it.
childrenList = nodePath.getChildren()
if self.ModelDic.has_key(name):
del self.ModelDic[name]
del self.ModelRefDic[name]
@ -214,7 +214,7 @@ class dataHolder:
else:
print 'You cannot remove this NodePath'
return
messenger.send('SGE_Update Explorer',[render])
return
@ -247,11 +247,11 @@ class dataHolder:
else:
print '---- DataHolder: Target Obj is not a legal object could be duplicate!'
return
FilePath = holderRef[name]
oPos = holder[name].getPos()+cPos
oHpr = holder[name].getHpr()+cHpr
for i in range(num):
if isModel:
### copy model node from modelpool
@ -268,7 +268,7 @@ class dataHolder:
holder[newName].setName(newName)
oPos = oPos + cPos
oHpr = oHpr + cHpr
else:
### copy the actor- not includ its animations
'''
@ -289,7 +289,7 @@ class dataHolder:
holder[newName].setName(newName)
oPos = oPos + cPos
oHpr = oHpr + cHpr
messenger.send('SGE_Update Explorer',[render])
return
@ -434,7 +434,7 @@ class dataHolder:
###########################################################################
self.lightManager.toggle()
return
def isLight(self,name):
###########################################################################
# isLight(self, name)
@ -519,10 +519,10 @@ class dataHolder:
if oName == nName:
# If the new name is the same with old name, do nothing.
return
while self.isInScene(nName):
nName = nName + '_1'
if self.isActor(oName):
self.ActorDic[nName]= self.ActorDic[oName]
self.ActorRefDic[nName]= self.ActorRefDic[oName]
@ -548,7 +548,7 @@ class dataHolder:
self.collisionDict[nName]= self.collisionDict[oName]
self.collisionDict[nName].setName(nName)
del self.collisionDict[oName]
elif self.particleNodes.has_key(oName):
self.particleNodes[nName]= self.particleNodes[oName]
self.particleDict[nName]= self.particleDict[oName]
@ -588,7 +588,7 @@ class dataHolder:
return True
return False
def bindCurveToNode(self,node,curveCollection):
###########################################################################
# bindCurveToNode(self,node,curveCollection)
@ -664,7 +664,7 @@ class dataHolder:
info['vFov'] = lens.getVfov()
info['focalLength'] = lens.getFocalLength()
elif name == 'SEditor':
type = 'Special'
elif self.isActor(name):
@ -684,7 +684,7 @@ class dataHolder:
info['collisionNode'] = self.collisionDict[name]
if self.curveDict.has_key(name):
info['curveList'] = self.getCurveList(nodePath)
return type, info
def getAnimationDictFromActor(self, actorName):
@ -754,7 +754,7 @@ class dataHolder:
base.cTrav.addCollider( self.collisionDict[name], self.CollisionHandler)
messenger.send('SGE_Update Explorer',[render])
return
def toggleCollisionVisable(self, visable):
@ -888,7 +888,7 @@ class dataHolder:
return self.particleNodes[name]
elif self.lightManager.isLight(name):
return self.lightManager.getLightNode(name)
return None
def getControlSetting(self):
@ -923,7 +923,7 @@ class dataHolder:
self.keyboardSpeedDict.clear()
self.keyboardSpeedDict = data[2].copy()
return
def loadScene(self):
###########################################################################
# loadScene(self)
@ -934,9 +934,9 @@ class dataHolder:
# in the scene file hence reviving the state for the scene
###########################################################################
### Ask for a filename
### Ask for a filename
OpenFilename = tkFileDialog.askopenfilename(filetypes = [("PY","py")],title = "Load Scene")
if(not OpenFilename):
if(not OpenFilename):
return None
f=Filename.fromOsSpecific(OpenFilename)
fileName=f.getBasenameWoExtension()
@ -953,7 +953,7 @@ class dataHolder:
############################################################################
self.theScene=__import__(fileName)
self.Scene=self.theScene.SavedScene(0,seParticleEffect,seParticles,dirName) # Specify load mode of 0 which will allow us to pass seParticle and seParticleEffect
messenger.send('SGE_Update Explorer',[render])
messenger.send('SGE_Update Explorer',[render])
# Lets call some important initialization methods on our scene:
@ -989,7 +989,7 @@ class dataHolder:
for light in self.Scene.LightDict:
#print light
alight=self.Scene.LightDict[light]
type=self.Scene.LightTypes[light]
type=self.Scene.LightTypes[light]
thenode=self.Scene.LightNodes[light]
#print type
if type == 'ambient':
@ -1032,7 +1032,7 @@ class dataHolder:
nodeP.removeNode()
thenode=render.find("**/"+str(node))
self.bindCurveToNode(thenode,curveColl)
############################################################################
# Populate Particle related Dictionaries
############################################################################
@ -1049,9 +1049,9 @@ class dataHolder:
theeffect.enable()
self.particleDict[effect]=theeffect
self.particleNodes[effect]=emitter
# Clean up things added to scene graph by saved file's code execution
for light in self.Scene.LightDict:
vestige=render.find('**/'+light)
@ -1061,11 +1061,11 @@ class dataHolder:
############################################################################
# return the filename and update the scenegraph explorer window
############################################################################
messenger.send('SGE_Update Explorer',[render])
messenger.send('SGE_Update Explorer',[render])
if(OpenFilename):
return OpenFilename
else:
return None
def getList(self):
return self.lightManager.getList()
return self.lightManager.getList()

View File

@ -27,7 +27,7 @@ class duplicateWindow(AppShell):
padx = 0
pady = 0
def __init__(self, parent = None, nodePath = None, **kw):
# Define the megawidget options.
optiondefs = (
@ -43,10 +43,10 @@ class duplicateWindow(AppShell):
self.nodePath = nodePath
self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
def appInit(self):
print '----SideWindow is Initialized!!'
def createInterface(self):
# The interior of the toplevel panel
interior = self.interior()
@ -90,18 +90,18 @@ class duplicateWindow(AppShell):
self.numberOfCopy = Pmw.EntryField(settingFrame,label_text='Number of Copy :',labelpos='w',value='1', validate=Pmw.integervalidator)
self.numberOfCopy.component('entry').config(width=15)
self.numberOfCopy.place(anchor=NW,x=52,y=150)
settingFrame.pack(fill=BOTH,expand=1,padx=7,pady=7)
self.button_ok = Button(mainFrame, text="OK", command=self.ok_press,width=10)
self.button_ok.pack(fill=BOTH,expand=0,side=RIGHT)
mainFrame.pack(fill = 'both', expand = 1,padx=7,pady=7)
def createMenuBar(self):
self.menuBar.destroy()
def onDestroy(self, event):
messenger.send('DW_close')
'''
@ -110,7 +110,7 @@ class duplicateWindow(AppShell):
pass
###############################
def ok_press(self):
#################################################################
# ok_press(self)

View File

@ -22,7 +22,7 @@ class lightingPanel(AppShell):
frameWidth = 400
frameHeight = 400
currentLight = None
def __init__(self, lightList, parent = None, **kw):
self.lightList = lightList
self.lightColor = [0.3*255,0.3*255,0.3*255]
@ -53,14 +53,14 @@ class lightingPanel(AppShell):
self.listZone = Pmw.Group(mainFrame,tag_pyclass = None)
self.listZone.pack(expand=0, fill=Tkinter.X,padx=3,pady=3)
listFrame = self.listZone.interior()
self.lightEntry = self.createcomponent(
'Lights List', (), None,
Pmw.ComboBox, (listFrame,),label_text='Light :',
labelpos = Tkinter.W, entry_width = 25, selectioncommand = self.selectLight,
scrolledlist_items = self.lightList)
self.lightEntry.pack(side=Tkinter.LEFT)
self.renameButton = self.createcomponent(
'Rename Light', (), None,
Button, (listFrame,),
@ -82,7 +82,7 @@ class lightingPanel(AppShell):
command = self.addPoint)
lightsMenu.add_command(label = 'Add Spotlight',
command = self.addSpot)
self.lightsButton.pack(expand=0)
self.lightsButton['menu'] = lightsMenu
@ -155,7 +155,7 @@ class lightingPanel(AppShell):
self.pConstantAttenuation.pack(fill = Tkinter.X, expand = 0)
self.bind(self.pConstantAttenuation,
'Set point light constant attenuation')
self.pLinearAttenuation = Slider(
pointPage,
text = 'Linear Attenuation',
@ -166,7 +166,7 @@ class lightingPanel(AppShell):
self.pLinearAttenuation.pack(fill = Tkinter.X, expand = 0)
self.bind(self.pLinearAttenuation,
'Set point light linear attenuation')
self.pQuadraticAttenuation = Slider(
pointPage,
text = 'Quadratic Attenuation',
@ -177,7 +177,7 @@ class lightingPanel(AppShell):
self.pQuadraticAttenuation.pack(fill = Tkinter.X, expand = 0)
self.bind(self.pQuadraticAttenuation,
'Set point light quadratic attenuation')
# Spot light controls
self.sSpecularColor = seColorEntry(
spotPage, text = 'Specular Color')
@ -196,7 +196,7 @@ class lightingPanel(AppShell):
self.sConstantAttenuation.pack(fill = Tkinter.X, expand = 0)
self.bind(self.sConstantAttenuation,
'Set spot light constant attenuation')
self.sLinearAttenuation = Slider(
spotPage,
text = 'Linear Attenuation',
@ -207,7 +207,7 @@ class lightingPanel(AppShell):
self.sLinearAttenuation.pack(fill = Tkinter.X, expand = 0)
self.bind(self.sLinearAttenuation,
'Set spot light linear attenuation')
self.sQuadraticAttenuation = Slider(
spotPage,
text = 'Quadratic Attenuation',
@ -218,7 +218,7 @@ class lightingPanel(AppShell):
self.sQuadraticAttenuation.pack(fill = Tkinter.X, expand = 0)
self.bind(self.sQuadraticAttenuation,
'Set spot light quadratic attenuation')
self.sExponent = Slider(
spotPage,
text = 'Exponent',
@ -231,7 +231,7 @@ class lightingPanel(AppShell):
'Set spot light exponent')
# MRM: Add frustum controls
self.lightNotebook.setnaturalsize()
self.lightNotebook.pack(expand = 1, fill = Tkinter.BOTH)
@ -329,7 +329,7 @@ class lightingPanel(AppShell):
self.lightColor.set([255*0.3,255*0.3,255*0.3])
oldType = self.type
self.type = 'ambient'
if self.type=='ambient':
self.lightNotebook.selectpage('Ambient')
elif self.type =='directional':
@ -384,7 +384,7 @@ class lightingPanel(AppShell):
#################################################################
messenger.send('LP_addLight',['ambient'])
return
def addDirectional(self):
#################################################################
# addDirectional(self)
@ -393,7 +393,7 @@ class lightingPanel(AppShell):
#################################################################
messenger.send('LP_addLight',['directional'])
return
def addPoint(self):
#################################################################
# addPoint(self)
@ -402,7 +402,7 @@ class lightingPanel(AppShell):
#################################################################
messenger.send('LP_addLight',['point'])
return
def addSpot(self):
#################################################################
# addSpot(self)
@ -455,7 +455,7 @@ class lightingPanel(AppShell):
return
self.currentLight.setOrientation(Vec3(orient[0],orient[1],orient[2]))
return
def setConstantAttenuation(self, value):
#################################################################
# setConstantAttenuation(self, value)
@ -464,7 +464,7 @@ class lightingPanel(AppShell):
#################################################################
self.currentLight.setConstantAttenuation(value)
return
def setLinearAttenuation(self, value):
#################################################################
# setLinearAttenuation(self, value)
@ -473,7 +473,7 @@ class lightingPanel(AppShell):
#################################################################
self.currentLight.setLinearAttenuation(value)
return
def setQuadraticAttenuation(self, value):
#################################################################
# setQuadraticAttenuation(self, value)
@ -482,7 +482,7 @@ class lightingPanel(AppShell):
#################################################################
self.currentLight.setQuadraticAttenuation(value)
return
def setExponent(self, value):
#################################################################
# setExponent(self, value)

View File

@ -31,17 +31,17 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
usestatusarea = 0
widgetsDict = {}
def __init__(self, target, type, info, parent = None, nodePath = render, **kw):
self.nodePath = target
self.name = target.getName()
self.type = type
self.info = info
# Initialise superclass
Pmw.MegaWidget.__init__(self, parent)
# Define the megawidget options.
optiondefs = (
('title', self.appname, None),
@ -51,12 +51,12 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
if parent == None:
self.parent = Toplevel()
AppShell.__init__(self, self.parent)
self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
def appInit(self):
return
def createInterface(self):
# The interior of the toplevel panel
interior = self.interior()
@ -110,15 +110,15 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
#### If nodePath has been binded with any curves
if self.info.has_key('curveList'):
self.createCurveFrame(self.contentFrame)
## Set all stuff done
mainFrame.pack(fill = 'both', expand = 1)
def createMenuBar(self):
# we don't need menu bar here.
self.menuBar.destroy()
def onDestroy(self, event):
self.ignore('forPorpertyWindow'+self.name)
messenger.send('PW_close', [self.name])
@ -154,7 +154,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
widget = Button(frame, text=buttonText, font=('MSSansSerif', 10), command = defaultFunction)
widget.pack(side=LEFT, padx=3)
self.widgetsDict[text+'-'+'DefaultButton']=widget
frame.pack(side = side, fill = fill, expand = expand,pady=3)
@ -175,7 +175,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.posX['commandData'] = ['x']
self.posX['command'] = self.setNodePathPosHprScale
self.posX.pack(side=LEFT,expand=0,fill=X, padx=1)
self.posY = self.createcomponent('posY', (), None,
Floater.Floater, (posInterior,),
text = 'Y', relief = FLAT,
@ -185,7 +185,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.posY['commandData'] = ['y']
self.posY['command'] = self.setNodePathPosHprScale
self.posY.pack(side=LEFT, expand=0,fill=X, padx=1)
self.posZ = self.createcomponent('posZ', (), None,
Floater.Floater, (posInterior,),
text = 'Z', relief = FLAT,
@ -215,7 +215,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.hprH['commandData'] = ['h']
self.hprH['command'] = self.setNodePathPosHprScale
self.hprH.pack(side = LEFT, expand=0,fill=X)
self.hprP = self.createcomponent('hprP', (), None,
Dial.AngleDial, (hprInterior,),
style = 'mini',
@ -226,7 +226,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.hprP['commandData'] = ['p']
self.hprP['command'] = self.setNodePathPosHprScale
self.hprP.pack(side = LEFT, expand=0,fill=X)
self.hprR = self.createcomponent('hprR', (), None,
Dial.AngleDial, (hprInterior,),
style = 'mini',
@ -249,7 +249,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
# And, it will set the call back function to setNodePathPosHprScale()
#################################################################
scaleInterior = Frame(contentFrame)
self.scale = self.createcomponent('scale', (), None,
Floater.Floater, (scaleInterior,),
text = 'Scale',
@ -280,10 +280,10 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.nodeColor['command'] = self.setNodeColorVec
self.nodeColor['resetValue'] = [255,255,255,255]
self.nodeColor.place(anchor=NW,y=235)
self.bind(self.nodeColor, 'Set nodePath color')
self.bind(self.nodeColor, 'Set nodePath color')
self.nodeColor.pack(side=TOP,expand=0,fill=X, padx=3, pady=3)
return
def setNodeColorVec(self, color):
#################################################################
# setNodeColorVec(self, color)
@ -295,7 +295,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
color[3]/255.0)
return
def setNodePathPosHprScale(self, data, axis):
#################################################################
# setNodePathPosHprScale(self, data, axis)
@ -345,9 +345,9 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
defaultFunction = lambda a = n, b = self : b.deleteCurve(a))
group.pack(side = TOP, fill = X, expand = 0,pady=3, padx=3)
self.curveFrame.pack(side = TOP, fill = X, expand = 0,pady=3, padx=3)
return
def deleteCurve(self, number = 0):
#################################################################
# deleteCurve(self, number = 0)
@ -374,7 +374,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
return
else:
self.ignore('curveRemovedFromNode')
if curveList!= None:
del self.info['curveList']
self.info['curveList'] = curveList
@ -397,7 +397,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
# cameraInterface(self, interior, mainFrame)
# Create the interface for camera node.
#################################################################
## Type entry : unchageable
widget = self.createEntryField(contentFrame,'Type:',
value = self.type,
@ -423,7 +423,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
tag_font=('MSSansSerif', 10))
self.createHprEntry(group.interior())
group.pack(side=TOP,fill = X, expand = 0, pady=3)
## near entry
group = Pmw.Group(contentFrame,tag_text='Lens Property',
tag_font=('MSSansSerif', 10))
@ -471,7 +471,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
widget = Label(frame, text = "Film Size:", font=('MSSansSerif', 10),width=12)
widget.pack(side=LEFT)
frame.pack(side = TOP, fill = X, expand = 0, pady=3)
frame = Frame(lensFrame)
widget = Pmw.EntryField(frame, labelpos='w', label_text = ' ',
value = self.info['FilmSize'].getX(),
@ -490,7 +490,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
widget.pack(side=LEFT, padx=3)
widget = Button(frame, text='Default', font=('MSSansSerif', 10), command = self.defaultCameraFilmSize)
widget.pack(side=LEFT, padx=3)
self.widgetsDict['FilmSize'+'-'+'DefaultButton']=widget
self.widgetsDict['FilmSize'+'-'+'DefaultButton']=widget
frame.pack(side = TOP, fill = X, expand = 0,pady=0)
## Focal Length entry
@ -504,7 +504,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
defaultFunction = self.defaultCameraFocalLength)
group.pack(side = TOP, fill = X, expand = 0,pady=2)
def defaultCameraFar(self):
#################################################################
# defaultCameraFar(self)
@ -655,7 +655,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
tag_font=('MSSansSerif', 10))
self.createPosEntry(group.interior())
group.pack(side=TOP,fill = X, expand = 0, pady=3)
group = Pmw.Group(contentFrame,tag_text='Orientation',
tag_font=('MSSansSerif', 10))
self.createHprEntry(group.interior())
@ -689,7 +689,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.nodePath.setTransparency(True)
self.nodePath.setBin("fixed", 1)
return
def actorInterface(self, contentFrame):
#################################################################
# actorInterface(self, contentFrame)
@ -744,7 +744,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
return
else:
self.ignore('animRemovedFromNode')
if len(animDict)!= 0:
del self.info['animDict']
self.info['animDict'] = animDict
@ -784,14 +784,14 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.lightColor['resetValue'] = [0.3*255,0.3*255,0.3*255,0]
self.lightColor.pack(side=TOP, fill=X,expand=1, padx = 2, pady =2)
self.bind(self.lightColor, 'Set light color')
self.varActive = IntVar()
self.varActive.set(self.lightNode.active)
checkButton = Checkbutton(frame, text='Enable This Light',
variable=self.varActive, command=self.toggleLight)
checkButton.pack(side=RIGHT,pady=3)
lightingGroup.pack(side=TOP, fill = X, expand =1)
# Directional light controls
if self.lightNode.type == 'directional':
lightingGroup = Pmw.Group(contentFrame,tag_pyclass=None)
@ -815,10 +815,10 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.dOrientation['resetValue'] = [0,0,0,0]
self.dOrientation.pack(fill = X, expand = 1)
self.bind(self.dOrientation, 'Set directional light orientation')
lightingGroup.pack(side=TOP, fill = X, expand =1)
elif self.lightNode.type == 'point':
# Point light controls
lightingGroup = Pmw.Group(contentFrame,tag_pyclass=None)
@ -830,7 +830,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.pSpecularColor.pack(fill = X, expand = 1)
self.bind(self.pSpecularColor,
'Set point light specular color')
self.pPosition = VectorWidgets.Vector3Entry(
pointPage, text = 'Position', label_font=('MSSansSerif', 10),
value = [self.lightNode.getPosition().getX(),self.lightNode.getPosition().getY(),self.lightNode.getPosition().getZ(),0])
@ -848,7 +848,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.pConstantAttenuation.pack(fill = X, expand = 1)
self.bind(self.pConstantAttenuation,
'Set point light constant attenuation')
self.pLinearAttenuation = Slider.Slider(
pointPage,
text = 'Linear Attenuation', label_font=('MSSansSerif', 10),
@ -858,7 +858,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.pLinearAttenuation.pack(fill = X, expand = 1)
self.bind(self.pLinearAttenuation,
'Set point light linear attenuation')
self.pQuadraticAttenuation = Slider.Slider(
pointPage,
text = 'Quadratic Attenuation', label_font=('MSSansSerif', 10),
@ -871,8 +871,8 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
lightingGroup.pack(side=TOP, fill = X, expand =1)
elif self.lightNode.type == 'spot':
elif self.lightNode.type == 'spot':
# Spot light controls
lightingGroup = Pmw.Group(contentFrame,tag_pyclass=None)
spotPage = lightingGroup.interior()
@ -893,7 +893,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.sConstantAttenuation.pack(fill = X, expand = 1)
self.bind(self.sConstantAttenuation,
'Set spot light constant attenuation')
self.sLinearAttenuation = Slider.Slider(
spotPage,
text = 'Linear Attenuation', label_font=('MSSansSerif', 10),
@ -903,7 +903,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.sLinearAttenuation.pack(fill = X, expand = 1)
self.bind(self.sLinearAttenuation,
'Set spot light linear attenuation')
self.sQuadraticAttenuation = Slider.Slider(
spotPage,
text = 'Quadratic Attenuation', label_font=('MSSansSerif', 10),
@ -913,7 +913,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.sQuadraticAttenuation.pack(fill = X, expand = 1)
self.bind(self.sQuadraticAttenuation,
'Set spot light quadratic attenuation')
self.sExponent = Slider.Slider(
spotPage,
text = 'Exponent', label_font=('MSSansSerif', 10),
@ -924,7 +924,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.bind(self.sExponent,
'Set spot light exponent')
lightingGroup.pack(side=TOP, fill = X, expand =1)
return
def setLightingColorVec(self,color):
@ -950,19 +950,19 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
return
self.lightNode.setOrientation(Vec3(orient[0],orient[1],orient[2]))
return
def setConstantAttenuation(self, value):
self.lightNode.setConstantAttenuation(value)
return
def setLinearAttenuation(self, value):
self.lightNode.setLinearAttenuation(value)
return
def setQuadraticAttenuation(self, value):
self.lightNode.setQuadraticAttenuation(value)
return
def setExponent(self, value):
self.lightNode.setExponent(value)
return
@ -988,12 +988,12 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
command = None,
initialState='disabled',
side = 'top')
group = Pmw.Group(contentFrame,tag_text='Position',
tag_font=('MSSansSerif', 10))
self.createPosEntry(group.interior())
group.pack(side=TOP,fill = X, expand = 0, pady=3)
group = Pmw.Group(contentFrame,tag_text='Orientation',
tag_font=('MSSansSerif', 10))
self.createHprEntry(group.interior())
@ -1027,7 +1027,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
group.pack(side=TOP,fill = X, expand = 0, padx = 3, pady=3)
gridPage = group.interior()
self.xyzSnap = BooleanVar()
self.xyzSnapButton = Checkbutton(
gridPage,
@ -1056,7 +1056,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
value = SEditor.grid.getGridSpacing())
self.gridSpacing['command'] = SEditor.grid.setGridSpacing
self.gridSpacing.pack(fill = X, expand = 0, pady=3)
self.gridSize = Floater.Floater(
gridPage,
text = 'Grid Size',
@ -1072,7 +1072,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
value = SEditor.grid.getSnapAngle())
self.gridSnapAngle['command'] = SEditor.grid.setSnapAngle
self.gridSnapAngle.pack(fill = X, expand = 0, pady=3)
return
def toggleXyzSnap(self):
@ -1108,14 +1108,14 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
tag_font=('MSSansSerif', 10))
self.createPosEntry(group.interior())
group.pack(side=TOP,fill = X, expand = 0, pady=3)
group = Pmw.Group(contentFrame,tag_text='Orientation',
tag_font=('MSSansSerif', 10))
self.createHprEntry(group.interior())
group.pack(side=TOP,fill = X, expand = 0, pady=3)
self.createScaleEntry(contentFrame)
collisionGroup = Pmw.Group(contentFrame,tag_text='Collision Object Properties',
tag_font=('MSSansSerif', 10))
cObjFrame = collisionGroup.interior()
@ -1139,7 +1139,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.cPosX['commandData'] = ['sphere-o']
self.cPosX['command'] = self.setCollisionPosHprScale
self.cPosX.pack(side=LEFT,expand=0,fill=X, padx=1)
self.cPosY = self.createcomponent('originY', (), None,
Floater.Floater, (posInterior,),
text = 'Y', relief = FLAT,
@ -1149,7 +1149,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.cPosY['commandData'] = ['sphere-o']
self.cPosY['command'] = self.setCollisionPosHprScale
self.cPosY.pack(side=LEFT, expand=0,fill=X, padx=1)
self.cPosZ = self.createcomponent('originZ', (), None,
Floater.Floater, (posInterior,),
text = 'Z', relief = FLAT,
@ -1164,7 +1164,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
group.pack(side=TOP,fill = X, expand = 0, pady=3)
scaleInterior = Frame(cObjFrame)
self.scaleS = self.createcomponent('radius', (), None,
Floater.Floater, (scaleInterior,),
text = 'Radius',
@ -1178,7 +1178,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
scaleInterior.pack(side=TOP,expand=0,fill=X, padx=3, pady=3)
pass
elif cType == 'CollisionPolygon':
frame = Frame(cObjFrame)
label = Label(frame, text= "Sorry!",font=('MSSansSerif', 10),
@ -1199,9 +1199,9 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
label = Label(frame, text= "If you really need to change, recreate one...",font=('MSSansSerif', 10),
borderwidth=5)
label.pack(side=LEFT)
frame.pack(side=TOP, fill=X, expand=True)
frame.pack(side=TOP, fill=X, expand=True)
pass
elif cType == 'CollisionSegment':
pointA = self.collisionObj.getPointA()
pointB = self.collisionObj.getPointB()
@ -1217,7 +1217,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.cPosX['commandData'] = ['segment-A']
self.cPosX['command'] = self.setCollisionPosHprScale
self.cPosX.pack(side=LEFT,expand=0,fill=X, padx=1)
self.cPosY = self.createcomponent('pointA-Y', (), None,
Floater.Floater, (posInterior,),
text = 'Y', relief = FLAT,
@ -1227,7 +1227,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.cPosY['commandData'] = ['segment-A']
self.cPosY['command'] = self.setCollisionPosHprScale
self.cPosY.pack(side=LEFT, expand=0,fill=X, padx=1)
self.cPosZ = self.createcomponent('pointA-Z', (), None,
Floater.Floater, (posInterior,),
text = 'Z', relief = FLAT,
@ -1251,7 +1251,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.cPosXB['commandData'] = ['segment-B']
self.cPosXB['command'] = self.setCollisionPosHprScale
self.cPosXB.pack(side=LEFT,expand=0,fill=X, padx=1)
self.cPosYB = self.createcomponent('pointB-Y', (), None,
Floater.Floater, (posInterior,),
text = 'Y', relief = FLAT,
@ -1261,7 +1261,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.cPosYB['commandData'] = ['segment-B']
self.cPosYB['command'] = self.setCollisionPosHprScale
self.cPosYB.pack(side=LEFT, expand=0,fill=X, padx=1)
self.cPosZB = self.createcomponent('pointB-Z', (), None,
Floater.Floater, (posInterior,),
text = 'Z', relief = FLAT,
@ -1289,7 +1289,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.cPosX['commandData'] = ['ray-A']
self.cPosX['command'] = self.setCollisionPosHprScale
self.cPosX.pack(side=LEFT,expand=0,fill=X, padx=1)
self.cPosY = self.createcomponent('origin-Y', (), None,
Floater.Floater, (posInterior,),
text = 'Y', relief = FLAT,
@ -1299,7 +1299,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.cPosY['commandData'] = ['ray-A']
self.cPosY['command'] = self.setCollisionPosHprScale
self.cPosY.pack(side=LEFT, expand=0,fill=X, padx=1)
self.cPosZ = self.createcomponent('origin-Z', (), None,
Floater.Floater, (posInterior,),
text = 'Z', relief = FLAT,
@ -1323,7 +1323,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.cPosXB['commandData'] = ['ray-B']
self.cPosXB['command'] = self.setCollisionPosHprScale
self.cPosXB.pack(side=LEFT,expand=0,fill=X, padx=1)
self.cPosYB = self.createcomponent('direction-Y', (), None,
Floater.Floater, (posInterior,),
text = 'Y', relief = FLAT,
@ -1333,7 +1333,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.cPosYB['commandData'] = ['ray-B']
self.cPosYB['command'] = self.setCollisionPosHprScale
self.cPosYB.pack(side=LEFT, expand=0,fill=X, padx=1)
self.cPosZB = self.createcomponent('direction-Z', (), None,
Floater.Floater, (posInterior,),
text = 'Z', relief = FLAT,
@ -1346,7 +1346,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
posInterior.pack(side=TOP, expand=0,fill=X, padx=3, pady=3)
group.pack(side=TOP,fill = X, expand = 0, pady=3)
pass
collisionGroup.pack(side=TOP,fill = X, expand = 0, pady=3)
return
@ -1422,18 +1422,18 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.hprR.set(hpr.getZ())
self.scale.set(scale.getX())
return
def trackDataFromSceneLight(self, pos=Point3(0,0,0), hpr=Vec3(0,0,0), scale=Point3(0,0,0)):
if self.lightNode.type == 'directional':
self.dPosition.set([pos.getX(),pos.getY(),pos.getZ()])
self.dOrientation.set([hpr.getX(),hpr.getY(),hpr.getZ()])
pass
elif self.lightNode.type == 'point':
self.pPosition.set([pos.getX(),pos.getY(),pos.getZ()])
pass
pass
return
def trackDataFromSceneDummy(self, pos=Point3(0,0,0), hpr=Vec3(0,0,0), scale=Point3(0,0,0)):
self.posX.set(pos.getX())
self.posY.set(pos.getY())
@ -1443,7 +1443,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.hprR.set(hpr.getZ())
self.scale.set(scale.getX())
return
def trackDataFromSceneCollision(self, pos=Point3(0,0,0), hpr=Vec3(0,0,0), scale=Point3(0,0,0)):
self.posX.set(pos.getX())
self.posY.set(pos.getY())
@ -1453,4 +1453,4 @@ class propertyWindow(AppShell,Pmw.MegaWidget):
self.hprR.set(hpr.getZ())
self.scale.set(scale.getX())
return

View File

@ -12,15 +12,15 @@ from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import *
import math
#Manakel 2/12/2005: replace from pandac import by from pandac.PandaModules import
from pandac.PandaModules import MouseWatcher
from pandac.PandaModules import MouseWatcher
class ViewPort:
#########################################################################################################################################
# The ViewPort class has the camera and associated display region set up for actually rendering the four sub-views
# The constructor needs the bounds, window layer, camera, color, projection type, name and scene for the view
#########################################################################################################################################
#########################################################################################################################################
def __init__(self,X1,X2,Y1,Y2,layer,cam,background=Vec4(0.3,0.3,0.3,1),projection="perspective",type="top",scene=render):
self.VPType=type
self.VP_X1=X1
@ -29,14 +29,14 @@ class ViewPort:
self.VP_Y2=Y2
self.VP_width=self.VP_X2 - self.VP_X1
self.VP_height=self.VP_Y2 - self.VP_Y1
self.the_viewport=layer.makeDisplayRegion(self.VP_X1, self.VP_X2,self.VP_Y1, self.VP_Y2)
self.the_viewport.setCamera(cam)
self.the_viewport.setClearDepthActive(1)
self.the_viewport.setClearColorActive(1)
self.the_viewport.setClearColor(background)
self.cam=cam
self.cam=cam
# Set up the cameras to look in the right place.
if(type=="top"):
@ -46,13 +46,13 @@ class ViewPort:
self.cam.setH(-90)
self.cam.setX(10)
elif(type=="front"):
self.cam.setY(-10)
self.cam.setY(-10)
elif(type=="perspective"):
cam.setY(-100)
#cam.setX(10)
#cam.setZ(-10)
#cam.setH(45)
#cam.setP(-45)
#cam.setP(-45)
#print "aa"
@ -89,9 +89,9 @@ class ViewPort:
y=1
self.lens.setAspectRatio(x/y)
self.cam.node().setLens(self.lens)
def resize(self,x,y):
if(self.VPType=="left"):
self.the_viewport.setDimensions(0,x,0,y)
w=abs(x-self.VP_X1)
@ -127,7 +127,7 @@ class ViewPort:
def setScene(self,scene):
self.cam.node().setScene(scene)
def setDR(self,mouseWatcher):
#mouseWatcher.setDisplayRegion(self.the_viewport)
pass
@ -141,7 +141,7 @@ class ViewPort:
def getCam(self):
return self.cam
class QuadView(DirectObject):
#########################################################################################################################################
@ -157,7 +157,7 @@ class QuadView(DirectObject):
self.AltPressed=0
self.PanConstantX=50
self.PanConstantY=50
self.ZoomConstant=1
self.ZoomConstant=1
self.FrontWidth=100
self.FrontHeight=100
self.TopWidth=100
@ -186,9 +186,9 @@ class QuadView(DirectObject):
self.PerspectiveWire=0
self.TopWire=0
# Keep track of the currently selected window... values are 1-4 for four quadrants of a standard
# Keep track of the currently selected window... values are 1-4 for four quadrants of a standard
# Cartesian coordinate system
# These are the orthographic cameras
# They will be restricted to panning and zooming i.e. no rotation
# Top could be flipped to back, left to right and front to back
@ -198,7 +198,7 @@ class QuadView(DirectObject):
# This camera will have a trackball control since its perspective
self.perspectiveCam = render.attachNewNode(Camera('perspectiveCam'))
#self.toplens=OrthographicLens()
#self.leftLens=OrthographicLens()
#self.frontLens=OrthographicLens()
@ -210,7 +210,7 @@ class QuadView(DirectObject):
#self.leftCamLens= base.cam.node().getLens()
#self.perspectiveCamLens= base.cam.node().getLens()
# Manipulate lenses here if need be
# Manipulate lenses here if need be
#self.topCamLens.setFilmSize(250)
# Set the Lenses
@ -239,17 +239,17 @@ class QuadView(DirectObject):
#self.FrontScene=render.copyTo(self.SceneParent)
#self.TopScene=render.copyTo(self.SceneParent)
#self.LeftScene=render.copyTo(self.SceneParent)
self.PerspectiveScene=render
self.FrontScene=render
self.TopScene=render
self.LeftScene=render
#self.PerspectiveScene.reparentTo(self.SceneParent)
#self.FrontScene.reparentTo(self.SceneParent)
#self.TopScene.reparentTo(self.SceneParent)
#self.LeftScene.reparentTo(self.SceneParent)
self.Perspective=ViewPort(0.5,1.0,0.0,0.5,self.newLayer,self.perspectiveCam,Vec4(0.75,0.75,0.75,1),"perspective","perspective",self.PerspectiveScene)
self.Top=ViewPort(0.0,0.5,0.5,1.0,self.newLayer,self.topCam,Vec4(0.80,0.80,0.80,1),"ortho","top",self.TopScene)
self.Left=ViewPort(0.0,0.5,0.0,0.5,self.newLayer,self.leftCam,Vec4(0.85,0.85,0.85,1),"ortho","left",self.LeftScene)
@ -263,7 +263,7 @@ class QuadView(DirectObject):
#self.lastPickPoint = None
#base.useTrackball()
#self.dataRoot = NodePath('dataRoot')
# Cache the node so we do not ask for it every frame
#self.dataRootNode = self.dataRoot.node()
@ -272,7 +272,7 @@ class QuadView(DirectObject):
#self.mak = self.dataRoot.attachNewNode(MouseAndKeyboard(base.win, 0, 'mak'))
#self.mak.node().setSource(base.win, 0)
self.mouseWatcherNode = MouseWatcher('mouseWatcher')
self.mouseWatcher = base.mak.attachNewNode(self.mouseWatcherNode)
#self.Perspective.setDR(self.mouseWatcherNode)
@ -282,7 +282,7 @@ class QuadView(DirectObject):
#ddr=DisplayRegionContext(self.Perspective.getCam())
#base.setMouseOnNode(self.smiley.node()) # Let Mouse Control Perspective View for now
#base.enableSoftwareMousePointer()
# Message Handlers
self.accept("a",self.setLeft)
self.accept("q",self.setTop)
@ -302,7 +302,7 @@ class QuadView(DirectObject):
self.accept("alt-mouse1-up",self.AltUp)
self.accept("control-mouse1",self.CtlDown)
self.accept("control-mouse1-up",self.CtlUp)
# Methods
#def setLastPickPoint( self ):
@ -407,7 +407,7 @@ class QuadView(DirectObject):
self.PerspectiveScene.clearTexture()
self.PerspectiveTexture=1
def reparenter(self):
#self.FrontScene.reparentTo(render)
@ -437,10 +437,10 @@ class QuadView(DirectObject):
if(self.oldY<-1 or self.oldY>1):
return
taskMgr.add(self.DragAction,'DragAction')
def AltUpHandler(self):
taskMgr.remove('DragAction')
taskMgr.remove('DragAction')
def gridtoggle(self):
#grid=DirectGrid()
#grid.enable()
@ -467,11 +467,11 @@ class QuadView(DirectObject):
self.setPerspective()
else:
self.setFront()
def MouseTell(self,buttonCode):
self.MouseButton=buttonCode
self.setAppropriateViewPort(self.mouseWatcherNode.getMouseX(),self.mouseWatcherNode.getMouseY())
x=base.mouseWatcherNode.getMouseX()
y=base.mouseWatcherNode.getMouseY()
@ -509,12 +509,12 @@ class QuadView(DirectObject):
print "Sent X:%f Sent Y:%f"%(ansX,ansY)
#SEditor.iRay.pick(render,self.xy)
SEditor.manipulationControl.manipulationStop(self.xy)
#print "MouseX " + str(base.mouseWatcherNode.getMouseX()) + "MouseY " + str(base.mouseWatcherNode.getMouseY()) + "\n"
#print "MouseX " + str(self.mouseWatcherNode.getMouseX()) + "MouseY " + str(self.mouseWatcherNode.getMouseY()) + "\n"
#print "MouseX " + str(base.mouseWatcherNode.getMouseX()) + "MouseY " + str(base.mouseWatcherNode.getMouseY()) + "\n"
#print "MouseX " + str(self.mouseWatcherNode.getMouseX()) + "MouseY " + str(self.mouseWatcherNode.getMouseY()) + "\n"
base.mouseWatcherNode=self.mouseWatcherNode
self.oldX=self.mouseWatcherNode.getMouseX()
if(self.oldX<-1 or self.oldX>1):
return
@ -533,11 +533,11 @@ class QuadView(DirectObject):
taskMgr.remove('DragAction')
self.Mouse_Draggin=0
#print "Mouse Up"
def Max_Style_Mouse_View(self,buttoncode):
pass
def ChangeBaseDR(self):
dr=base.win.getDisplayRegion(0)
if(self.CurrentQuad==1): #Front
@ -569,7 +569,7 @@ class QuadView(DirectObject):
self.ChangeBaseDR()
self.Perspective.setCam()
#self.Perspective.setDR(self.mouseWatcherNode)
def setFront(self):
print "FRONT"
self.CurrentQuad=1
@ -577,7 +577,7 @@ class QuadView(DirectObject):
self.Front.setCam()
#self.Front.setDR(self.mouseWatcherNode)
def DragAction(self,task):
#if(self.MouseDragging==1):
self.currX= self.mouseWatcherNode.getMouseX()
@ -598,7 +598,7 @@ class QuadView(DirectObject):
if(self.HorizontalAxis<-1 or self.HorizontalAxis>1 or self.VerticalAxis<-1 or self.VerticalAxis>1):
return
self.resizedr(self.VerticalAxis,self.HorizontalAxis)
#if(self.AltPressed): # View Camera Transforms -> Maya style
elif(1):
#print "ALTPRESSED"
@ -618,7 +618,7 @@ class QuadView(DirectObject):
self.MoveCamera(0,self.diffX*self.PanConstantX,-self.diffY*self.PanConstantY,self.CurrentQuad)
elif(self.CurrentQuad==4):
pass
elif(self.MouseButton==3): # Do Zoom
elif(self.MouseButton==3): # Do Zoom
if(self.CurrentQuad==1): # Y and Z values change meanings for different cameras
#lens = OrthographicLens()
#lens.setFilmSize(l,self.VP_height*200)
@ -634,26 +634,26 @@ class QuadView(DirectObject):
if(self.FrontHeight<=0):
FrontHeight=1
self.frontCam.node().getLens().setFilmSize(self.FrontWidth,self.FrontHeight)
self.resizedr(self.VerticalAxis,self.HorizontalAxis)
self.resizedr(self.VerticalAxis,self.HorizontalAxis)
elif(self.CurrentQuad==2):
self.TopWidth= self.TopWidth + self.diffX
self.TopHeight= self.TopHeight + self.diffX
self.TopWidth= self.TopWidth + self.diffY
self.TopHeight= self.TopHeight + self.diffY
self.topCam.node().getLens().setFilmSize(self.TopWidth,self.TopHeight)
self.resizedr(self.VerticalAxis,self.HorizontalAxis)
self.resizedr(self.VerticalAxis,self.HorizontalAxis)
elif(self.CurrentQuad==3):
self.LeftWidth= self.LeftWidth + self.diffX
self.LeftHeight= self.LeftHeight + self.diffX
self.LeftWidth= self.LeftWidth + self.diffY
self.LeftHeight= self.LeftHeight + self.diffY
self.leftCam.node().getLens().setFilmSize(self.LeftWidth,self.LeftHeight)
self.resizedr(self.VerticalAxis,self.HorizontalAxis)
self.resizedr(self.VerticalAxis,self.HorizontalAxis)
elif(self.CurrentQuad==4):
pass
else:
pass
self.oldX=self.currX
self.oldY=self.currY
return Task.cont
@ -669,8 +669,8 @@ class QuadView(DirectObject):
self.leftCam.setPos(self.leftCam.getX()+X_amt,self.leftCam.getY()+Y_amt,self.leftCam.getZ()+Z_amt)
elif(quad==4):
self.perspectiveCam.setPos(self.perspectiveCam.getX()+X_amt,self.perspectiveCam.getY()+Y_amt,self.perspectiveCam.getZ()+Z_amt)
#View=QuadView()
#run()

View File

@ -87,7 +87,7 @@ class myLevelEditor(AppShell):
controlType = 'Keyboard'
keyboardMapDict = {}
keyboardSpeedDict = {}
Scene=None
isSelect = False
nodeSelected = None
@ -99,9 +99,9 @@ class myLevelEditor(AppShell):
CurrentFileName=None #Holds the current scene file name
CurrentDirName=None # Holds the current file name without extension which is the path where file's data gets saved
Dirty=0 # Keeps track of whether there are any modifications that should be saved
def __init__(self, parent = None, **kw):
base.setBackgroundColor(0,0,0)
@ -149,12 +149,12 @@ class myLevelEditor(AppShell):
text_scale = 0.05,
text_align = TextNode.ALeft
)
self.initialiseoptions(myLevelEditor)
self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
######### Set the event handler ##########
self.dataFlowEvents = [
## Event from Side Window
@ -213,7 +213,7 @@ class myLevelEditor(AppShell):
['f11',self.loadFromBam],
['f12',self.saveAsBam],
]
#################################
### Collision detection
@ -223,7 +223,7 @@ class myLevelEditor(AppShell):
for event in self.dataFlowEvents:
self.accept(event[0], event[1], extraArgs = event[2:])
self.actionEvents = [
# Scene graph explorer functions
['SGE_changeName', self.changeName],
@ -247,7 +247,7 @@ class myLevelEditor(AppShell):
['se_deselectedAll',self.deselectFromScene],
]
''' All messages starting with "SGE_" are generated in seSceneGraphExplorer'''
for event in self.actionEvents:
self.accept(event[0], event[1], extraArgs = event[2:])
@ -260,7 +260,7 @@ class myLevelEditor(AppShell):
# Initialize the application.
# This function will be called when you call AppShell's constructor
#################################################################
### Create SceneEditor Ver. DirectSession
self.seSession = SeSession()
self.seSession.enable()
@ -270,7 +270,7 @@ class myLevelEditor(AppShell):
self.MopathPanel = None
self.alignPanelDict = {}
#self.quadview=QuadView()
self.lightingPanel = None
self.controllerPanel = None
@ -291,9 +291,9 @@ class myLevelEditor(AppShell):
self.sideWindowCount = 1
self.sideWindow.selectPage()
messenger.send('SGE_Update Explorer',[render]) ## Update the Scene Graph
pass
def getPhotoImage(self,name):
modpath = ConfigVariableSearchPath("model-path")
path = modpath.findFile(Filename(name))
@ -338,11 +338,11 @@ class myLevelEditor(AppShell):
i += 1
button = Button(buttonFrame, image = element, command=lambda n=i : self.buttonPushed(n))
button.pack(fill=X, side = LEFT)
buttonFrame.pack(fill=X, side=LEFT,expand=True)
def buttonPushed(self, buttonIndex):
#################################################################
# buttonPushed(self, buttonNum)
@ -379,7 +379,7 @@ class myLevelEditor(AppShell):
elif buttonIndex==9: # Open Particle Panel
self.openParticlePanel()
return
elif buttonIndex==10:
elif buttonIndex==10:
self.openInputPanel()
return
elif buttonIndex==11: # Help
@ -412,14 +412,14 @@ class myLevelEditor(AppShell):
elif buttonIndex==20:
print "You haven't defined the function for this Button, Number %d."%buttonIndex
return
return
def createMenuBar(self):
# Creates default menus. Can be overridden or simply augmented
# Using button Add below
self.menuBar.addmenuitem('Help', 'command',
'Get information on application',
'Get information on application',
label='About...', command=self.showAbout)
## Creat stuff inside the "File"
self.menuBar.addmenuitem('File', 'command', 'Creat New Scene',
@ -447,7 +447,7 @@ class myLevelEditor(AppShell):
self.menuBar.addmenuitem('File', 'command', 'Load Actor',
label='Load Actor',
command=self.loadActor)
self.menuBar.addmenuitem('File', 'separator')
self.menuBar.addmenuitem('File', 'command', 'Import a Scene',
@ -455,7 +455,7 @@ class myLevelEditor(AppShell):
command=self.importScene)
self.menuBar.addmenuitem('File', 'separator')
self.menuBar.addmenuitem('File', 'command', 'Quit this application',
label='Exit',
command=self.quit)
@ -535,7 +535,7 @@ class myLevelEditor(AppShell):
self.menuPanel.entryconfig('Animation Panel', state=DISABLED)
self.menuPanel.entryconfig('Side Window', state=DISABLED)
def onDestroy(self, event):
#################################################################
# If you have open any thing, please rewrite here!
@ -599,7 +599,7 @@ class myLevelEditor(AppShell):
if self.lightingPanel != None:
self.lightingPanel.updateList(list)
return
def lightRename(self,oName, nName):
#################################################################
# lightRename(self,oName, nName)
@ -613,7 +613,7 @@ class myLevelEditor(AppShell):
if self.lightingPanel != None:
self.lightingPanel.updateList(list,lightNode)
return
def lightSelect(self,lightName):
#################################################################
# lightSelect(self,lightName)
@ -627,7 +627,7 @@ class myLevelEditor(AppShell):
if self.lightingPanel != None:
self.lightingPanel.updateDisplay(lightNode)
return
def addLight(self, type):
#################################################################
# addLight(self, type)
@ -643,7 +643,7 @@ class myLevelEditor(AppShell):
self.lightingPanel.updateList(list,lightNode)
self.makeDirty()
return
def lightingPanelClose(self):
#################################################################
# lightingPanelClose(self)
@ -654,7 +654,7 @@ class myLevelEditor(AppShell):
self.menuPanel.entryconfig('Lighting Panel', state=NORMAL)
self.lightingPanel = None
return
def openPropertyPanel(self, nodePath = None):
#################################################################
# openPropertyPanel(self, nodePath = None)
@ -714,7 +714,7 @@ class myLevelEditor(AppShell):
#################################################################
# addDummyNode(self, nodepath = None)
# This function will be called when user try to create a dummy node into scene
#
#
# Here we will call dataHolder to create a dummy node
# and reparent it to the nodePath that user has assigned.
#
@ -727,7 +727,7 @@ class myLevelEditor(AppShell):
#################################################################
# addCollisionObj(self, nodepath = None)
# This function will be called when user try to create a collision object into the scene
#
#
# Here we will call collisionWindow to ask user what kind of collision objects they want to have.
# Then, send the information and generated collision object to dataHolder to finish the whole process
# and reparent it to the nodePath that user has assigned.
@ -757,7 +757,7 @@ class myLevelEditor(AppShell):
#################################################################
SEditor.reparent(nodepath, fWrt = 1)
return
def openPlacerPanel(self, nodePath = None):
#################################################################
# openPlacerPanel(self, nodePath = None)
@ -766,7 +766,7 @@ class myLevelEditor(AppShell):
#################################################################
if(self.placer==None):
self.placer = Placer()
self.menuPanel.entryconfig('Placer Panel', state=DISABLED)
self.menuPanel.entryconfig('Placer Panel', state=DISABLED)
return
def closePlacerPanel(self):
@ -779,7 +779,7 @@ class myLevelEditor(AppShell):
self.placer = None
self.menuPanel.entryconfig('Placer Panel', state=NORMAL)
return
def openAnimPanel(self, nodePath = None):
#################################################################
# openAnimPanel(self, nodePath = None)
@ -819,7 +819,7 @@ class myLevelEditor(AppShell):
#################################################################
oName = nodePath.getName() # I need this line in order to check the obj name in the control panel.
AllScene.rename(nodePath,nName)
# reset the list in the controller panel if it has been opened.
if (self.controllerPanel) != None:
list = AllScene.getAllObjNameAsList()
@ -841,7 +841,7 @@ class myLevelEditor(AppShell):
currentModName=currentF.getBasenameWoExtension()
# Let us actually remove the scene from sys modules... this is done because every scene is loaded as a module
# And if we reload a scene python wont reload since its already in sys.modules... and hence we delete it
# If there is ever a garbage colleciton bug..this might be a point to look at
# If there is ever a garbage colleciton bug..this might be a point to look at
if sys.modules.has_key(currentModName):
del sys.modules[currentModName]
print sys.getrefcount(AllScene.theScene)
@ -856,14 +856,14 @@ class myLevelEditor(AppShell):
# openScene(self)
#################################################################
# In the future try and provide merging of two scenes
if(self.CurrentFileName or self.Dirty):
saveScene = tkMessageBox._show("Load scene","Save the current scene?",icon = tkMessageBox.QUESTION,type = tkMessageBox.YESNOCANCEL)
if (saveScene == "yes"):
self.saveScene()
elif (saveScene == "cancel"):
return
self.closeAllSubWindows() ## Close all sub window
if(self.CurrentFileName):
currentF=Filename(self.CurrentFileName)
@ -871,7 +871,7 @@ class myLevelEditor(AppShell):
currentModName=currentF.getBasenameWoExtension()
# Let us actually remove the scene from sys modules... this is done because every scene is loaded as a module
# And if we reload a scene python wont reload since its already in sys.modules... and hence we delete it
# If there is ever a garbage colleciton bug..this might be a point to look at
# If there is ever a garbage colleciton bug..this might be a point to look at
if sys.modules.has_key(currentModName):
del sys.modules[currentModName]
print sys.getrefcount(AllScene.theScene)
@ -880,7 +880,7 @@ class myLevelEditor(AppShell):
AllScene.resetAll()
self.CurrentFileName = AllScene.loadScene()
if(self.CurrentFileName==None):
return
@ -894,7 +894,7 @@ class myLevelEditor(AppShell):
lightList=AllScene.getList()
self.lightingPanel.updateList(lightList)
messenger.send('SGE_Update Explorer',[render])
# Close the side window in order to reset all world settings to fit the scene we have loaded.
self.sideWindow.quit()
@ -920,7 +920,7 @@ class myLevelEditor(AppShell):
#################################################################
if(self.CurrentFileName):
f=FileSaver()
f=FileSaver()
f.SaveFile(AllScene,self.CurrentFileName,self.CurrentDirName,1)
self.Dirty=0
else:
@ -1012,7 +1012,7 @@ class myLevelEditor(AppShell):
title = 'Load New Actor',
parent = self.parent)
if ActorFilename:
self.makeDirty()
if not AllScene.loadActor(ActorFilename, Filename.fromOsSpecific(ActorFilename)):
@ -1028,7 +1028,7 @@ class myLevelEditor(AppShell):
## Take care those things under Edit nemu
def unDo(self):
pass
def reDo(self):
pass
@ -1064,7 +1064,7 @@ class myLevelEditor(AppShell):
# This function will do nothing but call other function
# to add a dummy into the scene.
#
# Ok... this is really redundancy...
# Ok... this is really redundancy...
#
#################################################################
self.addDummyNode(self.nodeSelected)
@ -1076,7 +1076,7 @@ class myLevelEditor(AppShell):
# This function will do nothing but call other function
# to open the duplication window.
#
# Ok... this is really redundancy...
# Ok... this is really redundancy...
#
#################################################################
if self.nodeSelected!=None:
@ -1089,7 +1089,7 @@ class myLevelEditor(AppShell):
# This function will do nothing but call other function
# to remove the current selected node..
#
# Ok... this is really redundancy...
# Ok... this is really redundancy...
#
################################################################
self.remove(self.nodeSelected)
@ -1101,11 +1101,11 @@ class myLevelEditor(AppShell):
# This function will do nothing but call other function
# to open the property window of current selected node..
#
# Ok... this is really redundancy...
# Ok... this is really redundancy...
#
################################################################
self.openPropertyPanel(self.nodeSelected)
pass
pass
def showCameraSetting(self):
################################################################
@ -1113,7 +1113,7 @@ class myLevelEditor(AppShell):
# This function will do nothing but call other function
# to open the property window of camera..
#
# Ok... this is really redundancy...
# Ok... this is really redundancy...
#
################################################################
self.openPropertyPanel(camera)
@ -1145,20 +1145,20 @@ class myLevelEditor(AppShell):
self.sideWindowCount = 1
self.menuPanel.entryconfig('Side Window', state=DISABLED)
return
def openAnimationPanel(self):
################################################################
# openAnimationPanel(self)
# This function will do nothing but call other function
# to open the animation window for selected node(if it is an Actor)..
#
# Ok... this is really redundancy...
# Ok... this is really redundancy...
#
################################################################
if AllScene.isActor(self.nodeSelected):
self.openAnimPanel(self.nodeSelected)
pass
def openMopathPanel(self):
################################################################
# openMopathPanel(self)
@ -1178,7 +1178,7 @@ class myLevelEditor(AppShell):
self.ParticleEnable = visable
AllScene.toggleParticleVisable(visable)
return
def openLightingPanel(self):
################################################################
# openLightingPanel(self)
@ -1189,7 +1189,7 @@ class myLevelEditor(AppShell):
self.lightingPanel = lightingPanel(AllScene.getLightList())
self.menuPanel.entryconfig('Lighting Panel', state=DISABLED)
return
def addParticleEffect(self,effect_name,effect,node):
AllScene.particleDict[effect_name]=effect
AllScene.particleNodes[effect_name]=node
@ -1215,7 +1215,7 @@ class myLevelEditor(AppShell):
def closeParticlePanel(self):
self.particlePanel = None
return
def openInputPanel(self):
if self.controllerPanel==None:
list = AllScene.getAllObjNameAsList()
@ -1237,10 +1237,10 @@ class myLevelEditor(AppShell):
# set it back into controller panel
################################################################
node = AllScene.getObjFromSceneByName(name)
if (self.controllerPanel) != None and (node!=None):
self.controllerPanel.setNodePathIn(node)
return
def setControlSet(self, controlType, dataList):
@ -1260,7 +1260,7 @@ class myLevelEditor(AppShell):
# Also this will make sure we won't catch wrong keyboard message
self.stopControl(controlType)
self.enableControl = True
self.setControlSet(controlType, dataList)
self.lastContorlTimer = globalClock.getFrameTime()
if controlType == 'Keyboard':
@ -1327,7 +1327,7 @@ class myLevelEditor(AppShell):
self.controlTarget.setScale(newScale.getX(),newScale.getY(),newScale.getZ())
self.transNodeKeyboard.setPosHpr(0,0,0,0,0,0)
return Task.cont
## Misc
##### This one get the event from SGE (Scene Graph Explorer) and Picking
def selectNode(self, nodePath=None, callBack = True):
@ -1428,7 +1428,7 @@ class myLevelEditor(AppShell):
# This function will do nothing but call other function
# to delete selected node...
#
# Ok... this is really redundancy...
# Ok... this is really redundancy...
#
################################################################
self.deSelectNode(self.nodeSelected)
@ -1444,7 +1444,7 @@ class myLevelEditor(AppShell):
self.makeDirty()
AllScene.toggleLight()
return
def sideWindowClose(self,worldColor,lightEnable,ParticleEnable, basedriveEnable,collision,
backface, texture, wireframe, grid, widgetVis, enableAutoCamera):
################################################################
@ -1478,7 +1478,7 @@ class myLevelEditor(AppShell):
# This function will do nothing but call other function
# to duplicate selected node...
#
# Ok... this is really redundancy...
# Ok... this is really redundancy...
#
################################################################
AllScene.duplicateObj(nodePath, pos, hpr, scale, num)
@ -1685,11 +1685,11 @@ class myLevelEditor(AppShell):
t.doneColor = doneColor
# This really does all the work
t.uponDeath = self.flashDone
def flashDummy(self, state):
# Real work is done in upon death function
return Task.done
def flashDone(self,state):
# Return node Path to original state
if state.nodePath.isEmpty():
@ -1701,7 +1701,7 @@ class myLevelEditor(AppShell):
state.nodePath.clearColor()
editor = myLevelEditor(parent = base.tkRoot)

View File

@ -31,7 +31,7 @@ class AnimPanel(AppShell):
dragMode = False
rateList= ['1/24.0', '0.1', '0.5', '1.0', '2.0', '5.0' , '10.0']
def __init__(self, aNode = None, parent = None, **kw):
INITOPT = Pmw.INITOPT
self.id = 'AnimPanel '+ aNode.getName()
@ -63,7 +63,7 @@ class AnimPanel(AppShell):
menuBar = self.menuBar
menuBar.addmenu('Anim', 'Anim Panel Operations')
# Reset all actor controls
menuBar.addmenuitem('File', 'command',
'Load Animation',
@ -102,7 +102,7 @@ class AnimPanel(AppShell):
scrolledlist_items = self['animList'])
self.AnimEntry.place(x=240,y=10,anchor=NW)
self.playRateEntry = self.createcomponent(
'playRateMenu', (), None,
Pmw.ComboBox, (actorFrame,),
@ -133,7 +133,7 @@ class AnimPanel(AppShell):
command = self.updateDisplay,
variable = self.unitsVar)
self.displayButton.place(x=120,y=77,anchor=NW)
## scale control
frameFrame = Frame(actorFrame, relief = SUNKEN, bd = 1)
self.minLabel = self.createcomponent(
@ -158,7 +158,7 @@ class AnimPanel(AppShell):
text = 24)
self.maxLabel.pack(side = LEFT)
frameFrame.pack(side = LEFT, expand = 1, fill = X)
## button contorl
ButtomFrame = Frame(actorFrame, relief = SUNKEN, bd = 1,borderwidth=5)
self.toStartButton = self.createcomponent(
@ -168,7 +168,7 @@ class AnimPanel(AppShell):
width = 8,
command = self.resetAllToZero)
self.toStartButton.pack(side = LEFT, expand = 1, fill = X)
self.playButton = self.createcomponent(
'playButton', (), None,
Button, (ButtomFrame,),
@ -214,14 +214,14 @@ class AnimPanel(AppShell):
#################################################################
# updateList(self)
# This function will update the list of animations that the Actor
# currently has into the combo box widget.
# currently has into the combo box widget.
#################################################################
self.ignore('DataH_loadFinish'+self.nodeName)
del self.loaderWindow
self['animList'] = self['actor'].getAnimNames()
animL = self['actor'].getAnimNames()
self.AnimEntry.setlist(animL)
def removeAnim(self):
#################################################################
@ -308,7 +308,7 @@ class AnimPanel(AppShell):
self.stopButton.config(state=DISABLED)
return Task.done
else:
self.gotoT(self.currTime)
self.gotoT(self.currTime)
return Task.cont
def stop(self):
@ -329,7 +329,7 @@ class AnimPanel(AppShell):
# the current animation. Most important thing this function do is
# to recalculate all variables to fit the selected animation
#################################################################
self.animName = self.AnimEntry.get()
self.animName = self.AnimEntry.get()
playRate = '%0.1f' % self['actor'].getPlayRate(self.animName)
if playRate not in self.rateList:
def strCmp(a, b):
@ -376,7 +376,7 @@ class AnimPanel(AppShell):
else:
self.minLabel['text'] = '0.0'
self.maxLabel['text'] = "%.2f" % self.duration
self.frameControl.configure(from_ = 0.0,
self.frameControl.configure(from_ = 0.0,
to = self.duration,
resolution = 0.01)
@ -429,7 +429,7 @@ class AnimPanel(AppShell):
#################################################################
self.dragMode = True
return
def resetAllToZero(self):
#################################################################
# resetAllToZero(self)
@ -536,8 +536,8 @@ class LoadAnimPanel(AppShell):
mainFrame.pack(expand = 1, fill = BOTH)
def onDestroy(self, event):
messenger.send('AWL_close',[self.nodeName])
'''

View File

@ -36,7 +36,7 @@ class BlendAnimPanel(AppShell):
enableBlend = False
currentBlendName = None
def __init__(self, aNode = None, blendDict={}, parent = None, **kw):
INITOPT = Pmw.INITOPT
self.id = 'BlendAnimPanel '+ aNode.getName()
@ -95,7 +95,7 @@ class BlendAnimPanel(AppShell):
self.blendAnimEntry.pack(side=LEFT)
Label(actorFrame, text= " ", font=('MSSansSerif', 10)).pack(side=LEFT)
button = Button(actorFrame, text="Save", font=('MSSansSerif', 10),width = 12,
command = self.saveButtonPushed).pack(side=LEFT)
button = Button(actorFrame, text="Remove", font=('MSSansSerif', 10),width = 12,
@ -130,7 +130,7 @@ class BlendAnimPanel(AppShell):
scrolledlist_items = self['animList'])
self.AnimEntryB.pack(side=LEFT)
actorFrame.pack(side = TOP, expand = False, fill = X)
### Blend Enable checkbox
actorFrame = Frame(interior, relief = SUNKEN, bd = 1)
Label(actorFrame, text= "Enable Blending:", font=('MSSansSerif', 10)).pack(side=LEFT,)
@ -182,7 +182,7 @@ class BlendAnimPanel(AppShell):
self.playRateEntry.pack(side=LEFT)
self.playRateEntry.selectitem('1.0')
### Loop checkbox
### Loop checkbox
Label(actorFrame, text= " ", font=('MSSansSerif', 10)).pack(side=LEFT,)
Label(actorFrame, text= "Loop:", font=('MSSansSerif', 10)).pack(side=LEFT,)
@ -193,14 +193,14 @@ class BlendAnimPanel(AppShell):
Checkbutton, (actorFrame,),
variable = self.loopVar)
self.loopButton.pack(side=LEFT)
actorFrame.pack(side = TOP, expand = True, fill = X)
### Display Frames/Seconds
actorFrame = Frame(interior)
Label(actorFrame, text= "Frame/Second:", font=('MSSansSerif', 10)).pack(side=LEFT)
self.unitsVar = IntVar()
@ -213,7 +213,7 @@ class BlendAnimPanel(AppShell):
self.displayButton.pack(side=LEFT)
actorFrame.pack(side = TOP, expand = True, fill = X)
## scale control
actorFrame = Frame(interior)
frameFrame = Frame(actorFrame, relief = SUNKEN, bd = 1)
@ -240,7 +240,7 @@ class BlendAnimPanel(AppShell):
self.maxLabel.pack(side = LEFT)
frameFrame.pack(side = LEFT, expand = 1, fill = X)
actorFrame.pack(side = TOP, expand = True, fill = X)
## button contorl
actorFrame = Frame(interior)
ButtomFrame = Frame(actorFrame, relief = SUNKEN, bd = 1,borderwidth=5)
@ -251,7 +251,7 @@ class BlendAnimPanel(AppShell):
width = 8,
command = self.resetAllToZero)
self.toStartButton.pack(side = LEFT, expand = 1, fill = X)
self.playButton = self.createcomponent(
'playButton', (), None,
Button, (ButtomFrame,),
@ -287,7 +287,7 @@ class BlendAnimPanel(AppShell):
animL = self['actor'].getAnimNames()
self.AnimEntryA.setlist(animL)
self.AnimEntryB.setlist(animL)
def play(self):
#################################################################
# play(self)
@ -330,7 +330,7 @@ class BlendAnimPanel(AppShell):
self.stopButton.config(state=DISABLED)
return Task.done
else:
self.gotoT(self.currTime)
self.gotoT(self.currTime)
return Task.cont
def stop(self):
@ -405,7 +405,7 @@ class BlendAnimPanel(AppShell):
else:
self.minLabel['text'] = '0.0'
self.maxLabel['text'] = "%.2f" % self.duration
self.frameControl.configure(from_ = 0.0,
self.frameControl.configure(from_ = 0.0,
to = self.duration,
resolution = 0.01)
@ -454,7 +454,7 @@ class BlendAnimPanel(AppShell):
#################################################################
self.dragMode = True
return
def resetAllToZero(self):
#################################################################
# resetAllToZero(self)
@ -559,7 +559,7 @@ class BlendAnimPanel(AppShell):
self.blendAnimEntry.clear()
self.currentBlendName = None
return
def saveButtonPushed(self):
#################################################################
# saveButtonPushed(self)

View File

@ -290,7 +290,7 @@ class DirectCameraControl(DirectObject):
def lockCOA(self):
self.fLockCOA = 1
SEditor.message('COA Lock On')
def unlockCOA(self):
self.fLockCOA = 0
SEditor.message('COA Lock Off')
@ -456,7 +456,7 @@ class DirectCameraControl(DirectObject):
def centerCam(self):
self.centerCamIn(1.0)
def centerCamNow(self):
self.centerCamIn(0.)
@ -493,7 +493,7 @@ class DirectCameraControl(DirectObject):
blendType = 'easeInOut',
task = 'manipulateCamera')
t.uponDeath = self.updateCoaMarkerSizeOnDeath
def spawnMoveToView(self, view):
# Kill any existing tasks
taskMgr.remove('manipulateCamera')
@ -527,7 +527,7 @@ class DirectCameraControl(DirectObject):
self.camManipRef.setPosHpr(self.coaMarker, ZERO_VEC,
hprOffset)
# Scale center vec by current distance to target
offsetDistance = Vec3(SEditor.camera.getPos(self.camManipRef) -
offsetDistance = Vec3(SEditor.camera.getPos(self.camManipRef) -
ZERO_POINT).length()
scaledCenterVec = Y_AXIS * (-1.0 * offsetDistance)
# Now put the camManipRef at that point
@ -543,15 +543,15 @@ class DirectCameraControl(DirectObject):
blendType = 'easeInOut',
task = 'manipulateCamera')
t.uponDeath = self.updateCoaMarkerSizeOnDeath
def swingCamAboutWidget(self, degrees, t):
# Remove existing camera manipulation task
taskMgr.remove('manipulateCamera')
# Record undo point
SEditor.pushUndo([SEditor.camera])
# Coincident with widget
self.camManipRef.setPos(self.coaMarker, ZERO_POINT)
# But aligned with render space
@ -584,16 +584,16 @@ class DirectCameraControl(DirectObject):
# At what distance does the object fill 30% of the screen?
# Assuming radius of 1 on widget
camY = SEditor.dr.near * (2.0 * maxScale)/(0.3 * maxDim)
# What is the vector through the center of the screen?
centerVec = Y_AXIS * camY
# Where is the node relative to the viewpoint
vWidget2Camera = SEditor.widget.getPos(SEditor.camera)
# How far do you move the camera to be this distance from the node?
deltaMove = vWidget2Camera - centerVec
# Move a target there
self.camManipRef.setPos(SEditor.camera, deltaMove)
@ -605,7 +605,7 @@ class DirectCameraControl(DirectObject):
task = 'manipulateCamera')
# Upon death, reparent Cam to parent
fitTask.parent = parent
fitTask.uponDeath = self.reparentCam
fitTask.uponDeath = self.reparentCam
def moveToFit(self):
# How bit is the active widget?
@ -629,7 +629,7 @@ class DirectCameraControl(DirectObject):
# Spawn a task to move the widget
t = SEditor.widget.lerpPos(Point3(centerVec),
CAM_MOVE_DURATION,
other = SEditor.camera,
other = SEditor.camera,
blendType = 'easeInOut',
task = 'moveToFitTask')
t.uponDeath = lambda state: taskMgr.remove('stickToWidget')

View File

@ -1,7 +1,7 @@
####################################################################################################################################################
# File Saving
####################################################################################################################################################
# File Saving
# This code saves the scene out as python code... the scene is stored in the various dictionaries in "dataHolder.py" ...the class "AllScene"
#
#
####################################################################################################################################################
from pandac.PandaModules import *
@ -21,12 +21,12 @@ import seForceGroup
class FileSaver:
####################################################################################################################################################
####################################################################################################################################################
# This class saves out the scene built with the scene editor as python code
# There are dictionaries saved out to save the state of the scene for reloading it with the editor
# Currently saving is supported for Models, Animations, Lights, Dummy Nodes
# Attributes like parenting are also saved out
# This class is actually instantiated in sceneEditor.py in the saveScene() method
# This class is actually instantiated in sceneEditor.py in the saveScene() method
####################################################################################################################################################
def __init(self):
@ -34,11 +34,11 @@ class FileSaver:
def SaveFile(self,AllScene,filename,dirname,reSaveFlag=0):
################################################################################################################################################
################################################################################################################################################
# This function takes the "dataHolder" instance "AllScene" which has dictionaries containing scene information
# The filename is where the scene will be written to
################################################################################################################################################
i1=" " # indentation
i2=i1+i1 # double indentation
out_file = open(filename,"w")
@ -57,7 +57,7 @@ class FileSaver:
out_file.write("# theScene=SavedScene() #instantiate the class\n")
out_file.write("# IMPORTANT: All the documentation below refers to \"theScene\" as the instance of SavedScene()\n")
out_file.write("##########################################################################################################\n\n")
out_file.write("##########################################################################################################\n")
out_file.write("# Import Panda Modules\n")
out_file.write("##########################################################################################################\n")
@ -146,7 +146,7 @@ class FileSaver:
for model in AllScene.ModelDic:
out_file.write("\n")
modelS=str(model)
if(1): # This is kept for now... perhaps later some sort of check might have to be enforced based on loadMode
#Loading Code
out_file.write(i2+"# Loading model's egg file\n")
@ -165,33 +165,33 @@ class FileSaver:
for index in range(textures.getNumTextures()):
texture=textures.getTexture(index)
texfilename=texture.getFilename()
fnamelist.append(texfilename.getFullpath())
fnamelist.append(texfilename.getFullpath())
oldFilename=Filename(Filename(AllScene.ModelRefDic[model].getDirname()),texfilename)
if(not oldFilename.isRegularFile()):
if(texfilename.resolveFilename(getTexturePath(),"")):
oldFilename=texfilename
oldtexpath=oldFilename.toOsSpecific()
newtexpath=dirname + "/" + texfilename.getBasename()
newtexpathF=Filename(newtexpath)
newtexpathSpecific=newtexpathF.toOsSpecific()
print "TEXTURE SAVER:: copying" + oldtexpath + " to " + newtexpathSpecific
if(oldtexpath != newtexpathSpecific):
shutil.copyfile(oldtexpath,newtexpathSpecific)
# Copy the file over to the relative directory
oldModelpath=AllScene.ModelRefDic[model].toOsSpecific()
print "FILESAVER:: copying from " + AllScene.ModelRefDic[model].toOsSpecific() + "to" + newpathSpecific
print "FILESAVER:: copying from " + AllScene.ModelRefDic[model].toOsSpecific() + "to" + newpathSpecific
if(oldModelpath!=newpathSpecific):
shutil.copyfile(oldModelpath,newpathSpecific)
e=EggData()
e.read(AllScene.ModelRefDic[model])
etc=EggTextureCollection()
@ -203,10 +203,10 @@ class FileSaver:
fn.setDirname("")
tex.setFilename(fn)
e.writeEgg(Filename.fromOsSpecific(newpathSpecific))
out_file.write(i2+"if(self.loadmode==1):\n")
out_file.write(i2+"if(self.loadmode==1):\n")
out_file.write(i2+i1+ "self."+ modelS + "=loader.loadModel(\'" + self.savepath + "/" + AllScene.ModelRefDic[model].getBasename() + "')\n")#Relative Path
out_file.write(i2+"else:\n")
out_file.write(i2+i1+ "self."+ modelS + "=loader.loadModel(self.executionpath + \'/" + AllScene.ModelRefDic[model].getBasename() + "')\n")#Relative Path with execution point specified by the invoking-level-editor
@ -221,7 +221,7 @@ class FileSaver:
out_file.write(i2+"# Alpha\n")
out_file.write(i2+ "self."+ modelS + ".setTransparency(1)\n")
clr=AllScene.ModelDic[model].getColor()
out_file.write(i2+ "self."+ modelS + ".setColor(%.4f,%.4f,%.4f,%.4f)\n"%(clr.getX(),clr.getY(),clr.getZ(),clr.getW()))
out_file.write(i2+ "self."+ modelS + ".setColor(%.4f,%.4f,%.4f,%.4f)\n"%(clr.getX(),clr.getY(),clr.getZ(),clr.getW()))
out_file.write("\n")
out_file.write(i2+ "# Reparent To Render for now and later we update all the parentings\n")
@ -234,7 +234,7 @@ class FileSaver:
out_file.write(i2+ "self.ModelDic[\'" + modelS + "\']=self." + AllScene.ModelDic[model].getName()+"\n")
#out_file.write(i2+ "self.ModelRefDic[\'" + modelS + "\']=Filename(\'"+ AllScene.ModelRefDic[model].getFullpath() +"\')\n")# The old Absolute Path way
out_file.write(i2+ "self.ModelRefDic[\'" + modelS + "\']=\'"+ AllScene.ModelRefDic[model].getBasename() +"\'\n")# Relative paths
out_file.write(i2+ "self.ModelDic[\'"+ modelS + "\'].setName(\'"+ modelS +"\')\n")
out_file.write(i2+ "self.ModelDic[\'"+ modelS + "\'].setName(\'"+ modelS +"\')\n")
out_file.write("\n")
####################################################################################################################################################
@ -248,7 +248,7 @@ class FileSaver:
for dummy in AllScene.dummyDict:
out_file.write("\n")
dummyS=str(dummy)
if(1): # This is kept for now... perhaps later some sort of check might have to be enforced based on loadMode
out_file.write(i2+ "self."+ dummyS + "=loader.loadModel(\"models/misc/sphere\")\n")
#Transformation Code
@ -259,13 +259,13 @@ class FileSaver:
out_file.write(i2+ "self.dummyDict[\'" + dummyS + "\']=self." + AllScene.dummyDict[dummy].getName()+"\n")
out_file.write(i2+ "self.dummyDict[\'"+ dummyS + "\'].setName(\'"+ dummyS +"\')\n")
out_file.write("\n")
out_file.write(i2+ "# Save Metadata...can be retrieved by doing theScene.dummyDict[\"Dummy_Name\"].getTag(\"Metadata\")\n")
out_file.write(i2+ "# Save Metadata...can be retrieved by doing theScene.dummyDict[\"Dummy_Name\"].getTag(\"Metadata\")\n")
out_file.write(i2+ "self."+ dummyS + ".setTag(\"Metadata\",\"" + AllScene.dummyDict[dummy].getTag("Metadata") + "\")\n")
out_file.write("\n")
####################################################################################################################################################
# Saving Actors and their animations
####################################################################################################################################################
####################################################################################################################################################
out_file.write(i2+"##########################################################################################################\n")
out_file.write(i2+"# Code for all the Actors and animations\n")
out_file.write(i2+"# To access the Actors\n")
@ -275,7 +275,7 @@ class FileSaver:
for actor in AllScene.ActorDic:
out_file.write("\n")
actorS=str(actor)
if(1): # This is kept for now... perhaps later some sort of check might have to be enforced based on loadMode
#out_file.write(i2+ "self."+ actorS + "=Actor.Actor(\'"+ AllScene.ActorRefDic[actor].getFullpath() + "\')\n")# The old way with absolute paths
@ -293,7 +293,7 @@ class FileSaver:
for index in range(textures.getNumTextures()):
texture=textures.getTexture(index)
texfilename=texture.getFilename()
actorfnamelist.append(texfilename.getFullpath())
actorfnamelist.append(texfilename.getFullpath())
oldFilename=Filename(Filename(AllScene.ActorRefDic[actor].getDirname()),texfilename)
if(not oldFilename.isRegularFile()):
@ -312,10 +312,10 @@ class FileSaver:
# Copy the file over to the relative directory
oldActorpath=AllScene.ActorRefDic[actor].toOsSpecific()
print "FILESAVER:: copying from " + AllScene.ActorRefDic[actor].toOsSpecific() + "to" + newpathSpecific
print "FILESAVER:: copying from " + AllScene.ActorRefDic[actor].toOsSpecific() + "to" + newpathSpecific
if(oldActorpath!=newpathSpecific):
shutil.copyfile(oldActorpath,newpathSpecific)
e=EggData()
e.read(AllScene.ActorRefDic[actor])
@ -328,10 +328,10 @@ class FileSaver:
fn.setDirname("")
tex.setFilename(fn)
e.writeEgg(Filename.fromOsSpecific(newpathSpecific))
out_file.write(i2+"if(self.loadmode==1):\n")
out_file.write(i2+"if(self.loadmode==1):\n")
out_file.write(i2+i1+ "self."+ actorS + "=Actor.Actor(\'" + self.savepath + "/" + AllScene.ActorRefDic[actor].getBasename() + "')\n")#Relative Path
out_file.write(i2+"else:\n")
out_file.write(i2+i1+ "self."+ actorS + "=Actor.Actor(self.executionpath + \'/" + AllScene.ActorRefDic[actor].getBasename() + "')\n")#Relative Path with execution point specified by the invoking-level-editor
@ -347,7 +347,7 @@ class FileSaver:
out_file.write(i2+ "self."+ actorS + ".setColor(%.4f,%.4f,%.4f,%.4f)\n"%(clr.getX(),clr.getY(),clr.getZ(),clr.getW()))
out_file.write(i2+ "self."+ actorS + ".reparentTo(render)\n")
out_file.write("\n")
out_file.write(i2+ "# Save Metadata...can be retrieved by doing theScene.ActorDic[\"Actor_Name\"].getTag(\"Metadata\")\n")
out_file.write(i2+ "self."+ actorS + ".setTag(\"Metadata\",\"" + AllScene.ActorDic[actor].getTag("Metadata") + "\")\n")
@ -362,7 +362,7 @@ class FileSaver:
#out_file.write(i2+ "self."+ actorS + ".loadAnims(" + str(ActorAnimations) +")\n") # Old way with absolute paths
#Manakel 2/12/2004: solve the not empty but not defined animation case
if not animation is None:
print "ACTOR ANIMATIONS:" + ActorAnimations[animation]
print "ACTOR ANIMATIONS:" + ActorAnimations[animation]
oldAnimPath=Filename(ActorAnimations[animation])
oldAnim=oldAnimPath.toOsSpecific()
dirOS=Filename(dirname)
@ -380,24 +380,24 @@ class FileSaver:
out_file.write(i2+"else:\n")
theloadAnimString=str(ActorAnimationsInvoke)# We hack the "self.executionpath" part into the dictionary as a variable using string replace
print "LOAD ANIM STRING BEFORE" + theloadAnimString
theloadAnimString=theloadAnimString.replace('\'self.executionpath +','self.executionpath + \'')
theloadAnimString=theloadAnimString.replace('\'self.executionpath +','self.executionpath + \'')
print "LOAD ANIM STRING AFTER" + theloadAnimString
out_file.write(i2+ i1+"self."+ actorS + ".loadAnims(" + theloadAnimString +")\n") # Now with new relative paths based on editor invocation
out_file.write(i2+ "self.ActorDic[\'" + actorS + "\']=self." + AllScene.ActorDic[actor].getName()+"\n")
#out_file.write(i2+ "self.ActorRefDic[\'" + actorS + "\']=Filename(\'"+AllScene.ActorRefDic[actor].getFullpath() +"\')\n") # Old way with absolute paths
out_file.write(i2+ "self.ActorRefDic[\'" + actorS + "\']=\'"+ AllScene.ActorRefDic[actor].getBasename() +"\'\n")# Relative paths
out_file.write(i2+ "self.ActorDic[\'"+ actorS + "\'].setName(\'"+ actorS +"\')\n")
out_file.write(i2+ "self.ActorDic[\'"+ actorS + "\'].setName(\'"+ actorS +"\')\n")
if(AllScene.blendAnimDict.has_key(actor)): # Check if a dictionary of blended animations exists
out_file.write(i2+ "self.blendAnimDict[\"" + actorS +"\"]=" + str(AllScene.blendAnimDict[actor]) + "\n")
out_file.write("\n")
####################################################################################################################################################
# Collsion Node Saving
####################################################################################################################################################
out_file.write(i2+"##########################################################################################################\n")
out_file.write(i2+"# Code for setting up Collision Nodes\n")
out_file.write(i2+"# To use collision detection:\n")
@ -410,7 +410,7 @@ class FileSaver:
nodetype=solid.getType().getName()
if(nodetype=="CollisionSphere"): #Save Collison Sphere
out_file.write(i2+"collSolid=CollisionSphere(%.3f,%.3f,%.3f,%.3f)\n"%(solid.getCenter().getX(),solid.getCenter().getY(),solid.getCenter().getZ(),solid.getRadius()))
out_file.write(i2+"collSolid=CollisionSphere(%.3f,%.3f,%.3f,%.3f)\n"%(solid.getCenter().getX(),solid.getCenter().getY(),solid.getCenter().getZ(),solid.getRadius()))
pass
elif(nodetype=="CollisionPolygon"): #Save Collison Polygon
@ -430,13 +430,13 @@ class FileSaver:
out_file.write(i2+"pointB = Point3(" + bx + "," + by + "," + bz + ")\n")
out_file.write(i2+"pointC = Point3(" + cx + "," + cy + "," + cz + ")\n")
out_file.write(i2+"collSolid=CollisionPolygon(pointA, pointB, pointC)\n")
pass
elif(nodetype=="CollisionSegment"): #Save Collison Segment
A=AllScene.collisionDict[collnode].node().getSolid(0).getPointA()
B=AllScene.collisionDict[collnode].node().getSolid(0).getPointB()
out_file.write(i2+"pointA = Point3(%.3f,%.3f,%.3f)\n"%(A.getX(),A.getY(),A.getZ()))
out_file.write(i2+"pointB = Point3(%.3f,%.3f,%.3f)\n"%(B.getX(),B.getY(),B.getZ()))
out_file.write(i2+"collSolid=CollisionSegment()\n")
@ -455,7 +455,7 @@ class FileSaver:
out_file.write(i2+"collSolid=CollisionRay()\n")
out_file.write(i2+"collSolid.setOrigin(point)\n")
out_file.write(i2+"collSolid.setDirection(vector)\n")
pass
else:
print "Invalid Collision Node: " + nodetype
@ -466,7 +466,7 @@ class FileSaver:
out_file.write(i2+"self." + collnodeS + "_Node" + ".addSolid(collSolid)\n")
out_file.write(i2+"base.cTrav.addCollider(self." + collnodeS + "_Node,self.CollisionHandler)\n")
out_file.write("\n")
@ -488,8 +488,8 @@ class FileSaver:
out_file.write (i2+ "alight = AmbientLight(\'"+ light.getName() +"\')\n")
out_file.write (i2+ "alight.setColor(VBase4("+ str(light.getLightColor().getX())+ "," + str(light.getLightColor().getY())+ "," + str(light.getLightColor().getZ()) + "," + str(light.getLightColor().getW()) + "))\n")
out_file.write (i2+ "self.lightAttrib=self.lightAttrib.addLight(alight)\n")
out_file.write (i2+ "self."+light.getName()+"= render.attachNewNode(alight.upcastToPandaNode())\n")
out_file.write (i2+ "self."+light.getName()+".setTag(\"Metadata\",\"" + light.getTag("Metadata") + "\")\n")
out_file.write (i2+ "self."+light.getName()+"= render.attachNewNode(alight.upcastToPandaNode())\n")
out_file.write (i2+ "self."+light.getName()+".setTag(\"Metadata\",\"" + light.getTag("Metadata") + "\")\n")
out_file.write (i2+ "self.LightDict[\'" + light.getName() + "\']=alight\n")
out_file.write (i2+ "self.LightTypes[\'" + light.getName() + "\']=\'" + type + "\'\n")
out_file.write (i2+ "self.LightNodes[\'" + light.getName() + "\']=self." + light.getName() + "\n")
@ -503,10 +503,10 @@ class FileSaver:
#out_file.write (i2+ "alight.setPoint(Point3(" + str(light.getX()) + "," + str(light.getY()) + "," + str(light.getZ()) + "))\n")
out_file.write (i2+ "alight.setSpecularColor(Vec4(" + str(light.getSpecColor().getX()) + "," + str(light.getSpecColor().getY()) + "," + str(light.getSpecColor().getZ()) + "," + str(light.getSpecColor().getW()) + "))\n")
out_file.write (i2+ "self.lightAttrib=self.lightAttrib.addLight(alight)\n")
out_file.write (i2+ "self."+light.getName()+ "= render.attachNewNode(alight.upcastToPandaNode())\n")
out_file.write (i2+ "self."+light.getName()+ "= render.attachNewNode(alight.upcastToPandaNode())\n")
out_file.write (i2+ "self."+light.getName()+ ".setPos(Point3(" + str(light.getX()) + "," + str(light.getY()) + "," + str(light.getZ()) + "))\n")
out_file.write (i2+ "self."+light.getName()+ ".setHpr(Vec3("+ str(light.getH())+ "," + str(light.getP())+ "," + str(light.getR()) + "))\n")
out_file.write (i2+ "self."+light.getName()+ ".setTag(\"Metadata\",\"" + light.getTag("Metadata") + "\")\n")
out_file.write (i2+ "self."+light.getName()+ ".setTag(\"Metadata\",\"" + light.getTag("Metadata") + "\")\n")
#out_file.write (i2+ "alight.setPos
out_file.write (i2+ "self.LightDict[\'" + light.getName() + "\']=alight\n")
out_file.write (i2+ "self.LightTypes[\'" + light.getName() + "\']=\'" + type + "\'\n")
@ -521,8 +521,8 @@ class FileSaver:
out_file.write (i2+ "alight.setSpecularColor(Vec4(" + str(light.getSpecColor().getX()) + "," + str(light.getSpecColor().getY()) + "," + str(light.getSpecColor().getZ()) + "," + str(light.getSpecColor().getW()) + "))\n")
out_file.write (i2+ "alight.setAttenuation(Vec3("+ str(light.getAttenuation().getX()) + "," + str(light.getAttenuation().getY()) + "," + str(light.getAttenuation().getZ()) + "))\n")
out_file.write (i2+ "self.lightAttrib=self.lightAttrib.addLight(alight)\n")
out_file.write (i2+ "self."+light.getName()+ "= render.attachNewNode(alight.upcastToPandaNode())\n")
out_file.write (i2+ "self."+light.getName()+ ".setTag(\"Metadata\",\"" + light.getTag("Metadata") + "\")\n")
out_file.write (i2+ "self."+light.getName()+ "= render.attachNewNode(alight.upcastToPandaNode())\n")
out_file.write (i2+ "self."+light.getName()+ ".setTag(\"Metadata\",\"" + light.getTag("Metadata") + "\")\n")
out_file.write (i2+ "self."+light.getName()+ ".setPos(Point3(" + str(light.getX()) + "," + str(light.getY()) + "," + str(light.getZ()) + "))\n")
out_file.write (i2+ "self.LightDict[\'" + light.getName() + "\']=alight\n")
out_file.write (i2+ "self.LightTypes[\'" + light.getName() + "\']=\'" + type + "\'\n")
@ -539,8 +539,8 @@ class FileSaver:
out_file.write (i2+ "alight.setAttenuation(Vec3("+ str(light.getAttenuation().getX()) + "," + str(light.getAttenuation().getY()) + "," + str(light.getAttenuation().getZ()) + "))\n")
out_file.write (i2+ "alight.setExponent(" +str(light.getExponent()) +")\n")
out_file.write (i2+ "self.lightAttrib=self.lightAttrib.addLight(alight)\n")
out_file.write (i2+ "self."+light.getName()+ "= render.attachNewNode(alight.upcastToLensNode())\n")
out_file.write (i2+ "self."+light.getName()+ ".setTag(\"Metadata\",\"" + light.getTag("Metadata") + "\")\n")
out_file.write (i2+ "self."+light.getName()+ "= render.attachNewNode(alight.upcastToLensNode())\n")
out_file.write (i2+ "self."+light.getName()+ ".setTag(\"Metadata\",\"" + light.getTag("Metadata") + "\")\n")
out_file.write (i2+ "self."+light.getName()+ ".setPos(Point3(" + str(light.getX()) + "," + str(light.getY()) + "," + str(light.getZ()) + "))\n")
out_file.write (i2+ "self."+light.getName()+ ".setHpr(Vec3("+ str(light.getH())+ "," + str(light.getP())+ "," + str(light.getR()) + "))\n")
out_file.write (i2+ "self.LightDict[\'" + light.getName() + "\']=alight\n")
@ -552,7 +552,7 @@ class FileSaver:
out_file.write (i2+ "return None")
out_file.write("\n")
####################################################################################################################################################
# Enable Lighting
@ -571,32 +571,32 @@ class FileSaver:
out_file.write(i2+"# Load Particle Effects. The parameters to this function are to allow us to use our modified versions of the Particle Effects modules when loading this file with the level editor\n")
out_file.write(i2+"self.starteffects(self.loadmode,self.seParticleEffect,self.seParticles)\n")
out_file.write("\n")
####################################################################################################################################################
# Save Camera Settings
####################################################################################################################################################
out_file.write("\n")
out_file.write(i2+ "# Save Camera Settings\n")
out_file.write(i2+ "camera.setX(" + str(camera.getX()) + ")\n")
out_file.write(i2+ "camera.setY(" + str(camera.getY()) + ")\n")
out_file.write(i2+ "camera.setZ(" + str(camera.getZ()) + ")\n")
out_file.write(i2+ "camera.setH(" + str(camera.getH()) + ")\n")
out_file.write(i2+ "camera.setP(" + str(camera.getP()) + ")\n")
out_file.write(i2+ "camera.setR(" + str(camera.getR()) + ")\n")
out_file.write(i2+ "camera.getChild(0).node().getLens().setNear(" + str(camera.getChild(0).node().getLens().getNear()) + ")\n")
out_file.write(i2+ "camera.getChild(0).node().getLens().setFar(" + str(camera.getChild(0).node().getLens().getFar()) + ")\n")
out_file.write(i2+ "camera.getChild(0).node().getLens().setFov(VBase2(%.5f,%.5f))\n"% (camera.getChild(0).node().getLens().getHfov(),camera.getChild(0).node().getLens().getVfov()))
out_file.write(i2+ "camera.setX(" + str(camera.getX()) + ")\n")
out_file.write(i2+ "camera.setY(" + str(camera.getY()) + ")\n")
out_file.write(i2+ "camera.setZ(" + str(camera.getZ()) + ")\n")
out_file.write(i2+ "camera.setH(" + str(camera.getH()) + ")\n")
out_file.write(i2+ "camera.setP(" + str(camera.getP()) + ")\n")
out_file.write(i2+ "camera.setR(" + str(camera.getR()) + ")\n")
out_file.write(i2+ "camera.getChild(0).node().getLens().setNear(" + str(camera.getChild(0).node().getLens().getNear()) + ")\n")
out_file.write(i2+ "camera.getChild(0).node().getLens().setFar(" + str(camera.getChild(0).node().getLens().getFar()) + ")\n")
out_file.write(i2+ "camera.getChild(0).node().getLens().setFov(VBase2(%.5f,%.5f))\n"% (camera.getChild(0).node().getLens().getHfov(),camera.getChild(0).node().getLens().getVfov()))
FilmSize=camera.getChild(0).node().getLens().getFilmSize()
out_file.write(i2+ "camera.getChild(0).node().getLens().setFilmSize(%.3f,%.3f)\n"%(FilmSize.getX(),FilmSize.getY()))
out_file.write(i2+ "camera.getChild(0).node().getLens().setFocalLength(" + str(camera.getChild(0).node().getLens().getFocalLength()) + ")\n")
out_file.write(i2+ "camera.setTag(\"Metadata\",\"" + camera.getTag("Metadata") + "\")\n")
out_file.write(i2+ "camera.getChild(0).node().getLens().setFilmSize(%.3f,%.3f)\n"%(FilmSize.getX(),FilmSize.getY()))
out_file.write(i2+ "camera.getChild(0).node().getLens().setFocalLength(" + str(camera.getChild(0).node().getLens().getFocalLength()) + ")\n")
out_file.write(i2+ "camera.setTag(\"Metadata\",\"" + camera.getTag("Metadata") + "\")\n")
out_file.write(i2+ "camera.reparentTo(render)\n")
out_file.write(i2+ "base.disableMouse()\n")
self.bgColor=base.getBackgroundColor()
out_file.write(i2+ "base.setBackgroundColor(%.3f,%.3f,%.3f)\n"%(self.bgColor.getX(),self.bgColor.getY(),self.bgColor.getZ()))
out_file.write("\n")
####################################################################################################################################################
# Mopath Saving
@ -626,17 +626,17 @@ class FileSaver:
out_file.write(i2+"mp=MopathInterval(m,self." + str(node) + ")\n")
out_file.write(i2+"self.curveIntervals.append(mp)\n")
out_file.write(i2+"if(self.loadmode==1):\n")
out_file.write(i2+i1+"self.curveRefColl.append(\"" + self.savepath +"/"+ filestring +"\")\n")
out_file.write(i2+"else:\n")
out_file.write(i2+i1+"self.curveRefColl.append(self.executionpath + \"/"+ filestring +"\")\n")
curvenumber=curvenumber+1
out_file.write(i2+"self.curveIntervalsDict[\"" + str(node) + "\"]=self.curveIntervals\n")
out_file.write(i2+"self.curveIntervalsDict[\"" + str(node) + "\"]=self.curveIntervals\n")
out_file.write(i2+"self.curveDict[\"" + str(node) + "\"]=self.curveRefColl\n")
####################################################################################################################################################
# Lets do all the reparenting here so as to make sure everything that needed to load was loaded
####################################################################################################################################################
@ -665,7 +665,7 @@ class FileSaver:
parent=AllScene.dummyDict[dummy].getParent().getName()
if(parent=="render" or parent=="camera"):
out_file.write(i2+ "self."+ dummyS + ".reparentTo(" + parent + ")\n")
else:
else:
if(AllScene.particleDict.has_key(parent)):
out_file.write(i2+ "self."+ dummyS + ".reparentTo(self." + parent + ".getEffect())\n")
else:
@ -675,7 +675,7 @@ class FileSaver:
out_file.write(i2+"\n")
for actor in AllScene.ActorDic:
actorS=str(actor)
actorS=str(actor)
parent=AllScene.ActorDic[actor].getParent().getName()
if(parent=="render" or parent=="camera"):
out_file.write(i2+ "self."+ actorS + ".reparentTo(" + parent + ")\n")
@ -687,7 +687,7 @@ class FileSaver:
out_file.write(i2+ "self.ActorDic[\'" + actorS + "\']=self." + AllScene.ActorDic[actor].getName()+"\n")
out_file.write(i2+"\n")
for collnode in AllScene.collisionDict:
collnodeS=str(collnode)
@ -741,7 +741,7 @@ class FileSaver:
for effect in AllScene.particleDict:
parent=AllScene.particleNodes[effect].getParent().getName()
if(parent=="render" or parent=="camera"):
out_file.write(i2+"self.particleDict[\""+ str(effect) +"\"].reparentTo(" + parent + ")\n")
out_file.write(i2+"self.particleDict[\""+ str(effect) +"\"].reparentTo(" + parent + ")\n")
else:
out_file.write(i2+"self.particleDict[\""+ str(effect) +"\"].reparentTo(self." + parent + ")\n")
out_file.write(i2+"\n")
@ -809,11 +809,11 @@ class FileSaver:
out_file.write(i2+"blendList=blendDicts[blendName]\n")
out_file.write(i2+"actor.stop(blendList[0])\n")
out_file.write(i2+"actor.stop(blendList[1])\n")
out_file.write("\n")
out_file.write("\n")
out_file.write(i1+"def changeBlending(self,actor,blendName,blending):\n")
out_file.write(i2+"blendDicts=self.blendAnimDict[actor.getName()]\n")
out_file.write(i2+"blendList=blendDicts[blendName]\n")
out_file.write(i2+"blendList=blendDicts[blendName]\n")
out_file.write(i2+"blendList[2]=blending\n")
out_file.write(i2+"self.blendAnimDict[actor.getName()]={blendName:[blendList[0],blendList[1],blending]}\n")
out_file.write("\n")
@ -823,21 +823,21 @@ class FileSaver:
####################################################################################################################################################
# Hide and Show Methods
####################################################################################################################################################
out_file.write("\n")
out_file.write(i2+"##########################################################################################################\n")
out_file.write(i2+"# Hide and Show Methods\n")
out_file.write(i2+"# These will help you hide/show dummies, collision solids, effect nodes etc.\n")
out_file.write(i2+"##########################################################################################################\n\n")
out_file.write("\n")
out_file.write(i1+"def hideDummies(self):\n")
out_file.write("\n")
out_file.write(i2+"for dummy in self.dummyDict:\n")
out_file.write(i2+i1+"self.dummyDict[dummy].reparentTo(hidden)\n")
out_file.write("\n")
out_file.write(i1+"def hideCollSolids(self):\n")
out_file.write("\n")
@ -857,8 +857,8 @@ class FileSaver:
out_file.write("\n")
out_file.write(i2+"for dummy in self.dummyDict:\n")
out_file.write(i2+i1+"self.dummyDict[dummy].reparentTo(hidden)\n")
out_file.write("\n")
out_file.write(i1+"def showCollSolids(self):\n")
out_file.write("\n")
@ -885,7 +885,7 @@ class FileSaver:
out_file.write(i2+"##########################################################################################################\n\n")
for effect in AllScene.particleDict:
out_file.write("\n\n")
out_file.write("class " + str(effect) + ":\n")
out_file.write(i1+"def __init__(self,mode=1,seParticleEffect=None,seParticles=None):\n")
@ -911,5 +911,5 @@ class FileSaver:
#out_file.write("run()\n")
out_file.close()

View File

@ -15,7 +15,7 @@ class ForceGroup(DirectObject):
"""__init__(self)"""
if (name == None):
self.name = 'ForceGroup-%d' % ForceGroup.id
self.name = 'ForceGroup-%d' % ForceGroup.id
ForceGroup.id += 1
else:
self.name = name
@ -74,7 +74,7 @@ class ForceGroup(DirectObject):
def getNodePath(self):
return self.nodePath
# Utility functions
# Utility functions
def __getitem__(self, index):
numForces = self.node.getNumForces()
if ((index < 0) or (index >= numForces)):

View File

@ -79,7 +79,7 @@ class LineNodePath(NodePath):
def getVertexColor( self ):
return self.lineSegs.getVertexColor()
def drawArrow(self, sv, ev, arrowAngle, arrowLength):
"""
Do the work of moving the cursor around to draw an arrow from
@ -206,12 +206,12 @@ def qSlerp(startQuat, endQuat, t):
destQuat = Quat.identQuat()
# Calc dot product
cosOmega = (startQ.getI() * endQuat.getI() +
startQ.getJ() * endQuat.getJ() +
startQ.getJ() * endQuat.getJ() +
startQ.getK() * endQuat.getK() +
startQ.getR() * endQuat.getR())
# If the above dot product is negative, it would be better to
# go between the negative of the initial and the final, so that
# we take the shorter path.
# we take the shorter path.
if ( cosOmega < 0.0 ):
cosOmega *= -1
startQ.setI(-1 * startQ.getI())
@ -227,7 +227,7 @@ def qSlerp(startQuat, endQuat, t):
startScale = math.sin((1.0 - t) * omega)/sinOmega
endScale = math.sin(t * omega)/sinOmega
else:
# ends very close
# ends very close
startScale = 1.0 - t
endScale = t
destQuat.setI(startScale * startQ.getI() +

View File

@ -90,7 +90,7 @@ class DirectGrid(NodePath,DirectObject):
# Now redraw lines
numLines = int(math.ceil(self.gridSize/self.gridSpacing))
scaledSize = numLines * self.gridSpacing
center = self.centerLines
minor = self.minorLines
major = self.majorLines
@ -116,7 +116,7 @@ class DirectGrid(NodePath,DirectObject):
minor.create()
major.create()
self.gridBack.setScale(scaledSize)
def setXyzSnap(self, fSnap):
self.fXyzSnap = fSnap
@ -138,7 +138,7 @@ class DirectGrid(NodePath,DirectObject):
ROUND_TO(self.snapPos[0], self.gridSpacing),
ROUND_TO(self.snapPos[1], self.gridSpacing),
ROUND_TO(self.snapPos[2], self.gridSpacing))
# Move snap marker to this point
self.snapMarker.setPos(self.snapPos)
@ -157,7 +157,7 @@ class DirectGrid(NodePath,DirectObject):
def setGridSpacing(self, spacing):
self.gridSpacing = spacing
self.updateGrid()
def getGridSpacing(self):
return self.gridSpacing

View File

@ -62,7 +62,7 @@ class seLight(NodePath):
self.exponent = exponent
self.lence = lence
self.active = True
if isinstance(light, Spotlight):
node = light.upcastToLensNode()
else:
@ -75,10 +75,10 @@ class seLight(NodePath):
self.LightNode.setHpr(self.orientation)
self.LightNode.setPos(self.position)
else:
self.LightNode.setHpr(self.orientation)
self.LightNode.setHpr(self.orientation)
self.LightNode.setPos(self.position)
self.assign(self.LightNode)
if(self.type=='spot'):
self.helpModel = loader.loadModel( "models/misc/Spotlight" )
@ -99,7 +99,7 @@ class seLight(NodePath):
# getLight(self)
# This function will return the light object it contains.
#################################################################
return self.light
def getLightColor(self):
@ -108,14 +108,14 @@ class seLight(NodePath):
# This function will return the color of the light color of this light node.
#################################################################
return self.lightcolor
def getName(self):
#################################################################
# getName(self)
# This function will return the name of this light.
#################################################################
return self.light.getName()
def rename(self,name):
#################################################################
# rename(self, name)
@ -203,7 +203,7 @@ class seLight(NodePath):
#################################################################
self.orientation = self.LightNode.getHpr()
return self.orientation
def setOrientation(self,orient):
#################################################################
# setOrientation(self, orient)
@ -241,7 +241,7 @@ class seLight(NodePath):
self.light.setAttenuation(Vec3(value, self.linear, self.quadratic))
self.constant = value
return
def setLinearAttenuation(self, value):
#################################################################
# setLinearAttenuation(self, value)
@ -252,7 +252,7 @@ class seLight(NodePath):
self.light.setAttenuation(Vec3(self.constant, value, self.quadratic))
self.linear = value
return
def setQuadraticAttenuation(self, value):
#################################################################
# setQuadraticAttenuation(self, value)
@ -270,7 +270,7 @@ class seLight(NodePath):
# This function will return the value of the Exponent Attenuation
# of this light node. (float)
#################################################################
return self.exponent
return self.exponent
def setExponent(self, value):
#################################################################
@ -282,7 +282,7 @@ class seLight(NodePath):
self.light.setExponent(value)
self.exponent = value
return
class seLightManager(NodePath):
#################################################################
# seLightManager(NodePath)
@ -307,7 +307,7 @@ class seLightManager(NodePath):
self.helpModel = loader.loadModel( "models/misc/sphere" )
self.helpModel.reparentTo(self)
self.helpModel.hide()
@ -342,7 +342,7 @@ class seLightManager(NodePath):
### create the light
lence = None
if type == 'ambient':
self.ambientCount += 1
if(name=='DEFAULT_NAME'):
@ -368,7 +368,7 @@ class seLightManager(NodePath):
light = PointLight('point_' + `self.pointCount`)
else:
light = PointLight(name)
light.setColor(lightcolor)
light.setSpecularColor(specularColor)
light.setAttenuation(Vec3(constant, linear, quadratic))
@ -406,7 +406,7 @@ class seLightManager(NodePath):
self.lightDict[light.getName()] = lightNode
self.setOn(lightNode)
return self.lightDict.keys(),lightNode
def addLight(self, light):
@ -507,7 +507,7 @@ class seLightManager(NodePath):
#################################################################
for name in self.lightDict:
self.delete(name, removeEntry = False)
self.lightDict.clear()
def isLight(self,name):
@ -531,7 +531,7 @@ class seLightManager(NodePath):
return self.lightDict.keys(),lightNode
else:
print '----Light Mnager: No such Light!'
def getLightNodeList(self):
#################################################################
# getLightNodeList(self)
@ -612,7 +612,7 @@ class seLightManager(NodePath):
if render.node().hasAttrib(LightAttrib.getClassType()):
render.node().setAttrib(self.lightAttrib)
def setOff(self, lightNode):
#################################################################
# setOff(self, lightNode)

View File

@ -200,7 +200,7 @@ class DirectManipulationControl(DirectObject):
# Send event to signal start of manipulation
messenger.send('DIRECT_manipulateObjectStart')
# Manipulate the real object with the constraint
# The constraint is passed as the name of the node
# The constraint is passed as the name of the node
self.spawnManipulateObjectTask()
def spawnManipulateObjectTask(self):
@ -314,7 +314,7 @@ class DirectManipulationControl(DirectObject):
self.fWidgetTop = self.widgetCheck('top?')
self.rotationCenter = getScreenXY(SEditor.widget)
self.lastCrankAngle = getCrankAngle(self.rotationCenter)
# Rotate widget based on how far cursor has swung around origin
newAngle = getCrankAngle(self.rotationCenter)
deltaAngle = self.lastCrankAngle - newAngle
@ -528,7 +528,7 @@ class ObjectHandles(NodePath,DirectObject):
self.xDiscGroup = self.xHandles.find('**/x-disc-group')
self.xDisc = self.xHandles.find('**/x-disc-visible')
self.xDiscCollision = self.xHandles.find('**/x-disc')
self.yHandles = self.find('**/Y')
self.yPostGroup = self.yHandles.find('**/y-post-group')
self.yPostCollision = self.yHandles.find('**/y-post')
@ -537,7 +537,7 @@ class ObjectHandles(NodePath,DirectObject):
self.yDiscGroup = self.yHandles.find('**/y-disc-group')
self.yDisc = self.yHandles.find('**/y-disc-visible')
self.yDiscCollision = self.yHandles.find('**/y-disc')
self.zHandles = self.find('**/Z')
self.zPostGroup = self.zHandles.find('**/z-post-group')
self.zPostCollision = self.zHandles.find('**/z-post')
@ -782,7 +782,7 @@ class ObjectHandles(NodePath,DirectObject):
lines.moveTo(0,0,0)
lines.drawTo(-1.5,0,0)
lines.create()
# X ring
self.xRing = self.xRingGroup.attachNewNode('x-ring-visible')
lines = LineNodePath(self.xRing)
@ -794,7 +794,7 @@ class ObjectHandles(NodePath,DirectObject):
math.cos(deg2Rad(ang)),
math.sin(deg2Rad(ang)))
lines.create()
# Y post
self.yPost = self.yPostGroup.attachNewNode('y-post-visible')
lines = LineNodePath(self.yPost)
@ -809,7 +809,7 @@ class ObjectHandles(NodePath,DirectObject):
lines.moveTo(0,0,0)
lines.drawTo(0,-1.5,0)
lines.create()
# Y ring
self.yRing = self.yRingGroup.attachNewNode('y-ring-visible')
lines = LineNodePath(self.yRing)
@ -836,7 +836,7 @@ class ObjectHandles(NodePath,DirectObject):
lines.moveTo(0,0,0)
lines.drawTo(0,0,-1.5)
lines.create()
# Z ring
self.zRing = self.zRingGroup.attachNewNode('z-ring-visible')
lines = LineNodePath(self.zRing)
@ -929,12 +929,12 @@ class ObjectHandles(NodePath,DirectObject):
# Calc the xfrom from camera to the nodePath
mCam2NodePath = SEditor.camera.getMat(nodePath)
# And determine where the viewpoint is relative to widget
lineOrigin = VBase3(0)
decomposeMatrix(mCam2NodePath, VBase3(0), VBase3(0), lineOrigin,
CSDefault)
# Next we find the vector from viewpoint to the widget through
# the mouse's position on near plane.
# This defines the intersection ray

View File

@ -59,7 +59,7 @@ class MopathRecorder(AppShell, DirectObject):
# Call superclass initialization function
AppShell.__init__(self)
self.initialiseoptions(MopathRecorder)
self.selectNodePathNamed('camera')
@ -306,9 +306,9 @@ class MopathRecorder(AppShell, DirectObject):
frame.pack(fill = Tkinter.X, expand = 1)
mainFrame.pack(expand = 1, fill = Tkinter.X, pady = 3)
# Playback controls
playbackFrame = Frame(interior, relief = Tkinter.SUNKEN,
borderwidth = 2)
@ -370,7 +370,7 @@ class MopathRecorder(AppShell, DirectObject):
string.atof(s.speedVar.get())))
self.speedEntry.pack(side = Tkinter.LEFT, expand = 0)
frame.pack(fill = Tkinter.X, expand = 1)
playbackFrame.pack(fill = Tkinter.X, pady = 2)
# Create notebook pages
@ -387,7 +387,7 @@ class MopathRecorder(AppShell, DirectObject):
label = Label(self.resamplePage, text = 'RESAMPLE CURVE',
font=('MSSansSerif', 12, 'bold'))
label.pack(fill = Tkinter.X)
# Resample
resampleFrame = Frame(
self.resamplePage, relief = Tkinter.SUNKEN, borderwidth = 2)
@ -411,7 +411,7 @@ class MopathRecorder(AppShell, DirectObject):
self.faceForward, side = Tkinter.LEFT, fill = Tkinter.X, expand = 1)
frame.pack(fill = Tkinter.X, expand = 0)
resampleFrame.pack(fill = Tkinter.X, expand = 0, pady = 2)
# Desample
desampleFrame = Frame(
self.resamplePage, relief = Tkinter.SUNKEN, borderwidth = 2)
@ -555,7 +555,7 @@ class MopathRecorder(AppShell, DirectObject):
sfFrame, 'Style', 'Num Segs',
'Set number of segments used to approximate each parametric unit',
min = 1.0, max = 400, resolution = 1.0,
value = 40,
value = 40,
command = self.setNumSegs, side = Tkinter.TOP)
widget.component('hull')['relief'] = Tkinter.RIDGE
widget = self.createSlider(
@ -644,8 +644,8 @@ class MopathRecorder(AppShell, DirectObject):
# Pack record frame
optionsFrame.pack(fill = Tkinter.X, pady = 2)
self.mainNotebook.setnaturalsize()
self.mainNotebook.setnaturalsize()
def pushUndo(self, fResetRedo = 1):
SEditor.pushUndo([self.nodePath])
@ -663,7 +663,7 @@ class MopathRecorder(AppShell, DirectObject):
def pushRedo(self):
SEditor.pushRedo([self.nodePath])
def redoHook(self):
# Reflect new changes
pass
@ -675,7 +675,7 @@ class MopathRecorder(AppShell, DirectObject):
def redoListEmptyHook(self):
# Make sure button is deactivated
self.redoButton.configure(state = 'disabled')
def selectedNodePathHook(self, nodePath):
"""
Hook called upon selection of a node path used to select playback
@ -770,11 +770,11 @@ class MopathRecorder(AppShell, DirectObject):
self.manipulandumId = self.playbackMarker.id()
elif SEditor.selected.last.id() == self.tangentMarker.id():
self.manipulandumId = self.tangentMarker.id()
def manipulateObjectCleanupHook(self):
# Clear flag
self.manipulandumId = None
def onDestroy(self, event):
# Remove hooks
for event, method in self.actionEvents:
@ -853,7 +853,7 @@ class MopathRecorder(AppShell, DirectObject):
self.curveNodePath.show()
else:
self.curveNodePath.hide()
def setKnotVis(self):
self.nurbsCurveDrawer.setShowKnots(
self.getVariable('Style', 'Knots').get())
@ -861,11 +861,11 @@ class MopathRecorder(AppShell, DirectObject):
def setCvVis(self):
self.nurbsCurveDrawer.setShowCvs(
self.getVariable('Style', 'CVs').get())
def setHullVis(self):
self.nurbsCurveDrawer.setShowHull(
self.getVariable('Style', 'Hull').get())
def setTraceVis(self):
if self.getVariable('Style', 'Trace').get():
self.trace.show()
@ -881,10 +881,10 @@ class MopathRecorder(AppShell, DirectObject):
def setNumSegs(self, value):
self.numSegs = int(value)
self.nurbsCurveDrawer.setNumSegs(self.numSegs)
def setNumTicks(self, value):
self.nurbsCurveDrawer.setNumTicks(float(value))
def setTickScale(self, value):
self.nurbsCurveDrawer.setTickScale(float(value))
@ -933,7 +933,7 @@ class MopathRecorder(AppShell, DirectObject):
self.curveCollection = None
self.curveFitter.reset()
self.nurbsCurveDrawer.hide()
def setSamplingMode(self, mode):
self.samplingMode = mode
@ -950,7 +950,7 @@ class MopathRecorder(AppShell, DirectObject):
def setRefineMode(self):
self.setRecordingType('Refine')
def setExtendMode(self):
self.setRecordingType('Extend')
@ -1015,7 +1015,7 @@ class MopathRecorder(AppShell, DirectObject):
self.recordTask, self.name + '-recordTask')
t.startTime = globalClock.getFrameTime()
else:
self.markingNode.removeNode() # Hide the marker in the end of recording
self.markingNode.removeNode() # Hide the marker in the end of recording
if self.samplingMode == 'Continuous':
# Kill old task
taskMgr.remove(self.name + '-recordTask')
@ -1043,7 +1043,7 @@ class MopathRecorder(AppShell, DirectObject):
self.setNewCurveMode()
# Compute curve
self.computeCurves()
def recordTask(self, state):
# Record raw data point
time = self.recordStart + (
@ -1324,7 +1324,7 @@ class MopathRecorder(AppShell, DirectObject):
def setPlaybackSF(self, value):
self.playbackSF = pow(10.0, float(value))
self.speedVar.set('%0.2f' % self.playbackSF)
def playbackTask(self, state):
time = globalClock.getFrameTime()
dTime = self.playbackSF * (time - state.lastTime)
@ -1383,7 +1383,7 @@ class MopathRecorder(AppShell, DirectObject):
def setDesampleFrequency(self, frequency):
self.desampleFrequency = frequency
def desampleCurve(self):
if (self.curveFitter.getNumSamples() == 0):
print 'MopathRecorder.desampleCurve: Must define curve first'
@ -1397,7 +1397,7 @@ class MopathRecorder(AppShell, DirectObject):
def setNumSamples(self, numSamples):
self.numSamples = int(numSamples)
def sampleCurve(self, fCompute = 1, curveName = None):
if self.curveCollection == None:
print 'MopathRecorder.sampleCurve: Must define curve first'
@ -1429,7 +1429,7 @@ class MopathRecorder(AppShell, DirectObject):
def setPathDuration(self, event):
newMaxT = float(self.getWidget('Resample', 'Path Duration').get())
self.setPathDurationTo(newMaxT)
def setPathDurationTo(self, newMaxT):
# Compute scale factor
sf = newMaxT/self.maxT
@ -1725,7 +1725,7 @@ class MopathRecorder(AppShell, DirectObject):
## WIDGET UTILITY FUNCTIONS ##
def addWidget(self, widget, category, text):
self.widgetDict[category + '-' + text] = widget
def getWidget(self, category, text):
return self.widgetDict[category + '-' + text]
@ -1763,7 +1763,7 @@ class MopathRecorder(AppShell, DirectObject):
self.bind(widget, balloonHelp)
self.widgetDict[category + '-' + text] = widget
return widget
def createCheckbutton(self, parent, category, text,
balloonHelp, command, initialState,
side = 'top', fill = Tkinter.X, expand = 0):
@ -1778,7 +1778,7 @@ class MopathRecorder(AppShell, DirectObject):
self.widgetDict[category + '-' + text] = widget
self.variableDict[category + '-' + text] = bool
return widget
def createRadiobutton(self, parent, side, category, text,
balloonHelp, variable, value,
command = None, fill = Tkinter.X, expand = 0):
@ -1790,7 +1790,7 @@ class MopathRecorder(AppShell, DirectObject):
self.bind(widget, balloonHelp)
self.widgetDict[category + '-' + text] = widget
return widget
def createFloater(self, parent, category, text, balloonHelp,
command = None, min = 0.0, resolution = None,
maxVelocity = 10.0, **kw):
@ -1948,7 +1948,7 @@ class MopathRecorder(AppShell, DirectObject):
self.cCamNode.setLens(self.cLens)
self.cCamNode.setScene(render)
self.cCam = self.cCamera.attachNewNode(self.cCamNode)
self.cDr.setCamera(self.cCam)
def toggleWidgetVis(self):
@ -1984,8 +1984,8 @@ class MopathRecorder(AppShell, DirectObject):
comboBox.selectitem(name)
messenger.send('mPath_bindPathToNode',[self.playbackNodePath, self.curveCollection])
return
def addCurvesFromNodepath(self,curveList):
'''addCurvesFromNodepath(self,curveList)
@ -2039,7 +2039,7 @@ class namePathPanel(AppShell):
label = Label(dataFrame, text='This name will be used as a reference for this Path.',font=('MSSansSerif', 10))
label.pack(side = Tkinter.TOP, expand = 0, fill = Tkinter.X)
dataFrame.pack(side = Tkinter.TOP, expand = 0, fill = Tkinter.X, padx=5, pady=10)
dataFrame = Frame(mainFrame)
self.inputZone = Pmw.EntryField(dataFrame, labelpos='w', label_text = 'Name Selected Path: ',
entry_font=('MSSansSerif', 10),
@ -2055,15 +2055,15 @@ class namePathPanel(AppShell):
mainFrame.pack(expand = 1, fill = Tkinter.BOTH)
def onDestroy(self, event):
'''
If you have open any thing, please rewrite here!
'''
pass
def ok_press(self):
name = self.inputZone.getvalue()
messenger.send('MP_checkName',[name])

View File

@ -6,7 +6,7 @@ from direct.directnotify import DirectNotifyGlobal
class ParticleEffect(NodePath):
notify = DirectNotifyGlobal.directNotify.newCategory('ParticleEffect')
pid = 1
pid = 1
def __init__(self, name=None, particles=None):
"""__init__()"""
@ -143,7 +143,7 @@ class ParticleEffect(NodePath):
def getParticlesList(self):
"""getParticles()"""
return self.particlesDict.values()
def getParticlesNamed(self, name):
"""getParticlesNamed(name)"""
return self.particlesDict.get(name, None)
@ -186,7 +186,7 @@ class ParticleEffect(NodePath):
# Save all the particles to file
num = 0
for p in self.particlesDict.values():
target = 'p%d' % num
target = 'p%d' % num
num = num + 1
f.write(target + ' = Particles.Particles(\'%s\')\n' % p.getName())
p.printParams(f, target)
@ -240,7 +240,7 @@ class ParticleEffect(NodePath):
# Save all the particles to file
num = 0
for p in self.particlesDict.values():
target = 'p%d' % num
target = 'p%d' % num
num = num + 1
f.write(i2+"if(mode==0):\n")
f.write(i2+i1+target + ' = seParticles.Particles(\'%s\')\n' % p.getName())

View File

@ -48,16 +48,16 @@ class ParticlePanel(AppShell):
pe = seParticleEffect.ParticleEffect('effect1', particles)
self.particleEffect = pe
self.emitter=loader.loadModel("sphere")
pe.reparentTo(self.emitter)
pe.reparentTo(self.emitter)
self.emitter.setName("effect1")
self.emitter.reparentTo(render)
pe.enable()
messenger.send('ParticlePanel_Added_Effect',['effect1',pe,self.emitter])
self.effectsDict[self.particleEffect.getName()]=self.particleEffect
messenger.send('SGE_Update Explorer',[render])
# Initialize application specific info
AppShell.__init__(self)

View File

@ -144,7 +144,7 @@ class Particles(ParticleSystem):
self.renderer = SpriteParticleRenderer.SpriteParticleRenderer()
if (self.renderer.getSourceType() ==
SpriteParticleRenderer.SpriteParticleRenderer.STTexture):
# Use current default texture
# Use current default texture
# See sourceTextureName SpriteParticleRenderer-extensions.py
self.renderer.setTextureFromFile()
else:

View File

@ -31,7 +31,7 @@ class Placer(AppShell):
# Call superclass initialization function
AppShell.__init__(self)
self.initialiseoptions(Placer)
# Accept the message from sceneEditor to update the information about the target nodePath
@ -44,7 +44,7 @@ class Placer(AppShell):
'placerOrbitFromCS')
self.orbitToCS = SEditor.group.attachNewNode('placerOrbitToCS')
self.refCS = self.tempCS
# Dictionary keeping track of all node paths manipulated so far
self.nodePathDict = {}
self.nodePathDict['camera'] = SEditor.camera
@ -109,7 +109,7 @@ class Placer(AppShell):
'Toggle widget manipulation mode',
label = 'Toggle Widget Mode',
command = SEditor.manipulationControl.toggleObjectHandlesMode)
# Get a handle to the menu frame
menuFrame = self.menuFrame
self.nodePathMenu = Pmw.ComboBox(
@ -133,7 +133,7 @@ class Placer(AppShell):
menubutton_width = 8)
modeMenu.pack(side = 'left', expand = 0)
self.bind(modeMenu, 'Select manipulation mode')
self.refNodePathMenu = Pmw.ComboBox(
menuFrame, entry_width = 16,
selectioncommand = self.selectRefNodePathNamed,
@ -190,7 +190,7 @@ class Placer(AppShell):
self.posX['postCallback'] = self.xformStop
self.posX['callbackData'] = ['x']
self.posX.pack(expand=1,fill='both')
self.posY = self.createcomponent('posY', (), None,
Floater, (posInterior,),
text = 'Y', relief = Tkinter.FLAT,
@ -201,7 +201,7 @@ class Placer(AppShell):
self.posY['postCallback'] = self.xformStop
self.posY['callbackData'] = ['y']
self.posY.pack(expand=1,fill='both')
self.posZ = self.createcomponent('posZ', (), None,
Floater, (posInterior,),
text = 'Z', relief = Tkinter.FLAT,
@ -228,7 +228,7 @@ class Placer(AppShell):
hprMenubutton['menu'] = hprMenu
hprGroup.pack(side='left',fill = 'both', expand = 1)
hprInterior = hprGroup.interior()
# Create the dials
self.hprH = self.createcomponent('hprH', (), None,
AngleDial, (hprInterior,),
@ -241,7 +241,7 @@ class Placer(AppShell):
self.hprH['postCallback'] = self.xformStop
self.hprH['callbackData'] = ['h']
self.hprH.pack(expand=1,fill='both')
self.hprP = self.createcomponent('hprP', (), None,
AngleDial, (hprInterior,),
style = 'mini',
@ -253,7 +253,7 @@ class Placer(AppShell):
self.hprP['postCallback'] = self.xformStop
self.hprP['callbackData'] = ['p']
self.hprP.pack(expand=1,fill='both')
self.hprR = self.createcomponent('hprR', (), None,
AngleDial, (hprInterior,),
style = 'mini',
@ -297,7 +297,7 @@ class Placer(AppShell):
# Pack group widgets
scaleGroup.pack(side='left',fill = 'both', expand = 1)
scaleInterior = scaleGroup.interior()
# Create the dials
self.scaleX = self.createcomponent('scaleX', (), None,
Floater, (scaleInterior,),
@ -311,7 +311,7 @@ class Placer(AppShell):
self.scaleX['preCallback'] = self.xformStart
self.scaleX['postCallback'] = self.xformStop
self.scaleX.pack(expand=1,fill='both')
self.scaleY = self.createcomponent('scaleY', (), None,
Floater, (scaleInterior,),
text = 'Y Scale',
@ -324,7 +324,7 @@ class Placer(AppShell):
self.scaleY['preCallback'] = self.xformStart
self.scaleY['postCallback'] = self.xformStop
self.scaleY.pack(expand=1,fill='both')
self.scaleZ = self.createcomponent('scaleZ', (), None,
Floater, (scaleInterior,),
text = 'Z Scale',
@ -417,7 +417,7 @@ class Placer(AppShell):
else:
if name == 'widget':
# Record relationship between selected nodes and widget
SEditor.selected.getWrtAll()
SEditor.selected.getWrtAll()
# Update active node path
self.setActiveNodePath(nodePath)
@ -490,7 +490,7 @@ class Placer(AppShell):
else:
# Flash entry
self.refNodePathMenuEntry.configure(background = 'Pink')
def addNodePath(self, nodePath):
self.addNodePathToDict(nodePath, self.nodePathNames,
self.nodePathMenu, self.nodePathDict)
@ -568,7 +568,7 @@ class Placer(AppShell):
else:
# Move the objects with the widget
SEditor.selected.moveWrtWidgetAll()
def xformStart(self, data):
# Record undo point
self.pushUndo()
@ -581,7 +581,7 @@ class Placer(AppShell):
self.deltaHpr = self['nodePath'].getHpr(self.refCS)
# Update placer to reflect new state
self.updatePlacer()
def xformStop(self, data):
# Throw event to signal manipulation done
# Send nodepath as a list
@ -746,7 +746,7 @@ class Placer(AppShell):
def pushRedo(self):
SEditor.pushRedo([self['nodePath']])
def redoHook(self, nodePathList = []):
# Reflect new changes
self.updatePlacer()
@ -758,7 +758,7 @@ class Placer(AppShell):
def redoListEmptyHook(self):
# Make sure button is deactivated
self.redoButton.configure(state = 'disabled')
def printNodePathInfo(self):
np = self['nodePath']
if np:
@ -787,7 +787,7 @@ class Placer(AppShell):
# Also, stop accepting the updata message from sceneEditor
messenger.send('Placer_close')
self.ignore('placerUpdate')
def place(nodePath):
return Placer(nodePath = nodePath)

View File

@ -5,7 +5,7 @@
#
# we need a customized SceneGraphExplorer.
#
# Do forget to check the seTree.
# Do forget to check the seTree.
#
#################################################################
from direct.showbase.DirectObject import DirectObject
@ -40,25 +40,25 @@ DEFAULT_MENU_ITEMS = [
class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject):
"Graphical display of a scene graph"
def __init__(self, parent = None, nodePath = render, **kw):
def __init__(self, parent = None, nodePath = render, **kw):
# Define the megawidget options.
optiondefs = (
('menuItems', [], Pmw.INITOPT),
)
self.defineoptions(kw, optiondefs)
# Initialise superclass
Pmw.MegaWidget.__init__(self, parent)
# Initialize some class variables
self.nodePath = nodePath
# Create the components.
# Setup up container
interior = self.interior()
interior.configure(relief = Tkinter.GROOVE, borderwidth = 2)
# Create a label and an entry
self._scrolledCanvas = self.createcomponent(
'scrolledCanvas',
@ -70,14 +70,14 @@ class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject):
self._canvas['scrollregion'] = ('0i', '0i', '2i', '4i')
self._scrolledCanvas.resizescrollregion()
self._scrolledCanvas.pack(padx = 3, pady = 3, expand=1, fill = Tkinter.BOTH)
self._canvas.bind('<ButtonPress-2>', self.mouse2Down)
self._canvas.bind('<B2-Motion>', self.mouse2Motion)
self._canvas.bind('<Configure>',
lambda e, sc = self._scrolledCanvas:
sc.resizescrollregion())
self.interior().bind('<Destroy>', self.onDestroy)
# Create the contents
self._treeItem = SceneGraphExplorerItem(self.nodePath)
@ -114,7 +114,7 @@ class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject):
self._width = 1.0 * self._canvas.winfo_width()
self._height = 1.0 * self._canvas.winfo_height()
xview = self._canvas.xview()
yview = self._canvas.yview()
yview = self._canvas.yview()
self._left = xview[0]
self._top = yview[0]
self._dxview = xview[1] - xview[0]

View File

@ -35,7 +35,7 @@ class DirectNodePath(NodePath):
self.mCoa2Dnp = Mat4(Mat4.identMat())
if SEditor.coaMode == COA_CENTER:
self.mCoa2Dnp.setRow(3, Vec4(center[0], center[1], center[2], 1))
# Transform from nodePath to widget
self.tDnp2Widget = TransformState.makeIdentity()
@ -72,11 +72,11 @@ class SelectedNodePaths(DirectObject):
if not nodePath:
print 'Nothing selected!!'
return None
# Reset selected objects and highlight if multiSelect is false
if not fMultiSelect:
self.deselectAll()
# Get this pointer
id = nodePath.id()
# First see if its already in the selected dictionary
@ -199,7 +199,7 @@ class SelectedNodePaths(DirectObject):
if selected:
selected.remove()
__builtins__["last"] = self.last = None
def removeAll(self):
# Remove all selected nodePaths from the Scene Graph
self.forEachSelectedNodePathDo(NodePath.remove)
@ -258,7 +258,7 @@ class DirectBoundingBox:
# Restore transform
self.nodePath.setMat(tMat)
del tMat
def computeBounds(self):
self.bounds = self.getBounds()
if self.bounds.isEmpty() or self.bounds.isInfinite():
@ -269,7 +269,7 @@ class DirectBoundingBox:
self.radius = self.bounds.getRadius()
self.min = Point3(self.center - Point3(self.radius))
self.max = Point3(self.center + Point3(self.radius))
def createBBoxLines(self):
# Create a line segments object for the bbox
lines = LineNodePath(hidden)
@ -283,7 +283,7 @@ class DirectBoundingBox:
maxX = self.max[0]
maxY = self.max[1]
maxZ = self.max[2]
# Bottom face
lines.moveTo( minX, minY, minZ )
lines.drawTo( maxX, minY, minZ )
@ -308,22 +308,22 @@ class DirectBoundingBox:
# Create and return bbox lines
lines.create()
# Make sure bbox is never lit or drawn in wireframe
useDirectRenderStyle(lines)
return lines
def updateBBoxLines(self):
ls = self.lines.lineSegs
minX = self.min[0]
minY = self.min[1]
minZ = self.min[2]
maxX = self.max[0]
maxY = self.max[1]
maxZ = self.max[2]
# Bottom face
ls.setVertex( 0, minX, minY, minZ )
ls.setVertex( 1, maxX, minY, minZ )
@ -359,7 +359,7 @@ class DirectBoundingBox:
def hide(self):
self.lines.reparentTo(hidden)
def getCenter(self):
return self.center
@ -376,7 +376,7 @@ class DirectBoundingBox:
return '%.2f %.2f %.2f' % (vec[0], vec[1], vec[2])
def __repr__(self):
return (`self.__class__` +
return (`self.__class__` +
'\nNodePath:\t%s\n' % self.nodePath.getName() +
'Min:\t\t%s\n' % self.vecAsString(self.min) +
'Max:\t\t%s\n' % self.vecAsString(self.max) +
@ -533,7 +533,7 @@ class SelectionRay(SelectionQueue):
# Initialize the superclass
SelectionQueue.__init__(self, parentNP)
self.addCollider(CollisionRay())
def pick(self, targetNodePath, xy = None):
# Determine ray direction based upon the mouse coordinates
if xy:
@ -553,7 +553,7 @@ class SelectionRay(SelectionQueue):
#mx = base.mouseWatcherNode.getMouseX()+1
#my = base.mouseWatcherNode.getMouseY()+1
#print base.camNode.getName()
#print "Arrived X" + str(mx) + " Arrived Y " + str(my)
#print "Arrived X" + str(mx) + " Arrived Y " + str(my)
self.collider.setFromLens( base.camNode, mx, my )
self.ct.traverse( targetNodePath )
@ -587,7 +587,7 @@ class SelectionRay(SelectionQueue):
self.collider.setDirection( dir )
self.ct.traverse( targetNodePath )
self.sortEntries()
def pickGeom3D(self, targetNodePath = render,
origin = Point3(0), dir = Vec3(0,0,-1),
skipFlags = SKIP_HIDDEN | SKIP_CAMERA ):
@ -616,7 +616,7 @@ class SelectionSegment(SelectionQueue):
self.numColliders = 0
for i in range(numSegments):
self.addCollider(CollisionSegment())
def addCollider(self, collider):
# Record new collision object
self.colliders.append(collider)
@ -659,30 +659,30 @@ class SelectionSphere(SelectionQueue):
self.numColliders = 0
for i in range(numSpheres):
self.addCollider(CollisionSphere(Point3(0), 1))
def addCollider(self, collider):
# Record new collision object
self.colliders.append(collider)
# Add the collider to the collision Node
self.collisionNode.addSolid( collider )
self.numColliders += 1
def setCenter(self, i, center):
c = self.colliders[i]
c.setCenter(center)
def setRadius(self, i, radius):
c = self.colliders[i]
c.setRadius(radius)
def setCenterRadius(self, i, center, radius):
c = self.colliders[i]
c.setCenter(center)
c.setRadius(radius)
def isEntryBackfacing(self, entry):
# If dot product of collision point surface normal and
# ray from sphere origin to collision point is positive,
# ray from sphere origin to collision point is positive,
# center is on the backside of the polygon
fromNodePath = entry.getFromNodePath()
v = Vec3(entry.getSurfacePoint(fromNodePath) -
@ -706,7 +706,7 @@ class SelectionSphere(SelectionQueue):
skipFlags = SKIP_HIDDEN | SKIP_CAMERA ):
self.collideWithGeom()
return self.pick(targetNodePath, skipFlags)
def pickBitMask(self, bitMask = BitMask32.allOff(),
targetNodePath = render,
skipFlags = SKIP_HIDDEN | SKIP_CAMERA ):

View File

@ -49,7 +49,7 @@ class SeSession(DirectObject): ### Customized DirectSession
self.useObjectHandles()
self.grid = DirectGrid()
self.grid.disable()
# Initialize the collection of selected nodePaths
self.selected = SelectedNodePaths()
# Ancestry of currently selected object
@ -94,19 +94,19 @@ class SeSession(DirectObject): ### Customized DirectSession
# Lists for managing undo/redo operations
self.undoList = []
self.redoList = []
# One run through the context task to init everything
self.drList.updateContext()
for dr in self.drList:
dr.camUpdate()
self.modifierEvents = ['control', 'control-up',
'shift', 'shift-up',
'alt', 'alt-up',
]
self.keyEvents = ['escape', 'delete', 'page_up', 'page_down',
self.keyEvents = ['escape', 'delete', 'page_up', 'page_down',
'[', '{', ']', '}',
'shift-a', 'b', 'control-f',
'l', 'shift-l', 'o', 'p', 'r',
@ -124,7 +124,7 @@ class SeSession(DirectObject): ### Customized DirectSession
'control-mouse3', 'control-mouse3-up',
'alt-mouse3', 'alt-mouse3-up',
]
def enable(self):
if self.fEnabled:
return
@ -361,7 +361,7 @@ class SeSession(DirectObject): ### Customized DirectSession
elif (input == ']') or (input == '}'):
self.redo()
def getModifiers(self, input, base):
modifiers = DIRECT_NO_MOD
modifierString = input[: input.find(base)]
@ -405,7 +405,7 @@ class SeSession(DirectObject): ### Customized DirectSession
self.cameraControl.updateCoa(coa)
# Adjust widgets size
# This uses the additional scaling factor used to grow and
# shrink the widget
# shrink the widget
self.widget.setScalingFactor(dnp.getRadius())
# Spawn task to have object handles follow the selected object
taskMgr.remove('followSelectedNodePath')
@ -462,7 +462,7 @@ class SeSession(DirectObject): ### Customized DirectSession
'Active Reparent Target:' + nodePath.getName())
# Alert everyone else
self.activeParentReadout.show()
def reparent(self, nodePath = None, fWrt = 0):
if (nodePath and self.activeParent and
self.isNotCycle(nodePath, self.activeParent)):
@ -486,7 +486,7 @@ class SeSession(DirectObject): ### Customized DirectSession
return self.isNotCycle(nodePath, parent.getParent())
else:
return 1
def fitOnNodePath(self, nodePath = 'None Given'):
if nodePath == 'None Given':
# If nothing specified, try selected node path
@ -553,7 +553,7 @@ class SeSession(DirectObject): ### Customized DirectSession
if (name != 'render') and (name != 'renderTop')and(self.checkTypeNameForAncestry(type, ntype)):
self.ancestryIndex = i
self.select(np, 0, 0, True)
def checkTypeNameForAncestry(self, type, nextType ):
if (type=='ModelRoot'):
if (nextType=='AmbientLight')or(nextType=='PointLight')or(nextType=='DirectionalLight')or(nextType=='Spotlight'):
@ -620,7 +620,7 @@ class SeSession(DirectObject): ### Customized DirectSession
messenger.send('DIRECT_undoListEmpty')
# Return last item
return undoGroup
def pushRedo(self, nodePathList):
# Assemble group of changes
redoGroup = []
@ -644,7 +644,7 @@ class SeSession(DirectObject): ### Customized DirectSession
messenger.send('DIRECT_redoListEmpty')
# Return last item
return redoGroup
def undo(self):
if self.undoList:
# Get last item off of redo list
@ -736,7 +736,7 @@ class SeSession(DirectObject): ### Customized DirectSession
print posE, hprE
posInterval1 = base.camera.posInterval(time, posE, bakeInStart = 1)
posInterval2 = base.camera.posInterval(time, posB, bakeInStart = 1)
hprInterval1 = base.camera.hprInterval(time, hprE, bakeInStart = 1)
hprInterval2 = base.camera.hprInterval(time, hprB, bakeInStart = 1)
@ -744,9 +744,9 @@ class SeSession(DirectObject): ### Customized DirectSession
parallel2 = Parallel(posInterval2, hprInterval2)
Sequence(Wait(7), parallel1, Wait(1), parallel2).start()
return
class DisplayRegionContext(DirectObject):
regionCount = 0
@ -833,14 +833,14 @@ class DisplayRegionContext(DirectObject):
return prop.getXSize()
else:
return 640
def getHeight(self):
prop = base.win.getProperties()
if prop.hasSize():
return prop.getYSize()
else:
return 480
def camUpdate(self, lens = None):
# Window Data
self.near = self.camLens.getNear()
@ -885,7 +885,7 @@ class DisplayRegionList(DirectObject):
else:
# MRM: Doesn't properly handle multiple camera groups anymore
# Assumes everything is under main camera
# This is following the old way of setting up
# display regions. A display region is set up for
# each camera node in the scene graph. This was done
@ -920,11 +920,11 @@ class DisplayRegionList(DirectObject):
def setNearFar(self, near, far):
for dr in self.displayRegionList:
dr.camLens.setNearFar(near, far)
def setNear(self, near):
for dr in self.displayRegionList:
dr.camLens.setNear(near)
def setFar(self, far):
for dr in self.displayRegionList:
dr.camLens.setFar(far)

View File

@ -54,7 +54,7 @@ class TreeNode:
value = i,
indicatoron = 0,
command = self.popupMenuCommand)
def destroy(self):
for key in self.kidKeys:
c = self.children[key]
@ -257,7 +257,7 @@ class TreeNode:
self.canvas.tag_bind(id, "<1>", self.select)
self.canvas.tag_bind(id, "<Double-1>", self.flip)
self.canvas.tag_bind(id, "<3>", self.popupMenu)
def drawtext(self, text=None):
textx = self.x+20-1
texty = self.y-1
@ -410,7 +410,7 @@ class TreeItem:
def OnSelect(self):
"""Called when item selected."""
def GetTextForEdit(self):
"""Called before editting the item."""

View File

@ -1,9 +1,10 @@
// Filename: direct.cxx
// Created by: drose (18May00)
//
////////////////////////////////////////////////////////////////////
/**
* @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.
// 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.

View File

@ -3,9 +3,10 @@
__all__ = ['Actor']
from panda3d.core import *
from panda3d.core import Loader as PandaLoader
from direct.showbase.DirectObject import DirectObject
from direct.directnotify import DirectNotifyGlobal
import types
class Actor(DirectObject, NodePath):
"""
@ -25,7 +26,7 @@ class Actor(DirectObject, NodePath):
validateSubparts = ConfigVariableBool('validate-subparts', True)
mergeLODBundles = ConfigVariableBool('merge-lod-bundles', True)
allowAsyncBind = ConfigVariableBool('allow-async-bind', True)
class PartDef:
"""Instances of this class are stored within the
@ -34,7 +35,7 @@ class Actor(DirectObject, NodePath):
model file is a different PartBundle. This can include the
multiple different LOD's, as well as the multiple different
pieces of a multipart Actor. """
def __init__(self, partBundleNP, partBundleHandle, partModel):
# We also save the ModelRoot node along with the
# PartBundle, so that the reference count in the ModelPool
@ -45,7 +46,7 @@ class Actor(DirectObject, NodePath):
def getBundle(self):
return self.partBundleHandle.getBundle()
def __repr__(self):
return 'Actor.PartDef(%s, %s)' % (repr(self.partBundleNP), repr(self.partModel))
@ -59,7 +60,7 @@ class Actor(DirectObject, NodePath):
There is a different AnimDef for each different part or
sub-part, times each different animation in the AnimDict. """
def __init__(self, filename = None, animBundle = None):
self.filename = filename
self.animBundle = None
@ -86,8 +87,8 @@ class Actor(DirectObject, NodePath):
def makeCopy(self):
return Actor.SubpartDef(self.truePartName, PartSubset(self.subset))
def __repr__(self):
return 'Actor.SubpartDef(%s, %s)' % (repr(self.truePartName), repr(self.subset))
@ -160,6 +161,8 @@ class Actor(DirectObject, NodePath):
# initialize our NodePath essence
NodePath.__init__(self)
self.loader = PandaLoader.getGlobalPtr()
# Set the mergeLODBundles flag. If this is true, all
# different LOD's will be merged into a single common bundle
# (joint hierarchy). All LOD's will thereafter share the same
@ -171,7 +174,7 @@ class Actor(DirectObject, NodePath):
# When this flag is true, __animControlDict has only one key,
# ['common']; when it is false, __animControlDict has one key
# per each LOD name.
if mergeLODBundles is None:
# If this isn't specified, it comes from the Config.prc
# file.
@ -223,7 +226,7 @@ class Actor(DirectObject, NodePath):
root.setPreserveTransform(1)
self.assign(NodePath(root))
self.setGeomNode(self.attachNewNode(ModelNode('actorGeom')))
self.__hasLOD = 0
# load models
@ -236,30 +239,30 @@ class Actor(DirectObject, NodePath):
# models{}{}, anims{}{} = multi-part actor w/ LOD
#
# make sure we have models
if (models):
if models:
# do we have a dictionary of models?
if (type(models)==type({})):
if type(models) == dict:
# if this is a dictionary of dictionaries
if (type(models[models.keys()[0]]) == type({})):
if type(models[next(iter(models))]) == dict:
# then it must be a multipart actor w/LOD
self.setLODNode(node = lodNode)
# preserve numerical order for lod's
# this will make it easier to set ranges
sortedKeys = models.keys()
sortedKeys = list(models.keys())
sortedKeys.sort()
for lodName in sortedKeys:
# make a node under the LOD switch
# for each lod (just because!)
self.addLOD(str(lodName))
# iterate over both dicts
for modelName in models[lodName].keys():
for modelName in models[lodName]:
self.loadModel(models[lodName][modelName],
modelName, lodName, copy = copy,
okMissing = okMissing)
# then if there is a dictionary of dictionaries of anims
elif (type(anims[anims.keys()[0]])==type({})):
elif type(anims[next(iter(anims))]) == dict:
# then this is a multipart actor w/o LOD
for partName in models.keys():
for partName in models:
# pass in each part
self.loadModel(models[partName], partName,
copy = copy, okMissing = okMissing)
@ -267,7 +270,7 @@ class Actor(DirectObject, NodePath):
# it is a single part actor w/LOD
self.setLODNode(node = lodNode)
# preserve order of LOD's
sortedKeys = models.keys()
sortedKeys = list(models.keys())
sortedKeys.sort()
for lodName in sortedKeys:
self.addLOD(str(lodName))
@ -280,28 +283,28 @@ class Actor(DirectObject, NodePath):
# load anims
# make sure the actor has animations
if (anims):
if (len(anims) >= 1):
if anims:
if len(anims) >= 1:
# if so, does it have a dictionary of dictionaries?
if (type(anims[anims.keys()[0]])==type({})):
if type(anims[next(iter(anims))]) == dict:
# are the models a dict of dicts too?
if (type(models)==type({})):
if (type(models[models.keys()[0]]) == type({})):
if type(models) == dict:
if type(models[next(iter(models))]) == dict:
# then we have a multi-part w/ LOD
sortedKeys = models.keys()
sortedKeys = list(models.keys())
sortedKeys.sort()
for lodName in sortedKeys:
# iterate over both dicts
for partName in anims.keys():
for partName in anims:
self.loadAnims(
anims[partName], partName, lodName)
else:
# then it must be multi-part w/o LOD
for partName in anims.keys():
for partName in anims:
self.loadAnims(anims[partName], partName)
elif (type(models)==type({})):
elif type(models) == dict:
# then we have single-part w/ LOD
sortedKeys = models.keys()
sortedKeys = list(models.keys())
sortedKeys.sort()
for lodName in sortedKeys:
self.loadAnims(anims, lodName=lodName)
@ -340,7 +343,7 @@ class Actor(DirectObject, NodePath):
def copyActor(self, other, overwrite=False):
# act like a copy constructor
self.gotName = other.gotName
# copy the scene graph elements of other
if (overwrite):
otherCopy = other.copyTo(NodePath())
@ -370,7 +373,7 @@ class Actor(DirectObject, NodePath):
self.__copyPartBundles(other)
self.__copySubpartDict(other)
self.__subpartsComplete = other.__subpartsComplete
# copy the anim dictionary from other
self.__copyAnimControls(other)
@ -428,11 +431,10 @@ class Actor(DirectObject, NodePath):
part.outputValue(lineStream)
value = lineStream.getLine()
print ' ' * indentLevel, part.getName(), value
print(' '.join((' ' * indentLevel, part.getName(), value)))
for i in range(part.getNumChildren()):
self.__doListJoints(indentLevel + 2, part.getChild(i),
isIncluded, subset)
for child in part.getChildren():
self.__doListJoints(indentLevel + 2, child, isIncluded, subset)
def getActorInfo(self):
@ -444,16 +446,16 @@ class Actor(DirectObject, NodePath):
for lodName, partDict in self.__animControlDict.items():
if self.mergeLODBundles:
lodName = self.__sortedLODNames[0]
partInfo = []
for partName in partDict.keys():
for partName in partDict:
subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
partBundleDict = self.__partBundleDict.get(lodName)
partDef = partBundleDict.get(subpartDef.truePartName)
partBundle = partDef.getBundle()
animDict = partDict[partName]
animInfo = []
for animName in animDict.keys():
for animName in animDict:
file = animDict[animName].filename
animControl = animDict[animName].animControl
animInfo.append([animName, file, animControl])
@ -475,17 +477,17 @@ class Actor(DirectObject, NodePath):
Pretty print actor's details
"""
for lodName, lodInfo in self.getActorInfo():
print 'LOD:', lodName
print('LOD: %s' % lodName)
for partName, bundle, animInfo in lodInfo:
print ' Part:', partName
print ' Bundle:', repr(bundle)
print(' Part: %s' % partName)
print(' Bundle: %r' % bundle)
for animName, file, animControl in animInfo:
print ' Anim:', animName
print ' File:', file
print(' Anim: %s' % animName)
print(' File: %s' % file)
if animControl == None:
print ' (not loaded)'
print(' (not loaded)')
else:
print (' NumFrames: %d PlayRate: %0.2f' %
print(' NumFrames: %d PlayRate: %0.2f' %
(animControl.getNumFrames(),
animControl.getPlayRate()))
@ -513,7 +515,7 @@ class Actor(DirectObject, NodePath):
self.__subpartDict = {}
self.__sortedLODNames = []
self.__animControlDict = {}
def flush(self):
"""
Actor flush function
@ -527,7 +529,7 @@ class Actor(DirectObject, NodePath):
# remove all its children
if self.__geomNode:
self.__geomNode.getChildren().detach()
self.__hasLOD = 0
# accessing
@ -544,9 +546,9 @@ class Actor(DirectObject, NodePath):
def getPartBundles(self, partName = None):
""" Returns a list of PartBundle objects for the entire Actor,
or for the indicated part only. """
bundles = []
for lodName, partBundleDict in self.__partBundleDict.items():
if partName == None:
for partDef in partBundleDict.values():
@ -565,7 +567,7 @@ class Actor(DirectObject, NodePath):
def __updateSortedLODNames(self):
# Cache the sorted LOD names so we don't have to grab them
# and sort them every time somebody asks for the list
self.__sortedLODNames = self.__partBundleDict.keys()
self.__sortedLODNames = list(self.__partBundleDict.keys())
# Reverse sort the doing a string->int
def sortKey(x):
if not str(x).isdigit():
@ -601,8 +603,8 @@ class Actor(DirectObject, NodePath):
"""
partNames = []
if self.__partBundleDict:
partNames = self.__partBundleDict.values()[0].keys()
return partNames + self.__subpartDict.keys()
partNames = list(next(iter(self.__partBundleDict.values())).keys())
return partNames + list(self.__subpartDict.keys())
def getGeomNode(self):
"""
@ -635,7 +637,7 @@ class Actor(DirectObject, NodePath):
self.__LODNode = self.__geomNode.attachNewNode(node)
self.__hasLOD = 1
self.switches = {}
def useLOD(self, lodName):
"""
@ -643,33 +645,33 @@ class Actor(DirectObject, NodePath):
"""
# make sure we don't call this twice in a row
# and pollute the the switches dictionary
## sortedKeys = self.switches.keys()
## sortedKeys = list(self.switches.keys())
## sortedKeys.sort()
child = self.__LODNode.find(str(lodName))
index = self.__LODNode.node().findChild(child.node())
index = self.__LODNode.node().findChild(child.node())
self.__LODNode.node().forceSwitch(index)
def printLOD(self):
## sortedKeys = self.switches.keys()
## sortedKeys = list(self.switches.keys())
## sortedKeys.sort()
sortedKeys = self.__sortedLODNames
for eachLod in sortedKeys:
print "python switches for %s: in: %d, out %d" % (eachLod,
print("python switches for %s: in: %d, out %d" % (eachLod,
self.switches[eachLod][0],
self.switches[eachLod][1])
self.switches[eachLod][1]))
switchNum = self.__LODNode.node().getNumSwitches()
for eachSwitch in range(0, switchNum):
print "c++ switches for %d: in: %d, out: %d" % (eachSwitch,
print("c++ switches for %d: in: %d, out: %d" % (eachSwitch,
self.__LODNode.node().getIn(eachSwitch),
self.__LODNode.node().getOut(eachSwitch))
self.__LODNode.node().getOut(eachSwitch)))
def resetLOD(self):
"""
Restore all switch distance info (usually after a useLOD call)"""
self.__LODNode.node().clearForceSwitch()
## sortedKeys = self.switches.keys()
## sortedKeys = list(self.switches.keys())
## sortedKeys.sort()
## for eachLod in sortedKeys:
## index = sortedKeys.index(eachLod)
@ -696,7 +698,7 @@ class Actor(DirectObject, NodePath):
# save the switch distance info
self.switches[lodName] = [inDist, outDist]
# add the switch distance info
## sortedKeys = self.switches.keys()
## sortedKeys = list(self.switches.keys())
## sortedKeys.sort()
self.__LODNode.node().setSwitch(self.getLODIndex(lodName), inDist, outDist)
@ -705,7 +707,7 @@ class Actor(DirectObject, NodePath):
safe method (but expensive) for retrieving the child index
"""
return list(self.__LODNode.getChildren()).index(self.getLOD(lodName))
def getLOD(self, lodName):
"""getLOD(self, string)
Get the named node under the LOD to which we parent all LOD
@ -754,7 +756,7 @@ class Actor(DirectObject, NodePath):
away. """
self.__LODAnimation = (farDistance, nearDistance, delayFactor)
for lodData in self.__partBundleDict.values():
for partData in lodData.values():
char = partData.partBundleNP
@ -781,7 +783,7 @@ class Actor(DirectObject, NodePath):
If force is True, this will update every joint, even if we
don't believe it's necessary.
Returns True if any joint has changed as a result of this,
False otherwise. """
@ -795,7 +797,7 @@ class Actor(DirectObject, NodePath):
lodName = lodNames[lod]
if partName == None:
partBundleDict = self.__partBundleDict[lodName]
partNames = partBundleDict.keys()
partNames = list(partBundleDict.keys())
else:
partNames = [partName]
@ -819,7 +821,7 @@ class Actor(DirectObject, NodePath):
If no part specified, return anim durations of first part.
NOTE: returns info only for an arbitrary LOD
"""
lodName = self.__animControlDict.keys()[0]
lodName = next(iter(self.__animControlDict))
controls = self.getAnimControls(animName, partName)
if len(controls) == 0:
return None
@ -831,7 +833,7 @@ class Actor(DirectObject, NodePath):
Return frame rate of given anim name and given part, unmodified
by any play rate in effect.
"""
lodName = self.__animControlDict.keys()[0]
lodName = next(iter(self.__animControlDict))
controls = self.getAnimControls(animName, partName)
if len(controls) == 0:
return None
@ -847,7 +849,7 @@ class Actor(DirectObject, NodePath):
"""
if self.__animControlDict:
# use the first lod
lodName = self.__animControlDict.keys()[0]
lodName = next(iter(self.__animControlDict))
controls = self.getAnimControls(animName, partName)
if controls:
return controls[0].getPlayRate()
@ -874,7 +876,7 @@ class Actor(DirectObject, NodePath):
If no part specified, return anim duration of first part.
NOTE: returns info for arbitrary LOD
"""
lodName = self.__animControlDict.keys()[0]
lodName = next(iter(self.__animControlDict))
controls = self.getAnimControls(animName, partName)
if len(controls) == 0:
return None
@ -887,7 +889,7 @@ class Actor(DirectObject, NodePath):
return ((toFrame+1)-fromFrame) / animControl.getFrameRate()
def getNumFrames(self, animName=None, partName=None):
lodName = self.__animControlDict.keys()[0]
lodName = next(iter(self.__animControlDict))
controls = self.getAnimControls(animName, partName)
if len(controls) == 0:
return None
@ -905,12 +907,12 @@ class Actor(DirectObject, NodePath):
specified return current anim of an arbitrary part in dictionary.
NOTE: only returns info for an arbitrary LOD
"""
if len(self.__animControlDict.items()) == 0:
if len(self.__animControlDict) == 0:
return
lodName, animControlDict = self.__animControlDict.items()[0]
lodName, animControlDict = next(iter(self.__animControlDict.items()))
if partName == None:
partName, animDict = animControlDict.items()[0]
partName, animDict = next(iter(animControlDict.items()))
else:
animDict = animControlDict.get(partName)
if animDict == None:
@ -933,9 +935,9 @@ class Actor(DirectObject, NodePath):
actor. If part not specified return current anim of first part
in dictionary. NOTE: only returns info for an arbitrary LOD
"""
lodName, animControlDict = self.__animControlDict.items()[0]
lodName, animControlDict = next(iter(self.__animControlDict.items()))
if partName == None:
partName, animDict = animControlDict.items()[0]
partName, animDict = next(iter(animControlDict.items()))
else:
animDict = animControlDict.get(partName)
if animDict == None:
@ -1138,7 +1140,7 @@ class Actor(DirectObject, NodePath):
""" Returns the list of all joints, from the named part or
from all parts, that match the indicated jointName. The
jointName may include pattern characters like *. """
joints=[]
pattern = GlobPattern(jointName)
@ -1219,7 +1221,7 @@ class Actor(DirectObject, NodePath):
for child in partNode.getChildren():
self.__getPartJoints(joints, pattern, child, subset, isIncluded)
def getJointTransform(self, partName, jointName, lodName='lodRoot'):
partBundleDict=self.__partBundleDict.get(lodName)
if not partBundleDict:
@ -1278,7 +1280,7 @@ class Actor(DirectObject, NodePath):
subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
trueName = subpartDef.truePartName
anyGood = False
for bundleDict in self.__partBundleDict.values():
for bundleDict in self.__partBundleDict.values():
bundle = bundleDict[trueName].getBundle()
if node == None:
node = self.attachNewNode(ModelNode(jointName))
@ -1308,20 +1310,20 @@ class Actor(DirectObject, NodePath):
subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
trueName = subpartDef.truePartName
anyGood = False
for bundleDict in self.__partBundleDict.values():
for bundleDict in self.__partBundleDict.values():
if bundleDict[trueName].getBundle().freezeJoint(jointName, transform):
anyGood = True
if not anyGood:
self.notify.warning("Cannot freeze joint %s" % (jointName))
def releaseJoint(self, partName, jointName):
"""Undoes a previous call to controlJoint() or freezeJoint()
and restores the named joint to its normal animation. """
subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
trueName = subpartDef.truePartName
for bundleDict in self.__partBundleDict.values():
for bundleDict in self.__partBundleDict.values():
bundleDict[trueName].getBundle().releaseJoint(jointName)
def instance(self, path, partName, jointName, lodName="lodRoot"):
@ -1417,17 +1419,15 @@ class Actor(DirectObject, NodePath):
if mode > 0:
# Use the 'fixed' bin instead of reordering the scene
# graph.
numFrontParts = frontParts.getNumPaths()
for partNum in range(0, numFrontParts):
frontParts[partNum].setBin('fixed', mode)
for part in frontParts:
part.setBin('fixed', mode)
return
if mode == -2:
# Turn off depth test/write on the frontParts.
numFrontParts = frontParts.getNumPaths()
for partNum in range(0, numFrontParts):
frontParts[partNum].setDepthWrite(0)
frontParts[partNum].setDepthTest(0)
for part in frontParts:
part.setDepthWrite(0)
part.setDepthTest(0)
# Find the back part.
backPart = root.find("**/" + backPartName)
@ -1454,12 +1454,8 @@ class Actor(DirectObject, NodePath):
char = partData.partBundleNP
char.node().update()
geomNodes = char.findAllMatches("**/+GeomNode")
numGeomNodes = geomNodes.getNumPaths()
for nodeNum in xrange(numGeomNodes):
thisGeomNode = geomNodes.getPath(nodeNum)
numGeoms = thisGeomNode.node().getNumGeoms()
for geomNum in xrange(numGeoms):
thisGeom = thisGeomNode.node().getGeom(geomNum)
for thisGeomNode in geomNodes:
for thisGeom in thisGeomNode.node().getGeoms():
thisGeom.markBoundsStale()
thisGeomNode.node().markInternalBoundsStale()
else:
@ -1470,15 +1466,11 @@ class Actor(DirectObject, NodePath):
char = partData.partBundleNP
char.node().update()
geomNodes = char.findAllMatches("**/+GeomNode")
numGeomNodes = geomNodes.getNumPaths()
for nodeNum in xrange(numGeomNodes):
thisGeomNode = geomNodes.getPath(nodeNum)
numGeoms = thisGeomNode.node().getNumGeoms()
for geomNum in xrange(numGeoms):
thisGeom = thisGeomNode.node().getGeom(geomNum)
for thisGeomNode in geomNodes:
for thisGeom in thisGeomNode.node().getGeoms():
thisGeom.markBoundsStale()
thisGeomNode.node().markInternalBoundsStale()
thisGeomNode.node().markInternalBoundsStale()
def fixBounds_old(self, part=None):
"""fixBounds(self, nodePath=None)
Force recomputation of bounding spheres for all geoms
@ -1491,19 +1483,14 @@ class Actor(DirectObject, NodePath):
# update all characters first
charNodes = part.findAllMatches("**/+Character")
numCharNodes = charNodes.getNumPaths()
for charNum in range(0, numCharNodes):
(charNodes.getPath(charNum)).node().update()
for charNode in charNodes:
charNode.node().update()
# for each geomNode, iterate through all geoms and force update
# of bounding spheres by marking current bounds as stale
geomNodes = part.findAllMatches("**/+GeomNode")
numGeomNodes = geomNodes.getNumPaths()
for nodeNum in range(0, numGeomNodes):
thisGeomNode = geomNodes.getPath(nodeNum)
numGeoms = thisGeomNode.node().getNumGeoms()
for geomNum in range(0, numGeoms):
thisGeom = thisGeomNode.node().getGeom(geomNum)
for nodeNum, thisGeomNode in enumerate(geomNodes):
for geomNum, thisGeom in enumerate(thisGeomNode.node().getGeoms()):
thisGeom.markBoundsStale()
assert Actor.notify.debug("fixing bounds for node %s, geom %s" % \
(nodeNum, geomNum))
@ -1514,26 +1501,26 @@ class Actor(DirectObject, NodePath):
Show the bounds of all actor geoms
"""
geomNodes = self.__geomNode.findAllMatches("**/+GeomNode")
numGeomNodes = geomNodes.getNumPaths()
for nodeNum in range(0, numGeomNodes):
geomNodes.getPath(nodeNum).showBounds()
for node in geomNodes:
node.showBounds()
def hideAllBounds(self):
"""
Hide the bounds of all actor geoms
"""
geomNodes = self.__geomNode.findAllMatches("**/+GeomNode")
numGeomNodes = geomNodes.getNumPaths()
for nodeNum in range(0, numGeomNodes):
geomNodes.getPath(nodeNum).hideBounds()
for node in geomNodes:
node.hideBounds()
# actions
def animPanel(self):
from direct.showbase import TkGlobal
from direct.tkpanels import AnimPanel
# Don't use a regular import, to prevent ModuleFinder from picking
# it up as a dependency when building a .p3d package.
import importlib
AnimPanel = importlib.import_module('direct.tkpanels.AnimPanel')
return AnimPanel.AnimPanel(self)
def stop(self, animName=None, partName=None):
@ -1567,7 +1554,7 @@ class Actor(DirectObject, NodePath):
is given then try to loop on all parts. NOTE: loops on
all LOD's
"""
if fromFrame == None:
for control in self.getAnimControls(animName, partName):
control.loop(restart)
@ -1612,7 +1599,7 @@ class Actor(DirectObject, NodePath):
The animBlend and frameBlend parameters are boolean flags.
You may set either or both to True or False. If you do not
specify them, they do not change from the previous value.
When animBlend is True, multiple different animations may
simultaneously be playing on the Actor. This means you may
call play(), loop(), or pose() on multiple animations and have
@ -1681,7 +1668,7 @@ class Actor(DirectObject, NodePath):
the overall pose. This controls blending of multiple
animations; it only makes sense to call this after a previous
call to setBlend(animBlend = True).
"""
"""
for control in self.getAnimControls(animName, partName, lodName):
control.getPart().setControlEffect(control, effect)
@ -1693,7 +1680,7 @@ class Actor(DirectObject, NodePath):
if self.mergeLODBundles:
lodName = 'common'
elif self.switches:
lodName = str(self.switches.keys()[0])
lodName = str(next(iter(self.switches)))
else:
lodName = 'lodRoot'
@ -1710,7 +1697,7 @@ class Actor(DirectObject, NodePath):
a given anim and part. If none specified, try the first part and lod.
Return the animControl if present, or None otherwise.
"""
if not partName:
partName = 'modelRoot'
@ -1718,7 +1705,7 @@ class Actor(DirectObject, NodePath):
lodName = 'common'
elif not lodName:
if self.switches:
lodName = str(self.switches.keys()[0])
lodName = str(next(iter(self.switches)))
else:
lodName = 'lodRoot'
@ -1772,8 +1759,8 @@ class Actor(DirectObject, NodePath):
# If we have the __subpartsComplete flag, and no partName
# is specified, it really means to play the animation on
# all subparts, not on the overall Actor.
partName = self.__subpartDict.keys()
partName = list(self.__subpartDict.keys())
controls = []
# build list of lodNames and corresponding animControlDicts
# requested.
@ -1800,13 +1787,13 @@ class Actor(DirectObject, NodePath):
else:
# Get exactly the named part or parts.
if isinstance(partName, types.StringTypes):
if isinstance(partName, str):
partNameList = [partName]
else:
partNameList = partName
animDictItems = []
for pName in partNameList:
animDict = partDict.get(pName)
if animDict == None:
@ -1830,7 +1817,7 @@ class Actor(DirectObject, NodePath):
controls.append(anim.animControl)
else:
# get the named animation(s) only.
if isinstance(animName, types.StringTypes):
if isinstance(animName, str):
# A single animName
animNameList = [animName]
else:
@ -1868,7 +1855,7 @@ class Actor(DirectObject, NodePath):
# Force the animation to load if it's
# not already loaded.
animControl.waitPending()
if animControl:
controls.append(animControl)
@ -1898,21 +1885,29 @@ class Actor(DirectObject, NodePath):
# If copy = 0, then we should always hit the disk.
loaderOptions = LoaderOptions(loaderOptions)
loaderOptions.setFlags(loaderOptions.getFlags() & ~LoaderOptions.LFNoRamCache)
if okMissing is not None:
if okMissing:
loaderOptions.setFlags(loaderOptions.getFlags() & ~LoaderOptions.LFReportErrors)
else:
loaderOptions.setFlags(loaderOptions.getFlags() | LoaderOptions.LFReportErrors)
# Pass loaderOptions to specify that we want to
# get the skeleton model. This only matters to model
# files (like .mb) for which we can choose to extract
# either the skeleton or animation, or neither.
model = loader.loadModel(modelPath, loaderOptions = loaderOptions, okMissing = okMissing)
model = self.loader.loadSync(Filename(modelPath), loaderOptions)
if model is not None:
model = NodePath(model)
if (model == None):
raise StandardError, "Could not load Actor model %s" % (modelPath)
raise IOError("Could not load Actor model %s" % (modelPath))
if (model.node().isOfType(Character.getClassType())):
bundleNP = model
else:
bundleNP = model.find("**/+Character")
if (bundleNP.isEmpty()):
Actor.notify.warning("%s is not a character!" % (modelPath))
model.reparentTo(self.__geomNode)
@ -2045,8 +2040,8 @@ class Actor(DirectObject, NodePath):
if otherPartName != partName and otherPartDef.truePartName == parent:
joints = self.getOverlappingJoints(partName, otherPartName)
if joints:
raise StandardError, 'Overlapping joints: %s and %s' % (partName, otherPartName)
raise Exception('Overlapping joints: %s and %s' % (partName, otherPartName))
def setSubpartsComplete(self, flag):
"""Sets the subpartsComplete flag. This affects the behavior
@ -2068,7 +2063,7 @@ class Actor(DirectObject, NodePath):
It makes sense to set this True when the union of all of your
subparts completely defines the entire Actor.
"""
self.__subpartsComplete = flag
if __dev__ and self.__subpartsComplete and self.validateSubparts.getValue():
@ -2076,11 +2071,11 @@ class Actor(DirectObject, NodePath):
# specified all of them.
if self.__subpartDict:
self.verifySubpartsComplete()
def getSubpartsComplete(self):
"""See setSubpartsComplete()."""
return self.__subpartsComplete
def verifySubpartsComplete(self, partName = None, lodName = None):
@ -2094,7 +2089,7 @@ class Actor(DirectObject, NodePath):
if lodName:
partNames = self.__partBundleDict[lodName].keys()
else:
partNames = self.__partBundleDict.values()[0].keys()
partNames = next(iter(self.__partBundleDict.values())).keys()
for partName in partNames:
subJoints = set()
@ -2120,13 +2115,13 @@ class Actor(DirectObject, NodePath):
lodNames = ['common']
elif lodName == 'all':
reload = False
lodNames = self.switches.keys()
lodNames = list(self.switches.keys())
lodNames.sort()
for i in range(0,len(lodNames)):
for i in range(0, len(lodNames)):
lodNames[i] = str(lodNames[i])
else:
lodNames = [lodName]
assert Actor.notify.debug("in loadAnims: %s, part: %s, lod: %s" %
(anims, partName, lodNames[0]))
@ -2170,7 +2165,7 @@ class Actor(DirectObject, NodePath):
lodNames = ['common']
else:
lodNames = self.__partBundleDict.keys()
for lod in lodNames:
for part in partNames:
self.__animControlDict.setdefault(lod,{})
@ -2181,9 +2176,9 @@ class Actor(DirectObject, NodePath):
# for lod in self.__partBundleDict.keys():
# # store the file path only; we will bind it (and produce
# # an AnimControl) when it is played
#
#
# self.__animControlDict[lod][partName][animName] = Actor.AnimDef(filename)
def loadAnimsOnAllLODs(self, anims,partName="modelRoot"):
"""loadAnims(self, string:string{}, string='modelRoot',
string='lodRoot')
@ -2196,13 +2191,13 @@ class Actor(DirectObject, NodePath):
lodNames = ['common']
else:
lodNames = self.__partBundleDict.keys()
for animName, filename in anims.items():
# make sure this lod is in anim control dict
for lod in lodNames:
# store the file path only; we will bind it (and produce
# an AnimControl) when it is played
self.__animControlDict[lod][partName][animName]= Actor.AnimDef(filename)
def postFlatten(self):
@ -2211,7 +2206,7 @@ class Actor(DirectObject, NodePath):
especially necessary when mergeLODBundles is true, since this
kind of actor may be broken after a flatten operation; this
method should restore proper Actor functionality. """
if self.mergeLODBundles:
# Re-merge all bundles, and restore the common bundle map.
self.__commonBundleHandles = {}
@ -2224,11 +2219,11 @@ class Actor(DirectObject, NodePath):
partDef.partBundleHandle = loadedBundleHandle
else:
self.__commonBundleHandles[partName] = partDef.partBundleHandle
# Since we may have merged together some bundles, all of
# our anims are now suspect. Force them to reload.
self.unloadAnims()
def unloadAnims(self, anims=None, partName=None, lodName=None):
"""unloadAnims(self, string:string{}, string='modelRoot',
string='lodRoot')
@ -2243,20 +2238,20 @@ class Actor(DirectObject, NodePath):
assert Actor.notify.debug("in unloadAnims: %s, part: %s, lod: %s" %
(anims, partName, lodName))
if lodName == None or self.mergeLODBundles:
if lodName is None or self.mergeLODBundles:
lodNames = self.__animControlDict.keys()
else:
lodNames = [lodName]
if (partName == None):
if partName is None:
if len(lodNames) > 0:
partNames = self.__animControlDict[lodNames[0]].keys()
partNames = self.__animControlDict[next(iter(lodNames))].keys()
else:
partNames = []
else:
partNames = [partName]
if (anims==None):
if anims is None:
for lodName in lodNames:
for partName in partNames:
for animDef in self.__animControlDict[lodName][partName].values():
@ -2368,7 +2363,7 @@ class Actor(DirectObject, NodePath):
# operation that will complete in the background, but if so it
# will still return a usable AnimControl.
animControl = bundle.loadBindAnim(
loader.loader, Filename(anim.filename), -1,
self.loader, Filename(anim.filename), -1,
subpartDef.subset, allowAsyncBind and self.allowAsyncBind)
if not animControl:
@ -2387,7 +2382,7 @@ class Actor(DirectObject, NodePath):
Copy the part bundle dictionary from another actor as this
instance's own. NOTE: this method does not actually copy geometry
"""
for lodName in other.__partBundleDict.keys():
for lodName in other.__partBundleDict:
# find the lod Asad
if lodName == 'lodRoot':
partLod = self
@ -2399,7 +2394,7 @@ class Actor(DirectObject, NodePath):
for partName, partDef in other.__partBundleDict[lodName].items():
# We can really only copy from a non-flattened avatar.
assert partDef.partBundleNP.node().getNumBundles() == 1
# find the part in our tree
bundleNP = partLod.find("**/%s%s"%(Actor.partPrefix,partName))
if (bundleNP != None):
@ -2432,11 +2427,11 @@ class Actor(DirectObject, NodePath):
assert(other.mergeLODBundles == self.mergeLODBundles)
for lodName in other.__animControlDict.keys():
for lodName in other.__animControlDict:
self.__animControlDict[lodName] = {}
for partName in other.__animControlDict[lodName].keys():
for partName in other.__animControlDict[lodName]:
self.__animControlDict[lodName][partName] = {}
for animName in other.__animControlDict[lodName][partName].keys():
for animName in other.__animControlDict[lodName][partName]:
anim = other.__animControlDict[lodName][partName][animName]
anim = anim.makeCopy()
self.__animControlDict[lodName][partName][animName] = anim
@ -2496,16 +2491,16 @@ class Actor(DirectObject, NodePath):
result.append((lodName, animList))
return result
def printAnimBlends(self, animName=None, partName=None, lodName=None):
for lodName, animList in self.getAnimBlends(animName, partName, lodName):
print 'LOD %s:' % (lodName)
print('LOD %s:' % (lodName))
for animName, blendList in animList:
list = []
for partName, effect in blendList:
list.append('%s:%.3f' % (partName, effect))
print ' %s: %s' % (animName, ', '.join(list))
print(' %s: %s' % (animName, ', '.join(list)))
def osdAnimBlends(self, animName=None, partName=None, lodName=None):
if not onScreenDebug.enabled:
@ -2552,5 +2547,5 @@ class Actor(DirectObject, NodePath):
def renamePartBundles(self, partName, newBundleName):
subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
for partBundleDict in self.__partBundleDict.values():
partDef=partBundleDict.get(subpartDef.truePartName)
partDef = partBundleDict.get(subpartDef.truePartName)
partDef.getBundle().setName(newBundleName)

View File

@ -4,18 +4,18 @@ __all__ = ['DistributedActor']
from direct.distributed import DistributedNode
import Actor
from . import Actor
class DistributedActor(DistributedNode.DistributedNode, Actor.Actor):
def __init__(self, cr):
try:
self.DistributedActor_initialized
except:
self.DistributedActor_initialized = 1
Actor.Actor.__init__(self)
self.DistributedActor_initialized = 1
Actor.Actor.__init__(self)
DistributedNode.DistributedNode.__init__(self, cr)
# Since actors are probably fairly heavyweight, we'd
# rather cache them than delete them if possible.
# rather cache them than delete them if possible.
self.setCacheable(1)
def disable(self):
@ -28,10 +28,10 @@ class DistributedActor(DistributedNode.DistributedNode, Actor.Actor):
try:
self.DistributedActor_deleted
except:
self.DistributedActor_deleted = 1
self.DistributedActor_deleted = 1
DistributedNode.DistributedNode.delete(self)
Actor.Actor.delete(self)
def loop(self, animName, restart=1, partName=None, fromFrame=None, toFrame=None):
def loop(self, animName, restart=1, partName=None, fromFrame=None, toFrame=None):
return Actor.Actor.loop(self, animName, restart, partName, fromFrame, toFrame)

View File

@ -1,8 +1,8 @@
"""ClusterClient: Master for mutli-piping or PC clusters. """
from panda3d.core import *
from ClusterMsgs import *
from ClusterConfig import *
from .ClusterMsgs import *
from .ClusterConfig import *
from direct.directnotify import DirectNotifyGlobal
from direct.showbase import DirectObject
from direct.task import Task
@ -44,10 +44,10 @@ class ClusterClient(DirectObject.DirectObject):
self.daemon.tellServer(serverConfig.serverName,
serverConfig.serverDaemonPort,
serverCommand)
print 'Begin waitForServers'
print('Begin waitForServers')
if not self.daemon.waitForServers(len(configList)):
print 'Cluster Client, no response from servers'
print 'End waitForServers'
print('Cluster Client, no response from servers')
print('End waitForServers')
self.qcm=QueuedConnectionManager()
self.serverList = []
self.serverQueues = []
@ -147,7 +147,7 @@ class ClusterClient(DirectObject.DirectObject):
if (serverList == None):
serverList = range(len(self.serverList))
for server in serverList:
self.serverList[server].sendNamedMovementDone()
@ -161,7 +161,7 @@ class ClusterClient(DirectObject.DirectObject):
key])
self.sortedControlMappings.sort()
def moveObject(self, nodePath, object, serverList, offset, hasColor = True):
self.notify.debug('moving object '+object)
xyz = nodePath.getPos(render) + offset
@ -222,7 +222,7 @@ class ClusterClient(DirectObject.DirectObject):
serverList = range(len(self.serverList))
if (offset == None):
offset = Vec3(0,0,0)
self.controlMappings[objectName] = [controlledName,serverList]
self.controlOffsets[objectName] = offset
self.controlPriorities[objectName] = priority
@ -247,7 +247,7 @@ class ClusterClient(DirectObject.DirectObject):
if (serverList == None):
self.controlMappings.pop(name)
self.controlPriorities.pop(name)
self.controlPriorities.pop(name)
else:
list = self.controlMappings[key][1]
newList = []
@ -260,11 +260,10 @@ class ClusterClient(DirectObject.DirectObject):
self.controlPriorities.pop(name)
self.redoSortedPriorities()
def getNodePathFindCmd(self, nodePath):
import string
pathString = repr(nodePath)
index = string.find(pathString, '/')
index = pathString.find('/')
if index != -1:
rootName = pathString[:index]
searchString = pathString[index+1:]
@ -273,9 +272,8 @@ class ClusterClient(DirectObject.DirectObject):
return rootName
def getNodePathName(self, nodePath):
import string
pathString = repr(nodePath)
index = string.find(pathString, '/')
index = pathString.find('/')
if index != -1:
name = pathString[index+1:]
return name
@ -288,14 +286,14 @@ class ClusterClient(DirectObject.DirectObject):
newTag["selectFunction"] = selectFunction
newTag["selectArgs"] = selectArgs
newTag["deselectFunction"] = deselectFunction
newTag["deselectArgs"] = deselectArgs
newTag["deselectArgs"] = deselectArgs
self.taggedObjects[object] = newTag
def removeObjectTag(self,object):
self.taggedObjects.pop(object)
def selectNodePath(self, nodePath):
name = self.getNodePathName(nodePath)
@ -308,14 +306,14 @@ class ClusterClient(DirectObject.DirectObject):
function(*args)
else:
self(self.getNodePathFindCmd(nodePath) + '.select()', 0)
def deselectNodePath(self, nodePath):
name = self.getNodePathName(nodePath)
if name in self.taggedObjects:
tag = self.taggedObjects[name]
function = tag["deselectFunction"]
args = tag["deselectArgs"]
args = tag["deselectArgs"]
if (function != None):
function(*args)
self.startMoveSelectedTask()
@ -372,12 +370,12 @@ class ClusterClient(DirectObject.DirectObject):
# clear the queue
self.serverQueues[server] = []
def handleNamedMovement(self, data):
""" Update cameraJig position to reflect latest position """
(name,x, y, z, h, p, r, sx, sy, sz,red,g,b,a, hidden) = data
(name,x, y, z, h, p, r, sx, sy, sz,red,g,b,a, hidden) = data
#print "name"
#if (name == "camNode"):
# print x,y,z,h,p,r, sx, sy, sz,red,g,b,a, hidden
@ -409,7 +407,7 @@ class ClusterClientSync(ClusterClient):
#I probably don't need this
self.waitForSwap = 0
self.ready = 0
print "creating synced client"
print("creating synced client")
self.startSwapCoordinatorTask()
def startSwapCoordinatorTask(self):

View File

@ -1,5 +1,5 @@
from ClusterClient import *
from .ClusterClient import *
# A dictionary of information for various cluster configurations.
# Dictionary is keyed on cluster-config string

View File

@ -166,7 +166,7 @@ class ClusterMsgHandler:
self.packetNumber = self.packetNumber + 1
datagram.addUint8(CLUSTER_NAMED_MOVEMENT_DONE)
return datagram
def makeNamedObjectMovementDatagram(self, xyz, hpr, scale, color, hidden, name):
datagram = PyDatagram()
@ -186,9 +186,9 @@ class ClusterMsgHandler:
datagram.addFloat32(color[0])
datagram.addFloat32(color[1])
datagram.addFloat32(color[2])
datagram.addFloat32(color[3])
datagram.addFloat32(color[3])
datagram.addBool(hidden)
return datagram
return datagram
def parseCamMovementDatagram(self, dgi):
x=dgi.getFloat32()
@ -215,7 +215,7 @@ class ClusterMsgHandler:
red = dgi.getFloat32()
g = dgi.getFloat32()
b = dgi.getFloat32()
a = dgi.getFloat32()
a = dgi.getFloat32()
hidden = dgi.getBool()
return (name,x, y, z, h, p, r, sx, sy, sz, red, g, b, a, hidden)

View File

@ -1,5 +1,5 @@
from panda3d.core import *
from ClusterMsgs import *
from .ClusterMsgs import *
from direct.distributed.MsgTypes import *
from direct.directnotify import DirectNotifyGlobal
from direct.showbase import DirectObject
@ -138,7 +138,7 @@ class ClusterServer(DirectObject.DirectObject):
def setControlMappingOffset(self,objectName,offset):
if (objectName in self.controlMappings):
self.controlOffsets[objectName] = offset
def removeControlMapping(self,name):
if (name in self.controlMappings):
@ -146,7 +146,7 @@ class ClusterServer(DirectObject.DirectObject):
self.controlPriorities.pop(name)
self.redoSortedPriorities()
def startControlObjectTask(self):
self.notify.debug("moving control objects")
taskMgr.add(self.controlObjectTask,"controlObjectTask",50)
@ -155,7 +155,7 @@ class ClusterServer(DirectObject.DirectObject):
#print "running control object task"
for pair in self.sortedControlPriorities:
object = pair[1]
name = self.controlMappings[object]
name = self.controlMappings[object]
if (object in self.objectMappings):
self.moveObject(self.objectMappings[object],name,self.controlOffsets[object],
self.objectHasColor[object])
@ -169,7 +169,7 @@ class ClusterServer(DirectObject.DirectObject):
self.notify.debug("named movement done")
datagram = self.msgHandler.makeNamedMovementDone()
self.cw.send(datagram,self.lastConnection)
def moveObject(self, nodePath, object, offset, hasColor):
self.notify.debug('moving object '+object)
#print "moving object",object
@ -246,7 +246,7 @@ class ClusterServer(DirectObject.DirectObject):
if (type == CLUSTER_NONE):
pass
elif (type == CLUSTER_EXIT):
print 'GOT EXIT'
print('GOT EXIT')
import sys
sys.exit()
elif (type == CLUSTER_CAM_OFFSET):
@ -322,7 +322,7 @@ class ClusterServer(DirectObject.DirectObject):
""" Update cameraJig position to reflect latest position """
(x, y, z, h, p, r) = self.msgHandler.parseCamMovementDatagram(dgi)
self.cameraJig.setPosHpr(render, x, y, z, h, p, r)
self.fPosReceived = 1
self.fPosReceived = 1
def handleSelectedMovement(self, dgi):
""" Update cameraJig position to reflect latest position """

View File

@ -1,8 +1,8 @@
from direct.showbase.InputStateGlobal import inputState
from direct.task.Task import Task
from pandac.PandaModules import *
import GravityWalker
from panda3d.core import *
from . import GravityWalker
BattleStrafe = 0
@ -36,12 +36,12 @@ class BattleWalker(GravityWalker.GravityWalker):
slideLeft = inputState.isSet("slideLeft")
slideRight = inputState.isSet("slideRight")
jump = inputState.isSet("jump")
# Check for Auto-Run
if base.localAvatar.getAutoRun():
forward = 1
reverse = 0
# Determine what the speeds are based on the buttons:
self.speed=(forward and self.avatarControlForwardSpeed or
reverse and -self.avatarControlReverseSpeed)
@ -58,7 +58,7 @@ class BattleWalker(GravityWalker.GravityWalker):
self.speed*=base.debugRunningMultiplier
self.slideSpeed*=base.debugRunningMultiplier
self.rotationSpeed*=1.25
if self.needToDeltaPos:
self.setPriorParentVector()
self.needToDeltaPos = 0
@ -166,7 +166,7 @@ class BattleWalker(GravityWalker.GravityWalker):
# Should fSlide be renamed slideButton?
self.slideSpeed=.15*(turnLeft and -self.avatarControlForwardSpeed or
turnRight and self.avatarControlForwardSpeed)
print 'slideSpeed: ', self.slideSpeed
print('slideSpeed: %s' % self.slideSpeed)
self.rotationSpeed=0
self.speed=0
@ -233,7 +233,7 @@ class BattleWalker(GravityWalker.GravityWalker):
if self.moving:
distance = dt * self.speed
slideDistance = dt * self.slideSpeed
print 'slideDistance: ', slideDistance
print('slideDistance: %s' % slideDistance)
rotation = dt * self.rotationSpeed
# Take a step in the direction of our previous heading.

View File

@ -19,7 +19,7 @@ CollisionHandlerRayStart = 4000.0 # This is a hack, it may be better to use a li
class ControlManager:
notify = DirectNotifyGlobal.directNotify.newCategory("ControlManager")
wantWASD = ConfigVariableBool('want-WASD', True)
wantWASD = ConfigVariableBool('want-WASD', False)
def __init__(self, enable=True, passMessagesThrough = False):
assert self.notify.debug("init control manager %s" % (passMessagesThrough))
@ -37,9 +37,9 @@ class ControlManager:
self.enable()
#self.monitorTask = taskMgr.add(self.monitor, "ControlManager-%s"%(id(self)), priority=-1)
self.forceAvJumpToken = None
if self.passMessagesThrough: # for not breaking toontown
ist=self.inputStateTokens
ist.append(inputState.watchWithModifiers("forward", "arrow_up", inputSource=inputState.ArrowKeys))
@ -50,7 +50,7 @@ class ControlManager:
def __str__(self):
return 'ControlManager: using \'%s\'' % self.currentControlsName
def add(self, controls, name="basic"):
"""
controls is an avatar control system.
@ -75,7 +75,7 @@ class ControlManager:
def get(self, name):
return self.controls.get(name)
def remove(self, name):
"""
name is any key that was used to refer to the
@ -166,7 +166,7 @@ class ControlManager:
if self.currentControls:
return self.currentControls.getIsAirborne()
return False
def setTag(self, key, value):
assert self.notify.debugCall(id(self))
for controls in self.controls.values():
@ -181,7 +181,7 @@ class ControlManager:
assert self.notify.debugCall(id(self))
if self.currentControls:
self.currentControls.setCollisionsActive(1)
def collisionsOff(self):
assert self.notify.debugCall(id(self))
if self.currentControls:
@ -198,25 +198,25 @@ class ControlManager:
if self.isEnabled:
assert self.notify.debug('already isEnabled')
return
self.isEnabled = 1
# keep track of what we do on the inputState so we can undo it later on
#self.inputStateTokens = []
ist = self.inputStateTokens
ist.append(inputState.watch("run", 'runningEvent', "running-on", "running-off"))
ist.append(inputState.watchWithModifiers("forward", "arrow_up", inputSource=inputState.ArrowKeys))
ist.append(inputState.watch("forward", "force-forward", "force-forward-stop"))
ist.append(inputState.watchWithModifiers("reverse", "arrow_down", inputSource=inputState.ArrowKeys))
ist.append(inputState.watchWithModifiers("reverse", "mouse4", inputSource=inputState.Mouse))
if self.wantWASD:
ist.append(inputState.watchWithModifiers("turnLeft", "arrow_left", inputSource=inputState.ArrowKeys))
ist.append(inputState.watch("turnLeft", "mouse-look_left", "mouse-look_left-done"))
ist.append(inputState.watch("turnLeft", "force-turnLeft", "force-turnLeft-stop"))
ist.append(inputState.watchWithModifiers("turnRight", "arrow_right", inputSource=inputState.ArrowKeys))
ist.append(inputState.watch("turnRight", "mouse-look_right", "mouse-look_right-done"))
ist.append(inputState.watch("turnRight", "force-turnRight", "force-turnRight-stop"))
@ -232,7 +232,7 @@ class ControlManager:
ist.append(inputState.watchWithModifiers("turnLeft", "arrow_left", inputSource=inputState.ArrowKeys))
ist.append(inputState.watch("turnLeft", "mouse-look_left", "mouse-look_left-done"))
ist.append(inputState.watch("turnLeft", "force-turnLeft", "force-turnLeft-stop"))
ist.append(inputState.watchWithModifiers("turnRight", "arrow_right", inputSource=inputState.ArrowKeys))
ist.append(inputState.watch("turnRight", "mouse-look_right", "mouse-look_right-done"))
ist.append(inputState.watch("turnRight", "force-turnRight", "force-turnRight-stop"))
@ -242,7 +242,7 @@ class ControlManager:
ist.append(inputState.watchWithModifiers("jump", "space"))
else:
ist.append(inputState.watch("jump", "control", "control-up"))
if self.currentControls:
self.currentControls.enableAvatarControls()
@ -260,7 +260,7 @@ class ControlManager:
if self.currentControls:
self.currentControls.disableAvatarControls()
if self.passMessagesThrough: # for not breaking toontown
ist=self.inputStateTokens
ist.append(inputState.watchWithModifiers("forward", "arrow_up", inputSource=inputState.ArrowKeys))
@ -274,10 +274,10 @@ class ControlManager:
self.currentControls.setCollisionsActive(0)
self.currentControls.setAvatar(None)
self.currentControls = None
def disableAvatarJump(self):
"""
prevent
prevent
"""
assert self.forceAvJumpToken is None
self.forceAvJumpToken=inputState.force(
@ -310,7 +310,7 @@ class ControlManager:
if not self.isEnabled:
return
turnLeftWASDSet = inputState.isSet("turnLeft", inputSource=inputState.WASD)
turnRightWASDSet = inputState.isSet("turnRight", inputSource=inputState.WASD)
slideLeftWASDSet = inputState.isSet("slideLeft", inputSource=inputState.WASD)
@ -339,7 +339,7 @@ class ControlManager:
inputState.set("slideLeft", turnLeftWASDSet, inputSource=inputState.WASD)
inputState.set("slideRight", turnRightWASDSet, inputSource=inputState.WASD)
inputState.set("turnLeft", False, inputSource=inputState.WASD)
inputState.set("turnRight", False, inputSource=inputState.WASD)

View File

@ -18,13 +18,14 @@ from direct.showbase.InputStateGlobal import inputState
from direct.directnotify import DirectNotifyGlobal
from direct.showbase import DirectObject
from direct.task.Task import Task
from pandac.PandaModules import *
from panda3d.core import *
class DevWalker(DirectObject.DirectObject):
notify = DirectNotifyGlobal.directNotify.newCategory("DevWalker")
wantDebugIndicator = base.config.GetBool('want-avatar-physics-indicator', 0)
runMultiplier = base.config.GetFloat('dev-run-multiplier', 4.0)
wantDebugIndicator = ConfigVariableBool('want-avatar-physics-indicator', False)
runMultiplier = ConfigVariableDouble('dev-run-multiplier', 4.0)
# Ghost mode overrides this:
slideName = "slide-is-disabled"
@ -109,13 +110,13 @@ class DevWalker(DirectObject.DirectObject):
slideRight = inputState.isSet("slideRight")
levitateUp = inputState.isSet("levitateUp")
levitateDown = inputState.isSet("levitateDown")
run = inputState.isSet("run") and self.runMultiplier or 1.0
run = inputState.isSet("run") and self.runMultiplier.getValue() or 1.0
# Check for Auto-Run
if base.localAvatar.getAutoRun():
forward = 1
reverse = 0
# Determine what the speeds are based on the buttons:
self.speed=(
(forward and self.avatarControlForwardSpeed or
@ -182,7 +183,7 @@ class DevWalker(DirectObject.DirectObject):
def flushEventHandlers(self):
pass
if __debug__:
def debugPrint(self, message):
"""for debugging"""

View File

@ -14,10 +14,8 @@ although it does send messeges that allow a listener to play sounds or
animations based on walker events.
"""
from direct.showbase.ShowBaseGlobal import *
from direct.directnotify import DirectNotifyGlobal
import NonPhysicsWalker
from . import NonPhysicsWalker
class GhostWalker(NonPhysicsWalker.NonPhysicsWalker):

View File

@ -19,11 +19,11 @@ from direct.showbase import DirectObject
from direct.controls.ControlManager import CollisionHandlerRayStart
from direct.showbase.InputStateGlobal import inputState
from direct.task.Task import Task
from pandac.PandaModules import *
from panda3d.core import *
class NonPhysicsWalker(DirectObject.DirectObject):
notify = DirectNotifyGlobal.directNotify.newCategory("NonPhysicsWalker")
wantDebugIndicator = base.config.GetBool('want-avatar-physics-indicator', 0)
wantDebugIndicator = ConfigVariableBool('want-avatar-physics-indicator', False)
# Ghost mode overrides this:
slideName = "slide-is-disabled"
@ -70,7 +70,7 @@ class NonPhysicsWalker(DirectObject.DirectObject):
if self.cRayNodePath and not self.cRayNodePath.isEmpty():
self.cRayNodePath.node().setFromCollideMask(self.cRayBitMask)
def initializeCollisions(self, collisionTraverser, avatarNodePath,
avatarRadius = 1.4, floorOffset = 1.0, reach = 1.0):
"""
@ -201,12 +201,12 @@ class NonPhysicsWalker(DirectObject.DirectObject):
turnRight = inputState.isSet("turnRight")
slide = inputState.isSet(self.slideName) or 0
#jump = inputState.isSet("jump")
# Check for Auto-Run
if base.localAvatar.getAutoRun():
forward = 1
reverse = 0
# Determine what the speeds are based on the buttons:
self.speed=(forward and self.avatarControlForwardSpeed or
reverse and -self.avatarControlReverseSpeed)
@ -218,7 +218,7 @@ class NonPhysicsWalker(DirectObject.DirectObject):
self.rotationSpeed=not slide and (
(turnLeft and self.avatarControlRotateSpeed) or
(turnRight and -self.avatarControlRotateSpeed))
def handleAvatarControls(self, task):
"""
Check on the arrow keys and update the avatar.
@ -311,7 +311,7 @@ class NonPhysicsWalker(DirectObject.DirectObject):
if hasattr(self, 'cTrav'):
self.pusher.flush()
self.lifter.flush() # not currently defined or needed
if __debug__:
def debugPrint(self, message):
"""for debugging"""

View File

@ -14,10 +14,9 @@ although it does send messeges that allow a listener to play sounds or
animations based on walker events.
"""
from direct.showbase.ShowBaseGlobal import *
from pandac.PandaModules import *
from panda3d.core import *
from direct.directnotify import DirectNotifyGlobal
import NonPhysicsWalker
from . import NonPhysicsWalker
class ObserverWalker(NonPhysicsWalker.NonPhysicsWalker):
notify = DirectNotifyGlobal.directNotify.newCategory("ObserverWalker")

View File

@ -324,7 +324,7 @@ class PhysicsWalker(DirectObject.DirectObject):
indicator.instanceTo(contactIndicatorNode)
self.physContactIndicator=contactIndicatorNode
else:
print "failed load of physics indicator"
print("failed load of physics indicator")
def avatarPhysicsIndicator(self, task):
#assert self.debugPrint("avatarPhysicsIndicator()")
@ -469,12 +469,12 @@ class PhysicsWalker(DirectObject.DirectObject):
slideLeft = 0#inputState.isSet("slideLeft")
slideRight = 0#inputState.isSet("slideRight")
jump = inputState.isSet("jump")
# Check for Auto-Run
if base.localAvatar.getAutoRun():
forward = 1
reverse = 0
# Determine what the speeds are based on the buttons:
self.__speed=(forward and self.avatarControlForwardSpeed or
reverse and -self.avatarControlReverseSpeed)
@ -710,7 +710,7 @@ class PhysicsWalker(DirectObject.DirectObject):
def setPriorParentVector(self):
assert self.debugPrint("doDeltaPos()")
print "self.__oldDt", self.__oldDt, "self.__oldPosDelta", self.__oldPosDelta
print("self.__oldDt %s self.__oldPosDelta %s" % (self.__oldDt, self.__oldPosDelta))
if __debug__:
onScreenDebug.add("__oldDt", "% 10.4f"%self.__oldDt)
onScreenDebug.add("self.__oldPosDelta",

View File

@ -16,7 +16,7 @@ class SwimWalker(NonPhysicsWalker.NonPhysicsWalker):
if base.localAvatar.getAutoRun():
forward = 1
reverse = 0
# Determine what the speeds are based on the buttons:
self.speed=(forward and self.avatarControlForwardSpeed or
reverse and -self.avatarControlReverseSpeed)

View File

@ -2,21 +2,23 @@
TwoDWalker.py is for controling the avatars in a 2D Scroller game environment.
"""
from GravityWalker import *
from .GravityWalker import *
from panda3d.core import ConfigVariableBool
class TwoDWalker(GravityWalker):
"""
The TwoDWalker is primarily for a 2D Scroller game environment. Eg - Toon Blitz minigame.
TODO: This class is still work in progress.
TODO: This class is still work in progress.
Currently Toon Blitz is using this only for jumping.
Moving the Toon left to right is handled by toontown/src/minigame/TwoDDrive.py.
I eventually want this class to control all the 2 D movements, possibly with a
customizable input list.
"""
notify = directNotify.newCategory("TwoDWalker")
wantDebugIndicator = base.config.GetBool('want-avatar-physics-indicator', 0)
wantFloorSphere = base.config.GetBool('want-floor-sphere', 0)
earlyEventSphere = base.config.GetBool('early-event-sphere', 0)
wantDebugIndicator = ConfigVariableBool('want-avatar-physics-indicator', False)
wantFloorSphere = ConfigVariableBool('want-floor-sphere', False)
earlyEventSphere = ConfigVariableBool('early-event-sphere', False)
# special methods
def __init__(self, gravity = -32.1740, standableGround=0.707,
@ -24,13 +26,13 @@ class TwoDWalker(GravityWalker):
assert self.notify.debugStateCall(self)
self.notify.debug('Constructing TwoDWalker')
GravityWalker.__init__(self)
def handleAvatarControls(self, task):
"""
Check on the arrow keys and update the avatar.
"""
"""
# get the button states:
jump = inputState.isSet("forward")
jump = inputState.isSet("forward")
if self.lifter.isOnGround():
if self.isAirborne:
self.isAirborne = 0
@ -43,9 +45,9 @@ class TwoDWalker(GravityWalker):
if self.isAirborne == 0:
assert self.debugPrint("isAirborne 1 due to isOnGround() false")
self.isAirborne = 1
return Task.cont
def jumpPressed(self):
"""This function should be called from TwoDDrive when the jump key is pressed."""
if self.lifter.isOnGround():
@ -55,4 +57,4 @@ class TwoDWalker(GravityWalker):
self.lifter.addVelocity(self.avatarControlJumpForce)
messenger.send("jumpStart")
self.isAirborne = 1
assert self.debugPrint("isAirborne 1 due to jump")
assert self.debugPrint("isAirborne 1 due to jump")

View File

@ -1,16 +1,15 @@
// Filename: dcparse.cxx
// Created by: drose (05Oct00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcparse.cxx
* @author drose
* @date 2000-10-05
*/
#include "dcbase.h"
#include "dcFile.h"
@ -22,7 +21,7 @@
void
usage() {
cerr <<
cerr <<
"\n"
"Usage:\n\n"
"dcparse [options] [file1 file2 ...]\n"
@ -32,7 +31,7 @@ usage() {
void
help() {
usage();
cerr <<
cerr <<
"This program reads one or more DC files, which are used to describe the\n"
"communication channels in the distributed class system. By default,\n"
"the file(s) are read and concatenated, and a single hash code is printed\n"
@ -58,7 +57,7 @@ help() {
}
void
write_class_hierarchy(int indent_level, const DCFile &file,
write_class_hierarchy(int indent_level, const DCFile &file,
const DCClass *this_dclass) {
indent(cout, indent_level)
<< this_dclass->get_name() << "\n";
@ -117,7 +116,7 @@ write_complete_field_list(const DCFile &file) {
int
main(int argc, char *argv[]) {
// extern char *optarg;
// extern char *optarg;
extern int optind;
const char *optstr = "bvcfh";

View File

@ -1,27 +1,24 @@
// Filename: dcArrayParameter.cxx
// Created by: drose (17Jun04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcArrayParameter.cxx
* @author drose
* @date 2004-06-17
*/
#include "dcArrayParameter.h"
#include "dcSimpleParameter.h"
#include "dcClassParameter.h"
#include "hashGenerator.h"
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCArrayParameter::
DCArrayParameter(DCParameter *element_type, const DCUnsignedIntRange &size) :
_element_type(element_type),
@ -41,10 +38,10 @@ DCArrayParameter(DCParameter *element_type, const DCUnsignedIntRange &size) :
_has_fixed_byte_size = true;
_fixed_byte_size = _array_size * _element_type->get_fixed_byte_size();
_has_fixed_structure = true;
} else {
// We only need to store the length bytes if the array has a
// variable size.
// We only need to store the length bytes if the array has a variable
// size.
_num_length_bytes = 2;
}
@ -63,20 +60,18 @@ DCArrayParameter(DCParameter *element_type, const DCUnsignedIntRange &size) :
DCSimpleParameter *simple_type = _element_type->as_simple_parameter();
if (simple_type != (DCSimpleParameter *)NULL) {
if (simple_type->get_type() == ST_char) {
// We make a special case for char[] arrays: these we format as
// a string. (It will still accept an array of ints packed into
// it.) We don't make this special case for uint8[] or int8[]
// arrays, although we will accept a string packed in for them.
// We make a special case for char[] arrays: these we format as a
// string. (It will still accept an array of ints packed into it.) We
// don't make this special case for uint8[] or int8[] arrays, although
// we will accept a string packed in for them.
_pack_type = PT_string;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCArrayParameter::
DCArrayParameter(const DCArrayParameter &copy) :
DCParameter(copy),
@ -86,91 +81,71 @@ DCArrayParameter(const DCArrayParameter &copy) :
{
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCArrayParameter::
~DCArrayParameter() {
delete _element_type;
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::as_array_parameter
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCArrayParameter *DCArrayParameter::
as_array_parameter() {
return this;
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::as_array_parameter
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
const DCArrayParameter *DCArrayParameter::
as_array_parameter() const {
return this;
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::make_copy
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCParameter *DCArrayParameter::
make_copy() const {
return new DCArrayParameter(*this);
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::is_valid
// Access: Published, Virtual
// Description: Returns false if the type is an invalid type
// (e.g. declared from an undefined typedef), true if
// it is valid.
////////////////////////////////////////////////////////////////////
/**
* Returns false if the type is an invalid type (e.g. declared from an
* undefined typedef), true if it is valid.
*/
bool DCArrayParameter::
is_valid() const {
return _element_type->is_valid();
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::get_element_type
// Access: Published
// Description: Returns the type of the individual elements of this
// array.
////////////////////////////////////////////////////////////////////
/**
* Returns the type of the individual elements of this array.
*/
DCParameter *DCArrayParameter::
get_element_type() const {
return _element_type;
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::get_array_size
// Access: Published
// Description: Returns the fixed number of elements in this array,
// or -1 if the array may contain a variable number of
// elements.
////////////////////////////////////////////////////////////////////
/**
* Returns the fixed number of elements in this array, or -1 if the array may
* contain a variable number of elements.
*/
int DCArrayParameter::
get_array_size() const {
return _array_size;
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::append_array_specification
// Access: Public, Virtual
// Description: Returns the type represented by this_type[size].
//
// In the case of a DCArrayParameter, this means it
// modifies the current type to append the array
// specification on the innermost type, and returns this
// same pointer again.
////////////////////////////////////////////////////////////////////
/**
* Returns the type represented by this_type[size].
*
* In the case of a DCArrayParameter, this means it modifies the current type
* to append the array specification on the innermost type, and returns this
* same pointer again.
*/
DCParameter *DCArrayParameter::
append_array_specification(const DCUnsignedIntRange &size) {
if (get_typedef() != (DCTypedef *)NULL) {
@ -183,16 +158,12 @@ append_array_specification(const DCUnsignedIntRange &size) {
return this;
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::calc_num_nested_fields
// Access: Public, Virtual
// Description: This flavor of get_num_nested_fields is used during
// unpacking. It returns the number of nested fields to
// expect, given a certain length in bytes (as read from
// the get_num_length_bytes() stored in the stream on the
// pack). This will only be called if
// get_num_length_bytes() returns nonzero.
////////////////////////////////////////////////////////////////////
/**
* This flavor of get_num_nested_fields is used during unpacking. It returns
* the number of nested fields to expect, given a certain length in bytes (as
* read from the get_num_length_bytes() stored in the stream on the pack).
* This will only be called if get_num_length_bytes() returns nonzero.
*/
int DCArrayParameter::
calc_num_nested_fields(size_t length_bytes) const {
if (_element_type->has_fixed_byte_size()) {
@ -201,43 +172,34 @@ calc_num_nested_fields(size_t length_bytes) const {
return -1;
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::get_nested_field
// Access: Public, Virtual
// Description: Returns the DCPackerInterface object that represents
// the nth nested field. This may return NULL if there
// is no such field (but it shouldn't do this if n is in
// the range 0 <= n < get_num_nested_fields()).
////////////////////////////////////////////////////////////////////
/**
* Returns the DCPackerInterface object that represents the nth nested field.
* This may return NULL if there is no such field (but it shouldn't do this if
* n is in the range 0 <= n < get_num_nested_fields()).
*/
DCPackerInterface *DCArrayParameter::
get_nested_field(int) const {
return _element_type;
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::validate_num_nested_fields
// Access: Public, Virtual
// Description: After a number of fields have been packed via push()
// .. pack_*() .. pop(), this is called to confirm that
// the number of nested fields that were added is valid
// for this type. This is primarily useful for array
// types with dynamic ranges that can't validate the
// number of fields any other way.
////////////////////////////////////////////////////////////////////
/**
* After a number of fields have been packed via push() .. pack_*() .. pop(),
* this is called to confirm that the number of nested fields that were added
* is valid for this type. This is primarily useful for array types with
* dynamic ranges that can't validate the number of fields any other way.
*/
bool DCArrayParameter::
validate_num_nested_fields(int num_nested_fields) const {
bool range_error = false;
_array_size_range.validate(num_nested_fields, range_error);
return !range_error;
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::output_instance
// Access: Public, Virtual
// Description: Formats the parameter in the C++-like dc syntax as a
// typename and identifier.
////////////////////////////////////////////////////////////////////
/**
* Formats the parameter in the C++-like dc syntax as a typename and
* identifier.
*/
void DCArrayParameter::
output_instance(ostream &out, bool brief, const string &prename,
const string &name, const string &postname) const {
@ -246,22 +208,19 @@ output_instance(ostream &out, bool brief, const string &prename,
} else {
ostringstream strm;
strm << "[";
_array_size_range.output(strm);
strm << "]";
_element_type->output_instance(out, brief, prename, name,
_element_type->output_instance(out, brief, prename, name,
postname + strm.str());
}
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::generate_hash
// Access: Public, Virtual
// Description: Accumulates the properties of this type into the
// hash.
////////////////////////////////////////////////////////////////////
/**
* Accumulates the properties of this type into the hash.
*/
void DCArrayParameter::
generate_hash(HashGenerator &hashgen) const {
DCParameter::generate_hash(hashgen);
@ -269,17 +228,13 @@ generate_hash(HashGenerator &hashgen) const {
_array_size_range.generate_hash(hashgen);
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::pack_string
// Access: Published, Virtual
// Description: Packs the indicated numeric or string value into the
// stream.
////////////////////////////////////////////////////////////////////
/**
* Packs the indicated numeric or string value into the stream.
*/
void DCArrayParameter::
pack_string(DCPackData &pack_data, const string &value,
bool &pack_error, bool &range_error) const {
// We can only pack a string if the array element type is char or
// int8.
// We can only pack a string if the array element type is char or int8.
DCSimpleParameter *simple_type = _element_type->as_simple_parameter();
if (simple_type == (DCSimpleParameter *)NULL) {
pack_error = true;
@ -305,27 +260,23 @@ pack_string(DCPackData &pack_data, const string &value,
}
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::pack_default_value
// Access: Public, Virtual
// Description: Packs the arrayParameter's specified default value (or a
// sensible default if no value is specified) into the
// stream. Returns true if the default value is packed,
// false if the arrayParameter doesn't know how to pack its
// default value.
////////////////////////////////////////////////////////////////////
/**
* Packs the arrayParameter's specified default value (or a sensible default
* if no value is specified) into the stream. Returns true if the default
* value is packed, false if the arrayParameter doesn't know how to pack its
* default value.
*/
bool DCArrayParameter::
pack_default_value(DCPackData &pack_data, bool &pack_error) const {
// We only want to call up if the DCField can pack the value
// immediately--we don't trust the DCField to generate the default
// value (since it doesn't know how large the minimum length array
// is).
// We only want to call up if the DCField can pack the value immediately--we
// don't trust the DCField to generate the default value (since it doesn't
// know how large the minimum length array is).
if (_has_default_value && !_default_value_stale) {
return DCField::pack_default_value(pack_data, pack_error);
}
// If a default value is not specified for a variable-length array,
// the default is the minimum array.
// If a default value is not specified for a variable-length array, the
// default is the minimum array.
unsigned int minimum_length = 0;
if (!_array_size_range.is_empty()) {
minimum_length = _array_size_range.get_min(0);
@ -347,17 +298,13 @@ pack_default_value(DCPackData &pack_data, bool &pack_error) const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::unpack_string
// Access: Public, Virtual
// Description: Unpacks the current numeric or string value from the
// stream.
////////////////////////////////////////////////////////////////////
/**
* Unpacks the current numeric or string value from the stream.
*/
void DCArrayParameter::
unpack_string(const char *data, size_t length, size_t &p, string &value,
bool &pack_error, bool &range_error) const {
// We can only unpack a string if the array element type is char or
// int8.
// We can only unpack a string if the array element type is char or int8.
DCSimpleParameter *simple_type = _element_type->as_simple_parameter();
if (simple_type == (DCSimpleParameter *)NULL) {
pack_error = true;
@ -390,47 +337,38 @@ unpack_string(const char *data, size_t length, size_t &p, string &value,
}
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::do_check_match
// Access: Protected, Virtual
// Description: Returns true if the other interface is bitwise the
// same as this one--that is, a uint32 only matches a
// uint32, etc. Names of components, and range limits,
// are not compared.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the other interface is bitwise the same as this one--that
* is, a uint32 only matches a uint32, etc. Names of components, and range
* limits, are not compared.
*/
bool DCArrayParameter::
do_check_match(const DCPackerInterface *other) const {
return other->do_check_match_array_parameter(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::do_check_match_simple_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// simple parameter, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if this field matches the indicated simple parameter, false
* otherwise.
*/
bool DCArrayParameter::
do_check_match_simple_parameter(const DCSimpleParameter *other) const {
return ((const DCPackerInterface *)other)->do_check_match_array_parameter(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::do_check_match_class_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// class parameter, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if this field matches the indicated class parameter, false
* otherwise.
*/
bool DCArrayParameter::
do_check_match_class_parameter(const DCClassParameter *other) const {
return ((const DCPackerInterface *)other)->do_check_match_array_parameter(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::do_check_match_array_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// array parameter, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if this field matches the indicated array parameter, false
* otherwise.
*/
bool DCArrayParameter::
do_check_match_array_parameter(const DCArrayParameter *other) const {
if (_array_size != other->_array_size) {

View File

@ -1,16 +1,15 @@
// Filename: dcArrayParameter.h
// Created by: drose (17Jun04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcArrayParameter.h
* @author drose
* @date 2004-06-17
*/
#ifndef DCARRAYPARAMETER_H
#define DCARRAYPARAMETER_H
@ -19,16 +18,14 @@
#include "dcParameter.h"
#include "dcNumericRange.h"
////////////////////////////////////////////////////////////////////
// Class : DCArrayParameter
// Description : This represents an array of some other kind of
// object, meaning this parameter type accepts an
// arbitrary (or possibly fixed) number of nested
// fields, all of which are of the same type.
////////////////////////////////////////////////////////////////////
/**
* This represents an array of some other kind of object, meaning this
* parameter type accepts an arbitrary (or possibly fixed) number of nested
* fields, all of which are of the same type.
*/
class EXPCL_DIRECT DCArrayParameter : public DCParameter {
public:
DCArrayParameter(DCParameter *element_type,
DCArrayParameter(DCParameter *element_type,
const DCUnsignedIntRange &size = DCUnsignedIntRange());
DCArrayParameter(const DCArrayParameter &copy);
virtual ~DCArrayParameter();
@ -49,13 +46,13 @@ public:
virtual DCPackerInterface *get_nested_field(int n) const;
virtual bool validate_num_nested_fields(int num_nested_fields) const;
virtual void output_instance(ostream &out, bool brief, const string &prename,
virtual void output_instance(ostream &out, bool brief, const string &prename,
const string &name, const string &postname) const;
virtual void generate_hash(HashGenerator &hashgen) const;
virtual void pack_string(DCPackData &pack_data, const string &value,
bool &pack_error, bool &range_error) const;
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
virtual void unpack_string(const char *data, size_t length, size_t &p,
virtual void unpack_string(const char *data, size_t length, size_t &p,
string &value, bool &pack_error, bool &range_error) const;
protected:

View File

@ -1,14 +1,12 @@
// Filename: dcAtomicField.I
// Created by: drose (15Aug06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcAtomicField.I
* @author drose
* @date 2006-08-15
*/

View File

@ -1,16 +1,15 @@
// Filename: dcAtomicField.cxx
// Created by: drose (05Oct00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcAtomicField.cxx
* @author drose
* @date 2000-10-05
*/
#include "dcAtomicField.h"
#include "hashGenerator.h"
@ -20,139 +19,110 @@
#include <math.h>
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCAtomicField::
DCAtomicField(const string &name, DCClass *dclass,
bool bogus_field) :
bool bogus_field) :
DCField(name, dclass)
{
_bogus_field = bogus_field;
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCAtomicField::
~DCAtomicField() {
Elements::iterator ei;
Elements::iterator ei;
for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
delete (*ei);
}
_elements.clear();
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::as_atomic_field
// Access: Published, Virtual
// Description: Returns the same field pointer converted to an atomic
// field pointer, if this is in fact an atomic field;
// otherwise, returns NULL.
////////////////////////////////////////////////////////////////////
/**
* Returns the same field pointer converted to an atomic field pointer, if
* this is in fact an atomic field; otherwise, returns NULL.
*/
DCAtomicField *DCAtomicField::
as_atomic_field() {
return this;
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::as_atomic_field
// Access: Published, Virtual
// Description: Returns the same field pointer converted to an atomic
// field pointer, if this is in fact an atomic field;
// otherwise, returns NULL.
////////////////////////////////////////////////////////////////////
/**
* Returns the same field pointer converted to an atomic field pointer, if
* this is in fact an atomic field; otherwise, returns NULL.
*/
const DCAtomicField *DCAtomicField::
as_atomic_field() const {
return this;
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::get_num_elements
// Access: Published
// Description: Returns the number of elements (parameters) of the
// atomic field.
////////////////////////////////////////////////////////////////////
/**
* Returns the number of elements (parameters) of the atomic field.
*/
int DCAtomicField::
get_num_elements() const {
return _elements.size();
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::get_element
// Access: Published
// Description: Returns the parameter object describing the
// nth element.
////////////////////////////////////////////////////////////////////
/**
* Returns the parameter object describing the nth element.
*/
DCParameter *DCAtomicField::
get_element(int n) const {
nassertr(n >= 0 && n < (int)_elements.size(), NULL);
return _elements[n];
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::get_element_default
// Access: Published
// Description: Returns the pre-formatted default value associated
// with the nth element of the field. This is only
// valid if has_element_default() returns true, in which
// case this string represents the bytes that should be
// assigned to the field as a default value.
//
// If the element is an array-type element, the returned
// value will include the two-byte length preceding the
// array data.
//
// This is deprecated; use get_element() instead.
////////////////////////////////////////////////////////////////////
/**
* Returns the pre-formatted default value associated with the nth element of
* the field. This is only valid if has_element_default() returns true, in
* which case this string represents the bytes that should be assigned to the
* field as a default value.
*
* If the element is an array-type element, the returned value will include
* the two-byte length preceding the array data.
*
* This is deprecated; use get_element() instead.
*/
string DCAtomicField::
get_element_default(int n) const {
nassertr(n >= 0 && n < (int)_elements.size(), string());
return _elements[n]->get_default_value();
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::has_element_default
// Access: Published
// Description: Returns true if the nth element of the field has a
// default value specified, false otherwise.
//
// This is deprecated; use get_element() instead.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the nth element of the field has a default value specified,
* false otherwise.
*
* This is deprecated; use get_element() instead.
*/
bool DCAtomicField::
has_element_default(int n) const {
nassertr(n >= 0 && n < (int)_elements.size(), false);
return _elements[n]->has_default_value();
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::get_element_name
// Access: Published
// Description: Returns the name of the nth element of the field.
// This name is strictly for documentary purposes; it
// does not generally affect operation. If a name is
// not specified, this will be the empty string.
//
// This method is deprecated; use
// get_element()->get_name() instead.
////////////////////////////////////////////////////////////////////
/**
* Returns the name of the nth element of the field. This name is strictly
* for documentary purposes; it does not generally affect operation. If a
* name is not specified, this will be the empty string.
*
* This method is deprecated; use get_element()->get_name() instead.
*/
string DCAtomicField::
get_element_name(int n) const {
nassertr(n >= 0 && n < (int)_elements.size(), string());
return _elements[n]->get_name();
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::get_element_type
// Access: Published
// Description: Returns the numeric type of the nth element of the
// field. This method is deprecated; use
// get_element() instead.
////////////////////////////////////////////////////////////////////
/**
* Returns the numeric type of the nth element of the field. This method is
* deprecated; use get_element() instead.
*/
DCSubatomicType DCAtomicField::
get_element_type(int n) const {
nassertr(n >= 0 && n < (int)_elements.size(), ST_invalid);
@ -161,18 +131,14 @@ get_element_type(int n) const {
return simple_parameter->get_type();
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::get_element_divisor
// Access: Published
// Description: Returns the divisor associated with the nth element
// of the field. This implements an implicit
// fixed-point system; floating-point values are to be
// multiplied by this value before encoding into a
// packet, and divided by this number after decoding.
//
// This method is deprecated; use
// get_element()->get_divisor() instead.
////////////////////////////////////////////////////////////////////
/**
* Returns the divisor associated with the nth element of the field. This
* implements an implicit fixed-point system; floating-point values are to be
* multiplied by this value before encoding into a packet, and divided by this
* number after decoding.
*
* This method is deprecated; use get_element()->get_divisor() instead.
*/
int DCAtomicField::
get_element_divisor(int n) const {
nassertr(n >= 0 && n < (int)_elements.size(), 1);
@ -181,11 +147,9 @@ get_element_divisor(int n) const {
return simple_parameter->get_divisor();
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
void DCAtomicField::
output(ostream &out, bool brief) const {
out << _name << "(";
@ -205,12 +169,10 @@ output(ostream &out, bool brief) const {
output_keywords(out);
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::write
// Access: Public, Virtual
// Description: Generates a parseable description of the object to
// the indicated output stream.
////////////////////////////////////////////////////////////////////
/**
* Generates a parseable description of the object to the indicated output
* stream.
*/
void DCAtomicField::
write(ostream &out, bool brief, int indent_level) const {
indent(out, indent_level);
@ -222,12 +184,9 @@ write(ostream &out, bool brief, int indent_level) const {
out << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::generate_hash
// Access: Public, Virtual
// Description: Accumulates the properties of this field into the
// hash.
////////////////////////////////////////////////////////////////////
/**
* Accumulates the properties of this field into the hash.
*/
void DCAtomicField::
generate_hash(HashGenerator &hashgen) const {
DCField::generate_hash(hashgen);
@ -241,28 +200,22 @@ generate_hash(HashGenerator &hashgen) const {
DCKeywordList::generate_hash(hashgen);
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::get_nested_field
// Access: Public, Virtual
// Description: Returns the DCPackerInterface object that represents
// the nth nested field. This may return NULL if there
// is no such field (but it shouldn't do this if n is in
// the range 0 <= n < get_num_nested_fields()).
////////////////////////////////////////////////////////////////////
/**
* Returns the DCPackerInterface object that represents the nth nested field.
* This may return NULL if there is no such field (but it shouldn't do this if
* n is in the range 0 <= n < get_num_nested_fields()).
*/
DCPackerInterface *DCAtomicField::
get_nested_field(int n) const {
nassertr(n >= 0 && n < (int)_elements.size(), NULL);
return _elements[n];
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::add_element
// Access: Public
// Description: Adds a new element (parameter) to the field.
// Normally this is called only during parsing. The
// DCAtomicField object becomes the owner of the new
// pointer and will delete it upon destruction.
////////////////////////////////////////////////////////////////////
/**
* Adds a new element (parameter) to the field. Normally this is called only
* during parsing. The DCAtomicField object becomes the owner of the new
* pointer and will delete it upon destruction.
*/
void DCAtomicField::
add_element(DCParameter *element) {
_elements.push_back(element);
@ -285,25 +238,20 @@ add_element(DCParameter *element) {
_default_value_stale = true;
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::do_check_match
// Access: Protected, Virtual
// Description: Returns true if the other interface is bitwise the
// same as this one--that is, a uint32 only matches a
// uint32, etc. Names of components, and range limits,
// are not compared.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the other interface is bitwise the same as this one--that
* is, a uint32 only matches a uint32, etc. Names of components, and range
* limits, are not compared.
*/
bool DCAtomicField::
do_check_match(const DCPackerInterface *other) const {
return other->do_check_match_atomic_field(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::do_check_match_atomic_field
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// atomic field, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if this field matches the indicated atomic field, false
* otherwise.
*/
bool DCAtomicField::
do_check_match_atomic_field(const DCAtomicField *other) const {
if (_elements.size() != other->_elements.size()) {
@ -318,11 +266,9 @@ do_check_match_atomic_field(const DCAtomicField *other) const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::output_element
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
void DCAtomicField::
output_element(ostream &out, bool brief, DCParameter *element) const {
element->output(out, brief);

View File

@ -1,16 +1,15 @@
// Filename: dcAtomicField.h
// Created by: drose (05Oct00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcAtomicField.h
* @author drose
* @date 2000-10-05
*/
#ifndef DCATOMICFIELD_H
#define DCATOMICFIELD_H
@ -20,17 +19,14 @@
#include "dcSubatomicType.h"
#include "dcParameter.h"
// Must use math.h instead of cmath.h so this can compile outside of
// Panda.
// Must use math.h instead of cmath.h so this can compile outside of Panda.
#include <math.h>
////////////////////////////////////////////////////////////////////
// Class : DCAtomicField
// Description : A single atomic field of a Distributed Class, as read
// from a .dc file. This defines an interface to the
// Distributed Class, and is always implemented as a
// remote procedure method.
////////////////////////////////////////////////////////////////////
/**
* A single atomic field of a Distributed Class, as read from a .dc file.
* This defines an interface to the Distributed Class, and is always
* implemented as a remote procedure method.
*/
class EXPCL_DIRECT DCAtomicField : public DCField {
public:
DCAtomicField(const string &name, DCClass *dclass, bool bogus_field);

View File

@ -1,87 +1,68 @@
// Filename: dcClass.I
// Created by: drose (15Sep04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcClass.I
* @author drose
* @date 2004-09-15
*/
////////////////////////////////////////////////////////////////////
// Function: DCClass::get_dc_file
// Access: Published
// Description: Returns the DCFile object that contains the class.
////////////////////////////////////////////////////////////////////
/**
* Returns the DCFile object that contains the class.
*/
INLINE DCFile *DCClass::
get_dc_file() const {
return _dc_file;
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::get_name
// Access: Published
// Description: Returns the name of this class.
////////////////////////////////////////////////////////////////////
/**
* Returns the name of this class.
*/
INLINE const string &DCClass::
get_name() const {
return _name;
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::get_number
// Access: Published
// Description: Returns a unique index number associated with this
// class. This is defined implicitly when the .dc
// file(s) are read.
////////////////////////////////////////////////////////////////////
/**
* Returns a unique index number associated with this class. This is defined
* implicitly when the .dc file(s) are read.
*/
INLINE int DCClass::
get_number() const {
return _number;
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::is_struct
// Access: Published
// Description: Returns true if the class has been identified with
// the "struct" keyword in the dc file, false if it was
// declared with "dclass".
////////////////////////////////////////////////////////////////////
/**
* Returns true if the class has been identified with the "struct" keyword in
* the dc file, false if it was declared with "dclass".
*/
INLINE bool DCClass::
is_struct() const {
return _is_struct;
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::is_bogus_class
// Access: Published
// Description: Returns true if the class has been flagged as a bogus
// class. This is set for classes that are generated by
// the parser as placeholder for missing classes, as
// when reading a partial file; it should not occur in a
// normal valid dc file.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the class has been flagged as a bogus class. This is set
* for classes that are generated by the parser as placeholder for missing
* classes, as when reading a partial file; it should not occur in a normal
* valid dc file.
*/
INLINE bool DCClass::
is_bogus_class() const {
return _bogus_class;
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::start_generate
// Access: Published
// Description: Starts the PStats timer going on the "generate" task,
// that is, marks the beginning of the process of
// generating a new object, for the purposes of timing
// this process.
//
// This should balance with a corresponding call to
// stop_generate().
////////////////////////////////////////////////////////////////////
/**
* Starts the PStats timer going on the "generate" task, that is, marks the
* beginning of the process of generating a new object, for the purposes of
* timing this process.
*
* This should balance with a corresponding call to stop_generate().
*/
INLINE void DCClass::
start_generate() {
#ifdef WITHIN_PANDA
@ -89,13 +70,10 @@ start_generate() {
#endif
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::stop_generate
// Access: Published
// Description: Stops the PStats timer on the "generate" task.
// This should balance with a preceding call to
// start_generate().
////////////////////////////////////////////////////////////////////
/**
* Stops the PStats timer on the "generate" task. This should balance with a
* preceding call to start_generate().
*/
INLINE void DCClass::
stop_generate() {
#ifdef WITHIN_PANDA

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,15 @@
// Filename: dcClass.h
// Created by: drose (05Oct00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcClass.h
* @author drose
* @date 2000-10-05
*/
#ifndef DCCLASS_H
#define DCCLASS_H
@ -39,14 +38,12 @@ static const bool dc_sort_inheritance_by_file = false;
class HashGenerator;
class DCParameter;
////////////////////////////////////////////////////////////////////
// Class : DCClass
// Description : Defines a particular DistributedClass as read from an
// input .dc file.
////////////////////////////////////////////////////////////////////
/**
* Defines a particular DistributedClass as read from an input .dc file.
*/
class EXPCL_DIRECT DCClass : public DCDeclaration {
public:
DCClass(DCFile *dc_file, const string &name,
DCClass(DCFile *dc_file, const string &name,
bool is_struct, bool bogus_class);
~DCClass();
@ -61,7 +58,7 @@ PUBLISHED:
int get_num_parents() const;
DCClass *get_parent(int n) const;
bool has_constructor() const;
DCField *get_constructor() const;
@ -82,7 +79,7 @@ PUBLISHED:
INLINE void stop_generate();
virtual void output(ostream &out) const;
#ifdef HAVE_PYTHON
bool has_class_def() const;
void set_class_def(PyObject *class_def);
@ -97,27 +94,27 @@ PUBLISHED:
void receive_update_all_required(PyObject *distobj, DatagramIterator &di) const;
void receive_update_other(PyObject *distobj, DatagramIterator &di) const;
void direct_update(PyObject *distobj, const string &field_name,
void direct_update(PyObject *distobj, const string &field_name,
const string &value_blob);
void direct_update(PyObject *distobj, const string &field_name,
void direct_update(PyObject *distobj, const string &field_name,
const Datagram &datagram);
bool pack_required_field(Datagram &datagram, PyObject *distobj,
bool pack_required_field(Datagram &datagram, PyObject *distobj,
const DCField *field) const;
bool pack_required_field(DCPacker &packer, PyObject *distobj,
bool pack_required_field(DCPacker &packer, PyObject *distobj,
const DCField *field) const;
Datagram client_format_update(const string &field_name,
DOID_TYPE do_id, PyObject *args) const;
Datagram ai_format_update(const string &field_name, DOID_TYPE do_id,
Datagram ai_format_update(const string &field_name, DOID_TYPE do_id,
CHANNEL_TYPE to_id, CHANNEL_TYPE from_id, PyObject *args) const;
Datagram ai_format_update_msg_type(const string &field_name, DOID_TYPE do_id,
Datagram ai_format_update_msg_type(const string &field_name, DOID_TYPE do_id,
CHANNEL_TYPE to_id, CHANNEL_TYPE from_id, int msg_type, PyObject *args) const;
Datagram ai_format_generate(PyObject *distobj, DOID_TYPE do_id, ZONEID_TYPE parent_id, ZONEID_TYPE zone_id,
CHANNEL_TYPE district_channel_id, CHANNEL_TYPE from_channel_id,
PyObject *optional_fields) const;
Datagram client_format_generate_CMU(PyObject *distobj, DOID_TYPE do_id,
Datagram client_format_generate_CMU(PyObject *distobj, DOID_TYPE do_id,
ZONEID_TYPE zone_id, PyObject *optional_fields) const;
#endif
@ -125,7 +122,7 @@ PUBLISHED:
public:
virtual void output(ostream &out, bool brief) const;
virtual void write(ostream &out, bool brief, int indent_level) const;
void output_instance(ostream &out, bool brief, const string &prename,
void output_instance(ostream &out, bool brief, const string &prename,
const string &name, const string &postname) const;
void generate_hash(HashGenerator &hashgen) const;
void clear_inherited_fields();

View File

@ -1,27 +1,24 @@
// Filename: dcClassParameter.cxx
// Created by: drose (18Jun04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcClassParameter.cxx
* @author drose
* @date 2004-06-18
*/
#include "dcClassParameter.h"
#include "dcClass.h"
#include "dcArrayParameter.h"
#include "hashGenerator.h"
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCClassParameter::
DCClassParameter(const DCClass *dclass) :
_dclass(dclass)
@ -48,9 +45,8 @@ DCClassParameter(const DCClass *dclass) :
}
_num_nested_fields = _nested_fields.size();
// If all of the nested fields have a fixed byte size, then so does
// the class (and its byte size is the sum of all of the nested
// fields).
// If all of the nested fields have a fixed byte size, then so does the
// class (and its byte size is the sum of all of the nested fields).
_has_fixed_byte_size = true;
_fixed_byte_size = 0;
_has_fixed_structure = true;
@ -64,11 +60,9 @@ DCClassParameter(const DCClass *dclass) :
}
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCClassParameter::
DCClassParameter(const DCClassParameter &copy) :
DCParameter(copy),
@ -77,80 +71,64 @@ DCClassParameter(const DCClassParameter &copy) :
{
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::as_class_parameter
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCClassParameter *DCClassParameter::
as_class_parameter() {
return this;
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::as_class_parameter
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
const DCClassParameter *DCClassParameter::
as_class_parameter() const {
return this;
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::make_copy
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCParameter *DCClassParameter::
make_copy() const {
return new DCClassParameter(*this);
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::is_valid
// Access: Published, Virtual
// Description: Returns false if the type is an invalid type
// (e.g. declared from an undefined typedef), true if
// it is valid.
////////////////////////////////////////////////////////////////////
/**
* Returns false if the type is an invalid type (e.g. declared from an
* undefined typedef), true if it is valid.
*/
bool DCClassParameter::
is_valid() const {
return !_dclass->is_bogus_class();
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::get_class
// Access: Published
// Description: Returns the class object this parameter represents.
////////////////////////////////////////////////////////////////////
/**
* Returns the class object this parameter represents.
*/
const DCClass *DCClassParameter::
get_class() const {
return _dclass;
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::get_nested_field
// Access: Public, Virtual
// Description: Returns the DCPackerInterface object that represents
// the nth nested field. This may return NULL if there
// is no such field (but it shouldn't do this if n is in
// the range 0 <= n < get_num_nested_fields()).
////////////////////////////////////////////////////////////////////
/**
* Returns the DCPackerInterface object that represents the nth nested field.
* This may return NULL if there is no such field (but it shouldn't do this if
* n is in the range 0 <= n < get_num_nested_fields()).
*/
DCPackerInterface *DCClassParameter::
get_nested_field(int n) const {
nassertr(n >= 0 && n < (int)_nested_fields.size(), NULL);
return _nested_fields[n];
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::output_instance
// Access: Public, Virtual
// Description: Formats the parameter in the C++-like dc syntax as a
// typename and identifier.
////////////////////////////////////////////////////////////////////
/**
* Formats the parameter in the C++-like dc syntax as a typename and
* identifier.
*/
void DCClassParameter::
output_instance(ostream &out, bool brief, const string &prename,
output_instance(ostream &out, bool brief, const string &prename,
const string &name, const string &postname) const {
if (get_typedef() != (DCTypedef *)NULL) {
output_typedef_name(out, brief, prename, name, postname);
@ -160,37 +138,29 @@ output_instance(ostream &out, bool brief, const string &prename,
}
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::generate_hash
// Access: Public, Virtual
// Description: Accumulates the properties of this type into the
// hash.
////////////////////////////////////////////////////////////////////
/**
* Accumulates the properties of this type into the hash.
*/
void DCClassParameter::
generate_hash(HashGenerator &hashgen) const {
DCParameter::generate_hash(hashgen);
_dclass->generate_hash(hashgen);
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::do_check_match
// Access: Protected, Virtual
// Description: Returns true if the other interface is bitwise the
// same as this one--that is, a uint32 only matches a
// uint32, etc. Names of components, and range limits,
// are not compared.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the other interface is bitwise the same as this one--that
* is, a uint32 only matches a uint32, etc. Names of components, and range
* limits, are not compared.
*/
bool DCClassParameter::
do_check_match(const DCPackerInterface *other) const {
return other->do_check_match_class_parameter(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::do_check_match_class_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// class parameter, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if this field matches the indicated class parameter, false
* otherwise.
*/
bool DCClassParameter::
do_check_match_class_parameter(const DCClassParameter *other) const {
if (_nested_fields.size() != other->_nested_fields.size()) {
@ -205,17 +175,15 @@ do_check_match_class_parameter(const DCClassParameter *other) const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::do_check_match_array_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// array parameter, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if this field matches the indicated array parameter, false
* otherwise.
*/
bool DCClassParameter::
do_check_match_array_parameter(const DCArrayParameter *other) const {
if ((int)_nested_fields.size() != other->get_array_size()) {
// We can only match a fixed-size array whose size happens to
// exactly match our number of fields.
// We can only match a fixed-size array whose size happens to exactly
// match our number of fields.
return false;
}

View File

@ -1,16 +1,15 @@
// Filename: dcClassParameter.h
// Created by: drose (18Jun04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcClassParameter.h
* @author drose
* @date 2004-06-18
*/
#ifndef DCCLASSPARAMETER_H
#define DCCLASSPARAMETER_H
@ -20,12 +19,10 @@
class DCClass;
////////////////////////////////////////////////////////////////////
// Class : DCClassParameter
// Description : This represents a class (or struct) object used as a
// parameter itself. This means that all the fields of
// the class get packed into the message.
////////////////////////////////////////////////////////////////////
/**
* This represents a class (or struct) object used as a parameter itself.
* This means that all the fields of the class get packed into the message.
*/
class EXPCL_DIRECT DCClassParameter : public DCParameter {
public:
DCClassParameter(const DCClass *dclass);
@ -42,7 +39,7 @@ PUBLISHED:
public:
virtual DCPackerInterface *get_nested_field(int n) const;
virtual void output_instance(ostream &out, bool brief, const string &prename,
virtual void output_instance(ostream &out, bool brief, const string &prename,
const string &name, const string &postname) const;
virtual void generate_hash(HashGenerator &hashgen) const;

View File

@ -1,86 +1,69 @@
// Filename: dcDeclaration.cxx
// Created by: drose (18Jun04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcDeclaration.cxx
* @author drose
* @date 2004-06-18
*/
#include "dcDeclaration.h"
////////////////////////////////////////////////////////////////////
// Function: DCDeclaration::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCDeclaration::
~DCDeclaration() {
}
////////////////////////////////////////////////////////////////////
// Function: DCDeclaration::as_class
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCClass *DCDeclaration::
as_class() {
return (DCClass *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCDeclaration::as_class
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
const DCClass *DCDeclaration::
as_class() const {
return (DCClass *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCDeclaration::as_switch
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCSwitch *DCDeclaration::
as_switch() {
return (DCSwitch *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCDeclaration::as_switch
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
const DCSwitch *DCDeclaration::
as_switch() const {
return (DCSwitch *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function : DCDeclaration::output
// Access : Published, Virtual
// Description : Write a string representation of this instance to
// <out>.
////////////////////////////////////////////////////////////////////
/**
* Write a string representation of this instance to <out>.
*/
void DCDeclaration::
output(ostream &out) const {
output(out, true);
}
////////////////////////////////////////////////////////////////////
// Function : DCDeclaration::
// Access : Published
// Description : Write a string representation of this instance to
// <out>.
////////////////////////////////////////////////////////////////////
/**
* Write a string representation of this instance to <out>.
*/
void DCDeclaration::
write(ostream &out, int indent_level) const {
write(out, false, indent_level);

View File

@ -1,16 +1,15 @@
// Filename: dcDeclaration.h
// Created by: drose (18Jun04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcDeclaration.h
* @author drose
* @date 2004-06-18
*/
#ifndef DCDECLARATION_H
#define DCDECLARATION_H
@ -20,16 +19,13 @@
class DCClass;
class DCSwitch;
////////////////////////////////////////////////////////////////////
// Class : DCDeclaration
// Description : This is a common interface for a declaration in a DC
// file. Currently, this is either a class or a typedef
// declaration (import declarations are still collected
// together at the top, and don't inherit from this
// object). Its only purpose is so that classes and
// typedefs can be stored in one list together so they
// can be ordered correctly on output.
////////////////////////////////////////////////////////////////////
/**
* This is a common interface for a declaration in a DC file. Currently, this
* is either a class or a typedef declaration (import declarations are still
* collected together at the top, and don't inherit from this object). Its
* only purpose is so that classes and typedefs can be stored in one list
* together so they can be ordered correctly on output.
*/
class EXPCL_DIRECT DCDeclaration {
public:
virtual ~DCDeclaration();
@ -54,4 +50,3 @@ INLINE ostream &operator << (ostream &out, const DCDeclaration &decl) {
}
#endif

View File

@ -1,61 +1,47 @@
// Filename: dcField.I
// Created by: drose (10Jan06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcField.I
* @author drose
* @date 2006-01-10
*/
////////////////////////////////////////////////////////////////////
// Function: DCField::get_number
// Access: Published
// Description: Returns a unique index number associated with this
// field. This is defined implicitly when the .dc
// file(s) are read.
////////////////////////////////////////////////////////////////////
/**
* Returns a unique index number associated with this field. This is defined
* implicitly when the .dc file(s) are read.
*/
INLINE int DCField::
get_number() const {
return _number;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::get_class
// Access: Published
// Description: Returns the DCClass pointer for the class that
// contains this field.
////////////////////////////////////////////////////////////////////
/**
* Returns the DCClass pointer for the class that contains this field.
*/
INLINE DCClass *DCField::
get_class() const {
return _dclass;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::has_default_value
// Access: Published
// Description: Returns true if a default value has been explicitly
// established for this field, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if a default value has been explicitly established for this
* field, false otherwise.
*/
INLINE bool DCField::
has_default_value() const {
return _has_default_value;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::get_default_value
// Access: Published
// Description: Returns the default value for this field. If a
// default value has been explicitly set
// (e.g. has_default_value() returns true), returns that
// value; otherwise, returns an implicit default for the
// field.
////////////////////////////////////////////////////////////////////
/**
* Returns the default value for this field. If a default value has been
* explicitly set (e.g. has_default_value() returns true), returns that
* value; otherwise, returns an implicit default for the field.
*/
INLINE const string &DCField::
get_default_value() const {
if (_default_value_stale) {
@ -64,170 +50,127 @@ get_default_value() const {
return _default_value;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_bogus_field
// Access: Published
// Description: Returns true if the field has been flagged as a bogus
// field. This is set for fields that are generated by
// the parser as placeholder for missing fields, as
// when reading a partial file; it should not occur in a
// normal valid dc file.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the field has been flagged as a bogus field. This is set
* for fields that are generated by the parser as placeholder for missing
* fields, as when reading a partial file; it should not occur in a normal
* valid dc file.
*/
INLINE bool DCField::
is_bogus_field() const {
return _bogus_field;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_required
// Access: Published
// Description: Returns true if the "required" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the "required" flag is set for this field, false otherwise.
*/
INLINE bool DCField::
is_required() const {
return has_keyword("required");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_broadcast
// Access: Published
// Description: Returns true if the "broadcast" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the "broadcast" flag is set for this field, false
* otherwise.
*/
INLINE bool DCField::
is_broadcast() const {
return has_keyword("broadcast");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_ram
// Access: Published
// Description: Returns true if the "ram" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the "ram" flag is set for this field, false otherwise.
*/
INLINE bool DCField::
is_ram() const {
return has_keyword("ram");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_db
// Access: Published
// Description: Returns true if the "db" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the "db" flag is set for this field, false otherwise.
*/
INLINE bool DCField::
is_db() const {
return has_keyword("db");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_clsend
// Access: Published
// Description: Returns true if the "clsend" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the "clsend" flag is set for this field, false otherwise.
*/
INLINE bool DCField::
is_clsend() const {
return has_keyword("clsend");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_clrecv
// Access: Published
// Description: Returns true if the "clrecv" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the "clrecv" flag is set for this field, false otherwise.
*/
INLINE bool DCField::
is_clrecv() const {
return has_keyword("clrecv");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_ownsend
// Access: Published
// Description: Returns true if the "ownsend" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the "ownsend" flag is set for this field, false otherwise.
*/
INLINE bool DCField::
is_ownsend() const {
return has_keyword("ownsend");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_ownrecv
// Access: Published
// Description: Returns true if the "ownrecv" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the "ownrecv" flag is set for this field, false otherwise.
*/
INLINE bool DCField::
is_ownrecv() const {
return has_keyword("ownrecv");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_airecv
// Access: Published
// Description: Returns true if the "airecv" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Returns true if the "airecv" flag is set for this field, false otherwise.
*/
INLINE bool DCField::
is_airecv() const {
return has_keyword("airecv");
}
////////////////////////////////////////////////////////////////////
// Function : DCField::output
// Access : Published
// Description : Write a string representation of this instance to
// <out>.
////////////////////////////////////////////////////////////////////
/**
* Write a string representation of this instance to <out>.
*/
INLINE void DCField::
output(ostream &out) const {
output(out, true);
}
////////////////////////////////////////////////////////////////////
// Function : DCField::
// Access : Published
// Description : Write a string representation of this instance to
// <out>.
////////////////////////////////////////////////////////////////////
/**
* Write a string representation of this instance to <out>.
*/
INLINE void DCField::
write(ostream &out, int indent_level) const {
write(out, false, indent_level);
}
////////////////////////////////////////////////////////////////////
// Function: DCField::set_number
// Access: Public
// Description: Assigns the unique number to this field. This is
// normally called only by the DCClass interface as the
// field is added.
////////////////////////////////////////////////////////////////////
/**
* Assigns the unique number to this field. This is normally called only by
* the DCClass interface as the field is added.
*/
INLINE void DCField::
set_number(int number) {
_number = number;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::set_class
// Access: Public
// Description: Assigns the class pointer to this field. This is
// normally called only by the DCClass interface as the
// field is added.
////////////////////////////////////////////////////////////////////
/**
* Assigns the class pointer to this field. This is normally called only by
* the DCClass interface as the field is added.
*/
INLINE void DCField::
set_class(DCClass *dclass) {
_dclass = dclass;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::set_default_value
// Access: Public
// Description: Establishes a default value for this field.
////////////////////////////////////////////////////////////////////
/**
* Establishes a default value for this field.
*/
INLINE void DCField::
set_default_value(const string &default_value) {
_default_value = default_value;

View File

@ -1,16 +1,15 @@
// Filename: dcField.cxx
// Created by: drose (11Oct00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dcField.cxx
* @author drose
* @date 2000-10-11
*/
#include "dcField.h"
#include "dcFile.h"
@ -19,17 +18,19 @@
#include "hashGenerator.h"
#include "dcmsgtypes.h"
#ifdef HAVE_PYTHON
#include "py_panda.h"
#endif
#ifdef WITHIN_PANDA
#include "pStatTimer.h"
#endif
////////////////////////////////////////////////////////////////////
// Function: DCField::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCField::
DCField() :
DCField() :
_dclass(NULL)
#ifdef WITHIN_PANDA
,
@ -51,13 +52,11 @@ DCField() :
_has_fixed_structure = true;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCField::
DCField(const string &name, DCClass *dclass) :
DCField(const string &name, DCClass *dclass) :
DCPackerInterface(name),
_dclass(dclass)
#ifdef WITHIN_PANDA
@ -80,110 +79,86 @@ DCField(const string &name, DCClass *dclass) :
_has_fixed_structure = true;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCField::
~DCField() {
}
////////////////////////////////////////////////////////////////////
// Function: DCField::as_field
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCField *DCField::
as_field() {
return this;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::as_field
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
const DCField *DCField::
as_field() const {
return this;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::as_atomic_field
// Access: Published, Virtual
// Description: Returns the same field pointer converted to an atomic
// field pointer, if this is in fact an atomic field;
// otherwise, returns NULL.
////////////////////////////////////////////////////////////////////
/**
* Returns the same field pointer converted to an atomic field pointer, if
* this is in fact an atomic field; otherwise, returns NULL.
*/
DCAtomicField *DCField::
as_atomic_field() {
return (DCAtomicField *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::as_atomic_field
// Access: Published, Virtual
// Description: Returns the same field pointer converted to an atomic
// field pointer, if this is in fact an atomic field;
// otherwise, returns NULL.
////////////////////////////////////////////////////////////////////
/**
* Returns the same field pointer converted to an atomic field pointer, if
* this is in fact an atomic field; otherwise, returns NULL.
*/
const DCAtomicField *DCField::
as_atomic_field() const {
return (DCAtomicField *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::as_molecular_field
// Access: Published, Virtual
// Description: Returns the same field pointer converted to a
// molecular field pointer, if this is in fact a
// molecular field; otherwise, returns NULL.
////////////////////////////////////////////////////////////////////
/**
* Returns the same field pointer converted to a molecular field pointer, if
* this is in fact a molecular field; otherwise, returns NULL.
*/
DCMolecularField *DCField::
as_molecular_field() {
return (DCMolecularField *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::as_molecular_field
// Access: Published, Virtual
// Description: Returns the same field pointer converted to a
// molecular field pointer, if this is in fact a
// molecular field; otherwise, returns NULL.
////////////////////////////////////////////////////////////////////
/**
* Returns the same field pointer converted to a molecular field pointer, if
* this is in fact a molecular field; otherwise, returns NULL.
*/
const DCMolecularField *DCField::
as_molecular_field() const {
return (DCMolecularField *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::as_parameter
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
DCParameter *DCField::
as_parameter() {
return (DCParameter *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::as_parameter
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
/**
*
*/
const DCParameter *DCField::
as_parameter() const {
return (DCParameter *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::format_data
// Access: Published
// Description: Given a blob that represents the packed data for this
// field, returns a string formatting it for human
// consumption. Returns empty string if there is an error.
////////////////////////////////////////////////////////////////////
/**
* Given a blob that represents the packed data for this field, returns a
* string formatting it for human consumption. Returns empty string if there
* is an error.
*/
string DCField::
format_data(const string &packed_data, bool show_field_names) {
DCPacker packer;
@ -196,15 +171,11 @@ format_data(const string &packed_data, bool show_field_names) {
return result;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::parse_string
// Access: Published
// Description: Given a human-formatted string (for instance, as
// returned by format_data(), above) that represents the
// value of this field, parse the string and return the
// corresponding packed data. Returns empty string if
// there is an error.
////////////////////////////////////////////////////////////////////
/**
* Given a human-formatted string (for instance, as returned by format_data(),
* above) that represents the value of this field, parse the string and return
* the corresponding packed data. Returns empty string if there is an error.
*/
string DCField::
parse_string(const string &formatted_string) {
DCPacker packer;
@ -221,14 +192,11 @@ parse_string(const string &formatted_string) {
return packer.get_string();
}
////////////////////////////////////////////////////////////////////
// Function: DCField::validate_ranges
// Access: Published
// Description: Verifies that all of the packed values in the field
// data are within the specified ranges and that there
// are no extra bytes on the end of the record. Returns
// true if all fields are valid, false otherwise.
////////////////////////////////////////////////////////////////////
/**
* Verifies that all of the packed values in the field data are within the
* specified ranges and that there are no extra bytes on the end of the
* record. Returns true if all fields are valid, false otherwise.
*/
bool DCField::
validate_ranges(const string &packed_data) const {
DCPacker packer;
@ -243,16 +211,12 @@ validate_ranges(const string &packed_data) const {
}
#ifdef HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: DCField::pack_args
// Access: Published
// Description: Packs the Python arguments from the indicated tuple
// into the packer. Returns true on success, false on
// failure.
//
// It is assumed that the packer is currently positioned
// on this field.
////////////////////////////////////////////////////////////////////
/**
* Packs the Python arguments from the indicated tuple into the packer.
* Returns true on success, false on failure.
*
* It is assumed that the packer is currently positioned on this field.
*/
bool DCField::
pack_args(DCPacker &packer, PyObject *sequence) const {
nassertr(!packer.had_error(), false);
@ -285,8 +249,7 @@ pack_args(DCPacker &packer, PyObject *sequence) const {
}
} else {
// If it's a molecular or atomic field, the value should be a
// sequence.
// If it's a molecular or atomic field, the value should be a sequence.
PyObject *tuple = PySequence_Tuple(sequence);
if (tuple == (PyObject *)NULL) {
strm << "Value for " << get_name() << " not a sequence: " \
@ -303,7 +266,7 @@ pack_args(DCPacker &packer, PyObject *sequence) const {
<< get_pystr(sequence);
exc_type = PyExc_ValueError;
}
Py_DECREF(tuple);
}
}
@ -316,16 +279,12 @@ pack_args(DCPacker &packer, PyObject *sequence) const {
#endif // HAVE_PYTHON
#ifdef HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: DCField::unpack_args
// Access: Published
// Description: Unpacks the values from the packer, beginning at
// the current point in the unpack_buffer, into a Python
// tuple and returns the tuple.
//
// It is assumed that the packer is currently positioned
// on this field.
////////////////////////////////////////////////////////////////////
/**
* Unpacks the values from the packer, beginning at the current point in the
* unpack_buffer, into a Python tuple and returns the tuple.
*
* It is assumed that the packer is currently positioned on this field.
*/
PyObject *DCField::
unpack_args(DCPacker &packer) const {
nassertr(!packer.had_error(), NULL);
@ -360,11 +319,11 @@ unpack_args(DCPacker &packer) const {
exc_type = PyExc_RuntimeError;
} else {
strm << "Value outside specified range when unpacking field "
strm << "Value outside specified range when unpacking field "
<< get_name() << ": " << get_pystr(object);
exc_type = PyExc_ValueError;
}
string message = strm.str();
PyErr_SetString(exc_type, message.c_str());
}
@ -375,18 +334,14 @@ unpack_args(DCPacker &packer) const {
#endif // HAVE_PYTHON
#ifdef HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: DCField::receive_update
// Access: Published
// Description: Extracts the update message out of the datagram and
// applies it to the indicated object by calling the
// appropriate method.
////////////////////////////////////////////////////////////////////
/**
* Extracts the update message out of the datagram and applies it to the
* indicated object by calling the appropriate method.
*/
void DCField::
receive_update(DCPacker &packer, PyObject *distobj) const {
if (as_parameter() != (DCParameter *)NULL) {
// If it's a parameter-type field, just store a new value on the
// object.
// If it's a parameter-type field, just store a new value on the object.
PyObject *value = unpack_args(packer);
if (value != (PyObject *)NULL) {
PyObject_SetAttrString(distobj, (char *)_name.c_str(), value);
@ -398,9 +353,8 @@ receive_update(DCPacker &packer, PyObject *distobj) const {
// corresponding method.
if (!PyObject_HasAttrString(distobj, (char *)_name.c_str())) {
// If there's no Python method to receive this message, don't
// bother unpacking it to a Python tuple--just skip past the
// message.
// If there's no Python method to receive this message, don't bother
// unpacking it to a Python tuple--just skip past the message.
packer.unpack_skip();
} else {
@ -411,7 +365,7 @@ receive_update(DCPacker &packer, PyObject *distobj) const {
if (args != (PyObject *)NULL) {
PyObject *func = PyObject_GetAttrString(distobj, (char *)_name.c_str());
nassertv(func != (PyObject *)NULL);
PyObject *result;
{
#ifdef WITHIN_PANDA
@ -429,13 +383,10 @@ receive_update(DCPacker &packer, PyObject *distobj) const {
#endif // HAVE_PYTHON
#ifdef HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: DCField::client_format_update
// Access: Published
// Description: Generates a datagram containing the message necessary
// to send an update for the indicated distributed
// object from the client.
////////////////////////////////////////////////////////////////////
/**
* Generates a datagram containing the message necessary to send an update for
* the indicated distributed object from the client.
*/
Datagram DCField::
client_format_update(DOID_TYPE do_id, PyObject *args) const {
DCPacker packer;
@ -455,13 +406,10 @@ client_format_update(DOID_TYPE do_id, PyObject *args) const {
#endif // HAVE_PYTHON
#ifdef HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: DCField::ai_format_update
// Access: Published
// Description: Generates a datagram containing the message necessary
// to send an update for the indicated distributed
// object from the AI.
////////////////////////////////////////////////////////////////////
/**
* Generates a datagram containing the message necessary to send an update for
* the indicated distributed object from the AI.
*/
Datagram DCField::
ai_format_update(DOID_TYPE do_id, CHANNEL_TYPE to_id, CHANNEL_TYPE from_id, PyObject *args) const {
DCPacker packer;
@ -484,14 +432,10 @@ ai_format_update(DOID_TYPE do_id, CHANNEL_TYPE to_id, CHANNEL_TYPE from_id, PyOb
#endif // HAVE_PYTHON
#ifdef HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: DCField::ai_format_update_msg_type
// Access: Published
// Description: Generates a datagram containing the message necessary
// to send an update, with the msg type,
// for the indicated distributed
// object from the AI.
////////////////////////////////////////////////////////////////////
/**
* Generates a datagram containing the message necessary to send an update,
* with the msg type, for the indicated distributed object from the AI.
*/
Datagram DCField::
ai_format_update_msg_type(DOID_TYPE do_id, CHANNEL_TYPE to_id, CHANNEL_TYPE from_id, int msg_type, PyObject *args) const {
DCPacker packer;
@ -514,41 +458,33 @@ ai_format_update_msg_type(DOID_TYPE do_id, CHANNEL_TYPE to_id, CHANNEL_TYPE from
#endif // HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: DCField::generate_hash
// Access: Public, Virtual
// Description: Accumulates the properties of this field into the
// hash.
////////////////////////////////////////////////////////////////////
/**
* Accumulates the properties of this field into the hash.
*/
void DCField::
generate_hash(HashGenerator &hashgen) const {
// It shouldn't be necessary to explicitly add _number to the
// hash--this is computed based on the relative position of this
// field with the other fields, so adding it explicitly will be
// redundant. However, the field name is significant.
// It shouldn't be necessary to explicitly add _number to the hash--this is
// computed based on the relative position of this field with the other
// fields, so adding it explicitly will be redundant. However, the field
// name is significant.
hashgen.add_string(_name);
// Actually, we add _number anyway, since we need to ensure the hash
// code comes out different in the dc_multiple_inheritance case.
// Actually, we add _number anyway, since we need to ensure the hash code
// comes out different in the dc_multiple_inheritance case.
if (dc_multiple_inheritance) {
hashgen.add_int(_number);
}
}
////////////////////////////////////////////////////////////////////
// Function: DCField::pack_default_value
// Access: Public, Virtual
// Description: Packs the field's specified default value (or a
// sensible default if no value is specified) into the
// stream. Returns true if the default value is packed,
// false if the field doesn't know how to pack its
// default value.
////////////////////////////////////////////////////////////////////
/**
* Packs the field's specified default value (or a sensible default if no
* value is specified) into the stream. Returns true if the default value is
* packed, false if the field doesn't know how to pack its default value.
*/
bool DCField::
pack_default_value(DCPackData &pack_data, bool &) const {
// The default behavior is to pack the default value if we got it;
// otherwise, to return false and let the packer visit our nested
// elements.
// otherwise, to return false and let the packer visit our nested elements.
if (!_default_value_stale) {
pack_data.append_data(_default_value.data(), _default_value.length());
return true;
@ -557,11 +493,9 @@ pack_default_value(DCPackData &pack_data, bool &) const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::set_name
// Access: Public, Virtual
// Description: Sets the name of this field.
////////////////////////////////////////////////////////////////////
/**
* Sets the name of this field.
*/
void DCField::
set_name(const string &name) {
DCPackerInterface::set_name(name);
@ -571,12 +505,9 @@ set_name(const string &name) {
}
#ifdef HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: DCField::get_pystr
// Access: Public, Static
// Description: Returns the string representation of the indicated
// Python object.
////////////////////////////////////////////////////////////////////
/**
* Returns the string representation of the indicated Python object.
*/
string DCField::
get_pystr(PyObject *value) {
if (value == NULL) {
@ -622,12 +553,9 @@ get_pystr(PyObject *value) {
}
#endif // HAVE_PYTHON
////////////////////////////////////////////////////////////////////
// Function: DCField::refresh_default_value
// Access: Protected
// Description: Recomputes the default value of the field by
// repacking it.
////////////////////////////////////////////////////////////////////
/**
* Recomputes the default value of the field by repacking it.
*/
void DCField::
refresh_default_value() {
DCPacker packer;

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