Panda3D
|
00001 // Filename: colladaPrimitive.cxx 00002 // Created by: rdb (23May11) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "colladaPrimitive.h" 00016 #include "geomLines.h" 00017 #include "geomLinestrips.h" 00018 #include "geomTriangles.h" 00019 #include "geomTrifans.h" 00020 #include "geomTristrips.h" 00021 00022 // Collada DOM includes. No other includes beyond this point. 00023 #include "pre_collada_include.h" 00024 #include <dom/domLines.h> 00025 #include <dom/domLinestrips.h> 00026 #include <dom/domPolygons.h> 00027 #include <dom/domPolylist.h> 00028 #include <dom/domTriangles.h> 00029 #include <dom/domTrifans.h> 00030 #include <dom/domTristrips.h> 00031 00032 #if PANDA_COLLADA_VERSION < 15 00033 #define domInput_local_offsetRef domInputLocalOffsetRef 00034 #endif 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Function: ColladaPrimitive::Constructor 00038 // Description: Why do I even bother documenting the simplest of 00039 // constructors? A private one at that. 00040 //////////////////////////////////////////////////////////////////// 00041 ColladaPrimitive:: 00042 ColladaPrimitive(GeomPrimitive *prim, daeTArray<domInput_local_offsetRef> &inputs) 00043 : _stride (1), _gprim (prim) { 00044 00045 PT(GeomVertexArrayFormat) aformat = new GeomVertexArrayFormat; 00046 00047 // Add the inputs one by one. 00048 for (size_t in = 0; in < inputs.getCount(); ++in) { 00049 PT(ColladaInput) input = ColladaInput::from_dom(*inputs[in]); 00050 add_input(input); 00051 00052 input->make_vertex_columns(aformat); 00053 } 00054 00055 // Create the vertex data. 00056 PT(GeomVertexFormat) format = new GeomVertexFormat(); 00057 format->add_array(aformat); 00058 _vdata = new GeomVertexData("", GeomVertexFormat::register_format(format), GeomEnums::UH_static); 00059 _geom = new Geom(_vdata); 00060 _geom->add_primitive(_gprim); 00061 } 00062 00063 //////////////////////////////////////////////////////////////////// 00064 // Function: ColladaPrimitive::from_dom 00065 // Description: Returns the ColladaPrimitive object that represents 00066 // the provided DOM input element. 00067 //////////////////////////////////////////////////////////////////// 00068 ColladaPrimitive *ColladaPrimitive:: 00069 from_dom(domLines &prim) { 00070 // If we already loaded it before, use that. 00071 if (prim.getUserData() != NULL) { 00072 return (ColladaPrimitive *) prim.getUserData(); 00073 } 00074 00075 ColladaPrimitive *new_prim = 00076 new ColladaPrimitive(new GeomLines(GeomEnums::UH_static), 00077 prim.getInput_array()); 00078 new_prim->_material = prim.getMaterial(); 00079 00080 prim.setUserData(new_prim); 00081 00082 domPRef p = prim.getP(); 00083 if (p != NULL) { 00084 new_prim->load_primitive(*p); 00085 } 00086 00087 return new_prim; 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: ColladaPrimitive::from_dom 00092 // Description: Returns the ColladaPrimitive object that represents 00093 // the provided DOM input element. 00094 //////////////////////////////////////////////////////////////////// 00095 ColladaPrimitive *ColladaPrimitive:: 00096 from_dom(domLinestrips &prim) { 00097 // If we already loaded it before, use that. 00098 if (prim.getUserData() != NULL) { 00099 return (ColladaPrimitive *) prim.getUserData(); 00100 } 00101 00102 ColladaPrimitive *new_prim = 00103 new ColladaPrimitive(new GeomLinestrips(GeomEnums::UH_static), 00104 prim.getInput_array()); 00105 new_prim->_material = prim.getMaterial(); 00106 00107 prim.setUserData(new_prim); 00108 00109 new_prim->load_primitives(prim.getP_array()); 00110 00111 return new_prim; 00112 } 00113 00114 //////////////////////////////////////////////////////////////////// 00115 // Function: ColladaPrimitive::from_dom 00116 // Description: Returns the ColladaPrimitive object that represents 00117 // the provided DOM input element. 00118 //////////////////////////////////////////////////////////////////// 00119 ColladaPrimitive *ColladaPrimitive:: 00120 from_dom(domPolygons &prim) { 00121 // If we already loaded it before, use that. 00122 if (prim.getUserData() != NULL) { 00123 return (ColladaPrimitive *) prim.getUserData(); 00124 } 00125 00126 // We use trifans to represent polygons, seems to be easiest. 00127 // I tried using tristrips instead, but for some reason, 00128 // this resulted in a few flipped polygons. Weird. 00129 ColladaPrimitive *new_prim = 00130 new ColladaPrimitive(new GeomTrifans(GeomEnums::UH_static), 00131 prim.getInput_array()); 00132 new_prim->_material = prim.getMaterial(); 00133 00134 prim.setUserData(new_prim); 00135 00136 new_prim->load_primitives(prim.getP_array()); 00137 00138 if (prim.getPh_array().getCount() > 0) { 00139 collada_cat.error() 00140 << "Polygons with holes are not supported!\n"; 00141 } 00142 00143 return new_prim; 00144 } 00145 00146 //////////////////////////////////////////////////////////////////// 00147 // Function: ColladaPrimitive::from_dom 00148 // Description: Returns the ColladaPrimitive object that represents 00149 // the provided DOM input element. 00150 //////////////////////////////////////////////////////////////////// 00151 ColladaPrimitive *ColladaPrimitive:: 00152 from_dom(domPolylist &prim) { 00153 // If we already loaded it before, use that. 00154 if (prim.getUserData() != NULL) { 00155 return (ColladaPrimitive *) prim.getUserData(); 00156 } 00157 00158 // We use trifans to represent polygons, seems to be easiest. 00159 // I tried using tristrips instead, but for some reason, 00160 // this resulted in a few flipped polygons. Weird. 00161 PT(GeomPrimitive) gprim = new GeomTrifans(GeomEnums::UH_static); 00162 00163 ColladaPrimitive *new_prim = 00164 new ColladaPrimitive(gprim, prim.getInput_array()); 00165 new_prim->_material = prim.getMaterial(); 00166 00167 prim.setUserData(new_prim); 00168 00169 domPRef p = prim.getP(); 00170 domPolylist::domVcountRef vcounts = prim.getVcount(); 00171 if (p == NULL || vcounts == NULL) { 00172 return new_prim; 00173 } 00174 00175 new_prim->write_data(new_prim->_vdata, 0, *p); 00176 00177 daeTArray<domUint> &values = vcounts->getValue(); 00178 for (size_t i = 0; i < values.getCount(); ++i) { 00179 unsigned int vcount = values[i]; 00180 gprim->add_next_vertices(vcount); 00181 gprim->close_primitive(); 00182 } 00183 00184 return new_prim; 00185 } 00186 00187 //////////////////////////////////////////////////////////////////// 00188 // Function: ColladaPrimitive::from_dom 00189 // Description: Returns the ColladaPrimitive object that represents 00190 // the provided DOM input element. 00191 //////////////////////////////////////////////////////////////////// 00192 ColladaPrimitive *ColladaPrimitive:: 00193 from_dom(domTriangles &prim) { 00194 // If we already loaded it before, use that. 00195 if (prim.getUserData() != NULL) { 00196 return (ColladaPrimitive *) prim.getUserData(); 00197 } 00198 00199 ColladaPrimitive *new_prim = 00200 new ColladaPrimitive(new GeomTriangles(GeomEnums::UH_static), 00201 prim.getInput_array()); 00202 new_prim->_material = prim.getMaterial(); 00203 00204 prim.setUserData(new_prim); 00205 00206 domPRef p = prim.getP(); 00207 if (p != NULL) { 00208 new_prim->load_primitive(*p); 00209 } 00210 00211 return new_prim; 00212 } 00213 00214 //////////////////////////////////////////////////////////////////// 00215 // Function: ColladaPrimitive::from_dom 00216 // Description: Returns the ColladaPrimitive object that represents 00217 // the provided DOM input element. 00218 //////////////////////////////////////////////////////////////////// 00219 ColladaPrimitive *ColladaPrimitive:: 00220 from_dom(domTrifans &prim) { 00221 // If we already loaded it before, use that. 00222 if (prim.getUserData() != NULL) { 00223 return (ColladaPrimitive *) prim.getUserData(); 00224 } 00225 00226 ColladaPrimitive *new_prim = 00227 new ColladaPrimitive(new GeomTrifans(GeomEnums::UH_static), 00228 prim.getInput_array()); 00229 new_prim->_material = prim.getMaterial(); 00230 00231 prim.setUserData(new_prim); 00232 00233 new_prim->load_primitives(prim.getP_array()); 00234 00235 return new_prim; 00236 } 00237 00238 //////////////////////////////////////////////////////////////////// 00239 // Function: ColladaPrimitive::from_dom 00240 // Description: Returns the ColladaPrimitive object that represents 00241 // the provided DOM input element. 00242 //////////////////////////////////////////////////////////////////// 00243 ColladaPrimitive *ColladaPrimitive:: 00244 from_dom(domTristrips &prim) { 00245 // If we already loaded it before, use that. 00246 if (prim.getUserData() != NULL) { 00247 return (ColladaPrimitive *) prim.getUserData(); 00248 } 00249 00250 ColladaPrimitive *new_prim = 00251 new ColladaPrimitive(new GeomTristrips(GeomEnums::UH_static), 00252 prim.getInput_array()); 00253 new_prim->_material = prim.getMaterial(); 00254 00255 prim.setUserData(new_prim); 00256 00257 new_prim->load_primitives(prim.getP_array()); 00258 00259 return new_prim; 00260 } 00261 00262 //////////////////////////////////////////////////////////////////// 00263 // Function: ColladaPrimitive::write_data 00264 // Description: Writes the vertex data to the GeomVertexData. 00265 // Returns the number of rows written. 00266 //////////////////////////////////////////////////////////////////// 00267 unsigned int ColladaPrimitive:: 00268 write_data(GeomVertexData *vdata, int start_row, domP &p) { 00269 unsigned int num_vertices = p.getValue().getCount() / _stride; 00270 00271 Inputs::iterator it; 00272 for (it = _inputs.begin(); it != _inputs.end(); ++it) { 00273 (*it)->write_data(vdata, start_row, p, _stride); 00274 } 00275 00276 return num_vertices; 00277 } 00278 00279 //////////////////////////////////////////////////////////////////// 00280 // Function: ColladaPrimitive::load_primitive 00281 // Description: Adds the given indices to the primitive, and 00282 // writes the relevant data to the geom. 00283 //////////////////////////////////////////////////////////////////// 00284 void ColladaPrimitive:: 00285 load_primitive(domP &p) { 00286 _gprim->add_next_vertices(write_data(_vdata, 0, p)); 00287 _gprim->close_primitive(); 00288 } 00289 00290 //////////////////////////////////////////////////////////////////// 00291 // Function: ColladaPrimitive::load_primitives 00292 // Description: Adds the given indices to the primitive, and 00293 // writes the relevant data to the geom. 00294 //////////////////////////////////////////////////////////////////// 00295 void ColladaPrimitive:: 00296 load_primitives(domP_Array &p_array) { 00297 int start_row = 0; 00298 00299 for (size_t i = 0; i < p_array.getCount(); ++i) { 00300 unsigned int num_vertices = write_data(_vdata, start_row, *p_array[i]); 00301 _gprim->add_next_vertices(num_vertices); 00302 _gprim->close_primitive(); 00303 start_row += num_vertices; 00304 } 00305 } 00306