00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "eggXfmAnimData.h"
00016 #include "eggXfmSAnim.h"
00017 #include "eggSAnimData.h"
00018 #include "eggMiscFuncs.h"
00019 #include "config_egg.h"
00020
00021 #include "indent.h"
00022 #include "luse.h"
00023 #include "lmatrix.h"
00024 #include "compose_matrix.h"
00025 #include "dcast.h"
00026
00027 TypeHandle EggXfmAnimData::_type_handle;
00028
00029
00030
00031
00032
00033
00034
00035
00036 EggXfmAnimData::
00037 EggXfmAnimData(const EggXfmSAnim &convert_from)
00038 : EggAnimData(convert_from.get_name())
00039 {
00040 if (convert_from.has_order()) {
00041 set_order(convert_from.get_order());
00042 }
00043 if (convert_from.has_fps()) {
00044 set_fps(convert_from.get_fps());
00045 }
00046 _coordsys = convert_from.get_coordinate_system();
00047
00048
00049
00050
00051
00052 pvector<EggSAnimData *> subtables;
00053
00054 EggXfmSAnim::const_iterator ci;
00055 for (ci = convert_from.begin(); ci != convert_from.end(); ++ci) {
00056 if ((*ci)->is_of_type(EggSAnimData::get_class_type())) {
00057 EggSAnimData *sanim = DCAST(EggSAnimData, *ci);
00058 nassertv(sanim->get_name().length() == 1);
00059
00060 if (sanim->get_num_rows() > 0) {
00061 subtables.push_back(sanim);
00062 _contents += sanim->get_name()[0];
00063 }
00064 }
00065 }
00066
00067
00068 int num_rows = convert_from.get_num_rows();
00069 for (int row = 0; row < num_rows; row++) {
00070 for (int col = 0; col < (int)subtables.size(); col++) {
00071 EggSAnimData *sanim = subtables[col];
00072 if (sanim->get_num_rows() == 1) {
00073 add_data(sanim->get_value(0));
00074 } else {
00075 nassertv(row < sanim->get_num_rows());
00076 add_data(sanim->get_value(row));
00077 }
00078 }
00079 }
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 void EggXfmAnimData::
00092 get_value(int row, LMatrix4d &mat) const {
00093 LVector3d scale(1.0, 1.0, 1.0);
00094 LVector3d shear(0.0, 0.0, 0.0);
00095 LVector3d hpr(0.0, 0.0, 0.0);
00096 LVector3d translate(0.0, 0.0, 0.0);
00097
00098 for (int col = 0; col < get_num_cols(); col++) {
00099 double value = get_value(row, col);
00100
00101 switch (_contents[col]) {
00102 case 'i':
00103 scale[0] = value;
00104 break;
00105
00106 case 'j':
00107 scale[1] = value;
00108 break;
00109
00110 case 'k':
00111 scale[2] = value;
00112 break;
00113
00114 case 'a':
00115 shear[0] = value;
00116 break;
00117
00118 case 'b':
00119 shear[1] = value;
00120 break;
00121
00122 case 'c':
00123 shear[2] = value;
00124 break;
00125
00126 case 'h':
00127 hpr[0] = value;
00128 break;
00129
00130 case 'p':
00131 hpr[1] = value;
00132 break;
00133
00134 case 'r':
00135 hpr[2] = value;
00136 break;
00137
00138 case 'x':
00139 translate[0] = value;
00140 break;
00141
00142 case 'y':
00143 translate[1] = value;
00144 break;
00145
00146 case 'z':
00147 translate[2] = value;
00148 break;
00149
00150 default:
00151
00152 nassertv(false);
00153 }
00154 }
00155
00156
00157 EggXfmSAnim::compose_with_order(mat, scale, shear, hpr, translate, get_order(),
00158 _coordsys);
00159 }
00160
00161
00162
00163
00164
00165
00166
00167 bool EggXfmAnimData::
00168 is_anim_matrix() const {
00169 return true;
00170 }
00171
00172
00173
00174
00175
00176
00177
00178 void EggXfmAnimData::
00179 write(ostream &out, int indent_level) const {
00180 write_header(out, indent_level, "<Xfm$Anim>");
00181
00182 if (has_fps()) {
00183 indent(out, indent_level + 2)
00184 << "<Scalar> fps { " << get_fps() << " }\n";
00185 }
00186
00187 if (has_order()) {
00188 indent(out, indent_level + 2)
00189 << "<Char*> order { " << get_order() << " }\n";
00190 }
00191
00192 if (has_contents()) {
00193 indent(out, indent_level + 2)
00194 << "<Char*> contents { " << get_contents() << " }\n";
00195 }
00196
00197 indent(out, indent_level + 2) << "<V> {\n";
00198 write_long_list(out, indent_level + 4, _data.begin(), _data.end(),
00199 "", "", 72);
00200 indent(out, indent_level + 2) << "}\n";
00201 indent(out, indent_level) << "}\n";
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211 void EggXfmAnimData::
00212 r_transform(const LMatrix4d &mat, const LMatrix4d &inv,
00213 CoordinateSystem to_cs) {
00214
00215
00216 LMatrix4d inv1 = inv;
00217 inv1.set_row(3, LVector3d(0.0, 0.0, 0.0));
00218
00219
00220
00221
00222
00223 if (to_cs == CS_default) {
00224 to_cs = _coordsys;
00225 }
00226
00227 EggXfmSAnim new_table(get_name(), to_cs);
00228 if (has_fps()) {
00229 new_table.set_fps(get_fps());
00230 }
00231
00232
00233 new_table.set_order(get_standard_order());
00234
00235
00236 LMatrix4d orig_mat;
00237 for (int r = 0; r < get_num_rows(); r++) {
00238 get_value(r, orig_mat);
00239 bool result = new_table.add_data(inv1 * orig_mat * mat);
00240
00241 if (!result) {
00242 egg_cat.error()
00243 << "Transform from " << _coordsys << " to " << to_cs
00244 << " failed!\n";
00245 LVector3d scale, shear, hpr, trans;
00246 bool d = decompose_matrix(orig_mat, scale, shear, hpr, trans, _coordsys);
00247 egg_cat.error(false)
00248 << "orig:\n" << orig_mat
00249 << "d = " << d
00250 << "\n scale: " << scale
00251 << "\n shear: " << shear
00252 << "\n hpr: " << hpr
00253 << "\n trans: " << trans << "\n";
00254
00255 LMatrix4d new_mat = inv1 * orig_mat * mat;
00256 d = decompose_matrix(new_mat, scale, shear, hpr, trans, to_cs);
00257 egg_cat.error(false)
00258 << "new:\n" << new_mat
00259 << "d = " << d
00260 << "\n scale: " << scale
00261 << "\n shear: " << shear
00262 << "\n hpr: " << hpr
00263 << "\n trans: " << trans << "\n";
00264 }
00265
00266
00267
00268
00269 nassertv(result);
00270 }
00271
00272
00273 new_table.optimize();
00274
00275
00276 EggXfmAnimData copy_table(new_table);
00277 (*this) = copy_table;
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 void EggXfmAnimData::
00290 r_mark_coordsys(CoordinateSystem cs) {
00291 _coordsys = cs;
00292 }