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