Panda3D
 All Classes Functions Variables Enumerations
colladaPrimitive.cxx
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 
 All Classes Functions Variables Enumerations