From c7a06524265b18f8dfd9b04d73b61c5bf7a0af7e Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 31 May 2007 23:13:49 +0000 Subject: [PATCH] add LerpTexOffsetInterval, etc. --- direct/src/interval/LerpInterval.py | 75 ++++++++++-- direct/src/interval/cLerpNodePathInterval.I | 108 ++++++++++++++++++ direct/src/interval/cLerpNodePathInterval.cxx | 67 ++++++++++- direct/src/interval/cLerpNodePathInterval.h | 38 ++++-- 4 files changed, 267 insertions(+), 21 deletions(-) diff --git a/direct/src/interval/LerpInterval.py b/direct/src/interval/LerpInterval.py index c731f713fd..fa2f653470 100644 --- a/direct/src/interval/LerpInterval.py +++ b/direct/src/interval/LerpInterval.py @@ -1,6 +1,16 @@ """LerpInterval module: contains the LerpInterval class""" -__all__ = ['LerpNodePathInterval', 'LerpPosInterval', 'LerpHprInterval', 'LerpQuatInterval', 'LerpScaleInterval', 'LerpShearInterval', 'LerpPosHprInterval', 'LerpPosQuatInterval', 'LerpHprScaleInterval', 'LerpQuatScaleInterval', 'LerpPosHprScaleInterval', 'LerpPosQuatScaleInterval', 'LerpPosHprScaleShearInterval', 'LerpPosQuatScaleShearInterval', 'LerpColorScaleInterval', 'LerpColorInterval', 'LerpFunctionInterval', 'LerpFunc'] +__all__ = [ + 'LerpNodePathInterval', 'LerpPosInterval', 'LerpHprInterval', + 'LerpQuatInterval', 'LerpScaleInterval', 'LerpShearInterval', + 'LerpPosHprInterval', 'LerpPosQuatInterval', + 'LerpHprScaleInterval', 'LerpQuatScaleInterval', + 'LerpPosHprScaleInterval', 'LerpPosQuatScaleInterval', + 'LerpPosHprScaleShearInterval', 'LerpPosQuatScaleShearInterval', + 'LerpColorInterval', 'LerpColorScaleInterval', + 'LerpTexOffsetInterval', 'LerpTexRotateInterval', 'LerpTexScaleInterval', + 'LerpFunctionInterval', 'LerpFunc' + ] from pandac.PandaModules import * from direct.directnotify.DirectNotifyGlobal import * @@ -24,6 +34,12 @@ class LerpNodePathInterval(CLerpNodePathInterval): if name == None: name = '%s-%d' % (self.__class__.__name__, self.lerpNodePathNum) LerpNodePathInterval.lerpNodePathNum += 1 + else: + # Allow the user to pass in a %d in the name and we'll go ahead + # and uniquify the name for them. + if "%d" in name: + name = name % LerpNodePathInterval.lerpNodePathNum + LerpNodePathInterval.lerpNodePathNum += 1 blendType = self.stringBlendType(blendType) assert blendType != self.BTInvalid @@ -571,25 +587,64 @@ class LerpPosQuatScaleShearInterval(LerpNodePathInterval): self.setupParam(self.setStartShear, self.startShear) LerpNodePathInterval.privDoEvent(self, t, event) +class LerpColorInterval(LerpNodePathInterval): + def __init__(self, nodePath, duration, color, startColor = None, + other = None, blendType = 'noBlend', + bakeInStart = 1, name = None): + LerpNodePathInterval.__init__(self, name, duration, blendType, + bakeInStart, 0, nodePath, other) + self.setEndColor(color) + if startColor != None: + self.setStartColor(startColor) + class LerpColorScaleInterval(LerpNodePathInterval): def __init__(self, nodePath, duration, colorScale, startColorScale = None, other = None, blendType = 'noBlend', - bakeInStart = 1, fluid = 0, name = None): + bakeInStart = 1, name = None): LerpNodePathInterval.__init__(self, name, duration, blendType, - bakeInStart, fluid, nodePath, other) + bakeInStart, 0, nodePath, other) self.setEndColorScale(colorScale) if startColorScale != None: self.setStartColorScale(startColorScale) -class LerpColorInterval(LerpNodePathInterval): - def __init__(self, nodePath, duration, color, startColor = None, +class LerpTexOffsetInterval(LerpNodePathInterval): + def __init__(self, nodePath, duration, texOffset, startTexOffset = None, other = None, blendType = 'noBlend', - bakeInStart = 1, fluid = 0, name = None): + textureStage = None, + bakeInStart = 1, name = None): LerpNodePathInterval.__init__(self, name, duration, blendType, - bakeInStart, fluid, nodePath, other) - self.setEndColor(color) - if startColor != None: - self.setStartColor(startColor) + bakeInStart, 0, nodePath, other) + self.setEndTexOffset(texOffset) + if startTexOffset != None: + self.setStartTexOffset(startTexOffset) + if textureStage != None: + self.setTextureStage(textureStage) + +class LerpTexRotateInterval(LerpNodePathInterval): + def __init__(self, nodePath, duration, texRotate, startTexRotate = None, + other = None, blendType = 'noBlend', + textureStage = None, + bakeInStart = 1, name = None): + LerpNodePathInterval.__init__(self, name, duration, blendType, + bakeInStart, 0, nodePath, other) + self.setEndTexRotate(texRotate) + if startTexRotate != None: + self.setStartTexRotate(startTexRotate) + if textureStage != None: + self.setTextureStage(textureStage) + +class LerpTexScaleInterval(LerpNodePathInterval): + def __init__(self, nodePath, duration, texScale, startTexScale = None, + other = None, blendType = 'noBlend', + textureStage = None, + bakeInStart = 1, name = None): + LerpNodePathInterval.__init__(self, name, duration, blendType, + bakeInStart, 0, nodePath, other) + self.setEndTexScale(texScale) + if startTexScale != None: + self.setStartTexScale(startTexScale) + if textureStage != None: + self.setTextureStage(textureStage) # diff --git a/direct/src/interval/cLerpNodePathInterval.I b/direct/src/interval/cLerpNodePathInterval.I index 05d660b2e8..2b006e538f 100644 --- a/direct/src/interval/cLerpNodePathInterval.I +++ b/direct/src/interval/cLerpNodePathInterval.I @@ -343,3 +343,111 @@ set_end_color_scale(const LVecBase4f &color_scale) { _end_color_scale = color_scale; _flags |= F_end_color_scale; } + +//////////////////////////////////////////////////////////////////// +// Function: CLerpNodePathInterval::set_texture_stage +// Access: Published +// Description: Indicates the texture stage that is adjusted by +// tex_offset, tex_rotate, and/or tex_scale. If this is +// not set, the default is the default texture stage. +//////////////////////////////////////////////////////////////////// +INLINE void CLerpNodePathInterval:: +set_texture_stage(TextureStage *stage) { + _texture_stage = stage; +} + +//////////////////////////////////////////////////////////////////// +// Function: CLerpNodePathInterval::set_start_tex_offset +// Access: Published +// Description: Indicates the initial UV offset of the lerped node. +// This is meaningful only if set_end_tex_offset() is also +// called. This parameter is optional; if unspecified, +// the value will be taken from the node's actual +// UV offset at the time the lerp is performed. +//////////////////////////////////////////////////////////////////// +INLINE void CLerpNodePathInterval:: +set_start_tex_offset(const LVecBase2f &tex_offset) { + nassertv(!tex_offset.is_nan()); + _start_tex_offset = tex_offset; + _flags |= F_start_tex_offset; +} + +//////////////////////////////////////////////////////////////////// +// Function: CLerpNodePathInterval::set_end_tex_offset +// Access: Published +// Description: Indicates that the UV offset of the node should be +// lerped, and specifies the final UV offset of the node. +// This should be called before priv_initialize(). If this +// is not called, the node's UV offset will not be +// affected by the lerp. +//////////////////////////////////////////////////////////////////// +INLINE void CLerpNodePathInterval:: +set_end_tex_offset(const LVecBase2f &tex_offset) { + nassertv(!tex_offset.is_nan()); + _end_tex_offset = tex_offset; + _flags |= F_end_tex_offset; +} + +//////////////////////////////////////////////////////////////////// +// Function: CLerpNodePathInterval::set_start_tex_rotate +// Access: Published +// Description: Indicates the initial UV rotate of the lerped node. +// This is meaningful only if set_end_tex_rotate() is also +// called. This parameter is optional; if unspecified, +// the value will be taken from the node's actual +// UV rotate at the time the lerp is performed. +//////////////////////////////////////////////////////////////////// +INLINE void CLerpNodePathInterval:: +set_start_tex_rotate(float tex_rotate) { + nassertv(!cnan(tex_rotate)); + _start_tex_rotate = tex_rotate; + _flags |= F_start_tex_rotate; +} + +//////////////////////////////////////////////////////////////////// +// Function: CLerpNodePathInterval::set_end_tex_rotate +// Access: Published +// Description: Indicates that the UV rotate of the node should be +// lerped, and specifies the final UV rotate of the node. +// This should be called before priv_initialize(). If this +// is not called, the node's UV rotate will not be +// affected by the lerp. +//////////////////////////////////////////////////////////////////// +INLINE void CLerpNodePathInterval:: +set_end_tex_rotate(float tex_rotate) { + nassertv(!cnan(tex_rotate)); + _end_tex_rotate = tex_rotate; + _flags |= F_end_tex_rotate; +} + +//////////////////////////////////////////////////////////////////// +// Function: CLerpNodePathInterval::set_start_tex_scale +// Access: Published +// Description: Indicates the initial UV scale of the lerped node. +// This is meaningful only if set_end_tex_scale() is also +// called. This parameter is optional; if unspecified, +// the value will be taken from the node's actual +// UV scale at the time the lerp is performed. +//////////////////////////////////////////////////////////////////// +INLINE void CLerpNodePathInterval:: +set_start_tex_scale(const LVecBase2f &tex_scale) { + nassertv(!tex_scale.is_nan()); + _start_tex_scale = tex_scale; + _flags |= F_start_tex_scale; +} + +//////////////////////////////////////////////////////////////////// +// Function: CLerpNodePathInterval::set_end_tex_scale +// Access: Published +// Description: Indicates that the UV scale of the node should be +// lerped, and specifies the final UV scale of the node. +// This should be called before priv_initialize(). If this +// is not called, the node's UV scale will not be +// affected by the lerp. +//////////////////////////////////////////////////////////////////// +INLINE void CLerpNodePathInterval:: +set_end_tex_scale(const LVecBase2f &tex_scale) { + nassertv(!tex_scale.is_nan()); + _end_tex_scale = tex_scale; + _flags |= F_end_tex_scale; +} diff --git a/direct/src/interval/cLerpNodePathInterval.cxx b/direct/src/interval/cLerpNodePathInterval.cxx index 2b992839d4..a8ef8ef8e5 100644 --- a/direct/src/interval/cLerpNodePathInterval.cxx +++ b/direct/src/interval/cLerpNodePathInterval.cxx @@ -22,6 +22,7 @@ #include "renderState.h" #include "colorAttrib.h" #include "colorScaleAttrib.h" +#include "texMatrixAttrib.h" #include "dcast.h" #include "config_interval.h" @@ -67,6 +68,7 @@ CLerpNodePathInterval(const string &name, double duration, _node(node), _other(other), _flags(0), + _texture_stage(TextureStage::get_default()), _slerp(NULL) { if (bake_in_start) { @@ -393,7 +395,7 @@ priv_step(double t) { _node.set_prev_transform(prev_transform); } - if ((_flags & (F_end_color | F_end_color_scale)) != 0) { + if ((_flags & (F_end_color | F_end_color_scale | F_end_tex_offset | F_end_tex_rotate | F_end_tex_scale)) != 0) { // We have some render state lerp. CPT(RenderState) state; @@ -458,6 +460,69 @@ priv_step(double t) { state = state->add_attrib(ColorScaleAttrib::make(color_scale)); } + if ((_flags & (F_end_tex_offset | F_end_tex_rotate | F_end_tex_scale)) != 0) { + // We have a UV lerp. + CPT(TransformState) transform = TransformState::make_identity(); + + const RenderAttrib *attrib = + state->get_attrib(TexMatrixAttrib::get_class_type()); + const TexMatrixAttrib *tma = NULL; + if (attrib != (const TexMatrixAttrib *)NULL) { + tma = DCAST(TexMatrixAttrib, attrib); + transform = tma->get_transform(_texture_stage); + } + + if ((_flags & F_end_tex_offset) != 0) { + LVecBase2f tex_offset; + + if ((_flags & F_start_tex_offset) != 0) { + lerp_value(tex_offset, d, _start_tex_offset, _end_tex_offset); + } else { + tex_offset = transform->get_pos2d(); + lerp_value_from_prev(tex_offset, d, _prev_d, tex_offset, + _end_tex_offset); + } + + transform = transform->set_pos2d(tex_offset); + } + + if ((_flags & F_end_tex_rotate) != 0) { + float tex_rotate; + + if ((_flags & F_start_tex_rotate) != 0) { + lerp_value(tex_rotate, d, _start_tex_rotate, _end_tex_rotate); + } else { + tex_rotate = transform->get_rotate2d(); + lerp_value_from_prev(tex_rotate, d, _prev_d, tex_rotate, + _end_tex_rotate); + } + + transform = transform->set_rotate2d(tex_rotate); + } + + if ((_flags & F_end_tex_scale) != 0) { + LVecBase2f tex_scale; + + if ((_flags & F_start_tex_scale) != 0) { + lerp_value(tex_scale, d, _start_tex_scale, _end_tex_scale); + } else { + tex_scale = transform->get_scale2d(); + lerp_value_from_prev(tex_scale, d, _prev_d, tex_scale, + _end_tex_scale); + } + + transform = transform->set_scale2d(tex_scale); + } + + // Apply the modified transform back to the state. + if (tma != (TexMatrixAttrib *)NULL) { + state = state->add_attrib(tma->add_stage(_texture_stage, transform)); + } else { + state = state->add_attrib(TexMatrixAttrib::make(_texture_stage, transform)); + } + } + + // Now apply the new state back to the node. if (_other.is_empty()) { _node.set_state(state); diff --git a/direct/src/interval/cLerpNodePathInterval.h b/direct/src/interval/cLerpNodePathInterval.h index ff6d6996ab..be83cf8dff 100644 --- a/direct/src/interval/cLerpNodePathInterval.h +++ b/direct/src/interval/cLerpNodePathInterval.h @@ -22,6 +22,7 @@ #include "directbase.h" #include "cLerpInterval.h" #include "nodePath.h" +#include "textureStage.h" //////////////////////////////////////////////////////////////////// // Class : CLerpNodePathInterval @@ -56,6 +57,13 @@ PUBLISHED: INLINE void set_end_color(const LVecBase4f &color); INLINE void set_start_color_scale(const LVecBase4f &color_scale); INLINE void set_end_color_scale(const LVecBase4f &color_scale); + INLINE void set_texture_stage(TextureStage *stage); + INLINE void set_start_tex_offset(const LVecBase2f &tex_offset); + INLINE void set_end_tex_offset(const LVecBase2f &tex_offset); + INLINE void set_start_tex_rotate(float tex_rotate); + INLINE void set_end_tex_rotate(float tex_rotate); + INLINE void set_start_tex_scale(const LVecBase2f &tex_scale); + INLINE void set_end_tex_scale(const LVecBase2f &tex_scale); virtual void priv_initialize(double t); virtual void priv_instant(); @@ -79,19 +87,25 @@ private: F_end_color = 0x000010, F_end_color_scale = 0x000020, F_end_shear = 0x000040, + F_end_tex_offset = 0x000080, + F_end_tex_rotate = 0x000100, + F_end_tex_scale = 0x000200, - F_start_pos = 0x000080, - F_start_hpr = 0x000100, - F_start_quat = 0x000200, - F_start_scale = 0x000400, - F_start_color = 0x000800, - F_start_color_scale = 0x001000, - F_start_shear = 0x002000, + F_start_pos = 0x010001, + F_start_hpr = 0x010002, + F_start_quat = 0x010004, + F_start_scale = 0x010008, + F_start_color = 0x010010, + F_start_color_scale = 0x010020, + F_start_shear = 0x010040, + F_start_tex_offset = 0x010080, + F_start_tex_rotate = 0x010100, + F_start_tex_scale = 0x010200, - F_fluid = 0x004000, - F_bake_in_start = 0x008000, + F_fluid = 0x100000, + F_bake_in_start = 0x200000, - F_slerp_setup = 0x010000, + F_slerp_setup = 0x400000, }; unsigned int _flags; @@ -102,6 +116,10 @@ private: LVecBase3f _start_shear, _end_shear; Colorf _start_color, _end_color; LVecBase4f _start_color_scale, _end_color_scale; + PT(TextureStage) _texture_stage; + LVecBase2f _start_tex_offset, _end_tex_offset; + float _start_tex_rotate, _end_tex_rotate; + LVecBase2f _start_tex_scale, _end_tex_scale; double _prev_d; float _slerp_angle;