From 3e2948ec8c5411221616ef952992cf43bb71d1e3 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 21 Oct 2003 04:07:50 +0000 Subject: [PATCH] add dynamic control for joints and sliders --- panda/src/chan/Sources.pp | 26 ++- panda/src/chan/animChannel.h | 1 + panda/src/chan/animChannelBase.cxx | 10 - panda/src/chan/animChannelBase.h | 6 +- panda/src/chan/animChannelMatrixDynamic.I | 19 ++ panda/src/chan/animChannelMatrixDynamic.cxx | 223 +++++++++++++++++++ panda/src/chan/animChannelMatrixDynamic.h | 96 ++++++++ panda/src/chan/animChannelMatrixXfmTable.cxx | 28 ++- panda/src/chan/animChannelMatrixXfmTable.h | 9 +- panda/src/chan/animChannelScalarDynamic.I | 18 ++ panda/src/chan/animChannelScalarDynamic.cxx | 198 ++++++++++++++++ panda/src/chan/animChannelScalarDynamic.h | 93 ++++++++ panda/src/chan/animChannelScalarTable.cxx | 2 +- panda/src/chan/animChannelScalarTable.h | 8 +- panda/src/chan/animControl.cxx | 5 - panda/src/chan/animGroup.cxx | 114 +++++++++- panda/src/chan/animGroup.h | 3 + panda/src/chan/chan_composite2.cxx | 2 + panda/src/chan/config_chan.cxx | 6 + panda/src/chan/movingPartBase.cxx | 2 +- panda/src/char/dynamicVertices.cxx | 10 +- panda/src/char/dynamicVertices.h | 23 +- 22 files changed, 840 insertions(+), 62 deletions(-) create mode 100644 panda/src/chan/animChannelMatrixDynamic.I create mode 100644 panda/src/chan/animChannelMatrixDynamic.cxx create mode 100644 panda/src/chan/animChannelMatrixDynamic.h create mode 100644 panda/src/chan/animChannelScalarDynamic.I create mode 100644 panda/src/chan/animChannelScalarDynamic.cxx create mode 100644 panda/src/chan/animChannelScalarDynamic.h diff --git a/panda/src/chan/Sources.pp b/panda/src/chan/Sources.pp index 0a9935f4de..ef0ab78caa 100644 --- a/panda/src/chan/Sources.pp +++ b/panda/src/chan/Sources.pp @@ -12,9 +12,12 @@ animBundle.I animBundle.h \ animBundleNode.I animBundleNode.h \ animChannel.I animChannel.h animChannelBase.I \ - animChannelBase.h animChannelMatrixXfmTable.I \ - animChannelMatrixXfmTable.h animChannelScalarTable.I \ - animChannelScalarTable.h animControl.I animControl.N \ + animChannelBase.h \ + animChannelMatrixDynamic.I animChannelMatrixDynamic.h \ + animChannelMatrixXfmTable.I animChannelMatrixXfmTable.h \ + animChannelScalarDynamic.I animChannelScalarDynamic.h \ + animChannelScalarTable.I animChannelScalarTable.h \ + animControl.I animControl.N \ animControl.h animControlCollection.I \ animControlCollection.h animGroup.I animGroup.h auto_bind.h \ config_chan.h movingPartBase.I movingPartBase.h \ @@ -28,8 +31,12 @@ animBundle.cxx \ animBundleNode.cxx \ animChannel.cxx \ - animChannelBase.cxx animChannelMatrixXfmTable.cxx \ - animChannelScalarTable.cxx animControl.cxx \ + animChannelBase.cxx \ + animChannelMatrixDynamic.cxx \ + animChannelMatrixXfmTable.cxx \ + animChannelScalarDynamic.cxx \ + animChannelScalarTable.cxx \ + animControl.cxx \ animControlCollection.cxx animGroup.cxx auto_bind.cxx \ config_chan.cxx movingPartBase.cxx movingPartMatrix.cxx \ movingPartScalar.cxx partBundle.cxx \ @@ -40,9 +47,12 @@ animBundle.I animBundle.h \ animBundleNode.I animBundleNode.h \ animChannel.I animChannel.h animChannelBase.I animChannelBase.h \ - animChannelFixed.I animChannelFixed.h animChannelMatrixXfmTable.I \ - animChannelMatrixXfmTable.h animChannelScalarTable.I \ - animChannelScalarTable.h animControl.I animControl.h \ + animChannelFixed.I animChannelFixed.h \ + animChannelMatrixDynamic.I animChannelMatrixDynamic.h \ + animChannelMatrixXfmTable.I animChannelMatrixXfmTable.h \ + animChannelScalarDynamic.I animChannelScalarDynamic.h \ + animChannelScalarTable.I animChannelScalarTable.h \ + animControl.I animControl.h \ animControlCollection.I animControlCollection.h animGroup.I \ animGroup.h auto_bind.h config_chan.h \ movingPart.I movingPart.h movingPartBase.I \ diff --git a/panda/src/chan/animChannel.h b/panda/src/chan/animChannel.h index d5bb71307d..aa3fd09767 100644 --- a/panda/src/chan/animChannel.h +++ b/panda/src/chan/animChannel.h @@ -44,6 +44,7 @@ public: INLINE AnimChannel(AnimGroup *parent, const string &name); +PUBLISHED: virtual void get_value(int frame, ValueType &value)=0; // These two functions only have meaning for matrix types. diff --git a/panda/src/chan/animChannelBase.cxx b/panda/src/chan/animChannelBase.cxx index cf863ddbc5..06bbf7e0f2 100644 --- a/panda/src/chan/animChannelBase.cxx +++ b/panda/src/chan/animChannelBase.cxx @@ -39,16 +39,6 @@ has_changed(int, int) { return true; } -//////////////////////////////////////////////////////////////////// -// Function: AnimChannelBase::output -// Access: Public, Virtual -// Description: Writes a one-line description of the channel. -//////////////////////////////////////////////////////////////////// -void AnimChannelBase:: -output(ostream &out) const { - out << get_type() << "(" << get_value_type() << ") " << get_name(); -} - //////////////////////////////////////////////////////////////////// // Function: AnimChannelBase::write_datagram // Access: Public diff --git a/panda/src/chan/animChannelBase.h b/panda/src/chan/animChannelBase.h index ea8421cd27..e9f997eb94 100644 --- a/panda/src/chan/animChannelBase.h +++ b/panda/src/chan/animChannelBase.h @@ -48,7 +48,6 @@ public: virtual bool has_changed(int last_frame, int this_frame); virtual TypeHandle get_value_type() const=0; - virtual void output(ostream &out) const; protected: @@ -60,11 +59,12 @@ public: protected: void fillin(DatagramIterator& scan, BamReader* manager); -public: - +PUBLISHED: virtual TypeHandle get_type() const { return get_class_type(); } + +public: virtual TypeHandle force_init_type() {init_type(); return get_class_type();} static TypeHandle get_class_type() { return _type_handle; diff --git a/panda/src/chan/animChannelMatrixDynamic.I b/panda/src/chan/animChannelMatrixDynamic.I new file mode 100644 index 0000000000..15a869318e --- /dev/null +++ b/panda/src/chan/animChannelMatrixDynamic.I @@ -0,0 +1,19 @@ +// Filename: animChannelMatrixDynamic.I +// Created by: drose (20Oct03) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + + diff --git a/panda/src/chan/animChannelMatrixDynamic.cxx b/panda/src/chan/animChannelMatrixDynamic.cxx new file mode 100644 index 0000000000..5abb5d7128 --- /dev/null +++ b/panda/src/chan/animChannelMatrixDynamic.cxx @@ -0,0 +1,223 @@ +// Filename: animChannelMatrixDynamic.cxx +// Created by: drose (20Oct03) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#include "animChannelMatrixDynamic.h" +#include "animBundle.h" +#include "config_chan.h" + +#include "compose_matrix.h" +#include "indent.h" +#include "datagram.h" +#include "datagramIterator.h" +#include "bamReader.h" +#include "bamWriter.h" +#include "fftCompressor.h" + +TypeHandle AnimChannelMatrixDynamic::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +AnimChannelMatrixDynamic:: +AnimChannelMatrixDynamic(AnimGroup *parent, const string &name) + : AnimChannelMatrix(parent, name) +{ + _last_value = _value = TransformState::make_identity(); +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::Constructor +// Access: Protected +// Description: For use only with the bam reader. +///////////////////////////////////////////////////////////// +AnimChannelMatrixDynamic:: +AnimChannelMatrixDynamic() { +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::has_changed +// Access: Public, Virtual +// Description: Returns true if the value has changed since the last +// call to has_changed(). last_frame is the frame +// number of the last call; this_frame is the current +// frame number. +//////////////////////////////////////////////////////////////////// +bool AnimChannelMatrixDynamic:: +has_changed(int, int) { + if (_value_node != (PandaNode *)NULL) { + _value = _value_node->get_transform(); + } + bool has_changed = (_value != _last_value); + _last_value = _value; + return has_changed; +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::get_value +// Access: Public, Virtual +// Description: Gets the value of the channel at the indicated frame. +//////////////////////////////////////////////////////////////////// +void AnimChannelMatrixDynamic:: +get_value(int, LMatrix4f &mat) { + mat = _value->get_mat(); +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::get_value_no_scale +// Access: Public, Virtual +// Description: Gets the value of the channel at the indicated frame, +// without any scale information. +//////////////////////////////////////////////////////////////////// +void AnimChannelMatrixDynamic:: +get_value_no_scale(int frame, LMatrix4f &mat) { + if (_value->has_scale()) { + compose_matrix(mat, LVecBase3f(1.0f, 1.0f, 1.0f), + _value->get_hpr(), _value->get_pos()); + } else { + mat = _value->get_mat(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::get_scale +// Access: Public, Virtual +// Description: Gets the scale value at the indicated frame. +//////////////////////////////////////////////////////////////////// +void AnimChannelMatrixDynamic:: +get_scale(int frame, float scale[3]) { + const LVecBase3f &sc = _value->get_scale(); + scale[0] = sc[0]; + scale[1] = sc[1]; + scale[2] = sc[2]; +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::set_value +// Access: Published +// Description: Explicitly sets the matrix value. +//////////////////////////////////////////////////////////////////// +void AnimChannelMatrixDynamic:: +set_value(const LMatrix4f &value) { + _value = TransformState::make_mat(value); + _value_node.clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::set_value +// Access: Published +// Description: Explicitly sets the matrix value, using the indicated +// TransformState object as a convenience. +//////////////////////////////////////////////////////////////////// +void AnimChannelMatrixDynamic:: +set_value(const TransformState *value) { + _value = value; + _value_node.clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::set_value_node +// Access: Published +// Description: Specifies a node whose transform will be queried each +// frame to implicitly specify the transform of this +// joint. +//////////////////////////////////////////////////////////////////// +void AnimChannelMatrixDynamic:: +set_value_node(PandaNode *value_node) { + _value_node = value_node; +} + + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::write_datagram +// Access: Public +// Description: Function to write the important information in +// the particular object to a Datagram +//////////////////////////////////////////////////////////////////// +void AnimChannelMatrixDynamic:: +write_datagram(BamWriter *manager, Datagram &dg) { + AnimChannelMatrix::write_datagram(manager, dg); + manager->write_pointer(dg, _value_node); + manager->write_pointer(dg, _value); +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::complete_pointers +// Access: Public, Virtual +// Description: Receives an array of pointers, one for each time +// manager->read_pointer() was called in fillin(). +// Returns the number of pointers processed. +//////////////////////////////////////////////////////////////////// +int AnimChannelMatrixDynamic:: +complete_pointers(TypedWritable **p_list, BamReader *manager) { + int pi = AnimChannelMatrix::complete_pointers(p_list, manager); + + // Get the _value_node and _value pointers. + _value_node = DCAST(PandaNode, p_list[pi++]); + _value = DCAST(TransformState, p_list[pi++]); + + return pi; +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::fillin +// Access: Public +// Description: Function that reads out of the datagram (or asks +// manager to read) all of the data that is needed to +// re-create this object and stores it in the appropiate +// place +//////////////////////////////////////////////////////////////////// +void AnimChannelMatrixDynamic:: +fillin(DatagramIterator &scan, BamReader *manager) { + AnimChannelMatrix::fillin(scan, manager); + + // Read the _value_node and _value pointers. + manager->read_pointer(scan); + manager->read_pointer(scan); +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::make_AnimChannelMatrixDynamic +// Access: Public +// Description: Factory method to generate an +// AnimChannelMatrixDynamic object. +//////////////////////////////////////////////////////////////////// +TypedWritable *AnimChannelMatrixDynamic:: +make_AnimChannelMatrixDynamic(const FactoryParams ¶ms) { + AnimChannelMatrixDynamic *me = new AnimChannelMatrixDynamic; + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + me->fillin(scan, manager); + return me; +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixDynamic::register_with_factory +// Access: Public, Static +// Description: Factory method to generate an +// AnimChannelMatrixDynamic object. +//////////////////////////////////////////////////////////////////// +void AnimChannelMatrixDynamic:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_AnimChannelMatrixDynamic); +} + + diff --git a/panda/src/chan/animChannelMatrixDynamic.h b/panda/src/chan/animChannelMatrixDynamic.h new file mode 100644 index 0000000000..bf927e8c28 --- /dev/null +++ b/panda/src/chan/animChannelMatrixDynamic.h @@ -0,0 +1,96 @@ +// Filename: animChannelMatrixDynamic.h +// Created by: drose (20Oct03) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#ifndef ANIMCHANNELMATRIXDYNAMIC_H +#define ANIMCHANNELMATRIXDYNAMIC_H + +#include "pandabase.h" + +#include "animChannel.h" +#include "transformState.h" +#include "pandaNode.h" +#include "pointerTo.h" + +//////////////////////////////////////////////////////////////////// +// Class : AnimChannelMatrixDynamic +// Description : An animation channel that accepts a matrix each frame +// from some dynamic input provided by code. +// +// This object operates in two modes: in explicit mode, +// the programmer should call set_value() each frame to +// indicate the new value; in implicit mode, the +// programmer should call set_value_node() to indicate +// the node whose transform will be copied to the joint +// each frame. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA AnimChannelMatrixDynamic : public AnimChannelMatrix { +public: + AnimChannelMatrixDynamic(AnimGroup *parent, const string &name); + +protected: + AnimChannelMatrixDynamic(); + +public: + virtual bool has_changed(int last_frame, int this_frame); + virtual void get_value(int frame, LMatrix4f &mat); + virtual void get_value_no_scale(int frame, LMatrix4f &value); + virtual void get_scale(int frame, float scale[3]); + +PUBLISHED: + void set_value(const LMatrix4f &value); + void set_value(const TransformState *value); + void set_value_node(PandaNode *node); + +private: + // This is filled in only if we are using the set_value_node() + // interface to get an implicit value from the transform on the + // indicated node each frame. + PT(PandaNode) _value_node; + + CPT(TransformState) _value; + CPT(TransformState) _last_value; + +public: + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &dg); + virtual int complete_pointers(TypedWritable **plist, BamReader *manager); + void fillin(DatagramIterator &scan, BamReader *manager); + + static TypedWritable *make_AnimChannelMatrixDynamic(const FactoryParams ¶ms); + +public: + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + AnimChannelMatrix::init_type(); + register_type(_type_handle, "AnimChannelMatrixDynamic", + AnimChannelMatrix::get_class_type()); + } + +private: + static TypeHandle _type_handle; +}; + +#include "animChannelMatrixDynamic.I" + +#endif diff --git a/panda/src/chan/animChannelMatrixXfmTable.cxx b/panda/src/chan/animChannelMatrixXfmTable.cxx index 47acf583cb..6d3e7e8c27 100644 --- a/panda/src/chan/animChannelMatrixXfmTable.cxx +++ b/panda/src/chan/animChannelMatrixXfmTable.cxx @@ -41,10 +41,22 @@ AnimChannelMatrixXfmTable(AnimGroup *parent, const string &name) : AnimChannelMatrix(parent, name) { } +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixXfmTable::Constructor +// Access: Protected +// Description: Used only for bam loader. ///////////////////////////////////////////////////////////// AnimChannelMatrixXfmTable:: -AnimChannelMatrixXfmTable(void) -{ +AnimChannelMatrixXfmTable() { +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelMatrixXfmTable::Destructor +// Access: Public, Virtual +// Description: +///////////////////////////////////////////////////////////// +AnimChannelMatrixXfmTable:: +~AnimChannelMatrixXfmTable() { } @@ -58,11 +70,13 @@ AnimChannelMatrixXfmTable(void) //////////////////////////////////////////////////////////////////// bool AnimChannelMatrixXfmTable:: has_changed(int last_frame, int 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()]) { - return true; + if (last_frame != 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()]) { + return true; + } } } } diff --git a/panda/src/chan/animChannelMatrixXfmTable.h b/panda/src/chan/animChannelMatrixXfmTable.h index c59ac3eff5..071172b88b 100644 --- a/panda/src/chan/animChannelMatrixXfmTable.h +++ b/panda/src/chan/animChannelMatrixXfmTable.h @@ -38,6 +38,12 @@ class EXPCL_PANDA AnimChannelMatrixXfmTable : public AnimChannelMatrix { public: AnimChannelMatrixXfmTable(AnimGroup *parent, const string &name); +protected: + AnimChannelMatrixXfmTable(); + +public: + ~AnimChannelMatrixXfmTable(); + virtual bool has_changed(int last_frame, int this_frame); virtual void get_value(int frame, LMatrix4f &mat); @@ -46,16 +52,17 @@ public: static INLINE bool is_valid_id(char table_id); +PUBLISHED: void clear_all_tables(); void set_table(char table_id, const CPTA_float &table); INLINE bool has_table(char table_id) const; INLINE CPTA_float get_table(char table_id) const; INLINE void clear_table(char table_id); +public: virtual void write(ostream &out, int indent_level) const; protected: - AnimChannelMatrixXfmTable(void); INLINE static char get_table_id(int table_index); static int get_table_index(char table_id); INLINE static float get_default_value(int table_index); diff --git a/panda/src/chan/animChannelScalarDynamic.I b/panda/src/chan/animChannelScalarDynamic.I new file mode 100644 index 0000000000..5527044ad7 --- /dev/null +++ b/panda/src/chan/animChannelScalarDynamic.I @@ -0,0 +1,18 @@ +// Filename: animChannelScalarDynamic.I +// Created by: drose (20Oct03) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + diff --git a/panda/src/chan/animChannelScalarDynamic.cxx b/panda/src/chan/animChannelScalarDynamic.cxx new file mode 100644 index 0000000000..0dd4ca931b --- /dev/null +++ b/panda/src/chan/animChannelScalarDynamic.cxx @@ -0,0 +1,198 @@ +// Filename: animChannelScalarDynamic.cxx +// Created by: drose (20Oct03) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#include "animChannelScalarDynamic.h" +#include "animBundle.h" +#include "config_chan.h" + +#include "indent.h" +#include "datagram.h" +#include "datagramIterator.h" +#include "bamReader.h" +#include "bamWriter.h" + +TypeHandle AnimChannelScalarDynamic::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelScalarDynamic::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +AnimChannelScalarDynamic:: +AnimChannelScalarDynamic(AnimGroup *parent, const string &name) + : AnimChannelScalar(parent, name) +{ + _last_value = _value = TransformState::make_identity(); +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelScalarDynamic::Constructor +// Access: Protected +// Description: For use only with the bam reader. +//////////////////////////////////////////////////////////////////// +AnimChannelScalarDynamic:: +AnimChannelScalarDynamic() { +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelScalarDynamic::has_changed +// Access: Public, Virtual +// Description: Returns true if the value has changed since the last +// call to has_changed(). last_frame is the frame +// number of the last call; this_frame is the current +// frame number. +//////////////////////////////////////////////////////////////////// +bool AnimChannelScalarDynamic:: +has_changed(int, int) { + if (_value_node != (PandaNode *)NULL) { + _value = _value_node->get_transform(); + bool has_changed = (_value != _last_value); + _last_value = _value; + return has_changed; + + } else { + bool has_changed = _value_changed; + _value_changed = false; + return has_changed; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelScalarDynamic::get_value +// Access: Public, Virtual +// Description: Gets the value of the channel at the indicated frame. +//////////////////////////////////////////////////////////////////// +void AnimChannelScalarDynamic:: +get_value(int, float &value) { + if (_value_node != (PandaNode *)NULL) { + value = _value->get_pos()[0]; + + } else { + value = _float_value; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelScalarDynamic::set_value +// Access: Published +// Description: Explicitly sets the value. +//////////////////////////////////////////////////////////////////// +void AnimChannelScalarDynamic:: +set_value(float value) { + _float_value = value; + _value_node.clear(); + _value_changed = true; +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelScalarDynamic::set_value_node +// Access: Published +// Description: Specifies a node whose transform will be queried each +// frame to implicitly specify the transform of this +// joint. +//////////////////////////////////////////////////////////////////// +void AnimChannelScalarDynamic:: +set_value_node(PandaNode *value_node) { + if (_value_node == (PandaNode *)NULL) { + _last_value = TransformState::make_pos(LVecBase3f(_float_value, 0.0f, 0.0f)); + } + + _value_node = value_node; +} + + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelScalarDynamic::write_datagram +// Access: Public +// Description: Function to write the important information in +// the particular object to a Datagram +//////////////////////////////////////////////////////////////////// +void AnimChannelScalarDynamic:: +write_datagram(BamWriter *manager, Datagram &dg) { + AnimChannelScalar::write_datagram(manager, dg); + manager->write_pointer(dg, _value_node); + manager->write_pointer(dg, _value); + dg.add_float32(_float_value); +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelScalarDynamic::complete_pointers +// Access: Public, Virtual +// Description: Receives an array of pointers, one for each time +// manager->read_pointer() was called in fillin(). +// Returns the number of pointers processed. +//////////////////////////////////////////////////////////////////// +int AnimChannelScalarDynamic:: +complete_pointers(TypedWritable **p_list, BamReader *manager) { + int pi = AnimChannelScalar::complete_pointers(p_list, manager); + + // Get the _value_node and _value pointers. + _value_node = DCAST(PandaNode, p_list[pi++]); + _value = DCAST(TransformState, p_list[pi++]); + + return pi; +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelScalarDynamic::fillin +// Access: Public +// Description: Function that reads out of the datagram (or asks +// manager to read) all of the data that is needed to +// re-create this object and stores it in the appropiate +// place +//////////////////////////////////////////////////////////////////// +void AnimChannelScalarDynamic:: +fillin(DatagramIterator &scan, BamReader *manager) { + AnimChannelScalar::fillin(scan, manager); + + // Read the _value_node and _value pointers. + manager->read_pointer(scan); + manager->read_pointer(scan); + + _float_value = scan.get_float32(); +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelScalarDynamic::make_AnimChannelScalarDynamic +// Access: Public +// Description: Factory method to generate a AnimChannelScalarDynamic object +//////////////////////////////////////////////////////////////////// +TypedWritable *AnimChannelScalarDynamic:: +make_AnimChannelScalarDynamic(const FactoryParams ¶ms) { + AnimChannelScalarDynamic *me = new AnimChannelScalarDynamic; + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + me->fillin(scan, manager); + return me; +} + +//////////////////////////////////////////////////////////////////// +// Function: AnimChannelScalarDynamic::register_with_factory +// Access: Public, Static +// Description: Factory method to generate a AnimChannelScalarDynamic object +//////////////////////////////////////////////////////////////////// +void AnimChannelScalarDynamic:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_AnimChannelScalarDynamic); +} + + + + diff --git a/panda/src/chan/animChannelScalarDynamic.h b/panda/src/chan/animChannelScalarDynamic.h new file mode 100644 index 0000000000..5708dbdc95 --- /dev/null +++ b/panda/src/chan/animChannelScalarDynamic.h @@ -0,0 +1,93 @@ +// Filename: animChannelScalarDynamic.h +// Created by: drose (20Oct03) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#ifndef ANIMCHANNELSCALARDYNAMIC_H +#define ANIMCHANNELSCALARDYNAMIC_H + +#include "pandabase.h" + +#include "animChannel.h" + +//////////////////////////////////////////////////////////////////// +// Class : AnimChannelScalarDynamic +// Description : An animation channel that accepts a scalar each frame +// from some dynamic input provided by code. +// +// This object operates in two modes: in explicit mode, +// the programmer should call set_value() each frame to +// indicate the new value; in implicit mode, the +// programmer should call set_value_node() to indicate +// the node whose X component will be copied to the +// scalar each frame. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA AnimChannelScalarDynamic : public AnimChannelScalar { +public: + AnimChannelScalarDynamic(AnimGroup *parent, const string &name); +protected: + AnimChannelScalarDynamic(); + +public: + virtual bool has_changed(int last_frame, int this_frame); + virtual void get_value(int frame, float &value); + +PUBLISHED: + void set_value(float value); + void set_value_node(PandaNode *node); + +private: + // This is filled in only if we are using the set_value_node() + // interface to get an implicit value from the transform on the + // indicated node each frame. + PT(PandaNode) _value_node; + CPT(TransformState) _value; + CPT(TransformState) _last_value; + + // This is used only if we are using the explicit set_value() + // interface. + bool _value_changed; + bool _float_value; + +public: + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &dg); + virtual int complete_pointers(TypedWritable **plist, BamReader *manager); + void fillin(DatagramIterator &scan, BamReader *manager); + + static TypedWritable *make_AnimChannelScalarDynamic(const FactoryParams ¶ms); + +public: + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + AnimChannelScalar::init_type(); + register_type(_type_handle, "AnimChannelScalarDynamic", + AnimChannelScalar::get_class_type()); + } + +private: + static TypeHandle _type_handle; +}; + +#include "animChannelScalarDynamic.I" + +#endif diff --git a/panda/src/chan/animChannelScalarTable.cxx b/panda/src/chan/animChannelScalarTable.cxx index 97bbf6651a..aa51ecac77 100644 --- a/panda/src/chan/animChannelScalarTable.cxx +++ b/panda/src/chan/animChannelScalarTable.cxx @@ -59,7 +59,7 @@ AnimChannelScalarTable(void){ //////////////////////////////////////////////////////////////////// bool AnimChannelScalarTable:: has_changed(int last_frame, int this_frame) { - if (_table.size() > 1) { + if (last_frame != this_frame && _table.size() > 1) { if (_table[last_frame % _table.size()] != _table[this_frame % _table.size()]) { return true; diff --git a/panda/src/chan/animChannelScalarTable.h b/panda/src/chan/animChannelScalarTable.h index 6ccc371533..13493e6331 100644 --- a/panda/src/chan/animChannelScalarTable.h +++ b/panda/src/chan/animChannelScalarTable.h @@ -19,12 +19,12 @@ #ifndef ANIMCHANNELSCALARTABLE_H #define ANIMCHANNELSCALARTABLE_H -#include +#include "pandabase.h" #include "animChannel.h" -#include -#include +#include "pointerToArray.h" +#include "pta_float.h" //////////////////////////////////////////////////////////////////// // Class : AnimChannelScalarTable @@ -39,10 +39,12 @@ public: virtual bool has_changed(int last_frame, int this_frame); virtual void get_value(int frame, float &value); +PUBLISHED: void set_table(const CPTA_float &table); INLINE bool has_table() const; INLINE void clear_table(); +public: virtual void write(ostream &out, int indent_level) const; protected: diff --git a/panda/src/chan/animControl.cxx b/panda/src/chan/animControl.cxx index 103c2e2058..96ad9d8505 100644 --- a/panda/src/chan/animControl.cxx +++ b/panda/src/chan/animControl.cxx @@ -442,11 +442,6 @@ channel_has_changed(AnimChannelBase *channel) const { } int this_frame = get_frame(); - - if (this_frame == _marked_frame) { - return false; - } - return channel->has_changed(_marked_frame, this_frame); } diff --git a/panda/src/chan/animGroup.cxx b/panda/src/chan/animGroup.cxx index 01dddc045e..413af77ab0 100644 --- a/panda/src/chan/animGroup.cxx +++ b/panda/src/chan/animGroup.cxx @@ -19,13 +19,15 @@ #include "animGroup.h" #include "animBundle.h" +#include "animChannelMatrixDynamic.h" +#include "animChannelScalarDynamic.h" #include "config_chan.h" -#include -#include -#include -#include -#include +#include "indent.h" +#include "datagram.h" +#include "datagramIterator.h" +#include "bamReader.h" +#include "bamWriter.h" #include @@ -48,6 +50,15 @@ AnimGroup(AnimGroup *parent, const string &name) : Namable(name) { _root = parent->_root; } +//////////////////////////////////////////////////////////////////// +// Function: AnimGroup::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +AnimGroup:: +~AnimGroup() { +} + //////////////////////////////////////////////////////////////////// // Function: AnimGroup::get_num_children @@ -94,6 +105,89 @@ find_child(const string &name) const { return (AnimGroup *)NULL; } +//////////////////////////////////////////////////////////////////// +// Function: AnimGroup::make_child_dynamic +// Access: Public +// Description: Finds the indicated child and replaces it with an +// AnimChannelMatrixDynamic or AnimChannelScalarDynamic, +// as appropriate, and returns the new channel. +// +// This may be called before binding the animation to a +// character to replace certain joints with +// dynamically-controlled ones. +// +// Returns NULL if the named child cannot be found. +//////////////////////////////////////////////////////////////////// +AnimGroup *AnimGroup:: +make_child_dynamic(const string &name) { + Children::iterator ci; + for (ci = _children.begin(); ci != _children.end(); ++ci) { + AnimGroup *child = (*ci); + if (child->get_name() == name) { + AnimGroup *new_child = NULL; + + if (child->is_of_type(AnimChannelMatrix::get_class_type())) { + AnimChannelMatrix *mchild = DCAST(AnimChannelMatrix, child); + AnimChannelMatrixDynamic *new_mchild = + new AnimChannelMatrixDynamic(this, name); + new_child = new_mchild; + + // Copy in the original value from frame 0. + LMatrix4f orig_value; + mchild->get_value(0, orig_value); + new_mchild->set_value(orig_value); + + } else if (child->is_of_type(AnimChannelScalar::get_class_type())) { + AnimChannelScalar *schild = DCAST(AnimChannelScalar, child); + AnimChannelScalarDynamic *new_schild = + new AnimChannelScalarDynamic(this, name); + new_child = new_schild; + + // Copy in the original value from frame 0. + float orig_value; + schild->get_value(0, orig_value); + new_schild->set_value(orig_value); + } + + if (new_child != (AnimGroup *)NULL) { + new_child->_children.swap(child->_children); + nassertr(_children.back() == new_child, NULL); + + // The new child was appended to the end of our children list + // by its constructor. Reposition it to replace the original + // child. +#ifndef __GNUC__ + // There appears to be a compiler bug in gcc 3.2 that causes + // the following not to compile correctly: + (*ci) = new_child; + _children.pop_back(); +#else + // But this longer way of achieving the same result works + // instead: + Children::iterator nci; + Children new_children; + for (nci = _children.begin(); nci != _children.end(); ++nci) { + if ((*nci) == child) { + new_children.push_back(new_child); + } else if ((*nci) != new_child) { + new_children.push_back(*nci); + } + } + new_children.swap(_children); + new_children.clear(); +#endif + return new_child; + } + } + AnimGroup *result = child->make_child_dynamic(name); + if (result != (AnimGroup *)NULL) { + return result; + } + } + + return (AnimGroup *)NULL; +} + //////////////////////////////////////////////////////////////////// // Function: AnimGroup::get_value_type // Access: Public, Virtual @@ -154,9 +248,13 @@ output(ostream &out) const { //////////////////////////////////////////////////////////////////// void AnimGroup:: write(ostream &out, int indent_level) const { - indent(out, indent_level) << *this << " {\n"; - write_descendants(out, indent_level + 2); - indent(out, indent_level) << "}\n"; + indent(out, indent_level) << *this; + if (!_children.empty()) { + out << " {\n"; + write_descendants(out, indent_level + 2); + indent(out, indent_level) << "}"; + } + out << "\n"; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/chan/animGroup.h b/panda/src/chan/animGroup.h index 823df926b4..cbeb597cda 100644 --- a/panda/src/chan/animGroup.h +++ b/panda/src/chan/animGroup.h @@ -47,12 +47,15 @@ protected: public: // This is the normal AnimGroup constructor. AnimGroup(AnimGroup *parent, const string &name); + virtual ~AnimGroup(); PUBLISHED: int get_num_children() const; AnimGroup *get_child(int n) const; AnimGroup *find_child(const string &name) const; + AnimGroup *make_child_dynamic(const string &name); + public: virtual TypeHandle get_value_type() const; diff --git a/panda/src/chan/chan_composite2.cxx b/panda/src/chan/chan_composite2.cxx index c501eca931..fe8dbd1a3a 100644 --- a/panda/src/chan/chan_composite2.cxx +++ b/panda/src/chan/chan_composite2.cxx @@ -3,7 +3,9 @@ #include "animBundleNode.cxx" #include "animChannel.cxx" #include "animChannelBase.cxx" +#include "animChannelMatrixDynamic.cxx" #include "animChannelMatrixXfmTable.cxx" +#include "animChannelScalarDynamic.cxx" #include "animChannelScalarTable.cxx" #include "animControl.cxx" #include "animControlCollection.cxx" diff --git a/panda/src/chan/config_chan.cxx b/panda/src/chan/config_chan.cxx index 34dfc8abea..44f70d7b00 100644 --- a/panda/src/chan/config_chan.cxx +++ b/panda/src/chan/config_chan.cxx @@ -22,7 +22,9 @@ #include "animBundleNode.h" #include "animChannelBase.h" #include "animChannelMatrixXfmTable.h" +#include "animChannelMatrixDynamic.h" #include "animChannelScalarTable.h" +#include "animChannelScalarDynamic.h" #include "animControl.h" #include "animGroup.h" #include "movingPartBase.h" @@ -81,7 +83,9 @@ ConfigureFn(config_chan) { AnimBundleNode::init_type(); AnimChannelBase::init_type(); AnimChannelMatrixXfmTable::init_type(); + AnimChannelMatrixDynamic::init_type(); AnimChannelScalarTable::init_type(); + AnimChannelScalarDynamic::init_type(); AnimControl::init_type(); AnimGroup::init_type(); MovingPartBase::init_type(); @@ -108,7 +112,9 @@ ConfigureFn(config_chan) { AnimBundle::register_with_read_factory(); AnimBundleNode::register_with_read_factory(); AnimChannelMatrixXfmTable::register_with_read_factory(); + AnimChannelMatrixDynamic::register_with_read_factory(); AnimChannelScalarTable::register_with_read_factory(); + AnimChannelScalarDynamic::register_with_read_factory(); } diff --git a/panda/src/chan/movingPartBase.cxx b/panda/src/chan/movingPartBase.cxx index 8cc7781320..8fdcf03f07 100644 --- a/panda/src/chan/movingPartBase.cxx +++ b/panda/src/chan/movingPartBase.cxx @@ -152,7 +152,7 @@ do_update(PartBundle *root, PartGroup *parent, //////////////////////////////////////////////////////////////////// bool MovingPartBase:: update_internals(PartGroup *, bool, bool) { - return false; + return true; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/char/dynamicVertices.cxx b/panda/src/char/dynamicVertices.cxx index 7212f77cd3..6e81143eec 100644 --- a/panda/src/char/dynamicVertices.cxx +++ b/panda/src/char/dynamicVertices.cxx @@ -18,11 +18,11 @@ #include "dynamicVertices.h" #include "config_char.h" -#include -#include -#include -#include -#include +#include "bamReader.h" +#include "bamWriter.h" +#include "datagram.h" +#include "datagramIterator.h" +#include "ioPtaDatagramLinMath.h" TypeHandle DynamicVertices::_type_handle; diff --git a/panda/src/char/dynamicVertices.h b/panda/src/char/dynamicVertices.h index ceb7bb3fbf..c4d58beb89 100644 --- a/panda/src/char/dynamicVertices.h +++ b/panda/src/char/dynamicVertices.h @@ -19,22 +19,25 @@ #ifndef DYNAMICVERTICES_H #define DYNAMICVERTICES_H -#include +#include "pandabase.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include "pointerToArray.h" +#include "typedObject.h" +#include "luse.h" +#include "pta_Vertexf.h" +#include "pta_Normalf.h" +#include "pta_Colorf.h" +#include "pta_TexCoordf.h" +#include "typedWritable.h" class BamReader; //////////////////////////////////////////////////////////////////// // Class : DynamicVertices -// Description : +// Description : A table of vertices associated with a Character that +// must be computed dynamically each frame. This is the +// actual table of vertices; see ComputedVertices for +// the code to compute their values. //////////////////////////////////////////////////////////////////// class EXPCL_PANDA DynamicVertices : public TypedWritable { public: