00001 // Filename: eggTransform3d.cxx 00002 // Created by: drose (21Jun02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "eggTransform3d.h" 00020 00021 00022 //////////////////////////////////////////////////////////////////// 00023 // Function: EggTransform3d::Constructor 00024 // Access: Public 00025 // Description: 00026 //////////////////////////////////////////////////////////////////// 00027 EggTransform3d:: 00028 EggTransform3d() : 00029 _transform(LMatrix4d::ident_mat()) 00030 { 00031 } 00032 00033 //////////////////////////////////////////////////////////////////// 00034 // Function: EggTransform3d::Copy Constructor 00035 // Access: Public 00036 // Description: 00037 //////////////////////////////////////////////////////////////////// 00038 EggTransform3d:: 00039 EggTransform3d(const EggTransform3d ©) : 00040 _components(copy._components), 00041 _transform(copy._transform) 00042 { 00043 } 00044 00045 //////////////////////////////////////////////////////////////////// 00046 // Function: EggTransform3d::Copy assignment operator 00047 // Access: Public 00048 // Description: 00049 //////////////////////////////////////////////////////////////////// 00050 EggTransform3d &EggTransform3d:: 00051 operator = (const EggTransform3d ©) { 00052 _components = copy._components; 00053 _transform = copy._transform; 00054 return *this; 00055 } 00056 00057 //////////////////////////////////////////////////////////////////// 00058 // Function: EggTransform3d::Destructor 00059 // Access: Public, Virtual 00060 // Description: 00061 //////////////////////////////////////////////////////////////////// 00062 EggTransform3d:: 00063 ~EggTransform3d() { 00064 } 00065 00066 //////////////////////////////////////////////////////////////////// 00067 // Function: EggTransform3d::add_translate 00068 // Access: Public 00069 // Description: Appends a translation operation to the current 00070 // transform. 00071 //////////////////////////////////////////////////////////////////// 00072 void EggTransform3d:: 00073 add_translate(const LVector3d &translate) { 00074 _components.push_back(Component(CT_translate)); 00075 _components.back()._vector = new LVector3d(translate); 00076 _transform *= LMatrix4d::translate_mat(translate); 00077 transform_changed(); 00078 } 00079 00080 //////////////////////////////////////////////////////////////////// 00081 // Function: EggTransform3d::add_rotx 00082 // Access: Public 00083 // Description: Appends a rotation about the X axis to the current 00084 // transform. The rotation angle is specified in 00085 // degrees counterclockwise about the axis. 00086 //////////////////////////////////////////////////////////////////// 00087 void EggTransform3d:: 00088 add_rotx(double angle) { 00089 _components.push_back(Component(CT_rotx, angle)); 00090 _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(1.0, 0.0, 0.0)); 00091 transform_changed(); 00092 } 00093 00094 //////////////////////////////////////////////////////////////////// 00095 // Function: EggTransform3d::add_roty 00096 // Access: Public 00097 // Description: Appends a rotation about the Y axis to the current 00098 // transform. The rotation angle is specified in 00099 // degrees counterclockwise about the axis. 00100 //////////////////////////////////////////////////////////////////// 00101 void EggTransform3d:: 00102 add_roty(double angle) { 00103 _components.push_back(Component(CT_roty, angle)); 00104 _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 1.0, 0.0)); 00105 transform_changed(); 00106 } 00107 00108 //////////////////////////////////////////////////////////////////// 00109 // Function: EggTransform3d::add_rotz 00110 // Access: Public 00111 // Description: Appends a rotation about the Z axis to the current 00112 // transform. The rotation angle is specified in 00113 // degrees counterclockwise about the axis. 00114 //////////////////////////////////////////////////////////////////// 00115 void EggTransform3d:: 00116 add_rotz(double angle) { 00117 _components.push_back(Component(CT_rotz, angle)); 00118 _transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 0.0, 1.0)); 00119 transform_changed(); 00120 } 00121 00122 //////////////////////////////////////////////////////////////////// 00123 // Function: EggTransform3d::add_rotate 00124 // Access: Public 00125 // Description: Appends a rotation about an arbitrary axis to the 00126 // current transform. The rotation angle is specified 00127 // in degrees counterclockwise about the axis. 00128 //////////////////////////////////////////////////////////////////// 00129 void EggTransform3d:: 00130 add_rotate(double angle, const LVector3d &axis) { 00131 LVector3d normaxis = normalize(axis); 00132 _components.push_back(Component(CT_rotate, angle)); 00133 _components.back()._vector = new LVector3d(normaxis); 00134 _transform *= LMatrix4d::rotate_mat(angle, normaxis); 00135 transform_changed(); 00136 } 00137 00138 //////////////////////////////////////////////////////////////////// 00139 // Function: EggTransform3d::add_rotate 00140 // Access: Public 00141 // Description: Appends an arbitrary rotation to the current 00142 // transform, expressed as a quaternion. This is 00143 // converted to axis-angle notation for the egg file. 00144 //////////////////////////////////////////////////////////////////// 00145 void EggTransform3d:: 00146 add_rotate(const LQuaterniond &quat) { 00147 add_rotate(quat.get_angle(), quat.get_axis()); 00148 transform_changed(); 00149 } 00150 00151 //////////////////////////////////////////////////////////////////// 00152 // Function: EggTransform3d::add_scale 00153 // Access: Public 00154 // Description: Appends a possibly non-uniform scale to the current 00155 // transform. 00156 //////////////////////////////////////////////////////////////////// 00157 void EggTransform3d:: 00158 add_scale(const LVecBase3d &scale) { 00159 _components.push_back(Component(CT_scale)); 00160 _components.back()._vector = new LVector3d(scale); 00161 _transform *= LMatrix4d::scale_mat(scale); 00162 transform_changed(); 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: EggTransform3d::add_uniform_scale 00167 // Access: Public 00168 // Description: Appends a uniform scale to the current transform. 00169 //////////////////////////////////////////////////////////////////// 00170 void EggTransform3d:: 00171 add_uniform_scale(double scale) { 00172 _components.push_back(Component(CT_uniform_scale, scale)); 00173 _transform *= LMatrix4d::scale_mat(scale); 00174 transform_changed(); 00175 } 00176 00177 //////////////////////////////////////////////////////////////////// 00178 // Function: EggTransform3d::write 00179 // Access: Public 00180 // Description: Writes the transform to the indicated stream in Egg 00181 // format. 00182 //////////////////////////////////////////////////////////////////// 00183 void EggTransform3d:: 00184 write(ostream &out, int indent_level) const { 00185 indent(out, indent_level) << "<Transform> {\n"; 00186 00187 int num_components = get_num_components(); 00188 for (int i = 0; i < num_components; i++) { 00189 switch (get_component_type(i)) { 00190 case CT_translate: 00191 indent(out, indent_level + 2) 00192 << "<Translate> { " << get_component_vector(i) << " }\n"; 00193 break; 00194 00195 case CT_rotx: 00196 indent(out, indent_level + 2) 00197 << "<RotX> { " << get_component_number(i) << " }\n"; 00198 break; 00199 00200 case CT_roty: 00201 indent(out, indent_level + 2) 00202 << "<RotY> { " << get_component_number(i) << " }\n"; 00203 break; 00204 00205 case CT_rotz: 00206 indent(out, indent_level + 2) 00207 << "<RotZ> { " << get_component_number(i) << " }\n"; 00208 break; 00209 00210 case CT_rotate: 00211 indent(out, indent_level + 2) 00212 << "<Rotate> { " << get_component_number(i) << " " 00213 << get_component_vector(i) << " }\n"; 00214 break; 00215 00216 case CT_scale: 00217 indent(out, indent_level + 2) 00218 << "<Scale> { " << get_component_vector(i) << " }\n"; 00219 break; 00220 00221 case CT_uniform_scale: 00222 indent(out, indent_level + 2) 00223 << "<Scale> { " << get_component_number(i) << " }\n"; 00224 break; 00225 00226 case CT_matrix: 00227 indent(out, indent_level + 2) << "<Matrix4> {\n"; 00228 get_component_matrix(i).write(out, indent_level + 4); 00229 indent(out, indent_level + 2) << "}\n"; 00230 break; 00231 00232 case CT_invalid: 00233 nassertv(false); 00234 break; 00235 } 00236 } 00237 00238 indent(out, indent_level) << "}\n"; 00239 } 00240 00241 //////////////////////////////////////////////////////////////////// 00242 // Function: EggTransform3d::internal_clear_transform 00243 // Access: Public 00244 // Description: Resets the transform to empty without calling 00245 // transform_changed(). 00246 //////////////////////////////////////////////////////////////////// 00247 void EggTransform3d:: 00248 internal_clear_transform() { 00249 _components.clear(); 00250 _transform = LMatrix4d::ident_mat(); 00251 } 00252 00253 //////////////////////////////////////////////////////////////////// 00254 // Function: EggTransform3d::internal_add_matrix 00255 // Access: Public 00256 // Description: Appends an arbitrary 4x4 matrix to the current 00257 // transform, without calling transform_changed(). 00258 //////////////////////////////////////////////////////////////////// 00259 void EggTransform3d:: 00260 internal_add_matrix(const LMatrix4d &mat) { 00261 _components.push_back(Component(CT_matrix)); 00262 _components.back()._matrix = new LMatrix4d(mat); 00263 _transform *= mat; 00264 } 00265 00266 //////////////////////////////////////////////////////////////////// 00267 // Function: EggTransform3d::transform_changed 00268 // Access: Protected, Virtual 00269 // Description: This virtual method is called whenever the transform 00270 // is changed; it is intended to provide a hook for 00271 // derived classes (e.g. EggGroup) to update their 00272 // internal cache appropriately. 00273 //////////////////////////////////////////////////////////////////// 00274 void EggTransform3d:: 00275 transform_changed() { 00276 } 00277