From cc1a49c7e44a676afa349f055cfe44f1e0ff964e Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 21 Jun 2002 19:01:57 +0000 Subject: [PATCH] store egg transforms componentwise --- panda/src/doc/eggSyntax.txt | 24 ++- panda/src/egg/Sources.pp | 3 + panda/src/egg/eggGroup.I | 35 ----- panda/src/egg/eggGroup.cxx | 41 +----- panda/src/egg/eggGroup.h | 11 +- panda/src/egg/eggMiscFuncs.cxx | 61 +------- panda/src/egg/eggMiscFuncs.h | 20 +-- panda/src/egg/eggRenderMode.h | 7 +- panda/src/egg/eggTransform3d.I | 205 ++++++++++++++++++++++++++ panda/src/egg/eggTransform3d.cxx | 242 +++++++++++++++++++++++++++++++ panda/src/egg/eggTransform3d.h | 97 +++++++++++++ panda/src/egg/egg_composite2.cxx | 1 + panda/src/egg/parser.yxx | 49 +++---- panda/src/egg2pg/eggLoader.cxx | 88 ++++++++++- panda/src/egg2pg/eggLoader.h | 3 + 15 files changed, 684 insertions(+), 203 deletions(-) create mode 100644 panda/src/egg/eggTransform3d.I create mode 100644 panda/src/egg/eggTransform3d.cxx create mode 100644 panda/src/egg/eggTransform3d.h diff --git a/panda/src/doc/eggSyntax.txt b/panda/src/doc/eggSyntax.txt index 79fdf923fa..0f2d2f4e47 100644 --- a/panda/src/doc/eggSyntax.txt +++ b/panda/src/doc/eggSyntax.txt @@ -1090,6 +1090,9 @@ GROUPING ENTRIES The transform definition may be any sequence of zero or more of the following. Transformations are post multiplied in the order they are encountered to produce a net transformation matrix. + Rotations are defined as a counterclockwise angle in degrees about + a particular axis, either implicit (x, y, or z axis), or + arbitrary. { x y z } { degrees } @@ -1097,12 +1100,7 @@ GROUPING ENTRIES { degrees } { degrees x y z } { x y z } - - { - 00 01 02 - 10 11 12 - 20 21 22 - } + { s } { 00 01 02 03 @@ -1111,6 +1109,20 @@ GROUPING ENTRIES 30 31 32 33 } + In the context of texture coordinates, the transform is defined in + 2-d space, and the allowable components correspondingly reflect + two-dimensional transforms: + + { x y } + { degrees } + { x y } + { s } + + { + 00 01 02 + 10 11 12 + 20 21 22 + } { indices { pool-name } } diff --git a/panda/src/egg/Sources.pp b/panda/src/egg/Sources.pp index ef46b11e41..47278809ef 100644 --- a/panda/src/egg/Sources.pp +++ b/panda/src/egg/Sources.pp @@ -30,6 +30,7 @@ eggSAnimData.I eggSAnimData.h eggSurface.I eggSurface.h \ eggSwitchCondition.h eggTable.I eggTable.h eggTexture.I \ eggTexture.h eggTextureCollection.I eggTextureCollection.h \ + eggTransform3d.I eggTransform3d.h \ eggUtilities.I eggUtilities.h eggVertex.I eggVertex.h \ eggVertexPool.I eggVertexPool.h eggXfmAnimData.I \ eggXfmAnimData.h eggXfmSAnim.I eggXfmSAnim.h parserDefs.h \ @@ -50,6 +51,7 @@ eggPoolUniquifier.cxx eggPrimitive.cxx eggRenderMode.cxx \ eggSAnimData.cxx eggSurface.cxx eggSwitchCondition.cxx \ eggTable.cxx eggTexture.cxx eggTextureCollection.cxx \ + eggTransform3d.cxx \ eggUtilities.cxx eggVertex.cxx eggVertexPool.cxx \ eggXfmAnimData.cxx eggXfmSAnim.cxx xx xx pt_EggMaterial.cxx \ vector_PT_EggMaterial.cxx pt_EggTexture.cxx \ @@ -74,6 +76,7 @@ eggSAnimData.I eggSAnimData.h eggSurface.I eggSurface.h \ eggSwitchCondition.h eggTable.I eggTable.h eggTexture.I \ eggTexture.h eggTextureCollection.I eggTextureCollection.h \ + eggTransform3d.I eggTransform3d.h \ eggUtilities.I eggUtilities.h eggVertex.I eggVertex.h \ eggVertexPool.I eggVertexPool.h eggXfmAnimData.I eggXfmAnimData.h \ eggXfmSAnim.I eggXfmSAnim.h \ diff --git a/panda/src/egg/eggGroup.I b/panda/src/egg/eggGroup.I index 572ef0bcdd..d64d8fd3f0 100644 --- a/panda/src/egg/eggGroup.I +++ b/panda/src/egg/eggGroup.I @@ -281,41 +281,6 @@ get_switch_fps() const { return _fps; } -//////////////////////////////////////////////////////////////////// -// Function: EggGroup::has_transform -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool EggGroup:: -has_transform() const { - return (_flags & F_has_transform) != 0; -} - -//////////////////////////////////////////////////////////////////// -// Function: EggGroup::get_transform -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE LMatrix4d EggGroup:: -get_transform() const { - nassertr(_flags & F_has_transform, _transform); - return _transform; -} - -//////////////////////////////////////////////////////////////////// -// Function: EggGroup::transform_is_identity() -// Access: Public -// Description: Returns true if no transform matrix has been -// specified, or if the one specified is the identity -// transform. Returns false only if a nonidentity -// transform has been applied. -//////////////////////////////////////////////////////////////////// -INLINE bool EggGroup:: -transform_is_identity() const { - return (!has_transform() || - _transform.almost_equal(LMatrix4d::ident_mat(), 0.0001)); -} - //////////////////////////////////////////////////////////////////// // Function: EggGroup::set_objecttype // Access: Public diff --git a/panda/src/egg/eggGroup.cxx b/panda/src/egg/eggGroup.cxx index 73b377ad9c..36e2a16266 100644 --- a/panda/src/egg/eggGroup.cxx +++ b/panda/src/egg/eggGroup.cxx @@ -38,7 +38,6 @@ EggGroup:: EggGroup(const string &name) : EggGroupNode(name) { _flags = 0; _flags2 = 0; - _transform = LMatrix4d::ident_mat(); _fps = 0.0; } @@ -59,9 +58,9 @@ EggGroup(const EggGroup ©) { //////////////////////////////////////////////////////////////////// EggGroup &EggGroup:: operator = (const EggGroup ©) { + EggTransform3d::operator = (copy); _flags = copy._flags; _flags2 = copy._flags2; - _transform = copy._transform; _objecttype = copy._objecttype; _collision_name = copy._collision_name; _fps = copy._fps; @@ -120,38 +119,6 @@ set_group_type(GroupType type) { } } -//////////////////////////////////////////////////////////////////// -// Function: EggGroup::set_transform -// Access: Public -// Description: Sets the indicated transformation matrix on the node. -//////////////////////////////////////////////////////////////////// -void EggGroup:: -set_transform(const LMatrix4d &transform) { - _transform = transform; - if (!has_transform()) { - _flags |= F_has_transform; - - // Now we have to update the under_flags. - update_under(0); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: EggGroup::clear_transform -// Access: Public -// Description: Removes any transformation matrix from the node. -//////////////////////////////////////////////////////////////////// -void EggGroup:: -clear_transform() { - _transform = LMatrix4d::ident_mat(); - if (has_transform()) { - _flags &= ~F_has_transform; - - // Now we have to update the under_flags. - update_under(0); - } -} - //////////////////////////////////////////////////////////////////// // Function: EggGroup::write // Access: Public, Virtual @@ -250,7 +217,7 @@ write(ostream &out, int indent_level) const { } if (has_transform()) { - write_transform(out, _transform, indent_level + 2); + EggTransform3d::write(out, indent_level + 2); } if (has_objecttype()) { @@ -767,7 +734,7 @@ adjust_under() { void EggGroup:: r_transform(const LMatrix4d &mat, const LMatrix4d &inv, CoordinateSystem to_cs) { - if (has_transform()) { + if (!transform_is_identity()) { // 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 @@ -785,7 +752,7 @@ r_transform(const LMatrix4d &mat, const LMatrix4d &inv, mat1.set_row(3, LVector3d(0.0, 0.0, 0.0)); inv1.set_row(3, LVector3d(0.0, 0.0, 0.0)); - _transform = inv1 * _transform * mat; + set_transform(inv1 * get_transform() * mat); EggGroupNode::r_transform(mat1, inv1, to_cs); } else { diff --git a/panda/src/egg/eggGroup.h b/panda/src/egg/eggGroup.h index 899217ed49..ddb1194eaf 100644 --- a/panda/src/egg/eggGroup.h +++ b/panda/src/egg/eggGroup.h @@ -23,6 +23,7 @@ #include "eggGroupNode.h" #include "eggRenderMode.h" +#include "eggTransform3d.h" #include "eggVertex.h" #include "eggSwitchCondition.h" #include "pt_EggVertex.h" @@ -35,7 +36,7 @@ // Description : The main glue of the egg hierarchy, this corresponds // to the , , and type nodes. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDAEGG EggGroup : public EggGroupNode, public EggRenderMode { +class EXPCL_PANDAEGG EggGroup : public EggGroupNode, public EggRenderMode, public EggTransform3d { public: typedef pmap VertexRef; @@ -130,12 +131,6 @@ public: INLINE void set_switch_fps(double fps); INLINE double get_switch_fps() const; - void set_transform(const LMatrix4d &transform); - void clear_transform(); - INLINE bool has_transform() const; - INLINE LMatrix4d get_transform() const; - INLINE bool transform_is_identity() const; - INLINE void set_objecttype(const string &objecttype); INLINE void clear_objecttype(); INLINE bool has_objecttype() const; @@ -213,7 +208,6 @@ private: F_dcs_flag = 0x00000010, F_billboard_type = 0x000000e0, F_switch_flag = 0x00000100, - F_has_transform = 0x00000200, F_model_flag = 0x00000400, F_texlist_flag = 0x00000800, F_nofog_flag = 0x00001000, @@ -231,7 +225,6 @@ private: int _flags; int _flags2; - LMatrix4d _transform; CollideMask _collide_mask, _from_collide_mask, _into_collide_mask; LPoint3d _billboard_center; string _objecttype; diff --git a/panda/src/egg/eggMiscFuncs.cxx b/panda/src/egg/eggMiscFuncs.cxx index f8e8a3ccb4..b6fc98edbf 100644 --- a/panda/src/egg/eggMiscFuncs.cxx +++ b/panda/src/egg/eggMiscFuncs.cxx @@ -16,10 +16,9 @@ // //////////////////////////////////////////////////////////////////// -#include +#include "pandabase.h" #include "eggMiscFuncs.h" - -#include +#include "indent.h" #include @@ -95,59 +94,3 @@ write_transform(ostream &out, const LMatrix3d &mat, int indent_level) { indent(out, indent_level+2) << "}\n"; indent(out, indent_level) << "}\n"; } - -//////////////////////////////////////////////////////////////////// -// Function: write_transform -// Description: A helper function to write out a 4x4 transform -// matrix. -//////////////////////////////////////////////////////////////////// -void -write_transform(ostream &out, const LMatrix4d &mat, int indent_level) { - indent(out, indent_level) << " {\n"; - - bool written = false; - - /* - int mat_type = mat.getMatType(); - if ((mat_type & - ~(PFMAT_TRANS | PFMAT_ROT | PFMAT_SCALE | PFMAT_NONORTHO))==0) { - // Write out the matrix componentwise if possible. - pfVec3 s, r, t; - if (ExtractMatrix(mat, s, r, t)) { - if (!s.almostEqual(pfVec3(1.0, 1.0, 1.0), 0.0001)) { - Indent(out, indent+2) << " { " << s << " }\n"; - } - if (fabs(r[0]) > 0.0001) { - Indent(out, indent+2) << " { " << r[0] << " }\n"; - } - if (fabs(r[1]) > 0.0001) { - Indent(out, indent+2) << " { " << r[1] << " }\n"; - } - if (fabs(r[2]) > 0.0001) { - Indent(out, indent+2) << " { " << r[2] << " }\n"; - } - if (!t.almostEqual(pfVec3(0.0, 0.0, 0.0), 0.0001)) { - Indent(out, indent+2) << " { " << t << " }\n"; - } - written = true; - } - } - */ - - if (!written) { - // It's some non-affine matrix, or it has a shear; write out the - // general 4x4. - indent(out, indent_level+2) << " {\n"; - - for (int r = 0; r < 4; r++) { - indent(out, indent_level+3); - for (int c = 0; c < 4; c++) { - out << " " << mat(r, c); - } - out << "\n"; - } - indent(out, indent_level+2) << "}\n"; - } - - indent(out, indent_level) << "}\n"; -} diff --git a/panda/src/egg/eggMiscFuncs.h b/panda/src/egg/eggMiscFuncs.h index 918cd958a2..d3c9b44235 100644 --- a/panda/src/egg/eggMiscFuncs.h +++ b/panda/src/egg/eggMiscFuncs.h @@ -29,16 +29,8 @@ // //////////////////////////////////////////////////////////////////// -#include - -#include -#include - -#include - -#ifndef WIN32_VC -class ostream; -#endif +#include "pandabase.h" +#include "lmatrix.h" //////////////////////////////////////////////////////////////////// @@ -64,14 +56,6 @@ void write_transform(ostream &out, const LMatrix3d &mat, int indent_level); -//////////////////////////////////////////////////////////////////// -// Function: write_transform -// Description: A helper function to write out a 4x4 transform -// matrix. -//////////////////////////////////////////////////////////////////// -void -write_transform(ostream &out, const LMatrix4d &mat, int indent_level); - #include "eggMiscFuncs.I" #endif diff --git a/panda/src/egg/eggRenderMode.h b/panda/src/egg/eggRenderMode.h index f4433f27bf..678785db3a 100644 --- a/panda/src/egg/eggRenderMode.h +++ b/panda/src/egg/eggRenderMode.h @@ -19,11 +19,8 @@ #ifndef EGGRENDERMODE_H #define EGGRENDERMODE_H -#include - -#include - -#include +#include "pandabase.h" +#include "typedObject.h" //////////////////////////////////////////////////////////////////// diff --git a/panda/src/egg/eggTransform3d.I b/panda/src/egg/eggTransform3d.I new file mode 100644 index 0000000000..509a282353 --- /dev/null +++ b/panda/src/egg/eggTransform3d.I @@ -0,0 +1,205 @@ +// Filename: eggTransform3d.I +// Created by: drose (21Jun02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::Component::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE EggTransform3d::Component:: +Component(EggTransform3d::ComponentType type, double number) : + _type(type), + _number(number) +{ + _vector = (LVector3d *)NULL; + _matrix = (LMatrix4d *)NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::Component::Copy Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE EggTransform3d::Component:: +Component(const EggTransform3d::Component ©) : + _type(copy._type), + _number(copy._number) +{ + _vector = (LVector3d *)NULL; + _matrix = (LMatrix4d *)NULL; + if (copy._vector != (LVector3d *)NULL) { + _vector = new LVector3d(*copy._vector); + } + if (copy._matrix != (LMatrix4d *)NULL) { + _matrix = new LMatrix4d(*copy._matrix); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::Component::Copy Assignment Operator +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void EggTransform3d::Component:: +operator = (const EggTransform3d::Component ©) { + _type = copy._type; + _number = copy._number; + if (_vector != (LVector3d *)NULL) { + delete _vector; + _vector = (LVector3d *)NULL; + } + if (_matrix != (LMatrix4d *)NULL) { + delete _matrix; + _matrix = (LMatrix4d *)NULL; + } + if (copy._vector != (LVector3d *)NULL) { + _vector = new LVector3d(*copy._vector); + } + if (copy._matrix != (LMatrix4d *)NULL) { + _matrix = new LMatrix4d(*copy._matrix); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::Component::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE EggTransform3d::Component:: +~Component() { + if (_vector != (LVector3d *)NULL) { + delete _vector; + } + if (_matrix != (LMatrix4d *)NULL) { + delete _matrix; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::has_transform +// Access: Public +// Description: Returns true if the transform is nonempty, false if +// it is empty (no transform components have been +// added). +//////////////////////////////////////////////////////////////////// +INLINE bool EggTransform3d:: +has_transform() const { + return !_components.empty(); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::set_transform +// Access: Public +// Description: Sets the overall transform as a 4x4 matrix. This +// completely replaces whatever componentwise transform +// may have been defined. +//////////////////////////////////////////////////////////////////// +INLINE void EggTransform3d:: +set_transform(const LMatrix4d &mat) { + clear_transform(); + add_matrix(mat); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::get_transform +// Access: Public +// Description: Returns the overall transform as a 4x4 matrix. +//////////////////////////////////////////////////////////////////// +INLINE const LMatrix4d &EggTransform3d:: +get_transform() const { + return _transform; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::transform_is_identity +// Access: Public +// Description: Returns true if the described transform is identity, +// false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool EggTransform3d:: +transform_is_identity() const { + return _components.empty() || + _transform.almost_equal(LMatrix4d::ident_mat(), 0.0001); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::get_num_components +// Access: Public +// Description: Returns the number of components that make up the +// transform. +//////////////////////////////////////////////////////////////////// +INLINE int EggTransform3d:: +get_num_components() const { + return _components.size(); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::get_component_type +// Access: Public +// Description: Returns the type of the nth component. +//////////////////////////////////////////////////////////////////// +INLINE EggTransform3d::ComponentType EggTransform3d:: +get_component_type(int n) const { + nassertr(n >= 0 && n < (int)_components.size(), CT_invalid); + return _components[n]._type; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::get_component_number +// Access: Public +// Description: Returns the solitary number associated with the nth +// component. In the case of a rotation, this is the +// angle in degrees to rotate; in the case of uniform +// scale, this is the amount of the scale. Other types +// do not use this property. +//////////////////////////////////////////////////////////////////// +INLINE double EggTransform3d:: +get_component_number(int n) const { + nassertr(n >= 0 && n < (int)_components.size(), 0.0); + return _components[n]._number; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::get_component_vector +// Access: Public +// Description: Returns the 3-component vector associated with the +// nth component. This may be the translate vector, +// rotate axis, or non-uniform scale. It is an error to +// call this if the component type does not use a vector +// property. +//////////////////////////////////////////////////////////////////// +INLINE const LVector3d &EggTransform3d:: +get_component_vector(int n) const { + nassertr(n >= 0 && n < (int)_components.size(), LVector3d::zero()); + nassertr(_components[n]._vector != (LVector3d *)NULL, LVector3d::zero()); + return *_components[n]._vector; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::get_component_matrix +// Access: Public +// Description: Returns the 4x4 matrix associated with the nth +// component. It is an error to call this if the +// component type is not CT_matrix. +//////////////////////////////////////////////////////////////////// +INLINE const LMatrix4d &EggTransform3d:: +get_component_matrix(int n) const { + nassertr(n >= 0 && n < (int)_components.size(), LMatrix4d::ident_mat()); + nassertr(_components[n]._matrix != (LMatrix4d *)NULL, LMatrix4d::ident_mat()); + return *_components[n]._matrix; +} diff --git a/panda/src/egg/eggTransform3d.cxx b/panda/src/egg/eggTransform3d.cxx new file mode 100644 index 0000000000..45f5c523c1 --- /dev/null +++ b/panda/src/egg/eggTransform3d.cxx @@ -0,0 +1,242 @@ +// Filename: eggTransform3d.cxx +// Created by: drose (21Jun02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "eggTransform3d.h" + + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +EggTransform3d:: +EggTransform3d() : + _transform(LMatrix4d::ident_mat()) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::Copy Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +EggTransform3d:: +EggTransform3d(const EggTransform3d ©) : + _components(copy._components), + _transform(copy._transform) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::Copy assignment operator +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +EggTransform3d &EggTransform3d:: +operator = (const EggTransform3d ©) { + _components = copy._components; + _transform = copy._transform; + return *this; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +EggTransform3d:: +~EggTransform3d() { +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::clear_transform +// Access: Public +// Description: Resets the transform to empty, identity. +//////////////////////////////////////////////////////////////////// +void EggTransform3d:: +clear_transform() { + _components.clear(); + _transform = LMatrix4d::ident_mat(); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::add_translate +// Access: Public +// Description: Appends a translation operation to the current +// transform. +//////////////////////////////////////////////////////////////////// +void EggTransform3d:: +add_translate(const LVector3d &translate) { + _components.push_back(Component(CT_translate)); + _components.back()._vector = new LVector3d(translate); + _transform *= LMatrix4d::translate_mat(translate); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::add_rotx +// Access: Public +// Description: Appends a rotation about the X axis to the current +// transform. The rotation angle is specified in +// degrees counterclockwise about the axis. +//////////////////////////////////////////////////////////////////// +void EggTransform3d:: +add_rotx(double angle) { + _components.push_back(Component(CT_rotx, angle)); + _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(1.0, 0.0, 0.0)); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::add_roty +// Access: Public +// Description: Appends a rotation about the Y axis to the current +// transform. The rotation angle is specified in +// degrees counterclockwise about the axis. +//////////////////////////////////////////////////////////////////// +void EggTransform3d:: +add_roty(double angle) { + _components.push_back(Component(CT_roty, angle)); + _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 1.0, 0.0)); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::add_rotz +// Access: Public +// Description: Appends a rotation about the Z axis to the current +// transform. The rotation angle is specified in +// degrees counterclockwise about the axis. +//////////////////////////////////////////////////////////////////// +void EggTransform3d:: +add_rotz(double angle) { + _components.push_back(Component(CT_rotz, angle)); + _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 0.0, 1.0)); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::add_rotate +// Access: Public +// Description: Appends a rotation about an arbitrary axis to the +// current transform. The rotation angle is specified +// in degrees counterclockwise about the axis. +//////////////////////////////////////////////////////////////////// +void EggTransform3d:: +add_rotate(double angle, const LVector3d &axis) { + _components.push_back(Component(CT_rotate, angle)); + _components.back()._vector = new LVector3d(axis); + _transform *= LMatrix4d::rotate_mat(angle, axis); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::add_scale +// Access: Public +// Description: Appends a possibly non-uniform scale to the current +// transform. +//////////////////////////////////////////////////////////////////// +void EggTransform3d:: +add_scale(const LVecBase3d &scale) { + _components.push_back(Component(CT_scale)); + _components.back()._vector = new LVector3d(scale); + _transform *= LMatrix4d::scale_mat(scale); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::add_uniform_scale +// Access: Public +// Description: Appends a uniform scale to the current transform. +//////////////////////////////////////////////////////////////////// +void EggTransform3d:: +add_uniform_scale(double scale) { + _components.push_back(Component(CT_uniform_scale, scale)); + _transform *= LMatrix4d::scale_mat(scale); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::add_matrix +// Access: Public +// Description: Appends an arbitrary 4x4 matrix to the current +// transform. +//////////////////////////////////////////////////////////////////// +void EggTransform3d:: +add_matrix(const LMatrix4d &mat) { + _components.push_back(Component(CT_matrix)); + _components.back()._matrix = new LMatrix4d(mat); + _transform *= mat; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTransform3d::write +// Access: Public +// Description: Writes the transform to the indicated stream in Egg +// format. +//////////////////////////////////////////////////////////////////// +void EggTransform3d:: +write(ostream &out, int indent_level) const { + indent(out, indent_level) << " {\n"; + + int num_components = get_num_components(); + for (int i = 0; i < num_components; i++) { + switch (get_component_type(i)) { + case CT_translate: + indent(out, indent_level + 2) + << " { " << get_component_vector(i) << " }\n"; + break; + + case CT_rotx: + indent(out, indent_level + 2) + << " { " << get_component_number(i) << " }\n"; + break; + + case CT_roty: + indent(out, indent_level + 2) + << " { " << get_component_number(i) << " }\n"; + break; + + case CT_rotz: + indent(out, indent_level + 2) + << " { " << get_component_number(i) << " }\n"; + break; + + case CT_rotate: + indent(out, indent_level + 2) + << " { " << get_component_number(i) << " " + << get_component_vector(i) << " }\n"; + break; + + case CT_scale: + indent(out, indent_level + 2) + << " { " << get_component_vector(i) << " }\n"; + break; + + case CT_uniform_scale: + indent(out, indent_level + 2) + << " { " << get_component_number(i) << " }\n"; + break; + + case CT_matrix: + indent(out, indent_level + 2) << " {\n"; + get_component_matrix(i).write(out, indent_level + 4); + indent(out, indent_level + 2) << "}\n"; + break; + + case CT_invalid: + nassertv(false); + break; + } + } + + indent(out, indent_level) << "}\n"; +} diff --git a/panda/src/egg/eggTransform3d.h b/panda/src/egg/eggTransform3d.h new file mode 100644 index 0000000000..58e763eaeb --- /dev/null +++ b/panda/src/egg/eggTransform3d.h @@ -0,0 +1,97 @@ +// Filename: eggTransform3d.h +// Created by: drose (21Jun02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 EGGTRANSFORM3D_H +#define EGGTRANSFORM3D_H + +#include "pandabase.h" +#include "luse.h" + +//////////////////////////////////////////////////////////////////// +// Class : EggTransform3d +// Description : This represents the entry of a group +// node: a list of component transform operations, +// applied in order, that describe a net transform +// matrix. This is a 3-d transform, and therefore +// computes a 4x4 matrix. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAEGG EggTransform3d { +public: + EggTransform3d(); + EggTransform3d(const EggTransform3d ©); + EggTransform3d &operator = (const EggTransform3d ©); + ~EggTransform3d(); + + void clear_transform(); + + void add_translate(const LVector3d &translate); + void add_rotx(double angle); + void add_roty(double angle); + void add_rotz(double angle); + void add_rotate(double angle, const LVector3d &axis); + void add_scale(const LVecBase3d &scale); + void add_uniform_scale(double scale); + void add_matrix(const LMatrix4d &mat); + + INLINE bool has_transform() const; + INLINE void set_transform(const LMatrix4d &mat); + INLINE const LMatrix4d &get_transform() const; + INLINE bool transform_is_identity() const; + + enum ComponentType { + CT_invalid, + CT_translate, + CT_rotx, + CT_roty, + CT_rotz, + CT_rotate, + CT_scale, + CT_uniform_scale, + CT_matrix + }; + + INLINE int get_num_components() const; + INLINE ComponentType get_component_type(int n) const; + INLINE double get_component_number(int n) const; + INLINE const LVector3d &get_component_vector(int n) const; + INLINE const LMatrix4d &get_component_matrix(int n) const; + + void write(ostream &out, int indent_level) const; + +private: + class Component { + public: + INLINE Component(ComponentType type, double number = 0.0); + INLINE Component(const Component ©); + INLINE void operator = (const Component ©); + INLINE ~Component(); + + ComponentType _type; + double _number; + LVector3d *_vector; + LMatrix4d *_matrix; + }; + + typedef pvector Components; + Components _components; + LMatrix4d _transform; +}; + +#include "eggTransform3d.I" + +#endif diff --git a/panda/src/egg/egg_composite2.cxx b/panda/src/egg/egg_composite2.cxx index 57285a8682..a2a4fe06c5 100644 --- a/panda/src/egg/egg_composite2.cxx +++ b/panda/src/egg/egg_composite2.cxx @@ -13,6 +13,7 @@ #include "eggTable.cxx" #include "eggTexture.cxx" #include "eggTextureCollection.cxx" +#include "eggTransform3d.cxx" #include "eggUtilities.cxx" #include "eggVertex.cxx" #include "eggVertexPool.cxx" diff --git a/panda/src/egg/parser.yxx b/panda/src/egg/parser.yxx index 471d44f235..da72613738 100644 --- a/panda/src/egg/parser.yxx +++ b/panda/src/egg/parser.yxx @@ -77,7 +77,6 @@ static int vertex_index; // We need to hold a matrix for a little bit while parsing the // entries. -static LMatrix4d matrix_3d; static LMatrix3d matrix_2d; @@ -1049,12 +1048,9 @@ collide_flags: transform_3d: TRANSFORM { - matrix_3d = LMatrix4d::ident_mat(); + DCAST(EggGroup, egg_stack.back())->clear_transform(); } '{' transform_3d_body '}' -{ - DCAST(EggGroup, egg_stack.back())->set_transform(matrix_3d); -} ; @@ -1067,49 +1063,52 @@ transform_3d: */ transform_3d_body: empty - | transform_3d_body matrix3_3d - | transform_3d_body matrix4_3d | transform_3d_body translate_3d | transform_3d_body rotx_3d | transform_3d_body roty_3d | transform_3d_body rotz_3d | transform_3d_body rotate_3d | transform_3d_body scale_3d + | transform_3d_body matrix4_3d ; translate_3d: TRANSLATE '{' real real real '}' { - matrix_3d *= LMatrix4d::translate_mat($3, $4, $5); + DCAST(EggGroup, egg_stack.back())->add_translate(LVector3d($3, $4, $5)); } ; rotx_3d: ROTX '{' real '}' { - matrix_3d *= LMatrix4d::rotate_mat_normaxis($3, LVector3d(1.0, 0.0, 0.0)); + DCAST(EggGroup, egg_stack.back())->add_rotx($3); } ; roty_3d: ROTY '{' real '}' { - matrix_3d *= LMatrix4d::rotate_mat_normaxis($3, LVector3d(0.0, 1.0, 0.0)); + DCAST(EggGroup, egg_stack.back())->add_roty($3); } ; rotz_3d: ROTZ '{' real '}' { - matrix_3d *= LMatrix4d::rotate_mat_normaxis($3, LVector3d(0.0, 0.0, 1.0)); + DCAST(EggGroup, egg_stack.back())->add_rotz($3); } ; rotate_3d: ROTATE '{' real real real real '}' { - matrix_3d *= LMatrix4d::rotate_mat($3, LVector3d($4, $5, $6)); + DCAST(EggGroup, egg_stack.back())->add_rotate($3, LVector3d($4, $5, $6)); } ; scale_3d: SCALE '{' real real real '}' { - matrix_3d *= LMatrix4d::scale_mat($3, $4, $5); + DCAST(EggGroup, egg_stack.back())->add_scale(LVecBase3d($3, $4, $5)); +} + | SCALE '{' real '}' +{ + DCAST(EggGroup, egg_stack.back())->add_uniform_scale($3); } ; @@ -1124,25 +1123,11 @@ matrix4_3d_body: real real real real real real real real { - matrix_3d *= LMatrix4d($1, $2, $3, $4, - $5, $6, $7, $8, - $9, $10, $11, $12, - $13, $14, $15, $16); -} - ; - -matrix3_3d: MATRIX3 '{' matrix3_3d_body '}' - ; - -matrix3_3d_body: - empty - | real real real - real real real - real real real -{ - matrix_3d *= LMatrix4d(LMatrix3d($1, $2, $3, - $4, $5, $6, - $7, $8, $9)); + DCAST(EggGroup, egg_stack.back())->add_matrix + (LMatrix4d($1, $2, $3, $4, + $5, $6, $7, $8, + $9, $10, $11, $12, + $13, $14, $15, $16)); } ; diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index 38b4968ce2..588fea839c 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -1431,8 +1431,7 @@ create_group_arc(EggGroup *egg_group, PandaNode *parent, PandaNode *node) { // If the group had a transform, apply it to the arc. if (egg_group->has_transform()) { - LMatrix4f matf = LCAST(float, egg_group->get_transform()); - node->set_transform(TransformState::make_mat(matf)); + node->set_transform(make_transform(egg_group)); } // If the group has a billboard flag, apply that. @@ -1924,3 +1923,88 @@ apply_deferred_nodes(PandaNode *node, const DeferredNodeProperty &prop) { apply_deferred_nodes(node->get_child(i), next_prop); } } + +//////////////////////////////////////////////////////////////////// +// Function: EggLoader::make_transform +// Access: Private +// Description: Walks back over the tree and applies the +// DeferredNodeProperties that were saved up along the +// way. +//////////////////////////////////////////////////////////////////// +CPT(TransformState) EggLoader:: +make_transform(const EggTransform3d *egg_transform) { + // We'll build up the transform componentwise, so we preserve any + // componentwise properties of the egg transform. + + CPT(TransformState) ts = TransformState::make_identity(); + int num_components = egg_transform->get_num_components(); + for (int i = 0; i < num_components; i++) { + switch (egg_transform->get_component_type(i)) { + case EggTransform3d::CT_translate: + { + LVector3f trans(LCAST(float, egg_transform->get_component_vector(i))); + ts = TransformState::make_pos(trans)->compose(ts); + } + break; + + case EggTransform3d::CT_rotx: + { + LRotationf rot(LVector3f(1.0f, 0.0f, 0.0f), + (float)egg_transform->get_component_number(i)); + ts = TransformState::make_quat(rot)->compose(ts); + } + break; + + case EggTransform3d::CT_roty: + { + LRotationf rot(LVector3f(0.0f, 1.0f, 0.0f), + (float)egg_transform->get_component_number(i)); + ts = TransformState::make_quat(rot)->compose(ts); + } + break; + + case EggTransform3d::CT_rotz: + { + LRotationf rot(LVector3f(0.0f, 0.0f, 1.0f), + (float)egg_transform->get_component_number(i)); + ts = TransformState::make_quat(rot)->compose(ts); + } + break; + + case EggTransform3d::CT_rotate: + { + LRotationf rot(LCAST(float, egg_transform->get_component_vector(i)), + (float)egg_transform->get_component_number(i)); + ts = TransformState::make_quat(rot)->compose(ts); + } + break; + + case EggTransform3d::CT_scale: + { + LVecBase3f scale(LCAST(float, egg_transform->get_component_vector(i))); + ts = TransformState::make_scale(scale)->compose(ts); + } + break; + + case EggTransform3d::CT_uniform_scale: + { + float scale = (float)egg_transform->get_component_number(i); + ts = TransformState::make_scale(scale)->compose(ts); + } + break; + + case EggTransform3d::CT_matrix: + { + LMatrix4f mat(LCAST(float, egg_transform->get_component_matrix(i))); + ts = TransformState::make_mat(mat)->compose(ts); + } + break; + + case EggTransform3d::CT_invalid: + nassertr(false, ts); + break; + } + } + + return ts; +} diff --git a/panda/src/egg2pg/eggLoader.h b/panda/src/egg2pg/eggLoader.h index 6abb5b7242..66d7742efb 100644 --- a/panda/src/egg2pg/eggLoader.h +++ b/panda/src/egg2pg/eggLoader.h @@ -35,6 +35,7 @@ #include "lmatrix.h" #include "indirectCompareTo.h" #include "textureAttrib.h" +#include "eggTransform3d.h" class EggNode; class EggBin; @@ -122,6 +123,8 @@ private: void apply_deferred_nodes(PandaNode *node, const DeferredNodeProperty &prop); + CPT(TransformState) make_transform(const EggTransform3d *egg_transform); + Builder _builder; typedef pmap Textures;