add 3-d texture coordinates to egg syntax

This commit is contained in:
David Rose 2005-07-20 21:54:24 +00:00
parent 47ca9df31c
commit ae4051cef8
45 changed files with 5712 additions and 5178 deletions

View File

@ -372,36 +372,49 @@ appear before they are referenced.
<Transform> { transform-definition }
This specifies a 2-d transformation that is applied to the UV's of
a surface to generate the texture coordinates.
This specifies a 2-d or 3-d transformation that is applied to the
UV's of a surface to generate the texture coordinates.
The transform syntax is similar to that for groups, except it
defines a 2-d 3x3 matrix. The 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 counterclockwise about the
origin in degrees. Matrices, when specified explicitly, are
row-major.
The transform syntax is similar to that for groups, except it may
define either a 2-d 3x3 matrix or a 3-d 4x4 matrix. (You should
use the two-dimensional forms if the UV's are two-dimensional, and
the three-dimensional forms if the UV's are three-dimensional.)
<Translate> { x y }
<Rotate> { degrees }
<Scale> { x y }
<Scale> { s }
A two-dimensional transform 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 counterclockwise about the origin in degrees.
Matrices, when specified explicitly, are row-major.
<Matrix3> {
00 01 02
10 11 12
20 21 22
}
<Translate> { x y }
<Rotate> { degrees }
<Scale> { x y }
<Scale> { s }
The transform definition might also include the following scalar:
<Matrix3> {
00 01 02
10 11 12
20 21 22
}
<Scalar> animated { 1 }
A three-dimensional transform may be any sequence of zero or more
of the following. See the description under <Group>, below, for
more information.
If this is set, it indicates the matrix may be animated by a
matrix channel, like a joint. At present, this flag is not used;
eventually, it may be used to define an arbitrary texture
coordinate animation.
<Translate> { x y z }
<RotX> { degrees }
<RotY> { degrees }
<RotZ> { degrees }
<Rotate> { degrees x y z }
<Scale> { x y z }
<Scale> { s }
<Matrix4> {
00 01 02 03
10 11 12 13
20 21 22 23
30 31 32 33
}
<Material> name { [scalars] }
@ -525,11 +538,18 @@ appear before they are referenced.
(1 1 1 1). The morph-list is an optional list of <DRGBA> entries.
<UV> [name] { u v [tangent] [binormal] [morph-list] }
<UV> [name] { u v [w] [tangent] [binormal] [morph-list] }
This gives the texture coordinates of the vertex. This must be
specified if a texture is to be mapped onto this geometry. As
before, morph-list is an optional list of <DUV> entries.
specified if a texture is to be mapped onto this geometry.
The texture coordinates are usually two-dimensional, with two
component values (u v), but they may also be three-dimensional,
with three component values (u v w). (Arguably, it should be
called <UVW> instead of <UV> in the three-dimensional case, but
it's not.)
As before, morph-list is an optional list of <DUV> entries.
Unlike the other kinds of attributes, there may be multiple sets
of UV's on each vertex, each with a unique name; this provides
@ -544,7 +564,7 @@ appear before they are referenced.
different UV coordinate set. If present, they have the expected
syntax:
<UV> [name] { u v <Tangent> { x y z } <Binormal> { x y z } }
<UV> [name] { u v [w] <Tangent> { x y z } <Binormal> { x y z } }
<DynamicVertexPool> name { vertices }
@ -1000,12 +1020,13 @@ corresponding attribute entries:
normalized to unit length.
<DUV> target { u v }
<DUV> target { u v [w] }
A texture-coordinate delta, valid within a <UV> entry (within a
<Vertex> entry). The given 2-valued offset vector, scaled by the
morph target's value, is added to the vertex's texture coordinates
each frame.
<Vertex> entry). The offset vector should be 2-valued if the
enclosing UV is 2-valued, or 3-valued if the enclosing UV is
3-valued. The given offset vector, scaled by the morph target's
value, is added to the vertex's texture coordinates each frame.
<DRGBA> target { r g b a }
@ -1366,25 +1387,25 @@ GROUPING ENTRIES
a particular axis, either implicit (about the x, y, or z axis), or
arbitrary. Matrices, when specified explicitly, are row-major.
<Translate> { x y z }
<RotX> { degrees }
<RotY> { degrees }
<RotZ> { degrees }
<Rotate> { degrees x y z }
<Scale> { x y z }
<Scale> { s }
<Translate> { x y z }
<RotX> { degrees }
<RotY> { degrees }
<RotZ> { degrees }
<Rotate> { degrees x y z }
<Scale> { x y z }
<Scale> { s }
<Matrix4> {
00 01 02 03
10 11 12 13
20 21 22 23
30 31 32 33
}
<Matrix4> {
00 01 02 03
10 11 12 13
20 21 22 23
30 31 32 33
}
Note that the <Transform> block defines a 3-d transform when it
appears within the context of a node, while it defines a 2-d
transform (and has correspondingly different entries) when it
appears within the context of a texture.
Note that the <Transform> block should always define a 3-d
transform when it appears within the body of a <Group>, while it
may define either a 2-d or a 3-d transform when it appears within
the body of a <Texture>. See <Texture>, above.
<VertexRef> { indices <Ref> { pool-name } }

View File

@ -41,7 +41,7 @@
eggTexture.h eggTextureCollection.I eggTextureCollection.h \
eggTriangleFan.I eggTriangleFan.h \
eggTriangleStrip.I eggTriangleStrip.h \
eggTransform3d.I eggTransform3d.h \
eggTransform.I eggTransform.h \
eggUserData.I eggUserData.h \
eggUtilities.I eggUtilities.h \
eggVertex.I eggVertex.h eggVertexPool.I eggVertexPool.h \
@ -72,7 +72,7 @@
eggPoolUniquifier.cxx eggPrimitive.cxx eggRenderMode.cxx \
eggSAnimData.cxx eggSurface.cxx eggSwitchCondition.cxx \
eggTable.cxx eggTexture.cxx eggTextureCollection.cxx \
eggTransform3d.cxx \
eggTransform.cxx \
eggTriangleFan.cxx \
eggTriangleStrip.cxx \
eggUserData.cxx \
@ -104,7 +104,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 \
eggTransform.I eggTransform.h \
eggTriangleFan.I eggTriangleFan.h \
eggTriangleStrip.I eggTriangleStrip.h \
eggUserData.I eggUserData.h \

View File

@ -85,8 +85,8 @@ write(ostream &out, int indent_level) const {
<< "<Normal> { " << get_normal() << " }\n";
} else {
indent(out, indent_level) << "<Normal> {\n";
indent(out, indent_level+2) << get_normal() << "\n";
_dnormals.write(out, indent_level+2);
indent(out, indent_level + 2) << get_normal() << "\n";
_dnormals.write(out, indent_level + 2, "<DNormal>", 3);
indent(out, indent_level) << "}\n";
}
}
@ -96,8 +96,8 @@ write(ostream &out, int indent_level) const {
<< "<RGBA> { " << get_color() << " }\n";
} else {
indent(out, indent_level) << "<RGBA> {\n";
indent(out, indent_level+2) << get_color() << "\n";
_drgbas.write(out, indent_level+2);
indent(out, indent_level + 2) << get_color() << "\n";
_drgbas.write(out, indent_level + 2, "<DRBGA>", 4);
indent(out, indent_level) << "}\n";
}
}

View File

@ -63,7 +63,7 @@ EggGroup(const EggGroup &copy) {
////////////////////////////////////////////////////////////////////
EggGroup &EggGroup::
operator = (const EggGroup &copy) {
EggTransform3d::operator = (copy);
EggTransform::operator = (copy);
_flags = copy._flags;
_flags2 = copy._flags2;
_collide_mask = copy._collide_mask;
@ -215,7 +215,7 @@ write(ostream &out, int indent_level) const {
write_switch_flags(out, indent_level + 2);
if (has_transform()) {
EggTransform3d::write(out, indent_level + 2);
EggTransform::write(out, indent_level + 2);
}
write_object_types(out, indent_level + 2);
@ -995,6 +995,17 @@ string_blend_operand(const string &strval) {
}
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::as_transform
// Access: Public, Virtual
// Description: Returns this object cross-cast to an EggTransform
// pointer, if it inherits from EggTransform, or NULL if
// it does not.
////////////////////////////////////////////////////////////////////
EggTransform *EggGroup::
as_transform() {
return this;
}
////////////////////////////////////////////////////////////////////

View File

@ -23,7 +23,7 @@
#include "eggGroupNode.h"
#include "eggRenderMode.h"
#include "eggTransform3d.h"
#include "eggTransform.h"
#include "eggVertex.h"
#include "eggSwitchCondition.h"
#include "pt_EggVertex.h"
@ -37,7 +37,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, public EggTransform3d {
class EXPCL_PANDAEGG EggGroup : public EggGroupNode, public EggRenderMode, public EggTransform {
PUBLISHED:
typedef pmap<PT_EggVertex, double> VertexRef;
typedef pmap<string, string> TagData;
@ -297,6 +297,9 @@ PUBLISHED:
static BlendMode string_blend_mode(const string &strval);
static BlendOperand string_blend_operand(const string &strval);
public:
virtual EggTransform *as_transform();
protected:
void write_vertex_ref(ostream &out, int indent_level) const;
virtual bool egg_start_parse_body();

View File

@ -94,3 +94,25 @@ 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";
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

@ -55,6 +55,14 @@ enquote_string(ostream &out, const string &str,
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"

View File

@ -105,40 +105,17 @@ compare_to(const EggMorph<Parameter> &other) const {
return _offset.compare_to(other._offset);
}
////////////////////////////////////////////////////////////////////
// Function: EggMorphVertex output operator
// Description:
// Function: EggMorph::output
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE ostream &operator << (ostream &out, const EggMorphVertex &m) {
return out << "<Dxyz> " << m.get_name() << " { " << m.get_offset() << " }";
}
/*
////////////////////////////////////////////////////////////////////
// Function: EggMorphNormal output operator
// Description:
////////////////////////////////////////////////////////////////////
INLINE ostream &operator << (ostream &out, const EggMorphNormal &m) {
return out << "<DNormal> " << m.get_name() << " { " << m.get_offset() << " }";
}
*/
////////////////////////////////////////////////////////////////////
// Function: EggMorphTexCoord output operator
// Description:
////////////////////////////////////////////////////////////////////
INLINE ostream &operator << (ostream &out, const EggMorphTexCoord &m) {
return out << "<Duv> " << m.get_name() << " { " << m.get_offset() << " }";
}
////////////////////////////////////////////////////////////////////
// Function: EggMorphColor output operator
// Description:
////////////////////////////////////////////////////////////////////
INLINE ostream &operator << (ostream &out, const EggMorphColor &m) {
return out << "<Drgba> " << m.get_name() << " { " << m.get_offset() << " }";
template<class Parameter>
INLINE void EggMorph<Parameter>::
output(ostream &out, const string &tag, int num_dimensions) const {
out << tag << " " << get_name() << " {";
for (int i = 0; i < num_dimensions; ++i) {
out << " " << MAYBE_ZERO(_offset[i]);
}
out << " }";
}

View File

@ -46,28 +46,21 @@ public:
INLINE int compare_to(const EggMorph<Parameter> &other) const;
INLINE void output(ostream &out, const string &tag,
int num_dimensions) const;
private:
Parameter _offset;
};
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEGG, EXPTP_PANDAEGG, EggMorph<LVector3d>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEGG, EXPTP_PANDAEGG, EggMorph<LVector2d>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEGG, EXPTP_PANDAEGG, EggMorph<LVector4f>);
typedef EggMorph<LVector3d> EggMorphVertex;
typedef EggMorph<LVector3d> EggMorphNormal;
typedef EggMorph<LVector2d> EggMorphTexCoord;
typedef EggMorph<LVector3d> EggMorphTexCoord;
typedef EggMorph<LVector4f> EggMorphColor;
INLINE ostream &operator << (ostream &out, const EggMorphVertex &m);
INLINE ostream &operator << (ostream &out, const EggMorphTexCoord &m);
INLINE ostream &operator << (ostream &out, const EggMorphColor &m);
// EggMorphNormal is, by virtue of equivalent typedefs, another name
// for EggMorphVertex. Therefore we shouldn't define its output
// operator again.
//INLINE ostream &operator << (ostream &out, const EggMorphNormal &m);
#include "eggMorph.I"
#endif

View File

@ -231,11 +231,14 @@ clear() {
////////////////////////////////////////////////////////////////////
template<class MorphType>
void EggMorphList<MorphType>::
write(ostream &out, int indent_level) const {
write(ostream &out, int indent_level, const string &tag,
int num_dimensions) const {
const_iterator i;
for (i = begin(); i != end(); ++i) {
indent(out, indent_level) << *i << "\n";
indent(out, indent_level);
i->output(out, tag, num_dimensions);
out << "\n";
}
}

View File

@ -62,7 +62,8 @@ public:
pair<iterator, bool> insert(const MorphType &value);
INLINE void clear();
void write(ostream &out, int indent_level) const;
void write(ostream &out, int indent_level,
const string &tag, int num_dimensions) const;
private:
Morphs _morphs;

View File

@ -175,3 +175,15 @@ clear_user_data(TypeHandle type) {
_user_data.erase(ui);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::as_transform
// Access: Public, Virtual
// Description: Returns this object cross-cast to an EggTransform
// pointer, if it inherits from EggTransform, or NULL if
// it does not.
////////////////////////////////////////////////////////////////////
EggTransform *EggObject::
as_transform() {
return NULL;
}

View File

@ -25,6 +25,8 @@
#include "pointerTo.h"
#include "pmap.h"
class EggTransform;
////////////////////////////////////////////////////////////////////
// Class : EggObject
// Description : The highest-level base class in the egg directory.
@ -46,6 +48,9 @@ PUBLISHED:
void clear_user_data();
void clear_user_data(TypeHandle type);
public:
virtual EggTransform *as_transform();
private:
typedef pmap<TypeHandle, PT(EggUserData) > UserData;
UserData _user_data;

View File

@ -1037,7 +1037,7 @@ r_apply_texmats(EggTextureCollection &textures) {
// We've got a texture with a matrix applied. Save the matrix,
// and get a new texture without the matrix.
LMatrix3d mat = texture->get_transform();
LMatrix4d mat = texture->get_transform();
EggTexture new_texture(*texture);
new_texture.clear_transform();
EggTexture *unique = textures.create_unique_texture(new_texture, ~0);
@ -1055,7 +1055,12 @@ r_apply_texmats(EggTextureCollection &textures) {
if (uv_obj != (EggVertexUV *)NULL) {
EggVertex new_vertex(*vertex);
PT(EggVertexUV) new_uv_obj = new EggVertexUV(*uv_obj);
new_uv_obj->set_uv(uv_obj->get_uv() * mat);
TexCoord3d uvw = uv_obj->get_uvw() * mat;
if (uv_obj->has_w() || !texture->is_transform_2d()) {
new_uv_obj->set_uvw(uvw);
} else {
new_uv_obj->set_uv(TexCoordd(uvw[0], uvw[1]));
}
new_vertex.set_uv_obj(new_uv_obj);
EggVertexPool *pool = vertex->get_pool();

View File

@ -522,8 +522,12 @@ get_color() const {
////////////////////////////////////////////////////////////////////
INLINE void EggTexture::
set_uv_name(const string &uv_name) {
_uv_name = uv_name;
_flags |= F_has_uv_name;
if (uv_name == "default" || uv_name.empty()) {
clear_uv_name();
} else {
_uv_name = uv_name;
_flags |= F_has_uv_name;
}
}
////////////////////////////////////////////////////////////////////
@ -663,65 +667,6 @@ get_alpha_scale() const {
return _alpha_scale;
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::set_transform
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EggTexture::
set_transform(const LMatrix3d &transform) {
_transform = transform;
_flags |= F_has_transform;
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::clear_transform
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EggTexture::
clear_transform() {
_transform = LMatrix3d::ident_mat();
_flags &= ~F_has_transform;
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::has_transform
// Access: Published
// Description: Returns true if a texture matrix transform has been
// specified for the texture (even if the transform is
// identity).
////////////////////////////////////////////////////////////////////
INLINE bool EggTexture::
has_transform() const {
return (_flags & F_has_transform) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::get_transform
// Access: Published
// Description: Returns the texture matrix transform if one has been
// specified, or identity matrix otherwise.
////////////////////////////////////////////////////////////////////
INLINE const LMatrix3d &EggTexture::
get_transform() const {
return _transform;
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::transform_is_identity()
// Access: Published
// Description: Returns true if no texture matrix transform has been
// specified, or if the one specified is the identity
// transform. Returns false only if a nonidentity
// transform has been applied.
////////////////////////////////////////////////////////////////////
INLINE bool EggTexture::
transform_is_identity() const {
return (!has_transform() ||
_transform.almost_equal(LMatrix3d::ident_mat(), 0.0001));
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::set_alpha_filename
// Access: Published

View File

@ -48,7 +48,6 @@ EggTexture(const string &tref_name, const string &filename)
_priority = 0;
_color.set(0.0f, 0.0f, 0.0f, 1.0f);
_flags = 0;
_transform = LMatrix3d::ident_mat();
_alpha_file_channel = 0;
_multitexture_sort = 0;
}
@ -74,6 +73,7 @@ operator = (const EggTexture &copy) {
EggFilenameNode::operator = (copy);
EggRenderMode::operator = (copy);
EggTransform::operator = (copy);
_format = copy._format;
_wrap_mode = copy._wrap_mode;
@ -92,7 +92,6 @@ operator = (const EggTexture &copy) {
_rgb_scale = 1;
_alpha_scale = 1;
_flags = copy._flags;
_transform = copy._transform;
_alpha_filename = copy._alpha_filename;
_alpha_fullpath = copy._alpha_fullpath;
_alpha_file_channel = copy._alpha_file_channel;
@ -247,7 +246,7 @@ write(ostream &out, int indent_level) const {
EggRenderMode::write(out, indent_level + 2);
if (has_transform()) {
write_transform(out, _transform, indent_level + 2);
EggTransform::write(out, indent_level + 2);
}
indent(out, indent_level) << "}\n";
@ -324,7 +323,7 @@ is_equivalent_to(const EggTexture &other, int eq) const {
}
if (has_transform() && other.has_transform()) {
if (!_transform.almost_equal(other._transform, 0.0001)) {
if (!get_transform().almost_equal(other.get_transform(), 0.0001)) {
return false;
}
}
@ -400,9 +399,9 @@ sorts_less_than(const EggTexture &other, int eq) const {
}
if (has_transform() && other.has_transform()) {
int compare = _transform.compare_to(other._transform);
int compare = get_transform().compare_to(other.get_transform());
if (compare != 0) {
return compare < 0;
return compare < 0;
}
}
}

View File

@ -23,6 +23,7 @@
#include "eggRenderMode.h"
#include "eggFilenameNode.h"
#include "eggTransform.h"
#include "pset.h"
#include "luse.h"
@ -33,7 +34,7 @@
// Description : Defines a texture map that may be applied to
// geometry.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEGG EggTexture : public EggFilenameNode, public EggRenderMode {
class EXPCL_PANDAEGG EggTexture : public EggFilenameNode, public EggRenderMode, public EggTransform {
PUBLISHED:
EggTexture(const string &tref_name, const string &filename);
EggTexture(const EggTexture &copy);
@ -216,12 +217,6 @@ PUBLISHED:
INLINE bool has_alpha_scale() const;
INLINE int get_alpha_scale() const;
INLINE void set_transform(const LMatrix3d &transform);
INLINE void clear_transform();
INLINE bool has_transform() const;
INLINE const LMatrix3d &get_transform() const;
INLINE bool transform_is_identity() const;
INLINE void set_alpha_filename(const Filename &filename);
INLINE void clear_alpha_filename();
INLINE bool has_alpha_filename() const;
@ -256,7 +251,6 @@ private:
bool r_min_multitexture_sort(int sort, MultiTextures &cycle_detector);
enum Flags {
F_has_transform = 0x0001,
F_has_alpha_filename = 0x0002,
F_has_anisotropic_degree = 0x0004,
F_has_alpha_file_channel = 0x0008,
@ -282,7 +276,6 @@ private:
int _rgb_scale;
int _alpha_scale;
int _flags;
LMatrix3d _transform;
Filename _alpha_filename;
Filename _alpha_fullpath;
int _alpha_file_channel;

View File

@ -0,0 +1,369 @@
// Filename: eggTransform.I
// Created by: drose (21Jun02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggTransform::Component::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggTransform::Component::
Component(EggTransform::ComponentType type, double number) :
_type(type),
_number(number)
{
_vec2 = (LVecBase2d *)NULL;
_vec3 = (LVecBase3d *)NULL;
_mat3 = (LMatrix3d *)NULL;
_mat4 = (LMatrix4d *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::Component::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggTransform::Component::
Component(const EggTransform::Component &copy) :
_type(copy._type),
_number(copy._number)
{
_vec2 = (LVecBase2d *)NULL;
_vec3 = (LVecBase3d *)NULL;
_mat3 = (LMatrix3d *)NULL;
_mat4 = (LMatrix4d *)NULL;
if (copy._vec2 != (LVecBase2d *)NULL) {
_vec2 = new LVector2d(*copy._vec2);
}
if (copy._vec3 != (LVecBase3d *)NULL) {
_vec3 = new LVector3d(*copy._vec3);
}
if (copy._mat3 != (LMatrix3d *)NULL) {
_mat3 = new LMatrix3d(*copy._mat3);
}
if (copy._mat4 != (LMatrix4d *)NULL) {
_mat4 = new LMatrix4d(*copy._mat4);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::Component::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EggTransform::Component::
operator = (const EggTransform::Component &copy) {
_type = copy._type;
_number = copy._number;
if (_vec2 != (LVecBase2d *)NULL) {
delete _vec2;
_vec2 = (LVecBase2d *)NULL;
}
if (_vec3 != (LVecBase3d *)NULL) {
delete _vec3;
_vec3 = (LVecBase3d *)NULL;
}
if (_mat3 != (LMatrix3d *)NULL) {
delete _mat3;
_mat3 = (LMatrix3d *)NULL;
}
if (_mat4 != (LMatrix4d *)NULL) {
delete _mat4;
_mat4 = (LMatrix4d *)NULL;
}
if (copy._vec2 != (LVecBase2d *)NULL) {
_vec2 = new LVecBase2d(*copy._vec2);
}
if (copy._vec3 != (LVecBase3d *)NULL) {
_vec3 = new LVecBase3d(*copy._vec3);
}
if (copy._mat3 != (LMatrix3d *)NULL) {
_mat3 = new LMatrix3d(*copy._mat3);
}
if (copy._mat4 != (LMatrix4d *)NULL) {
_mat4 = new LMatrix4d(*copy._mat4);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::Component::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggTransform::Component::
~Component() {
if (_vec2 != (LVecBase2d *)NULL) {
delete _vec2;
}
if (_vec3 != (LVecBase3d *)NULL) {
delete _vec3;
}
if (_mat3 != (LMatrix3d *)NULL) {
delete _mat3;
}
if (_mat4 != (LMatrix4d *)NULL) {
delete _mat4;
}
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::clear_transform
// Access: Public
// Description: Resets the transform to empty, identity.
////////////////////////////////////////////////////////////////////
INLINE void EggTransform::
clear_transform() {
internal_clear_transform();
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::add_matrix3
// Access: Public
// Description: Appends an arbitrary 3x3 matrix to the current
// transform.
////////////////////////////////////////////////////////////////////
INLINE void EggTransform::
add_matrix3(const LMatrix3d &mat) {
internal_add_matrix(mat);
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::add_matrix4
// Access: Public
// Description: Appends an arbitrary 4x4 matrix to the current
// transform.
////////////////////////////////////////////////////////////////////
INLINE void EggTransform::
add_matrix4(const LMatrix4d &mat) {
internal_add_matrix(mat);
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::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 EggTransform::
has_transform() const {
return !_components.empty();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::is_transform_2d
// Access: Public
// Description: Returns true if the transform is specified as a 2-d
// transform, e.g. with a 3x3 matrix, or false if it is
// specified as a 3-d transform, with a 4x4 matrix.
//
// Normally, EggTextures have a 2-d matrix (but
// occasionally they use a 3-d matrix), and EggGroups
// always have a 3-d matrix.
////////////////////////////////////////////////////////////////////
INLINE bool EggTransform::
is_transform_2d() const {
return _is_transform_2d;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::set_transform_2d
// Access: Public
// Description: Sets the overall transform as a 3x3 matrix. This
// completely replaces whatever componentwise transform
// may have been defined.
////////////////////////////////////////////////////////////////////
INLINE void EggTransform::
set_transform_2d(const LMatrix3d &mat) {
internal_set_transform(mat);
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::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 EggTransform::
set_transform(const LMatrix4d &mat) {
internal_set_transform(mat);
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::get_transform_2d
// Access: Public
// Description: Returns the overall transform as a 3x3 matrix. It is
// only valid to call this if is_transform_2d() has
// returned true.
////////////////////////////////////////////////////////////////////
INLINE LMatrix3d EggTransform::
get_transform_2d() const {
nassertr(is_transform_2d(), LMatrix3d::ident_mat());
const LMatrix4d &t = _transform;
return LMatrix3d(t(0, 0), t(0, 1), t(0, 3),
t(1, 0), t(1, 1), t(1, 3),
t(3, 0), t(3, 1), t(3, 3));
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::get_transform
// Access: Public
// Description: Returns the overall transform as a 4x4 matrix.
////////////////////////////////////////////////////////////////////
INLINE const LMatrix4d &EggTransform::
get_transform() const {
return _transform;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::transform_is_identity
// Access: Public
// Description: Returns true if the described transform is identity,
// false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool EggTransform::
transform_is_identity() const {
return _components.empty() ||
_transform.almost_equal(LMatrix4d::ident_mat(), 0.0001);
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::get_num_components
// Access: Public
// Description: Returns the number of components that make up the
// transform.
////////////////////////////////////////////////////////////////////
INLINE int EggTransform::
get_num_components() const {
return _components.size();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::get_component_type
// Access: Public
// Description: Returns the type of the nth component.
////////////////////////////////////////////////////////////////////
INLINE EggTransform::ComponentType EggTransform::
get_component_type(int n) const {
nassertr(n >= 0 && n < (int)_components.size(), CT_invalid);
return _components[n]._type;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::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 EggTransform::
get_component_number(int n) const {
nassertr(n >= 0 && n < (int)_components.size(), 0.0);
return _components[n]._number;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::get_component_vec2
// Access: Public
// Description: Returns the 2-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 2-d
// vector property.
////////////////////////////////////////////////////////////////////
INLINE const LVecBase2d &EggTransform::
get_component_vec2(int n) const {
nassertr(n >= 0 && n < (int)_components.size(), LVector2d::zero());
nassertr(_components[n]._vec2 != (LVecBase2d *)NULL, LVector2d::zero());
return *_components[n]._vec2;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::get_component_vec3
// 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 3-d
// vector property.
////////////////////////////////////////////////////////////////////
INLINE const LVecBase3d &EggTransform::
get_component_vec3(int n) const {
nassertr(n >= 0 && n < (int)_components.size(), LVector3d::zero());
nassertr(_components[n]._vec3 != (LVecBase3d *)NULL, LVector3d::zero());
return *_components[n]._vec3;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::get_component_mat3
// Access: Public
// Description: Returns the 3x3 matrix associated with the nth
// component. It is an error to call this if the
// component type is not CT_matrix3.
////////////////////////////////////////////////////////////////////
INLINE const LMatrix3d &EggTransform::
get_component_mat3(int n) const {
nassertr(n >= 0 && n < (int)_components.size(), LMatrix3d::ident_mat());
nassertr(_components[n]._mat3 != (LMatrix3d *)NULL, LMatrix3d::ident_mat());
return *_components[n]._mat3;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::get_component_mat4
// 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_matrix4.
////////////////////////////////////////////////////////////////////
INLINE const LMatrix4d &EggTransform::
get_component_mat4(int n) const {
nassertr(n >= 0 && n < (int)_components.size(), LMatrix4d::ident_mat());
nassertr(_components[n]._mat4 != (LMatrix4d *)NULL, LMatrix4d::ident_mat());
return *_components[n]._mat4;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::internal_set_transform
// Access: Protected
// Description: Sets the overall transform without calling
// transform_changed().
////////////////////////////////////////////////////////////////////
INLINE void EggTransform::
internal_set_transform(const LMatrix3d &mat) {
internal_clear_transform();
internal_add_matrix(mat);
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::internal_set_transform
// Access: Protected
// Description: Sets the overall transform without calling
// transform_changed().
////////////////////////////////////////////////////////////////////
INLINE void EggTransform::
internal_set_transform(const LMatrix4d &mat) {
internal_clear_transform();
internal_add_matrix(mat);
}

View File

@ -1,4 +1,4 @@
// Filename: eggTransform3d.cxx
// Filename: eggTransform.cxx
// Created by: drose (21Jun02)
//
////////////////////////////////////////////////////////////////////
@ -16,158 +16,211 @@
//
////////////////////////////////////////////////////////////////////
#include "eggTransform3d.h"
#include "eggTransform.h"
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::Constructor
// Function: EggTransform::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggTransform3d::
EggTransform3d() :
EggTransform::
EggTransform() :
_is_transform_2d(true),
_transform(LMatrix4d::ident_mat())
{
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::Copy Constructor
// Function: EggTransform::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggTransform3d::
EggTransform3d(const EggTransform3d &copy) :
EggTransform::
EggTransform(const EggTransform &copy) :
_is_transform_2d(copy._is_transform_2d),
_components(copy._components),
_transform(copy._transform)
{
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::Copy assignment operator
// Function: EggTransform::Copy assignment operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggTransform3d &EggTransform3d::
operator = (const EggTransform3d &copy) {
EggTransform &EggTransform::
operator = (const EggTransform &copy) {
_is_transform_2d = copy._is_transform_2d;
_components = copy._components;
_transform = copy._transform;
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::Destructor
// Function: EggTransform::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
EggTransform3d::
~EggTransform3d() {
EggTransform::
~EggTransform() {
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::add_translate
// Function: EggTransform::add_translate2d
// Access: Public
// Description: Appends a translation operation to the current
// Description: Appends a 2-d 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);
void EggTransform::
add_translate2d(const LVector2d &translate) {
_components.push_back(Component(CT_translate2d));
_components.back()._vec2 = new LVecBase2d(translate);
_transform *= LMatrix4d::translate_mat(LVector3d(translate[0], translate[1], 0.0));
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::add_translate3d
// Access: Public
// Description: Appends a 3-d translation operation to the current
// transform.
////////////////////////////////////////////////////////////////////
void EggTransform::
add_translate3d(const LVector3d &translate) {
_is_transform_2d = false;
_components.push_back(Component(CT_translate3d));
_components.back()._vec3 = new LVecBase3d(translate);
_transform *= LMatrix4d::translate_mat(translate);
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::add_rotx
// Function: EggTransform::add_rotate2d
// Access: Public
// Description: Appends a 2-d rotation to the current transform. The
// rotation angle is specified in degrees
// counterclockwise about the origin.
////////////////////////////////////////////////////////////////////
void EggTransform::
add_rotate2d(double angle) {
_components.push_back(Component(CT_rotate2d, angle));
_transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 0.0, 1.0));
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::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::
void EggTransform::
add_rotx(double angle) {
_is_transform_2d = false;
_components.push_back(Component(CT_rotx, angle));
_transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(1.0, 0.0, 0.0));
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::add_roty
// Function: EggTransform::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::
void EggTransform::
add_roty(double angle) {
_is_transform_2d = false;
_components.push_back(Component(CT_roty, angle));
_transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 1.0, 0.0));
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::add_rotz
// Function: EggTransform::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::
void EggTransform::
add_rotz(double angle) {
_is_transform_2d = false;
_components.push_back(Component(CT_rotz, angle));
_transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 0.0, 1.0));
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::add_rotate
// Function: EggTransform::add_rotate3d
// Access: Public
// Description: Appends a rotation about an arbitrary axis to the
// Description: Appends a 3-d 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) {
void EggTransform::
add_rotate3d(double angle, const LVector3d &axis) {
_is_transform_2d = false;
LVector3d normaxis = normalize(axis);
_components.push_back(Component(CT_rotate, angle));
_components.back()._vector = new LVector3d(normaxis);
_components.push_back(Component(CT_rotate3d, angle));
_components.back()._vec3 = new LVecBase3d(normaxis);
_transform *= LMatrix4d::rotate_mat(angle, normaxis);
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::add_rotate
// Function: EggTransform::add_rotate3d
// Access: Public
// Description: Appends an arbitrary rotation to the current
// Description: Appends an arbitrary 3-d rotation to the current
// transform, expressed as a quaternion. This is
// converted to axis-angle notation for the egg file.
////////////////////////////////////////////////////////////////////
void EggTransform3d::
add_rotate(const LQuaterniond &quat) {
add_rotate(quat.get_angle(), quat.get_axis());
void EggTransform::
add_rotate3d(const LQuaterniond &quat) {
_is_transform_2d = false;
add_rotate3d(quat.get_angle(), quat.get_axis());
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::add_scale
// Function: EggTransform::add_scale2d
// 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);
void EggTransform::
add_scale2d(const LVecBase2d &scale) {
_is_transform_2d = false;
_components.push_back(Component(CT_scale2d));
_components.back()._vec2 = new LVecBase2d(scale);
_transform *= LMatrix4d::scale_mat(LVecBase3d(scale[0], scale[1], 1.0));
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::add_scale3d
// Access: Public
// Description: Appends a possibly non-uniform scale to the current
// transform.
////////////////////////////////////////////////////////////////////
void EggTransform::
add_scale3d(const LVecBase3d &scale) {
_is_transform_2d = false;
_components.push_back(Component(CT_scale3d));
_components.back()._vec3 = new LVecBase3d(scale);
_transform *= LMatrix4d::scale_mat(scale);
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::add_uniform_scale
// Function: EggTransform::add_uniform_scale
// Access: Public
// Description: Appends a uniform scale to the current transform.
////////////////////////////////////////////////////////////////////
void EggTransform3d::
void EggTransform::
add_uniform_scale(double scale) {
_components.push_back(Component(CT_uniform_scale, scale));
_transform *= LMatrix4d::scale_mat(scale);
@ -175,21 +228,31 @@ add_uniform_scale(double scale) {
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::write
// Function: EggTransform::write
// Access: Public
// Description: Writes the transform to the indicated stream in Egg
// format.
////////////////////////////////////////////////////////////////////
void EggTransform3d::
void EggTransform::
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:
case CT_translate2d:
indent(out, indent_level + 2)
<< "<Translate> { " << get_component_vector(i) << " }\n";
<< "<Translate> { " << get_component_vec2(i) << " }\n";
break;
case CT_translate3d:
indent(out, indent_level + 2)
<< "<Translate> { " << get_component_vec3(i) << " }\n";
break;
case CT_rotate2d:
indent(out, indent_level + 2)
<< "<Rotate> { " << get_component_number(i) << " }\n";
break;
case CT_rotx:
@ -207,15 +270,20 @@ write(ostream &out, int indent_level) const {
<< "<RotZ> { " << get_component_number(i) << " }\n";
break;
case CT_rotate:
case CT_rotate3d:
indent(out, indent_level + 2)
<< "<Rotate> { " << get_component_number(i) << " "
<< get_component_vector(i) << " }\n";
<< get_component_vec3(i) << " }\n";
break;
case CT_scale:
case CT_scale2d:
indent(out, indent_level + 2)
<< "<Scale> { " << get_component_vector(i) << " }\n";
<< "<Scale> { " << get_component_vec2(i) << " }\n";
break;
case CT_scale3d:
indent(out, indent_level + 2)
<< "<Scale> { " << get_component_vec3(i) << " }\n";
break;
case CT_uniform_scale:
@ -223,9 +291,15 @@ write(ostream &out, int indent_level) const {
<< "<Scale> { " << get_component_number(i) << " }\n";
break;
case CT_matrix:
case CT_matrix3:
indent(out, indent_level + 2) << "<Matrix3> {\n";
get_component_mat3(i).write(out, indent_level + 4);
indent(out, indent_level + 2) << "}\n";
break;
case CT_matrix4:
indent(out, indent_level + 2) << "<Matrix4> {\n";
get_component_matrix(i).write(out, indent_level + 4);
get_component_mat4(i).write(out, indent_level + 4);
indent(out, indent_level + 2) << "}\n";
break;
@ -239,39 +313,58 @@ write(ostream &out, int indent_level) const {
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::internal_clear_transform
// Function: EggTransform::internal_clear_transform
// Access: Public
// Description: Resets the transform to empty without calling
// transform_changed().
////////////////////////////////////////////////////////////////////
void EggTransform3d::
void EggTransform::
internal_clear_transform() {
_is_transform_2d = true;
_components.clear();
_transform = LMatrix4d::ident_mat();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::internal_add_matrix
// Function: EggTransform::internal_add_matrix
// Access: Public
// Description: Appends an arbitrary 4x4 matrix to the current
// transform, without calling transform_changed().
////////////////////////////////////////////////////////////////////
void EggTransform3d::
void EggTransform::
internal_add_matrix(const LMatrix3d &mat) {
_components.push_back(Component(CT_matrix3));
_components.back()._mat3 = new LMatrix3d(mat);
LMatrix4d mat4(mat(0, 0), mat(0, 1), 0.0, mat(0, 2),
mat(1, 0), mat(1, 1), 0.0, mat(1, 2),
0.0, 0.0, 1.0, 0.0,
mat(2, 0), mat(2, 1), 0.0, mat(2, 2));
_transform *= mat4;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform::internal_add_matrix
// Access: Public
// Description: Appends an arbitrary 4x4 matrix to the current
// transform, without calling transform_changed().
////////////////////////////////////////////////////////////////////
void EggTransform::
internal_add_matrix(const LMatrix4d &mat) {
_components.push_back(Component(CT_matrix));
_components.back()._matrix = new LMatrix4d(mat);
_is_transform_2d = false;
_components.push_back(Component(CT_matrix4));
_components.back()._mat4 = new LMatrix4d(mat);
_transform *= mat;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::transform_changed
// Function: EggTransform::transform_changed
// Access: Protected, Virtual
// Description: This virtual method is called whenever the transform
// is changed; it is intended to provide a hook for
// derived classes (e.g. EggGroup) to update their
// internal cache appropriately.
////////////////////////////////////////////////////////////////////
void EggTransform3d::
void EggTransform::
transform_changed() {
}

View File

@ -1,4 +1,4 @@
// Filename: eggTransform3d.h
// Filename: eggTransform.h
// Created by: drose (21Jun02)
//
////////////////////////////////////////////////////////////////////
@ -16,67 +16,85 @@
//
////////////////////////////////////////////////////////////////////
#ifndef EGGTRANSFORM3D_H
#define EGGTRANSFORM3D_H
#ifndef EGGTRANSFORM_H
#define EGGTRANSFORM_H
#include "pandabase.h"
#include "luse.h"
////////////////////////////////////////////////////////////////////
// Class : EggTransform3d
// Class : EggTransform
// 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.
// or texture node: a list of component transform
// operations, applied in order, that describe a net
// transform matrix.
//
// This may be either a 3-d transform, and therefore
// described by a 4x4 matrix, or a 2-d transform,
// described by a 3x3 matrix.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEGG EggTransform3d {
class EXPCL_PANDAEGG EggTransform {
PUBLISHED:
EggTransform3d();
EggTransform3d(const EggTransform3d &copy);
EggTransform3d &operator = (const EggTransform3d &copy);
virtual ~EggTransform3d();
EggTransform();
EggTransform(const EggTransform &copy);
EggTransform &operator = (const EggTransform &copy);
virtual ~EggTransform();
INLINE void clear_transform();
void add_translate(const LVector3d &translate);
void add_translate2d(const LVector2d &translate);
void add_translate3d(const LVector3d &translate);
void add_rotate2d(double angle);
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_rotate(const LQuaterniond &quat);
void add_scale(const LVecBase3d &scale);
void add_rotate3d(double angle, const LVector3d &axis);
void add_rotate3d(const LQuaterniond &quat);
void add_scale2d(const LVecBase2d &scale);
void add_scale3d(const LVecBase3d &scale);
void add_uniform_scale(double scale);
INLINE void add_matrix(const LMatrix4d &mat);
INLINE void add_matrix3(const LMatrix3d &mat);
INLINE void add_matrix4(const LMatrix4d &mat);
INLINE bool has_transform() const;
INLINE bool is_transform_2d() const;
INLINE void set_transform_2d(const LMatrix3d &mat);
INLINE void set_transform(const LMatrix4d &mat);
INLINE LMatrix3d get_transform_2d() const;
INLINE const LMatrix4d &get_transform() const;
INLINE bool transform_is_identity() const;
enum ComponentType {
CT_invalid,
CT_translate,
CT_translate2d,
CT_translate3d,
CT_rotate2d,
CT_rotx,
CT_roty,
CT_rotz,
CT_rotate,
CT_scale,
CT_rotate3d,
CT_scale2d,
CT_scale3d,
CT_uniform_scale,
CT_matrix
CT_matrix3,
CT_matrix4
};
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;
INLINE const LVecBase2d &get_component_vec2(int n) const;
INLINE const LVecBase3d &get_component_vec3(int n) const;
INLINE const LMatrix3d &get_component_mat3(int n) const;
INLINE const LMatrix4d &get_component_mat4(int n) const;
void write(ostream &out, int indent_level) const;
protected:
void internal_clear_transform();
void internal_add_matrix(const LMatrix3d &mat);
void internal_add_matrix(const LMatrix4d &mat);
INLINE void internal_set_transform(const LMatrix3d &mat);
INLINE void internal_set_transform(const LMatrix4d &mat);
virtual void transform_changed();
@ -91,15 +109,18 @@ private:
ComponentType _type;
double _number;
LVector3d *_vector;
LMatrix4d *_matrix;
LVecBase2d *_vec2;
LVecBase3d *_vec3;
LMatrix3d *_mat3;
LMatrix4d *_mat4;
};
bool _is_transform_2d;
typedef pvector<Component> Components;
Components _components;
LMatrix4d _transform;
};
#include "eggTransform3d.I"
#include "eggTransform.I"
#endif

View File

@ -1,240 +0,0 @@
// Filename: eggTransform3d.I
// Created by: drose (21Jun02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// 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::clear_transform
// Access: Public
// Description: Resets the transform to empty, identity.
////////////////////////////////////////////////////////////////////
INLINE void EggTransform3d::
clear_transform() {
internal_clear_transform();
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::add_matrix
// Access: Public
// Description: Appends an arbitrary 4x4 matrix to the current
// transform.
////////////////////////////////////////////////////////////////////
INLINE void EggTransform3d::
add_matrix(const LMatrix4d &mat) {
internal_add_matrix(mat);
transform_changed();
}
////////////////////////////////////////////////////////////////////
// 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) {
internal_set_transform(mat);
transform_changed();
}
////////////////////////////////////////////////////////////////////
// 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;
}
////////////////////////////////////////////////////////////////////
// Function: EggTransform3d::internal_set_transform
// Access: Protected
// Description: Sets the overall transform without calling
// transform_changed().
////////////////////////////////////////////////////////////////////
INLINE void EggTransform3d::
internal_set_transform(const LMatrix4d &mat) {
internal_clear_transform();
internal_add_matrix(mat);
}

View File

@ -211,7 +211,7 @@ has_uv() const {
// multitexturing; see get_uv(name) for the interface
// that supports multitexturing.
////////////////////////////////////////////////////////////////////
INLINE const TexCoordd &EggVertex::
INLINE TexCoordd EggVertex::
get_uv() const {
nassertr(has_uv(), TexCoordd::zero());
return get_uv("");

View File

@ -117,12 +117,34 @@ EggVertex::
// Function: EggVertex::has_uv
// Access: Published
// Description: Returns true if the vertex has the named UV
// coordinate pair, false otherwise.
// coordinate pair, and the named UV coordinate pair is
// 2-d, false otherwise.
////////////////////////////////////////////////////////////////////
bool EggVertex::
has_uv(const string &name) const {
UVMap::const_iterator ui = _uv_map.find(name);
return (ui != _uv_map.end());
if (ui != _uv_map.end()) {
EggVertexUV *uv_obj = (*ui).second;
return !uv_obj->has_w();
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::has_uvw
// Access: Published
// Description: Returns true if the vertex has the named UV
// coordinate triple, and the named UV coordinate triple is
// 3-d, false otherwise.
////////////////////////////////////////////////////////////////////
bool EggVertex::
has_uvw(const string &name) const {
UVMap::const_iterator ui = _uv_map.find(name);
if (ui != _uv_map.end()) {
EggVertexUV *uv_obj = (*ui).second;
return uv_obj->has_w();
}
return false;
}
////////////////////////////////////////////////////////////////////
@ -132,13 +154,27 @@ has_uv(const string &name) const {
// vertex. It is an error to call this if has_uv(name)
// returned false.
////////////////////////////////////////////////////////////////////
const TexCoordd &EggVertex::
TexCoordd EggVertex::
get_uv(const string &name) const {
UVMap::const_iterator ui = _uv_map.find(name);
nassertr(ui != _uv_map.end(), TexCoordd::zero());
return (*ui).second->get_uv();
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::get_uvw
// Access: Published
// Description: Returns the named UV coordinate triple on the vertex.
// vertex. It is an error to call this if has_uvw(name)
// returned false.
////////////////////////////////////////////////////////////////////
const TexCoord3d &EggVertex::
get_uvw(const string &name) const {
UVMap::const_iterator ui = _uv_map.find(name);
nassertr(ui != _uv_map.end(), TexCoord3d::zero());
return (*ui).second->get_uvw();
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::set_uv
// Access: Published
@ -160,6 +196,28 @@ set_uv(const string &name, const TexCoordd &uv) {
nassertv(get_uv(name) == uv);
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::set_uvw
// Access: Published
// Description: Sets the indicated UV coordinate triple on the vertex.
// This replaces any UV coordinate pair or triple with
// the same name already on the vertex, but preserves UV
// morphs.
////////////////////////////////////////////////////////////////////
void EggVertex::
set_uvw(const string &name, const TexCoord3d &uvw) {
PT(EggVertexUV) &uv_obj = _uv_map[name];
if (uv_obj.is_null()) {
uv_obj = new EggVertexUV(name, uvw);
} else {
uv_obj = new EggVertexUV(*uv_obj);
uv_obj->set_uvw(uvw);
}
nassertv(get_uvw(name) == uvw);
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::get_uv_obj
// Access: Published
@ -257,7 +315,7 @@ write(ostream &out, int indent_level) const {
EggAttributes::write(out, indent_level+2);
_dxyzs.write(out, indent_level+2);
_dxyzs.write(out, indent_level + 2, "<Dxyz>", 3);
// If the vertex is referenced by one or more groups, write that as
// a helpful comment.

View File

@ -82,12 +82,15 @@ PUBLISHED:
INLINE LPoint4d get_pos4() const;
INLINE bool has_uv() const;
INLINE const TexCoordd &get_uv() const;
INLINE TexCoordd get_uv() const;
INLINE void set_uv(const TexCoordd &texCoord);
INLINE void clear_uv();
bool has_uv(const string &name) const;
const TexCoordd &get_uv(const string &name) const;
bool has_uvw(const string &name) const;
TexCoordd get_uv(const string &name) const;
const TexCoord3d &get_uvw(const string &name) const;
void set_uv(const string &name, const TexCoordd &texCoord);
void set_uvw(const string &name, const TexCoord3d &texCoord);
EggVertexUV *get_uv_obj(const string &name) const;
void set_uv_obj(EggVertexUV *vertex_uv);
void clear_uv(const string &name);

View File

@ -295,14 +295,17 @@ has_uvs() const {
// Function: EggVertexPool::get_uv_names
// Access: Public
// Description: Returns the list of UV names that are defined by any
// vertices in the pool. Also returns the subset of UV
// names that define the tangent and binormal. It is
// the user's responsibility to clear both vectors
// before calling this method.
// vertices in the pool, as well as the subset of UV
// names that actually define 3-d texture coordinates
// ("uvw_names"). Also returns the subset of UV/UVW
// names that define a tangent and binormal. It is the
// user's responsibility to clear both vectors before
// calling this method.
////////////////////////////////////////////////////////////////////
void EggVertexPool::
get_uv_names(vector_string &uv_names, vector_string &tbn_names) const {
pset<string> uv_names_set, tbn_names_set;
get_uv_names(vector_string &uv_names, vector_string &uvw_names,
vector_string &tbn_names) const {
pset<string> uv_names_set, uvw_names_set, tbn_names_set;
IndexVertices::const_iterator ivi;
for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
EggVertex *vertex = (*ivi).second;
@ -310,6 +313,9 @@ get_uv_names(vector_string &uv_names, vector_string &tbn_names) const {
for (uvi = vertex->uv_begin(); uvi != vertex->uv_end(); ++uvi) {
EggVertexUV *uv_obj = (*uvi);
uv_names_set.insert(uv_obj->get_name());
if (uv_obj->has_w()) {
uvw_names_set.insert(uv_obj->get_name());
}
if (uv_obj->has_tangent() && uv_obj->has_binormal()) {
tbn_names_set.insert(uv_obj->get_name());
}
@ -320,6 +326,9 @@ get_uv_names(vector_string &uv_names, vector_string &tbn_names) const {
for (si = uv_names_set.begin(); si != uv_names_set.end(); ++si) {
uv_names.push_back(*si);
}
for (si = uvw_names_set.begin(); si != uvw_names_set.end(); ++si) {
uvw_names.push_back(*si);
}
for (si = tbn_names_set.begin(); si != tbn_names_set.end(); ++si) {
tbn_names.push_back(*si);
}

View File

@ -98,7 +98,8 @@ PUBLISHED:
bool has_colors() const;
bool has_nonwhite_colors() const;
bool has_uvs() const;
void get_uv_names(vector_string &uv_names, vector_string &tbn_names) const;
void get_uv_names(vector_string &uv_names, vector_string &uvw_names,
vector_string &tbn_names) const;
public:
// Can be used to traverse all the vertices in index number order.

View File

@ -17,24 +17,92 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::set_name
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EggVertexUV::
set_name(const string &name) {
if (name == "default") {
clear_name();
} else {
Namable::set_name(name);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::get_num_dimensions
// Access: Published
// Description: Returns the number of components of the texture
// coordinate set. This is either 2 (the normal case)
// or 3 (for a 3-d texture coordinate).
////////////////////////////////////////////////////////////////////
INLINE int EggVertexUV::
get_num_dimensions() const {
return has_w() ? 3 : 2;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::has_w
// Access: Published
// Description: Returns true if the texture coordinate has a third, w
// component, false if it is just a normal 2-d texture
// coordinate.
////////////////////////////////////////////////////////////////////
INLINE bool EggVertexUV::
has_w() const {
return (_flags & F_has_w) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::get_uv
// Access: Published
// Description: Returns the texture coordinate pair.
// Description: Returns the texture coordinate pair, if
// get_num_dimensions() is 2.
////////////////////////////////////////////////////////////////////
INLINE const TexCoordd &EggVertexUV::
INLINE TexCoordd EggVertexUV::
get_uv() const {
return _uv;
nassertr(!has_w(), TexCoordd::zero());
return TexCoordd(_uvw[0], _uvw[1]);
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::get_uvw
// Access: Published
// Description: Returns the texture coordinate triple, if
// get_num_dimensions() is 3. This is also legal to
// call if get_num_dimensions() is 2 (but the last
// dimension will be zero).
////////////////////////////////////////////////////////////////////
INLINE const TexCoord3d &EggVertexUV::
get_uvw() const {
return _uvw;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::set_uv
// Access: Published
// Description: Sets the texture coordinate pair.
// Description: Sets the texture coordinate pair. This makes the
// texture coordinate a 2-d texture coordinate, which is
// the usual case.
////////////////////////////////////////////////////////////////////
INLINE void EggVertexUV::
set_uv(const TexCoordd &uv) {
_uv = uv;
_uvw.set(uv[0], uv[1], 0.0);
_flags &= ~F_has_w;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::set_uvw
// Access: Published
// Description: Sets the texture coordinate triple. This makes the
// texture coordinate a 3-d texture coordinate.
////////////////////////////////////////////////////////////////////
INLINE void EggVertexUV::
set_uvw(const TexCoord3d &uvw) {
_uvw = uvw;
_flags |= F_has_w;
}
////////////////////////////////////////////////////////////////////

View File

@ -32,8 +32,27 @@ EggVertexUV::
EggVertexUV(const string &name, const TexCoordd &uv) :
EggNamedObject(name),
_flags(0),
_uv(uv)
_uvw(uv[0], uv[1], 0.0)
{
if (get_name() == "default") {
clear_name();
}
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
EggVertexUV::
EggVertexUV(const string &name, const TexCoord3d &uvw) :
EggNamedObject(name),
_flags(F_has_w),
_uvw(uvw)
{
if (get_name() == "default") {
clear_name();
}
}
////////////////////////////////////////////////////////////////////
@ -48,7 +67,7 @@ EggVertexUV(const EggVertexUV &copy) :
_flags(copy._flags),
_tangent(copy._tangent),
_binormal(copy._binormal),
_uv(copy._uv)
_uvw(copy._uvw)
{
}
@ -64,7 +83,7 @@ operator = (const EggVertexUV &copy) {
_flags = copy._flags;
_tangent = copy._tangent;
_binormal = copy._binormal;
_uv = copy._uv;
_uvw = copy._uvw;
return (*this);
}
@ -109,12 +128,21 @@ write(ostream &out, int indent_level) const {
inline_name += ' ';
}
if (_duvs.empty() && _flags == 0) {
indent(out, indent_level)
<< "<UV> " << inline_name << "{ " << get_uv() << " }\n";
if (_duvs.empty() && (_flags & ~F_has_w) == 0) {
if (has_w()) {
indent(out, indent_level)
<< "<UV> " << inline_name << "{ " << get_uvw() << " }\n";
} else {
indent(out, indent_level)
<< "<UV> " << inline_name << "{ " << get_uv() << " }\n";
}
} else {
indent(out, indent_level) << "<UV> " << inline_name << "{\n";
indent(out, indent_level+2) << get_uv() << "\n";
if (has_w()) {
indent(out, indent_level+2) << get_uvw() << "\n";
} else {
indent(out, indent_level+2) << get_uv() << "\n";
}
if (has_tangent()) {
indent(out, indent_level + 2)
<< "<Tangent> { " << get_tangent() << " }\n";
@ -123,7 +151,7 @@ write(ostream &out, int indent_level) const {
indent(out, indent_level + 2)
<< "<Binormal> { " << get_binormal() << " }\n";
}
_duvs.write(out, indent_level+2);
_duvs.write(out, indent_level + 2, "<Duv>", get_num_dimensions());
indent(out, indent_level) << "}\n";
}
}
@ -141,7 +169,7 @@ compare_to(const EggVertexUV &other) const {
return _flags - other._flags;
}
int compare;
compare = _uv.compare_to(other._uv, egg_parameters->_uv_threshold);
compare = _uvw.compare_to(other._uvw, egg_parameters->_uv_threshold);
if (compare != 0) {
return compare;
}

View File

@ -36,12 +36,19 @@
class EXPCL_PANDAEGG EggVertexUV : public EggNamedObject {
PUBLISHED:
EggVertexUV(const string &name, const TexCoordd &uv);
EggVertexUV(const string &name, const TexCoord3d &uvw);
EggVertexUV(const EggVertexUV &copy);
EggVertexUV &operator = (const EggVertexUV &copy);
virtual ~EggVertexUV();
INLINE const TexCoordd &get_uv() const;
INLINE void set_name(const string &name);
INLINE int get_num_dimensions() const;
INLINE bool has_w() const;
INLINE TexCoordd get_uv() const;
INLINE const TexCoord3d &get_uvw() const;
INLINE void set_uv(const TexCoordd &texCoord);
INLINE void set_uvw(const TexCoord3d &texCoord);
INLINE bool has_tangent() const;
INLINE const Normald &get_tangent() const;
@ -64,12 +71,13 @@ private:
enum Flags {
F_has_tangent = 0x001,
F_has_binormal = 0x002,
F_has_w = 0x004,
};
int _flags;
Normald _tangent;
Normald _binormal;
TexCoordd _uv;
TexCoord3d _uvw;
public:
static TypeHandle get_class_type() {

View File

@ -12,7 +12,7 @@
#include "eggTable.cxx"
#include "eggTexture.cxx"
#include "eggTextureCollection.cxx"
#include "eggTransform3d.cxx"
#include "eggTransform.cxx"
#include "eggTriangleFan.cxx"
#include "eggTriangleStrip.cxx"
#include "eggUserData.cxx"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* A Bison parser, made by GNU Bison 1.875b. */
/* A Bison parser, made by GNU Bison 2.0. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -622,7 +622,7 @@ texture_body:
eggyywarning("Unsupported texture scalar: " + name);
}
}
| texture_body transform_2d
| texture_body transform
;
/*
@ -955,6 +955,10 @@ vertex_uv_body:
real real
{
DCAST(EggVertexUV, egg_stack.back())->set_uv(TexCoordd($1, $2));
}
| real real real
{
DCAST(EggVertexUV, egg_stack.back())->set_uvw(LVecBase3d($1, $2, $3));
}
| vertex_uv_body TANGENT '{' real real real '}'
{
@ -975,15 +979,31 @@ vertex_uv_body:
| vertex_uv_body DUV string '{' real real '}'
{
bool inserted = DCAST(EggVertexUV, egg_stack.back())->_duvs.
insert(EggMorphTexCoord($3, LVector2d($5, $6))).second;
insert(EggMorphTexCoord($3, LVector3d($5, $6, 0.0))).second;
if (!inserted) {
eggyywarning("Ignoring repeated morph name " + $3);
}
}
| vertex_uv_body DUV '{' string real real '}'
| vertex_uv_body DUV string '{' real real real '}'
{
bool inserted = DCAST(EggVertexUV, egg_stack.back())->_duvs.
insert(EggMorphTexCoord($4, LVector2d($5, $6))).second;
insert(EggMorphTexCoord($3, LVector3d($5, $6, $7))).second;
if (!inserted) {
eggyywarning("Ignoring repeated morph name " + $3);
}
}
| vertex_uv_body DUV '{' string real real '}'
{
bool inserted = DCAST(EggVertexUV, egg_stack.back())->_duvs.
insert(EggMorphTexCoord($4, LVector3d($5, $6, 0.0))).second;
if (!inserted) {
eggyywarning("Ignoring repeated morph name " + $4);
}
}
| vertex_uv_body DUV '{' string real real real '}'
{
bool inserted = DCAST(EggVertexUV, egg_stack.back())->_duvs.
insert(EggMorphTexCoord($4, LVector3d($5, $6, $7))).second;
if (!inserted) {
eggyywarning("Ignoring repeated morph name " + $4);
}
@ -1343,7 +1363,7 @@ group_body:
int value = (int)$4;
group->set_texlist_flag(value!=0);
}
| group_body transform_3d
| group_body transform
| group_body group_vertex_ref
| group_body switchcondition
| group_body node
@ -1406,91 +1426,144 @@ collide_flags:
;
/*
* transform_3d
* transform
*
* enter: TOS is EggGroup.
* exit: group's transform matrix has been set.
* enter: TOS is some kind of EggTransform.
* exit: transform matrix has been set.
*
*/
transform_3d:
transform:
TRANSFORM
{
DCAST(EggGroup, egg_stack.back())->clear_transform();
egg_stack.back()->as_transform()->clear_transform();
}
'{' transform_3d_body '}'
'{' transform_body '}'
;
/*
* transform_3d_body
* transform_body
*
* enter: matrix_3d contains some sensible value.
* exit: matrix_3d has been transformed by the parsed transformation.
* enter: TOS is some kind of EggTransform.
* exit: transform has been filled in.
*
*/
transform_3d_body:
transform_body:
empty
| 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
| transform_body translate2d
| transform_body translate3d
| transform_body rotate2d
| transform_body rotx
| transform_body roty
| transform_body rotz
| transform_body rotate3d
| transform_body scale2d
| transform_body scale3d
| transform_body uniform_scale
| transform_body matrix3
| transform_body matrix4
;
translate_3d: TRANSLATE '{' real real real '}'
translate2d:
TRANSLATE '{' real real '}'
{
DCAST(EggGroup, egg_stack.back())->add_translate(LVector3d($3, $4, $5));
egg_stack.back()->as_transform()->add_translate2d(LVector2d($3, $4));
}
;
rotx_3d: ROTX '{' real '}'
translate3d:
TRANSLATE '{' real real real '}'
{
DCAST(EggGroup, egg_stack.back())->add_rotx($3);
egg_stack.back()->as_transform()->add_translate3d(LVector3d($3, $4, $5));
}
;
roty_3d: ROTY '{' real '}'
rotate2d:
ROTATE '{' real '}'
{
DCAST(EggGroup, egg_stack.back())->add_roty($3);
egg_stack.back()->as_transform()->add_rotate2d($3);
}
;
rotz_3d: ROTZ '{' real '}'
rotx:
ROTX '{' real '}'
{
DCAST(EggGroup, egg_stack.back())->add_rotz($3);
egg_stack.back()->as_transform()->add_rotx($3);
}
;
rotate_3d: ROTATE '{' real real real real '}'
roty:
ROTY '{' real '}'
{
DCAST(EggGroup, egg_stack.back())->add_rotate($3, LVector3d($4, $5, $6));
egg_stack.back()->as_transform()->add_roty($3);
}
;
scale_3d: SCALE '{' real real real '}'
rotz:
ROTZ '{' real '}'
{
DCAST(EggGroup, egg_stack.back())->add_scale(LVecBase3d($3, $4, $5));
}
| SCALE '{' real '}'
{
DCAST(EggGroup, egg_stack.back())->add_uniform_scale($3);
egg_stack.back()->as_transform()->add_rotz($3);
}
;
matrix4_3d:
MATRIX4 '{' matrix4_3d_body '}'
rotate3d:
ROTATE '{' real real real real '}'
{
egg_stack.back()->as_transform()->add_rotate3d($3, LVector3d($4, $5, $6));
}
;
matrix4_3d_body:
scale2d:
SCALE '{' real real '}'
{
egg_stack.back()->as_transform()->add_scale2d(LVecBase2d($3, $4));
}
;
scale3d:
SCALE '{' real real real '}'
{
egg_stack.back()->as_transform()->add_scale3d(LVecBase3d($3, $4, $5));
}
;
uniform_scale:
SCALE '{' real '}'
{
egg_stack.back()->as_transform()->add_uniform_scale($3);
}
;
matrix3:
MATRIX3 '{' matrix3_body '}'
;
matrix3_body:
empty
| real real real real
real real real real
real real real real
real real real real
{
DCAST(EggGroup, egg_stack.back())->add_matrix
egg_stack.back()->as_transform()->add_matrix3
(LMatrix3d($1, $2, $3,
$4, $5, $6,
$7, $8, $9));
}
;
matrix4:
MATRIX4 '{' matrix4_body '}'
;
matrix4_body:
empty
| real real real real
real real real real
real real real real
real real real real
{
egg_stack.back()->as_transform()->add_matrix4
(LMatrix4d($1, $2, $3, $4,
$5, $6, $7, $8,
$9, $10, $11, $12,
@ -1499,74 +1572,6 @@ matrix4_3d_body:
;
/*
* transform_2d
*
* enter: TOS is EggTexture.
* exit: texture's transform matrix has been set.
*
*/
transform_2d:
TRANSFORM
{
matrix_2d = LMatrix3d::ident_mat();
}
'{' transform_2d_body '}'
{
DCAST(EggTexture, egg_stack.back())->set_transform(matrix_2d);
}
;
/*
* transform_2d_body
*
* enter: matrix contains some sensible value.
* exit: matrix has been transformed by the parsed transformation.
*
*/
transform_2d_body:
empty
| transform_2d_body matrix3_2d
| transform_2d_body translate_2d
| transform_2d_body rotate_2d
| transform_2d_body scale_2d
;
translate_2d: TRANSLATE '{' real real '}'
{
matrix_2d *= LMatrix3d::translate_mat($3, $4);
}
;
rotate_2d: ROTATE '{' real '}'
{
matrix_2d *= LMatrix3d::rotate_mat($3);
}
;
scale_2d: SCALE '{' real real '}'
{
matrix_2d *= LMatrix3d::scale_mat($3, $4);
}
;
matrix3_2d: MATRIX3 '{' matrix3_2d_body '}'
;
matrix3_2d_body:
empty
| real real real
real real real
real real real
{
matrix_2d *= LMatrix3d($1, $2, $3,
$4, $5, $6,
$7, $8, $9);
}
;
/*
* group_vertex_ref
*

View File

@ -391,6 +391,126 @@ make_polyset(EggBin *egg_bin, PandaNode *parent, const LMatrix4d *transform,
}
}
////////////////////////////////////////////////////////////////////
// Function: EggLoader::make_transform
// Access: Public, Static
// Description: Creates a TransformState object corresponding to the
// indicated EggTransform.
////////////////////////////////////////////////////////////////////
CPT(TransformState) EggLoader::
make_transform(const EggTransform *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 EggTransform::CT_translate2d:
{
LVecBase2f trans2d(LCAST(float, egg_transform->get_component_vec2(i)));
LVecBase3f trans3d(trans2d[0], trans2d[1], 0.0f);
ts = TransformState::make_pos(trans3d)->compose(ts);
}
break;
case EggTransform::CT_translate3d:
{
LVecBase3f trans3d(LCAST(float, egg_transform->get_component_vec3(i)));
ts = TransformState::make_pos(trans3d)->compose(ts);
}
break;
case EggTransform::CT_rotate2d:
{
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 EggTransform::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 EggTransform::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 EggTransform::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 EggTransform::CT_rotate3d:
{
LRotationf rot(LCAST(float, egg_transform->get_component_vec3(i)),
(float)egg_transform->get_component_number(i));
ts = TransformState::make_quat(rot)->compose(ts);
}
break;
case EggTransform::CT_scale2d:
{
LVecBase2f scale2d(LCAST(float, egg_transform->get_component_vec2(i)));
LVecBase3f scale3d(scale2d[0], scale2d[1], 1.0f);
ts = TransformState::make_scale(scale3d)->compose(ts);
}
break;
case EggTransform::CT_scale3d:
{
LVecBase3f scale3d(LCAST(float, egg_transform->get_component_vec3(i)));
ts = TransformState::make_scale(scale3d)->compose(ts);
}
break;
case EggTransform::CT_uniform_scale:
{
float scale = (float)egg_transform->get_component_number(i);
ts = TransformState::make_scale(scale)->compose(ts);
}
break;
case EggTransform::CT_matrix3:
{
LMatrix3f m(LCAST(float, egg_transform->get_component_mat3(i)));
LMatrix4f mat4(m(0, 0), m(0, 1), 0.0, m(0, 2),
m(1, 0), m(1, 1), 0.0, m(1, 2),
0.0, 0.0, 1.0, 0.0,
m(2, 0), m(2, 1), 0.0, m(2, 2));
ts = TransformState::make_mat(mat4)->compose(ts);
}
break;
case EggTransform::CT_matrix4:
{
LMatrix4f mat4(LCAST(float, egg_transform->get_component_mat4(i)));
ts = TransformState::make_mat(mat4)->compose(ts);
}
break;
case EggTransform::CT_invalid:
nassertr(false, ts);
break;
}
}
return ts;
}
////////////////////////////////////////////////////////////////////
// Function: EggLoader::show_normals
// Access: Private
@ -1183,8 +1303,7 @@ make_texture_stage(const EggTexture *egg_tex) {
}
if (egg_tex->has_uv_name() && !egg_tex->get_uv_name().empty() &&
egg_tex->get_uv_name() != string("default")) {
if (egg_tex->has_uv_name()) {
CPT(InternalName) name =
InternalName::get_texcoord_name(egg_tex->get_uv_name());
stage->set_texcoord_name(name);
@ -1725,23 +1844,26 @@ make_vertex_data(const EggRenderState *render_state,
Geom::NT_packed_dabc, Geom::C_color);
}
vector_string uv_names, tbn_names;
vertex_pool->get_uv_names(uv_names, tbn_names);
vector_string uv_names, uvw_names, tbn_names;
vertex_pool->get_uv_names(uv_names, uvw_names, tbn_names);
vector_string::const_iterator ni;
for (ni = uv_names.begin(); ni != uv_names.end(); ++ni) {
string name = (*ni);
if (name == "default") {
name = string();
}
PT(InternalName) iname = InternalName::get_texcoord_name(name);
array_format->add_column
(iname, 2, Geom::NT_float32, Geom::C_texcoord);
if (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end()) {
// This one actually represents 3-d texture coordinates.
array_format->add_column
(iname, 3, Geom::NT_float32, Geom::C_texcoord);
} else {
array_format->add_column
(iname, 2, Geom::NT_float32, Geom::C_texcoord);
}
}
for (ni = tbn_names.begin(); ni != tbn_names.end(); ++ni) {
string name = (*ni);
if (name == "default") {
name = string();
}
PT(InternalName) iname = InternalName::get_tangent_name(name);
array_format->add_column
(iname, 3, Geom::NT_float32, Geom::C_vector);
@ -1807,16 +1929,14 @@ make_vertex_data(const EggRenderState *render_state,
for (uvi = vertex->uv_begin(); uvi != vertex->uv_end(); ++uvi) {
EggVertexUV *egg_uv = (*uvi);
string name = egg_uv->get_name();
if (name == "default") {
name = string();
}
bool has_w = (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end());
PT(InternalName) iname = InternalName::get_texcoord_name(name);
EggMorphTexCoordList::const_iterator mti;
for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
slider_names.insert((*mti).get_name());
record_morph(anim_array_format, character_maker, (*mti).get_name(),
iname, 2);
iname, has_w ? 3 : 2);
}
}
}
@ -1910,23 +2030,20 @@ make_vertex_data(const EggRenderState *render_state,
EggVertex::const_uv_iterator uvi;
for (uvi = vertex->uv_begin(); uvi != vertex->uv_end(); ++uvi) {
EggVertexUV *egg_uv = (*uvi);
TexCoordd orig_uv = egg_uv->get_uv();
TexCoordd uv = egg_uv->get_uv();
TexCoord3d orig_uvw = egg_uv->get_uvw();
TexCoord3d uvw = egg_uv->get_uvw();
string name = egg_uv->get_name();
if (name == "default") {
name = string();
}
PT(InternalName) iname = InternalName::get_texcoord_name(name);
gvw.set_column(iname);
BakeInUVs::const_iterator buv = render_state->_bake_in_uvs.find(iname);
if (buv != render_state->_bake_in_uvs.end()) {
// If we are to bake in a texture matrix, do so now.
uv = uv * (*buv).second->get_transform();
uvw = uvw * (*buv).second->get_transform();
}
gvw.set_data2f(LCAST(float, uv));
gvw.set_data3f(LCAST(float, uvw));
if (is_dynamic) {
EggMorphTexCoordList::const_iterator mti;
@ -1935,13 +2052,13 @@ make_vertex_data(const EggRenderState *render_state,
CPT(InternalName) delta_name =
InternalName::get_morph(iname, morph.get_name());
gvw.set_column(delta_name);
TexCoordd duv = morph.get_offset();
TexCoord3d duvw = morph.get_offset();
if (buv != render_state->_bake_in_uvs.end()) {
TexCoordd new_uv = orig_uv + duv;
duv = (new_uv * (*buv).second->get_transform()) - uv;
TexCoord3d new_uvw = orig_uvw + duvw;
duvw = (new_uvw * (*buv).second->get_transform()) - uvw;
}
gvw.add_data2f(LCAST(float, duv));
gvw.add_data3f(LCAST(float, duvw));
}
}
@ -2994,91 +3111,6 @@ do_expand_object_type(EggGroup *egg_group, const pset<string> &expanded,
return true;
}
////////////////////////////////////////////////////////////////////
// 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;
}
////////////////////////////////////////////////////////////////////
// Function: EggLoader::get_combine_mode
// Access: Private, Static

View File

@ -38,7 +38,7 @@
#include "textureStage.h"
#include "texGenAttrib.h"
#include "colorBlendAttrib.h"
#include "eggTransform3d.h"
#include "eggTransform.h"
#include "geomVertexData.h"
#include "geomPrimitive.h"
@ -80,6 +80,8 @@ public:
const LMatrix4d *transform, bool is_dynamic,
CharacterMaker *character_maker);
static CPT(TransformState) make_transform(const EggTransform *egg_transform);
private:
class TextureDef {
public:
@ -185,8 +187,6 @@ private:
const pvector<string> &expanded_history,
const string &object_type);
CPT(TransformState) make_transform(const EggTransform3d *egg_transform);
static TextureStage::CombineMode
get_combine_mode(const EggTexture *egg_tex,
EggTexture::CombineChannel channel);

View File

@ -536,24 +536,7 @@ CPT(RenderAttrib) EggRenderState::
apply_tex_mat(CPT(RenderAttrib) tex_mat_attrib,
TextureStage *stage, const EggTexture *egg_tex) {
if (egg_tex->has_transform()) {
const LMatrix3d &tex_mat = egg_tex->get_transform();
LMatrix4f mat4(tex_mat(0, 0), tex_mat(0, 1), 0.0f, tex_mat(0, 2),
tex_mat(1, 0), tex_mat(1, 1), 0.0f, tex_mat(1, 2),
0.0f, 0.0f, 1.0f, 0.0f,
tex_mat(2, 0), tex_mat(2, 1), 0.0f, tex_mat(2, 2));
CPT(TransformState) transform;
LVecBase3f scale, shear, hpr, translate;
if (decompose_matrix(mat4, scale, shear, hpr, translate)) {
// If the texture matrix can be represented componentwise, do
// so.
transform = TransformState::make_pos_hpr_scale_shear
(translate, hpr, scale, shear);
} else {
// Otherwise, make a matrix transform.
transform = TransformState::make_mat(mat4);
}
CPT(TransformState) transform = EggLoader::make_transform(egg_tex);
if (tex_mat_attrib == (const RenderAttrib *)NULL) {
tex_mat_attrib = TexMatrixAttrib::make();

View File

@ -77,7 +77,7 @@ private:
EggLoader &_loader;
typedef pvector<const TextureDef *> TexMatTextures;
typedef pmap<LMatrix3d, TexMatTextures> TexMatTransforms;
typedef pmap<LMatrix4d, TexMatTextures> TexMatTransforms;
typedef pmap<CPT(InternalName), TexMatTransforms> TexMats;
};

View File

@ -53,12 +53,14 @@
typedef LPoint3f Vertexf;
typedef LVector3f Normalf;
typedef LPoint2f TexCoordf;
typedef LPoint3f TexCoord3f;
typedef LVecBase4f Colorf;
typedef LVecBase3f RGBColorf;
typedef LPoint3d Vertexd;
typedef LVector3d Normald;
typedef LPoint2d TexCoordd;
typedef LPoint3d TexCoord3d;
typedef LVecBase4d Colord;
typedef LVecBase3d RGBColord;

View File

@ -429,13 +429,13 @@ apply_node_properties(EggGroup *egg_group, PandaNode *node) {
const LQuaternionf &quat = transform->get_quat();
const LVecBase3f &pos = transform->get_pos();
if (!scale.almost_equal(LVecBase3f(1.0f, 1.0f, 1.0f))) {
egg_group->add_scale(LCAST(double, scale));
egg_group->add_scale3d(LCAST(double, scale));
}
if (!quat.is_identity()) {
egg_group->add_rotate(LCAST(double, quat));
egg_group->add_rotate3d(LCAST(double, quat));
}
if (!pos.almost_equal(LVecBase3f::zero())) {
egg_group->add_translate(LCAST(double, pos));
egg_group->add_translate3d(LCAST(double, pos));
}
} else if (transform->has_mat()) {

View File

@ -161,7 +161,7 @@ set_transform(const FltBead *flt_bead, EggGroup *egg_group) {
const FltTransformTranslate *trans;
DCAST_INTO_V(trans, step);
if (!trans->get_delta().almost_equal(LVector3d::zero())) {
egg_group->add_translate(trans->get_delta());
egg_group->add_translate3d(trans->get_delta());
}
} else if (step->is_exact_type(FltTransformRotateAboutPoint::get_class_type())) {
@ -169,12 +169,12 @@ set_transform(const FltBead *flt_bead, EggGroup *egg_group) {
DCAST_INTO_V(rap, step);
if (!IS_NEARLY_ZERO(rap->get_angle())) {
if (!rap->get_center().almost_equal(LVector3d::zero())) {
egg_group->add_translate(-rap->get_center());
egg_group->add_translate3d(-rap->get_center());
}
LVector3d axis = LCAST(double, rap->get_axis());
egg_group->add_rotate(rap->get_angle(), axis);
egg_group->add_rotate3d(rap->get_angle(), axis);
if (!rap->get_center().almost_equal(LVector3d::zero())) {
egg_group->add_translate(rap->get_center());
egg_group->add_translate3d(rap->get_center());
}
}
@ -183,12 +183,12 @@ set_transform(const FltBead *flt_bead, EggGroup *egg_group) {
DCAST_INTO_V(rae, step);
if (!IS_NEARLY_ZERO(rae->get_angle())) {
if (!rae->get_point_a().almost_equal(LVector3d::zero())) {
egg_group->add_translate(-rae->get_point_a());
egg_group->add_translate3d(-rae->get_point_a());
}
LVector3d axis = rae->get_point_b() - rae->get_point_a();
egg_group->add_rotate(rae->get_angle(), axis);
egg_group->add_rotate3d(rae->get_angle(), axis);
if (!rae->get_point_a().almost_equal(LVector3d::zero())) {
egg_group->add_translate(rae->get_point_a());
egg_group->add_translate3d(rae->get_point_a());
}
}
@ -198,12 +198,12 @@ set_transform(const FltBead *flt_bead, EggGroup *egg_group) {
if (!scale->get_scale().almost_equal(LVecBase3f(1.0f, 1.0f, 1.0f))) {
if (scale->has_center() &&
!scale->get_center().almost_equal(LVector3d::zero())) {
egg_group->add_translate(-scale->get_center());
egg_group->add_translate3d(-scale->get_center());
}
egg_group->add_scale(LCAST(double, scale->get_scale()));
egg_group->add_scale3d(LCAST(double, scale->get_scale()));
if (scale->has_center() &&
!scale->get_center().almost_equal(LVector3d::zero())) {
egg_group->add_translate(scale->get_center());
egg_group->add_translate3d(scale->get_center());
}
}
@ -212,7 +212,7 @@ set_transform(const FltBead *flt_bead, EggGroup *egg_group) {
DCAST_INTO_V(put, step);
if (!put->get_from_origin().almost_equal(LVector3d::zero())) {
egg_group->add_translate(-put->get_from_origin());
egg_group->add_translate3d(-put->get_from_origin());
}
LQuaterniond q1, q2;
look_at(q1, put->get_from_align() - put->get_from_origin(),
@ -225,10 +225,10 @@ set_transform(const FltBead *flt_bead, EggGroup *egg_group) {
LQuaterniond q = invert(q1) * q2;
if (!q.is_identity()) {
egg_group->add_rotate(q);
egg_group->add_rotate3d(q);
}
if (!put->get_to_origin().almost_equal(LVector3d::zero())) {
egg_group->add_translate(put->get_to_origin());
egg_group->add_translate3d(put->get_to_origin());
}
} else {

View File

@ -317,43 +317,33 @@ convert_group(EggGroup *egg_group, FltBead *flt_node,
// flt bead.
////////////////////////////////////////////////////////////////////
void EggToFlt::
apply_transform(EggTransform3d *egg_transform, FltBead *flt_node) {
apply_transform(EggTransform *egg_transform, FltBead *flt_node) {
flt_node->clear_transform();
bool components_ok = true;
int num_components = egg_transform->get_num_components();
for (int i = num_components - 1; i >= 0 && components_ok; i--) {
switch (egg_transform->get_component_type(i)) {
case EggTransform3d::CT_translate:
case EggTransform::CT_translate2d:
{
FltTransformTranslate *translate =
new FltTransformTranslate(_flt_header);
translate->set(LPoint3d::zero(), egg_transform->get_component_vector(i));
LVector2d v2 = egg_transform->get_component_vec2(i);
translate->set(LPoint3d::zero(), LVector3d(v2[0], v2[1], 0.0));
flt_node->add_transform_step(translate);
}
break;
case EggTransform3d::CT_rotx:
case EggTransform::CT_translate3d:
{
FltTransformRotateAboutEdge *rotate =
new FltTransformRotateAboutEdge(_flt_header);
rotate->set(LPoint3d::zero(), LPoint3d(1.0, 0.0, 0.0),
egg_transform->get_component_number(i));
flt_node->add_transform_step(rotate);
FltTransformTranslate *translate =
new FltTransformTranslate(_flt_header);
translate->set(LPoint3d::zero(), egg_transform->get_component_vec3(i));
flt_node->add_transform_step(translate);
}
break;
case EggTransform3d::CT_roty:
{
FltTransformRotateAboutEdge *rotate =
new FltTransformRotateAboutEdge(_flt_header);
rotate->set(LPoint3d::zero(), LPoint3d(0.0, 1.0, 0.0),
egg_transform->get_component_number(i));
flt_node->add_transform_step(rotate);
}
break;
case EggTransform3d::CT_rotz:
case EggTransform::CT_rotate2d:
{
FltTransformRotateAboutEdge *rotate =
new FltTransformRotateAboutEdge(_flt_header);
@ -363,25 +353,64 @@ apply_transform(EggTransform3d *egg_transform, FltBead *flt_node) {
}
break;
case EggTransform3d::CT_rotate:
case EggTransform::CT_rotx:
{
FltTransformRotateAboutEdge *rotate =
new FltTransformRotateAboutEdge(_flt_header);
rotate->set(LPoint3d::zero(), egg_transform->get_component_vector(i),
rotate->set(LPoint3d::zero(), LPoint3d(1.0, 0.0, 0.0),
egg_transform->get_component_number(i));
flt_node->add_transform_step(rotate);
}
break;
case EggTransform3d::CT_scale:
case EggTransform::CT_roty:
{
FltTransformRotateAboutEdge *rotate =
new FltTransformRotateAboutEdge(_flt_header);
rotate->set(LPoint3d::zero(), LPoint3d(0.0, 1.0, 0.0),
egg_transform->get_component_number(i));
flt_node->add_transform_step(rotate);
}
break;
case EggTransform::CT_rotz:
{
FltTransformRotateAboutEdge *rotate =
new FltTransformRotateAboutEdge(_flt_header);
rotate->set(LPoint3d::zero(), LPoint3d(0.0, 0.0, 1.0),
egg_transform->get_component_number(i));
flt_node->add_transform_step(rotate);
}
break;
case EggTransform::CT_rotate3d:
{
FltTransformRotateAboutEdge *rotate =
new FltTransformRotateAboutEdge(_flt_header);
rotate->set(LPoint3d::zero(), egg_transform->get_component_vec3(i),
egg_transform->get_component_number(i));
flt_node->add_transform_step(rotate);
}
break;
case EggTransform::CT_scale2d:
{
FltTransformScale *scale = new FltTransformScale(_flt_header);
scale->set(LPoint3d::zero(), LCAST(float, egg_transform->get_component_vector(i)));
LVector2d v2 = egg_transform->get_component_vec2(i);
scale->set(LPoint3d::zero(), LVector3f(v2[0], v2[1], 1.0f));
flt_node->add_transform_step(scale);
}
break;
case EggTransform3d::CT_uniform_scale:
case EggTransform::CT_scale3d:
{
FltTransformScale *scale = new FltTransformScale(_flt_header);
scale->set(LPoint3d::zero(), LCAST(float, egg_transform->get_component_vec3(i)));
flt_node->add_transform_step(scale);
}
break;
case EggTransform::CT_uniform_scale:
{
FltTransformScale *scale = new FltTransformScale(_flt_header);
float factor = (float)egg_transform->get_component_number(i);
@ -390,11 +419,25 @@ apply_transform(EggTransform3d *egg_transform, FltBead *flt_node) {
}
break;
case EggTransform3d::CT_matrix:
case EggTransform::CT_matrix3:
{
FltTransformGeneralMatrix *matrix =
new FltTransformGeneralMatrix(_flt_header);
matrix->set_matrix(egg_transform->get_component_matrix(i));
const LMatrix3d &m = egg_transform->get_component_mat3(i);
LMatrix4d mat4(m(0, 0), m(0, 1), 0.0, m(0, 2),
m(1, 0), m(1, 1), 0.0, m(1, 2),
0.0, 0.0, 1.0, 0.0,
m(2, 0), m(2, 1), 0.0, m(2, 2));
matrix->set_matrix(mat4);
flt_node->add_transform_step(matrix);
}
break;
case EggTransform::CT_matrix4:
{
FltTransformGeneralMatrix *matrix =
new FltTransformGeneralMatrix(_flt_header);
matrix->set_matrix(egg_transform->get_component_mat4(i));
flt_node->add_transform_step(matrix);
}
break;

View File

@ -32,7 +32,7 @@ class EggGroup;
class EggVertex;
class EggPrimitive;
class EggTexture;
class EggTransform3d;
class EggTransform;
class FltVertex;
class FltBead;
class FltTexture;
@ -56,7 +56,7 @@ private:
FltGeometry::BillboardType billboard);
void convert_group(EggGroup *egg_group, FltBead *flt_node,
FltGeometry::BillboardType billboard);
void apply_transform(EggTransform3d *egg_transform, FltBead *flt_node);
void apply_transform(EggTransform *egg_transform, FltBead *flt_node);
void apply_egg_syntax(const string &egg_syntax, FltRecord *flt_record);
FltVertex *get_flt_vertex(EggVertex *egg_vertex, EggNode *context);
FltTexture *get_flt_texture(EggTexture *egg_texture);

View File

@ -86,8 +86,8 @@ from_egg(EggFile *egg_file, EggData *data, EggTexture *egg_tex) {
_egg_data = data;
_tref_name = egg_tex->get_name();
if (_egg_tex->has_transform()) {
_tex_mat = _egg_tex->get_transform();
if (_egg_tex->has_transform() && egg_tex->is_transform_2d()) {
_tex_mat = _egg_tex->get_transform_2d();
if (!_inv_tex_mat.invert_from(_tex_mat)) {
_inv_tex_mat = LMatrix3d::ident_mat();
}

View File

@ -60,8 +60,8 @@ set_from_egg(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
if (egg_prim->has_texture()) {
// Check if there's a texture matrix on the texture.
EggTexture *egg_tex = egg_prim->get_texture();
if (egg_tex->has_transform()) {
uv = uv * egg_tex->get_transform();
if (egg_tex->has_transform() && egg_tex->is_transform_2d()) {
uv = uv * egg_tex->get_transform_2d();
}
}