00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "eggMatrixTablePointer.h"
00016 #include "dcast.h"
00017 #include "eggSAnimData.h"
00018 #include "eggXfmAnimData.h"
00019 #include "eggXfmSAnim.h"
00020
00021 TypeHandle EggMatrixTablePointer::_type_handle;
00022
00023
00024
00025
00026
00027
00028 EggMatrixTablePointer::
00029 EggMatrixTablePointer(EggObject *object) {
00030 _table = DCAST(EggTable, object);
00031
00032 if (_table != (EggTable *)NULL) {
00033
00034
00035 EggGroupNode::iterator ci;
00036 bool found = false;
00037 for (ci = _table->begin(); ci != _table->end() && !found; ++ci) {
00038 EggNode *child = (*ci);
00039 if (child->get_name() == "xform") {
00040 if (child->is_of_type(EggXfmSAnim::get_class_type())) {
00041 _xform = DCAST(EggXfmSAnim, child);
00042 _xform->normalize();
00043 found = true;
00044
00045 } else if (child->is_of_type(EggXfmAnimData::get_class_type())) {
00046
00047
00048 PT(EggXfmAnimData) anim = DCAST(EggXfmAnimData, child);
00049 _xform = new EggXfmSAnim(*anim);
00050 _table->replace(ci, _xform.p());
00051 found = true;
00052 }
00053 }
00054 }
00055 }
00056 }
00057
00058
00059
00060
00061
00062
00063
00064 double EggMatrixTablePointer::
00065 get_frame_rate() const {
00066 if (_xform == (EggXfmSAnim *)NULL || !_xform->has_fps()) {
00067 return 0.0;
00068 } else {
00069 return _xform->get_fps();
00070 }
00071 }
00072
00073
00074
00075
00076
00077
00078
00079 int EggMatrixTablePointer::
00080 get_num_frames() const {
00081 if (_xform == (EggXfmSAnim *)NULL) {
00082 return 0;
00083 } else {
00084 return _xform->get_num_rows();
00085 }
00086 }
00087
00088
00089
00090
00091
00092
00093 void EggMatrixTablePointer::
00094 extend_to(int num_frames) {
00095 nassertv(_xform != (EggXfmSAnim *)NULL);
00096 _xform->normalize();
00097 int num_rows = _xform->get_num_rows();
00098 LMatrix4d last_mat;
00099 if (num_rows == 0) {
00100 last_mat = LMatrix4d::ident_mat();
00101 } else {
00102 _xform->get_value(num_rows - 1, last_mat);
00103 }
00104
00105 while (num_rows < num_frames) {
00106 _xform->add_data(last_mat);
00107 num_rows++;
00108 }
00109 }
00110
00111
00112
00113
00114
00115
00116
00117 LMatrix4d EggMatrixTablePointer::
00118 get_frame(int n) const {
00119 if (get_num_frames() == 1) {
00120
00121
00122 n = 0;
00123
00124 } else if (get_num_frames() == 0) {
00125
00126 return LMatrix4d::ident_mat();
00127 }
00128
00129 nassertr(n >= 0 && n < get_num_frames(), LMatrix4d::ident_mat());
00130 LMatrix4d mat;
00131 _xform->get_value(n, mat);
00132 return mat;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141 void EggMatrixTablePointer::
00142 set_frame(int n, const LMatrix4d &mat) {
00143 nassertv(n >= 0 && n < get_num_frames());
00144 _xform->set_value(n, mat);
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154 bool EggMatrixTablePointer::
00155 add_frame(const LMatrix4d &mat) {
00156 if (_xform == (EggXfmSAnim *)NULL) {
00157 return false;
00158 }
00159
00160 return _xform->add_data(mat);
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170 void EggMatrixTablePointer::
00171 do_finish_reparent(EggJointPointer *new_parent) {
00172 if (new_parent == (EggJointPointer *)NULL) {
00173
00174 EggGroupNode *egg_parent = _table->get_parent();
00175 if (egg_parent != (EggGroupNode *)NULL) {
00176 egg_parent->remove_child(_table.p());
00177 }
00178
00179 } else {
00180
00181
00182 EggMatrixTablePointer *new_node = DCAST(EggMatrixTablePointer, new_parent);
00183 if (new_node->_table != _table->get_parent()) {
00184 new_node->_table->add_child(_table.p());
00185 }
00186 }
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 bool EggMatrixTablePointer::
00203 do_rebuild(EggCharacterDb &db) {
00204 LMatrix4d mat;
00205 if (!db.get_matrix(this, EggCharacterDb::TT_rebuild_frame, 0, mat)) {
00206
00207 return true;
00208 }
00209
00210 if (_xform == (EggXfmSAnim *)NULL) {
00211 return false;
00212 }
00213
00214 bool all_ok = true;
00215
00216 _xform->clear_data();
00217 if (!_xform->add_data(mat)) {
00218 all_ok = false;
00219 }
00220
00221
00222 int n = 1;
00223 while (db.get_matrix(this, EggCharacterDb::TT_rebuild_frame, n, mat)) {
00224 if (!_xform->add_data(mat)) {
00225 all_ok = false;
00226 }
00227 ++n;
00228 }
00229
00230 return all_ok;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240 void EggMatrixTablePointer::
00241 optimize() {
00242 if (_xform != (EggXfmSAnim *)NULL) {
00243 _xform->optimize();
00244 }
00245 }
00246
00247
00248
00249
00250
00251
00252
00253 void EggMatrixTablePointer::
00254 zero_channels(const string &components) {
00255 if (_xform == (EggXfmSAnim *)NULL) {
00256 return;
00257 }
00258
00259
00260
00261 string::const_iterator si;
00262 for (si = components.begin(); si != components.end(); ++si) {
00263 string table_name(1, *si);
00264 EggNode *child = _xform->find_child(table_name);
00265 if (child != (EggNode *)NULL) {
00266 _xform->remove_child(child);
00267 }
00268 }
00269 }
00270
00271
00272
00273
00274
00275
00276
00277 void EggMatrixTablePointer::
00278 quantize_channels(const string &components, double quantum) {
00279 if (_xform == (EggXfmSAnim *)NULL) {
00280 return;
00281 }
00282
00283
00284
00285 string::const_iterator si;
00286 for (si = components.begin(); si != components.end(); ++si) {
00287 string table_name(1, *si);
00288 EggNode *child = _xform->find_child(table_name);
00289 if (child != (EggNode *)NULL &&
00290 child->is_of_type(EggSAnimData::get_class_type())) {
00291 EggSAnimData *anim = DCAST(EggSAnimData, child);
00292 anim->quantize(quantum);
00293 }
00294 }
00295 }
00296
00297
00298
00299
00300
00301
00302
00303 EggJointPointer *EggMatrixTablePointer::
00304 make_new_joint(const string &name) {
00305 EggTable *new_table = new EggTable(name);
00306 _table->add_child(new_table);
00307 CoordinateSystem cs = CS_default;
00308 if (_xform != (EggXfmSAnim *)NULL) {
00309 cs = _xform->get_coordinate_system();
00310 }
00311 EggXfmSAnim *new_xform = new EggXfmSAnim("xform", cs);
00312 new_table->add_child(new_xform);
00313 new_xform->add_data(LMatrix4d::ident_mat());
00314
00315 return new EggMatrixTablePointer(new_table);
00316 }
00317
00318
00319
00320
00321
00322
00323 void EggMatrixTablePointer::
00324 set_name(const string &name) {
00325 _table->set_name(name);
00326 }