00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "colladaInput.h"
00016 #include "string_utils.h"
00017 #include "geomVertexArrayFormat.h"
00018 #include "geomVertexWriter.h"
00019
00020
00021 #include "pre_collada_include.h"
00022 #include <dom/domAccessor.h>
00023 #include <dom/domP.h>
00024 #include <dom/domSource.h>
00025 #include <dom/domVertices.h>
00026
00027 #if PANDA_COLLADA_VERSION >= 15
00028 #include <dom/domInput_local_offset.h>
00029 #include <dom/domInput_local.h>
00030 #else
00031 #include <dom/domInputLocalOffset.h>
00032 #include <dom/domInputLocal.h>
00033 #define domList_of_floats domListOfFloats
00034 #define domList_of_uints domListOfUInts
00035 #endif
00036
00037
00038
00039
00040
00041 ColladaInput::
00042 ColladaInput(const string &semantic) :
00043 _column_name (NULL),
00044 _semantic (semantic),
00045 _offset (0),
00046 _have_set (false),
00047 _set (0) {
00048
00049 if (semantic == "POSITION") {
00050 _column_name = InternalName::get_vertex();
00051 _column_contents = GeomEnums::C_point;
00052 } else if (semantic == "COLOR") {
00053 _column_name = InternalName::get_color();
00054 _column_contents = GeomEnums::C_color;
00055 } else if (semantic == "NORMAL") {
00056 _column_name = InternalName::get_normal();
00057 _column_contents = GeomEnums::C_vector;
00058 } else if (semantic == "TEXCOORD") {
00059 _column_name = InternalName::get_texcoord();
00060 _column_contents = GeomEnums::C_texcoord;
00061 } else if (semantic == "TEXBINORMAL") {
00062 _column_name = InternalName::get_binormal();
00063 _column_contents = GeomEnums::C_vector;
00064 } else if (semantic == "TEXTANGENT") {
00065 _column_name = InternalName::get_tangent();
00066 _column_contents = GeomEnums::C_vector;
00067 }
00068 }
00069
00070
00071
00072
00073
00074 ColladaInput::
00075 ColladaInput(const string &semantic, unsigned int set) :
00076 _column_name (NULL),
00077 _semantic (semantic),
00078 _offset (0),
00079 _have_set (true),
00080 _set (set) {
00081
00082 ostringstream setstr;
00083 setstr << _set;
00084
00085 if (semantic == "POSITION") {
00086 _column_name = InternalName::get_vertex();
00087 _column_contents = GeomEnums::C_point;
00088 } else if (semantic == "COLOR") {
00089 _column_name = InternalName::get_color();
00090 _column_contents = GeomEnums::C_color;
00091 } else if (semantic == "NORMAL") {
00092 _column_name = InternalName::get_normal();
00093 _column_contents = GeomEnums::C_vector;
00094 } else if (semantic == "TEXCOORD") {
00095 _column_name = InternalName::get_texcoord_name(setstr.str());
00096 _column_contents = GeomEnums::C_texcoord;
00097 } else if (semantic == "TEXBINORMAL") {
00098 _column_name = InternalName::get_binormal_name(setstr.str());
00099 _column_contents = GeomEnums::C_vector;
00100 } else if (semantic == "TEXTANGENT") {
00101 _column_name = InternalName::get_tangent_name(setstr.str());
00102 _column_contents = GeomEnums::C_vector;
00103 }
00104 }
00105
00106
00107
00108
00109
00110
00111 ColladaInput *ColladaInput::
00112 from_dom(domInput_local_offset &input) {
00113
00114 if (input.getUserData() != NULL) {
00115 return (ColladaInput *) input.getUserData();
00116 }
00117
00118 ColladaInput *new_input = new ColladaInput(input.getSemantic(), input.getSet());
00119 new_input->_offset = input.getOffset();
00120
00121
00122 if (new_input->is_vertex_source()) {
00123 domVertices *verts = daeSafeCast<domVertices> (input.getSource().getElement());
00124 nassertr(verts != NULL, NULL);
00125 daeTArray<domInput_localRef> &inputs = verts->getInput_array();
00126
00127
00128 for (size_t i = 0; i < inputs.getCount(); ++i) {
00129 PT(ColladaInput) vtx_input = ColladaInput::from_dom(*inputs[i]);
00130 new_input->_vertex_inputs.push_back(vtx_input);
00131 }
00132 } else {
00133 domSource *source = daeSafeCast<domSource> (input.getSource().getElement());
00134 nassertr(source != NULL, NULL);
00135 new_input->read_data(*source);
00136 }
00137
00138 return new_input;
00139 }
00140
00141
00142
00143
00144
00145
00146 ColladaInput *ColladaInput::
00147 from_dom(domInput_local &input) {
00148
00149 if (input.getUserData() != NULL) {
00150 return (ColladaInput *) input.getUserData();
00151 }
00152
00153 ColladaInput *new_input = new ColladaInput(input.getSemantic());
00154 new_input->_offset = 0;
00155
00156 nassertr (!new_input->is_vertex_source(), NULL);
00157
00158 domSource *source = daeSafeCast<domSource> (input.getSource().getElement());
00159 nassertr(source != NULL, NULL);
00160 new_input->read_data(*source);
00161
00162 return new_input;
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 int ColladaInput::
00174 make_vertex_columns(GeomVertexArrayFormat *format) const {
00175
00176 if (is_vertex_source()) {
00177 int counter = 0;
00178 Inputs::const_iterator it;
00179 for (it = _vertex_inputs.begin(); it != _vertex_inputs.end(); ++it) {
00180 counter += (*it)->make_vertex_columns(format);
00181 }
00182 return counter;
00183 }
00184
00185 nassertr(_column_name != NULL, 0);
00186
00187 format->add_column(_column_name, _num_bound_params, GeomEnums::NT_stdfloat, _column_contents);
00188 return 1;
00189 }
00190
00191
00192
00193
00194
00195 bool ColladaInput::
00196 read_data(domSource &source) {
00197 _data.clear();
00198
00199
00200 domFloat_array* float_array = source.getFloat_array();
00201 if (float_array == NULL) {
00202 return false;
00203 }
00204
00205 domList_of_floats &floats = float_array->getValue();
00206 domAccessor &accessor = *source.getTechnique_common()->getAccessor();
00207 domParam_Array ¶ms = accessor.getParam_array();
00208
00209
00210 _num_bound_params = 0;
00211 for (size_t p = 0; p < params.getCount(); ++p) {
00212 if (params[p]->getName()) {
00213 ++_num_bound_params;
00214 }
00215 }
00216
00217 _data.reserve(accessor.getCount());
00218
00219 domUint pos = accessor.getOffset();
00220 for (domUint a = 0; a < accessor.getCount(); ++a) {
00221 domUint c = 0;
00222
00223
00224 LVecBase4f v (0, 0, 0, 1);
00225 for (domUint p = 0; p < params.getCount(); ++p) {
00226 if (params[c]->getName()) {
00227 v[c++] = floats[pos + p];
00228 }
00229 }
00230 _data.push_back(v);
00231 pos += accessor.getStride();
00232 }
00233
00234 return true;
00235 }
00236
00237
00238
00239
00240
00241
00242 void ColladaInput::
00243 write_data(GeomVertexData *vdata, int start_row, domP &p, unsigned int stride) const {
00244 if (is_vertex_source()) {
00245 Inputs::const_iterator it;
00246 for (it = _vertex_inputs.begin(); it != _vertex_inputs.end(); ++it) {
00247 (*it)->write_data(vdata, start_row, p, stride, _offset);
00248 }
00249
00250 } else {
00251 write_data(vdata, start_row, p, stride, _offset);
00252 }
00253 }
00254
00255
00256
00257
00258
00259 void ColladaInput::
00260 write_data(GeomVertexData *vdata, int start_row, domP &p, unsigned int stride, unsigned int offset) const {
00261 nassertv(_column_name != NULL);
00262 GeomVertexWriter writer (vdata, _column_name);
00263 writer.set_row_unsafe(start_row);
00264
00265 domList_of_uints &indices = p.getValue();
00266
00267
00268 int min_length = start_row + indices.getCount() / stride;
00269 if (vdata->get_num_rows() < min_length) {
00270 vdata->unclean_set_num_rows(start_row);
00271 }
00272
00273 for (size_t i = 0; i < indices.getCount(); i += stride) {
00274 size_t index = indices[i + offset];
00275 writer.add_data4f(_data[index]);
00276 }
00277 }