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 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.
<Translate> { x y z }
<RotX> { degrees }
@ -1097,12 +1100,7 @@ GROUPING ENTRIES
<RotZ> { degrees }
<Rotate> { degrees x y z }
<Scale> { x y z }
<Matrix3> {
00 01 02
10 11 12
20 21 22
}
<Scale> { s }
<Matrix4> {
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:
<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 } }

View File

@ -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 \

View File

@ -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

View File

@ -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 &copy) {
////////////////////////////////////////////////////////////////////
EggGroup &EggGroup::
operator = (const EggGroup &copy) {
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 {

View File

@ -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 <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:
typedef pmap<PT_EggVertex, double> 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;

View File

@ -16,10 +16,9 @@
//
////////////////////////////////////////////////////////////////////
#include <pandabase.h>
#include "pandabase.h"
#include "eggMiscFuncs.h"
#include <indent.h>
#include "indent.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) << "}\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 <lmatrix.h>
#include <typedef.h>
#include <string>
#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

View File

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

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 "eggTexture.cxx"
#include "eggTextureCollection.cxx"
#include "eggTransform3d.cxx"
#include "eggUtilities.cxx"
#include "eggVertex.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
// <Transform> 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));
}
;

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 (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;
}

View File

@ -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<PT_EggTexture, TextureDef> Textures;