Explorar el Código

add dynamic control for joints and sliders

David Rose hace 22 años
padre
commit
3e2948ec8c

+ 18 - 8
panda/src/chan/Sources.pp

@@ -12,9 +12,12 @@
     animBundle.I animBundle.h \
     animBundle.I animBundle.h \
     animBundleNode.I animBundleNode.h \
     animBundleNode.I animBundleNode.h \
     animChannel.I animChannel.h animChannelBase.I  \
     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  \
     animControl.h animControlCollection.I  \
     animControlCollection.h animGroup.I animGroup.h auto_bind.h  \
     animControlCollection.h animGroup.I animGroup.h auto_bind.h  \
     config_chan.h movingPartBase.I movingPartBase.h  \
     config_chan.h movingPartBase.I movingPartBase.h  \
@@ -28,8 +31,12 @@
     animBundle.cxx \
     animBundle.cxx \
     animBundleNode.cxx \
     animBundleNode.cxx \
     animChannel.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  \
     animControlCollection.cxx animGroup.cxx auto_bind.cxx  \
     config_chan.cxx movingPartBase.cxx movingPartMatrix.cxx  \
     config_chan.cxx movingPartBase.cxx movingPartMatrix.cxx  \
     movingPartScalar.cxx partBundle.cxx \
     movingPartScalar.cxx partBundle.cxx \
@@ -40,9 +47,12 @@
     animBundle.I animBundle.h \
     animBundle.I animBundle.h \
     animBundleNode.I animBundleNode.h \
     animBundleNode.I animBundleNode.h \
     animChannel.I animChannel.h animChannelBase.I animChannelBase.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 \
     animControlCollection.I animControlCollection.h animGroup.I \
     animGroup.h auto_bind.h config_chan.h \
     animGroup.h auto_bind.h config_chan.h \
     movingPart.I movingPart.h movingPartBase.I \
     movingPart.I movingPart.h movingPartBase.I \

+ 1 - 0
panda/src/chan/animChannel.h

@@ -44,6 +44,7 @@ public:
 
 
   INLINE AnimChannel(AnimGroup *parent, const string &name);
   INLINE AnimChannel(AnimGroup *parent, const string &name);
 
 
+PUBLISHED:
   virtual void get_value(int frame, ValueType &value)=0;
   virtual void get_value(int frame, ValueType &value)=0;
 
 
   // These two functions only have meaning for matrix types.
   // These two functions only have meaning for matrix types.

+ 0 - 10
panda/src/chan/animChannelBase.cxx

@@ -39,16 +39,6 @@ has_changed(int, int) {
   return true;
   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
 //     Function: AnimChannelBase::write_datagram
 //       Access: Public
 //       Access: Public

+ 3 - 3
panda/src/chan/animChannelBase.h

@@ -48,7 +48,6 @@ public:
   virtual bool has_changed(int last_frame, int this_frame);
   virtual bool has_changed(int last_frame, int this_frame);
 
 
   virtual TypeHandle get_value_type() const=0;
   virtual TypeHandle get_value_type() const=0;
-  virtual void output(ostream &out) const;
 
 
 protected:
 protected:
 
 
@@ -60,11 +59,12 @@ public:
 protected:
 protected:
   void fillin(DatagramIterator& scan, BamReader* manager);
   void fillin(DatagramIterator& scan, BamReader* manager);
 
 
-public:
-
+PUBLISHED:
   virtual TypeHandle get_type() const {
   virtual TypeHandle get_type() const {
     return get_class_type();
     return get_class_type();
   }
   }
+
+public:
   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {
     return _type_handle;
     return _type_handle;

+ 19 - 0
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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+

+ 223 - 0
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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#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 &params) {
+  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);
+}
+
+

+ 96 - 0
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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#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 &params);
+
+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

+ 21 - 7
panda/src/chan/animChannelMatrixXfmTable.cxx

@@ -41,10 +41,22 @@ AnimChannelMatrixXfmTable(AnimGroup *parent, const string &name)
   : AnimChannelMatrix(parent, name) {
   : AnimChannelMatrix(parent, name) {
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: AnimChannelMatrixXfmTable::Constructor
+//       Access: Protected
+//  Description: Used only for bam loader.
+/////////////////////////////////////////////////////////////
+AnimChannelMatrixXfmTable::
+AnimChannelMatrixXfmTable() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AnimChannelMatrixXfmTable::Destructor
+//       Access: Public, Virtual
+//  Description: 
 /////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////
 AnimChannelMatrixXfmTable::
 AnimChannelMatrixXfmTable::
-AnimChannelMatrixXfmTable(void)
-{
+~AnimChannelMatrixXfmTable() {
 }
 }
 
 
 
 
@@ -58,11 +70,13 @@ AnimChannelMatrixXfmTable(void)
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool AnimChannelMatrixXfmTable::
 bool AnimChannelMatrixXfmTable::
 has_changed(int last_frame, int this_frame) {
 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;
+        }
       }
       }
     }
     }
   }
   }

+ 8 - 1
panda/src/chan/animChannelMatrixXfmTable.h

@@ -38,6 +38,12 @@
 class EXPCL_PANDA AnimChannelMatrixXfmTable : public AnimChannelMatrix {
 class EXPCL_PANDA AnimChannelMatrixXfmTable : public AnimChannelMatrix {
 public:
 public:
   AnimChannelMatrixXfmTable(AnimGroup *parent, const string &name);
   AnimChannelMatrixXfmTable(AnimGroup *parent, const string &name);
+protected:
+  AnimChannelMatrixXfmTable();
+
+public:
+  ~AnimChannelMatrixXfmTable();
+  
 
 
   virtual bool has_changed(int last_frame, int this_frame);
   virtual bool has_changed(int last_frame, int this_frame);
   virtual void get_value(int frame, LMatrix4f &mat);
   virtual void get_value(int frame, LMatrix4f &mat);
@@ -46,16 +52,17 @@ public:
 
 
   static INLINE bool is_valid_id(char table_id);
   static INLINE bool is_valid_id(char table_id);
 
 
+PUBLISHED:
   void clear_all_tables();
   void clear_all_tables();
   void set_table(char table_id, const CPTA_float &table);
   void set_table(char table_id, const CPTA_float &table);
   INLINE bool has_table(char table_id) const;
   INLINE bool has_table(char table_id) const;
   INLINE CPTA_float get_table(char table_id) const;
   INLINE CPTA_float get_table(char table_id) const;
   INLINE void clear_table(char table_id);
   INLINE void clear_table(char table_id);
 
 
+public:
   virtual void write(ostream &out, int indent_level) const;
   virtual void write(ostream &out, int indent_level) const;
 
 
 protected:
 protected:
-  AnimChannelMatrixXfmTable(void);
   INLINE static char get_table_id(int table_index);
   INLINE static char get_table_id(int table_index);
   static int get_table_index(char table_id);
   static int get_table_index(char table_id);
   INLINE static float get_default_value(int table_index);
   INLINE static float get_default_value(int table_index);

+ 18 - 0
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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+

+ 198 - 0
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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#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 &params) {
+  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);
+}
+
+
+
+

+ 93 - 0
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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#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 &params);
+
+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

+ 1 - 1
panda/src/chan/animChannelScalarTable.cxx

@@ -59,7 +59,7 @@ AnimChannelScalarTable(void){
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool AnimChannelScalarTable::
 bool AnimChannelScalarTable::
 has_changed(int last_frame, int this_frame) {
 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()] !=
     if (_table[last_frame % _table.size()] !=
         _table[this_frame % _table.size()]) {
         _table[this_frame % _table.size()]) {
       return true;
       return true;

+ 5 - 3
panda/src/chan/animChannelScalarTable.h

@@ -19,12 +19,12 @@
 #ifndef ANIMCHANNELSCALARTABLE_H
 #ifndef ANIMCHANNELSCALARTABLE_H
 #define ANIMCHANNELSCALARTABLE_H
 #define ANIMCHANNELSCALARTABLE_H
 
 
-#include <pandabase.h>
+#include "pandabase.h"
 
 
 #include "animChannel.h"
 #include "animChannel.h"
 
 
-#include <pointerToArray.h>
-#include <pta_float.h>
+#include "pointerToArray.h"
+#include "pta_float.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : AnimChannelScalarTable
 //       Class : AnimChannelScalarTable
@@ -39,10 +39,12 @@ public:
   virtual bool has_changed(int last_frame, int this_frame);
   virtual bool has_changed(int last_frame, int this_frame);
   virtual void get_value(int frame, float &value);
   virtual void get_value(int frame, float &value);
 
 
+PUBLISHED:
   void set_table(const CPTA_float &table);
   void set_table(const CPTA_float &table);
   INLINE bool has_table() const;
   INLINE bool has_table() const;
   INLINE void clear_table();
   INLINE void clear_table();
 
 
+public:
   virtual void write(ostream &out, int indent_level) const;
   virtual void write(ostream &out, int indent_level) const;
 
 
 protected:
 protected:

+ 0 - 5
panda/src/chan/animControl.cxx

@@ -442,11 +442,6 @@ channel_has_changed(AnimChannelBase *channel) const {
   }
   }
 
 
   int this_frame = get_frame();
   int this_frame = get_frame();
-
-  if (this_frame == _marked_frame) {
-    return false;
-  }
-
   return channel->has_changed(_marked_frame, this_frame);
   return channel->has_changed(_marked_frame, this_frame);
 }
 }
 
 

+ 106 - 8
panda/src/chan/animGroup.cxx

@@ -19,13 +19,15 @@
 
 
 #include "animGroup.h"
 #include "animGroup.h"
 #include "animBundle.h"
 #include "animBundle.h"
+#include "animChannelMatrixDynamic.h"
+#include "animChannelScalarDynamic.h"
 #include "config_chan.h"
 #include "config_chan.h"
 
 
-#include <indent.h>
-#include <datagram.h>
-#include <datagramIterator.h>
-#include <bamReader.h>
-#include <bamWriter.h>
+#include "indent.h"
+#include "datagram.h"
+#include "datagramIterator.h"
+#include "bamReader.h"
+#include "bamWriter.h"
 
 
 
 
 #include <algorithm>
 #include <algorithm>
@@ -48,6 +50,15 @@ AnimGroup(AnimGroup *parent, const string &name) : Namable(name) {
   _root = parent->_root;
   _root = parent->_root;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: AnimGroup::Destructor
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+AnimGroup::
+~AnimGroup() {
+}
+
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: AnimGroup::get_num_children
 //     Function: AnimGroup::get_num_children
@@ -94,6 +105,89 @@ find_child(const string &name) const {
   return (AnimGroup *)NULL;
   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
 //     Function: AnimGroup::get_value_type
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -154,9 +248,13 @@ output(ostream &out) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void AnimGroup::
 void AnimGroup::
 write(ostream &out, int indent_level) const {
 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";
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 3 - 0
panda/src/chan/animGroup.h

@@ -47,12 +47,15 @@ protected:
 public:
 public:
   // This is the normal AnimGroup constructor.
   // This is the normal AnimGroup constructor.
   AnimGroup(AnimGroup *parent, const string &name);
   AnimGroup(AnimGroup *parent, const string &name);
+  virtual ~AnimGroup();
 
 
 PUBLISHED:
 PUBLISHED:
   int get_num_children() const;
   int get_num_children() const;
   AnimGroup *get_child(int n) const;
   AnimGroup *get_child(int n) const;
   AnimGroup *find_child(const string &name) const;
   AnimGroup *find_child(const string &name) const;
 
 
+  AnimGroup *make_child_dynamic(const string &name);
+
 public:
 public:
   virtual TypeHandle get_value_type() const;
   virtual TypeHandle get_value_type() const;
 
 

+ 2 - 0
panda/src/chan/chan_composite2.cxx

@@ -3,7 +3,9 @@
 #include "animBundleNode.cxx"
 #include "animBundleNode.cxx"
 #include "animChannel.cxx"
 #include "animChannel.cxx"
 #include "animChannelBase.cxx"
 #include "animChannelBase.cxx"
+#include "animChannelMatrixDynamic.cxx"
 #include "animChannelMatrixXfmTable.cxx"
 #include "animChannelMatrixXfmTable.cxx"
+#include "animChannelScalarDynamic.cxx"
 #include "animChannelScalarTable.cxx"
 #include "animChannelScalarTable.cxx"
 #include "animControl.cxx"
 #include "animControl.cxx"
 #include "animControlCollection.cxx"
 #include "animControlCollection.cxx"

+ 6 - 0
panda/src/chan/config_chan.cxx

@@ -22,7 +22,9 @@
 #include "animBundleNode.h"
 #include "animBundleNode.h"
 #include "animChannelBase.h"
 #include "animChannelBase.h"
 #include "animChannelMatrixXfmTable.h"
 #include "animChannelMatrixXfmTable.h"
+#include "animChannelMatrixDynamic.h"
 #include "animChannelScalarTable.h"
 #include "animChannelScalarTable.h"
+#include "animChannelScalarDynamic.h"
 #include "animControl.h"
 #include "animControl.h"
 #include "animGroup.h"
 #include "animGroup.h"
 #include "movingPartBase.h"
 #include "movingPartBase.h"
@@ -81,7 +83,9 @@ ConfigureFn(config_chan) {
   AnimBundleNode::init_type();
   AnimBundleNode::init_type();
   AnimChannelBase::init_type();
   AnimChannelBase::init_type();
   AnimChannelMatrixXfmTable::init_type();
   AnimChannelMatrixXfmTable::init_type();
+  AnimChannelMatrixDynamic::init_type();
   AnimChannelScalarTable::init_type();
   AnimChannelScalarTable::init_type();
+  AnimChannelScalarDynamic::init_type();
   AnimControl::init_type();
   AnimControl::init_type();
   AnimGroup::init_type();
   AnimGroup::init_type();
   MovingPartBase::init_type();
   MovingPartBase::init_type();
@@ -108,7 +112,9 @@ ConfigureFn(config_chan) {
   AnimBundle::register_with_read_factory();
   AnimBundle::register_with_read_factory();
   AnimBundleNode::register_with_read_factory();
   AnimBundleNode::register_with_read_factory();
   AnimChannelMatrixXfmTable::register_with_read_factory();
   AnimChannelMatrixXfmTable::register_with_read_factory();
+  AnimChannelMatrixDynamic::register_with_read_factory();
   AnimChannelScalarTable::register_with_read_factory();
   AnimChannelScalarTable::register_with_read_factory();
+  AnimChannelScalarDynamic::register_with_read_factory();
 }
 }
 
 
 
 

+ 1 - 1
panda/src/chan/movingPartBase.cxx

@@ -152,7 +152,7 @@ do_update(PartBundle *root, PartGroup *parent,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool MovingPartBase::
 bool MovingPartBase::
 update_internals(PartGroup *, bool, bool) {
 update_internals(PartGroup *, bool, bool) {
-  return false;
+  return true;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 5 - 5
panda/src/char/dynamicVertices.cxx

@@ -18,11 +18,11 @@
 
 
 #include "dynamicVertices.h"
 #include "dynamicVertices.h"
 #include "config_char.h"
 #include "config_char.h"
-#include <bamReader.h>
-#include <bamWriter.h>
-#include <datagram.h>
-#include <datagramIterator.h>
-#include <ioPtaDatagramLinMath.h>
+#include "bamReader.h"
+#include "bamWriter.h"
+#include "datagram.h"
+#include "datagramIterator.h"
+#include "ioPtaDatagramLinMath.h"
 
 
 TypeHandle DynamicVertices::_type_handle;
 TypeHandle DynamicVertices::_type_handle;
 
 

+ 13 - 10
panda/src/char/dynamicVertices.h

@@ -19,22 +19,25 @@
 #ifndef DYNAMICVERTICES_H
 #ifndef DYNAMICVERTICES_H
 #define DYNAMICVERTICES_H
 #define DYNAMICVERTICES_H
 
 
-#include <pandabase.h>
+#include "pandabase.h"
 
 
-#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>
+#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 BamReader;
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : DynamicVertices
 //       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 {
 class EXPCL_PANDA DynamicVertices : public TypedWritable {
 public:
 public: