half-body animations

This commit is contained in:
David Rose 2006-01-20 02:45:03 +00:00
parent 1e5469d22f
commit aa837381d3
20 changed files with 683 additions and 194 deletions

View File

@ -14,6 +14,7 @@
animChannel.I animChannel.h animChannelBase.I \
animChannelBase.h \
animChannelMatrixDynamic.I animChannelMatrixDynamic.h \
animChannelMatrixFixed.I animChannelMatrixFixed.h \
animChannelMatrixXfmTable.I animChannelMatrixXfmTable.h \
animChannelScalarDynamic.I animChannelScalarDynamic.h \
animChannelScalarTable.I animChannelScalarTable.h \
@ -25,6 +26,7 @@
movingPartScalar.h partBundle.I partBundle.N partBundle.h \
partBundleNode.I partBundleNode.h \
partGroup.I partGroup.h \
partSubset.I partSubset.h \
vector_PartGroupStar.h
#define INCLUDED_SOURCES \
@ -33,6 +35,7 @@
animChannel.cxx \
animChannelBase.cxx \
animChannelMatrixDynamic.cxx \
animChannelMatrixFixed.cxx \
animChannelMatrixXfmTable.cxx \
animChannelScalarDynamic.cxx \
animChannelScalarTable.cxx \
@ -41,7 +44,9 @@
config_chan.cxx movingPartBase.cxx movingPartMatrix.cxx \
movingPartScalar.cxx partBundle.cxx \
partBundleNode.cxx \
partGroup.cxx vector_PartGroupStar.cxx
partGroup.cxx \
partSubset.cxx \
vector_PartGroupStar.cxx
#define INSTALL_HEADERS \
animBundle.I animBundle.h \
@ -49,6 +54,7 @@
animChannel.I animChannel.h animChannelBase.I animChannelBase.h \
animChannelFixed.I animChannelFixed.h \
animChannelMatrixDynamic.I animChannelMatrixDynamic.h \
animChannelMatrixFixed.I animChannelMatrixFixed.h \
animChannelMatrixXfmTable.I animChannelMatrixXfmTable.h \
animChannelScalarDynamic.I animChannelScalarDynamic.h \
animChannelScalarTable.I animChannelScalarTable.h \
@ -60,6 +66,7 @@
movingPartScalar.I movingPartScalar.h partBundle.I partBundle.h \
partBundleNode.I partBundleNode.h \
partGroup.I partGroup.h \
partSubset.I partSubset.h \
vector_PartGroupStar.h
#define IGATESCAN all

View File

@ -26,7 +26,6 @@
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "fftCompressor.h"
TypeHandle AnimChannelMatrixDynamic::_type_handle;
@ -101,7 +100,7 @@ get_value_no_scale_shear(int frame, LMatrix4f &mat) {
// Description: Gets the scale value at the indicated frame.
////////////////////////////////////////////////////////////////////
void AnimChannelMatrixDynamic::
get_scale(int frame, LVecBase3f &scale) {
get_scale(int, LVecBase3f &scale) {
scale = _value->get_scale();
}

View File

@ -0,0 +1,18 @@
// Filename: animChannelMatrixFixed.I
// Created by: drose (19Jan06)
//
////////////////////////////////////////////////////////////////////
//
// 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 .
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,110 @@
// Filename: animChannelMatrixFixed.cxx
// Created by: drose (19Jan06)
//
////////////////////////////////////////////////////////////////////
//
// 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 "animChannelMatrixFixed.h"
#include "compose_matrix.h"
TypeHandle AnimChannelMatrixFixed::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: AnimChannelMatrixFixed::Constructor
// Access: Public
// Description: This flavor creates an AnimChannelMatrixFixed that is not
// in a hierarchy.
////////////////////////////////////////////////////////////////////
AnimChannelMatrixFixed::
AnimChannelMatrixFixed(const string &name, const LMatrix4f &value)
: AnimChannelFixed<ACMatrixSwitchType>(name, value)
{
// Decompose the matrix into components in case we will be blending.
decompose_matrix(_value, _scale, _shear, _hpr, _pos);
compose_matrix(_value_no_scale_shear, LVecBase3f(1.0f, 1.0f, 1.0f),
_hpr, _pos);
_quat.set_hpr(_hpr);
}
////////////////////////////////////////////////////////////////////
// Function: AnimChannelMatrixFixed::get_value_no_scale_shear
// Access: Public, Virtual
// Description: Gets the value of the channel at the indicated frame,
// without any scale or shear information.
////////////////////////////////////////////////////////////////////
void AnimChannelMatrixFixed::
get_value_no_scale_shear(int frame, LMatrix4f &mat) {
mat = _value_no_scale_shear;
}
////////////////////////////////////////////////////////////////////
// Function: AnimChannelMatrixFixed::get_scale
// Access: Public, Virtual
// Description: Gets the scale value at the indicated frame.
////////////////////////////////////////////////////////////////////
void AnimChannelMatrixFixed::
get_scale(int, LVecBase3f &scale) {
scale = _scale;
}
////////////////////////////////////////////////////////////////////
// Function: AnimChannelMatrixFixed::get_hpr
// Access: Public, Virtual
// Description: Returns the h, p, and r components associated
// with the current frame. As above, this only makes
// sense for a matrix-type channel.
////////////////////////////////////////////////////////////////////
void AnimChannelMatrixFixed::
get_hpr(int, LVecBase3f &hpr) {
hpr = _hpr;
}
////////////////////////////////////////////////////////////////////
// Function: AnimChannelMatrixFixed::get_quat
// Access: Public, Virtual
// Description: Returns the rotation component associated with the
// current frame, expressed as a quaternion. As above,
// this only makes sense for a matrix-type channel.
////////////////////////////////////////////////////////////////////
void AnimChannelMatrixFixed::
get_quat(int, LQuaternionf &quat) {
quat = _quat;
}
////////////////////////////////////////////////////////////////////
// Function: AnimChannelMatrixFixed::get_pos
// Access: Public, Virtual
// Description: Returns the x, y, and z translation components
// associated with the current frame. As above, this
// only makes sense for a matrix-type channel.
////////////////////////////////////////////////////////////////////
void AnimChannelMatrixFixed::
get_pos(int, LVecBase3f &pos) {
pos = _pos;
}
////////////////////////////////////////////////////////////////////
// Function: AnimChannelMatrixFixed::get_shear
// Access: Public, Virtual
// Description: Returns the a, b, and c shear components associated
// with the current frame. As above, this only makes
// sense for a matrix-type channel.
////////////////////////////////////////////////////////////////////
void AnimChannelMatrixFixed::
get_shear(int, LVecBase3f &shear) {
shear = _shear;
}

View File

@ -0,0 +1,77 @@
// Filename: animChannelMatrixFixed.h
// Created by: drose (19Jan06)
//
////////////////////////////////////////////////////////////////////
//
// 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 ANIMCHANNELMATRIXFIXED_H
#define ANIMCHANNELMATRIXFIXED_H
#include "pandabase.h"
#include "animChannelFixed.h"
#include "luse.h"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, AnimChannelFixed<ACMatrixSwitchType>);
////////////////////////////////////////////////////////////////////
// Class : AnimChannelMatrixFixed
// Description : A specialization on AnimChannelFixed to add all the
// special matrix component operations.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA AnimChannelMatrixFixed : public AnimChannelFixed<ACMatrixSwitchType> {
public:
AnimChannelMatrixFixed(const string &name, const LMatrix4f &value);
virtual void get_value_no_scale_shear(int frame, LMatrix4f &value);
virtual void get_scale(int frame, LVecBase3f &scale);
virtual void get_hpr(int frame, LVecBase3f &hpr);
virtual void get_quat(int frame, LQuaternionf &quat);
virtual void get_pos(int frame, LVecBase3f &pos);
virtual void get_shear(int frame, LVecBase3f &shear);
private:
LMatrix4f _value_no_scale_shear;
LVecBase3f _scale;
LVecBase3f _hpr;
LQuaternionf _quat;
LVecBase3f _pos;
LVecBase3f _shear;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
AnimChannelFixed<ACMatrixSwitchType>::init_type();
register_type(_type_handle, "AnimChannelMatrixFixed",
AnimChannelFixed<ACMatrixSwitchType>::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "animChannelMatrixFixed.I"
#endif

View File

@ -1,11 +1,14 @@
#include "auto_bind.cxx"
#include "config_chan.cxx"
#include "movingPartBase.cxx"
#include "movingPartMatrix.cxx"
#include "movingPartScalar.cxx"
#include "partBundle.cxx"
#include "partBundleNode.cxx"
#include "partGroup.cxx"
#include "vector_PartGroupStar.cxx"
#include "animBundle.cxx"
#include "animBundleNode.cxx"
#include "animChannel.cxx"
#include "animChannelBase.cxx"
#include "animChannelMatrixDynamic.cxx"
#include "animChannelMatrixFixed.cxx"
#include "animChannelMatrixXfmTable.cxx"
#include "animChannelScalarDynamic.cxx"
#include "animChannelScalarTable.cxx"
#include "animControl.cxx"
#include "animControlCollection.cxx"
#include "animGroup.cxx"

View File

@ -1,13 +1,9 @@
#include "animBundle.cxx"
#include "animBundleNode.cxx"
#include "animChannel.cxx"
#include "animChannelBase.cxx"
#include "animChannelMatrixDynamic.cxx"
#include "animChannelMatrixXfmTable.cxx"
#include "animChannelScalarDynamic.cxx"
#include "animChannelScalarTable.cxx"
#include "animControl.cxx"
#include "animControlCollection.cxx"
#include "animGroup.cxx"
#include "config_chan.cxx"
#include "movingPartBase.cxx"
#include "movingPartMatrix.cxx"
#include "movingPartScalar.cxx"
#include "partBundle.cxx"
#include "partBundleNode.cxx"
#include "partGroup.cxx"
#include "partSubset.cxx"
#include "vector_PartGroupStar.cxx"

View File

@ -23,6 +23,7 @@
#include "animChannelBase.h"
#include "animChannelMatrixXfmTable.h"
#include "animChannelMatrixDynamic.h"
#include "animChannelMatrixFixed.h"
#include "animChannelScalarTable.h"
#include "animChannelScalarDynamic.h"
#include "animControl.h"
@ -89,6 +90,7 @@ ConfigureFn(config_chan) {
AnimChannelBase::init_type();
AnimChannelMatrixXfmTable::init_type();
AnimChannelMatrixDynamic::init_type();
AnimChannelMatrixFixed::init_type();
AnimChannelScalarTable::init_type();
AnimChannelScalarDynamic::init_type();
AnimControl::init_type();

View File

@ -47,7 +47,7 @@ MovingPartBase(){
////////////////////////////////////////////////////////////////////
// Function: MovingPartBase::write
// Access: Public, Virtual
// Access: Published, Virtual
// Description: Writes a brief description of the channel and all of
// its descendants.
////////////////////////////////////////////////////////////////////
@ -65,7 +65,7 @@ write(ostream &out, int indent_level) const {
////////////////////////////////////////////////////////////////////
// Function: MovingPartBase::write_with_value
// Access: Public, Virtual
// Access: Published, Virtual
// Description: Writes a brief description of the channel and all of
// its descendants, along with their values.
////////////////////////////////////////////////////////////////////
@ -112,9 +112,9 @@ do_update(PartBundle *root, PartGroup *parent,
int channel_index = control->get_channel_index();
nassertr(channel_index >= 0 && channel_index < (int)_channels.size(), false);
AnimChannelBase *channel = _channels[channel_index];
nassertr(channel != (AnimChannelBase*)0L, false);
needs_update = control->channel_has_changed(channel);
if (channel != (AnimChannelBase*)NULL) {
needs_update = control->channel_has_changed(channel);
}
}
if (needs_update) {
@ -187,7 +187,7 @@ pick_channel_index(plist<int> &holes, int &next) const {
if (next < (int)_channels.size()) {
int i;
for (i = next; i < (int)_channels.size(); i++) {
if (_channels[i] == (AnimChannelBase*)0L) {
if (_channels[i] == (AnimChannelBase*)NULL) {
// Here's a hole we do have.
holes.push_back(i);
}
@ -207,25 +207,29 @@ pick_channel_index(plist<int> &holes, int &next) const {
// hierarchy, at the given channel index number.
////////////////////////////////////////////////////////////////////
void MovingPartBase::
bind_hierarchy(AnimGroup *anim, int channel_index) {
bind_hierarchy(AnimGroup *anim, int channel_index, bool is_included,
const PartSubset &subset) {
if (chan_cat.is_debug()) {
chan_cat.debug()
<< "binding " << *this << " to " << *anim << "\n";
<< "binding " << *this << " to " << *anim << ", is_included = "
<< is_included << "\n";
}
while ((int)_channels.size() <= channel_index) {
_channels.push_back((AnimChannelBase*)0L);
_channels.push_back((AnimChannelBase*)NULL);
}
nassertv(_channels[channel_index] == (AnimChannelBase*)0L);
nassertv(_channels[channel_index] == (AnimChannelBase*)NULL);
if (anim == (AnimGroup*)0L) {
// If we're binding to the NULL anim, it means actually to create
// a default AnimChannel that just returns the part's initial
// value.
_channels[channel_index] = make_initial_channel();
} else {
_channels[channel_index] = DCAST(AnimChannelBase, anim);
if (is_included) {
if (anim == (AnimGroup*)NULL) {
// If we're binding to the NULL anim, it means actually to create
// a default AnimChannel that just returns the part's initial
// value.
_channels[channel_index] = make_initial_channel();
} else {
_channels[channel_index] = DCAST(AnimChannelBase, anim);
}
}
PartGroup::bind_hierarchy(anim, channel_index);
PartGroup::bind_hierarchy(anim, channel_index, is_included, subset);
}

View File

@ -49,10 +49,13 @@ PUBLISHED:
public:
virtual TypeHandle get_value_type() const=0;
virtual AnimChannelBase *make_initial_channel() const=0;
PUBLISHED:
virtual void write(ostream &out, int indent_level) const;
virtual void write_with_value(ostream &out, int indent_level) const;
virtual void output_value(ostream &out) const=0;
public:
virtual bool do_update(PartBundle *root, PartGroup *parent,
bool parent_changed, bool anim_changed);
@ -64,7 +67,8 @@ protected:
MovingPartBase();
virtual void pick_channel_index(plist<int> &holes, int &next) const;
virtual void bind_hierarchy(AnimGroup *anim, int channel_index);
virtual void bind_hierarchy(AnimGroup *anim, int channel_index,
bool is_included, const PartSubset &subset);
typedef pvector< PT(AnimChannelBase) > Channels;
Channels _channels;

View File

@ -41,6 +41,19 @@ MovingPartMatrix::
~MovingPartMatrix() {
}
////////////////////////////////////////////////////////////////////
// Function: MovingPartMatrix::make_initial_channel
// Access: Public, Virtual
// Description: Creates and returns a new AnimChannel that is not
// part of any hierarchy, but that returns the default
// value associated with this part.
////////////////////////////////////////////////////////////////////
AnimChannelBase *MovingPartMatrix::
make_initial_channel() const {
return new AnimChannelMatrixFixed(get_name(), _initial_value);
}
////////////////////////////////////////////////////////////////////
// Function: MovingPartMatrix::get_blend_value
// Access: Public
@ -63,9 +76,13 @@ get_blend_value(const PartBundle *root) {
int channel_index = control->get_channel_index();
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
nassertv(channel != NULL);
if (channel == (ChannelType *)NULL) {
// Nothing is actually bound here.
_value = _initial_value;
channel->get_value(control->get_frame(), _value);
} else {
channel->get_value(control->get_frame(), _value);
}
} else {
// A blend of two or more values.
@ -90,17 +107,20 @@ get_blend_value(const PartBundle *root) {
int channel_index = control->get_channel_index();
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
nassertv(channel != NULL);
if (channel != (ChannelType *)NULL) {
ValueType v;
channel->get_value(control->get_frame(), v);
ValueType v;
channel->get_value(control->get_frame(), v);
_value += v * effect;
net += effect;
_value += v * effect;
net += effect;
}
}
nassertv(net != 0.0f);
_value /= net;
if (net == 0.0f) {
_value = _initial_value;
} else {
_value /= net;
}
}
break;
@ -126,30 +146,34 @@ get_blend_value(const PartBundle *root) {
int channel_index = control->get_channel_index();
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
nassertv(channel != NULL);
if (channel != (ChannelType *)NULL) {
ValueType v;
channel->get_value_no_scale_shear(control->get_frame(), v);
LVecBase3f iscale, ishear;
channel->get_scale(control->get_frame(), iscale);
channel->get_shear(control->get_frame(), ishear);
ValueType v;
channel->get_value_no_scale_shear(control->get_frame(), v);
LVecBase3f iscale, ishear;
channel->get_scale(control->get_frame(), iscale);
channel->get_shear(control->get_frame(), ishear);
_value += v * effect;
scale += iscale * effect;
shear += ishear * effect;
net += effect;
_value += v * effect;
scale += iscale * effect;
shear += ishear * effect;
net += effect;
}
}
nassertv(net != 0.0f);
_value /= net;
scale /= net;
shear /= net;
if (net == 0.0f) {
_value = _initial_value;
// Now rebuild the matrix with the correct scale values.
} else {
_value /= net;
scale /= net;
shear /= net;
LVector3f false_scale, false_shear, hpr, translate;
decompose_matrix(_value, false_scale, false_shear, hpr, translate);
compose_matrix(_value, scale, shear, hpr, translate);
// Now rebuild the matrix with the correct scale values.
LVector3f false_scale, false_shear, hpr, translate;
decompose_matrix(_value, false_scale, false_shear, hpr, translate);
compose_matrix(_value, scale, shear, hpr, translate);
}
}
break;
@ -171,28 +195,32 @@ get_blend_value(const PartBundle *root) {
int channel_index = control->get_channel_index();
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
nassertv(channel != NULL);
if (channel != (ChannelType *)NULL) {
LVecBase3f iscale, ihpr, ipos, ishear;
channel->get_scale(control->get_frame(), iscale);
channel->get_hpr(control->get_frame(), ihpr);
channel->get_pos(control->get_frame(), ipos);
channel->get_shear(control->get_frame(), ishear);
LVecBase3f iscale, ihpr, ipos, ishear;
channel->get_scale(control->get_frame(), iscale);
channel->get_hpr(control->get_frame(), ihpr);
channel->get_pos(control->get_frame(), ipos);
channel->get_shear(control->get_frame(), ishear);
scale += iscale * effect;
hpr += ihpr * effect;
pos += ipos * effect;
shear += ishear * effect;
net += effect;
scale += iscale * effect;
hpr += ihpr * effect;
pos += ipos * effect;
shear += ishear * effect;
net += effect;
}
}
nassertv(net != 0.0f);
scale /= net;
hpr /= net;
pos /= net;
shear /= net;
if (net == 0.0f) {
_value = _initial_value;
compose_matrix(_value, scale, shear, hpr, pos);
} else {
scale /= net;
hpr /= net;
pos /= net;
shear /= net;
compose_matrix(_value, scale, shear, hpr, pos);
}
}
break;
@ -215,34 +243,38 @@ get_blend_value(const PartBundle *root) {
int channel_index = control->get_channel_index();
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
nassertv(channel != NULL);
if (channel != (ChannelType *)NULL) {
LVecBase3f iscale, ipos, ishear;
LQuaternionf iquat;
channel->get_scale(control->get_frame(), iscale);
channel->get_quat(control->get_frame(), iquat);
channel->get_pos(control->get_frame(), ipos);
channel->get_shear(control->get_frame(), ishear);
LVecBase3f iscale, ipos, ishear;
LQuaternionf iquat;
channel->get_scale(control->get_frame(), iscale);
channel->get_quat(control->get_frame(), iquat);
channel->get_pos(control->get_frame(), ipos);
channel->get_shear(control->get_frame(), ishear);
scale += iscale * effect;
quat += iquat * effect;
pos += ipos * effect;
shear += ishear * effect;
net += effect;
scale += iscale * effect;
quat += iquat * effect;
pos += ipos * effect;
shear += ishear * effect;
net += effect;
}
}
nassertv(net != 0.0f);
scale /= net;
quat /= net;
pos /= net;
shear /= net;
if (net == 0.0f) {
_value = _initial_value;
// There should be no need to normalize the quaternion,
// assuming all of the input quaternions were already
// normalized.
} else {
scale /= net;
quat /= net;
pos /= net;
shear /= net;
_value = LMatrix4f::scale_shear_mat(scale, shear) * quat;
_value.set_row(3, pos);
// There should be no need to normalize the quaternion,
// assuming all of the input quaternions were already
// normalized.
_value = LMatrix4f::scale_shear_mat(scale, shear) * quat;
_value.set_row(3, pos);
}
}
break;
}

View File

@ -43,6 +43,7 @@ public:
LMatrix4f::ident_mat());
virtual ~MovingPartMatrix();
virtual AnimChannelBase *make_initial_channel() const;
virtual void get_blend_value(const PartBundle *root);
protected:

View File

@ -61,9 +61,13 @@ get_blend_value(const PartBundle *root) {
int channel_index = control->get_channel_index();
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
nassertv(channel != NULL);
if (channel == NULL) {
// Nothing is actually bound here.
_value = _initial_value;
channel->get_value(control->get_frame(), _value);
} else {
channel->get_value(control->get_frame(), _value);
}
} else {
// A blend of two or more values.
@ -79,17 +83,21 @@ get_blend_value(const PartBundle *root) {
int channel_index = control->get_channel_index();
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
nassertv(channel != NULL);
if (channel != NULL) {
ValueType v;
channel->get_value(control->get_frame(), v);
ValueType v;
channel->get_value(control->get_frame(), v);
_value += v * effect;
net += effect;
_value += v * effect;
net += effect;
}
}
nassertv(net != 0.0f);
_value /= net;
if (net == 0.0f) {
_value = _initial_value;
} else {
_value /= net;
}
}
}

View File

@ -43,8 +43,6 @@ PartBundle(const PartBundle &copy) :
PartGroup(copy),
_blend_type(copy._blend_type)
{
// We don't invoke the AnimControlCollection's copy, or any of the
// bound animations.
_last_control_set = NULL;
_net_blend = 0.0f;
_anim_changed = false;
@ -250,16 +248,18 @@ write(ostream &out, int indent_level) const {
// conditions that will be tolerated (but warnings will
// still be issued).
//
// This flavor of bind_anim() does not associate a name
// with the channel, and the AnimControl is not stored
// within the PartBundle; it is the user's
// responsibility to maintain the pointer. The
// animation will automatically unbind itself when the
// AnimControl destructs (i.e. its reference count goes
// to zero).
// If subset is specified, it restricts the binding only
// to the named subtree of joints.
//
// The AnimControl is not stored within the PartBundle;
// it is the user's responsibility to maintain the
// pointer. The animation will automatically unbind
// itself when the AnimControl destructs (i.e. its
// reference count goes to zero).
////////////////////////////////////////////////////////////////////
PT(AnimControl) PartBundle::
bind_anim(AnimBundle *anim, int hierarchy_match_flags) {
bind_anim(AnimBundle *anim, int hierarchy_match_flags,
const PartSubset &subset) {
if ((hierarchy_match_flags & HMF_ok_wrong_root_name) == 0) {
// Make sure the root names match.
if (get_name() != anim->get_name()) {
@ -285,47 +285,10 @@ bind_anim(AnimBundle *anim, int hierarchy_match_flags) {
channel_index = holes.front();
}
bind_hierarchy(anim, channel_index);
bind_hierarchy(anim, channel_index, subset.is_empty(), subset);
return new AnimControl(this, anim, channel_index);
}
////////////////////////////////////////////////////////////////////
// Function: PartBundle::bind_anim
// Access: Published
// Description: Binds the animation to the bundle, if possible, and
// returns a new AnimControl that can be used to start
// and stop the animation. If the anim hierarchy does
// not match the part hierarchy, returns NULL.
//
// If hierarchy_match_flags is 0, only an exact match is
// accepted; otherwise, it may contain a union of
// PartGroup::HierarchyMatchFlags values indicating
// conditions that will be tolerated (but warnings will
// still be issued).
//
// This flavor of bind_anim() automatically stores the
// bound AnimControl in the PartBundle with the
// indicated name, so that it may later be referenced by
// name. This means that the animation will not be
// unbound until another animation with the same name is
// bound, or it is explicitly unbound with
// unbind_anim().
//
// The return value is true if the animation was
// successfully bound, false if there was some error.
////////////////////////////////////////////////////////////////////
bool PartBundle::
bind_anim(AnimBundle *anim, const string &name,
int hierarchy_match_flags) {
PT(AnimControl) control = bind_anim(anim, hierarchy_match_flags);
if (control == (AnimControl *)NULL) {
return false;
}
store_anim(control, name);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: PartBundle::update
// Access: Public

View File

@ -23,8 +23,7 @@
#include "partGroup.h"
#include "animControl.h"
#include "animControlCollection.h"
#include "partSubset.h"
#include "pointerTo.h"
#include "iterator_types.h"
@ -38,7 +37,7 @@ class PartBundleNode;
// defines the hierarchy of moving parts that make up an
// animatable object.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA PartBundle : public PartGroup, public AnimControlCollection {
class EXPCL_PANDA PartBundle : public PartGroup {
public:
// This is passed down through the MovingParts during the
@ -113,10 +112,8 @@ PUBLISHED:
virtual void write(ostream &out, int indent_level) const;
PT(AnimControl) bind_anim(AnimBundle *anim,
int hierarchy_match_flags = 0);
bool bind_anim(AnimBundle *anim, const string &name,
int hierarchy_match_flags = 0);
int hierarchy_match_flags = 0,
const PartSubset &subset = PartSubset());
public:
// The following functions may be used to traverse the set of

View File

@ -16,10 +16,10 @@
//
////////////////////////////////////////////////////////////////////
#include "partGroup.h"
#include "animGroup.h"
#include "config_chan.h"
#include "partSubset.h"
#include "indent.h"
#include "datagram.h"
@ -432,7 +432,14 @@ pick_channel_index(plist<int> &holes, int &next) const {
// hierarchy, at the given channel index number.
////////////////////////////////////////////////////////////////////
void PartGroup::
bind_hierarchy(AnimGroup *anim, int channel_index) {
bind_hierarchy(AnimGroup *anim, int channel_index, bool is_included,
const PartSubset &subset) {
if (subset.matches_include(get_name())) {
is_included = true;
} else if (subset.matches_exclude(get_name())) {
is_included = false;
}
int i = 0, j = 0;
int part_num_children = get_num_children();
int anim_num_children = (anim == NULL) ? 0 : anim->get_num_children();
@ -444,12 +451,12 @@ bind_hierarchy(AnimGroup *anim, int channel_index) {
if (pc->get_name() < ac->get_name()) {
// Here's a part, not in the anim. Bind it to the special NULL
// anim.
pc->bind_hierarchy(NULL, channel_index);
pc->bind_hierarchy(NULL, channel_index, is_included, subset);
i++;
} else if (ac->get_name() < pc->get_name()) {
j++;
} else {
pc->bind_hierarchy(ac, channel_index);
pc->bind_hierarchy(ac, channel_index, is_included, subset);
i++;
j++;
}
@ -458,7 +465,7 @@ bind_hierarchy(AnimGroup *anim, int channel_index) {
// Now pick up any more parts, not in the anim.
while (i < part_num_children) {
PartGroup *pc = get_child(i);
pc->bind_hierarchy(NULL, channel_index);
pc->bind_hierarchy(NULL, channel_index, is_included, subset);
i++;
}
}

View File

@ -31,6 +31,7 @@
class AnimControl;
class AnimGroup;
class PartBundle;
class PartSubset;
class BamReader;
class FactoryParams;
@ -91,7 +92,8 @@ protected:
void write_descendants_with_value(ostream &out, int indent_level) const;
virtual void pick_channel_index(plist<int> &holes, int &next) const;
virtual void bind_hierarchy(AnimGroup *anim, int channel_index);
virtual void bind_hierarchy(AnimGroup *anim, int channel_index,
bool is_included, const PartSubset &subset);
typedef pvector< PT(PartGroup) > Children;
Children _children;

View File

@ -0,0 +1,18 @@
// Filename: partSubset.I
// Created by: drose (19Jan06)
//
////////////////////////////////////////////////////////////////////
//
// 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 .
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,178 @@
// Filename: partSubset.cxx
// Created by: drose (19Jan06)
//
////////////////////////////////////////////////////////////////////
//
// 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 "partSubset.h"
////////////////////////////////////////////////////////////////////
// Function: PartSubset::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
PartSubset::
PartSubset() {
}
////////////////////////////////////////////////////////////////////
// Function: PartSubset::Copy Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
PartSubset::
PartSubset(const PartSubset &copy) :
_include_joints(copy._include_joints),
_exclude_joints(copy._exclude_joints)
{
}
////////////////////////////////////////////////////////////////////
// Function: PartSubset::Copy Assignment Operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void PartSubset::
operator = (const PartSubset &copy) {
_include_joints = copy._include_joints;
_exclude_joints = copy._exclude_joints;
}
////////////////////////////////////////////////////////////////////
// Function: PartSubset::add_include_joint
// Access: Published
// Description: Adds the named joint to the list of joints that will
// be explicitly included in the subset. Any joint at
// or below a named node will be included in the subset
// (unless a lower node is also listed in the exclude
// list).
//
// Since the name is a GlobPattern, it may of course
// include filename globbing characters like * and ?.
////////////////////////////////////////////////////////////////////
void PartSubset::
add_include_joint(const GlobPattern &name) {
_include_joints.push_back(name);
}
////////////////////////////////////////////////////////////////////
// Function: PartSubset::add_exclude_joint
// Access: Published
// Description: Adds the named joint to the list of joints that will
// be explicitly exlcluded from the subset. Any joint at
// or below a named node will not be included in the
// subset (unless a lower node is also listed in the
// include list).
//
// Since the name is a GlobPattern, it may of course
// include filename globbing characters like * and ?.
////////////////////////////////////////////////////////////////////
void PartSubset::
add_exclude_joint(const GlobPattern &name) {
_exclude_joints.push_back(name);
}
////////////////////////////////////////////////////////////////////
// Function: PartSubset::append
// Access: Published
// Description: Appends the include and exclude list from the other
// object onto this object's lists.
////////////////////////////////////////////////////////////////////
void PartSubset::
append(const PartSubset &other) {
Joints::const_iterator ji;
for (ji = other._include_joints.begin();
ji != other._include_joints.end();
++ji) {
_include_joints.push_back(*ji);
}
for (ji = other._exclude_joints.begin();
ji != other._exclude_joints.end();
++ji) {
_exclude_joints.push_back(*ji);
}
}
////////////////////////////////////////////////////////////////////
// Function: PartSubset::output
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void PartSubset::
output(ostream &out) const {
if (_include_joints.empty() && _exclude_joints.empty()) {
out << "PartSubset, empty";
} else {
out << "PartSubset, include: [";
Joints::const_iterator ji;
for (ji = _include_joints.begin(); ji != _include_joints.end(); ++ji) {
out << " " << (*ji);
}
out << " ], exclude: [";
for (ji = _exclude_joints.begin(); ji != _exclude_joints.end(); ++ji) {
out << " " << (*ji);
}
out << " ]";
}
}
////////////////////////////////////////////////////////////////////
// Function: PartSubset::is_empty
// Access: Published
// Description: Returns true if the PartSubset is completely empty,
// false otherwise. If it is empty, it is the same
// thing as including all joints.
////////////////////////////////////////////////////////////////////
bool PartSubset::
is_empty() const {
return _include_joints.empty() && _exclude_joints.empty();
}
////////////////////////////////////////////////////////////////////
// Function: PartSubset::matches_include
// Access: Published
// Description: Returns true if the indicated name matches a name on
// the include list, false otherwise.
////////////////////////////////////////////////////////////////////
bool PartSubset::
matches_include(const string &joint_name) const {
Joints::const_iterator ji;
for (ji = _include_joints.begin(); ji != _include_joints.end(); ++ji) {
if ((*ji).matches(joint_name)) {
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PartSubset::matches_exclude
// Access: Published
// Description: Returns true if the indicated name matches a name on
// the exclude list, false otherwise.
////////////////////////////////////////////////////////////////////
bool PartSubset::
matches_exclude(const string &joint_name) const {
Joints::const_iterator ji;
for (ji = _exclude_joints.begin(); ji != _exclude_joints.end(); ++ji) {
if ((*ji).matches(joint_name)) {
return true;
}
}
return false;
}

View File

@ -0,0 +1,63 @@
// Filename: partSubset.h
// Created by: drose (19Jan06)
//
////////////////////////////////////////////////////////////////////
//
// 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 PARTSUBSET_H
#define PARTSUBSET_H
#include "pandabase.h"
#include "globPattern.h"
////////////////////////////////////////////////////////////////////
// Class : PartSubset
// Description : This class is used to define a subset of part names
// to apply to the PartBundle::bind_anim() operation.
// Only those part names within the subset will be
// included in the bind.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA PartSubset {
PUBLISHED:
PartSubset();
PartSubset(const PartSubset &copy);
void operator = (const PartSubset &copy);
void add_include_joint(const GlobPattern &name);
void add_exclude_joint(const GlobPattern &name);
void append(const PartSubset &other);
void output(ostream &out) const;
bool is_empty() const;
bool matches_include(const string &joint_name) const;
bool matches_exclude(const string &joint_name) const;
private:
typedef pvector<GlobPattern> Joints;
Joints _include_joints;
Joints _exclude_joints;
};
INLINE ostream &operator << (ostream &out, const PartSubset &subset) {
subset.output(out);
return out;
}
#include "partSubset.I"
#endif