00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "movingPartBase.h"
00016 #include "animControl.h"
00017 #include "animChannelBase.h"
00018 #include "bitArray.h"
00019 #include "config_chan.h"
00020 #include "dcast.h"
00021 #include "indent.h"
00022
00023 TypeHandle MovingPartBase::_type_handle;
00024
00025
00026
00027
00028
00029
00030
00031 MovingPartBase::
00032 MovingPartBase(PartGroup *parent, const string &name) :
00033 PartGroup(parent, name),
00034 _num_effective_channels(0),
00035 _effective_control(NULL)
00036 {
00037 }
00038
00039
00040
00041
00042
00043
00044 MovingPartBase::
00045 MovingPartBase() :
00046 _num_effective_channels(0),
00047 _effective_control(NULL)
00048 {
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058 bool MovingPartBase::
00059 clear_forced_channel() {
00060 if (_forced_channel != (AnimChannelBase *)NULL) {
00061 _forced_channel.clear();
00062 return true;
00063 }
00064 return false;
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 AnimChannelBase *MovingPartBase::
00076 get_forced_channel() const {
00077 return _forced_channel;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086 void MovingPartBase::
00087 write(ostream &out, int indent_level) const {
00088 indent(out, indent_level) << get_value_type() << " " << get_name();
00089 if (_children.empty()) {
00090 out << "\n";
00091 } else {
00092 out << " {\n";
00093 write_descendants(out, indent_level + 2);
00094 indent(out, indent_level) << "}\n";
00095 }
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 void MovingPartBase::
00105 write_with_value(ostream &out, int indent_level) const {
00106 indent(out, indent_level) << get_value_type() << " " << get_name() << "\n";
00107 indent(out, indent_level);
00108 output_value(out);
00109
00110 if (_children.empty()) {
00111 out << "\n";
00112 } else {
00113 out << " {\n";
00114 write_descendants_with_value(out, indent_level + 2);
00115 indent(out, indent_level) << "}\n";
00116 }
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 bool MovingPartBase::
00132 do_update(PartBundle *root, const CycleData *root_cdata, PartGroup *parent,
00133 bool parent_changed, bool anim_changed,
00134 Thread *current_thread) {
00135 bool any_changed = false;
00136 bool needs_update = anim_changed;
00137
00138
00139
00140 if (!needs_update) {
00141 if (_forced_channel != (AnimChannelBase *)NULL) {
00142 needs_update = _forced_channel->has_changed(0, 0.0, 0, 0.0);
00143
00144 } else if (_effective_control != (AnimControl *)NULL) {
00145 const PartBundle::CData *cdata = (const PartBundle::CData *)root_cdata;
00146 needs_update = _effective_control->channel_has_changed(_effective_channel, cdata->_frame_blend_flag);
00147
00148 } else {
00149 const PartBundle::CData *cdata = (const PartBundle::CData *)root_cdata;
00150 PartBundle::ChannelBlend::const_iterator bci;
00151 for (bci = cdata->_blend.begin();
00152 !needs_update && bci != cdata->_blend.end();
00153 ++bci) {
00154 AnimControl *control = (*bci).first;
00155
00156 AnimChannelBase *channel = NULL;
00157 int channel_index = control->get_channel_index();
00158 if (channel_index >= 0 && channel_index < (int)_channels.size()) {
00159 channel = _channels[channel_index];
00160 }
00161 if (channel != (AnimChannelBase*)NULL) {
00162 needs_update = control->channel_has_changed(channel, cdata->_frame_blend_flag);
00163 }
00164 }
00165 }
00166 }
00167
00168 if (needs_update) {
00169
00170 get_blend_value(root);
00171 }
00172
00173 if (parent_changed || needs_update) {
00174 any_changed = update_internals(root, parent, needs_update, parent_changed,
00175 current_thread);
00176 }
00177
00178
00179 Children::iterator ci;
00180 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00181 if ((*ci)->do_update(root, root_cdata, this,
00182 parent_changed || needs_update,
00183 anim_changed, current_thread)) {
00184 any_changed = true;
00185 }
00186 }
00187
00188 return any_changed;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 bool MovingPartBase::
00204 update_internals(PartBundle *, PartGroup *, bool, bool, Thread *) {
00205 return true;
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 void MovingPartBase::
00217 pick_channel_index(plist<int> &holes, int &next) const {
00218
00219
00220 plist<int>::iterator ii, ii_next;
00221 ii = holes.begin();
00222 while (ii != holes.end()) {
00223 ii_next = ii;
00224 ++ii_next;
00225
00226 int hole = (*ii);
00227 nassertv(hole >= 0 && hole < next);
00228 if (hole < (int)_channels.size() ||
00229 _channels[hole] != (AnimChannelBase *)NULL) {
00230
00231 holes.erase(ii);
00232 }
00233 ii = ii_next;
00234 }
00235
00236
00237 if (next < (int)_channels.size()) {
00238 int i;
00239 for (i = next; i < (int)_channels.size(); i++) {
00240 if (_channels[i] == (AnimChannelBase*)NULL) {
00241
00242 holes.push_back(i);
00243 }
00244 }
00245 next = _channels.size();
00246 }
00247
00248 PartGroup::pick_channel_index(holes, next);
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 void MovingPartBase::
00260 bind_hierarchy(AnimGroup *anim, int channel_index, int &joint_index,
00261 bool is_included, BitArray &bound_joints,
00262 const PartSubset &subset) {
00263 if (subset.matches_include(get_name())) {
00264 is_included = true;
00265 } else if (subset.matches_exclude(get_name())) {
00266 is_included = false;
00267 }
00268
00269 if (chan_cat.is_debug()) {
00270 if (anim == (AnimGroup *)NULL) {
00271 chan_cat.debug()
00272 << "binding " << *this << " to NULL, is_included = "
00273 << is_included << "\n";
00274 } else {
00275 chan_cat.debug()
00276 << "binding " << *this << " to " << *anim << ", is_included = "
00277 << is_included << "\n";
00278 }
00279 }
00280 while ((int)_channels.size() <= channel_index) {
00281 _channels.push_back((AnimChannelBase*)NULL);
00282 }
00283
00284 nassertv(_channels[channel_index] == (AnimChannelBase*)NULL);
00285
00286 if (is_included) {
00287 if (anim == (AnimGroup*)NULL) {
00288
00289
00290
00291 _channels[channel_index] = make_default_channel();
00292 } else {
00293 _channels[channel_index] = DCAST(AnimChannelBase, anim);
00294 }
00295
00296
00297
00298 bound_joints.set_bit(joint_index);
00299 } else {
00300
00301 bound_joints.clear_bit(joint_index);
00302 }
00303 ++joint_index;
00304
00305 PartGroup::bind_hierarchy(anim, channel_index, joint_index,
00306 is_included, bound_joints, subset);
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 void MovingPartBase::
00321 find_bound_joints(int &joint_index, bool is_included, BitArray &bound_joints,
00322 const PartSubset &subset) {
00323 if (subset.matches_include(get_name())) {
00324 is_included = true;
00325 } else if (subset.matches_exclude(get_name())) {
00326 is_included = false;
00327 }
00328
00329 bound_joints.set_bit_to(joint_index, is_included);
00330 ++joint_index;
00331
00332 PartGroup::find_bound_joints(joint_index, is_included, bound_joints, subset);
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342 void MovingPartBase::
00343 determine_effective_channels(const CycleData *root_cdata) {
00344 _effective_control = NULL;
00345 _effective_channel = NULL;
00346 _num_effective_channels = 0;
00347
00348 AnimControl *effective_control = NULL;
00349 AnimChannelBase *effective_channel = NULL;
00350 int num_effective_channels = 0;
00351
00352 const PartBundle::CData *cdata = (const PartBundle::CData *)root_cdata;
00353 PartBundle::ChannelBlend::const_iterator cbi;
00354 for (cbi = cdata->_blend.begin();
00355 cbi != cdata->_blend.end();
00356 ++cbi) {
00357 AnimControl *control = (*cbi).first;
00358 int channel_index = control->get_channel_index();
00359 if (channel_index >= 0 && channel_index < (int)_channels.size()) {
00360 if (_channels[channel_index] != (AnimChannelBase *)NULL) {
00361 effective_control = control;
00362 effective_channel = _channels[channel_index];
00363 ++num_effective_channels;
00364 }
00365 }
00366 }
00367
00368 _num_effective_channels = num_effective_channels;
00369 if (num_effective_channels == 1) {
00370 _effective_control = effective_control;
00371 _effective_channel = effective_channel;
00372 }
00373
00374 PartGroup::determine_effective_channels(root_cdata);
00375 }
00376
00377
00378
00379
00380
00381
00382
00383 void MovingPartBase::
00384 write_datagram(BamWriter *manager, Datagram &dg) {
00385 PartGroup::write_datagram(manager, dg);
00386
00387 manager->write_pointer(dg, _forced_channel);
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 int MovingPartBase::
00413 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00414 int pi = PartGroup::complete_pointers(p_list, manager);
00415
00416 if (manager->get_file_minor_ver() >= 20) {
00417 _forced_channel = DCAST(AnimChannelBase, p_list[pi++]);
00418 }
00419
00420 return pi;
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430 void MovingPartBase::
00431 fillin(DatagramIterator &scan, BamReader *manager) {
00432 PartGroup::fillin(scan, manager);
00433
00434 if (manager->get_file_minor_ver() >= 20) {
00435 manager->read_pointer(scan);
00436 }
00437 }