15 #include "movingPartBase.h" 16 #include "animControl.h" 17 #include "animChannelBase.h" 19 #include "config_chan.h" 32 MovingPartBase(
PartGroup *parent,
const string &name) :
34 _num_effective_channels(0),
35 _effective_control(NULL)
46 _num_effective_channels(0),
47 _effective_control(NULL)
61 _forced_channel.clear();
77 return _forced_channel;
87 write(ostream &out,
int indent_level)
const {
88 indent(out, indent_level) <<
get_value_type() <<
" " << get_name();
89 if (_children.empty()) {
93 write_descendants(out, indent_level + 2);
94 indent(out, indent_level) <<
"}\n";
106 indent(out, indent_level) <<
get_value_type() <<
" " << get_name() <<
"\n";
107 indent(out, indent_level);
110 if (_children.empty()) {
114 write_descendants_with_value(out, indent_level + 2);
115 indent(out, indent_level) <<
"}\n";
133 bool parent_changed,
bool anim_changed,
135 bool any_changed =
false;
136 bool needs_update = anim_changed;
142 needs_update = _forced_channel->has_changed(0, 0.0, 0, 0.0);
144 }
else if (_effective_control != (
AnimControl *)NULL) {
145 const PartBundle::CData *cdata = (
const PartBundle::CData *)root_cdata;
146 needs_update = _effective_control->
channel_has_changed(_effective_channel, cdata->_frame_blend_flag);
149 const PartBundle::CData *cdata = (
const PartBundle::CData *)root_cdata;
150 PartBundle::ChannelBlend::const_iterator bci;
151 for (bci = cdata->_blend.begin();
152 !needs_update && bci != cdata->_blend.end();
158 if (channel_index >= 0 && channel_index < (
int)_channels.size()) {
159 channel = _channels[channel_index];
170 get_blend_value(root);
173 if (parent_changed || needs_update) {
179 Children::iterator ci;
180 for (ci = _children.begin(); ci != _children.end(); ++ci) {
181 if ((*ci)->do_update(root, root_cdata,
this,
182 parent_changed || needs_update,
183 anim_changed, current_thread)) {
216 void MovingPartBase::
217 pick_channel_index(
plist<int> &holes,
int &next)
const {
222 while (ii != holes.end()) {
227 nassertv(hole >= 0 && hole < next);
228 if (hole < (
int)_channels.size() ||
237 if (next < (
int)_channels.size()) {
239 for (i = next; i < (int)_channels.size(); i++) {
245 next = _channels.size();
248 PartGroup::pick_channel_index(holes, next);
259 void MovingPartBase::
260 bind_hierarchy(
AnimGroup *anim,
int channel_index,
int &joint_index,
261 bool is_included,
BitArray &bound_joints,
269 if (chan_cat.is_debug()) {
272 <<
"binding " << *
this <<
" to NULL, is_included = " 273 << is_included <<
"\n";
276 <<
"binding " << *
this <<
" to " << *anim <<
", is_included = " 277 << is_included <<
"\n";
280 while ((
int)_channels.size() <= channel_index) {
291 _channels[channel_index] = make_default_channel();
298 bound_joints.
set_bit(joint_index);
305 PartGroup::bind_hierarchy(anim, channel_index, joint_index,
306 is_included, bound_joints, subset);
320 void MovingPartBase::
321 find_bound_joints(
int &joint_index,
bool is_included,
BitArray &bound_joints,
329 bound_joints.
set_bit_to(joint_index, is_included);
332 PartGroup::find_bound_joints(joint_index, is_included, bound_joints, subset);
342 void MovingPartBase::
343 determine_effective_channels(
const CycleData *root_cdata) {
344 _effective_control = NULL;
345 _effective_channel = NULL;
346 _num_effective_channels = 0;
350 int num_effective_channels = 0;
352 const PartBundle::CData *cdata = (
const PartBundle::CData *)root_cdata;
353 PartBundle::ChannelBlend::const_iterator cbi;
354 for (cbi = cdata->_blend.begin();
355 cbi != cdata->_blend.end();
359 if (channel_index >= 0 && channel_index < (
int)_channels.size()) {
361 effective_control = control;
362 effective_channel = _channels[channel_index];
363 ++num_effective_channels;
368 _num_effective_channels = num_effective_channels;
369 if (num_effective_channels == 1) {
370 _effective_control = effective_control;
371 _effective_channel = effective_channel;
430 void MovingPartBase::
432 PartGroup::fillin(scan, manager);
bool matches_exclude(const string &joint_name) const
Returns true if the indicated name matches a name on the exclude list, false otherwise.
void set_bit_to(int index, bool value)
Sets the nth bit either on or off, according to the indicated bool value.
bool matches_include(const string &joint_name) const
Returns true if the indicated name matches a name on the include list, false otherwise.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
virtual bool do_update(PartBundle *root, const CycleData *root_cdata, PartGroup *parent, bool parent_changed, bool anim_changed, Thread *current_thread)
Recursively update this particular part and all of its descendents for the current frame...
A single page of data maintained by a PipelineCycler.
Base class for objects that can be written to and read from Bam files.
virtual AnimChannelBase * get_forced_channel() const
Returns the AnimChannelBase that has been forced to this joint by a previous call to apply_freeze() o...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
bool channel_has_changed(AnimChannelBase *channel, bool frame_blend_flag) const
Returns true if the indicated channel value has changed since the last call to mark_channels().
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
void clear_bit(int index)
Sets the nth bit off.
A dynamic array with an unlimited number of bits.
Parent class for all animation channels.
This is the base class for AnimChannel and AnimBundle.
virtual void determine_effective_channels(const CycleData *root_cdata)
Should be called whenever the ChannelBlend values have changed, this recursively updates the _effecti...
virtual void write_with_value(ostream &out, int indent_level) const
Writes a brief description of the channel and all of its descendants, along with their values...
This class is used to define a subset of part names to apply to the PartBundle::bind_anim() operation...
virtual bool update_internals(PartBundle *root, PartGroup *parent, bool self_changed, bool parent_changed, Thread *current_thread)
This is called by do_update() whenever the part or some ancestor has changed values.
void set_bit(int index)
Sets the nth bit on.
A thread; that is, a lightweight process.
This is the root of a MovingPart hierarchy.
virtual bool clear_forced_channel()
Undoes the effect of a previous call to apply_freeze() or apply_control().
int get_channel_index() const
Returns the particular channel index associated with this AnimControl.
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin()...
Controls the timing of a character animation.
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
virtual TypeHandle get_value_type() const =0
Returns the TypeHandle associated with the ValueType we are concerned with.
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Takes in a vector of pointers to TypedWritable objects that correspond to all the requests for pointe...
virtual void write(ostream &out, int indent_level) const
Writes a brief description of the channel and all of its descendants.
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
void read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
This is the base class for PartRoot and MovingPart.