Panda3D
|
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 ©) : 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 ©) { 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