diff --git a/panda/src/chan/animChannelBase.cxx b/panda/src/chan/animChannelBase.cxx index faa42431c2..b8f206d546 100644 --- a/panda/src/chan/animChannelBase.cxx +++ b/panda/src/chan/animChannelBase.cxx @@ -35,7 +35,7 @@ TypeHandle AnimChannelBase::_type_handle; // frame number. //////////////////////////////////////////////////////////////////// bool AnimChannelBase:: -has_changed(int, int) { +has_changed(double, double) { return true; } diff --git a/panda/src/chan/animChannelBase.h b/panda/src/chan/animChannelBase.h index a174cccf63..41bbe6d5ed 100644 --- a/panda/src/chan/animChannelBase.h +++ b/panda/src/chan/animChannelBase.h @@ -45,7 +45,7 @@ protected: public: INLINE AnimChannelBase(AnimGroup *parent, const string &name); - virtual bool has_changed(int last_frame, int this_frame); + virtual bool has_changed(double last_frame, double this_frame); virtual TypeHandle get_value_type() const=0; diff --git a/panda/src/chan/animChannelFixed.I b/panda/src/chan/animChannelFixed.I index 2dc1bc8b90..b00dc3f7b8 100644 --- a/panda/src/chan/animChannelFixed.I +++ b/panda/src/chan/animChannelFixed.I @@ -55,7 +55,7 @@ AnimChannelFixed(const string &name, const ValueType &value) //////////////////////////////////////////////////////////////////// template bool AnimChannelFixed:: -has_changed(int, int) { +has_changed(double, double) { return false; } diff --git a/panda/src/chan/animChannelFixed.h b/panda/src/chan/animChannelFixed.h index 443dbc7de3..e57a4f0f20 100644 --- a/panda/src/chan/animChannelFixed.h +++ b/panda/src/chan/animChannelFixed.h @@ -41,7 +41,7 @@ public: INLINE AnimChannelFixed(AnimGroup *parent, const string &name, const ValueType &value); INLINE AnimChannelFixed(const string &name, const ValueType &value); - virtual bool has_changed(int last_frame, int this_frame); + virtual bool has_changed(double last_frame, double this_frame); virtual void get_value(int frame, ValueType &value); virtual void output(ostream &out) const; diff --git a/panda/src/chan/animChannelMatrixDynamic.cxx b/panda/src/chan/animChannelMatrixDynamic.cxx index cf7d17e893..a136052900 100644 --- a/panda/src/chan/animChannelMatrixDynamic.cxx +++ b/panda/src/chan/animChannelMatrixDynamic.cxx @@ -61,7 +61,7 @@ AnimChannelMatrixDynamic() { // frame number. //////////////////////////////////////////////////////////////////// bool AnimChannelMatrixDynamic:: -has_changed(int, int) { +has_changed(double, double) { if (_value_node != (PandaNode *)NULL) { _value = _value_node->get_transform(); } diff --git a/panda/src/chan/animChannelMatrixDynamic.h b/panda/src/chan/animChannelMatrixDynamic.h index b6e17b11b7..c1155eb372 100644 --- a/panda/src/chan/animChannelMatrixDynamic.h +++ b/panda/src/chan/animChannelMatrixDynamic.h @@ -46,7 +46,7 @@ protected: AnimChannelMatrixDynamic(); public: - virtual bool has_changed(int last_frame, int this_frame); + virtual bool has_changed(double last_frame, double this_frame); virtual void get_value(int frame, LMatrix4f &mat); virtual void get_value_no_scale_shear(int frame, LMatrix4f &value); diff --git a/panda/src/chan/animChannelMatrixXfmTable.cxx b/panda/src/chan/animChannelMatrixXfmTable.cxx index a1f17280a9..4f0472b583 100644 --- a/panda/src/chan/animChannelMatrixXfmTable.cxx +++ b/panda/src/chan/animChannelMatrixXfmTable.cxx @@ -70,12 +70,14 @@ AnimChannelMatrixXfmTable:: // frame number. //////////////////////////////////////////////////////////////////// bool AnimChannelMatrixXfmTable:: -has_changed(int last_frame, int this_frame) { +has_changed(double last_frame, double this_frame) { if (last_frame != this_frame) { + int last_i_frame = (int)floor(last_frame); + int next_i_frame = (int)ceil(this_frame); for (int i = 0; i < num_matrix_components; i++) { if (_tables[i].size() > 1) { - if (_tables[i][last_frame % _tables[i].size()] != - _tables[i][this_frame % _tables[i].size()]) { + if (_tables[i][last_i_frame % _tables[i].size()] != + _tables[i][next_i_frame % _tables[i].size()]) { return true; } } diff --git a/panda/src/chan/animChannelMatrixXfmTable.h b/panda/src/chan/animChannelMatrixXfmTable.h index eb3330369d..659755f435 100644 --- a/panda/src/chan/animChannelMatrixXfmTable.h +++ b/panda/src/chan/animChannelMatrixXfmTable.h @@ -45,7 +45,7 @@ public: ~AnimChannelMatrixXfmTable(); - virtual bool has_changed(int last_frame, int this_frame); + virtual bool has_changed(double last_frame, double this_frame); virtual void get_value(int frame, LMatrix4f &mat); virtual void get_value_no_scale_shear(int frame, LMatrix4f &value); diff --git a/panda/src/chan/animChannelScalarDynamic.cxx b/panda/src/chan/animChannelScalarDynamic.cxx index 388cc1496a..46a2a53aa5 100644 --- a/panda/src/chan/animChannelScalarDynamic.cxx +++ b/panda/src/chan/animChannelScalarDynamic.cxx @@ -59,7 +59,7 @@ AnimChannelScalarDynamic() { // frame number. //////////////////////////////////////////////////////////////////// bool AnimChannelScalarDynamic:: -has_changed(int, int) { +has_changed(double, double) { if (_value_node != (PandaNode *)NULL) { _value = _value_node->get_transform(); bool has_changed = (_value != _last_value); diff --git a/panda/src/chan/animChannelScalarDynamic.h b/panda/src/chan/animChannelScalarDynamic.h index 020ad09ce7..c420b0e2cf 100644 --- a/panda/src/chan/animChannelScalarDynamic.h +++ b/panda/src/chan/animChannelScalarDynamic.h @@ -45,7 +45,7 @@ protected: AnimChannelScalarDynamic(); public: - virtual bool has_changed(int last_frame, int this_frame); + virtual bool has_changed(double last_frame, double this_frame); virtual void get_value(int frame, float &value); PUBLISHED: diff --git a/panda/src/chan/animChannelScalarTable.cxx b/panda/src/chan/animChannelScalarTable.cxx index e7b2dc6aae..ae048f4402 100644 --- a/panda/src/chan/animChannelScalarTable.cxx +++ b/panda/src/chan/animChannelScalarTable.cxx @@ -58,10 +58,12 @@ AnimChannelScalarTable(){ // frame number. //////////////////////////////////////////////////////////////////// bool AnimChannelScalarTable:: -has_changed(int last_frame, int this_frame) { +has_changed(double last_frame, double this_frame) { if (last_frame != this_frame && _table.size() > 1) { - if (_table[last_frame % _table.size()] != - _table[this_frame % _table.size()]) { + int last_i_frame = (int)floor(last_frame); + int next_i_frame = (int)ceil(this_frame); + if (_table[last_i_frame % _table.size()] != + _table[next_i_frame % _table.size()]) { return true; } } diff --git a/panda/src/chan/animChannelScalarTable.h b/panda/src/chan/animChannelScalarTable.h index 2c8c618d2a..67842cabc2 100644 --- a/panda/src/chan/animChannelScalarTable.h +++ b/panda/src/chan/animChannelScalarTable.h @@ -36,7 +36,7 @@ class EXPCL_PANDA AnimChannelScalarTable : public AnimChannelScalar { public: AnimChannelScalarTable(AnimGroup *parent, const string &name); - virtual bool has_changed(int last_frame, int this_frame); + virtual bool has_changed(double last_frame, double this_frame); virtual void get_value(int frame, float &value); void set_table(const CPTA_float &table); diff --git a/panda/src/chan/animControl.cxx b/panda/src/chan/animControl.cxx index 2c6e0cce01..c083aa7f6a 100644 --- a/panda/src/chan/animControl.cxx +++ b/panda/src/chan/animControl.cxx @@ -87,12 +87,15 @@ output(ostream &out) const { // changed since the last call to mark_channels(). //////////////////////////////////////////////////////////////////// bool AnimControl:: -channel_has_changed(AnimChannelBase *channel) const { - if (_marked_frame < 0) { +channel_has_changed(AnimChannelBase *channel, bool frame_blend_flag) const { + if (_marked_frame < 0.0) { return true; } - int this_frame = get_frame(); + double this_frame = get_full_fframe(); + if (!frame_blend_flag) { + this_frame = floor(this_frame + 0.0001); + } return channel->has_changed(_marked_frame, this_frame); } @@ -103,8 +106,11 @@ channel_has_changed(AnimChannelBase *channel) const { // next call to channel_has_changed(). //////////////////////////////////////////////////////////////////// void AnimControl:: -mark_channels() { - _marked_frame = get_frame(); +mark_channels(bool frame_blend_flag) { + _marked_frame = get_full_fframe(); + if (!frame_blend_flag) { + _marked_frame = floor(_marked_frame + 0.0001); + } } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/chan/animControl.h b/panda/src/chan/animControl.h index ef745eb92d..cee955fef2 100644 --- a/panda/src/chan/animControl.h +++ b/panda/src/chan/animControl.h @@ -59,8 +59,8 @@ public: // interface; they're just public so we don't have to declare a // bunch of friends. - bool channel_has_changed(AnimChannelBase *channel) const; - void mark_channels(); + bool channel_has_changed(AnimChannelBase *channel, bool frame_blend_flag) const; + void mark_channels(bool frame_blend_flag); protected: virtual void animation_activated(); @@ -74,7 +74,7 @@ private: int _channel_index; // This is the frame number as of the last call to mark_channels(). - int _marked_frame; + double _marked_frame; // This is the bitmask of joints and/or sliders from the animation // that we have actually bound into this AnimControl. See diff --git a/panda/src/chan/movingPartBase.cxx b/panda/src/chan/movingPartBase.cxx index ad55e66664..db4b8b9e01 100644 --- a/panda/src/chan/movingPartBase.cxx +++ b/panda/src/chan/movingPartBase.cxx @@ -98,7 +98,7 @@ write_with_value(ostream &out, int indent_level) const { // false otherwise. //////////////////////////////////////////////////////////////////// bool MovingPartBase:: -do_update(PartBundle *root, PartGroup *parent, +do_update(PartBundle *root, const CycleData *root_cdata, PartGroup *parent, bool parent_changed, bool anim_changed, Thread *current_thread) { bool any_changed = false; @@ -107,7 +107,7 @@ do_update(PartBundle *root, PartGroup *parent, // See if any of the channel values have changed since last time. { - PartBundle::CDReader cdata(root->_cycler, current_thread); + const PartBundle::CData *cdata = (const PartBundle::CData *)root_cdata; PartBundle::ChannelBlend::const_iterator bci; for (bci = cdata->_blend.begin(); !needs_update && bci != cdata->_blend.end(); @@ -117,7 +117,7 @@ do_update(PartBundle *root, PartGroup *parent, nassertr(channel_index >= 0 && channel_index < (int)_channels.size(), false); AnimChannelBase *channel = _channels[channel_index]; if (channel != (AnimChannelBase*)NULL) { - needs_update = control->channel_has_changed(channel); + needs_update = control->channel_has_changed(channel, cdata->_frame_blend_flag); } } } @@ -135,7 +135,8 @@ do_update(PartBundle *root, PartGroup *parent, // Now recurse. Children::iterator ci; for (ci = _children.begin(); ci != _children.end(); ++ci) { - if ((*ci)->do_update(root, this, parent_changed || needs_update, + if ((*ci)->do_update(root, root_cdata, this, + parent_changed || needs_update, anim_changed, current_thread)) { any_changed = true; } diff --git a/panda/src/chan/movingPartBase.h b/panda/src/chan/movingPartBase.h index bc011b3bc5..93d5e53506 100644 --- a/panda/src/chan/movingPartBase.h +++ b/panda/src/chan/movingPartBase.h @@ -56,9 +56,9 @@ PUBLISHED: virtual void output_value(ostream &out) const=0; public: - virtual bool do_update(PartBundle *root, PartGroup *parent, - bool parent_changed, bool anim_changed, - Thread *current_thread); + virtual bool do_update(PartBundle *root, const CycleData *root_cdata, + PartGroup *parent, bool parent_changed, + bool anim_changed, Thread *current_thread); virtual void get_blend_value(const PartBundle *root)=0; virtual bool update_internals(PartGroup *parent, bool self_changed, diff --git a/panda/src/chan/partBundle.cxx b/panda/src/chan/partBundle.cxx index 4e24e8d1c3..44dce02e6e 100644 --- a/panda/src/chan/partBundle.cxx +++ b/panda/src/chan/partBundle.cxx @@ -246,24 +246,20 @@ bool PartBundle:: update() { Thread *current_thread = Thread::get_current_thread(); bool anim_changed; - { - CDReader cdata(_cycler, current_thread); - anim_changed = cdata->_anim_changed; + bool frame_blend_flag; + CDWriter cdata(_cycler, false, current_thread); + anim_changed = cdata->_anim_changed; + frame_blend_flag = cdata->_frame_blend_flag; - if (cdata->_frame_blend_flag) { - // If the intra-frame blend flag is on, we will just assume the - // animation changes every time we call update(). - anim_changed = true; - } - } - bool any_changed = do_update(this, NULL, false, anim_changed, current_thread); + bool any_changed = do_update(this, cdata, NULL, false, anim_changed, + current_thread); // Now update all the controls for next time. - CDWriter cdata(_cycler, false, current_thread); + // CDWriter cdata(_cycler, false, current_thread); ChannelBlend::const_iterator cbi; for (cbi = cdata->_blend.begin(); cbi != cdata->_blend.end(); ++cbi) { AnimControl *control = (*cbi).first; - control->mark_channels(); + control->mark_channels(frame_blend_flag); } cdata->_anim_changed = false; @@ -281,14 +277,14 @@ update() { bool PartBundle:: force_update() { Thread *current_thread = Thread::get_current_thread(); - bool any_changed = do_update(this, NULL, true, true, current_thread); + CDWriter cdata(_cycler, false, current_thread); + bool any_changed = do_update(this, cdata, NULL, true, true, current_thread); // Now update all the controls for next time. - CDWriter cdata(_cycler, false, current_thread); ChannelBlend::const_iterator cbi; for (cbi = cdata->_blend.begin(); cbi != cdata->_blend.end(); ++cbi) { AnimControl *control = (*cbi).first; - control->mark_channels(); + control->mark_channels(cdata->_frame_blend_flag); } cdata->_anim_changed = false; @@ -442,7 +438,8 @@ clear_and_stop_intersecting(AnimControl *control, CData *cdata) { void PartBundle:: finalize(BamReader *) { Thread *current_thread = Thread::get_current_thread(); - do_update(this, NULL, true, true, current_thread); + CDWriter cdata(_cycler, true); + do_update(this, cdata, NULL, true, true, current_thread); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/chan/partGroup.cxx b/panda/src/chan/partGroup.cxx index 1dc93cee06..a00bb3feae 100644 --- a/panda/src/chan/partGroup.cxx +++ b/panda/src/chan/partGroup.cxx @@ -360,14 +360,14 @@ write_with_value(ostream &out, int indent_level) const { // false otherwise. //////////////////////////////////////////////////////////////////// bool PartGroup:: -do_update(PartBundle *root, PartGroup *, +do_update(PartBundle *root, const CycleData *root_cdata, PartGroup *, bool parent_changed, bool anim_changed, Thread *current_thread) { bool any_changed = false; Children::iterator ci; for (ci = _children.begin(); ci != _children.end(); ++ci) { - if ((*ci)->do_update(root, this, parent_changed, anim_changed, - current_thread)) { + if ((*ci)->do_update(root, root_cdata, this, parent_changed, + anim_changed, current_thread)) { any_changed = true; } } diff --git a/panda/src/chan/partGroup.h b/panda/src/chan/partGroup.h index 0e00d6d0ee..165d7eb8a1 100644 --- a/panda/src/chan/partGroup.h +++ b/panda/src/chan/partGroup.h @@ -35,6 +35,7 @@ class PartSubset; class BamReader; class FactoryParams; class BitArray; +class CycleData; //////////////////////////////////////////////////////////////////// // Class : PartGroup @@ -85,9 +86,9 @@ public: const PartGroup *parent, int hierarchy_match_flags = 0) const; - virtual bool do_update(PartBundle *root, PartGroup *parent, - bool parent_changed, bool anim_changed, - Thread *current_thread); + virtual bool do_update(PartBundle *root, const CycleData *root_cdata, + PartGroup *parent, bool parent_changed, + bool anim_changed, Thread *current_thread); protected: void write_descendants(ostream &out, int indent_level) const; diff --git a/panda/src/char/character.cxx b/panda/src/char/character.cxx index 15278ae539..8a0e356f3b 100644 --- a/panda/src/char/character.cxx +++ b/panda/src/char/character.cxx @@ -155,19 +155,7 @@ cull_callback(CullTraverser *, CullTraverserData &) { // the view frustum. We may need a better way to do this // optimization later, to handle characters that might animate // themselves in front of the view frustum. - - double now = ClockObject::get_global_clock()->get_frame_time(); - if (now != _last_auto_update) { - _last_auto_update = now; - - PStatTimer timer(_joints_pcollector); - if (char_cat.is_spam()) { - char_cat.spam() << "Animating " << *this << " at time " << now << "\n"; - } - - do_update(); - } - + update(); return true; } @@ -211,14 +199,11 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, // code to force an update of the character's position // to the current frame, regardless of whether the // character is currently onscreen and animating. +// +// This method is deprecated. Call update() instead. //////////////////////////////////////////////////////////////////// void Character:: update_to_now() { - if (char_cat.is_spam()) { - double now = ClockObject::get_global_clock()->get_frame_time(); - char_cat.spam() << "Animating " << *this << " at time " << now << "\n"; - } - update(); } @@ -232,8 +217,17 @@ update_to_now() { //////////////////////////////////////////////////////////////////// void Character:: update() { - PStatTimer timer(_joints_pcollector); - do_update(); + double now = ClockObject::get_global_clock()->get_frame_time(); + if (now != _last_auto_update) { + _last_auto_update = now; + + PStatTimer timer(_joints_pcollector); + if (char_cat.is_spam()) { + char_cat.spam() << "Animating " << *this << " at time " << now << "\n"; + } + + do_update(); + } } ////////////////////////////////////////////////////////////////////