Panda3D
eggTransform.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file eggTransform.cxx
10  * @author drose
11  * @date 2002-06-21
12  */
13 
14 #include "eggTransform.h"
15 
16 
17 /**
18  *
19  */
20 EggTransform::
21 EggTransform() :
22  _is_transform_2d(true),
23  _transform(LMatrix4d::ident_mat())
24 {
25 }
26 
27 /**
28  *
29  */
30 EggTransform::
31 EggTransform(const EggTransform &copy) :
32  _is_transform_2d(copy._is_transform_2d),
33  _components(copy._components),
34  _transform(copy._transform)
35 {
36 }
37 
38 /**
39  *
40  */
41 EggTransform &EggTransform::
42 operator = (const EggTransform &copy) {
43  _is_transform_2d = copy._is_transform_2d;
44  _components = copy._components;
45  _transform = copy._transform;
46  return *this;
47 }
48 
49 /**
50  *
51  */
52 EggTransform::
53 ~EggTransform() {
54 }
55 
56 /**
57  * Appends a 2-d translation operation to the current transform.
58  */
59 void EggTransform::
60 add_translate2d(const LVector2d &translate) {
61  _components.push_back(Component(CT_translate2d));
62  _components.back()._vec2 = new LVecBase2d(translate);
63  _transform *= LMatrix4d::translate_mat(LVector3d(translate[0], translate[1], 0.0));
64  transform_changed();
65 }
66 
67 /**
68  * Appends a 3-d translation operation to the current transform.
69  */
70 void EggTransform::
71 add_translate3d(const LVector3d &translate) {
72  _is_transform_2d = false;
73  _components.push_back(Component(CT_translate3d));
74  _components.back()._vec3 = new LVecBase3d(translate);
75  _transform *= LMatrix4d::translate_mat(translate);
76  transform_changed();
77 }
78 
79 /**
80  * Appends a 2-d rotation to the current transform. The rotation angle is
81  * specified in degrees counterclockwise about the origin.
82  */
83 void EggTransform::
84 add_rotate2d(double angle) {
85  _components.push_back(Component(CT_rotate2d, angle));
86  _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 0.0, 1.0));
87  transform_changed();
88 }
89 
90 /**
91  * Appends a rotation about the X axis to the current transform. The rotation
92  * angle is specified in degrees counterclockwise about the axis.
93  */
94 void EggTransform::
95 add_rotx(double angle) {
96  _is_transform_2d = false;
97  _components.push_back(Component(CT_rotx, angle));
98  _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(1.0, 0.0, 0.0));
99  transform_changed();
100 }
101 
102 /**
103  * Appends a rotation about the Y axis to the current transform. The rotation
104  * angle is specified in degrees counterclockwise about the axis.
105  */
106 void EggTransform::
107 add_roty(double angle) {
108  _is_transform_2d = false;
109  _components.push_back(Component(CT_roty, angle));
110  _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 1.0, 0.0));
111  transform_changed();
112 }
113 
114 /**
115  * Appends a rotation about the Z axis to the current transform. The rotation
116  * angle is specified in degrees counterclockwise about the axis.
117  */
118 void EggTransform::
119 add_rotz(double angle) {
120  _is_transform_2d = false;
121  _components.push_back(Component(CT_rotz, angle));
122  _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 0.0, 1.0));
123  transform_changed();
124 }
125 
126 /**
127  * Appends a 3-d rotation about an arbitrary axis to the current transform.
128  * The rotation angle is specified in degrees counterclockwise about the axis.
129  */
130 void EggTransform::
131 add_rotate3d(double angle, const LVector3d &axis) {
132  _is_transform_2d = false;
133  LVector3d normaxis = normalize(axis);
134  _components.push_back(Component(CT_rotate3d, angle));
135  _components.back()._vec3 = new LVecBase3d(normaxis);
136  _transform *= LMatrix4d::rotate_mat(angle, normaxis);
137  transform_changed();
138 }
139 
140 /**
141  * Appends an arbitrary 3-d rotation to the current transform, expressed as a
142  * quaternion. This is converted to axis-angle notation for the egg file.
143  */
144 void EggTransform::
145 add_rotate3d(const LQuaterniond &quat) {
146  _is_transform_2d = false;
147  add_rotate3d(quat.get_angle(), quat.get_axis());
148  transform_changed();
149 }
150 
151 /**
152  * Appends a possibly non-uniform scale to the current transform.
153  */
154 void EggTransform::
155 add_scale2d(const LVecBase2d &scale) {
156  _is_transform_2d = false;
157  _components.push_back(Component(CT_scale2d));
158  _components.back()._vec2 = new LVecBase2d(scale);
159  _transform *= LMatrix4d::scale_mat(LVecBase3d(scale[0], scale[1], 1.0));
160  transform_changed();
161 }
162 
163 /**
164  * Appends a possibly non-uniform scale to the current transform.
165  */
166 void EggTransform::
167 add_scale3d(const LVecBase3d &scale) {
168  _is_transform_2d = false;
169  _components.push_back(Component(CT_scale3d));
170  _components.back()._vec3 = new LVecBase3d(scale);
171  _transform *= LMatrix4d::scale_mat(scale);
172  transform_changed();
173 }
174 
175 /**
176  * Appends a uniform scale to the current transform.
177  */
178 void EggTransform::
179 add_uniform_scale(double scale) {
180  _components.push_back(Component(CT_uniform_scale, scale));
181  _transform *= LMatrix4d::scale_mat(scale);
182  transform_changed();
183 }
184 
185 /**
186  * Writes the transform to the indicated stream in Egg format.
187  */
188 void EggTransform::
189 write(std::ostream &out, int indent_level, const std::string &label) const {
190  indent(out, indent_level) << label << " {\n";
191 
192  int num_components = get_num_components();
193  for (int i = 0; i < num_components; i++) {
194  switch (get_component_type(i)) {
195  case CT_translate2d:
196  indent(out, indent_level + 2)
197  << "<Translate> { " << get_component_vec2(i) << " }\n";
198  break;
199 
200  case CT_translate3d:
201  indent(out, indent_level + 2)
202  << "<Translate> { " << get_component_vec3(i) << " }\n";
203  break;
204 
205  case CT_rotate2d:
206  indent(out, indent_level + 2)
207  << "<Rotate> { " << get_component_number(i) << " }\n";
208  break;
209 
210  case CT_rotx:
211  indent(out, indent_level + 2)
212  << "<RotX> { " << get_component_number(i) << " }\n";
213  break;
214 
215  case CT_roty:
216  indent(out, indent_level + 2)
217  << "<RotY> { " << get_component_number(i) << " }\n";
218  break;
219 
220  case CT_rotz:
221  indent(out, indent_level + 2)
222  << "<RotZ> { " << get_component_number(i) << " }\n";
223  break;
224 
225  case CT_rotate3d:
226  indent(out, indent_level + 2)
227  << "<Rotate> { " << get_component_number(i) << " "
228  << get_component_vec3(i) << " }\n";
229  break;
230 
231  case CT_scale2d:
232  indent(out, indent_level + 2)
233  << "<Scale> { " << get_component_vec2(i) << " }\n";
234  break;
235 
236  case CT_scale3d:
237  indent(out, indent_level + 2)
238  << "<Scale> { " << get_component_vec3(i) << " }\n";
239  break;
240 
241  case CT_uniform_scale:
242  indent(out, indent_level + 2)
243  << "<Scale> { " << get_component_number(i) << " }\n";
244  break;
245 
246  case CT_matrix3:
247  indent(out, indent_level + 2) << "<Matrix3> {\n";
248  get_component_mat3(i).write(out, indent_level + 4);
249  indent(out, indent_level + 2) << "}\n";
250  break;
251 
252  case CT_matrix4:
253  indent(out, indent_level + 2) << "<Matrix4> {\n";
254  get_component_mat4(i).write(out, indent_level + 4);
255  indent(out, indent_level + 2) << "}\n";
256  break;
257 
258  case CT_invalid:
259  nassertv(false);
260  break;
261  }
262  }
263 
264  indent(out, indent_level) << "}\n";
265 }
266 
267 /**
268  * Resets the transform to empty without calling transform_changed().
269  */
270 void EggTransform::
271 internal_clear_transform() {
272  _is_transform_2d = true;
273  _components.clear();
274  _transform = LMatrix4d::ident_mat();
275 }
276 
277 /**
278  * Appends an arbitrary 4x4 matrix to the current transform, without calling
279  * transform_changed().
280  */
281 void EggTransform::
282 internal_add_matrix(const LMatrix3d &mat) {
283  _components.push_back(Component(CT_matrix3));
284  _components.back()._mat3 = new LMatrix3d(mat);
285  LMatrix4d mat4(mat(0, 0), mat(0, 1), 0.0, mat(0, 2),
286  mat(1, 0), mat(1, 1), 0.0, mat(1, 2),
287  0.0, 0.0, 1.0, 0.0,
288  mat(2, 0), mat(2, 1), 0.0, mat(2, 2));
289  _transform *= mat4;
290 }
291 
292 /**
293  * Appends an arbitrary 4x4 matrix to the current transform, without calling
294  * transform_changed().
295  */
296 void EggTransform::
297 internal_add_matrix(const LMatrix4d &mat) {
298  _is_transform_2d = false;
299  _components.push_back(Component(CT_matrix4));
300  _components.back()._mat4 = new LMatrix4d(mat);
301  _transform *= mat;
302 }
303 
304 /**
305  * This virtual method is called whenever the transform is changed; it is
306  * intended to provide a hook for derived classes (e.g. EggGroup) to update
307  * their internal cache appropriately.
308  */
309 void EggTransform::
310 transform_changed() {
311 }
const LVecBase3d & get_component_vec3(int n) const
Returns the 3-component vector associated with the nth component.
Definition: eggTransform.I:272
double get_component_number(int n) const
Returns the solitary number associated with the nth component.
Definition: eggTransform.I:249
void add_rotate3d(double angle, const LVector3d &axis)
Appends a 3-d rotation about an arbitrary axis to the current transform.
void add_translate2d(const LVector2d &translate)
Appends a 2-d translation operation to the current transform.
void add_rotx(double angle)
Appends a rotation about the X axis to the current transform.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_roty(double angle)
Appends a rotation about the Y axis to the current transform.
void write(std::ostream &out, int indent_level, const std::string &label) const
Writes the transform to the indicated stream in Egg format.
int get_num_components() const
Returns the number of components that make up the transform.
Definition: eggTransform.I:229
const LVecBase2d & get_component_vec2(int n) const
Returns the 2-component vector associated with the nth component.
Definition: eggTransform.I:260
ComponentType get_component_type(int n) const
Returns the type of the nth component.
Definition: eggTransform.I:237
void add_uniform_scale(double scale)
Appends a uniform scale to the current transform.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
void add_rotate2d(double angle)
Appends a 2-d rotation to the current transform.
void add_rotz(double angle)
Appends a rotation about the Z axis to the current transform.
void add_translate3d(const LVector3d &translate)
Appends a 3-d translation operation to the current transform.
const LMatrix3d & get_component_mat3(int n) const
Returns the 3x3 matrix associated with the nth component.
Definition: eggTransform.I:283
void add_scale3d(const LVecBase3d &scale)
Appends a possibly non-uniform scale to the current transform.
const LMatrix4d & get_component_mat4(int n) const
Returns the 4x4 matrix associated with the nth component.
Definition: eggTransform.I:294
This represents the <Transform> entry of a group or texture node: a list of component transform opera...
Definition: eggTransform.h:29
void add_scale2d(const LVecBase2d &scale)
Appends a possibly non-uniform scale to the current transform.