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:
commit
18e75e2917
36
.travis.yml
36
.travis.yml
|
|
@ -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:
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
'''
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)):
|
||||
|
|
|
|||
|
|
@ -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() +
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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 ):
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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."""
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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 """
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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"""
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
||||
|
|
|
|||
|
|
@ -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"""
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ©) :
|
||||
DCParameter(copy),
|
||||
|
|
@ -86,91 +81,71 @@ DCArrayParameter(const DCArrayParameter ©) :
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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) {
|
||||
|
|
|
|||
|
|
@ -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 ©);
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 ©) :
|
||||
DCParameter(copy),
|
||||
|
|
@ -77,80 +71,64 @@ DCClassParameter(const DCClassParameter ©) :
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue