00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "cLerpNodePathInterval.h"
00020 #include "lerp_helpers.h"
00021 #include "transformState.h"
00022 #include "renderState.h"
00023 #include "colorAttrib.h"
00024 #include "colorScaleAttrib.h"
00025 #include "dcast.h"
00026 #include "config_interval.h"
00027
00028 TypeHandle CLerpNodePathInterval::_type_handle;
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 CLerpNodePathInterval::
00059 CLerpNodePathInterval(const string &name, double duration,
00060 CLerpInterval::BlendType blend_type,
00061 bool bake_in_start,
00062 const NodePath &node, const NodePath &other) :
00063 CLerpInterval(name, duration, blend_type),
00064 _node(node),
00065 _other(other),
00066 _flags(0)
00067 {
00068 if (bake_in_start) {
00069 _flags |= F_bake_in_start;
00070 }
00071 _prev_d = 0.0;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 void CLerpNodePathInterval::
00083 priv_initialize(double t) {
00084 check_stopped(get_class_type(), "priv_initialize");
00085 recompute();
00086 _prev_d = 0.0;
00087 _state = S_started;
00088 priv_step(t);
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 void CLerpNodePathInterval::
00100 priv_instant() {
00101 check_stopped(get_class_type(), "priv_instant");
00102 recompute();
00103 _prev_d = 0.0;
00104 _state = S_started;
00105 priv_step(get_duration());
00106 _state = S_final;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 void CLerpNodePathInterval::
00117 priv_step(double t) {
00118 check_started(get_class_type(), "priv_step");
00119 _state = S_started;
00120 double d = compute_delta(t);
00121
00122 if ((_flags & (F_end_pos | F_end_hpr | F_end_scale)) != 0) {
00123
00124 CPT(TransformState) transform;
00125
00126 if (_other.is_empty()) {
00127
00128 transform = _node.get_transform();
00129 } else {
00130
00131
00132 transform = _node.get_transform(_other);
00133 }
00134
00135 LPoint3f pos;
00136 LVecBase3f hpr;
00137 LVecBase3f scale;
00138
00139 if ((_flags & F_end_pos) != 0) {
00140 if ((_flags & F_start_pos) != 0) {
00141 lerp_value(pos, d, _start_pos, _end_pos);
00142
00143 } else if ((_flags & F_bake_in_start) != 0) {
00144
00145 set_start_pos(transform->get_pos());
00146 lerp_value(pos, d, _start_pos, _end_pos);
00147
00148 } else {
00149
00150 pos = transform->get_pos();
00151 lerp_value_from_prev(pos, d, _prev_d, pos, _end_pos);
00152 }
00153 }
00154 if ((_flags & F_end_hpr) != 0) {
00155 if ((_flags & F_start_hpr) != 0) {
00156 lerp_value(hpr, d, _start_hpr, _end_hpr);
00157
00158 } else if ((_flags & F_bake_in_start) != 0) {
00159 set_start_hpr(transform->get_hpr());
00160 lerp_value(hpr, d, _start_hpr, _end_hpr);
00161
00162 } else {
00163 hpr = transform->get_hpr();
00164 lerp_value_from_prev(hpr, d, _prev_d, hpr, _end_hpr);
00165 }
00166 }
00167 if ((_flags & F_end_scale) != 0) {
00168 if ((_flags & F_start_scale) != 0) {
00169 lerp_value(scale, d, _start_scale, _end_scale);
00170
00171 } else if ((_flags & F_bake_in_start) != 0) {
00172 set_start_scale(transform->get_scale());
00173 lerp_value(scale, d, _start_scale, _end_scale);
00174
00175 } else {
00176 scale = transform->get_scale();
00177 lerp_value_from_prev(scale, d, _prev_d, scale, _end_scale);
00178 }
00179 }
00180
00181
00182
00183
00184
00185
00186 switch (_flags & (F_end_pos | F_end_hpr | F_end_scale)) {
00187 case F_end_pos:
00188 transform = transform->set_pos(pos);
00189 break;
00190
00191 case F_end_hpr:
00192 transform = transform->set_hpr(hpr);
00193 break;
00194
00195 case F_end_scale:
00196 transform = transform->set_scale(scale);
00197 break;
00198
00199 case F_end_hpr | F_end_scale:
00200 transform = TransformState::make_pos_hpr_scale(transform->get_pos(), hpr, scale);
00201 break;
00202
00203 case F_end_pos | F_end_hpr:
00204 transform = TransformState::make_pos_hpr_scale(pos, hpr, transform->get_scale());
00205 break;
00206
00207 case F_end_pos | F_end_scale:
00208 if (transform->quat_given()) {
00209 transform = TransformState::make_pos_quat_scale(pos, transform->get_quat(), scale);
00210 } else {
00211 transform = TransformState::make_pos_hpr_scale(pos, transform->get_hpr(), scale);
00212 }
00213 break;
00214
00215 case F_end_pos | F_end_hpr | F_end_scale:
00216 transform = TransformState::make_pos_hpr_scale(pos, hpr, scale);
00217 break;
00218
00219 default:
00220 interval_cat.error()
00221 << "Internal error in CLerpNodePathInterval::priv_step().\n";
00222 }
00223
00224
00225 if (_other.is_empty()) {
00226 _node.set_transform(transform);
00227 } else {
00228 _node.set_transform(_other, transform);
00229 }
00230 }
00231
00232 if ((_flags & (F_end_color | F_end_color_scale)) != 0) {
00233
00234 CPT(RenderState) state;
00235
00236 if (_other.is_empty()) {
00237
00238
00239 state = _node.get_state();
00240 } else {
00241
00242
00243
00244 state = _node.get_state(_other);
00245 }
00246
00247
00248
00249
00250
00251 if ((_flags & F_end_color) != 0) {
00252 Colorf color;
00253
00254 if ((_flags & F_start_color) != 0) {
00255 lerp_value(color, d, _start_color, _end_color);
00256
00257 } else {
00258
00259 color.set(1.0f, 1.0f, 1.0f, 1.0f);
00260 const RenderAttrib *attrib =
00261 state->get_attrib(ColorAttrib::get_class_type());
00262 if (attrib != (const RenderAttrib *)NULL) {
00263 const ColorAttrib *ca = DCAST(ColorAttrib, attrib);
00264 if (ca->get_color_type() == ColorAttrib::T_flat) {
00265 color = ca->get_color();
00266 }
00267 }
00268
00269 lerp_value_from_prev(color, d, _prev_d, color, _end_color);
00270 }
00271
00272 state = state->add_attrib(ColorAttrib::make_flat(color));
00273 }
00274
00275 if ((_flags & F_end_color_scale) != 0) {
00276 LVecBase4f color_scale;
00277
00278 if ((_flags & F_start_color_scale) != 0) {
00279 lerp_value(color_scale, d, _start_color_scale, _end_color_scale);
00280
00281 } else {
00282
00283 color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
00284 const RenderAttrib *attrib =
00285 state->get_attrib(ColorScaleAttrib::get_class_type());
00286 if (attrib != (const RenderAttrib *)NULL) {
00287 const ColorScaleAttrib *csa = DCAST(ColorScaleAttrib, attrib);
00288 color_scale = csa->get_scale();
00289 }
00290
00291 lerp_value_from_prev(color_scale, d, _prev_d, color_scale, _end_color_scale);
00292 }
00293
00294 state = state->add_attrib(ColorScaleAttrib::make(color_scale));
00295 }
00296
00297
00298 if (_other.is_empty()) {
00299 _node.set_state(state);
00300 } else {
00301 _node.set_state(_other, state);
00302 }
00303 }
00304
00305 _prev_d = d;
00306 _curr_t = t;
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 void CLerpNodePathInterval::
00318 priv_reverse_initialize(double t) {
00319 check_stopped(get_class_type(), "priv_reverse_initialize");
00320 recompute();
00321 _state = S_started;
00322 _prev_d = 1.0;
00323 priv_step(t);
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 void CLerpNodePathInterval::
00336 priv_reverse_instant() {
00337 check_stopped(get_class_type(), "priv_reverse_initialize");
00338 recompute();
00339 _state = S_started;
00340 _prev_d = 1.0;
00341 priv_step(0.0);
00342 _state = S_initial;
00343 }
00344
00345
00346
00347
00348
00349
00350 void CLerpNodePathInterval::
00351 output(ostream &out) const {
00352 out << get_name() << ":";
00353
00354 if ((_flags & F_end_pos) != 0) {
00355 out << " pos";
00356 if ((_flags & F_start_pos) != 0) {
00357 out << " from " << _start_pos;
00358 }
00359 out << " to " << _end_pos;
00360 }
00361
00362 if ((_flags & F_end_hpr) != 0) {
00363 out << " hpr";
00364 if ((_flags & F_start_hpr) != 0) {
00365 out << " from " << _start_hpr;
00366 }
00367 out << " to " << _end_hpr;
00368 }
00369
00370 if ((_flags & F_end_scale) != 0) {
00371 out << " scale";
00372 if ((_flags & F_start_scale) != 0) {
00373 out << " from " << _start_scale;
00374 }
00375 out << " to " << _end_scale;
00376 }
00377
00378 if ((_flags & F_end_color) != 0) {
00379 out << " color";
00380 if ((_flags & F_start_color) != 0) {
00381 out << " from " << _start_color;
00382 }
00383 out << " to " << _end_color;
00384 }
00385
00386 if ((_flags & F_end_color_scale) != 0) {
00387 out << " color_scale";
00388 if ((_flags & F_start_color_scale) != 0) {
00389 out << " from " << _start_color_scale;
00390 }
00391 out << " to " << _end_color_scale;
00392 }
00393
00394 out << " dur " << get_duration();
00395 }