mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
half-body animations
This commit is contained in:
parent
1e5469d22f
commit
aa837381d3
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
18
panda/src/chan/animChannelMatrixFixed.I
Normal file
18
panda/src/chan/animChannelMatrixFixed.I
Normal 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
110
panda/src/chan/animChannelMatrixFixed.cxx
Normal file
110
panda/src/chan/animChannelMatrixFixed.cxx
Normal 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;
|
||||
}
|
77
panda/src/chan/animChannelMatrixFixed.h
Normal file
77
panda/src/chan/animChannelMatrixFixed.h
Normal 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
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
|
@ -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,10 +112,10 @@ 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);
|
||||
|
||||
if (channel != (AnimChannelBase*)NULL) {
|
||||
needs_update = control->channel_has_changed(channel);
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_update) {
|
||||
// Ok, get the latest value.
|
||||
@ -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,18 +207,21 @@ 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 (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.
|
||||
@ -226,6 +229,7 @@ bind_hierarchy(AnimGroup *anim, int channel_index) {
|
||||
} else {
|
||||
_channels[channel_index] = DCAST(AnimChannelBase, anim);
|
||||
}
|
||||
|
||||
PartGroup::bind_hierarchy(anim, channel_index);
|
||||
}
|
||||
|
||||
PartGroup::bind_hierarchy(anim, channel_index, is_included, subset);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
} else {
|
||||
channel->get_value(control->get_frame(), _value);
|
||||
}
|
||||
|
||||
} else {
|
||||
// A blend of two or more values.
|
||||
@ -90,18 +107,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 != (ChannelType *)NULL) {
|
||||
ValueType v;
|
||||
channel->get_value(control->get_frame(), v);
|
||||
|
||||
_value += v * effect;
|
||||
net += effect;
|
||||
}
|
||||
}
|
||||
|
||||
nassertv(net != 0.0f);
|
||||
if (net == 0.0f) {
|
||||
_value = _initial_value;
|
||||
} else {
|
||||
_value /= net;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PartBundle::BT_normalized_linear:
|
||||
@ -126,8 +146,7 @@ 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;
|
||||
@ -139,8 +158,12 @@ get_blend_value(const PartBundle *root) {
|
||||
shear += ishear * effect;
|
||||
net += effect;
|
||||
}
|
||||
}
|
||||
|
||||
nassertv(net != 0.0f);
|
||||
if (net == 0.0f) {
|
||||
_value = _initial_value;
|
||||
|
||||
} else {
|
||||
_value /= net;
|
||||
scale /= net;
|
||||
shear /= net;
|
||||
@ -151,6 +174,7 @@ get_blend_value(const PartBundle *root) {
|
||||
decompose_matrix(_value, false_scale, false_shear, hpr, translate);
|
||||
compose_matrix(_value, scale, shear, hpr, translate);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PartBundle::BT_componentwise:
|
||||
@ -171,8 +195,7 @@ 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);
|
||||
@ -185,8 +208,12 @@ get_blend_value(const PartBundle *root) {
|
||||
shear += ishear * effect;
|
||||
net += effect;
|
||||
}
|
||||
}
|
||||
|
||||
nassertv(net != 0.0f);
|
||||
if (net == 0.0f) {
|
||||
_value = _initial_value;
|
||||
|
||||
} else {
|
||||
scale /= net;
|
||||
hpr /= net;
|
||||
pos /= net;
|
||||
@ -194,6 +221,7 @@ get_blend_value(const PartBundle *root) {
|
||||
|
||||
compose_matrix(_value, scale, shear, hpr, pos);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PartBundle::BT_componentwise_quat:
|
||||
@ -215,8 +243,7 @@ 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);
|
||||
@ -230,8 +257,12 @@ get_blend_value(const PartBundle *root) {
|
||||
shear += ishear * effect;
|
||||
net += effect;
|
||||
}
|
||||
}
|
||||
|
||||
nassertv(net != 0.0f);
|
||||
if (net == 0.0f) {
|
||||
_value = _initial_value;
|
||||
|
||||
} else {
|
||||
scale /= net;
|
||||
quat /= net;
|
||||
pos /= net;
|
||||
@ -244,6 +275,7 @@ get_blend_value(const PartBundle *root) {
|
||||
_value = LMatrix4f::scale_shear_mat(scale, shear) * quat;
|
||||
_value.set_row(3, pos);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
} else {
|
||||
channel->get_value(control->get_frame(), _value);
|
||||
}
|
||||
|
||||
} else {
|
||||
// A blend of two or more values.
|
||||
@ -79,19 +83,23 @@ 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);
|
||||
|
||||
_value += v * effect;
|
||||
net += effect;
|
||||
}
|
||||
}
|
||||
|
||||
nassertv(net != 0.0f);
|
||||
if (net == 0.0f) {
|
||||
_value = _initial_value;
|
||||
|
||||
} else {
|
||||
_value /= net;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovingPartScalar::make_MovingPartScalar
|
||||
|
@ -43,8 +43,6 @@ PartBundle(const PartBundle ©) :
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
18
panda/src/chan/partSubset.I
Normal file
18
panda/src/chan/partSubset.I
Normal 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
178
panda/src/chan/partSubset.cxx
Normal file
178
panda/src/chan/partSubset.cxx
Normal 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 ©) :
|
||||
_include_joints(copy._include_joints),
|
||||
_exclude_joints(copy._exclude_joints)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartSubset::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PartSubset::
|
||||
operator = (const PartSubset ©) {
|
||||
_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;
|
||||
}
|
63
panda/src/chan/partSubset.h
Normal file
63
panda/src/chan/partSubset.h
Normal 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 ©);
|
||||
void operator = (const PartSubset ©);
|
||||
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user