obviate the need to call Actor.update() most of the time

This commit is contained in:
David Rose 2006-07-26 21:40:53 +00:00
parent f75b83c440
commit 8e178ae9d6
22 changed files with 620 additions and 41 deletions

View File

@ -12,7 +12,9 @@
#define SOURCES \
character.I character.h \
characterJoint.h characterJointBundle.I \
characterJointBundle.h characterSlider.h \
characterJointBundle.h \
characterJointEffect.h characterJointEffect.I \
characterSlider.h \
characterVertexSlider.I characterVertexSlider.h \
config_char.h \
jointVertexTransform.I jointVertexTransform.h
@ -20,6 +22,7 @@
#define INCLUDED_SOURCES \
character.cxx \
characterJoint.cxx characterJointBundle.cxx \
characterJointEffect.cxx \
characterSlider.cxx \
characterVertexSlider.cxx \
config_char.cxx \
@ -28,7 +31,9 @@
#define INSTALL_HEADERS \
character.I character.h \
characterJoint.h characterJointBundle.I \
characterJointBundle.h characterSlider.h \
characterJointBundle.h \
characterJointEffect.h characterJointEffect.I \
characterSlider.h \
characterVertexSlider.I characterVertexSlider.h \
config_char.h \
jointVertexTransform.I jointVertexTransform.h

View File

@ -1,4 +1,3 @@
#include "config_char.cxx"
#include "character.cxx"
#include "characterJoint.cxx"

View File

@ -1,4 +1,4 @@
#include "characterJointEffect.cxx"
#include "characterSlider.cxx"
#include "characterVertexSlider.cxx"
#include "jointVertexTransform.cxx"

View File

@ -74,6 +74,7 @@ Character(const string &name) :
////////////////////////////////////////////////////////////////////
Character::
~Character() {
r_clear_joint_characters(get_bundle());
}
////////////////////////////////////////////////////////////////////
@ -251,6 +252,9 @@ copy_joints(PartGroup *copy, PartGroup *orig) {
for (ci = orig->_children.begin(); ci != orig->_children.end(); ++ci) {
PartGroup *orig_child = (*ci);
PartGroup *copy_child = orig_child->make_copy();
if (copy_child->is_of_type(CharacterJoint::get_class_type())) {
DCAST(CharacterJoint, copy_child)->set_character(this);
}
copy->_children.push_back(copy_child);
copy_joints(copy_child, orig_child);
}
@ -449,6 +453,7 @@ copy_node_pointers(const Character *from, const Character::NodeMap &node_map) {
// Here's an internal joint that the source Character was
// animating directly. We'll animate our corresponding
// joint the same way.
dest_joint->set_character(this);
dest_joint->add_net_transform(dest_node);
}
}
@ -466,6 +471,7 @@ copy_node_pointers(const Character *from, const Character::NodeMap &node_map) {
// Here's an internal joint that the source Character was
// animating directly. We'll animate our corresponding
// joint the same way.
dest_joint->set_character(this);
dest_joint->add_local_transform(dest_node);
}
}
@ -633,6 +639,29 @@ redirect_slider(const VertexSlider *vs, Character::GeomSliderMap &gsmap) {
return new_cvs;
}
////////////////////////////////////////////////////////////////////
// Function: Character::r_clear_joint_characters
// Access: Private
// Description: Recursively walks through the joint hierarchy and
// clears any _character pointers on all the joints.
// Intended to be called just before Character
// destruction.
////////////////////////////////////////////////////////////////////
void Character::
r_clear_joint_characters(PartGroup *part) {
if (part->is_of_type(CharacterJoint::get_class_type())) {
CharacterJoint *joint = DCAST(CharacterJoint, part);
nassertv(joint->get_character() == this);
joint->set_character(NULL);
}
int num_children = part->get_num_children();
for (int i = 0; i < num_children; ++i) {
PartGroup *child = part->get_child(i);
r_clear_joint_characters(child);
}
}
////////////////////////////////////////////////////////////////////
// Function: Character::register_with_read_factory
// Access: Public, Static

View File

@ -107,6 +107,8 @@ private:
GeomJointMap &gjmap);
PT(CharacterVertexSlider) redirect_slider(const VertexSlider *vs, GeomSliderMap &gsmap);
void r_clear_joint_characters(PartGroup *part);
// This vector is used by the ComputedVertices object to index back
// into our joints and sliders.
typedef vector_PartGroupStar Parts;

View File

@ -19,7 +19,7 @@
#include "characterJoint.h"
#include "config_char.h"
#include "jointVertexTransform.h"
#include "characterJointEffect.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
@ -33,7 +33,9 @@ TypeHandle CharacterJoint::_type_handle;
// Description: For internal use only.
////////////////////////////////////////////////////////////////////
CharacterJoint::
CharacterJoint() {
CharacterJoint() :
_character(NULL)
{
}
////////////////////////////////////////////////////////////////////
@ -44,6 +46,7 @@ CharacterJoint() {
CharacterJoint::
CharacterJoint(const CharacterJoint &copy) :
MovingPartMatrix(copy),
_character(NULL),
_net_transform(copy._net_transform),
_initial_net_transform_inverse(copy._initial_net_transform_inverse)
{
@ -56,9 +59,11 @@ CharacterJoint(const CharacterJoint &copy) :
// Description:
////////////////////////////////////////////////////////////////////
CharacterJoint::
CharacterJoint(PartGroup *parent, const string &name,
const LMatrix4f &initial_value)
: MovingPartMatrix(parent, name, initial_value)
CharacterJoint(Character *character,
PartGroup *parent, const string &name,
const LMatrix4f &initial_value) :
MovingPartMatrix(parent, name, initial_value),
_character(character)
{
Thread *current_thread = Thread::get_current_thread();
@ -79,6 +84,7 @@ CharacterJoint(PartGroup *parent, const string &name,
CharacterJoint::
~CharacterJoint() {
nassertv(_vertex_transforms.empty());
nassertv(_character == (Character *)NULL);
}
////////////////////////////////////////////////////////////////////
@ -179,9 +185,15 @@ update_internals(PartGroup *parent, bool self_changed, bool parent_changed,
// from the root. Returns true if the node is
// successfully added, false if it had already been
// added.
//
// A CharacterJointEffect for this joint's Character
// will automatically be added to the specified node.
////////////////////////////////////////////////////////////////////
bool CharacterJoint::
add_net_transform(PandaNode *node) {
if (_character != (Character *)NULL) {
node->set_effect(CharacterJointEffect::make(_character));
}
return _net_transform_nodes.insert(node).second;
}
@ -193,9 +205,18 @@ add_net_transform(PandaNode *node) {
// transform from the root. Returns true if the node is
// successfully removed, false if it was not on the
// list.
//
// If the node has a CharacterJointEffect that matches
// this joint's Character, it will be cleared.
////////////////////////////////////////////////////////////////////
bool CharacterJoint::
remove_net_transform(PandaNode *node) {
CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
if (effect != (RenderEffect *)NULL &&
DCAST(CharacterJointEffect, effect)->get_character() == _character) {
node->clear_effect(CharacterJointEffect::get_class_type());
}
return (_net_transform_nodes.erase(node) > 0);
}
@ -220,6 +241,19 @@ has_net_transform(PandaNode *node) const {
////////////////////////////////////////////////////////////////////
void CharacterJoint::
clear_net_transforms() {
NodeList::iterator ai;
for (ai = _net_transform_nodes.begin();
ai != _net_transform_nodes.end();
++ai) {
PandaNode *node = *ai;
CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
if (effect != (RenderEffect *)NULL &&
DCAST(CharacterJointEffect, effect)->get_character() == _character) {
node->clear_effect(CharacterJointEffect::get_class_type());
}
}
_net_transform_nodes.clear();
}
@ -231,9 +265,20 @@ clear_net_transforms() {
// transform from its parent. Returns true if the node
// is successfully added, false if it had already been
// added.
//
// The Character pointer should be the Character object
// that owns this joint; this will be used to create a
// CharacterJointEffect for this node. If it is NULL,
// no such effect will be created.
//
// A CharacterJointEffect for this joint's Character
// will automatically be added to the specified node.
////////////////////////////////////////////////////////////////////
bool CharacterJoint::
add_local_transform(PandaNode *node) {
if (_character != (Character *)NULL) {
node->set_effect(CharacterJointEffect::make(_character));
}
return _local_transform_nodes.insert(node).second;
}
@ -245,9 +290,18 @@ add_local_transform(PandaNode *node) {
// transform from its parent. Returns true if the node
// is successfully removed, false if it was not on the
// list.
//
// If the node has a CharacterJointEffect that matches
// this joint's Character, it will be cleared.
////////////////////////////////////////////////////////////////////
bool CharacterJoint::
remove_local_transform(PandaNode *node) {
CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
if (effect != (RenderEffect *)NULL &&
DCAST(CharacterJointEffect, effect)->get_character() == _character) {
node->clear_effect(CharacterJointEffect::get_class_type());
}
return (_local_transform_nodes.erase(node) > 0);
}
@ -272,6 +326,19 @@ has_local_transform(PandaNode *node) const {
////////////////////////////////////////////////////////////////////
void CharacterJoint::
clear_local_transforms() {
NodeList::iterator ai;
for (ai = _local_transform_nodes.begin();
ai != _local_transform_nodes.end();
++ai) {
PandaNode *node = *ai;
CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
if (effect != (RenderEffect *)NULL &&
DCAST(CharacterJointEffect, effect)->get_character() == _character) {
node->clear_effect(CharacterJointEffect::get_class_type());
}
}
_local_transform_nodes.clear();
}
@ -298,6 +365,73 @@ get_net_transform(LMatrix4f &transform) const {
transform = _net_transform;
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJoint::get_character
// Access: Published
// Description: Returns the Character that owns this joint.
////////////////////////////////////////////////////////////////////
Character *CharacterJoint::
get_character() const {
return _character;
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJoint::set_character
// Access: Private
// Description: Changes the Character that owns this joint.
////////////////////////////////////////////////////////////////////
void CharacterJoint::
set_character(Character *character) {
if (character != _character) {
if (character != (Character *)NULL) {
// Change or set a _character pointer on each joint's exposed
// node.
NodeList::iterator ai;
for (ai = _net_transform_nodes.begin();
ai != _net_transform_nodes.end();
++ai) {
PandaNode *node = *ai;
node->set_effect(CharacterJointEffect::make(character));
}
for (ai = _local_transform_nodes.begin();
ai != _local_transform_nodes.end();
++ai) {
PandaNode *node = *ai;
node->set_effect(CharacterJointEffect::make(character));
}
} else { // (character == (Character *)NULL)
// Clear the _character pointer on each joint's exposed node.
NodeList::iterator ai;
for (ai = _net_transform_nodes.begin();
ai != _net_transform_nodes.end();
++ai) {
PandaNode *node = *ai;
CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
if (effect != (RenderEffect *)NULL &&
DCAST(CharacterJointEffect, effect)->get_character() == _character) {
node->clear_effect(CharacterJointEffect::get_class_type());
}
}
for (ai = _local_transform_nodes.begin();
ai != _local_transform_nodes.end();
++ai) {
PandaNode *node = *ai;
CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
if (effect != (RenderEffect *)NULL &&
DCAST(CharacterJointEffect, effect)->get_character() == _character) {
node->clear_effect(CharacterJointEffect::get_class_type());
}
}
}
}
_character = character;
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJoint::write_datagram
// Access: Public
@ -305,22 +439,23 @@ get_net_transform(LMatrix4f &transform) const {
// the particular object to a Datagram
////////////////////////////////////////////////////////////////////
void CharacterJoint::
write_datagram(BamWriter *manager, Datagram &me)
{
write_datagram(BamWriter *manager, Datagram &me) {
NodeList::iterator ni;
MovingPartMatrix::write_datagram(manager, me);
manager->write_pointer(me, _character);
me.add_uint16(_net_transform_nodes.size());
for(ni = _net_transform_nodes.begin();
ni != _net_transform_nodes.end();
ni++) {
for (ni = _net_transform_nodes.begin();
ni != _net_transform_nodes.end();
ni++) {
manager->write_pointer(me, (*ni));
}
me.add_uint16(_local_transform_nodes.size());
for(ni = _local_transform_nodes.begin();
ni != _local_transform_nodes.end();
ni++) {
for (ni = _local_transform_nodes.begin();
ni != _local_transform_nodes.end();
ni++) {
manager->write_pointer(me, (*ni));
}
@ -340,6 +475,10 @@ fillin(DatagramIterator &scan, BamReader *manager) {
int i;
MovingPartMatrix::fillin(scan, manager);
if (manager->get_file_minor_ver() >= 4) {
manager->read_pointer(scan);
}
_num_net_nodes = scan.get_uint16();
for(i = 0; i < _num_net_nodes; i++) {
manager->read_pointer(scan);
@ -356,15 +495,20 @@ fillin(DatagramIterator &scan, BamReader *manager) {
////////////////////////////////////////////////////////////////////
// Function: CharacterJoint::complete_pointers
// Access: Public
// Description: Takes in a vector of pointes to TypedWritable
// Description: Takes in a vector of pointers to TypedWritable
// objects that correspond to all the requests for
// pointers that this object made to BamReader.
////////////////////////////////////////////////////////////////////
int CharacterJoint::
complete_pointers(TypedWritable **p_list, BamReader* manager)
{
complete_pointers(TypedWritable **p_list, BamReader* manager) {
int pi = MovingPartMatrix::complete_pointers(p_list, manager);
if (manager->get_file_minor_ver() >= 4) {
_character = DCAST(Character, p_list[pi++]);
} else {
_character = NULL;
}
int i;
for (i = 0; i < _num_net_nodes; i++) {
add_net_transform(DCAST(PandaNode, p_list[pi++]));
@ -383,8 +527,7 @@ complete_pointers(TypedWritable **p_list, BamReader* manager)
// Description: Factory method to generate a CharacterJoint object
////////////////////////////////////////////////////////////////////
TypedWritable* CharacterJoint::
make_CharacterJoint(const FactoryParams &params)
{
make_CharacterJoint(const FactoryParams &params) {
CharacterJoint *me = new CharacterJoint;
DatagramIterator scan;
BamReader *manager;
@ -400,8 +543,7 @@ make_CharacterJoint(const FactoryParams &params)
// Description: Factory method to generate a CharacterJoint object
////////////////////////////////////////////////////////////////////
void CharacterJoint::
register_with_read_factory()
{
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_CharacterJoint);
}

View File

@ -25,6 +25,7 @@
#include "pandaNode.h"
class JointVertexTransform;
class Character;
////////////////////////////////////////////////////////////////////
// Class : CharacterJoint
@ -37,7 +38,8 @@ protected:
CharacterJoint(const CharacterJoint &copy);
public:
CharacterJoint(PartGroup *parent, const string &name,
CharacterJoint(Character *character,
PartGroup *parent, const string &name,
const LMatrix4f &initial_value);
virtual ~CharacterJoint();
@ -60,7 +62,15 @@ PUBLISHED:
void get_transform(LMatrix4f &transform) const;
void get_net_transform(LMatrix4f &transform) const;
Character *get_character() const;
private:
void set_character(Character *character);
private:
// Not a reference-counted pointer.
Character *_character;
typedef pset< PT(PandaNode) > NodeList;
NodeList _net_transform_nodes;
NodeList _local_transform_nodes;

View File

@ -0,0 +1,39 @@
// Filename: characterJointEffect.I
// Created by: drose (26Jul06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::Constructor
// Access: Private
// Description: Use CharacterJointEffect::make() to construct a new
// CharacterJointEffect object.
////////////////////////////////////////////////////////////////////
INLINE CharacterJointEffect::
CharacterJointEffect() {
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::get_character
// Access: Published
// Description: Returns the Character that will get update() called
// on it when this node's relative transform is queried.
////////////////////////////////////////////////////////////////////
INLINE Character *CharacterJointEffect::
get_character() const {
return _character;
}

View File

@ -0,0 +1,239 @@
// Filename: characterJointEffect.cxx
// Created by: drose (26Jul06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "characterJointEffect.h"
#include "cullTraverser.h"
#include "cullTraverserData.h"
#include "nodePath.h"
#include "look_at.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "datagram.h"
#include "datagramIterator.h"
TypeHandle CharacterJointEffect::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::make
// Access: Published, Static
// Description: Constructs a new CharacterJointEffect object that
// references the indicated character. When a relative
// get_transform() is called on the node that contains
// the CharacterJointEffect, it will implicitly call
// character->update() first.
////////////////////////////////////////////////////////////////////
CPT(RenderEffect) CharacterJointEffect::
make(Character *character) {
CharacterJointEffect *effect = new CharacterJointEffect;
effect->_character = character;
return return_new(effect);
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::safe_to_transform
// Access: Public, Virtual
// Description: Returns true if it is generally safe to transform
// this particular kind of RenderEffect by calling the
// xform() method, false otherwise.
////////////////////////////////////////////////////////////////////
bool CharacterJointEffect::
safe_to_transform() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CharacterJointEffect::
output(ostream &out) const {
out << get_type() << "(" << _character->get_name() << ")";
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::has_cull_callback
// Access: Public, Virtual
// Description: Should be overridden by derived classes to return
// true if cull_callback() has been defined. Otherwise,
// returns false to indicate cull_callback() does not
// need to be called for this effect during the cull
// traversal.
////////////////////////////////////////////////////////////////////
bool CharacterJointEffect::
has_cull_callback() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::cull_callback
// Access: Public, Virtual
// Description: If has_cull_callback() returns true, this function
// will be called during the cull traversal to perform
// any additional operations that should be performed at
// cull time. This may include additional manipulation
// of render state or additional visible/invisible
// decisions, or any other arbitrary operation.
//
// At the time this function is called, the current
// node's transform and state have not yet been applied
// to the net_transform and net_state. This callback
// may modify the node_transform and node_state to apply
// an effective change to the render state at this
// level.
////////////////////////////////////////////////////////////////////
void CharacterJointEffect::
cull_callback(CullTraverser *trav, CullTraverserData &data,
CPT(TransformState) &node_transform,
CPT(RenderState) &) const {
CPT(TransformState) dummy_transform = TransformState::make_identity();
adjust_transform(dummy_transform, node_transform, data.node());
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::has_adjust_transform
// Access: Public, Virtual
// Description: Should be overridden by derived classes to return
// true if adjust_transform() has been defined, and
// therefore the RenderEffect has some effect on the
// node's apparent local and net transforms.
////////////////////////////////////////////////////////////////////
bool CharacterJointEffect::
has_adjust_transform() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::adjust_transform
// Access: Public, Virtual
// Description: Performs some operation on the node's apparent net
// and/or local transforms. This will only be called if
// has_adjust_transform() is redefined to return true.
//
// Both parameters are in/out. The original transforms
// will be passed in, and they may (or may not) be
// modified in-place by the RenderEffect.
////////////////////////////////////////////////////////////////////
void CharacterJointEffect::
adjust_transform(CPT(TransformState) &net_transform,
CPT(TransformState) &node_transform,
PandaNode *node) const {
_character->update();
node_transform = node->get_transform();
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::compare_to_impl
// Access: Protected, Virtual
// Description: Intended to be overridden by derived CharacterJointEffect
// types to return a unique number indicating whether
// this CharacterJointEffect is equivalent to the other one.
//
// This should return 0 if the two CharacterJointEffect objects
// are equivalent, a number less than zero if this one
// should be sorted before the other one, and a number
// greater than zero otherwise.
//
// This will only be called with two CharacterJointEffect
// objects whose get_type() functions return the same.
////////////////////////////////////////////////////////////////////
int CharacterJointEffect::
compare_to_impl(const RenderEffect *other) const {
const CharacterJointEffect *ta;
DCAST_INTO_R(ta, other, 0);
if (_character != ta->_character) {
return _character < ta->_character ? -1 : 1;
}
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::register_with_read_factory
// Access: Public, Static
// Description: Tells the BamReader how to create objects of type
// CharacterJointEffect.
////////////////////////////////////////////////////////////////////
void CharacterJointEffect::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
void CharacterJointEffect::
write_datagram(BamWriter *manager, Datagram &dg) {
RenderEffect::write_datagram(manager, dg);
manager->write_pointer(dg, _character);
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::complete_pointers
// Access: Public, Virtual
// Description: Receives an array of pointers, one for each time
// manager->read_pointer() was called in fillin().
// Returns the number of pointers processed.
////////////////////////////////////////////////////////////////////
int CharacterJointEffect::
complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = RenderEffect::complete_pointers(p_list, manager);
_character = DCAST(Character, p_list[pi++]);
return pi;
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::make_from_bam
// Access: Protected, Static
// Description: This function is called by the BamReader's factory
// when a new object of type CharacterJointEffect is encountered
// in the Bam file. It should create the CharacterJointEffect
// and extract its information from the file.
////////////////////////////////////////////////////////////////////
TypedWritable *CharacterJointEffect::
make_from_bam(const FactoryParams &params) {
CharacterJointEffect *effect = new CharacterJointEffect;
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
effect->fillin(scan, manager);
return effect;
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointEffect::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new CharacterJointEffect.
////////////////////////////////////////////////////////////////////
void CharacterJointEffect::
fillin(DatagramIterator &scan, BamReader *manager) {
RenderEffect::fillin(scan, manager);
manager->read_pointer(scan);
}

View File

@ -0,0 +1,100 @@
// Filename: characterJointEffect.h
// Created by: drose (26Jul06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef CHARACTERJOINTEFFECT_H
#define CHARACTERJOINTEFFECT_H
#include "pandabase.h"
#include "renderEffect.h"
#include "luse.h"
#include "nodePath.h"
#include "character.h"
////////////////////////////////////////////////////////////////////
// Class : CharacterJointEffect
// Description : This effect will be added automatically to a node by
// CharacterJoint::add_net_transform() and
// CharacterJoint::add_local_transform().
//
// The effect binds the node back to the character, so
// that querying the relative transform of the affected
// node will automatically force the indicated character
// to be updated first.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CharacterJointEffect : public RenderEffect {
private:
INLINE CharacterJointEffect();
PUBLISHED:
static CPT(RenderEffect) make(Character *character);
INLINE Character *get_character() const;
public:
virtual bool safe_to_transform() const;
virtual void output(ostream &out) const;
virtual bool has_cull_callback() const;
virtual void cull_callback(CullTraverser *trav, CullTraverserData &data,
CPT(TransformState) &node_transform,
CPT(RenderState) &node_state) const;
virtual bool has_adjust_transform() const;
virtual void adjust_transform(CPT(TransformState) &net_transform,
CPT(TransformState) &node_transform,
PandaNode *node) const;
protected:
virtual int compare_to_impl(const RenderEffect *other) const;
private:
PT(Character) _character;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);
virtual int complete_pointers(TypedWritable **plist,
BamReader *manager);
protected:
static TypedWritable *make_from_bam(const FactoryParams &params);
void fillin(DatagramIterator &scan, BamReader *manager);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
RenderEffect::init_type();
register_type(_type_handle, "CharacterJointEffect",
RenderEffect::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "characterJointEffect.I"
#endif

View File

@ -21,6 +21,7 @@
#include "character.h"
#include "characterJoint.h"
#include "characterJointBundle.h"
#include "characterJointEffect.h"
#include "characterSlider.h"
#include "characterVertexSlider.h"
#include "jointVertexTransform.h"
@ -62,6 +63,7 @@ init_libchar() {
Character::init_type();
CharacterJoint::init_type();
CharacterJointBundle::init_type();
CharacterJointEffect::init_type();
CharacterSlider::init_type();
CharacterVertexSlider::init_type();
JointVertexTransform::init_type();
@ -77,6 +79,7 @@ init_libchar() {
Character::register_with_read_factory();
CharacterJoint::register_with_read_factory();
CharacterJointBundle::register_with_read_factory();
CharacterJointEffect::register_with_read_factory();
CharacterSlider::register_with_read_factory();
CharacterVertexSlider::register_with_read_factory();
JointVertexTransform::register_with_read_factory();

View File

@ -261,7 +261,7 @@ build_joint_hierarchy(EggNode *egg_node, PartGroup *part, int index) {
LMatrix4f matf = LCAST(float, matd);
CharacterJoint *joint =
new CharacterJoint(part, egg_group->get_name(), matf);
new CharacterJoint(_character_node, part, egg_group->get_name(), matf);
index = _parts.size();
_parts.push_back(joint);

View File

@ -197,7 +197,8 @@ has_adjust_transform() const {
////////////////////////////////////////////////////////////////////
void BillboardEffect::
adjust_transform(CPT(TransformState) &net_transform,
CPT(TransformState) &node_transform) const {
CPT(TransformState) &node_transform,
PandaNode *) const {
// A BillboardEffect can only affect the net transform when it is to
// a particular node. A billboard to a camera is camera-dependent,
// of course, so it has no effect in the absence of any particular

View File

@ -66,7 +66,8 @@ public:
virtual bool has_adjust_transform() const;
virtual void adjust_transform(CPT(TransformState) &net_transform,
CPT(TransformState) &node_transform) const;
CPT(TransformState) &node_transform,
PandaNode *node) const;
protected:
virtual int compare_to_impl(const RenderEffect *other) const;

View File

@ -145,7 +145,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data,
CPT(TransformState) true_net_transform = data.get_net_transform(trav);
CPT(TransformState) want_net_transform = true_net_transform;
adjust_transform(want_net_transform, node_transform);
adjust_transform(want_net_transform, node_transform, data.node());
// Now compute the transform that will convert true_net_transform to
// want_transform. This is inv(true_net_transform) * want_transform.
@ -185,7 +185,8 @@ has_adjust_transform() const {
////////////////////////////////////////////////////////////////////
void CompassEffect::
adjust_transform(CPT(TransformState) &net_transform,
CPT(TransformState) &node_transform) const {
CPT(TransformState) &node_transform,
PandaNode *) const {
if (_properties == 0) {
// Nothing to do.
return;

View File

@ -90,7 +90,8 @@ public:
virtual bool has_adjust_transform() const;
virtual void adjust_transform(CPT(TransformState) &net_transform,
CPT(TransformState) &node_transform) const;
CPT(TransformState) &node_transform,
PandaNode *node) const;
protected:
virtual int compare_to_impl(const RenderEffect *other) const;

View File

@ -5805,11 +5805,12 @@ r_get_net_transform(NodePathComponent *comp, Thread *current_thread) const {
} else {
int pipeline_stage = current_thread->get_pipeline_stage();
CPT(TransformState) net_transform = r_get_net_transform(comp->get_next(pipeline_stage, current_thread), current_thread);
CPT(TransformState) transform = comp->get_node()->get_transform(current_thread);
PandaNode *node = comp->get_node();
CPT(TransformState) transform = node->get_transform(current_thread);
CPT(RenderEffects) effects = comp->get_node()->get_effects(current_thread);
CPT(RenderEffects) effects = node->get_effects(current_thread);
if (effects->has_adjust_transform()) {
effects->adjust_transform(net_transform, transform);
effects->adjust_transform(net_transform, transform, node);
}
return net_transform->compose(transform);

View File

@ -199,7 +199,8 @@ has_adjust_transform() const {
// modified in-place by the RenderEffect.
////////////////////////////////////////////////////////////////////
void RenderEffect::
adjust_transform(CPT(TransformState) &, CPT(TransformState) &) const {
adjust_transform(CPT(TransformState) &, CPT(TransformState) &,
PandaNode *) const {
}
////////////////////////////////////////////////////////////////////

View File

@ -31,6 +31,7 @@
class CullTraverser;
class CullTraverserData;
class PandaNode;
////////////////////////////////////////////////////////////////////
// Class : RenderEffect
@ -78,7 +79,8 @@ public:
virtual bool has_adjust_transform() const;
virtual void adjust_transform(CPT(TransformState) &net_transform,
CPT(TransformState) &node_transform) const;
CPT(TransformState) &node_transform,
PandaNode *node) const;
PUBLISHED:
INLINE int compare_to(const RenderEffect &other) const;

View File

@ -520,10 +520,11 @@ cull_callback(CullTraverser *trav, CullTraverserData &data,
////////////////////////////////////////////////////////////////////
void RenderEffects::
adjust_transform(CPT(TransformState) &net_transform,
CPT(TransformState) &node_transform) const {
CPT(TransformState) &node_transform,
PandaNode *node) const {
Effects::const_iterator ei;
for (ei = _effects.begin(); ei != _effects.end(); ++ei) {
(*ei)._effect->adjust_transform(net_transform, node_transform);
(*ei)._effect->adjust_transform(net_transform, node_transform, node);
}
}

View File

@ -107,8 +107,9 @@ public:
CPT(RenderState) &node_state) const;
INLINE bool has_adjust_transform() const;
virtual void adjust_transform(CPT(TransformState) &net_transform,
CPT(TransformState) &node_transform) const;
void adjust_transform(CPT(TransformState) &net_transform,
CPT(TransformState) &node_transform,
PandaNode *node) const;
static void init_states();

View File

@ -36,10 +36,11 @@ static const unsigned short _bam_major_ver = 6;
// Bumped to major version 5 on 5/6/05 for new Geom implementation.
// Bumped to major version 6 on 2/11/06 to factor out PandaNode::CData.
static const unsigned short _bam_minor_ver = 3;
static const unsigned short _bam_minor_ver = 4;
// Bumped to minor version 1 on 3/12/06 to add Texture::_compression.
// Bumped to minor version 2 on 3/17/06 to add PandaNode::_draw_control_mask.
// Bumped to minor version 3 on 3/21/06 to add Texture::_ram_images.
// Bumped to minor version 4 on 7/26/06 to add CharacterJoint::_character.
#endif