00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "movingPartScalar.h"
00017 #include "animChannelScalarDynamic.h"
00018 #include "datagram.h"
00019 #include "datagramIterator.h"
00020 #include "bamReader.h"
00021 #include "bamWriter.h"
00022
00023
00024 #ifdef __GNUC__
00025 #pragma implementation
00026 #endif
00027
00028 TypeHandle MovingPartScalar::_type_handle;
00029
00030
00031
00032
00033
00034
00035 MovingPartScalar::
00036 ~MovingPartScalar() {
00037 }
00038
00039
00040
00041
00042
00043
00044
00045
00046 void MovingPartScalar::
00047 get_blend_value(const PartBundle *root) {
00048
00049
00050
00051 if (_forced_channel != (AnimChannelBase *)NULL) {
00052 ChannelType *channel = DCAST(ChannelType, _forced_channel);
00053 channel->get_value(0, _value);
00054 return;
00055 }
00056
00057 PartBundle::CDReader cdata(root->_cycler);
00058
00059 if (cdata->_blend.empty()) {
00060
00061 if (restore_initial_pose) {
00062 _value = _default_value;
00063 }
00064
00065 } else if (_effective_control != (AnimControl *)NULL &&
00066 !cdata->_frame_blend_flag) {
00067
00068 ChannelType *channel = DCAST(ChannelType, _effective_channel);
00069 channel->get_value(_effective_control->get_frame(), _value);
00070
00071 } else {
00072
00073 _value = 0.0f;
00074 PN_stdfloat net = 0.0f;
00075
00076 PartBundle::ChannelBlend::const_iterator cbi;
00077 for (cbi = cdata->_blend.begin(); cbi != cdata->_blend.end(); ++cbi) {
00078 AnimControl *control = (*cbi).first;
00079 PN_stdfloat effect = (*cbi).second;
00080 nassertv(effect != 0.0f);
00081
00082 ChannelType *channel = NULL;
00083 int channel_index = control->get_channel_index();
00084 if (channel_index >= 0 && channel_index < (int)_channels.size()) {
00085 channel = DCAST(ChannelType, _channels[channel_index]);
00086 }
00087 if (channel != NULL) {
00088 ValueType v;
00089 channel->get_value(control->get_frame(), v);
00090
00091 if (!cdata->_frame_blend_flag) {
00092
00093 _value += v * effect;
00094 } else {
00095
00096 PN_stdfloat frac = (PN_stdfloat)control->get_frac();
00097 _value += v * (effect * (1.0f - frac));
00098
00099 channel->get_value(control->get_next_frame(), v);
00100 _value += v * (effect * frac);
00101 }
00102 net += effect;
00103 }
00104 }
00105
00106 if (net == 0.0f) {
00107 if (restore_initial_pose) {
00108 _value = _default_value;
00109 }
00110
00111 } else {
00112 _value /= net;
00113 }
00114 }
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 bool MovingPartScalar::
00127 apply_freeze_scalar(PN_stdfloat value) {
00128 _forced_channel = new AnimChannelFixed<ACScalarSwitchType>(get_name(), value);
00129 return true;
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 bool MovingPartScalar::
00142 apply_control(PandaNode *node) {
00143 AnimChannelScalarDynamic *chan = new AnimChannelScalarDynamic(get_name());
00144 chan->set_value_node(node);
00145 _forced_channel = chan;
00146 return true;
00147 }
00148
00149
00150
00151
00152
00153
00154 TypedWritable* MovingPartScalar::
00155 make_MovingPartScalar(const FactoryParams ¶ms) {
00156 MovingPartScalar *me = new MovingPartScalar;
00157 DatagramIterator scan;
00158 BamReader *manager;
00159
00160 parse_params(params, scan, manager);
00161 me->fillin(scan, manager);
00162 return me;
00163 }
00164
00165
00166
00167
00168
00169
00170 void MovingPartScalar::
00171 register_with_read_factory() {
00172 BamReader::get_factory()->register_factory(get_class_type(), make_MovingPartScalar);
00173 }
00174