store egg transforms componentwise

This commit is contained in:
David Rose 2002-06-21 19:01:57 +00:00
parent a85f958fdb
commit cc1a49c7e4
15 changed files with 684 additions and 203 deletions

View File

@ -1090,6 +1090,9 @@ GROUPING ENTRIES
The transform definition may be any sequence of zero or more of The transform definition may be any sequence of zero or more of
the following. Transformations are post multiplied in the order the following. Transformations are post multiplied in the order
they are encountered to produce a net transformation matrix. 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.
<Translate> { x y z } <Translate> { x y z }
<RotX> { degrees } <RotX> { degrees }
@ -1097,12 +1100,7 @@ GROUPING ENTRIES
<RotZ> { degrees } <RotZ> { degrees }
<Rotate> { degrees x y z } <Rotate> { degrees x y z }
<Scale> { x y z } <Scale> { x y z }
<Scale> { s }
<Matrix3> {
00 01 02
10 11 12
20 21 22
}
<Matrix4> { <Matrix4> {
00 01 02 03 00 01 02 03
@ -1111,6 +1109,20 @@ GROUPING ENTRIES
30 31 32 33 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:
<Translate> { x y }
<Rotate> { degrees }
<Scale> { x y }
<Scale> { s }
<Matrix3> {
00 01 02
10 11 12
20 21 22
}
<VertexRef> { indices <Ref> { pool-name } } <VertexRef> { indices <Ref> { pool-name } }

View File

@ -30,6 +30,7 @@
eggSAnimData.I eggSAnimData.h eggSurface.I eggSurface.h \ eggSAnimData.I eggSAnimData.h eggSurface.I eggSurface.h \
eggSwitchCondition.h eggTable.I eggTable.h eggTexture.I \ eggSwitchCondition.h eggTable.I eggTable.h eggTexture.I \
eggTexture.h eggTextureCollection.I eggTextureCollection.h \ eggTexture.h eggTextureCollection.I eggTextureCollection.h \
eggTransform3d.I eggTransform3d.h \
eggUtilities.I eggUtilities.h eggVertex.I eggVertex.h \ eggUtilities.I eggUtilities.h eggVertex.I eggVertex.h \
eggVertexPool.I eggVertexPool.h eggXfmAnimData.I \ eggVertexPool.I eggVertexPool.h eggXfmAnimData.I \
eggXfmAnimData.h eggXfmSAnim.I eggXfmSAnim.h parserDefs.h \ eggXfmAnimData.h eggXfmSAnim.I eggXfmSAnim.h parserDefs.h \
@ -50,6 +51,7 @@
eggPoolUniquifier.cxx eggPrimitive.cxx eggRenderMode.cxx \ eggPoolUniquifier.cxx eggPrimitive.cxx eggRenderMode.cxx \
eggSAnimData.cxx eggSurface.cxx eggSwitchCondition.cxx \ eggSAnimData.cxx eggSurface.cxx eggSwitchCondition.cxx \
eggTable.cxx eggTexture.cxx eggTextureCollection.cxx \ eggTable.cxx eggTexture.cxx eggTextureCollection.cxx \
eggTransform3d.cxx \
eggUtilities.cxx eggVertex.cxx eggVertexPool.cxx \ eggUtilities.cxx eggVertex.cxx eggVertexPool.cxx \
eggXfmAnimData.cxx eggXfmSAnim.cxx xx xx pt_EggMaterial.cxx \ eggXfmAnimData.cxx eggXfmSAnim.cxx xx xx pt_EggMaterial.cxx \
vector_PT_EggMaterial.cxx pt_EggTexture.cxx \ vector_PT_EggMaterial.cxx pt_EggTexture.cxx \
@ -74,6 +76,7 @@
eggSAnimData.I eggSAnimData.h eggSurface.I eggSurface.h \ eggSAnimData.I eggSAnimData.h eggSurface.I eggSurface.h \
eggSwitchCondition.h eggTable.I eggTable.h eggTexture.I \ eggSwitchCondition.h eggTable.I eggTable.h eggTexture.I \
eggTexture.h eggTextureCollection.I eggTextureCollection.h \ eggTexture.h eggTextureCollection.I eggTextureCollection.h \
eggTransform3d.I eggTransform3d.h \
eggUtilities.I eggUtilities.h eggVertex.I eggVertex.h \ eggUtilities.I eggUtilities.h eggVertex.I eggVertex.h \
eggVertexPool.I eggVertexPool.h eggXfmAnimData.I eggXfmAnimData.h \ eggVertexPool.I eggVertexPool.h eggXfmAnimData.I eggXfmAnimData.h \
eggXfmSAnim.I eggXfmSAnim.h \ eggXfmSAnim.I eggXfmSAnim.h \

View File

@ -281,41 +281,6 @@ get_switch_fps() const {
return _fps; 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 // Function: EggGroup::set_objecttype
// Access: Public // Access: Public

View File

@ -38,7 +38,6 @@ EggGroup::
EggGroup(const string &name) : EggGroupNode(name) { EggGroup(const string &name) : EggGroupNode(name) {
_flags = 0; _flags = 0;
_flags2 = 0; _flags2 = 0;
_transform = LMatrix4d::ident_mat();
_fps = 0.0; _fps = 0.0;
} }
@ -59,9 +58,9 @@ EggGroup(const EggGroup &copy) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
EggGroup &EggGroup:: EggGroup &EggGroup::
operator = (const EggGroup &copy) { operator = (const EggGroup &copy) {
EggTransform3d::operator = (copy);
_flags = copy._flags; _flags = copy._flags;
_flags2 = copy._flags2; _flags2 = copy._flags2;
_transform = copy._transform;
_objecttype = copy._objecttype; _objecttype = copy._objecttype;
_collision_name = copy._collision_name; _collision_name = copy._collision_name;
_fps = copy._fps; _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 // Function: EggGroup::write
// Access: Public, Virtual // Access: Public, Virtual
@ -250,7 +217,7 @@ write(ostream &out, int indent_level) const {
} }
if (has_transform()) { if (has_transform()) {
write_transform(out, _transform, indent_level + 2); EggTransform3d::write(out, indent_level + 2);
} }
if (has_objecttype()) { if (has_objecttype()) {
@ -767,7 +734,7 @@ adjust_under() {
void EggGroup:: void EggGroup::
r_transform(const LMatrix4d &mat, const LMatrix4d &inv, r_transform(const LMatrix4d &mat, const LMatrix4d &inv,
CoordinateSystem to_cs) { CoordinateSystem to_cs) {
if (has_transform()) { if (!transform_is_identity()) {
// Since we want to apply this transform to all matrices, // Since we want to apply this transform to all matrices,
// including nested matrices, we can't simply premult it in and // including nested matrices, we can't simply premult it in and
// leave it, because that would leave the rotational component in // 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)); mat1.set_row(3, LVector3d(0.0, 0.0, 0.0));
inv1.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); EggGroupNode::r_transform(mat1, inv1, to_cs);
} else { } else {

View File

@ -23,6 +23,7 @@
#include "eggGroupNode.h" #include "eggGroupNode.h"
#include "eggRenderMode.h" #include "eggRenderMode.h"
#include "eggTransform3d.h"
#include "eggVertex.h" #include "eggVertex.h"
#include "eggSwitchCondition.h" #include "eggSwitchCondition.h"
#include "pt_EggVertex.h" #include "pt_EggVertex.h"
@ -35,7 +36,7 @@
// Description : The main glue of the egg hierarchy, this corresponds // Description : The main glue of the egg hierarchy, this corresponds
// to the <Group>, <Instance>, and <Joint> type nodes. // to the <Group>, <Instance>, and <Joint> type nodes.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEGG EggGroup : public EggGroupNode, public EggRenderMode { class EXPCL_PANDAEGG EggGroup : public EggGroupNode, public EggRenderMode, public EggTransform3d {
public: public:
typedef pmap<PT_EggVertex, double> VertexRef; typedef pmap<PT_EggVertex, double> VertexRef;
@ -130,12 +131,6 @@ public:
INLINE void set_switch_fps(double fps); INLINE void set_switch_fps(double fps);
INLINE double get_switch_fps() const; 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 set_objecttype(const string &objecttype);
INLINE void clear_objecttype(); INLINE void clear_objecttype();
INLINE bool has_objecttype() const; INLINE bool has_objecttype() const;
@ -213,7 +208,6 @@ private:
F_dcs_flag = 0x00000010, F_dcs_flag = 0x00000010,
F_billboard_type = 0x000000e0, F_billboard_type = 0x000000e0,
F_switch_flag = 0x00000100, F_switch_flag = 0x00000100,
F_has_transform = 0x00000200,
F_model_flag = 0x00000400, F_model_flag = 0x00000400,
F_texlist_flag = 0x00000800, F_texlist_flag = 0x00000800,
F_nofog_flag = 0x00001000, F_nofog_flag = 0x00001000,
@ -231,7 +225,6 @@ private:
int _flags; int _flags;
int _flags2; int _flags2;
LMatrix4d _transform;
CollideMask _collide_mask, _from_collide_mask, _into_collide_mask; CollideMask _collide_mask, _from_collide_mask, _into_collide_mask;
LPoint3d _billboard_center; LPoint3d _billboard_center;
string _objecttype; string _objecttype;

View File

@ -16,10 +16,9 @@
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#include <pandabase.h> #include "pandabase.h"
#include "eggMiscFuncs.h" #include "eggMiscFuncs.h"
#include "indent.h"
#include <indent.h>
#include <ctype.h> #include <ctype.h>
@ -95,59 +94,3 @@ write_transform(ostream &out, const LMatrix3d &mat, int indent_level) {
indent(out, indent_level+2) << "}\n"; indent(out, indent_level+2) << "}\n";
indent(out, indent_level) << "}\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) << "<Transform> {\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) << "<Scale> { " << s << " }\n";
}
if (fabs(r[0]) > 0.0001) {
Indent(out, indent+2) << "<RotX> { " << r[0] << " }\n";
}
if (fabs(r[1]) > 0.0001) {
Indent(out, indent+2) << "<RotY> { " << r[1] << " }\n";
}
if (fabs(r[2]) > 0.0001) {
Indent(out, indent+2) << "<RotZ> { " << r[2] << " }\n";
}
if (!t.almostEqual(pfVec3(0.0, 0.0, 0.0), 0.0001)) {
Indent(out, indent+2) << "<Translate> { " << 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) << "<Matrix4> {\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";
}

View File

@ -29,16 +29,8 @@
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#include <pandabase.h> #include "pandabase.h"
#include "lmatrix.h"
#include <lmatrix.h>
#include <typedef.h>
#include <string>
#ifndef WIN32_VC
class ostream;
#endif
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -64,14 +56,6 @@ void
write_transform(ostream &out, const LMatrix3d &mat, int indent_level); 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" #include "eggMiscFuncs.I"
#endif #endif

View File

@ -19,11 +19,8 @@
#ifndef EGGRENDERMODE_H #ifndef EGGRENDERMODE_H
#define EGGRENDERMODE_H #define EGGRENDERMODE_H
#include <pandabase.h> #include "pandabase.h"
#include "typedObject.h"
#include <typedObject.h>
#include <string>
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -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 &copy) :
_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 &copy) {
_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;
}

View File

@ -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 &copy) :
_components(copy._components),
_transform(copy._transform)
{
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::Copy assignment operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggTransform3d &EggTransform3d::
operator = (const EggTransform3d &copy) {
_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) << "<Transform> {\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)
<< "<Translate> { " << get_component_vector(i) << " }\n";
break;
case CT_rotx:
indent(out, indent_level + 2)
<< "<RotX> { " << get_component_number(i) << " }\n";
break;
case CT_roty:
indent(out, indent_level + 2)
<< "<RotY> { " << get_component_number(i) << " }\n";
break;
case CT_rotz:
indent(out, indent_level + 2)
<< "<RotZ> { " << get_component_number(i) << " }\n";
break;
case CT_rotate:
indent(out, indent_level + 2)
<< "<Rotate> { " << get_component_number(i) << " "
<< get_component_vector(i) << " }\n";
break;
case CT_scale:
indent(out, indent_level + 2)
<< "<Scale> { " << get_component_vector(i) << " }\n";
break;
case CT_uniform_scale:
indent(out, indent_level + 2)
<< "<Scale> { " << get_component_number(i) << " }\n";
break;
case CT_matrix:
indent(out, indent_level + 2) << "<Matrix4> {\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";
}

View File

@ -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 <Transform> 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 &copy);
EggTransform3d &operator = (const EggTransform3d &copy);
~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 &copy);
INLINE void operator = (const Component &copy);
INLINE ~Component();
ComponentType _type;
double _number;
LVector3d *_vector;
LMatrix4d *_matrix;
};
typedef pvector<Component> Components;
Components _components;
LMatrix4d _transform;
};
#include "eggTransform3d.I"
#endif

View File

@ -13,6 +13,7 @@
#include "eggTable.cxx" #include "eggTable.cxx"
#include "eggTexture.cxx" #include "eggTexture.cxx"
#include "eggTextureCollection.cxx" #include "eggTextureCollection.cxx"
#include "eggTransform3d.cxx"
#include "eggUtilities.cxx" #include "eggUtilities.cxx"
#include "eggVertex.cxx" #include "eggVertex.cxx"
#include "eggVertexPool.cxx" #include "eggVertexPool.cxx"

View File

@ -77,7 +77,6 @@ static int vertex_index;
// We need to hold a matrix for a little bit while parsing the // We need to hold a matrix for a little bit while parsing the
// <Transform> entries. // <Transform> entries.
static LMatrix4d matrix_3d;
static LMatrix3d matrix_2d; static LMatrix3d matrix_2d;
@ -1049,12 +1048,9 @@ collide_flags:
transform_3d: transform_3d:
TRANSFORM TRANSFORM
{ {
matrix_3d = LMatrix4d::ident_mat(); DCAST(EggGroup, egg_stack.back())->clear_transform();
} }
'{' transform_3d_body '}' '{' transform_3d_body '}'
{
DCAST(EggGroup, egg_stack.back())->set_transform(matrix_3d);
}
; ;
@ -1067,49 +1063,52 @@ transform_3d:
*/ */
transform_3d_body: transform_3d_body:
empty empty
| transform_3d_body matrix3_3d
| transform_3d_body matrix4_3d
| transform_3d_body translate_3d | transform_3d_body translate_3d
| transform_3d_body rotx_3d | transform_3d_body rotx_3d
| transform_3d_body roty_3d | transform_3d_body roty_3d
| transform_3d_body rotz_3d | transform_3d_body rotz_3d
| transform_3d_body rotate_3d | transform_3d_body rotate_3d
| transform_3d_body scale_3d | transform_3d_body scale_3d
| transform_3d_body matrix4_3d
; ;
translate_3d: TRANSLATE '{' real real real '}' 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 '}' 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 '}' 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 '}' 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 '}' 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 '}' 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
real real real real real real real real
{ {
matrix_3d *= LMatrix4d($1, $2, $3, $4, DCAST(EggGroup, egg_stack.back())->add_matrix
(LMatrix4d($1, $2, $3, $4,
$5, $6, $7, $8, $5, $6, $7, $8,
$9, $10, $11, $12, $9, $10, $11, $12,
$13, $14, $15, $16); $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));
} }
; ;

View File

@ -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 the group had a transform, apply it to the arc.
if (egg_group->has_transform()) { if (egg_group->has_transform()) {
LMatrix4f matf = LCAST(float, egg_group->get_transform()); node->set_transform(make_transform(egg_group));
node->set_transform(TransformState::make_mat(matf));
} }
// If the group has a billboard flag, apply that. // 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); 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;
}

View File

@ -35,6 +35,7 @@
#include "lmatrix.h" #include "lmatrix.h"
#include "indirectCompareTo.h" #include "indirectCompareTo.h"
#include "textureAttrib.h" #include "textureAttrib.h"
#include "eggTransform3d.h"
class EggNode; class EggNode;
class EggBin; class EggBin;
@ -122,6 +123,8 @@ private:
void apply_deferred_nodes(PandaNode *node, const DeferredNodeProperty &prop); void apply_deferred_nodes(PandaNode *node, const DeferredNodeProperty &prop);
CPT(TransformState) make_transform(const EggTransform3d *egg_transform);
Builder _builder; Builder _builder;
typedef pmap<PT_EggTexture, TextureDef> Textures; typedef pmap<PT_EggTexture, TextureDef> Textures;