56 if (_forced_channel !=
nullptr) {
58 channel->get_value(0, _value);
64 if (cdata->_blend.empty()) {
66 if (restore_initial_pose) {
67 _value = _default_value;
70 }
else if (_effective_control !=
nullptr &&
71 !cdata->_frame_blend_flag) {
74 channel->get_value(_effective_control->get_frame(), _value);
80 switch (cdata->_blend_type) {
81 case PartBundle::BT_linear:
84 LMatrix4 net_value = LMatrix4::zeros_mat();
85 PN_stdfloat net_effect = 0.0f;
87 PartBundle::ChannelBlend::const_iterator cbi;
88 for (cbi = cdata->_blend.begin(); cbi != cdata->_blend.end(); ++cbi) {
90 PN_stdfloat effect = (*cbi).second;
91 nassertv(effect != 0.0f);
94 nassertv(channel_index >= 0 && channel_index < (
int)_channels.size());
96 if (channel !=
nullptr) {
98 channel->get_value(control->
get_frame(), v);
100 if (!cdata->_frame_blend_flag) {
102 net_value += v * effect;
105 PN_stdfloat frac = (PN_stdfloat)control->
get_frac();
106 net_value += v * (effect * (1.0f - frac));
109 net_value += v * (effect * frac);
111 net_effect += effect;
115 if (net_effect == 0.0f) {
116 if (restore_initial_pose) {
117 _value = _default_value;
120 _value = net_value / net_effect;
125 case PartBundle::BT_normalized_linear:
132 LMatrix4 net_value = LMatrix4::zeros_mat();
133 LVecBase3 scale(0.0f, 0.0f, 0.0f);
134 LVecBase3 shear(0.0f, 0.0f, 0.0f);
135 PN_stdfloat net_effect = 0.0f;
137 PartBundle::ChannelBlend::const_iterator cbi;
138 for (cbi = cdata->_blend.begin(); cbi != cdata->_blend.end(); ++cbi) {
140 PN_stdfloat effect = (*cbi).second;
141 nassertv(effect != 0.0f);
145 if (channel_index >= 0 && channel_index < (
int)_channels.size()) {
146 channel = DCAST(
ChannelType, _channels[channel_index]);
148 if (channel !=
nullptr) {
151 LVecBase3 iscale, ishear;
156 if (!cdata->_frame_blend_flag) {
158 net_value += v * effect;
159 scale += iscale * effect;
160 shear += ishear * effect;
163 PN_stdfloat frac = (PN_stdfloat)control->
get_frac();
164 PN_stdfloat e0 = effect * (1.0f - frac);
166 scale += iscale * e0;
167 shear += ishear * e0;
173 PN_stdfloat e1 = effect * frac;
175 scale += iscale * e1;
176 shear += ishear * e1;
178 net_effect += effect;
182 if (net_effect == 0.0f) {
183 if (restore_initial_pose) {
184 _value = _default_value;
188 net_value /= net_effect;
194 LVector3 false_scale, false_shear, hpr, translate;
195 decompose_matrix(net_value, false_scale, false_shear, hpr, translate);
196 compose_matrix(_value, scale, shear, hpr, translate);
201 case PartBundle::BT_componentwise:
204 LVecBase3 scale(0.0f, 0.0f, 0.0f);
205 LVecBase3 hpr(0.0f, 0.0f, 0.0f);
206 LVecBase3 pos(0.0f, 0.0f, 0.0f);
207 LVecBase3 shear(0.0f, 0.0f, 0.0f);
208 PN_stdfloat net_effect = 0.0f;
210 PartBundle::ChannelBlend::const_iterator cbi;
211 for (cbi = cdata->_blend.begin(); cbi != cdata->_blend.end(); ++cbi) {
213 PN_stdfloat effect = (*cbi).second;
214 nassertv(effect != 0.0f);
218 if (channel_index >= 0 && channel_index < (
int)_channels.size()) {
219 channel = DCAST(
ChannelType, _channels[channel_index]);
221 if (channel !=
nullptr) {
223 LVecBase3 iscale, ihpr, ipos, ishear;
229 if (!cdata->_frame_blend_flag) {
231 scale += iscale * effect;
232 hpr += ihpr * effect;
233 pos += ipos * effect;
234 shear += ishear * effect;
237 PN_stdfloat frac = (PN_stdfloat)control->
get_frac();
238 PN_stdfloat e0 = effect * (1.0f - frac);
240 scale += iscale * e0;
243 shear += ishear * e0;
247 channel->
get_hpr(next_frame, ihpr);
248 channel->
get_pos(next_frame, ipos);
250 PN_stdfloat e1 = effect * frac;
252 scale += iscale * e1;
255 shear += ishear * e1;
257 net_effect += effect;
261 if (net_effect == 0.0f) {
262 if (restore_initial_pose) {
263 _value = _default_value;
272 compose_matrix(_value, scale, shear, hpr, pos);
277 case PartBundle::BT_componentwise_quat:
280 LVecBase3 scale(0.0f, 0.0f, 0.0f);
281 LQuaternion quat(0.0f, 0.0f, 0.0f, 0.0f);
282 LVecBase3 pos(0.0f, 0.0f, 0.0f);
283 LVecBase3 shear(0.0f, 0.0f, 0.0f);
284 PN_stdfloat net_effect = 0.0f;
286 PartBundle::ChannelBlend::const_iterator cbi;
287 for (cbi = cdata->_blend.begin(); cbi != cdata->_blend.end(); ++cbi) {
289 PN_stdfloat effect = (*cbi).second;
290 nassertv(effect != 0.0f);
294 if (channel_index >= 0 && channel_index < (
int)_channels.size()) {
295 channel = DCAST(
ChannelType, _channels[channel_index]);
297 if (channel !=
nullptr) {
299 LVecBase3 iscale, ipos, ishear;
306 if (!cdata->_frame_blend_flag) {
308 scale += iscale * effect;
309 quat += iquat * effect;
310 pos += ipos * effect;
311 shear += ishear * effect;
315 PN_stdfloat frac = (PN_stdfloat)control->
get_frac();
316 PN_stdfloat e0 = effect * (1.0f - frac);
318 scale += iscale * e0;
321 shear += ishear * e0;
325 channel->
get_quat(next_frame, iquat);
326 channel->
get_pos(next_frame, ipos);
328 PN_stdfloat e1 = effect * frac;
330 scale += iscale * e1;
333 shear += ishear * e1;
335 net_effect += effect;
339 if (net_effect == 0.0f) {
340 if (restore_initial_pose) {
341 _value = _default_value;
353 _value = LMatrix4::scale_shear_mat(scale, shear) * quat;
354 _value.set_row(3, pos);