00001 // Filename: eggMatrixTablePointer.cxx 00002 // Created by: drose (26Feb01) 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 "eggMatrixTablePointer.h" 00020 00021 #include "dcast.h" 00022 #include "eggXfmAnimData.h" 00023 #include "eggXfmSAnim.h" 00024 00025 TypeHandle EggMatrixTablePointer::_type_handle; 00026 00027 //////////////////////////////////////////////////////////////////// 00028 // Function: EggMatrixTablePointer::Constructor 00029 // Access: Public 00030 // Description: 00031 //////////////////////////////////////////////////////////////////// 00032 EggMatrixTablePointer:: 00033 EggMatrixTablePointer(EggObject *object) { 00034 _table = DCAST(EggTable, object); 00035 00036 if (_table != (EggTable *)NULL) { 00037 // Now search for the child named "xform". This contains the 00038 // actual table data. 00039 EggGroupNode::iterator ci; 00040 bool found = false; 00041 for (ci = _table->begin(); ci != _table->end() && !found; ++ci) { 00042 EggNode *child = (*ci); 00043 if (child->get_name() == "xform") { 00044 if (child->is_of_type(EggXfmSAnim::get_class_type())) { 00045 _xform = DCAST(EggXfmSAnim, child); 00046 _xform->normalize(); 00047 found = true; 00048 00049 } else if (child->is_of_type(EggXfmAnimData::get_class_type())) { 00050 // Quietly replace old-style XfmAnim tables with new-style 00051 // XfmSAnim tables. 00052 PT(EggXfmAnimData) anim = DCAST(EggXfmAnimData, child); 00053 _xform = new EggXfmSAnim(*anim); 00054 _table->replace(ci, _xform.p()); 00055 found = true; 00056 } 00057 } 00058 } 00059 } 00060 } 00061 00062 //////////////////////////////////////////////////////////////////// 00063 // Function: EggMatrixTablePointer::get_num_frames 00064 // Access: Public, Virtual 00065 // Description: Returns the number of frames of animation for this 00066 // particular joint. 00067 //////////////////////////////////////////////////////////////////// 00068 int EggMatrixTablePointer:: 00069 get_num_frames() const { 00070 if (_xform == (EggXfmSAnim *)NULL) { 00071 return 0; 00072 } else { 00073 return _xform->get_num_rows(); 00074 } 00075 } 00076 00077 //////////////////////////////////////////////////////////////////// 00078 // Function: EggMatrixTablePointer::get_frame 00079 // Access: Public, Virtual 00080 // Description: Returns the transform matrix corresponding to this 00081 // joint position in the nth frame. 00082 //////////////////////////////////////////////////////////////////// 00083 LMatrix4d EggMatrixTablePointer:: 00084 get_frame(int n) const { 00085 if (get_num_frames() == 1) { 00086 // If we have exactly one frame, then we have as many frames as we 00087 // want; just repeat the first frame. 00088 n = 0; 00089 } 00090 00091 nassertr(n >= 0 && n < get_num_frames(), LMatrix4d::ident_mat()); 00092 LMatrix4d mat; 00093 _xform->get_value(n, mat); 00094 return mat; 00095 } 00096 00097 //////////////////////////////////////////////////////////////////// 00098 // Function: EggMatrixTablePointer::set_frame 00099 // Access: Public, Virtual 00100 // Description: Sets the transform matrix corresponding to this 00101 // joint position in the nth frame. 00102 //////////////////////////////////////////////////////////////////// 00103 void EggMatrixTablePointer:: 00104 set_frame(int n, const LMatrix4d &mat) { 00105 nassertv(n >= 0 && n < get_num_frames()); 00106 _xform->set_value(n, mat); 00107 } 00108 00109 //////////////////////////////////////////////////////////////////// 00110 // Function: EggMatrixTablePointer::add_frame 00111 // Access: Public, Virtual 00112 // Description: Appends a new frame onto the end of the data, if 00113 // possible; returns true if not possible, or false 00114 // otherwise (e.g. for a static joint). 00115 //////////////////////////////////////////////////////////////////// 00116 bool EggMatrixTablePointer:: 00117 add_frame(const LMatrix4d &mat) { 00118 if (_xform == (EggXfmSAnim *)NULL) { 00119 return false; 00120 } 00121 00122 return _xform->add_data(mat); 00123 } 00124 00125 //////////////////////////////////////////////////////////////////// 00126 // Function: EggMatrixTablePointer::do_rebuild 00127 // Access: Public, Virtual 00128 // Description: Rebuilds the entire table all at once, based on the 00129 // frames added by repeated calls to add_rebuild_frame() 00130 // since the last call to begin_rebuild(). 00131 // 00132 // Until do_rebuild() is called, the animation table is 00133 // not changed. 00134 // 00135 // The return value is true if all frames are 00136 // acceptable, or false if there is some problem. 00137 //////////////////////////////////////////////////////////////////// 00138 bool EggMatrixTablePointer:: 00139 do_rebuild() { 00140 if (_rebuild_frames.empty()) { 00141 return true; 00142 } 00143 00144 if (_xform == (EggXfmSAnim *)NULL) { 00145 return false; 00146 } 00147 00148 _xform->clear_data(); 00149 RebuildFrames::const_iterator fi; 00150 for (fi = _rebuild_frames.begin(); fi != _rebuild_frames.end(); ++fi) { 00151 if (!_xform->add_data(*fi)) { 00152 return false; 00153 } 00154 } 00155 00156 _rebuild_frames.clear(); 00157 return true; 00158 } 00159 00160 //////////////////////////////////////////////////////////////////// 00161 // Function: EggMatrixTablePointer::optimize 00162 // Access: Public, Virtual 00163 // Description: Resets the table before writing to disk so that 00164 // redundant rows (e.g. i { 1 1 1 1 1 1 1 1 }) are 00165 // collapsed out. 00166 //////////////////////////////////////////////////////////////////// 00167 void EggMatrixTablePointer:: 00168 optimize() { 00169 if (_xform != (EggXfmSAnim *)NULL) { 00170 _xform->optimize(); 00171 } 00172 }