24 TypeHandle CLerpNodePathInterval::_type_handle;
51 CLerpInterval::BlendType blend_type,
52 bool bake_in_start,
bool fluid,
63 _flags |= F_bake_in_start;
78 check_stopped(get_class_type(),
"priv_initialize");
92 check_stopped(get_class_type(),
"priv_instant");
107 check_started(get_class_type(),
"priv_step");
109 double d = compute_delta(t);
114 if ((_flags & (F_end_pos | F_end_hpr | F_end_quat | F_end_scale | F_end_shear)) != 0) {
133 if ((_flags & F_end_pos) != 0) {
134 if ((_flags & F_start_pos) != 0) {
137 }
else if ((_flags & F_bake_in_start) != 0) {
144 pos = transform->get_pos();
148 if ((_flags & F_end_hpr) != 0) {
149 if ((_flags & F_start_hpr) != 0) {
152 }
else if ((_flags & F_start_quat) != 0) {
153 _start_hpr = _start_quat.get_hpr();
154 _flags |= F_start_hpr;
157 }
else if ((_flags & F_bake_in_start) != 0) {
162 hpr = transform->get_hpr();
166 if ((_flags & F_end_quat) != 0) {
167 if ((_flags & F_slerp_setup) == 0) {
168 if ((_flags & F_start_quat) != 0) {
171 }
else if ((_flags & F_start_hpr) != 0) {
172 _start_quat.set_hpr(_start_hpr);
173 _flags |= F_start_quat;
176 }
else if ((_flags & F_bake_in_start) != 0) {
181 if (_prev_d == 1.0) {
182 _start_quat = _end_quat;
184 LQuaternion prev_value = transform->get_quat();
185 _start_quat = (prev_value - _prev_d * _end_quat) / (1.0 - _prev_d);
191 _flags &= ~F_slerp_setup;
194 nassertv(_slerp !=
nullptr);
195 (this->*_slerp)(quat, d);
197 if ((_flags & F_end_scale) != 0) {
198 if ((_flags & F_start_scale) != 0) {
199 lerp_value(scale, d, _start_scale, _end_scale);
201 }
else if ((_flags & F_bake_in_start) != 0) {
203 lerp_value(scale, d, _start_scale, _end_scale);
206 scale = transform->get_scale();
210 if ((_flags & F_end_shear) != 0) {
211 if ((_flags & F_start_shear) != 0) {
212 lerp_value(shear, d, _start_shear, _end_shear);
214 }
else if ((_flags & F_bake_in_start) != 0) {
216 lerp_value(shear, d, _start_shear, _end_shear);
219 shear = transform->get_shear();
228 unsigned int transform_flags = _flags & (F_end_pos | F_end_hpr | F_end_quat | F_end_scale);
229 switch (transform_flags) {
237 _node.set_pos(_other, pos);
265 case F_end_hpr | F_end_scale:
273 case F_end_quat | F_end_scale:
281 case F_end_pos | F_end_hpr:
289 case F_end_pos | F_end_quat:
297 case F_end_pos | F_end_scale:
298 if (transform->quat_given()) {
313 case F_end_pos | F_end_hpr | F_end_scale:
314 if ((_flags & F_end_shear) != 0) {
331 case F_end_pos | F_end_quat | F_end_scale:
332 if ((_flags & F_end_shear) != 0) {
352 <<
"Internal error in CLerpNodePathInterval::priv_step().\n";
354 if ((_flags & F_end_shear) != 0) {
356 if (transform_flags == (F_end_pos | F_end_hpr | F_end_scale) ||
357 transform_flags == (F_end_pos | F_end_quat | F_end_scale)) {
370 if ((_flags & F_fluid) != 0) {
374 _node.set_prev_transform(prev_transform);
377 if ((_flags & (F_end_color | F_end_color_scale | F_end_tex_offset | F_end_tex_rotate | F_end_tex_scale)) != 0) {
396 if ((_flags & F_end_color) != 0) {
399 if ((_flags & F_start_color) != 0) {
400 lerp_value(color, d, _start_color, _end_color);
404 color.set(1.0f, 1.0f, 1.0f, 1.0f);
406 state->get_attrib(ColorAttrib::get_class_type());
407 if (attrib !=
nullptr) {
417 state = state->add_attrib(ColorAttrib::make_flat(color), _override);
420 if ((_flags & F_end_color_scale) != 0) {
421 LVecBase4 color_scale;
423 if ((_flags & F_start_color_scale) != 0) {
424 lerp_value(color_scale, d, _start_color_scale, _end_color_scale);
428 color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
430 state->get_attrib(ColorScaleAttrib::get_class_type());
431 if (attrib !=
nullptr) {
439 state = state->add_attrib(ColorScaleAttrib::make(color_scale), _override);
442 if ((_flags & (F_end_tex_offset | F_end_tex_rotate | F_end_tex_scale)) != 0) {
447 state->get_attrib(TexMatrixAttrib::get_class_type());
449 if (attrib !=
nullptr) {
451 transform = tma->get_transform(_texture_stage);
456 if ((_flags & F_end_tex_offset) != 0) {
457 LVecBase2 tex_offset;
459 if ((_flags & F_start_tex_offset) != 0) {
460 lerp_value(tex_offset, d, _start_tex_offset, _end_tex_offset);
462 tex_offset = transform->get_pos2d();
467 transform = transform->set_pos2d(tex_offset);
470 if ((_flags & F_end_tex_rotate) != 0) {
471 PN_stdfloat tex_rotate;
473 if ((_flags & F_start_tex_rotate) != 0) {
474 lerp_value(tex_rotate, d, _start_tex_rotate, _end_tex_rotate);
476 tex_rotate = transform->get_rotate2d();
481 transform = transform->set_rotate2d(tex_rotate);
484 if ((_flags & F_end_tex_scale) != 0) {
487 if ((_flags & F_start_tex_scale) != 0) {
488 lerp_value(tex_scale, d, _start_tex_scale, _end_tex_scale);
490 tex_scale = transform->get_scale2d();
495 transform = transform->set_scale2d(tex_scale);
499 state = state->set_attrib(tma->add_stage(_texture_stage, transform, _override));
520 check_stopped(get_class_type(),
"priv_reverse_initialize");
535 check_stopped(get_class_type(),
"priv_reverse_initialize");
546 void CLerpNodePathInterval::
547 output(std::ostream &out)
const {
548 out << get_name() <<
":";
550 if ((_flags & F_end_pos) != 0) {
552 if ((_flags & F_start_pos) != 0) {
553 out <<
" from " << _start_pos;
555 out <<
" to " << _end_pos;
558 if ((_flags & F_end_hpr) != 0) {
560 if ((_flags & F_start_hpr) != 0) {
561 out <<
" from " << _start_hpr;
563 out <<
" to " << _end_hpr;
566 if ((_flags & F_end_quat) != 0) {
568 if ((_flags & F_start_quat) != 0) {
569 out <<
" from " << _start_quat;
571 out <<
" to " << _end_quat;
574 if ((_flags & F_end_scale) != 0) {
576 if ((_flags & F_start_scale) != 0) {
577 out <<
" from " << _start_scale;
579 out <<
" to " << _end_scale;
582 if ((_flags & F_end_shear) != 0) {
584 if ((_flags & F_start_shear) != 0) {
585 out <<
" from " << _start_shear;
587 out <<
" to " << _end_shear;
590 if ((_flags & F_end_color) != 0) {
592 if ((_flags & F_start_color) != 0) {
593 out <<
" from " << _start_color;
595 out <<
" to " << _end_color;
598 if ((_flags & F_end_color_scale) != 0) {
599 out <<
" color_scale";
600 if ((_flags & F_start_color_scale) != 0) {
601 out <<
" from " << _start_color_scale;
603 out <<
" to " << _end_color_scale;
614 void CLerpNodePathInterval::
616 if (_start_quat.dot(_end_quat) < 0.0f) {
618 _start_quat = -_start_quat;
621 _slerp_angle = _start_quat.angle_rad(_end_quat);
623 if (_slerp_angle < 0.1f) {
628 _slerp = &CLerpNodePathInterval::slerp_angle_0;
630 }
else if (_slerp_angle > 3.14) {
638 _slerp_c = (_start_quat + _end_quat);
639 _slerp_c.normalize();
640 _slerp_angle = _end_quat.angle_rad(_slerp_c);
641 _slerp_denom = csin(_slerp_angle);
643 _slerp = &CLerpNodePathInterval::slerp_angle_180;
647 _slerp_denom = csin(_slerp_angle);
648 _slerp = &CLerpNodePathInterval::slerp_basic;
651 nassertv(_slerp_denom != 0.0f);
652 _flags |= F_slerp_setup;
660 void CLerpNodePathInterval::
661 slerp_basic(LQuaternion &result, PN_stdfloat t)
const {
662 nassertv(_slerp_denom != 0.0f);
663 PN_stdfloat ti = 1.0f - t;
664 PN_stdfloat ta = t * _slerp_angle;
665 PN_stdfloat tia = ti * _slerp_angle;
667 if (interval_cat.is_spam()) {
669 <<
"slerp_basic, (t = " << t <<
"), angle = " << _slerp_angle <<
"\n" 670 <<
"_start_quat = " << _start_quat <<
", _end_quat = " 671 << _end_quat <<
", denom = " << _slerp_denom <<
"\n";
674 result = (csin(tia) * _start_quat + csin(ta) * _end_quat) / _slerp_denom;
675 nassertv(!result.is_nan());
682 void CLerpNodePathInterval::
683 slerp_angle_0(LQuaternion &result, PN_stdfloat t)
const {
684 nassertv(_slerp_denom != 0.0f);
685 PN_stdfloat ti = 1.0f - t;
686 PN_stdfloat ta = t * _slerp_angle;
687 PN_stdfloat tia = ti * _slerp_angle;
689 if (interval_cat.is_spam()) {
691 <<
"slerp_angle_0, (t = " << t <<
"), angle = " << _slerp_angle
692 <<
"\n_start_quat = " << _start_quat <<
", _end_quat = " 693 << _end_quat <<
", denom = " << _slerp_denom <<
"\n";
697 nassertv(!result.is_nan());
706 void CLerpNodePathInterval::
707 slerp_angle_180(LQuaternion &result, PN_stdfloat t)
const {
708 nassertv(_slerp_denom != 0.0f);
714 PN_stdfloat ti = 1.0f - t;
715 PN_stdfloat ta = t * _slerp_angle;
716 PN_stdfloat tia = ti * _slerp_angle;
718 if (interval_cat.is_spam()) {
720 <<
"slerp_angle_180, first half (t = " << t <<
"), angle = " 721 << _slerp_angle <<
"\n_start_quat = " << _start_quat
722 <<
", _slerp_c = " << _slerp_c <<
", denom = " 723 << _slerp_denom <<
"\n";
726 result = (csin(tia) * _start_quat + csin(ta) * _slerp_c) / _slerp_denom;
732 PN_stdfloat ti = 1.0f - t;
733 PN_stdfloat ta = t * _slerp_angle;
734 PN_stdfloat tia = ti * _slerp_angle;
736 if (interval_cat.is_spam()) {
738 <<
"slerp_angle_180, second half (t = " << t <<
"), angle = " 739 << _slerp_angle <<
"\n_slerp_c = " << _slerp_c
740 <<
", _end_quat = " << _end_quat <<
", denom = " 741 << _slerp_denom <<
"\n";
744 result = (csin(tia) * _slerp_c + csin(ta) * _end_quat) / _slerp_denom;
747 nassertv(!result.is_nan());
void set_start_scale(const LVecBase3 &scale)
Indicates the initial scale of the lerped node.
void set_start_shear(const LVecBase3 &shear)
Indicates the initial shear of the lerped node.
void set_start_hpr(const LVecBase3 &hpr)
Indicates the initial rotation of the lerped node.
virtual void priv_initialize(double t)
This replaces the first call to priv_step(), and indicates that the interval has just begun.
void set_hpr_scale(PN_stdfloat h, PN_stdfloat p, PN_stdfloat r, PN_stdfloat sx, PN_stdfloat sy, PN_stdfloat sz)
Sets the rotation and scale components of the transform, leaving translation untouched.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
void set_pos_hpr(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat h, PN_stdfloat p, PN_stdfloat r)
Sets the translation and rotation component of the transform, leaving scale untouched.
bool is_empty() const
Returns true if the NodePath contains no nodes.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_scale(PN_stdfloat scale)
Sets the scale component of the transform, leaving translation and rotation untouched.
get_color
If the type is T_flat or T_off, this returns the color that will be applied to geometry.
void set_start_quat(const LQuaternion &quat)
Indicates the initial rotation of the lerped node.
float csin_over_x(float v)
Computes sin(x) / x, well-behaved as x approaches 0.
void set_quat_scale(const LQuaternion &quat, const LVecBase3 &scale)
Sets the rotation and scale components of the transform, leaving translation untouched.
void set_pos_quat(const LVecBase3 &pos, const LQuaternion &quat)
Sets the translation and rotation component of the transform, leaving scale untouched.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_pos_quat_scale_shear(const LVecBase3 &pos, const LQuaternion &quat, const LVecBase3 &scale, const LVecBase3 &shear)
Completely replaces the transform with new translation, rotation, scale, and shear components.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_scale
Returns the scale to be applied to colors.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void lerp_value_from_prev(NumericType ¤t_value, double d, double prev_d, const NumericType &prev_value, const NumericType &ending_value)
Applies the linear lerp computation for a single parameter, when the starting value is implicit.
void set_pos_quat_scale(const LVecBase3 &pos, const LQuaternion &quat, const LVecBase3 &scale)
Replaces the translation, rotation, and scale components, implicitly setting shear to 0.
void lerp_value(NumericType ¤t_value, double d, const NumericType &starting_value, const NumericType &ending_value)
Applies the linear lerp computation for a single parameter.
void set_quat(const LQuaternion &quat)
Sets the rotation component of the transform, leaving translation and scale untouched.
virtual void priv_reverse_initialize(double t)
Similar to priv_initialize(), but this is called when the interval is being played backwards; it indi...
virtual void priv_step(double t)
Advances the time on the interval.
LVecBase3 get_hpr() const
Retrieves the rotation component of the transform.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
LQuaternion get_quat() const
Retrieves the rotation component of the transform.
Applies a scale to colors in the scene graph and on vertices.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Applies a transform matrix to UV's before they are rendered.
void set_shear(PN_stdfloat shxy, PN_stdfloat shxz, PN_stdfloat shyz)
Sets the shear component of the transform, leaving translation, rotation, and scale untouched.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_hpr(PN_stdfloat h, PN_stdfloat p, PN_stdfloat r)
Sets the rotation component of the transform, leaving translation and scale untouched.
void set_pos_hpr_scale_shear(const LVecBase3 &pos, const LVecBase3 &hpr, const LVecBase3 &scale, const LVecBase3 &shear)
Completely replaces the transform with new translation, rotation, scale, and shear components.
CLerpNodePathInterval(const std::string &name, double duration, BlendType blend_type, bool bake_in_start, bool fluid, const NodePath &node, const NodePath &other)
Constructs a lerp interval that will lerp some properties on the indicated node, possibly relative to...
Indicates what color should be applied to renderable geometry.
void set_start_pos(const LVecBase3 &pos)
Indicates the initial position of the lerped node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_duration
Returns the duration of the interval in seconds.
void set_pos_hpr_scale(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat h, PN_stdfloat p, PN_stdfloat r, PN_stdfloat sx, PN_stdfloat sy, PN_stdfloat sz)
Completely replaces the transform with new translation, rotation, and scale components.
TypeHandle is the identifier used to differentiate C++ class types.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Defines the properties of a named stage of the multitexture pipeline.
get_color_type
Returns the type of color specified by this ColorAttrib.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
void set_state(const RenderState *state, Thread *current_thread=Thread::get_current_thread())
Changes the complete state object on this node.
virtual void priv_reverse_instant()
This is called in lieu of priv_reverse_initialize() .
The base class for a family of intervals that linearly interpolate one or more numeric values over ti...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const TransformState * get_prev_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the transform that has been set as this node's "previous" position.
const RenderState * get_state(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete state object set on this node.
virtual void priv_instant()
This is called in lieu of priv_initialize() .