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_norm_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");
546void CLerpNodePathInterval::
547output(std::ostream &out)
const {
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;
614void 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;
660void CLerpNodePathInterval::
661slerp_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());
682void CLerpNodePathInterval::
683slerp_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());
706void CLerpNodePathInterval::
707slerp_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());
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_name
Returns the interval's name.
get_duration
Returns the duration of the interval in seconds.
The base class for a family of intervals that linearly interpolate one or more numeric values over ti...
void set_start_scale(const LVecBase3 &scale)
Indicates the initial scale of the lerped node.
void set_start_hpr(const LVecBase3 &hpr)
Indicates the initial rotation of the lerped node.
virtual void priv_instant()
This is called in lieu of priv_initialize() .
virtual void priv_initialize(double t)
This replaces the first call to priv_step(), and indicates that the interval has just begun.
virtual void priv_reverse_initialize(double t)
Similar to priv_initialize(), but this is called when the interval is being played backwards; it indi...
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...
void set_start_quat(const LQuaternion &quat)
Indicates the initial rotation of the lerped node.
virtual void priv_step(double t)
Advances the time on the interval.
virtual void priv_reverse_instant()
This is called in lieu of priv_reverse_initialize() .
void set_start_pos(const LVecBase3 &pos)
Indicates the initial position of the lerped node.
void set_start_shear(const LVecBase3 &shear)
Indicates the initial shear of the lerped node.
Indicates what color should be applied to renderable geometry.
get_color
If the type is T_flat or T_off, this returns the color that will be applied to geometry.
get_color_type
Returns the type of color specified by this ColorAttrib.
Applies a scale to colors in the scene graph and on vertices.
get_scale
Returns the scale to be applied to colors.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
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.
void set_quat(const LQuaternion &quat)
Sets the rotation component of the transform, leaving translation and scale untouched.
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.
LVecBase3 get_hpr() const
Retrieves the rotation component of the transform.
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.
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.
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.
bool is_empty() const
Returns true if the NodePath contains no nodes.
void set_pos_quat(const LVecBase3 &pos, const LQuaternion &quat)
Sets the translation and rotation component of the transform, leaving scale untouched.
LQuaternion get_quat() const
Retrieves the rotation component of the transform.
void set_state(const RenderState *state, Thread *current_thread=Thread::get_current_thread())
Changes the complete state object on this node.
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.
const RenderState * get_state(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete state object set on this node.
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.
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.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
void set_scale(PN_stdfloat scale)
Sets the scale component of the transform, leaving translation and rotation untouched.
void set_quat_scale(const LQuaternion &quat, const LVecBase3 &scale)
Sets the rotation and scale components of the transform, leaving translation untouched.
void set_hpr(PN_stdfloat h, PN_stdfloat p, PN_stdfloat r)
Sets the rotation component of the transform, leaving translation and scale untouched.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
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.
Defines the properties of a named stage of the multitexture pipeline.
TypeHandle is the identifier used to differentiate C++ class types.
float csin_over_x(float v)
Computes sin(x) / x, well-behaved as x approaches 0.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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 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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.