Panda3D
Loading...
Searching...
No Matches
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 */
20EggTransform::
21EggTransform() :
22 _is_transform_2d(true),
23 _transform(LMatrix4d::ident_mat())
24{
25}
26
27/**
28 *
29 */
30EggTransform::
31EggTransform(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 */
41EggTransform &EggTransform::
42operator = (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 */
52EggTransform::
53~EggTransform() {
54}
55
56/**
57 * Appends a 2-d translation operation to the current transform.
58 */
60add_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 */
71add_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 */
84add_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 */
95add_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 */
107add_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 */
119add_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 */
131add_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 */
145add_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 */
155add_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 */
167add_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 */
179add_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 */
189write(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 */
270void EggTransform::
271internal_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 */
281void EggTransform::
282internal_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 */
296void EggTransform::
297internal_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 */
309void EggTransform::
310transform_changed() {
311}
This represents the <Transform> entry of a group or texture node: a list of component transform opera...
void add_rotz(double angle)
Appends a rotation about the Z axis to the current transform.
void add_rotate2d(double angle)
Appends a 2-d rotation to the current transform.
const LVecBase3d & get_component_vec3(int n) const
Returns the 3-component vector associated with the nth component.
ComponentType get_component_type(int n) const
Returns the type of the nth component.
void add_scale3d(const LVecBase3d &scale)
Appends a possibly non-uniform scale to the current transform.
void add_rotx(double angle)
Appends a rotation about the X axis to the current transform.
const LVecBase2d & get_component_vec2(int n) const
Returns the 2-component vector associated with the nth component.
int get_num_components() const
Returns the number of components that make up the transform.
const LMatrix3d & get_component_mat3(int n) const
Returns the 3x3 matrix associated with the nth component.
const LMatrix4d & get_component_mat4(int n) const
Returns the 4x4 matrix associated with the nth component.
void add_uniform_scale(double scale)
Appends a uniform scale to the current transform.
void add_translate3d(const LVector3d &translate)
Appends a 3-d translation operation 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.
void add_roty(double angle)
Appends a rotation about the Y axis to the current transform.
void add_scale2d(const LVecBase2d &scale)
Appends a possibly non-uniform scale to the current transform.
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.
double get_component_number(int n) const
Returns the solitary number associated with the nth component.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition indent.cxx:20