Panda3D
 All Classes Functions Variables Enumerations
eggTransform.cxx
00001 // Filename: eggTransform.cxx
00002 // Created by:  drose (21Jun02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "eggTransform.h"
00016 
00017 
00018 ////////////////////////////////////////////////////////////////////
00019 //     Function: EggTransform::Constructor
00020 //       Access: Public
00021 //  Description:
00022 ////////////////////////////////////////////////////////////////////
00023 EggTransform::
00024 EggTransform() :
00025   _is_transform_2d(true),
00026   _transform(LMatrix4d::ident_mat())
00027 {
00028 }
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 //     Function: EggTransform::Copy Constructor
00032 //       Access: Public
00033 //  Description:
00034 ////////////////////////////////////////////////////////////////////
00035 EggTransform::
00036 EggTransform(const EggTransform &copy) :
00037   _is_transform_2d(copy._is_transform_2d),
00038   _components(copy._components),
00039   _transform(copy._transform)
00040 {
00041 }
00042 
00043 ////////////////////////////////////////////////////////////////////
00044 //     Function: EggTransform::Copy assignment operator
00045 //       Access: Public
00046 //  Description:
00047 ////////////////////////////////////////////////////////////////////
00048 EggTransform &EggTransform::
00049 operator = (const EggTransform &copy) {
00050   _is_transform_2d = copy._is_transform_2d;
00051   _components = copy._components;
00052   _transform = copy._transform;
00053   return *this;
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: EggTransform::Destructor
00058 //       Access: Public, Virtual
00059 //  Description:
00060 ////////////////////////////////////////////////////////////////////
00061 EggTransform::
00062 ~EggTransform() {
00063 }
00064 
00065 ////////////////////////////////////////////////////////////////////
00066 //     Function: EggTransform::add_translate2d
00067 //       Access: Public
00068 //  Description: Appends a 2-d translation operation to the current
00069 //               transform.
00070 ////////////////////////////////////////////////////////////////////
00071 void EggTransform::
00072 add_translate2d(const LVector2d &translate) {
00073   _components.push_back(Component(CT_translate2d));
00074   _components.back()._vec2 = new LVecBase2d(translate);
00075   _transform *= LMatrix4d::translate_mat(LVector3d(translate[0], translate[1], 0.0));
00076   transform_changed();
00077 }
00078 
00079 ////////////////////////////////////////////////////////////////////
00080 //     Function: EggTransform::add_translate3d
00081 //       Access: Public
00082 //  Description: Appends a 3-d translation operation to the current
00083 //               transform.
00084 ////////////////////////////////////////////////////////////////////
00085 void EggTransform::
00086 add_translate3d(const LVector3d &translate) {
00087   _is_transform_2d = false;
00088   _components.push_back(Component(CT_translate3d));
00089   _components.back()._vec3 = new LVecBase3d(translate);
00090   _transform *= LMatrix4d::translate_mat(translate);
00091   transform_changed();
00092 }
00093 
00094 ////////////////////////////////////////////////////////////////////
00095 //     Function: EggTransform::add_rotate2d
00096 //       Access: Public
00097 //  Description: Appends a 2-d rotation to the current transform.  The
00098 //               rotation angle is specified in degrees
00099 //               counterclockwise about the origin.
00100 ////////////////////////////////////////////////////////////////////
00101 void EggTransform::
00102 add_rotate2d(double angle) {
00103   _components.push_back(Component(CT_rotate2d, angle));
00104   _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 0.0, 1.0));
00105   transform_changed();
00106 }
00107 
00108 ////////////////////////////////////////////////////////////////////
00109 //     Function: EggTransform::add_rotx
00110 //       Access: Public
00111 //  Description: Appends a rotation about the X axis to the current
00112 //               transform.  The rotation angle is specified in
00113 //               degrees counterclockwise about the axis.
00114 ////////////////////////////////////////////////////////////////////
00115 void EggTransform::
00116 add_rotx(double angle) {
00117   _is_transform_2d = false;
00118   _components.push_back(Component(CT_rotx, angle));
00119   _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(1.0, 0.0, 0.0));
00120   transform_changed();
00121 }
00122 
00123 ////////////////////////////////////////////////////////////////////
00124 //     Function: EggTransform::add_roty
00125 //       Access: Public
00126 //  Description: Appends a rotation about the Y axis to the current
00127 //               transform.  The rotation angle is specified in
00128 //               degrees counterclockwise about the axis.
00129 ////////////////////////////////////////////////////////////////////
00130 void EggTransform::
00131 add_roty(double angle) {
00132   _is_transform_2d = false;
00133   _components.push_back(Component(CT_roty, angle));
00134   _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 1.0, 0.0));
00135   transform_changed();
00136 }
00137 
00138 ////////////////////////////////////////////////////////////////////
00139 //     Function: EggTransform::add_rotz
00140 //       Access: Public
00141 //  Description: Appends a rotation about the Z axis to the current
00142 //               transform.  The rotation angle is specified in
00143 //               degrees counterclockwise about the axis.
00144 ////////////////////////////////////////////////////////////////////
00145 void EggTransform::
00146 add_rotz(double angle) {
00147   _is_transform_2d = false;
00148   _components.push_back(Component(CT_rotz, angle));
00149   _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 0.0, 1.0));
00150   transform_changed();
00151 }
00152 
00153 ////////////////////////////////////////////////////////////////////
00154 //     Function: EggTransform::add_rotate3d
00155 //       Access: Public
00156 //  Description: Appends a 3-d rotation about an arbitrary axis to the
00157 //               current transform.  The rotation angle is specified
00158 //               in degrees counterclockwise about the axis.
00159 ////////////////////////////////////////////////////////////////////
00160 void EggTransform::
00161 add_rotate3d(double angle, const LVector3d &axis) {
00162   _is_transform_2d = false;
00163   LVector3d normaxis = normalize(axis);
00164   _components.push_back(Component(CT_rotate3d, angle));
00165   _components.back()._vec3 = new LVecBase3d(normaxis);
00166   _transform *= LMatrix4d::rotate_mat(angle, normaxis);
00167   transform_changed();
00168 }
00169 
00170 ////////////////////////////////////////////////////////////////////
00171 //     Function: EggTransform::add_rotate3d
00172 //       Access: Public
00173 //  Description: Appends an arbitrary 3-d rotation to the current
00174 //               transform, expressed as a quaternion.  This is
00175 //               converted to axis-angle notation for the egg file.
00176 ////////////////////////////////////////////////////////////////////
00177 void EggTransform::
00178 add_rotate3d(const LQuaterniond &quat) {
00179   _is_transform_2d = false;
00180   add_rotate3d(quat.get_angle(), quat.get_axis());
00181   transform_changed();
00182 }
00183 
00184 ////////////////////////////////////////////////////////////////////
00185 //     Function: EggTransform::add_scale2d
00186 //       Access: Public
00187 //  Description: Appends a possibly non-uniform scale to the current
00188 //               transform.
00189 ////////////////////////////////////////////////////////////////////
00190 void EggTransform::
00191 add_scale2d(const LVecBase2d &scale) {
00192   _is_transform_2d = false;
00193   _components.push_back(Component(CT_scale2d));
00194   _components.back()._vec2 = new LVecBase2d(scale);
00195   _transform *= LMatrix4d::scale_mat(LVecBase3d(scale[0], scale[1], 1.0));
00196   transform_changed();
00197 }
00198 
00199 ////////////////////////////////////////////////////////////////////
00200 //     Function: EggTransform::add_scale3d
00201 //       Access: Public
00202 //  Description: Appends a possibly non-uniform scale to the current
00203 //               transform.
00204 ////////////////////////////////////////////////////////////////////
00205 void EggTransform::
00206 add_scale3d(const LVecBase3d &scale) {
00207   _is_transform_2d = false;
00208   _components.push_back(Component(CT_scale3d));
00209   _components.back()._vec3 = new LVecBase3d(scale);
00210   _transform *= LMatrix4d::scale_mat(scale);
00211   transform_changed();
00212 }
00213 
00214 ////////////////////////////////////////////////////////////////////
00215 //     Function: EggTransform::add_uniform_scale
00216 //       Access: Public
00217 //  Description: Appends a uniform scale to the current transform.
00218 ////////////////////////////////////////////////////////////////////
00219 void EggTransform::
00220 add_uniform_scale(double scale) {
00221   _components.push_back(Component(CT_uniform_scale, scale));
00222   _transform *= LMatrix4d::scale_mat(scale);
00223   transform_changed();
00224 }
00225 
00226 ////////////////////////////////////////////////////////////////////
00227 //     Function: EggTransform::write
00228 //       Access: Public
00229 //  Description: Writes the transform to the indicated stream in Egg
00230 //               format.
00231 ////////////////////////////////////////////////////////////////////
00232 void EggTransform::
00233 write(ostream &out, int indent_level, const string &label) const {
00234   indent(out, indent_level) << label << " {\n";
00235 
00236   int num_components = get_num_components();
00237   for (int i = 0; i < num_components; i++) {
00238     switch (get_component_type(i)) {
00239     case CT_translate2d:
00240       indent(out, indent_level + 2)
00241         << "<Translate> { " << get_component_vec2(i) << " }\n";
00242       break;
00243 
00244     case CT_translate3d:
00245       indent(out, indent_level + 2)
00246         << "<Translate> { " << get_component_vec3(i) << " }\n";
00247       break;
00248 
00249     case CT_rotate2d:
00250       indent(out, indent_level + 2)
00251         << "<Rotate> { " << get_component_number(i) << " }\n";
00252       break;
00253 
00254     case CT_rotx:
00255       indent(out, indent_level + 2)
00256         << "<RotX> { " << get_component_number(i) << " }\n";
00257       break;
00258 
00259     case CT_roty:
00260       indent(out, indent_level + 2)
00261         << "<RotY> { " << get_component_number(i) << " }\n";
00262       break;
00263 
00264     case CT_rotz:
00265       indent(out, indent_level + 2)
00266         << "<RotZ> { " << get_component_number(i) << " }\n";
00267       break;
00268 
00269     case CT_rotate3d:
00270       indent(out, indent_level + 2)
00271         << "<Rotate> { " << get_component_number(i) << " " 
00272         << get_component_vec3(i) << " }\n";
00273       break;
00274 
00275     case CT_scale2d:
00276       indent(out, indent_level + 2)
00277         << "<Scale> { " << get_component_vec2(i) << " }\n";
00278       break;
00279 
00280     case CT_scale3d:
00281       indent(out, indent_level + 2)
00282         << "<Scale> { " << get_component_vec3(i) << " }\n";
00283       break;
00284 
00285     case CT_uniform_scale:
00286       indent(out, indent_level + 2)
00287         << "<Scale> { " << get_component_number(i) << " }\n";
00288       break;
00289 
00290     case CT_matrix3:
00291       indent(out, indent_level + 2) << "<Matrix3> {\n";
00292       get_component_mat3(i).write(out, indent_level + 4);
00293       indent(out, indent_level + 2) << "}\n";
00294       break;
00295 
00296     case CT_matrix4:
00297       indent(out, indent_level + 2) << "<Matrix4> {\n";
00298       get_component_mat4(i).write(out, indent_level + 4);
00299       indent(out, indent_level + 2) << "}\n";
00300       break;
00301 
00302     case CT_invalid:
00303       nassertv(false);
00304       break;
00305     }
00306   }
00307 
00308   indent(out, indent_level) << "}\n";
00309 }
00310 
00311 ////////////////////////////////////////////////////////////////////
00312 //     Function: EggTransform::internal_clear_transform
00313 //       Access: Public
00314 //  Description: Resets the transform to empty without calling
00315 //               transform_changed().
00316 ////////////////////////////////////////////////////////////////////
00317 void EggTransform::
00318 internal_clear_transform() {
00319   _is_transform_2d = true;
00320   _components.clear();
00321   _transform = LMatrix4d::ident_mat();
00322 }
00323 
00324 ////////////////////////////////////////////////////////////////////
00325 //     Function: EggTransform::internal_add_matrix
00326 //       Access: Public
00327 //  Description: Appends an arbitrary 4x4 matrix to the current
00328 //               transform, without calling transform_changed().
00329 ////////////////////////////////////////////////////////////////////
00330 void EggTransform::
00331 internal_add_matrix(const LMatrix3d &mat) {
00332   _components.push_back(Component(CT_matrix3));
00333   _components.back()._mat3 = new LMatrix3d(mat);
00334   LMatrix4d mat4(mat(0, 0), mat(0, 1), 0.0, mat(0, 2),
00335                  mat(1, 0), mat(1, 1), 0.0, mat(1, 2),
00336                  0.0, 0.0, 1.0, 0.0,
00337                  mat(2, 0), mat(2, 1), 0.0, mat(2, 2));
00338   _transform *= mat4;
00339 }
00340 
00341 ////////////////////////////////////////////////////////////////////
00342 //     Function: EggTransform::internal_add_matrix
00343 //       Access: Public
00344 //  Description: Appends an arbitrary 4x4 matrix to the current
00345 //               transform, without calling transform_changed().
00346 ////////////////////////////////////////////////////////////////////
00347 void EggTransform::
00348 internal_add_matrix(const LMatrix4d &mat) {
00349   _is_transform_2d = false;
00350   _components.push_back(Component(CT_matrix4));
00351   _components.back()._mat4 = new LMatrix4d(mat);
00352   _transform *= mat;
00353 }
00354 
00355 ////////////////////////////////////////////////////////////////////
00356 //     Function: EggTransform::transform_changed
00357 //       Access: Protected, Virtual
00358 //  Description: This virtual method is called whenever the transform
00359 //               is changed; it is intended to provide a hook for
00360 //               derived classes (e.g. EggGroup) to update their
00361 //               internal cache appropriately.
00362 ////////////////////////////////////////////////////////////////////
00363 void EggTransform::
00364 transform_changed() {
00365 }
00366 
 All Classes Functions Variables Enumerations