Panda3D
 All Classes Functions Variables Enumerations
eggTransform.cxx
1 // Filename: eggTransform.cxx
2 // Created by: drose (21Jun02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "eggTransform.h"
16 
17 
18 ////////////////////////////////////////////////////////////////////
19 // Function: EggTransform::Constructor
20 // Access: Public
21 // Description:
22 ////////////////////////////////////////////////////////////////////
23 EggTransform::
24 EggTransform() :
25  _is_transform_2d(true),
26  _transform(LMatrix4d::ident_mat())
27 {
28 }
29 
30 ////////////////////////////////////////////////////////////////////
31 // Function: EggTransform::Copy Constructor
32 // Access: Public
33 // Description:
34 ////////////////////////////////////////////////////////////////////
35 EggTransform::
36 EggTransform(const EggTransform &copy) :
37  _is_transform_2d(copy._is_transform_2d),
38  _components(copy._components),
39  _transform(copy._transform)
40 {
41 }
42 
43 ////////////////////////////////////////////////////////////////////
44 // Function: EggTransform::Copy assignment operator
45 // Access: Public
46 // Description:
47 ////////////////////////////////////////////////////////////////////
48 EggTransform &EggTransform::
49 operator = (const EggTransform &copy) {
50  _is_transform_2d = copy._is_transform_2d;
51  _components = copy._components;
52  _transform = copy._transform;
53  return *this;
54 }
55 
56 ////////////////////////////////////////////////////////////////////
57 // Function: EggTransform::Destructor
58 // Access: Public, Virtual
59 // Description:
60 ////////////////////////////////////////////////////////////////////
61 EggTransform::
62 ~EggTransform() {
63 }
64 
65 ////////////////////////////////////////////////////////////////////
66 // Function: EggTransform::add_translate2d
67 // Access: Public
68 // Description: Appends a 2-d translation operation to the current
69 // transform.
70 ////////////////////////////////////////////////////////////////////
71 void EggTransform::
72 add_translate2d(const LVector2d &translate) {
73  _components.push_back(Component(CT_translate2d));
74  _components.back()._vec2 = new LVecBase2d(translate);
75  _transform *= LMatrix4d::translate_mat(LVector3d(translate[0], translate[1], 0.0));
76  transform_changed();
77 }
78 
79 ////////////////////////////////////////////////////////////////////
80 // Function: EggTransform::add_translate3d
81 // Access: Public
82 // Description: Appends a 3-d translation operation to the current
83 // transform.
84 ////////////////////////////////////////////////////////////////////
85 void EggTransform::
86 add_translate3d(const LVector3d &translate) {
87  _is_transform_2d = false;
88  _components.push_back(Component(CT_translate3d));
89  _components.back()._vec3 = new LVecBase3d(translate);
90  _transform *= LMatrix4d::translate_mat(translate);
91  transform_changed();
92 }
93 
94 ////////////////////////////////////////////////////////////////////
95 // Function: EggTransform::add_rotate2d
96 // Access: Public
97 // Description: Appends a 2-d rotation to the current transform. The
98 // rotation angle is specified in degrees
99 // counterclockwise about the origin.
100 ////////////////////////////////////////////////////////////////////
101 void EggTransform::
102 add_rotate2d(double angle) {
103  _components.push_back(Component(CT_rotate2d, angle));
104  _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 0.0, 1.0));
105  transform_changed();
106 }
107 
108 ////////////////////////////////////////////////////////////////////
109 // Function: EggTransform::add_rotx
110 // Access: Public
111 // Description: Appends a rotation about the X axis to the current
112 // transform. The rotation angle is specified in
113 // degrees counterclockwise about the axis.
114 ////////////////////////////////////////////////////////////////////
115 void EggTransform::
116 add_rotx(double angle) {
117  _is_transform_2d = false;
118  _components.push_back(Component(CT_rotx, angle));
119  _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(1.0, 0.0, 0.0));
120  transform_changed();
121 }
122 
123 ////////////////////////////////////////////////////////////////////
124 // Function: EggTransform::add_roty
125 // Access: Public
126 // Description: Appends a rotation about the Y axis to the current
127 // transform. The rotation angle is specified in
128 // degrees counterclockwise about the axis.
129 ////////////////////////////////////////////////////////////////////
130 void EggTransform::
131 add_roty(double angle) {
132  _is_transform_2d = false;
133  _components.push_back(Component(CT_roty, angle));
134  _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 1.0, 0.0));
135  transform_changed();
136 }
137 
138 ////////////////////////////////////////////////////////////////////
139 // Function: EggTransform::add_rotz
140 // Access: Public
141 // Description: Appends a rotation about the Z axis to the current
142 // transform. The rotation angle is specified in
143 // degrees counterclockwise about the axis.
144 ////////////////////////////////////////////////////////////////////
145 void EggTransform::
146 add_rotz(double angle) {
147  _is_transform_2d = false;
148  _components.push_back(Component(CT_rotz, angle));
149  _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 0.0, 1.0));
150  transform_changed();
151 }
152 
153 ////////////////////////////////////////////////////////////////////
154 // Function: EggTransform::add_rotate3d
155 // Access: Public
156 // Description: Appends a 3-d rotation about an arbitrary axis to the
157 // current transform. The rotation angle is specified
158 // in degrees counterclockwise about the axis.
159 ////////////////////////////////////////////////////////////////////
160 void EggTransform::
161 add_rotate3d(double angle, const LVector3d &axis) {
162  _is_transform_2d = false;
163  LVector3d normaxis = normalize(axis);
164  _components.push_back(Component(CT_rotate3d, angle));
165  _components.back()._vec3 = new LVecBase3d(normaxis);
166  _transform *= LMatrix4d::rotate_mat(angle, normaxis);
167  transform_changed();
168 }
169 
170 ////////////////////////////////////////////////////////////////////
171 // Function: EggTransform::add_rotate3d
172 // Access: Public
173 // Description: Appends an arbitrary 3-d rotation to the current
174 // transform, expressed as a quaternion. This is
175 // converted to axis-angle notation for the egg file.
176 ////////////////////////////////////////////////////////////////////
177 void EggTransform::
179  _is_transform_2d = false;
180  add_rotate3d(quat.get_angle(), quat.get_axis());
181  transform_changed();
182 }
183 
184 ////////////////////////////////////////////////////////////////////
185 // Function: EggTransform::add_scale2d
186 // Access: Public
187 // Description: Appends a possibly non-uniform scale to the current
188 // transform.
189 ////////////////////////////////////////////////////////////////////
190 void EggTransform::
191 add_scale2d(const LVecBase2d &scale) {
192  _is_transform_2d = false;
193  _components.push_back(Component(CT_scale2d));
194  _components.back()._vec2 = new LVecBase2d(scale);
195  _transform *= LMatrix4d::scale_mat(LVecBase3d(scale[0], scale[1], 1.0));
196  transform_changed();
197 }
198 
199 ////////////////////////////////////////////////////////////////////
200 // Function: EggTransform::add_scale3d
201 // Access: Public
202 // Description: Appends a possibly non-uniform scale to the current
203 // transform.
204 ////////////////////////////////////////////////////////////////////
205 void EggTransform::
206 add_scale3d(const LVecBase3d &scale) {
207  _is_transform_2d = false;
208  _components.push_back(Component(CT_scale3d));
209  _components.back()._vec3 = new LVecBase3d(scale);
210  _transform *= LMatrix4d::scale_mat(scale);
211  transform_changed();
212 }
213 
214 ////////////////////////////////////////////////////////////////////
215 // Function: EggTransform::add_uniform_scale
216 // Access: Public
217 // Description: Appends a uniform scale to the current transform.
218 ////////////////////////////////////////////////////////////////////
219 void EggTransform::
220 add_uniform_scale(double scale) {
221  _components.push_back(Component(CT_uniform_scale, scale));
222  _transform *= LMatrix4d::scale_mat(scale);
223  transform_changed();
224 }
225 
226 ////////////////////////////////////////////////////////////////////
227 // Function: EggTransform::write
228 // Access: Public
229 // Description: Writes the transform to the indicated stream in Egg
230 // format.
231 ////////////////////////////////////////////////////////////////////
232 void EggTransform::
233 write(ostream &out, int indent_level, const string &label) const {
234  indent(out, indent_level) << label << " {\n";
235 
236  int num_components = get_num_components();
237  for (int i = 0; i < num_components; i++) {
238  switch (get_component_type(i)) {
239  case CT_translate2d:
240  indent(out, indent_level + 2)
241  << "<Translate> { " << get_component_vec2(i) << " }\n";
242  break;
243 
244  case CT_translate3d:
245  indent(out, indent_level + 2)
246  << "<Translate> { " << get_component_vec3(i) << " }\n";
247  break;
248 
249  case CT_rotate2d:
250  indent(out, indent_level + 2)
251  << "<Rotate> { " << get_component_number(i) << " }\n";
252  break;
253 
254  case CT_rotx:
255  indent(out, indent_level + 2)
256  << "<RotX> { " << get_component_number(i) << " }\n";
257  break;
258 
259  case CT_roty:
260  indent(out, indent_level + 2)
261  << "<RotY> { " << get_component_number(i) << " }\n";
262  break;
263 
264  case CT_rotz:
265  indent(out, indent_level + 2)
266  << "<RotZ> { " << get_component_number(i) << " }\n";
267  break;
268 
269  case CT_rotate3d:
270  indent(out, indent_level + 2)
271  << "<Rotate> { " << get_component_number(i) << " "
272  << get_component_vec3(i) << " }\n";
273  break;
274 
275  case CT_scale2d:
276  indent(out, indent_level + 2)
277  << "<Scale> { " << get_component_vec2(i) << " }\n";
278  break;
279 
280  case CT_scale3d:
281  indent(out, indent_level + 2)
282  << "<Scale> { " << get_component_vec3(i) << " }\n";
283  break;
284 
285  case CT_uniform_scale:
286  indent(out, indent_level + 2)
287  << "<Scale> { " << get_component_number(i) << " }\n";
288  break;
289 
290  case CT_matrix3:
291  indent(out, indent_level + 2) << "<Matrix3> {\n";
292  get_component_mat3(i).write(out, indent_level + 4);
293  indent(out, indent_level + 2) << "}\n";
294  break;
295 
296  case CT_matrix4:
297  indent(out, indent_level + 2) << "<Matrix4> {\n";
298  get_component_mat4(i).write(out, indent_level + 4);
299  indent(out, indent_level + 2) << "}\n";
300  break;
301 
302  case CT_invalid:
303  nassertv(false);
304  break;
305  }
306  }
307 
308  indent(out, indent_level) << "}\n";
309 }
310 
311 ////////////////////////////////////////////////////////////////////
312 // Function: EggTransform::internal_clear_transform
313 // Access: Public
314 // Description: Resets the transform to empty without calling
315 // transform_changed().
316 ////////////////////////////////////////////////////////////////////
317 void EggTransform::
318 internal_clear_transform() {
319  _is_transform_2d = true;
320  _components.clear();
321  _transform = LMatrix4d::ident_mat();
322 }
323 
324 ////////////////////////////////////////////////////////////////////
325 // Function: EggTransform::internal_add_matrix
326 // Access: Public
327 // Description: Appends an arbitrary 4x4 matrix to the current
328 // transform, without calling transform_changed().
329 ////////////////////////////////////////////////////////////////////
330 void EggTransform::
331 internal_add_matrix(const LMatrix3d &mat) {
332  _components.push_back(Component(CT_matrix3));
333  _components.back()._mat3 = new LMatrix3d(mat);
334  LMatrix4d mat4(mat(0, 0), mat(0, 1), 0.0, mat(0, 2),
335  mat(1, 0), mat(1, 1), 0.0, mat(1, 2),
336  0.0, 0.0, 1.0, 0.0,
337  mat(2, 0), mat(2, 1), 0.0, mat(2, 2));
338  _transform *= mat4;
339 }
340 
341 ////////////////////////////////////////////////////////////////////
342 // Function: EggTransform::internal_add_matrix
343 // Access: Public
344 // Description: Appends an arbitrary 4x4 matrix to the current
345 // transform, without calling transform_changed().
346 ////////////////////////////////////////////////////////////////////
347 void EggTransform::
348 internal_add_matrix(const LMatrix4d &mat) {
349  _is_transform_2d = false;
350  _components.push_back(Component(CT_matrix4));
351  _components.back()._mat4 = new LMatrix4d(mat);
352  _transform *= mat;
353 }
354 
355 ////////////////////////////////////////////////////////////////////
356 // Function: EggTransform::transform_changed
357 // Access: Protected, Virtual
358 // Description: This virtual method is called whenever the transform
359 // is changed; it is intended to provide a hook for
360 // derived classes (e.g. EggGroup) to update their
361 // internal cache appropriately.
362 ////////////////////////////////////////////////////////////////////
363 void EggTransform::
364 transform_changed() {
365 }
366 
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.
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:4716
void add_rotx(double angle)
Appends a rotation about the X axis to the current transform.
static LMatrix4d rotate_mat(double angle, const LVecBase3d &axis, CoordinateSystem cs=CS_default)
Returns a matrix that rotates by the given angle in degrees counterclockwise about the indicated vect...
Definition: lmatrix.h:6690
This is a two-component vector offset.
Definition: lvector2.h:416
This is the base class for all two-component vectors and points.
Definition: lvecBase2.h:1241
void add_roty(double angle)
Appends a rotation about the Y axis to the current transform.
This is the base quaternion class.
Definition: lquaternion.h:974
const LMatrix3d & get_component_mat3(int n) const
Returns the 3x3 matrix associated with the nth component.
Definition: eggTransform.I:344
static LMatrix4d scale_mat(const LVecBase3d &scale)
Returns a matrix that applies the indicated scale in each of the three axes.
Definition: lmatrix.h:6721
LVector3d get_axis() const
This, along with get_angle(), returns the rotation represented by the quaternion as an angle about an...
Definition: lquaternion.h:1407
static LMatrix4d translate_mat(const LVecBase3d &trans)
Returns a matrix that applies the indicated translation.
Definition: lmatrix.h:6662
double get_angle() const
This, along with get_axis(), returns the rotation represented by the quaternion as an angle about an ...
Definition: lquaternion.h:1455
This is a 3-by-3 transform matrix.
Definition: lmatrix.h:4375
void add_uniform_scale(double scale)
Appends a 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:358
static const LMatrix4d & ident_mat()
Returns an identity matrix.
Definition: lmatrix.h:5168
static LMatrix4d rotate_mat_normaxis(double angle, const LVecBase3d &axis, CoordinateSystem cs=CS_default)
Returns a matrix that rotates by the given angle in degrees counterclockwise about the indicated vect...
Definition: lmatrix.h:6705
const LVecBase3d & get_component_vec3(int n) const
Returns the 3-component vector associated with the nth component.
Definition: eggTransform.I:330
double get_component_number(int n) const
Returns the solitary number associated with the nth component.
Definition: eggTransform.I:299
void add_rotate2d(double angle)
Appends a 2-d rotation to the current transform.
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:1455
int get_num_components() const
Returns the number of components that make up the transform.
Definition: eggTransform.I:274
void add_rotz(double angle)
Appends a rotation about the Z axis to the current transform.
void write(ostream &out, int indent_level, const string &label) const
Writes the transform to the indicated stream in Egg format.
void add_translate3d(const LVector3d &translate)
Appends a 3-d translation operation to the current transform.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:746
void add_scale3d(const LVecBase3d &scale)
Appends a possibly non-uniform scale to the current transform.
ComponentType get_component_type(int n) const
Returns the type of the nth component.
Definition: eggTransform.I:284
const LVecBase2d & get_component_vec2(int n) const
Returns the 2-component vector associated with the nth component.
Definition: eggTransform.I:314
This represents the &lt;Transform&gt; entry of a group or texture node: a list of component transform opera...
Definition: eggTransform.h:33
void add_scale2d(const LVecBase2d &scale)
Appends a possibly non-uniform scale to the current transform.