From 6526538d659be73e4c4a54da5bec03e1ebb077d6 Mon Sep 17 00:00:00 2001 From: David Rose Date: Sat, 22 Nov 2003 20:02:27 +0000 Subject: [PATCH] straighten out -TT on animation tables --- panda/src/egg/eggGroup.cxx | 2 +- panda/src/egg/eggGroupNode.cxx | 25 ++++++++++ panda/src/egg/eggGroupNode.h | 1 + panda/src/egg/eggNode.cxx | 23 +++++++++ panda/src/egg/eggNode.h | 5 +- panda/src/egg/eggPrimitive.cxx | 12 +++++ panda/src/egg/eggPrimitive.h | 1 + panda/src/egg/eggTable.cxx | 84 +++++++++++++++++++++++++++++++- panda/src/egg/eggTable.h | 5 ++ panda/src/egg/eggXfmAnimData.cxx | 11 +++++ panda/src/egg/eggXfmAnimData.h | 1 + panda/src/egg/eggXfmSAnim.cxx | 11 +++++ panda/src/egg/eggXfmSAnim.h | 1 + 13 files changed, 178 insertions(+), 4 deletions(-) diff --git a/panda/src/egg/eggGroup.cxx b/panda/src/egg/eggGroup.cxx index a6a1fa6b34..5e66128863 100644 --- a/panda/src/egg/eggGroup.cxx +++ b/panda/src/egg/eggGroup.cxx @@ -971,7 +971,7 @@ adjust_under() { void EggGroup:: r_transform(const LMatrix4d &mat, const LMatrix4d &inv, CoordinateSystem to_cs) { - if (has_transform()) { + if (has_transform() || get_group_type() == GT_joint) { // Since we want to apply this transform to all matrices, // including nested matrices, we can't simply premult it in and // leave it, because that would leave the rotational component in diff --git a/panda/src/egg/eggGroupNode.cxx b/panda/src/egg/eggGroupNode.cxx index 0c074e6a73..b873744142 100644 --- a/panda/src/egg/eggGroupNode.cxx +++ b/panda/src/egg/eggGroupNode.cxx @@ -778,6 +778,31 @@ has_primitives() const { return false; } +//////////////////////////////////////////////////////////////////// +// Function: EggGroupNode::joint_has_primitives +// Access: Published, Virtual +// Description: Returns true if there are any primitives +// (e.g. polygons) defined within this group or below, +// but the search does not include nested joints. +//////////////////////////////////////////////////////////////////// +bool EggGroupNode:: +joint_has_primitives() const { + Children::const_iterator ci; + for (ci = _children.begin(); + ci != _children.end(); + ++ci) { + EggNode *child = (*ci); + + if (!child->is_joint()) { + if (child->joint_has_primitives()) { + return true; + } + } + } + + return false; +} + //////////////////////////////////////////////////////////////////// // Function: EggGroupNode::update_under // Access: Protected, Virtual diff --git a/panda/src/egg/eggGroupNode.h b/panda/src/egg/eggGroupNode.h index ddcb620553..38c947d9d4 100644 --- a/panda/src/egg/eggGroupNode.h +++ b/panda/src/egg/eggGroupNode.h @@ -133,6 +133,7 @@ PUBLISHED: int remove_unused_vertices(); int remove_invalid_primitives(); virtual bool has_primitives() const; + virtual bool joint_has_primitives() const; protected: virtual void update_under(int depth_offset); diff --git a/panda/src/egg/eggNode.cxx b/panda/src/egg/eggNode.cxx index 3e5508cfec..cece8ebc5e 100644 --- a/panda/src/egg/eggNode.cxx +++ b/panda/src/egg/eggNode.cxx @@ -58,6 +58,17 @@ is_joint() const { return false; } +//////////////////////////////////////////////////////////////////// +// Function: EggNode::is_anim_matrix +// Access: Public, Virtual +// Description: Returns true if this node represents a table of +// animation transformation data, false otherwise. +//////////////////////////////////////////////////////////////////// +bool EggNode:: +is_anim_matrix() const { + return false; +} + //////////////////////////////////////////////////////////////////// // Function: EggNode::determine_alpha_mode // Access: Public, Virtual @@ -323,6 +334,18 @@ has_primitives() const { return false; } +//////////////////////////////////////////////////////////////////// +// Function: EggNode::joint_has_primitives +// Access: Protected, Virtual +// Description: Returns true if there are any primitives +// (e.g. polygons) defined within this group or below, +// but the search does not include nested joints. +//////////////////////////////////////////////////////////////////// +bool EggNode:: +joint_has_primitives() const { + return false; +} + //////////////////////////////////////////////////////////////////// // Function: EggNode::r_transform diff --git a/panda/src/egg/eggNode.h b/panda/src/egg/eggNode.h index 7e0ab065d7..a27297ee3b 100644 --- a/panda/src/egg/eggNode.h +++ b/panda/src/egg/eggNode.h @@ -71,6 +71,7 @@ PUBLISHED: void apply_texmats(); virtual bool is_joint() const; + virtual bool is_anim_matrix() const; virtual EggRenderMode *determine_alpha_mode(); virtual EggRenderMode *determine_depth_write_mode(); @@ -101,6 +102,7 @@ protected: virtual void update_under(int depth_offset); virtual void adjust_under(); virtual bool has_primitives() const; + virtual bool joint_has_primitives() const; virtual void r_transform(const LMatrix4d &mat, const LMatrix4d &inv, CoordinateSystem to_cs); @@ -145,7 +147,8 @@ public: private: static TypeHandle _type_handle; -friend class EggGroupNode; + friend class EggGroupNode; + friend class EggTable; }; #include "eggNode.I" diff --git a/panda/src/egg/eggPrimitive.cxx b/panda/src/egg/eggPrimitive.cxx index e8afdd9498..d7b8d11d61 100644 --- a/panda/src/egg/eggPrimitive.cxx +++ b/panda/src/egg/eggPrimitive.cxx @@ -344,6 +344,18 @@ has_primitives() const { return true; } +//////////////////////////////////////////////////////////////////// +// Function: EggPrimitive::joint_has_primitives +// Access: Published, Virtual +// Description: Returns true if there are any primitives +// (e.g. polygons) defined within this group or below, +// but the search does not include nested joints. +//////////////////////////////////////////////////////////////////// +bool EggPrimitive:: +joint_has_primitives() const { + return true; +} + //////////////////////////////////////////////////////////////////// // Function: EggPrimitive::erase diff --git a/panda/src/egg/eggPrimitive.h b/panda/src/egg/eggPrimitive.h index e338ed6410..6a569d714b 100644 --- a/panda/src/egg/eggPrimitive.h +++ b/panda/src/egg/eggPrimitive.h @@ -101,6 +101,7 @@ PUBLISHED: void remove_doubled_verts(bool closed); void remove_nonunique_verts(); virtual bool has_primitives() const; + virtual bool joint_has_primitives() const; // The EggPrimitive itself appears to be an STL container of diff --git a/panda/src/egg/eggTable.cxx b/panda/src/egg/eggTable.cxx index 0658494ca1..57d01ba5f0 100644 --- a/panda/src/egg/eggTable.cxx +++ b/panda/src/egg/eggTable.cxx @@ -18,11 +18,31 @@ #include "eggTable.h" -#include -#include +#include "string_utils.h" +#include "indent.h" TypeHandle EggTable::_type_handle; +//////////////////////////////////////////////////////////////////// +// Function: EggTable::has_transform +// Access: Public +// Description: Returns true if the table contains a transform +// description, false otherwise. +//////////////////////////////////////////////////////////////////// +bool EggTable:: +has_transform() const { + const_iterator ci; + + for (ci = begin(); ci != end(); ++ci) { + EggNode *child = (*ci); + if (child->is_anim_matrix()) { + return true; + } + } + + return false; +} + //////////////////////////////////////////////////////////////////// // Function: EggTable::write // Access: Public, Virtual @@ -70,6 +90,66 @@ string_table_type(const string &string) { } } +//////////////////////////////////////////////////////////////////// +// Function: EggTable::r_transform +// Access: Protected, Virtual +// Description: This is called from within the egg code by +// transform(). It applies a transformation matrix +// to the current node in some sensible way, then +// continues down the tree. +// +// The first matrix is the transformation to apply; the +// second is its inverse. The third parameter is the +// coordinate system we are changing to, or CS_default +// if we are not changing coordinate systems. +//////////////////////////////////////////////////////////////////// +void EggTable:: +r_transform(const LMatrix4d &mat, const LMatrix4d &inv, + CoordinateSystem to_cs) { + // We need to duplicate the logic in EggGroup: if we have a matrix + // transform witin this table, apply the transformation to it, but + // then apply only the scale/rotational part of the transformation + // to any children. + + // On the other hand, if we have no matrix transform within this + // table, pass the transformation through. + + // This logic is complicated by the fact that matrix transforms with + // a group are not stored within the table itself, but + // rather within a child named "xform". Fortunately, + // has_transform() abstracts out this detail for us. + + if (has_transform()) { + // At least one child of this table represents an animation matrix + // transform: that child gets the real matrix, while all other + // children get the truncated matrix. + + LMatrix4d mat1 = mat; + LMatrix4d inv1 = inv; + + // If we have a translation component, we should only apply + // it to the top matrix. All subsequent matrices get just the + // rotational component. + mat1.set_row(3, LVector3d(0.0, 0.0, 0.0)); + inv1.set_row(3, LVector3d(0.0, 0.0, 0.0)); + + iterator ci; + for (ci = begin(); ci != end(); ++ci) { + EggNode *child = (*ci); + if (child->is_anim_matrix()) { + child->r_transform(mat, inv, to_cs); + } else { + child->r_transform(mat1, inv1, to_cs); + } + } + + } else { + // No children of this table represent an animation matrix + // transform: all children get the real matrix. + EggGroupNode::r_transform(mat, inv, to_cs); + } +} + //////////////////////////////////////////////////////////////////// // Function: TableType output operator diff --git a/panda/src/egg/eggTable.h b/panda/src/egg/eggTable.h index 10e5edc4c2..b0a3096a30 100644 --- a/panda/src/egg/eggTable.h +++ b/panda/src/egg/eggTable.h @@ -47,10 +47,15 @@ PUBLISHED: INLINE void set_table_type(TableType type); INLINE TableType get_table_type() const; + bool has_transform() const; virtual void write(ostream &out, int indent_level) const; static TableType string_table_type(const string &string); +protected: + virtual void r_transform(const LMatrix4d &mat, const LMatrix4d &inv, + CoordinateSystem to_cs); + private: TableType _type; diff --git a/panda/src/egg/eggXfmAnimData.cxx b/panda/src/egg/eggXfmAnimData.cxx index 7aded58277..7bba935e9d 100644 --- a/panda/src/egg/eggXfmAnimData.cxx +++ b/panda/src/egg/eggXfmAnimData.cxx @@ -161,6 +161,17 @@ get_value(int row, LMatrix4d &mat) const { _coordsys); } +//////////////////////////////////////////////////////////////////// +// Function: EggXfmAnimData::is_anim_matrix +// Access: Public, Virtual +// Description: Returns true if this node represents a table of +// animation transformation data, false otherwise. +//////////////////////////////////////////////////////////////////// +bool EggXfmAnimData:: +is_anim_matrix() const { + return true; +} + //////////////////////////////////////////////////////////////////// // Function: EggXfmAnimData::write // Access: Public, Virtual diff --git a/panda/src/egg/eggXfmAnimData.h b/panda/src/egg/eggXfmAnimData.h index fd23b1c455..8dfb824794 100644 --- a/panda/src/egg/eggXfmAnimData.h +++ b/panda/src/egg/eggXfmAnimData.h @@ -61,6 +61,7 @@ PUBLISHED: void get_value(int row, LMatrix4d &mat) const; + virtual bool is_anim_matrix() const; virtual void write(ostream &out, int indent_level) const; protected: diff --git a/panda/src/egg/eggXfmSAnim.cxx b/panda/src/egg/eggXfmSAnim.cxx index cee60b99fb..2867588f41 100644 --- a/panda/src/egg/eggXfmSAnim.cxx +++ b/panda/src/egg/eggXfmSAnim.cxx @@ -150,6 +150,17 @@ normalize() { } } +//////////////////////////////////////////////////////////////////// +// Function: EggXfmSAnim::is_anim_matrix +// Access: Public, Virtual +// Description: Returns true if this node represents a table of +// animation transformation data, false otherwise. +//////////////////////////////////////////////////////////////////// +bool EggXfmSAnim:: +is_anim_matrix() const { + return true; +} + //////////////////////////////////////////////////////////////////// // Function: EggXfmSAnim::write // Access: Public, Virtual diff --git a/panda/src/egg/eggXfmSAnim.h b/panda/src/egg/eggXfmSAnim.h index 6485a9a2c6..f52dac2958 100644 --- a/panda/src/egg/eggXfmSAnim.h +++ b/panda/src/egg/eggXfmSAnim.h @@ -69,6 +69,7 @@ PUBLISHED: void add_component_data(const string &component_name, double value); void add_component_data(int component, double value); + virtual bool is_anim_matrix() const; virtual void write(ostream &out, int indent_level) const; static void compose_with_order(LMatrix4d &mat,