00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "movingPartBase.h"
00021 #include "animControl.h"
00022 #include "animChannelBase.h"
00023
00024 #include <indent.h>
00025
00026 TypeHandle MovingPartBase::_type_handle;
00027
00028
00029
00030
00031
00032
00033
00034 MovingPartBase::
00035 MovingPartBase(PartGroup *parent, const string &name)
00036 : PartGroup(parent, name) {
00037 }
00038
00039
00040
00041
00042
00043
00044 MovingPartBase::
00045 MovingPartBase(void){
00046 }
00047
00048
00049
00050
00051
00052
00053
00054 void MovingPartBase::
00055 write(ostream &out, int indent_level) const {
00056 indent(out, indent_level) << get_value_type() << " " << get_name();
00057 if (_children.empty()) {
00058 out << "\n";
00059 } else {
00060 out << " {\n";
00061 write_descendants(out, indent_level + 2);
00062 indent(out, indent_level) << "}\n";
00063 }
00064 }
00065
00066
00067
00068
00069
00070
00071
00072 void MovingPartBase::
00073 write_with_value(ostream &out, int indent_level) const {
00074 indent(out, indent_level) << get_value_type() << " " << get_name() << "\n";
00075 indent(out, indent_level);
00076 output_value(out);
00077
00078 if (_children.empty()) {
00079 out << "\n";
00080 } else {
00081 out << " {\n";
00082 write_descendants_with_value(out, indent_level + 2);
00083 indent(out, indent_level) << "}\n";
00084 }
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 bool MovingPartBase::
00100 do_update(PartBundle *root, PartGroup *parent,
00101 bool parent_changed, bool anim_changed) {
00102 bool any_changed = false;
00103 bool needs_update = anim_changed;
00104
00105
00106
00107 PartBundle::control_iterator bci;
00108 for (bci = root->control_begin();
00109 !needs_update && bci != root->control_end();
00110 ++bci) {
00111 AnimControl *control = (*bci);
00112 int channel_index = control->get_channel_index();
00113 nassertr(channel_index >= 0 && channel_index < (int)_channels.size(), false);
00114 AnimChannelBase *channel = _channels[channel_index];
00115 nassertr(channel != (AnimChannelBase*)0L, false);
00116
00117 needs_update = control->channel_has_changed(channel);
00118 }
00119
00120 if (needs_update) {
00121
00122 get_blend_value(root);
00123 }
00124
00125 if (parent_changed || needs_update) {
00126 any_changed = update_internals(parent, needs_update, parent_changed);
00127 }
00128
00129
00130 Children::iterator ci;
00131 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00132 if ((*ci)->do_update(root, this, parent_changed || needs_update,
00133 anim_changed)) {
00134 any_changed = true;
00135 }
00136 }
00137
00138 return any_changed;
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 bool MovingPartBase::
00154 update_internals(PartGroup *, bool, bool) {
00155 return false;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 void MovingPartBase::
00167 pick_channel_index(plist<int> &holes, int &next) const {
00168
00169
00170 plist<int>::iterator ii, ii_next;
00171 ii = holes.begin();
00172 while (ii != holes.end()) {
00173 ii_next = ii;
00174 ++ii_next;
00175
00176 int hole = (*ii);
00177 nassertv(hole >= 0 && hole < next);
00178 if (hole < (int)_channels.size() ||
00179 _channels[hole] != (AnimChannelBase *)NULL) {
00180
00181 holes.erase(ii);
00182 }
00183 ii = ii_next;
00184 }
00185
00186
00187 if (next < (int)_channels.size()) {
00188 int i;
00189 for (i = next; i < (int)_channels.size(); i++) {
00190 if (_channels[i] == (AnimChannelBase*)0L) {
00191
00192 holes.push_back(i);
00193 }
00194 }
00195 next = _channels.size();
00196 }
00197
00198 PartGroup::pick_channel_index(holes, next);
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 void MovingPartBase::
00210 bind_hierarchy(AnimGroup *anim, int channel_index) {
00211 while ((int)_channels.size() <= channel_index) {
00212 _channels.push_back((AnimChannelBase*)0L);
00213 }
00214
00215 nassertv(_channels[channel_index] == (AnimChannelBase*)0L);
00216
00217 if (anim == (AnimGroup*)0L) {
00218
00219
00220
00221 _channels[channel_index] = make_initial_channel();
00222 } else {
00223 _channels[channel_index] = DCAST(AnimChannelBase, anim);
00224 }
00225
00226 PartGroup::bind_hierarchy(anim, channel_index);
00227 }