diff --git a/direct/src/extensions/NodePath-extensions.py b/direct/src/extensions/NodePath-extensions.py index 3fac653785..7f5850f9b7 100644 --- a/direct/src/extensions/NodePath-extensions.py +++ b/direct/src/extensions/NodePath-extensions.py @@ -943,6 +943,10 @@ import LerpInterval return LerpInterval.LerpScaleInterval(self, *args, **kw) + def shearInterval(self, *args, **kw): + import LerpInterval + return LerpInterval.LerpShearInterval(self, *args, **kw) + def posHprInterval(self, *args, **kw): import LerpInterval return LerpInterval.LerpPosHprInterval(self, *args, **kw) @@ -955,6 +959,10 @@ import LerpInterval return LerpInterval.LerpPosHprScaleInterval(self, *args, **kw) + def posHprScaleShearInterval(self, *args, **kw): + import LerpInterval + return LerpInterval.LerpPosHprScaleShearInterval(self, *args, **kw) + def colorInterval(self, *args, **kw): import LerpInterval return LerpInterval.LerpColorInterval(self, *args, **kw) diff --git a/direct/src/interval/LerpInterval.py b/direct/src/interval/LerpInterval.py index e654e5a0aa..898ff7952d 100644 --- a/direct/src/interval/LerpInterval.py +++ b/direct/src/interval/LerpInterval.py @@ -56,12 +56,12 @@ class LerpNodePathInterval(CLerpNodePathInterval): ##################################################################### ## ## It is legal to pass in a functor (a callable Python function that -## returns an appropriate value) for the any of the pos, hpr, or -## scale parameters in the intervals below. These will be evaluated -## at the time the interval starts in order to determine the actual -## final (or initial) position. However, doing so forces the entire -## LerpInterval to be executed up in Python, instead of down in the -## low-level C++ code, at some performance cost. +## returns an appropriate value) for the any of the pos, hpr, scale, +## or shear parameters in the intervals below. These will be +## evaluated at the time the interval starts in order to determine +## the actual final (or initial) position. However, doing so forces +## the entire LerpInterval to be executed up in Python, instead of +## down in the low-level C++ code, at some performance cost. ## ## If bakeInStart is true, the starting values (if unspecified) are ## computed at the time the interval runs for the first time, and @@ -150,6 +150,31 @@ class LerpScaleInterval(LerpNodePathInterval): self.setupParam(self.setStartScale, self.startScale) LerpNodePathInterval.privDoEvent(self, t, event) +class LerpShearInterval(LerpNodePathInterval): + def __init__(self, node, duration, shear, startShear = None, + other = None, blendType = 'noBlend', + bakeInStart = 1, name = None): + LerpNodePathInterval.__init__(self, name, duration, blendType, + bakeInStart, node, other) + # Check for functors in the input parameters. + self.paramSetup = self.anyCallable(shear, startShear) + if self.paramSetup: + self.endShear = shear + self.startShear = startShear + self.inPython = 1 + else: + self.setEndShear(shear) + if startShear != None: + self.setStartShear(startShear) + + def privDoEvent(self, t, event): + # This function is only used if Python functors were passed in + # for some of the input parameters. + if self.paramSetup and event == CInterval.ETInitialize: + self.setupParam(self.setEndShear, self.endShear) + self.setupParam(self.setStartShear, self.startShear) + LerpNodePathInterval.privDoEvent(self, t, event) + class LerpPosHprInterval(LerpNodePathInterval): def __init__(self, node, duration, pos, hpr, startPos = None, startHpr = None, @@ -257,6 +282,53 @@ class LerpPosHprScaleInterval(LerpNodePathInterval): self.setupParam(self.setStartScale, self.startScale) LerpNodePathInterval.privDoEvent(self, t, event) +class LerpPosHprScaleShearInterval(LerpNodePathInterval): + def __init__(self, node, duration, pos, hpr, scale, shear, + startPos = None, startHpr = None, startScale = None, startShear = None, + other = None, blendType = 'noBlend', + bakeInStart = 1, name = None): + LerpNodePathInterval.__init__(self, name, duration, blendType, + bakeInStart, node, other) + # Check for functors in the input parameters. + self.paramSetup = self.anyCallable(pos, startPos, hpr, startHpr, scale, startScale, shear, startShear) + if self.paramSetup: + self.endPos = pos + self.startPos = startPos + self.endHpr = hpr + self.startHpr = startHpr + self.endScale = scale + self.startScale = startScale + self.endShear = shear + self.startShear = startShear + self.inPython = 1 + else: + self.setEndPos(pos) + if startPos != None: + self.setStartPos(startPos) + self.setEndHpr(hpr) + if startHpr != None: + self.setStartHpr(startHpr) + self.setEndScale(scale) + if startScale != None: + self.setStartScale(startScale) + self.setEndShear(shear) + if startShear != None: + self.setStartShear(startShear) + + def privDoEvent(self, t, event): + # This function is only used if Python functors were passed in + # for some of the input parameters. + if self.paramSetup and event == CInterval.ETInitialize: + self.setupParam(self.setEndPos, self.endPos) + self.setupParam(self.setStartPos, self.startPos) + self.setupParam(self.setEndHpr, self.endHpr) + self.setupParam(self.setStartHpr, self.startHpr) + self.setupParam(self.setEndScale, self.endScale) + self.setupParam(self.setStartScale, self.startScale) + self.setupParam(self.setEndShear, self.endShear) + self.setupParam(self.setStartShear, self.startShear) + LerpNodePathInterval.privDoEvent(self, t, event) + class LerpColorScaleInterval(LerpNodePathInterval): def __init__(self, node, duration, colorScale, startColorScale = None, other = None, blendType = 'noBlend', diff --git a/direct/src/interval/cLerpNodePathInterval.I b/direct/src/interval/cLerpNodePathInterval.I index 5304a337eb..d8a4d34af1 100644 --- a/direct/src/interval/cLerpNodePathInterval.I +++ b/direct/src/interval/cLerpNodePathInterval.I @@ -158,6 +158,36 @@ set_end_scale(float scale) { set_end_scale(LVecBase3f(scale, scale, scale)); } +//////////////////////////////////////////////////////////////////// +// Function: CLerpNodePathInterval::set_start_shear +// Access: Published +// Description: Indicates the initial shear of the lerped node. +// This is meaningful only if set_end_shear() is also +// called. This parameter is optional; if unspecified, +// the value will be taken from the node's actual +// shear at the time the lerp is performed. +//////////////////////////////////////////////////////////////////// +INLINE void CLerpNodePathInterval:: +set_start_shear(const LVecBase3f &shear) { + _start_shear = shear; + _flags |= F_start_shear; +} + +//////////////////////////////////////////////////////////////////// +// Function: CLerpNodePathInterval::set_end_shear +// Access: Published +// Description: Indicates that the shear of the node should be +// lerped, and specifies the final shear of the node. +// This should be called before priv_initialize(). If this +// is not called, the node's shear will not be +// affected by the lerp. +//////////////////////////////////////////////////////////////////// +INLINE void CLerpNodePathInterval:: +set_end_shear(const LVecBase3f &shear) { + _end_shear = shear; + _flags |= F_end_shear; +} + //////////////////////////////////////////////////////////////////// // Function: CLerpNodePathInterval::set_start_color // Access: Published diff --git a/direct/src/interval/cLerpNodePathInterval.cxx b/direct/src/interval/cLerpNodePathInterval.cxx index 5a99ff9919..e991f1ca09 100644 --- a/direct/src/interval/cLerpNodePathInterval.cxx +++ b/direct/src/interval/cLerpNodePathInterval.cxx @@ -119,7 +119,7 @@ priv_step(double t) { _state = S_started; double d = compute_delta(t); - if ((_flags & (F_end_pos | F_end_hpr | F_end_scale)) != 0) { + if ((_flags & (F_end_pos | F_end_hpr | F_end_scale | F_end_shear)) != 0) { // We have some transform lerp. CPT(TransformState) transform; @@ -135,6 +135,7 @@ priv_step(double t) { LPoint3f pos; LVecBase3f hpr; LVecBase3f scale; + LVecBase3f shear; if ((_flags & F_end_pos) != 0) { if ((_flags & F_start_pos) != 0) { @@ -177,6 +178,19 @@ priv_step(double t) { lerp_value_from_prev(scale, d, _prev_d, scale, _end_scale); } } + if ((_flags & F_end_shear) != 0) { + if ((_flags & F_start_shear) != 0) { + lerp_value(shear, d, _start_shear, _end_shear); + + } else if ((_flags & F_bake_in_start) != 0) { + set_start_shear(transform->get_shear()); + lerp_value(shear, d, _start_shear, _end_shear); + + } else { + shear = transform->get_shear(); + lerp_value_from_prev(shear, d, _prev_d, shear, _end_shear); + } + } // Now apply the modifications back to the transform. We want to // be a little careful here, because we don't want to assume the @@ -184,6 +198,9 @@ priv_step(double t) { // in any case, we only want to apply the components that we // computed, above. switch (_flags & (F_end_pos | F_end_hpr | F_end_scale)) { + case 0: + break; + case F_end_pos: if (_other.is_empty()) { _node.set_pos(pos); @@ -241,17 +258,43 @@ priv_step(double t) { break; case F_end_pos | F_end_hpr | F_end_scale: - if (_other.is_empty()) { - _node.set_pos_hpr_scale(pos, hpr, scale); + if ((_flags & F_end_shear) != 0) { + // Even better: we have all four components. + if (_other.is_empty()) { + _node.set_pos_hpr_scale_shear(pos, hpr, scale, shear); + } else { + _node.set_pos_hpr_scale_shear(_other, pos, hpr, scale, shear); + } } else { - _node.set_pos_hpr_scale(_other, pos, hpr, scale); + // We have only the primary three components. + if (_other.is_empty()) { + _node.set_pos_hpr_scale(pos, hpr, scale); + } else { + _node.set_pos_hpr_scale(_other, pos, hpr, scale); + } } break; default: + // Some unhandled combination. We should handle this. interval_cat.error() << "Internal error in CLerpNodePathInterval::priv_step().\n"; } + + if ((_flags & F_end_shear) != 0) { + // Also apply changes to shear. + if ((_flags & (F_end_pos | F_end_hpr | F_end_scale)) == + (F_end_pos | F_end_hpr | F_end_scale)) { + // Actually, we already handled this case above. + + } else { + if (_other.is_empty()) { + _node.set_shear(shear); + } else { + _node.set_shear(_other, shear); + } + } + } } if ((_flags & (F_end_color | F_end_color_scale)) != 0) { @@ -400,6 +443,14 @@ output(ostream &out) const { out << " to " << _end_scale; } + if ((_flags & F_end_shear) != 0) { + out << " shear"; + if ((_flags & F_start_shear) != 0) { + out << " from " << _start_shear; + } + out << " to " << _end_shear; + } + if ((_flags & F_end_color) != 0) { out << " color"; if ((_flags & F_start_color) != 0) { diff --git a/direct/src/interval/cLerpNodePathInterval.h b/direct/src/interval/cLerpNodePathInterval.h index 5cc47e3a75..339bb36db1 100644 --- a/direct/src/interval/cLerpNodePathInterval.h +++ b/direct/src/interval/cLerpNodePathInterval.h @@ -45,6 +45,8 @@ PUBLISHED: INLINE void set_start_scale(float scale); INLINE void set_end_scale(const LVecBase3f &scale); INLINE void set_end_scale(float scale); + INLINE void set_start_shear(const LVecBase3f &shear); + INLINE void set_end_shear(const LVecBase3f &shear); INLINE void set_start_color(const LVecBase4f &color); INLINE void set_end_color(const LVecBase4f &color); INLINE void set_start_color_scale(const LVecBase4f &color_scale); @@ -68,12 +70,14 @@ private: F_end_scale = 0x0004, F_end_color = 0x0008, F_end_color_scale = 0x0010, + F_end_shear = 0x0020, F_start_pos = 0x0100, F_start_hpr = 0x0200, F_start_scale = 0x0400, F_start_color = 0x0800, F_start_color_scale = 0x1000, + F_start_shear = 0x2000, F_bake_in_start = 0x8000, }; @@ -82,6 +86,7 @@ private: LPoint3f _start_pos, _end_pos; LVecBase3f _start_hpr, _end_hpr; LVecBase3f _start_scale, _end_scale; + LVecBase3f _start_shear, _end_shear; Colorf _start_color, _end_color; LVecBase4f _start_color_scale, _end_color_scale;