diff --git a/panda/src/char/character.cxx b/panda/src/char/character.cxx index a2d1de7e1c..63fd019c50 100644 --- a/panda/src/char/character.cxx +++ b/panda/src/char/character.cxx @@ -197,7 +197,12 @@ update() { PStatTimer timer(_char_pcollector); // First, update all the joints and sliders. - bool any_changed = get_bundle()->update(); + bool any_changed; + if (even_animation) { + any_changed = get_bundle()->force_update(); + } else { + any_changed = get_bundle()->update(); + } // Now update the vertices, if we need to. This is likely to be a // slow operation. diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index a9c111efc4..2c2fda5e79 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -36,7 +36,7 @@ #include "qpgeomVertexFormat.h" #include "qpgeomVertexArrayFormat.h" #include "qpgeomVertexData.h" -#include "qpgeomVertexIterator.h" +#include "qpgeomVertexWriter.h" #include "qpgeom.h" #include "qpgeomTriangles.h" #include "qpgeomTristrips.h" @@ -1987,21 +1987,21 @@ make_vertex_data(const EggRenderState *render_state, // And fill the data from the vertex pool. EggVertexPool::const_iterator vi; for (vi = vertex_pool->begin(); vi != vertex_pool->end(); ++vi) { - qpGeomVertexIterator gvi(vertex_data); + qpGeomVertexWriter gvi(vertex_data); EggVertex *vertex = (*vi); gvi.set_vertex(vertex->get_index()); gvi.set_data_type(InternalName::get_vertex()); - gvi.set_data4f(LCAST(float, vertex->get_pos4() * transform)); + gvi.add_data4f(LCAST(float, vertex->get_pos4() * transform)); if (vertex->has_normal()) { gvi.set_data_type(InternalName::get_normal()); - gvi.set_data3f(LCAST(float, vertex->get_normal() * transform)); + gvi.add_data3f(LCAST(float, vertex->get_normal() * transform)); } if (vertex->has_color()) { gvi.set_data_type(InternalName::get_color()); - gvi.set_data4f(vertex->get_color()); + gvi.add_data4f(vertex->get_color()); } EggVertex::const_uv_iterator uvi; diff --git a/panda/src/framework/windowFramework.cxx b/panda/src/framework/windowFramework.cxx index e9531c979b..61b87feec1 100644 --- a/panda/src/framework/windowFramework.cxx +++ b/panda/src/framework/windowFramework.cxx @@ -31,7 +31,7 @@ #include "qpgeomTristrips.h" #include "qpgeomVertexData.h" #include "qpgeomVertexFormat.h" -#include "qpgeomVertexIterator.h" +#include "qpgeomVertexWriter.h" #include "texturePool.h" #include "textureAttrib.h" #include "colorAttrib.h" @@ -635,26 +635,26 @@ load_default_model(const NodePath &parent) { PT(qpGeomVertexData) vdata = new qpGeomVertexData (string(), qpGeomVertexFormat::get_v3n3cpt2(), qpGeomUsageHint::UH_static); - qpGeomVertexIterator vertex(vdata, InternalName::get_vertex()); - qpGeomVertexIterator normal(vdata, InternalName::get_normal()); - qpGeomVertexIterator color(vdata, InternalName::get_color()); - qpGeomVertexIterator texcoord(vdata, InternalName::get_texcoord()); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); + qpGeomVertexWriter normal(vdata, InternalName::get_normal()); + qpGeomVertexWriter color(vdata, InternalName::get_color()); + qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); - vertex.set_data3f(Vertexf::rfu(0.0, 0.0, 0.0)); - vertex.set_data3f(Vertexf::rfu(1.0, 0.0, 0.0)); - vertex.set_data3f(Vertexf::rfu(0.0, 0.0, 1.0)); + vertex.add_data3f(Vertexf::rfu(0.0, 0.0, 0.0)); + vertex.add_data3f(Vertexf::rfu(1.0, 0.0, 0.0)); + vertex.add_data3f(Vertexf::rfu(0.0, 0.0, 1.0)); - normal.set_data3f(Normalf::back()); - normal.set_data3f(Normalf::back()); - normal.set_data3f(Normalf::back()); + normal.add_data3f(Normalf::back()); + normal.add_data3f(Normalf::back()); + normal.add_data3f(Normalf::back()); - color.set_data4f(0.5, 0.5, 1.0, 1.0); - color.set_data4f(0.5, 0.5, 1.0, 1.0); - color.set_data4f(0.5, 0.5, 1.0, 1.0); + color.add_data4f(0.5, 0.5, 1.0, 1.0); + color.add_data4f(0.5, 0.5, 1.0, 1.0); + color.add_data4f(0.5, 0.5, 1.0, 1.0); - texcoord.set_data2f(0.0, 0.0); - texcoord.set_data2f(1.0, 0.0); - texcoord.set_data2f(0.0, 1.0); + texcoord.add_data2f(0.0, 0.0); + texcoord.add_data2f(1.0, 0.0); + texcoord.add_data2f(0.0, 1.0); PT(qpGeomTriangles) tri = new qpGeomTriangles(qpGeomUsageHint::UH_static); tri->add_consecutive_vertices(0, 3); @@ -1062,18 +1062,18 @@ load_image_as_model(const Filename &filename) { PT(qpGeomVertexData) vdata = new qpGeomVertexData (string(), qpGeomVertexFormat::get_v3t2(), qpGeomUsageHint::UH_static); - qpGeomVertexIterator vertex(vdata, InternalName::get_vertex()); - qpGeomVertexIterator texcoord(vdata, InternalName::get_texcoord()); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); + qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); - vertex.set_data3f(Vertexf::rfu(left, 0.02f, top)); - vertex.set_data3f(Vertexf::rfu(left, 0.02f, bottom)); - vertex.set_data3f(Vertexf::rfu(right, 0.02f, top)); - vertex.set_data3f(Vertexf::rfu(right, 0.02f, bottom)); + vertex.add_data3f(Vertexf::rfu(left, 0.02f, top)); + vertex.add_data3f(Vertexf::rfu(left, 0.02f, bottom)); + vertex.add_data3f(Vertexf::rfu(right, 0.02f, top)); + vertex.add_data3f(Vertexf::rfu(right, 0.02f, bottom)); - texcoord.set_data2f(0.0f, 1.0f); - texcoord.set_data2f(0.0f, 0.0f); - texcoord.set_data2f(1.0f, 1.0f); - texcoord.set_data2f(1.0f, 0.0f); + texcoord.add_data2f(0.0f, 1.0f); + texcoord.add_data2f(0.0f, 0.0f); + texcoord.add_data2f(1.0f, 1.0f); + texcoord.add_data2f(1.0f, 0.0f); PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static); strip->add_consecutive_vertices(0, 4); diff --git a/panda/src/gobj/Sources.pp b/panda/src/gobj/Sources.pp index add1846389..a9c4780db0 100644 --- a/panda/src/gobj/Sources.pp +++ b/panda/src/gobj/Sources.pp @@ -35,8 +35,8 @@ qpgeomVertexData.h qpgeomVertexData.I \ qpgeomVertexDataType.h qpgeomVertexDataType.I \ qpgeomVertexFormat.h qpgeomVertexFormat.I \ - qpgeomVertexIterator.h qpgeomVertexIterator.I \ qpgeomVertexReader.h qpgeomVertexReader.I \ + qpgeomVertexWriter.h qpgeomVertexWriter.I \ indexBufferContext.I indexBufferContext.h \ internalName.I internalName.h \ material.I material.h materialPool.I materialPool.h \ @@ -81,8 +81,8 @@ qpgeomVertexData.cxx \ qpgeomVertexDataType.cxx \ qpgeomVertexFormat.cxx \ - qpgeomVertexIterator.cxx \ qpgeomVertexReader.cxx \ + qpgeomVertexWriter.cxx \ indexBufferContext.cxx \ material.cxx \ internalName.cxx \ @@ -125,8 +125,8 @@ qpgeomVertexData.h qpgeomVertexData.I \ qpgeomVertexDataType.h qpgeomVertexDataType.I \ qpgeomVertexFormat.h qpgeomVertexFormat.I \ - qpgeomVertexIterator.h qpgeomVertexIterator.I \ qpgeomVertexReader.h qpgeomVertexReader.I \ + qpgeomVertexWriter.h qpgeomVertexWriter.I \ indexBufferContext.I indexBufferContext.h \ internalName.I internalName.h \ material.I material.h \ diff --git a/panda/src/gobj/gobj_composite1.cxx b/panda/src/gobj/gobj_composite1.cxx index d3abc281d1..23d169deb7 100644 --- a/panda/src/gobj/gobj_composite1.cxx +++ b/panda/src/gobj/gobj_composite1.cxx @@ -27,5 +27,5 @@ #include "qpgeomVertexData.cxx" #include "qpgeomVertexDataType.cxx" #include "qpgeomVertexFormat.cxx" -#include "qpgeomVertexIterator.cxx" #include "qpgeomVertexReader.cxx" +#include "qpgeomVertexWriter.cxx" diff --git a/panda/src/gobj/qpgeom.cxx b/panda/src/gobj/qpgeom.cxx index 9b78808a8f..4cb4f7327e 100644 --- a/panda/src/gobj/qpgeom.cxx +++ b/panda/src/gobj/qpgeom.cxx @@ -17,6 +17,7 @@ //////////////////////////////////////////////////////////////////// #include "qpgeom.h" +#include "qpgeomVertexReader.h" #include "pStatTimer.h" #include "bamReader.h" #include "bamWriter.h" @@ -404,6 +405,32 @@ draw(GraphicsStateGuardianBase *gsg, const qpGeomMunger *munger, } } +//////////////////////////////////////////////////////////////////// +// Function: qpGeom::calc_tight_bounds +// Access: Public, Virtual +// Description: Expands min_point and max_point to include all of the +// vertices in the Geom, if any. found_any is set true +// if any points are found. It is the caller's +// responsibility to initialize min_point, max_point, +// and found_any before calling this function. +//////////////////////////////////////////////////////////////////// +void qpGeom:: +calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, + bool &found_any, + const qpGeomVertexData *vertex_data, + bool got_mat, const LMatrix4f &mat) const { + + CDReader cdata(_cycler); + + Primitives::const_iterator pi; + for (pi = cdata->_primitives.begin(); + pi != cdata->_primitives.end(); + ++pi) { + (*pi)->calc_tight_bounds(min_point, max_point, found_any, vertex_data, + got_mat, mat); + } +} + //////////////////////////////////////////////////////////////////// // Function: qpGeom::get_next_modified // Access: Public, Static @@ -437,56 +464,22 @@ recompute_bound() { GeometricBoundingVolume *gbv = DCAST(GeometricBoundingVolume, bound); - // Now actually compute the bounding volume by putting it around all - // of our vertices. - CDReader cdata(_cycler); + // Now actually compute the bounding volume. We do this by using + // calc_tight_bounds to determine our minmax first. + LPoint3f points[2]; + bool found_any = false; + calc_tight_bounds(points[0], points[1], found_any, get_vertex_data(), + false, LMatrix4f::ident_mat()); + if (found_any) { + // Then we put the bounding volume around both of those points. + // Technically, we should put it around the eight points at the + // corners of the rectangular solid, but we happen to know that + // the two diagonally opposite points is good enough to define any + // of our bound volume types. - const qpGeomVertexFormat *format = cdata->_data->get_format(); - - int array_index = format->get_array_with(InternalName::get_vertex()); - if (array_index < 0) { - // No vertex data. - return bound; - } - - const qpGeomVertexArrayFormat *array_format = format->get_array(array_index); - const qpGeomVertexDataType *data_type = - array_format->get_data_type(InternalName::get_vertex()); - - int stride = array_format->get_stride(); - int start = data_type->get_start(); - int num_components = data_type->get_num_components(); - - CPTA_uchar array_data = cdata->_data->get_array(array_index)->get_data(); - - if (stride == 3 * sizeof(PN_float32) && start == 0 && num_components == 3 && - (array_data.size() % stride) == 0) { - // Here's an easy special case: it's a standalone table of vertex - // positions, with nothing else in the middle, so we can use - // directly as an array of LPoint3f's. - const LPoint3f *vertices_begin = (const LPoint3f *)&array_data[0]; - const LPoint3f *vertices_end = (const LPoint3f *)&array_data[array_data.size()]; - gbv->around(vertices_begin, vertices_end); - - } else { - // Otherwise, we have to copy the vertex positions out one at time. - pvector vertices; - - size_t p = start; - while (p + stride <= array_data.size()) { - const PN_float32 *v = (const PN_float32 *)&array_data[p]; - - LPoint3f vertex; - qpGeomVertexData::to_vec3(vertex, v, num_components); - - vertices.push_back(vertex); - p += stride; - } - - const LPoint3f *vertices_begin = &vertices[0]; - const LPoint3f *vertices_end = vertices_begin + vertices.size(); - - gbv->around(vertices_begin, vertices_end); + const LPoint3f *points_begin = &points[0]; + const LPoint3f *points_end = points_begin + 2; + gbv->around(points_begin, points_end); } return bound; diff --git a/panda/src/gobj/qpgeom.h b/panda/src/gobj/qpgeom.h index c8250ae16e..4943cda0af 100644 --- a/panda/src/gobj/qpgeom.h +++ b/panda/src/gobj/qpgeom.h @@ -97,6 +97,11 @@ public: const qpGeomMunger *munger, const qpGeomVertexData *vertex_data) const; + void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, + bool &found_any, + const qpGeomVertexData *vertex_data, + bool got_mat, const LMatrix4f &mat) const; + static UpdateSeq get_next_modified(); protected: diff --git a/panda/src/gobj/qpgeomPrimitive.cxx b/panda/src/gobj/qpgeomPrimitive.cxx index f6b35208f2..30c1f06c13 100644 --- a/panda/src/gobj/qpgeomPrimitive.cxx +++ b/panda/src/gobj/qpgeomPrimitive.cxx @@ -21,6 +21,7 @@ #include "qpgeomVertexData.h" #include "qpgeomVertexArrayFormat.h" #include "qpgeomVertexDataType.h" +#include "qpgeomVertexReader.h" #include "preparedGraphicsObjects.h" #include "internalName.h" #include "bamReader.h" @@ -671,46 +672,55 @@ clear_prepared(PreparedGraphicsObjects *prepared_objects) { void qpGeomPrimitive:: calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, - const qpGeomVertexData *vertex_data) const { - CDReader cdata(_cycler); - - const qpGeomVertexFormat *format = vertex_data->get_format(); - - int array_index = format->get_array_with(InternalName::get_vertex()); - if (array_index < 0) { + const qpGeomVertexData *vertex_data, + bool got_mat, const LMatrix4f &mat) const { + qpGeomVertexReader reader(vertex_data, InternalName::get_vertex()); + if (!reader.has_data_type()) { // No vertex data. return; } - const qpGeomVertexArrayFormat *array_format = format->get_array(array_index); - const qpGeomVertexDataType *data_type = - array_format->get_data_type(InternalName::get_vertex()); + CDReader cdata(_cycler); - int stride = array_format->get_stride(); - int start = data_type->get_start(); - int num_components = data_type->get_num_components(); - - CPTA_uchar array_data = vertex_data->get_array(array_index)->get_data(); - - PTA_ushort::const_iterator ii; - for (ii = cdata->_vertices.begin(); ii != cdata->_vertices.end(); ++ii) { - int index = (int)(*ii); - const PN_float32 *v = (const PN_float32 *)&array_data[start + index * stride]; - - LPoint3f vertex; - qpGeomVertexData::to_vec3(vertex, v, num_components); - - if (found_any) { - min_point.set(min(min_point[0], vertex[0]), - min(min_point[1], vertex[1]), - min(min_point[2], vertex[2])); - max_point.set(max(max_point[0], vertex[0]), - max(max_point[1], vertex[1]), - max(max_point[2], vertex[2])); - } else { - min_point = vertex; - max_point = vertex; - found_any = true; + if (got_mat) { + PTA_ushort::const_iterator ii; + for (ii = cdata->_vertices.begin(); ii != cdata->_vertices.end(); ++ii) { + int index = (int)(*ii); + reader.set_vertex(index); + const LVecBase3f &vertex = reader.get_data3f(); + + if (found_any) { + min_point.set(min(min_point[0], vertex[0]), + min(min_point[1], vertex[1]), + min(min_point[2], vertex[2])); + max_point.set(max(max_point[0], vertex[0]), + max(max_point[1], vertex[1]), + max(max_point[2], vertex[2])); + } else { + min_point = vertex; + max_point = vertex; + found_any = true; + } + } + } else { + PTA_ushort::const_iterator ii; + for (ii = cdata->_vertices.begin(); ii != cdata->_vertices.end(); ++ii) { + int index = (int)(*ii); + reader.set_vertex(index); + LPoint3f vertex = mat.xform_point(reader.get_data3f()); + + if (found_any) { + min_point.set(min(min_point[0], vertex[0]), + min(min_point[1], vertex[1]), + min(min_point[2], vertex[2])); + max_point.set(max(max_point[0], vertex[0]), + max(max_point[1], vertex[1]), + max(max_point[2], vertex[2])); + } else { + min_point = vertex; + max_point = vertex; + found_any = true; + } } } } diff --git a/panda/src/gobj/qpgeomPrimitive.h b/panda/src/gobj/qpgeomPrimitive.h index 8267eae6d5..08de9cb8b2 100644 --- a/panda/src/gobj/qpgeomPrimitive.h +++ b/panda/src/gobj/qpgeomPrimitive.h @@ -162,9 +162,10 @@ private: public: virtual void draw(GraphicsStateGuardianBase *gsg) const=0; - virtual void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, - bool &found_any, - const qpGeomVertexData *vertex_data) const; + void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, + bool &found_any, + const qpGeomVertexData *vertex_data, + bool got_mat, const LMatrix4f &mat) const; protected: virtual CPT(qpGeomPrimitive) decompose_impl() const; diff --git a/panda/src/gobj/qpgeomVertexArrayFormat.cxx b/panda/src/gobj/qpgeomVertexArrayFormat.cxx index 7a3875cf0b..8ca20ff4fa 100644 --- a/panda/src/gobj/qpgeomVertexArrayFormat.cxx +++ b/panda/src/gobj/qpgeomVertexArrayFormat.cxx @@ -19,6 +19,7 @@ #include "qpgeomVertexFormat.h" #include "qpgeomVertexDataType.h" #include "qpgeomVertexData.h" +#include "qpgeomVertexReader.h" #include "indent.h" #include "bamReader.h" #include "bamWriter.h" @@ -430,20 +431,24 @@ write_with_data(ostream &out, int indent_level, const qpGeomVertexData *data, int array_index) const { consider_sort_data_types(); int num_vertices = data->get_num_vertices(); + + qpGeomVertexReader reader(data); + for (int i = 0; i < num_vertices; i++) { indent(out, indent_level) << "vertex index " << i << ":\n"; + reader.set_vertex(i); DataTypes::const_iterator dti; for (dti = _data_types.begin(); dti != _data_types.end(); ++dti) { const qpGeomVertexDataType *data_type = (*dti); int num_values = min(data_type->get_num_values(), 4); - float data_values[4]; - data->get_data(array_index, data_type, i, data_values, num_values); + reader.set_data_type(array_index, data_type); + const LVecBase4f &d = reader.get_data4f(); indent(out, indent_level + 2) << *data_type->get_name(); for (int v = 0; v < num_values; v++) { - out << " " << data_values[v]; + out << " " << d[v]; } out << "\n"; } diff --git a/panda/src/gobj/qpgeomVertexData.cxx b/panda/src/gobj/qpgeomVertexData.cxx index 71a44e8de5..dac674e8e4 100644 --- a/panda/src/gobj/qpgeomVertexData.cxx +++ b/panda/src/gobj/qpgeomVertexData.cxx @@ -17,8 +17,8 @@ //////////////////////////////////////////////////////////////////// #include "qpgeomVertexData.h" -#include "qpgeomVertexIterator.h" #include "qpgeomVertexReader.h" +#include "qpgeomVertexWriter.h" #include "pStatTimer.h" #include "bamReader.h" #include "bamWriter.h" @@ -381,8 +381,8 @@ scale_color(const LVecBase4f &color_scale, int num_components, contents, get_usage_hint(), true); // Now go through and apply the scale, copying it to the new data. - qpGeomVertexIterator from(this, InternalName::get_color()); - qpGeomVertexIterator to(new_data, InternalName::get_color()); + qpGeomVertexReader from(this, InternalName::get_color()); + qpGeomVertexWriter to(new_data, InternalName::get_color()); for (int i = 0; i < num_vertices; i++) { Colorf color = from.get_data4f(); @@ -423,7 +423,7 @@ set_color(const Colorf &color, int num_components, contents, get_usage_hint(), true); // Now go through and set the new color value. - qpGeomVertexIterator to(new_data, InternalName::get_color()); + qpGeomVertexWriter to(new_data, InternalName::get_color()); for (int i = 0; i < num_vertices; i++) { to.set_data4f(color); @@ -522,16 +522,23 @@ replace_data_type(const InternalName *name, int num_components, new qpGeomVertexArrayFormat(name, num_components, numeric_type, contents); new_type_array = new_format->add_array(type_array_format); } - + + CPT(qpGeomVertexFormat) format = + qpGeomVertexFormat::register_format(new_format); + + if (gobj_cat.is_debug()) { + gobj_cat.debug() + << "Replacing data type " << *name << "; converting " + << get_num_vertices() << " vertices from " + << *_format << " to " << *new_format << "\n"; + } + PT(qpGeomVertexData) new_data = - new qpGeomVertexData(get_name(), - qpGeomVertexFormat::register_format(new_format), - usage_hint); + new qpGeomVertexData(get_name(), format, usage_hint); if (keep_animation) { new_data->set_transform_blend_palette(get_transform_blend_palette()); } - int j = 0; int num_arrays = get_num_arrays(); for (int i = 0; i < num_arrays; ++i) { @@ -589,398 +596,6 @@ write(ostream &out, int indent_level) const { } } -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::set_data -// Access: Public -// Description: Sets the nth vertex to a particular value. Query the -// format to get the array index and data_type -// parameters for the particular data type you want to -// set. -// -// This flavor of set_data() accepts a generic float -// array and a specific number of dimensions. The new -// data will be copied from the num_values elements -// of data. -//////////////////////////////////////////////////////////////////// -void qpGeomVertexData:: -set_data(int array, const qpGeomVertexDataType *data_type, - int vertex, const float *data, int num_values) { - int stride = _format->get_array(array)->get_stride(); - int element = vertex * stride + data_type->get_start(); - - { - CDReader cdata(_cycler); - int array_size = (int)cdata->_arrays[array]->get_data_size_bytes(); - if (element + data_type->get_total_bytes() > array_size) { - // Whoops, we need more vertices! - CDWriter cdataw(_cycler, cdata); - do_set_num_vertices(vertex + 1, cdataw); - } - } - - PTA_uchar array_data = modify_array(array)->modify_data(); - nassertv(element >= 0 && element + data_type->get_total_bytes() <= (int)array_data.size()); - - switch (data_type->get_numeric_type()) { - case qpGeomVertexDataType::NT_uint16: - { - // Elevate or truncate to the right number of components. - int i = 0; - int min_values = min(num_values, data_type->get_num_values()); - while (i < min_values) { - *(PN_uint16 *)&array_data[element] = (int)data[i]; - element += sizeof(PN_uint16); - ++i; - } - while (i < data_type->get_num_values()) { - *(PN_uint16 *)&array_data[element] = 0; - element += sizeof(PN_uint16); - ++i; - } - } - - break; - - case qpGeomVertexDataType::NT_uint8: - { - int i = 0; - int min_values = min(num_values, data_type->get_num_values()); - while (i < min_values) { - int value = (int)(data[i] * 255.0f); - array_data[element] = value; - element += 1; - ++i; - } - while (i < data_type->get_num_values()) { - array_data[element] = 0; - element += 1; - ++i; - } - } - break; - - case qpGeomVertexDataType::NT_packed_8888: - { - if (num_values == 4) { - *(PN_uint32 *)&array_data[element] = pack_argb(data); - } else { - // Elevate (or truncate) to 4 components. - float data4[4]; - memset(data4, 0, 4 * sizeof(float)); - memcpy(data4, data, min(4, num_values) * sizeof(float)); - *(PN_uint32 *)&array_data[element] = pack_argb(data4); - } - } - break; - - case qpGeomVertexDataType::NT_float32: - if (num_values == 4 && sizeof(float) == sizeof(PN_float32)) { - // The easy way: we can memcpy the data directly in. - memcpy(&array_data[element], data, data_type->get_total_bytes()); - - } else { - // Elevate or truncate to the right number of components. - int i = 0; - int min_values = min(num_values, data_type->get_num_values()); - while (i < min_values) { - *(PN_float32 *)&array_data[element] = data[i]; - element += sizeof(PN_float32); - ++i; - } - while (i < data_type->get_num_values()) { - if (i == 3 && data_type->get_num_values() == 4) { - *(PN_float32 *)&array_data[element] = 1.0f; - } else { - *(PN_float32 *)&array_data[element] = 0.0f; - } - element += sizeof(PN_float32); - ++i; - } - } - - break; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::get_data -// Access: Public -// Description: Returns the data associated with the nth vertex for a -// particular value. Query the format to get the array -// index and data_type parameters for the particular -// data type you want to get. -// -// This flavor of get_data() copies its data into a -// generic float array. -//////////////////////////////////////////////////////////////////// -void qpGeomVertexData:: -get_data(int array, const qpGeomVertexDataType *data_type, - int vertex, float *data, int num_values) const { - CPTA_uchar array_data = get_array(array)->get_data(); - int stride = _format->get_array(array)->get_stride(); - int element = vertex * stride + data_type->get_start(); - nassertv(element >= 0 && element + data_type->get_total_bytes() <= (int)array_data.size()); - - switch (data_type->get_numeric_type()) { - case qpGeomVertexDataType::NT_uint16: - { - int i = 0; - int min_values = min(num_values, data_type->get_num_values()); - while (i < min_values) { - data[i] = *(PN_uint16 *)&array_data[element]; - element += sizeof(PN_uint16); - ++i; - } - while (i < num_values) { - data[i] = 0; - ++i; - } - } - break; - - case qpGeomVertexDataType::NT_uint8: - { - int i = 0; - int min_values = min(num_values, data_type->get_num_values()); - while (i < min_values) { - int value = *(unsigned char *)&array_data[element]; - element += 1; - data[i] = (float)value / 255.0f; - ++i; - } - while (i < num_values) { - data[i] = 0.0f; - ++i; - } - } - break; - - case qpGeomVertexDataType::NT_packed_8888: - { - if (num_values == 4) { - unpack_argb(data, *(PN_uint32 *)&array_data[element]); - } else { - float data4[4]; - unpack_argb(data4, *(PN_uint32 *)&array_data[element]); - memset(data, 0, num_values * sizeof(float)); - memcpy(data, data4, min(num_values, 4) * sizeof(float)); - } - } - break; - - case qpGeomVertexDataType::NT_float32: - if (num_values == data_type->get_num_values() && - sizeof(float) == sizeof(PN_float32)) { - memcpy(data, &array_data[element], num_values * sizeof(PN_float32)); - } else { - int i = 0; - int min_values = min(num_values, data_type->get_num_values()); - while (i < min_values) { - data[i] = *(PN_float32 *)&array_data[element]; - element += sizeof(PN_float32); - ++i; - } - while (i < num_values) { - if (i == 3 && num_values == 4) { - data[i] = 1.0f; - } else { - data[i] = 0.0f; - } - ++i; - } - } - break; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::set_data -// Access: Public -// Description: Sets the nth vertex to a particular value. Query the -// format to get the array index and data_type -// parameters for the particular data type you want to -// set. -// -// This flavor of set_data() accepts a generic float -// array and a specific number of dimensions. The new -// data will be copied from the num_values elements -// of data. -//////////////////////////////////////////////////////////////////// -void qpGeomVertexData:: -set_data(int array, const qpGeomVertexDataType *data_type, - int vertex, const int *data, int num_values) { - int stride = _format->get_array(array)->get_stride(); - int element = vertex * stride + data_type->get_start(); - - { - CDReader cdata(_cycler); - int array_size = (int)cdata->_arrays[array]->get_data_size_bytes(); - if (element + data_type->get_total_bytes() > array_size) { - // Whoops, we need more vertices! - CDWriter cdataw(_cycler, cdata); - do_set_num_vertices(vertex + 1, cdataw); - } - } - - PTA_uchar array_data = modify_array(array)->modify_data(); - nassertv(element >= 0 && element + data_type->get_total_bytes() <= (int)array_data.size()); - - switch (data_type->get_numeric_type()) { - case qpGeomVertexDataType::NT_uint16: - { - // Elevate or truncate to the right number of components. - int i = 0; - int min_values = min(num_values, data_type->get_num_values()); - while (i < min_values) { - *(PN_uint16 *)&array_data[element] = data[i]; - element += sizeof(PN_uint16); - ++i; - } - while (i < data_type->get_num_values()) { - *(PN_uint16 *)&array_data[element] = 0; - element += sizeof(PN_uint16); - ++i; - } - } - - break; - - case qpGeomVertexDataType::NT_uint8: - { - int i = 0; - int min_values = min(num_values, data_type->get_num_values()); - while (i < min_values) { - array_data[element] = data[i]; - element += 1; - ++i; - } - while (i < data_type->get_num_values()) { - array_data[element] = 0; - element += 1; - ++i; - } - } - break; - - case qpGeomVertexDataType::NT_packed_8888: - { - if (num_values == 4) { - *(PN_uint32 *)&array_data[element] = pack_argb(data); - } else { - // Elevate (or truncate) to 4 components. - int data4[4]; - memset(data4, 0, 4 * sizeof(int)); - memcpy(data4, data, min(4, num_values) * sizeof(int)); - *(PN_uint32 *)&array_data[element] = pack_argb(data4); - } - } - break; - - case qpGeomVertexDataType::NT_float32: - { - // Elevate or truncate to the right number of components. - int i = 0; - int min_values = min(num_values, data_type->get_num_values()); - while (i < min_values) { - *(PN_float32 *)&array_data[element] = data[i]; - element += sizeof(PN_float32); - ++i; - } - while (i < data_type->get_num_values()) { - *(PN_float32 *)&array_data[element] = 0.0f; - element += sizeof(PN_float32); - ++i; - } - } - - break; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::get_data -// Access: Public -// Description: Returns the data associated with the nth vertex for a -// particular value. Query the format to get the array -// index and data_type parameters for the particular -// data type you want to get. -// -// This flavor of get_data() copies its data into a -// generic float array. -//////////////////////////////////////////////////////////////////// -void qpGeomVertexData:: -get_data(int array, const qpGeomVertexDataType *data_type, - int vertex, int *data, int num_values) const { - CPTA_uchar array_data = get_array(array)->get_data(); - int stride = _format->get_array(array)->get_stride(); - int element = vertex * stride + data_type->get_start(); - nassertv(element >= 0 && element + data_type->get_total_bytes() <= (int)array_data.size()); - - switch (data_type->get_numeric_type()) { - case qpGeomVertexDataType::NT_uint16: - { - int i = 0; - int min_values = min(num_values, data_type->get_num_values()); - while (i < min_values) { - data[i] = *(PN_uint16 *)&array_data[element]; - element += sizeof(PN_uint16); - ++i; - } - while (i < num_values) { - data[i] = 0; - ++i; - } - } - break; - - case qpGeomVertexDataType::NT_uint8: - { - int i = 0; - int min_values = min(num_values, data_type->get_num_values()); - while (i < min_values) { - int value = *(unsigned char *)&array_data[element]; - element += 1; - data[i] = value; - ++i; - } - while (i < num_values) { - data[i] = 0; - ++i; - } - } - break; - - case qpGeomVertexDataType::NT_packed_8888: - { - if (num_values == 4) { - unpack_argb(data, *(PN_uint32 *)&array_data[element]); - } else { - int data4[4]; - unpack_argb(data4, *(PN_uint32 *)&array_data[element]); - memset(data, 0, num_values * sizeof(int)); - memcpy(data, data4, min(num_values, 4) * sizeof(int)); - } - } - break; - - case qpGeomVertexDataType::NT_float32: - { - int i = 0; - int min_values = min(num_values, data_type->get_num_values()); - while (i < min_values) { - data[i] = (int)*(PN_float32 *)&array_data[element]; - element += sizeof(PN_float32); - ++i; - } - while (i < num_values) { - data[i] = 0; - ++i; - } - } - break; - } -} - //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexData::get_array_info // Access: Public @@ -1015,142 +630,6 @@ get_array_info(const InternalName *name, return false; } -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::to_vec2 -// Access: Public, Static -// Description: Converts a data element of arbitrary number of -// dimensions (1 - 4) into a vec2 in a sensible way. -//////////////////////////////////////////////////////////////////// -void qpGeomVertexData:: -to_vec2(LVecBase2f &vec, const float *data, int num_values) { - switch (num_values) { - case 1: - vec.set(data[0], 0.0f); - break; - - case 2: - case 3: - vec.set(data[0], data[1]); - break; - - default: // 4 or more. - vec.set(data[0] / data[3], data[1] / data[3]); - break; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::to_vec3 -// Access: Public, Static -// Description: Converts a data element of arbitrary number of -// dimensions (1 - 4) into a vec3 in a sensible way. -//////////////////////////////////////////////////////////////////// -void qpGeomVertexData:: -to_vec3(LVecBase3f &vec, const float *data, int num_values) { - switch (num_values) { - case 1: - vec.set(data[0], 0.0f, 0.0f); - break; - - case 2: - vec.set(data[0], data[1], 0.0f); - break; - - case 3: - vec.set(data[0], data[1], data[2]); - break; - - default: // 4 or more. - vec.set(data[0] / data[3], data[1] / data[3], data[2] / data[3]); - break; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::to_vec4 -// Access: Public, Static -// Description: Converts a data element of arbitrary number of -// dimensions (1 - 4) into a vec4 in a sensible way. -//////////////////////////////////////////////////////////////////// -void qpGeomVertexData:: -to_vec4(LVecBase4f &vec, const float *data, int num_values) { - switch (num_values) { - case 1: - vec.set(data[0], 0.0f, 0.0f, 1.0f); - break; - - case 2: - vec.set(data[0], data[1], 0.0f, 1.0f); - break; - - case 3: - vec.set(data[0], data[1], data[2], 1.0f); - break; - - default: // 4 or more. - vec.set(data[0], data[1], data[2], data[3]); - break; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::pack_argb -// Access: Public, Static -// Description: Packs four floats, stored R, G, B, A, into a -// packed_argb value. -//////////////////////////////////////////////////////////////////// -unsigned int qpGeomVertexData:: -pack_argb(const float data[4]) { - unsigned int r = ((unsigned int)(data[0] * 255.0f)) & 0xff; - unsigned int g = ((unsigned int)(data[1] * 255.0f)) & 0xff; - unsigned int b = ((unsigned int)(data[2] * 255.0f)) & 0xff; - unsigned int a = ((unsigned int)(data[3] * 255.0f)) & 0xff; - return ((a << 24) | (r << 16) | (g << 8) | b); -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::unpack_argb -// Access: Public, Static -// Description: Unpacks a packed_argb value into four floats, stored -// R, G, B, A. -//////////////////////////////////////////////////////////////////// -void qpGeomVertexData:: -unpack_argb(float data[4], unsigned int packed_argb) { - data[0] = (float)((packed_argb >> 16) & 0xff) / 255.0f; - data[1] = (float)((packed_argb >> 8) & 0xff) / 255.0f; - data[2] = (float)(packed_argb & 0xff) / 255.0f; - data[3] = (float)((packed_argb >> 24) & 0xff) / 255.0f; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::pack_argb -// Access: Public, Static -// Description: Packs four ints, stored R, G, B, A, into a -// packed_argb value. -//////////////////////////////////////////////////////////////////// -unsigned int qpGeomVertexData:: -pack_argb(const int data[4]) { - unsigned int r = ((unsigned int)data[0]) & 0xff; - unsigned int g = ((unsigned int)data[1]) & 0xff; - unsigned int b = ((unsigned int)data[2]) & 0xff; - unsigned int a = ((unsigned int)data[3]) & 0xff; - return ((a << 24) | (r << 16) | (g << 8) | b); -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::unpack_argb -// Access: Public, Static -// Description: Unpacks a packed_argb value into four ints, stored -// R, G, B, A. -//////////////////////////////////////////////////////////////////// -void qpGeomVertexData:: -unpack_argb(int data[4], unsigned int packed_argb) { - data[0] = (int)((packed_argb >> 16) & 0xff); - data[1] = (int)((packed_argb >> 8) & 0xff); - data[2] = (int)(packed_argb & 0xff); - data[3] = (int)((packed_argb >> 24) & 0xff); -} - //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexData::do_set_num_vertices // Access: Private @@ -1234,7 +713,7 @@ update_animated_vertices(qpGeomVertexData::CDWriter &cdata) { // Now go through and apply the scale, copying it to the new data. qpGeomVertexReader from(this, InternalName::get_vertex()); qpGeomVertexReader blendi(this, InternalName::get_transform_blend()); - qpGeomVertexIterator to(new_data, InternalName::get_vertex()); + qpGeomVertexWriter to(new_data, InternalName::get_vertex()); if (from.get_data_type()->get_num_values() == 4) { for (int i = 0; i < num_vertices; i++) { diff --git a/panda/src/gobj/qpgeomVertexData.h b/panda/src/gobj/qpgeomVertexData.h index 1e93010dbe..57c66d8f60 100644 --- a/panda/src/gobj/qpgeomVertexData.h +++ b/panda/src/gobj/qpgeomVertexData.h @@ -117,30 +117,12 @@ PUBLISHED: void write(ostream &out, int indent_level = 0) const; public: - void set_data(int array, const qpGeomVertexDataType *data_type, - int vertex, const float *data, int num_values); - void get_data(int array, const qpGeomVertexDataType *data_type, - int vertex, float *data, int num_values) const; - void set_data(int array, const qpGeomVertexDataType *data_type, - int vertex, const int *data, int num_values); - void get_data(int array, const qpGeomVertexDataType *data_type, - int vertex, int *data, int num_values) const; - bool get_array_info(const InternalName *name, const qpGeomVertexArrayData *&array_data, int &num_components, qpGeomVertexDataType::NumericType &numeric_type, int &start, int &stride) const; - static void to_vec2(LVecBase2f &vec, const float *data, int num_values); - static void to_vec3(LVecBase3f &vec, const float *data, int num_values); - static void to_vec4(LVecBase4f &vec, const float *data, int num_values); - - static unsigned int pack_argb(const float data[4]); - static void unpack_argb(float data[4], unsigned int packed_argb); - static unsigned int pack_argb(const int data[4]); - static void unpack_argb(int data[4], unsigned int packed_argb); - private: string _name; CPT(qpGeomVertexFormat) _format; diff --git a/panda/src/gobj/qpgeomVertexIterator.I b/panda/src/gobj/qpgeomVertexIterator.I deleted file mode 100644 index 6a1cd4b92b..0000000000 --- a/panda/src/gobj/qpgeomVertexIterator.I +++ /dev/null @@ -1,473 +0,0 @@ -// Filename: qpgeomVertexIterator.I -// Created by: drose (10Mar05) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved -// -// All use of this software is subject to the terms of the Panda 3d -// Software license. You should have received a copy of this license -// along with this source code; you will also find a current copy of -// the license at http://etc.cmu.edu/panda3d/docs/license/ . -// -// To contact the maintainers of this program write to -// panda3d-general@lists.sourceforge.net . -// -//////////////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::Constructor -// Access: Published -// Description: Constructs a new iterator to process the vertices of -// the indicated data object. -//////////////////////////////////////////////////////////////////// -INLINE qpGeomVertexIterator:: -qpGeomVertexIterator(qpGeomVertexData *data) : - _data(data), - _const_data(false), - _array(0), - _data_type(NULL), - _start_vertex(0), - _read_vertex(0), - _write_vertex(0) -{ -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::Constructor -// Access: Published -// Description: Constructs a new iterator to process the vertices of -// the indicated data object. This flavor creates the -// iterator specifically to process the named data type. -//////////////////////////////////////////////////////////////////// -INLINE qpGeomVertexIterator:: -qpGeomVertexIterator(qpGeomVertexData *data, const string &name) : - _data(data), - _const_data(false), - _array(0), - _data_type(NULL), - _start_vertex(0), - _read_vertex(0), - _write_vertex(0) -{ - set_data_type(name); -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::Constructor -// Access: Published -// Description: Constructs a new iterator to process the vertices of -// the indicated data object. This flavor creates the -// iterator specifically to process the named data type. -//////////////////////////////////////////////////////////////////// -INLINE qpGeomVertexIterator:: -qpGeomVertexIterator(qpGeomVertexData *data, const InternalName *name) : - _data(data), - _const_data(false), - _array(0), - _data_type(NULL), - _start_vertex(0), - _read_vertex(0), - _write_vertex(0) -{ - set_data_type(name); -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::Constructor -// Access: Published -// Description: Constructs a new iterator to process the vertices of -// the indicated data object. -//////////////////////////////////////////////////////////////////// -INLINE qpGeomVertexIterator:: -qpGeomVertexIterator(const qpGeomVertexData *data) : - _data((qpGeomVertexData *)data), - _const_data(true), - _array(0), - _data_type(NULL), - _start_vertex(0), - _read_vertex(0), - _write_vertex(0) -{ -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::Constructor -// Access: Published -// Description: Constructs a new iterator to process the vertices of -// the indicated data object. This flavor creates the -// iterator specifically to process the named data type. -//////////////////////////////////////////////////////////////////// -INLINE qpGeomVertexIterator:: -qpGeomVertexIterator(const qpGeomVertexData *data, const string &name) : - _data((qpGeomVertexData *)data), - _const_data(true), - _array(0), - _data_type(NULL), - _start_vertex(0), - _read_vertex(0), - _write_vertex(0) -{ - set_data_type(name); -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::Constructor -// Access: Published -// Description: Constructs a new iterator to process the vertices of -// the indicated data object. This flavor creates the -// iterator specifically to process the named data type. -//////////////////////////////////////////////////////////////////// -INLINE qpGeomVertexIterator:: -qpGeomVertexIterator(const qpGeomVertexData *data, const InternalName *name) : - _data((qpGeomVertexData *)data), - _const_data(true), - _array(0), - _data_type(NULL), - _start_vertex(0), - _read_vertex(0), - _write_vertex(0) -{ - set_data_type(name); -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::get_data -// Access: Published -// Description: Returns the current data object that the iterator is -// processing. -//////////////////////////////////////////////////////////////////// -INLINE const qpGeomVertexData *qpGeomVertexIterator:: -get_data() const { - return _data; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_data_type -// Access: Published -// Description: Sets up the iterator to use the nth data type of the -// GeomVertexFormat, numbering from 0. -// -// This also resets the read and write vertex numbers to -// the start vertex (the same value passed to a previous -// call to set_vertex(), or 0 if set_vertex() was never -// called.) -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_data_type(int data_type) { - nassertv(_data->get_format()->get_array_with(data_type) >= 0); - set_data_type(_data->get_format()->get_array_with(data_type), - _data->get_format()->get_data_type(data_type)); -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_data_type -// Access: Published -// Description: Sets up the iterator to use the data type with the -// indicated name. -// -// This also resets the read and write vertex numbers to -// the start vertex (the same value passed to a previous -// call to set_vertex(), or 0 if set_vertex() was never -// called.) -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_data_type(const string &name) { - set_data_type(InternalName::make(name)); -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_data_type -// Access: Published -// Description: Sets up the iterator to use the data type with the -// indicated name. -// -// This also resets the read and write vertex numbers to -// the start vertex (the same value passed to a previous -// call to set_vertex(), or 0 if set_vertex() was never -// called.) -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_data_type(const InternalName *name) { - nassertv(_data->get_format()->get_array_with(name) >= 0); - set_data_type(_data->get_format()->get_array_with(name), - _data->get_format()->get_data_type(name)); -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_data_type -// Access: Published -// Description: Sets up the iterator to use the indicated data_type -// description on the given array. -// -// This also resets the read and write vertex numbers to -// the start vertex (the same value passed to a previous -// call to set_vertex(), or 0 if set_vertex() was never -// called.) -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_data_type(int array, const qpGeomVertexDataType *data_type) { - nassertv(array >= 0 && array < _data->get_num_arrays()); - nassertv(data_type != (qpGeomVertexDataType *)NULL); - _array = array; - _data_type = data_type; - - _read_vertex = _start_vertex; - _write_vertex = _start_vertex; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::get_array -// Access: Published -// Description: Returns the array index containing the data type that -// the iterator is working on. -//////////////////////////////////////////////////////////////////// -INLINE int qpGeomVertexIterator:: -get_array() const { - return _array; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::get_data_type -// Access: Published -// Description: Returns the description of the data type that the -// iterator is working on. -//////////////////////////////////////////////////////////////////// -INLINE const qpGeomVertexDataType *qpGeomVertexIterator:: -get_data_type() const { - return _data_type; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_vertex -// Access: Published -// Description: Sets the start, read, and write index to the -// indicated value. The iterator will begin traversing -// from the given vertex. -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_vertex(int vertex) { - _start_vertex = vertex; - _read_vertex = vertex; - _write_vertex = vertex; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::get_start_vertex -// Access: Published -// Description: Returns the vertex index at which the iterator -// started. It will return to this vertex if you reset -// the current data_type. -//////////////////////////////////////////////////////////////////// -INLINE int qpGeomVertexIterator:: -get_start_vertex() const { - return _start_vertex; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::get_read_vertex -// Access: Published -// Description: Returns the current read vertex index of the -// iterator. This is the index whose value will be -// returned by the next call to get_vertex(). -//////////////////////////////////////////////////////////////////// -INLINE int qpGeomVertexIterator:: -get_read_vertex() const { - return _read_vertex; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::get_write_vertex -// Access: Published -// Description: Returns the current write vertex index of the -// iterator. This is the index whose value will be -// modified by the next call to set_vertex(). -//////////////////////////////////////////////////////////////////// -INLINE int qpGeomVertexIterator:: -get_write_vertex() const { - return _write_vertex; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_data1f -// Access: Published -// Description: Sets the write vertex to a particular 1-component -// value, and advances the write vertex. -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_data1f(float data) { - nassertv(!_const_data); - _data->set_data(_array, _data_type, _write_vertex, &data, 1); - ++_write_vertex; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_data2f -// Access: Published -// Description: Sets the write vertex to a particular 2-component -// value, and advances the write vertex. -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_data2f(float x, float y) { - set_data2f(LVecBase2f(x, y)); -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_data2f -// Access: Published -// Description: Sets the write vertex to a particular 2-component -// value, and advances the write vertex. -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_data2f(const LVecBase2f &data) { - nassertv(!_const_data); - _data->set_data(_array, _data_type, _write_vertex, data.get_data(), 2); - ++_write_vertex; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_data3f -// Access: Published -// Description: Sets the write vertex to a particular 3-component -// value, and advances the write vertex. -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_data3f(float x, float y, float z) { - set_data3f(LVecBase3f(x, y, z)); -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_data3f -// Access: Published -// Description: Sets the write vertex to a particular 3-component -// value, and advances the write vertex. -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_data3f(const LVecBase3f &data) { - nassertv(!_const_data); - _data->set_data(_array, _data_type, _write_vertex, data.get_data(), 3); - ++_write_vertex; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_data4f -// Access: Published -// Description: Sets the write vertex to a particular 4-component -// value, and advances the write vertex. -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_data4f(float x, float y, float z, float w) { - set_data4f(LVecBase4f(x, y, z, w)); -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_data4f -// Access: Published -// Description: Sets the write vertex to a particular 4-component -// value, and advances the write vertex. -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_data4f(const LVecBase4f &data) { - nassertv(!_const_data); - _data->set_data(_array, _data_type, _write_vertex, data.get_data(), 4); - ++_write_vertex; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::get_data1f -// Access: Published -// Description: Returns the data associated with the read vertex, -// expressed as a 1-component value, and advances the -// read vertex. -//////////////////////////////////////////////////////////////////// -INLINE float qpGeomVertexIterator:: -get_data1f() { - float data; - _data->get_data(_array, _data_type, _read_vertex, &data, 1); - ++_read_vertex; - return data; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::get_data2f -// Access: Published -// Description: Returns the data associated with the read vertex, -// expressed as a 2-component value, and advances the -// read vertex. -//////////////////////////////////////////////////////////////////// -INLINE LVecBase2f qpGeomVertexIterator:: -get_data2f() { - float data[4]; - int num_values = min(_data_type->get_num_values(), 4); - _data->get_data(_array, _data_type, _read_vertex, data, num_values); - ++_read_vertex; - LVecBase2f result; - qpGeomVertexData::to_vec2(result, data, num_values); - return result; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::get_data3f -// Access: Published -// Description: Returns the data associated with the read vertex, -// expressed as a 3-component value, and advances the -// read vertex. -//////////////////////////////////////////////////////////////////// -INLINE LVecBase3f qpGeomVertexIterator:: -get_data3f() { - float data[4]; - int num_values = min(_data_type->get_num_values(), 4); - _data->get_data(_array, _data_type, _read_vertex, data, num_values); - ++_read_vertex; - LVecBase3f result; - qpGeomVertexData::to_vec3(result, data, num_values); - return result; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::get_data4f -// Access: Published -// Description: Returns the data associated with the read vertex, -// expressed as a 4-component value, and advances the -// read vertex. -//////////////////////////////////////////////////////////////////// -INLINE LVecBase4f qpGeomVertexIterator:: -get_data4f() { - float data[4]; - int num_values = min(_data_type->get_num_values(), 4); - _data->get_data(_array, _data_type, _read_vertex, data, num_values); - ++_read_vertex; - LVecBase4f result; - qpGeomVertexData::to_vec4(result, data, num_values); - return result; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::set_data1i -// Access: Published -// Description: Sets the write vertex to a particular 1-component -// value, and advances the write vertex. -//////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexIterator:: -set_data1i(int data) { - nassertv(!_const_data); - _data->set_data(_array, _data_type, _write_vertex, &data, 1); - ++_write_vertex; -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexIterator::get_data1i -// Access: Published -// Description: Returns the data associated with the read vertex, -// expressed as a 1-component value, and advances the -// read vertex. -//////////////////////////////////////////////////////////////////// -INLINE int qpGeomVertexIterator:: -get_data1i() { - int data; - _data->get_data(_array, _data_type, _read_vertex, &data, 1); - ++_read_vertex; - return data; -} diff --git a/panda/src/gobj/qpgeomVertexIterator.cxx b/panda/src/gobj/qpgeomVertexIterator.cxx deleted file mode 100644 index 26dee44baf..0000000000 --- a/panda/src/gobj/qpgeomVertexIterator.cxx +++ /dev/null @@ -1,19 +0,0 @@ -// Filename: qpgeomVertexIterator.cxx -// Created by: drose (10Mar05) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved -// -// All use of this software is subject to the terms of the Panda 3d -// Software license. You should have received a copy of this license -// along with this source code; you will also find a current copy of -// the license at http://etc.cmu.edu/panda3d/docs/license/ . -// -// To contact the maintainers of this program write to -// panda3d-general@lists.sourceforge.net . -// -//////////////////////////////////////////////////////////////////// - -#include "qpgeomVertexIterator.h" diff --git a/panda/src/gobj/qpgeomVertexIterator.h b/panda/src/gobj/qpgeomVertexIterator.h deleted file mode 100644 index 4739241df9..0000000000 --- a/panda/src/gobj/qpgeomVertexIterator.h +++ /dev/null @@ -1,99 +0,0 @@ -// Filename: qpgeomVertexIterator.h -// Created by: drose (10Mar05) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved -// -// All use of this software is subject to the terms of the Panda 3d -// Software license. You should have received a copy of this license -// along with this source code; you will also find a current copy of -// the license at http://etc.cmu.edu/panda3d/docs/license/ . -// -// To contact the maintainers of this program write to -// panda3d-general@lists.sourceforge.net . -// -//////////////////////////////////////////////////////////////////// - -#ifndef qpGEOMVERTEXITERATOR_H -#define qpGEOMVERTEXITERATOR_H - -#include "pandabase.h" -#include "qpgeomVertexData.h" -#include "qpgeomVertexDataType.h" -#include "internalName.h" -#include "luse.h" -#include "pointerTo.h" - -//////////////////////////////////////////////////////////////////// -// Class : qpGeomVertexIterator -// Description : This is used to read or write the vertices of a -// GeomVertexData structure, one vertex and data type at -// a time. -// -// This is part of the experimental Geom rewrite. -//////////////////////////////////////////////////////////////////// -class EXPCL_PANDA qpGeomVertexIterator { -PUBLISHED: - INLINE qpGeomVertexIterator(qpGeomVertexData *data); - INLINE qpGeomVertexIterator(qpGeomVertexData *data, - const string &name); - INLINE qpGeomVertexIterator(qpGeomVertexData *data, - const InternalName *name); -public: - // These const variants are not published, since our Python layer - // doesn't know the difference between const and non-const anyway. - INLINE qpGeomVertexIterator(const qpGeomVertexData *data); - INLINE qpGeomVertexIterator(const qpGeomVertexData *data, - const string &name); - INLINE qpGeomVertexIterator(const qpGeomVertexData *data, - const InternalName *name); - -PUBLISHED: - INLINE const qpGeomVertexData *get_data() const; - - INLINE void set_data_type(int data_type); - INLINE void set_data_type(const string &name); - INLINE void set_data_type(const InternalName *name); - INLINE void set_data_type(int array, const qpGeomVertexDataType *data_type); - - INLINE int get_array() const; - INLINE const qpGeomVertexDataType *get_data_type() const; - - INLINE void set_vertex(int vertex); - - INLINE int get_start_vertex() const; - INLINE int get_read_vertex() const; - INLINE int get_write_vertex() const; - - INLINE void set_data1f(float data); - INLINE void set_data2f(float x, float y); - INLINE void set_data2f(const LVecBase2f &data); - INLINE void set_data3f(float x, float y, float z); - INLINE void set_data3f(const LVecBase3f &data); - INLINE void set_data4f(float x, float y, float z, float w); - INLINE void set_data4f(const LVecBase4f &data); - - INLINE float get_data1f(); - INLINE LVecBase2f get_data2f(); - INLINE LVecBase3f get_data3f(); - INLINE LVecBase4f get_data4f(); - - INLINE void set_data1i(int data); - INLINE int get_data1i(); - -private: - PT(qpGeomVertexData) _data; - bool _const_data; - int _array; - const qpGeomVertexDataType *_data_type; - - int _start_vertex; - int _read_vertex; - int _write_vertex; -}; - -#include "qpgeomVertexIterator.I" - -#endif diff --git a/panda/src/gobj/qpgeomVertexReader.I b/panda/src/gobj/qpgeomVertexReader.I index 783b834f97..e9b01d0016 100644 --- a/panda/src/gobj/qpgeomVertexReader.I +++ b/panda/src/gobj/qpgeomVertexReader.I @@ -31,6 +31,7 @@ qpGeomVertexReader(const qpGeomVertexData *vertex_data) : _pointer(NULL), _start_vertex(0), _read_vertex(0), + _num_vertices(0), _reader(NULL) { } @@ -50,6 +51,7 @@ qpGeomVertexReader(const qpGeomVertexData *vertex_data, const string &name) : _pointer(NULL), _start_vertex(0), _read_vertex(0), + _num_vertices(0), _reader(NULL) { set_data_type(name); @@ -71,6 +73,7 @@ qpGeomVertexReader(const qpGeomVertexData *vertex_data, _pointer(NULL), _start_vertex(0), _read_vertex(0), + _num_vertices(0), _reader(NULL) { set_data_type(name); @@ -109,12 +112,14 @@ get_vertex_data() const { // This also resets the read vertex number to the start // vertex (the same value passed to a previous call to // set_vertex(), or 0 if set_vertex() was never called.) +// +// The return value is true if the data type is valid, +// false otherwise. //////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexReader:: +INLINE bool qpGeomVertexReader:: set_data_type(int data_type) { - nassertv(_vertex_data->get_format()->get_array_with(data_type) >= 0); - set_data_type(_vertex_data->get_format()->get_array_with(data_type), - _vertex_data->get_format()->get_data_type(data_type)); + return set_data_type(_vertex_data->get_format()->get_array_with(data_type), + _vertex_data->get_format()->get_data_type(data_type)); } //////////////////////////////////////////////////////////////////// @@ -126,10 +131,13 @@ set_data_type(int data_type) { // This also resets the read vertex number to the start // vertex (the same value passed to a previous call to // set_vertex(), or 0 if set_vertex() was never called.) +// +// The return value is true if the data type is valid, +// false otherwise. //////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexReader:: +INLINE bool qpGeomVertexReader:: set_data_type(const string &name) { - set_data_type(InternalName::make(name)); + return set_data_type(InternalName::make(name)); } //////////////////////////////////////////////////////////////////// @@ -141,12 +149,26 @@ set_data_type(const string &name) { // This also resets the read vertex number to the start // vertex (the same value passed to a previous call to // set_vertex(), or 0 if set_vertex() was never called.) +// +// The return value is true if the data type is valid, +// false otherwise. //////////////////////////////////////////////////////////////////// -INLINE void qpGeomVertexReader:: +INLINE bool qpGeomVertexReader:: set_data_type(const InternalName *name) { - nassertv(_vertex_data->get_format()->get_array_with(name) >= 0); - set_data_type(_vertex_data->get_format()->get_array_with(name), - _vertex_data->get_format()->get_data_type(name)); + return set_data_type(_vertex_data->get_format()->get_array_with(name), + _vertex_data->get_format()->get_data_type(name)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::has_data_type +// Access: Published +// Description: Returns true if a valid data type has been +// successfully set, or false if the data type does not +// exist. +//////////////////////////////////////////////////////////////////// +INLINE bool qpGeomVertexReader:: +has_data_type() const { + return (_data_type != (qpGeomVertexDataType *)NULL); } //////////////////////////////////////////////////////////////////// @@ -181,8 +203,9 @@ get_data_type() const { INLINE void qpGeomVertexReader:: set_vertex(int vertex) { _start_vertex = vertex; - _read_vertex = vertex; - set_pointer(); + if (_data_type != (qpGeomVertexDataType *)NULL) { + set_pointer(_start_vertex); + } } //////////////////////////////////////////////////////////////////// @@ -209,6 +232,29 @@ get_read_vertex() const { return _read_vertex; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::get_num_vertices +// Access: Published +// Description: Returns the number of vertices in the vertex data. +//////////////////////////////////////////////////////////////////// +INLINE int qpGeomVertexReader:: +get_num_vertices() const { + return _num_vertices; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::is_at_end +// Access: Published +// Description: Returns true if the reader is currently at the end of +// the list of vertices, false otherwise. If this is +// true, another call to get_data*() will result in a +// crash. +//////////////////////////////////////////////////////////////////// +INLINE bool qpGeomVertexReader:: +is_at_end() const { + return _read_vertex >= _num_vertices; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexReader::get_data1f // Access: Published @@ -218,6 +264,7 @@ get_read_vertex() const { //////////////////////////////////////////////////////////////////// INLINE float qpGeomVertexReader:: get_data1f() { + nassertr(_data_type != (qpGeomVertexDataType *)NULL, 0.0f); return _reader->get_data1f(inc_pointer()); } @@ -230,6 +277,7 @@ get_data1f() { //////////////////////////////////////////////////////////////////// INLINE const LVecBase2f &qpGeomVertexReader:: get_data2f() { + nassertr(_data_type != (qpGeomVertexDataType *)NULL, LVecBase2f::zero()); return _reader->get_data2f(inc_pointer()); } @@ -242,6 +290,7 @@ get_data2f() { //////////////////////////////////////////////////////////////////// INLINE const LVecBase3f &qpGeomVertexReader:: get_data3f() { + nassertr(_data_type != (qpGeomVertexDataType *)NULL, LVecBase3f::zero()); return _reader->get_data3f(inc_pointer()); } @@ -254,6 +303,7 @@ get_data3f() { //////////////////////////////////////////////////////////////////// INLINE const LVecBase4f &qpGeomVertexReader:: get_data4f() { + nassertr(_data_type != (qpGeomVertexDataType *)NULL, LVecBase4f::zero()); return _reader->get_data4f(inc_pointer()); } @@ -266,20 +316,24 @@ get_data4f() { //////////////////////////////////////////////////////////////////// INLINE int qpGeomVertexReader:: get_data1i() { + nassertr(_data_type != (qpGeomVertexDataType *)NULL, 0); return _reader->get_data1i(inc_pointer()); } //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexReader::set_pointer // Access: Private -// Description: Sets up the internal pointer, etc. to use the vertex -// indicated by _start_vertex. +// Description: Sets up the internal write pointer, etc. to use the +// indicated vertex. //////////////////////////////////////////////////////////////////// INLINE void qpGeomVertexReader:: -set_pointer() { - _read_vertex = _start_vertex; - _data = _vertex_data->get_array(_array)->get_data(); +set_pointer(int vertex) { + nassertv(_data_type != (qpGeomVertexDataType *)NULL); + _read_vertex = vertex; + CPT(qpGeomVertexArrayData) array_data = _vertex_data->get_array(_array); + _data = array_data->get_data(); _pointer = _data.p() + _data_type->get_start() + _stride * _read_vertex; + _num_vertices = array_data->get_num_vertices(); } //////////////////////////////////////////////////////////////////// @@ -290,6 +344,9 @@ set_pointer() { //////////////////////////////////////////////////////////////////// INLINE const unsigned char *qpGeomVertexReader:: inc_pointer() { + nassertr(_read_vertex < _num_vertices, NULL); + nassertr(_pointer == _vertex_data->get_array(_array)->get_data().p() + _data_type->get_start() + _stride * _read_vertex, NULL); + const unsigned char *orig_pointer = _pointer; _pointer += _stride; ++_read_vertex; diff --git a/panda/src/gobj/qpgeomVertexReader.cxx b/panda/src/gobj/qpgeomVertexReader.cxx index 3af3aecd37..ca712ca700 100644 --- a/panda/src/gobj/qpgeomVertexReader.cxx +++ b/panda/src/gobj/qpgeomVertexReader.cxx @@ -28,26 +28,42 @@ // the start vertex (the same value passed to a previous // call to set_vertex(), or 0 if set_vertex() was never // called.) +// +// The return value is true if the data type is valid, +// false otherwise. //////////////////////////////////////////////////////////////////// -void qpGeomVertexReader:: +bool qpGeomVertexReader:: set_data_type(int array, const qpGeomVertexDataType *data_type) { - nassertv(array >= 0 && array < _vertex_data->get_num_arrays()); - nassertv(data_type != (qpGeomVertexDataType *)NULL); - _array = array; - _data_type = data_type; - _stride = _vertex_data->get_format()->get_array(_array)->get_stride(); - - set_pointer(); - // Delete the old reader, if we've got one. if (_reader != (Reader *)NULL) { delete _reader; _reader = NULL; } - // Now set up a new reader. - _reader = make_reader(); - _reader->_data_type = _data_type; + if (array < 0 || array >= _vertex_data->get_num_arrays() || + data_type == (qpGeomVertexDataType *)NULL) { + // Clear the data type. + _array = -1; + _data_type = NULL; + _stride = 0; + _read_vertex = _start_vertex; + _num_vertices = 0; + + return false; + + } else { + _array = array; + _data_type = data_type; + _stride = _vertex_data->get_format()->get_array(_array)->get_stride(); + + set_pointer(_start_vertex); + + // Now set up a new reader. + _reader = make_reader(); + _reader->_data_type = _data_type; + + return true; + } } //////////////////////////////////////////////////////////////////// @@ -58,40 +74,109 @@ set_data_type(int array, const qpGeomVertexDataType *data_type) { //////////////////////////////////////////////////////////////////// qpGeomVertexReader::Reader *qpGeomVertexReader:: make_reader() const { - if (_data_type->get_contents() == qpGeomVertexDataType::C_point && - _data_type->get_num_values() < 4) { - return new Reader_point; - - } else { + switch (_data_type->get_contents()) { + case qpGeomVertexDataType::C_point: + case qpGeomVertexDataType::C_texcoord: + // These types are read as a 4-d homogeneous point. switch (_data_type->get_numeric_type()) { case qpGeomVertexDataType::NT_float32: - if (sizeof(float) == 4) { + if (sizeof(float) == sizeof(PN_float32)) { + // Use the native float type implementation for a tiny bit + // more optimization. switch (_data_type->get_num_components()) { + case 2: + return new Reader_point_nativefloat_2; case 3: - return new Reader_float_3; - - default: - break; + return new Reader_point_nativefloat_3; + case 4: + return new Reader_point_nativefloat_4; + } + } else { + switch (_data_type->get_num_components()) { + case 2: + return new Reader_point_float32_2; + case 3: + return new Reader_point_float32_3; + case 4: + return new Reader_point_float32_4; } } break; + default: + break; + } + return new Reader_point; - case qpGeomVertexDataType::NT_uint16: + case qpGeomVertexDataType::C_rgba: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: switch (_data_type->get_num_components()) { - case 1: - return new Reader_uint16_1; + case 4: + return new Reader_rgba_uint8_4; default: break; } - + break; + case qpGeomVertexDataType::NT_float32: + switch (_data_type->get_num_components()) { + case 4: + if (sizeof(float) == sizeof(PN_float32)) { + // Use the native float type implementation for a tiny bit + // more optimization. + return new Reader_rgba_nativefloat_4; + } else { + return new Reader_rgba_float32_4; + } + + default: + break; + } + break; default: break; } - } + return new Reader_color; - // If we got here, we have to create a generic reader. - return new Reader; + case qpGeomVertexDataType::C_argb: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_packed_8888: + switch (_data_type->get_num_components()) { + case 1: + return new Reader_argb_packed_8888; + + default: + break; + } + break; + default: + break; + } + return new Reader_color; + + default: + // Otherwise, we just read it as a generic value. + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_float32: + switch (_data_type->get_num_components()) { + case 3: + if (sizeof(float) == sizeof(PN_float32)) { + // Use the native float type implementation for a tiny bit + // more optimization. + return new Reader_nativefloat_3; + } else { + return new Reader_float32_3; + } + + default: + break; + } + break; + default: + break; + } + return new Reader; + } } //////////////////////////////////////////////////////////////////// @@ -121,7 +206,11 @@ get_data1f(const unsigned char *pointer) { { packed_8888 dword; dword._i = *(PN_uint32 *)pointer; - return maybe_scale_color(dword._b[0]); + if (_data_type->get_contents() == qpGeomVertexDataType::C_argb) { + return maybe_scale_color(dword._b[1]); + } else { + return maybe_scale_color(dword._b[0]); + } } case qpGeomVertexDataType::NT_float32: @@ -159,7 +248,11 @@ get_data2f(const unsigned char *pointer) { { packed_8888 dword; dword._i = *(PN_uint32 *)pointer; - maybe_scale_color(dword._b[0], dword._b[1]); + if (_data_type->get_contents() == qpGeomVertexDataType::C_argb) { + maybe_scale_color(dword._b[1], dword._b[2]); + } else { + maybe_scale_color(dword._b[0], dword._b[1]); + } } return _v2; @@ -184,7 +277,7 @@ const LVecBase3f &qpGeomVertexReader::Reader:: get_data3f(const unsigned char *pointer) { switch (_data_type->get_num_values()) { case 1: - _v3.set(get_data1i(pointer), 0.0f, 0.0f); + _v3.set(get_data1f(pointer), 0.0f, 0.0f); return _v3; case 2: @@ -211,7 +304,11 @@ get_data3f(const unsigned char *pointer) { { packed_8888 dword; dword._i = *(PN_uint32 *)pointer; - maybe_scale_color(dword._b[0], dword._b[1], dword._b[2]); + if (_data_type->get_contents() == qpGeomVertexDataType::C_argb) { + maybe_scale_color(dword._b[1], dword._b[2], dword._b[3]); + } else { + maybe_scale_color(dword._b[0], dword._b[1], dword._b[2]); + } } return _v3; @@ -270,7 +367,11 @@ get_data4f(const unsigned char *pointer) { { packed_8888 dword; dword._i = *(PN_uint32 *)pointer; - maybe_scale_color(dword._b[0], dword._b[1], dword._b[2], dword._b[3]); + if (_data_type->get_contents() == qpGeomVertexDataType::C_argb) { + maybe_scale_color(dword._b[1], dword._b[2], dword._b[3], dword._b[0]); + } else { + maybe_scale_color(dword._b[0], dword._b[1], dword._b[2], dword._b[3]); + } } return _v4; @@ -315,6 +416,53 @@ get_data1i(const unsigned char *pointer) { return 0; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_point::get_data1f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +float qpGeomVertexReader::Reader_point:: +get_data1f(const unsigned char *pointer) { + if (_data_type->get_num_values() == 4) { + const LVecBase4f &v4 = get_data4f(pointer); + return v4[0] / v4[3]; + } else { + return Reader::get_data1f(pointer); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_point::get_data2f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase2f &qpGeomVertexReader::Reader_point:: +get_data2f(const unsigned char *pointer) { + if (_data_type->get_num_values() == 4) { + const LVecBase4f &v4 = get_data4f(pointer); + _v2.set(v4[0] / v4[3], v4[1] / v4[3]); + return _v2; + } else { + return Reader::get_data2f(pointer); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_point::get_data3f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase3f &qpGeomVertexReader::Reader_point:: +get_data3f(const unsigned char *pointer) { + if (_data_type->get_num_values() == 4) { + const LVecBase4f &v4 = get_data4f(pointer); + _v3.set(v4[0] / v4[3], v4[1] / v4[3], v4[2] / v4[3]); + return _v3; + } else { + return Reader::get_data3f(pointer); + } +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexReader::Reader_point::get_data4f // Access: Public, Virtual @@ -358,7 +506,11 @@ get_data4f(const unsigned char *pointer) { { packed_8888 dword; dword._i = *(PN_uint32 *)pointer; - maybe_scale_color(dword._b[0], dword._b[1], dword._b[2], dword._b[3]); + if (_data_type->get_contents() == qpGeomVertexDataType::C_argb) { + maybe_scale_color(dword._b[1], dword._b[2], dword._b[3], dword._b[0]); + } else { + maybe_scale_color(dword._b[0], dword._b[1], dword._b[2], dword._b[3]); + } } return _v4; @@ -375,16 +527,206 @@ get_data4f(const unsigned char *pointer) { } //////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexReader::Reader_float_3::get_data3f +// Function: qpGeomVertexReader::Reader_color::get_data4f // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -const LVecBase3f &qpGeomVertexReader::Reader_float_3:: +const LVecBase4f &qpGeomVertexReader::Reader_color:: +get_data4f(const unsigned char *pointer) { + switch (_data_type->get_num_values()) { + case 1: + _v4.set(get_data1i(pointer), 0.0f, 0.0f, 1.0f); + return _v4; + + case 2: + { + const LVecBase2f &v2 = get_data2f(pointer); + _v4.set(v2[0], v2[1], 0.0f, 1.0f); + } + return _v4; + + case 3: + { + const LVecBase3f &v3 = get_data3f(pointer); + _v4.set(v3[0], v3[1], v3[2], 1.0f); + } + return _v4; + + default: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + maybe_scale_color(pointer[0], pointer[1], pointer[2], pointer[3]); + return _v4; + + case qpGeomVertexDataType::NT_uint16: + { + PN_uint16 *pi = (PN_uint16 *)pointer; + _v4.set(pi[0], pi[1], pi[2], pi[3]); + } + return _v4; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + dword._i = *(PN_uint32 *)pointer; + if (_data_type->get_contents() == qpGeomVertexDataType::C_argb) { + maybe_scale_color(dword._b[1], dword._b[2], dword._b[3], dword._b[0]); + } else { + maybe_scale_color(dword._b[0], dword._b[1], dword._b[2], dword._b[3]); + } + } + return _v4; + + case qpGeomVertexDataType::NT_float32: + { + PN_float32 *pi = (PN_float32 *)pointer; + _v4.set(pi[0], pi[1], pi[2], pi[3]); + } + return _v4; + } + } + + return _v4; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_float32_3::get_data3f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase3f &qpGeomVertexReader::Reader_float32_3:: get_data3f(const unsigned char *pointer) { - // We sneakily cast a float[3] array to an LVecBase3f reference, - // making all kinds of assumptions about how an LVecBase3f is - // stored. - return *(LVecBase3f *)pointer; + PN_float32 *pi = (PN_float32 *)pointer; + _v3.set(pi[0], pi[1], pi[2]); + return _v3; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_point_float32_2::get_data2f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase2f &qpGeomVertexReader::Reader_point_float32_2:: +get_data2f(const unsigned char *pointer) { + PN_float32 *pi = (PN_float32 *)pointer; + _v2.set(pi[0], pi[1]); + return _v2; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_point_float32_3::get_data3f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase3f &qpGeomVertexReader::Reader_point_float32_3:: +get_data3f(const unsigned char *pointer) { + PN_float32 *pi = (PN_float32 *)pointer; + _v3.set(pi[0], pi[1], pi[2]); + return _v3; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_point_float32_4::get_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase4f &qpGeomVertexReader::Reader_point_float32_4:: +get_data4f(const unsigned char *pointer) { + PN_float32 *pi = (PN_float32 *)pointer; + _v4.set(pi[0], pi[1], pi[2], pi[3]); + return _v4; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_nativefloat_3::get_data3f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase3f &qpGeomVertexReader::Reader_nativefloat_3:: +get_data3f(const unsigned char *pointer) { + return *(const LVecBase3f *)pointer; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_point_nativefloat_2::get_data2f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase2f &qpGeomVertexReader::Reader_point_nativefloat_2:: +get_data2f(const unsigned char *pointer) { + return *(const LVecBase2f *)pointer; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_point_nativefloat_3::get_data3f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase3f &qpGeomVertexReader::Reader_point_nativefloat_3:: +get_data3f(const unsigned char *pointer) { + return *(const LVecBase3f *)pointer; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_point_nativefloat_4::get_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase4f &qpGeomVertexReader::Reader_point_nativefloat_4:: +get_data4f(const unsigned char *pointer) { + return *(const LVecBase4f *)pointer; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_argb_packed_8888::get_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase4f &qpGeomVertexReader::Reader_argb_packed_8888:: +get_data4f(const unsigned char *pointer) { + packed_8888 dword; + dword._i = *(PN_uint32 *)pointer; + _v4.set((float)dword._b[1] / 255.0f, + (float)dword._b[2] / 255.0f, + (float)dword._b[3] / 255.0f, + (float)dword._b[0] / 255.0f); + return _v4; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_rgba_uint8_4::get_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase4f &qpGeomVertexReader::Reader_rgba_uint8_4:: +get_data4f(const unsigned char *pointer) { + _v4.set((float)pointer[0] / 255.0f, + (float)pointer[1] / 255.0f, + (float)pointer[2] / 255.0f, + (float)pointer[3] / 255.0f); + return _v4; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_rgba_float32_4::get_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase4f &qpGeomVertexReader::Reader_rgba_float32_4:: +get_data4f(const unsigned char *pointer) { + PN_float32 *pi = (PN_float32 *)pointer; + _v4.set(pi[0], pi[1], pi[2], pi[3]); + return _v4; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_rgba_nativefloat_4::get_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase4f &qpGeomVertexReader::Reader_rgba_nativefloat_4:: +get_data4f(const unsigned char *pointer) { + return *(const LVecBase4f *)pointer; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/qpgeomVertexReader.h b/panda/src/gobj/qpgeomVertexReader.h index 522ba3824b..d8015a6146 100644 --- a/panda/src/gobj/qpgeomVertexReader.h +++ b/panda/src/gobj/qpgeomVertexReader.h @@ -53,11 +53,12 @@ PUBLISHED: INLINE const qpGeomVertexData *get_vertex_data() const; - INLINE void set_data_type(int data_type); - INLINE void set_data_type(const string &name); - INLINE void set_data_type(const InternalName *name); - void set_data_type(int array, const qpGeomVertexDataType *data_type); + INLINE bool set_data_type(int data_type); + INLINE bool set_data_type(const string &name); + INLINE bool set_data_type(const InternalName *name); + bool set_data_type(int array, const qpGeomVertexDataType *data_type); + INLINE bool has_data_type() const; INLINE int get_array() const; INLINE const qpGeomVertexDataType *get_data_type() const; @@ -65,6 +66,8 @@ PUBLISHED: INLINE int get_start_vertex() const; INLINE int get_read_vertex() const; + INLINE int get_num_vertices() const; + INLINE bool is_at_end() const; INLINE float get_data1f(); INLINE const LVecBase2f &get_data2f(); @@ -76,7 +79,7 @@ PUBLISHED: private: class Reader; - INLINE void set_pointer(); + INLINE void set_pointer(int vertex); INLINE const unsigned char *inc_pointer(); Reader *make_reader() const; @@ -90,6 +93,7 @@ private: int _start_vertex; int _read_vertex; + int _num_vertices; Reader *_reader; @@ -126,9 +130,22 @@ private: }; // This is a specialization on the generic Reader that handles - // points, which are special because the fourth component, if - // omitted, is 1.0. + // points, which are special because the fourth component, if not + // present in the data, is implicitly 1.0; and if it is present, + // than any three-component or smaller return is implicitly divided + // by the fourth component. class Reader_point : public Reader { + public: + virtual float get_data1f(const unsigned char *pointer); + virtual const LVecBase2f &get_data2f(const unsigned char *pointer); + virtual const LVecBase3f &get_data3f(const unsigned char *pointer); + virtual const LVecBase4f &get_data4f(const unsigned char *pointer); + }; + + // This is similar to Reader_point, in that the fourth component is + // implicitly 1.0 if it is not present in the data, but we never + // divide by alpha. + class Reader_color : public Reader { public: virtual const LVecBase4f &get_data4f(const unsigned char *pointer); }; @@ -137,11 +154,66 @@ private: // These are the specializations on the generic Reader that handle // the direct code paths. - class Reader_float_3 : public Reader { + class Reader_float32_3 : public Reader { public: virtual const LVecBase3f &get_data3f(const unsigned char *pointer); }; + class Reader_point_float32_2 : public Reader_point { + public: + virtual const LVecBase2f &get_data2f(const unsigned char *pointer); + }; + + class Reader_point_float32_3 : public Reader_point { + public: + virtual const LVecBase3f &get_data3f(const unsigned char *pointer); + }; + + class Reader_point_float32_4 : public Reader_point { + public: + virtual const LVecBase4f &get_data4f(const unsigned char *pointer); + }; + + class Reader_nativefloat_3 : public Reader { + public: + virtual const LVecBase3f &get_data3f(const unsigned char *pointer); + }; + + class Reader_point_nativefloat_2 : public Reader_point { + public: + virtual const LVecBase2f &get_data2f(const unsigned char *pointer); + }; + + class Reader_point_nativefloat_3 : public Reader_point { + public: + virtual const LVecBase3f &get_data3f(const unsigned char *pointer); + }; + + class Reader_point_nativefloat_4 : public Reader_point { + public: + virtual const LVecBase4f &get_data4f(const unsigned char *pointer); + }; + + class Reader_argb_packed_8888 : public Reader_color { + public: + virtual const LVecBase4f &get_data4f(const unsigned char *pointer); + }; + + class Reader_rgba_uint8_4 : public Reader_color { + public: + virtual const LVecBase4f &get_data4f(const unsigned char *pointer); + }; + + class Reader_rgba_float32_4 : public Reader_color { + public: + virtual const LVecBase4f &get_data4f(const unsigned char *pointer); + }; + + class Reader_rgba_nativefloat_4 : public Reader_color { + public: + virtual const LVecBase4f &get_data4f(const unsigned char *pointer); + }; + class Reader_uint16_1 : public Reader { public: virtual int get_data1i(const unsigned char *pointer); diff --git a/panda/src/gobj/qpgeomVertexWriter.I b/panda/src/gobj/qpgeomVertexWriter.I new file mode 100644 index 0000000000..048577614e --- /dev/null +++ b/panda/src/gobj/qpgeomVertexWriter.I @@ -0,0 +1,636 @@ +// Filename: qpgeomVertexWriter.I +// Created by: drose (25Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Constructor +// Access: Published +// Description: Constructs a new writer to process the vertices of +// the indicated data object. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexWriter:: +qpGeomVertexWriter(qpGeomVertexData *vertex_data) : + _vertex_data(vertex_data), + _array(0), + _data_type(NULL), + _pointer(NULL), + _start_vertex(0), + _write_vertex(0), + _num_vertices(0), + _writer(NULL) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Constructor +// Access: Published +// Description: Constructs a new writer to process the vertices of +// the indicated data object. This flavor creates the +// writer specifically to process the named data type. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexWriter:: +qpGeomVertexWriter(qpGeomVertexData *vertex_data, const string &name) : + _vertex_data(vertex_data), + _array(0), + _data_type(NULL), + _pointer(NULL), + _start_vertex(0), + _write_vertex(0), + _num_vertices(0), + _writer(NULL) +{ + set_data_type(name); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Constructor +// Access: Published +// Description: Constructs a new writer to process the vertices of +// the indicated data object. This flavor creates the +// writer specifically to process the named data type. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexWriter:: +qpGeomVertexWriter(qpGeomVertexData *vertex_data, const InternalName *name) : + _vertex_data(vertex_data), + _array(0), + _data_type(NULL), + _pointer(NULL), + _start_vertex(0), + _write_vertex(0), + _num_vertices(0), + _writer(NULL) +{ + set_data_type(name); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Destructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexWriter:: +~qpGeomVertexWriter() { + if (_writer != (Writer *)NULL) { + delete _writer; + _writer = NULL; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::get_vertex_data +// Access: Published +// Description: Returns the vertex data object that the +// writer is processing. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexData *qpGeomVertexWriter:: +get_vertex_data() const { + return _vertex_data; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_data_type +// Access: Published +// Description: Sets up the writer to use the nth data type of the +// GeomVertexFormat, numbering from 0. +// +// This also resets the write vertex number to the start +// vertex (the same value passed to a previous call to +// set_vertex(), or 0 if set_vertex() was never called.) +// +// The return value is true if the data type is valid, +// false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool qpGeomVertexWriter:: +set_data_type(int data_type) { + return set_data_type(_vertex_data->get_format()->get_array_with(data_type), + _vertex_data->get_format()->get_data_type(data_type)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_data_type +// Access: Published +// Description: Sets up the writer to use the data type with the +// indicated name. +// +// This also resets the write vertex number to the start +// vertex (the same value passed to a previous call to +// set_vertex(), or 0 if set_vertex() was never called.) +// +// The return value is true if the data type is valid, +// false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool qpGeomVertexWriter:: +set_data_type(const string &name) { + return set_data_type(InternalName::make(name)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_data_type +// Access: Published +// Description: Sets up the writer to use the data type with the +// indicated name. +// +// This also resets the write number to the start vertex +// (the same value passed to a previous call to +// set_vertex(), or 0 if set_vertex() was never called.) +// +// The return value is true if the data type is valid, +// false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool qpGeomVertexWriter:: +set_data_type(const InternalName *name) { + return set_data_type(_vertex_data->get_format()->get_array_with(name), + _vertex_data->get_format()->get_data_type(name)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::has_data_type +// Access: Published +// Description: Returns true if a valid data type has been +// successfully set, or false if the data type does not +// exist. +//////////////////////////////////////////////////////////////////// +INLINE bool qpGeomVertexWriter:: +has_data_type() const { + return (_data_type != (qpGeomVertexDataType *)NULL); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::get_array +// Access: Published +// Description: Returns the array index containing the data type that +// the writer is working on. +//////////////////////////////////////////////////////////////////// +INLINE int qpGeomVertexWriter:: +get_array() const { + return _array; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::get_data_type +// Access: Published +// Description: Returns the description of the data type that the +// writer is working on. +//////////////////////////////////////////////////////////////////// +INLINE const qpGeomVertexDataType *qpGeomVertexWriter:: +get_data_type() const { + return _data_type; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_vertex +// Access: Published +// Description: Sets the start, write, and write index to the +// indicated value. The writer will begin traversing +// from the given vertex. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +set_vertex(int vertex) { + _start_vertex = vertex; + if (_data_type != (qpGeomVertexDataType *)NULL) { + set_pointer(_start_vertex); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::get_start_vertex +// Access: Published +// Description: Returns the vertex index at which the writer +// started. It will return to this vertex if you reset +// the current data_type. +//////////////////////////////////////////////////////////////////// +INLINE int qpGeomVertexWriter:: +get_start_vertex() const { + return _start_vertex; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::get_write_vertex +// Access: Published +// Description: Returns the current write vertex index of the +// writer. This is the index whose value will be +// returned by the next call to get_data*(). +//////////////////////////////////////////////////////////////////// +INLINE int qpGeomVertexWriter:: +get_write_vertex() const { + return _write_vertex; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::get_num_vertices +// Access: Published +// Description: Returns the number of vertices in the vertex data. +//////////////////////////////////////////////////////////////////// +INLINE int qpGeomVertexWriter:: +get_num_vertices() const { + return _num_vertices; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::is_at_end +// Access: Published +// Description: Returns true if the writer is currently at the end of +// the list of vertices, false otherwise. If this is +// true, another call to set_data*() will result in a +// crash, but another call to add_data*() will add a new +// vertex. +//////////////////////////////////////////////////////////////////// +INLINE bool qpGeomVertexWriter:: +is_at_end() const { + return _write_vertex >= _num_vertices; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_data1f +// Access: Published +// Description: Sets the write vertex to a particular 1-component +// value, and advances the write vertex. +// +// It is an error for the write vertex to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +set_data1f(float data) { + nassertv(_data_type != (qpGeomVertexDataType *)NULL); + _writer->set_data1f(inc_pointer(), data); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_data2f +// Access: Published +// Description: Sets the write vertex to a particular 2-component +// value, and advances the write vertex. +// +// It is an error for the write vertex to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +set_data2f(float x, float y) { + set_data2f(LVecBase2f(x, y)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_data2f +// Access: Published +// Description: Sets the write vertex to a particular 2-component +// value, and advances the write vertex. +// +// It is an error for the write vertex to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +set_data2f(const LVecBase2f &data) { + nassertv(_data_type != (qpGeomVertexDataType *)NULL); + _writer->set_data2f(inc_pointer(), data); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_data3f +// Access: Published +// Description: Sets the write vertex to a particular 3-component +// value, and advances the write vertex. +// +// It is an error for the write vertex to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +set_data3f(float x, float y, float z) { + set_data3f(LVecBase3f(x, y, z)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_data3f +// Access: Published +// Description: Sets the write vertex to a particular 3-component +// value, and advances the write vertex. +// +// It is an error for the write vertex to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +set_data3f(const LVecBase3f &data) { + nassertv(_data_type != (qpGeomVertexDataType *)NULL); + _writer->set_data3f(inc_pointer(), data); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_data4f +// Access: Published +// Description: Sets the write vertex to a particular 4-component +// value, and advances the write vertex. +// +// It is an error for the write vertex to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +set_data4f(float x, float y, float z, float w) { + set_data4f(LVecBase4f(x, y, z, w)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_data4f +// Access: Published +// Description: Sets the write vertex to a particular 4-component +// value, and advances the write vertex. +// +// It is an error for the write vertex to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +set_data4f(const LVecBase4f &data) { + nassertv(_data_type != (qpGeomVertexDataType *)NULL); + _writer->set_data4f(inc_pointer(), data); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_data1i +// Access: Published +// Description: Sets the write vertex to a particular 1-component +// value, and advances the write vertex. +// +// It is an error for the write vertex to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +set_data1i(int data) { + nassertv(_data_type != (qpGeomVertexDataType *)NULL); + _writer->set_data1i(inc_pointer(), data); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::add_data1f +// Access: Published +// Description: Sets the write vertex to a particular 1-component +// value, and advances the write vertex. +// +// If the write vertex advances past the end of data, +// implicitly adds a new vertex to the data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +add_data1f(float data) { + nassertv(_data_type != (qpGeomVertexDataType *)NULL); + _writer->set_data1f(inc_add_pointer(), data); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::add_data2f +// Access: Published +// Description: Sets the write vertex to a particular 2-component +// value, and advances the write vertex. +// +// If the write vertex advances past the end of data, +// implicitly adds a new vertex to the data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +add_data2f(float x, float y) { + add_data2f(LVecBase2f(x, y)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::add_data2f +// Access: Published +// Description: Sets the write vertex to a particular 2-component +// value, and advances the write vertex. +// +// If the write vertex advances past the end of data, +// implicitly adds a new vertex to the data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +add_data2f(const LVecBase2f &data) { + nassertv(_data_type != (qpGeomVertexDataType *)NULL); + _writer->set_data2f(inc_add_pointer(), data); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::add_data3f +// Access: Published +// Description: Sets the write vertex to a particular 3-component +// value, and advances the write vertex. +// +// If the write vertex advances past the end of data, +// implicitly adds a new vertex to the data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +add_data3f(float x, float y, float z) { + add_data3f(LVecBase3f(x, y, z)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::add_data3f +// Access: Published +// Description: Sets the write vertex to a particular 3-component +// value, and advances the write vertex. +// +// If the write vertex advances past the end of data, +// implicitly adds a new vertex to the data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +add_data3f(const LVecBase3f &data) { + nassertv(_data_type != (qpGeomVertexDataType *)NULL); + _writer->set_data3f(inc_add_pointer(), data); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::add_data4f +// Access: Published +// Description: Sets the write vertex to a particular 4-component +// value, and advances the write vertex. +// +// If the write vertex advances past the end of data, +// implicitly adds a new vertex to the data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +add_data4f(float x, float y, float z, float w) { + add_data4f(LVecBase4f(x, y, z, w)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::add_data4f +// Access: Published +// Description: Sets the write vertex to a particular 4-component +// value, and advances the write vertex. +// +// If the write vertex advances past the end of data, +// implicitly adds a new vertex to the data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +add_data4f(const LVecBase4f &data) { + nassertv(_data_type != (qpGeomVertexDataType *)NULL); + _writer->set_data4f(inc_add_pointer(), data); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::add_data1i +// Access: Published +// Description: Sets the write vertex to a particular 1-component +// value, and advances the write vertex. +// +// If the write vertex advances past the end of data, +// implicitly adds a new vertex to the data. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +add_data1i(int data) { + nassertv(_data_type != (qpGeomVertexDataType *)NULL); + _writer->set_data1i(inc_add_pointer(), data); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_pointer +// Access: Private +// Description: Sets up the internal write pointer, etc. to use the +// indicated vertex. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter:: +set_pointer(int vertex) { + nassertv(_data_type != (qpGeomVertexDataType *)NULL); + _write_vertex = vertex; + PT(qpGeomVertexArrayData) array_data = _vertex_data->modify_array(_array); + _data = array_data->modify_data(); + _pointer = _data.p() + _data_type->get_start() + _stride * _write_vertex; + _num_vertices = array_data->get_num_vertices(); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::inc_pointer +// Access: Private +// Description: Increments to the next vertex, and returns the data +// pointer as it was before incrementing. +//////////////////////////////////////////////////////////////////// +INLINE unsigned char *qpGeomVertexWriter:: +inc_pointer() { + nassertr(_write_vertex < _num_vertices, NULL); + nassertr(_pointer == _vertex_data->get_array(_array)->get_data().p() + _data_type->get_start() + _stride * _write_vertex, NULL); + + unsigned char *orig_pointer = _pointer; + _pointer += _stride; + ++_write_vertex; + return orig_pointer; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::inc_add_pointer +// Access: Private +// Description: Increments to the next vertex, and returns the data +// pointer as it was before incrementing. If we are at +// or past the end of data, implicitly adds more +// vertices first. +//////////////////////////////////////////////////////////////////// +INLINE unsigned char *qpGeomVertexWriter:: +inc_add_pointer() { + if (_write_vertex >= _num_vertices) { + // Reset the data pointer. + _vertex_data->set_num_vertices(max(_write_vertex + 1, _vertex_data->get_num_vertices())); + set_pointer(_write_vertex); + } + return inc_pointer(); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer::maybe_scale_color +// Access: Public +// Description: Converts a floating-point value to a uint8 value. If +// the contents value indicates this is a color value, +// scales it into the range 0..255 per convention; +// otherwise leaves it alone. +//////////////////////////////////////////////////////////////////// +INLINE unsigned int qpGeomVertexWriter::Writer:: +maybe_scale_color(float data) { + switch (_data_type->get_contents()) { + case qpGeomVertexDataType::C_rgba: + case qpGeomVertexDataType::C_argb: + return (unsigned int)(data * 255.0f); + + default: + return (unsigned int)data; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer::maybe_scale_color +// Access: Public +// Description: Converts an LVecBase2f into a pair of uint8 +// values. See one-parameter maybe_scale_color() for +// more info. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter::Writer:: +maybe_scale_color(const LVecBase2f &data) { + switch (_data_type->get_contents()) { + case qpGeomVertexDataType::C_rgba: + case qpGeomVertexDataType::C_argb: + _a = (unsigned int)(data[0] * 255.0f); + _b = (unsigned int)(data[1] * 255.0f); + break; + + default: + _a = (unsigned int)data[0]; + _b = (unsigned int)data[1]; + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer::maybe_scale_color +// Access: Public +// Description: Converts an LVecBase3f into a pair of uint8 +// values. See one-parameter maybe_scale_color() for +// more info. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter::Writer:: +maybe_scale_color(const LVecBase3f &data) { + switch (_data_type->get_contents()) { + case qpGeomVertexDataType::C_rgba: + case qpGeomVertexDataType::C_argb: + _a = (unsigned int)(data[0] * 255.0f); + _b = (unsigned int)(data[1] * 255.0f); + _c = (unsigned int)(data[2] * 255.0f); + break; + + default: + _a = (unsigned int)data[0]; + _b = (unsigned int)data[1]; + _c = (unsigned int)data[2]; + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer::maybe_scale_color +// Access: Public +// Description: Converts an LVecBase4f into a pair of uint8 +// values. See one-parameter maybe_scale_color() for +// more info. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexWriter::Writer:: +maybe_scale_color(const LVecBase4f &data) { + switch (_data_type->get_contents()) { + case qpGeomVertexDataType::C_rgba: + case qpGeomVertexDataType::C_argb: + _a = (unsigned int)(data[0] * 255.0f); + _b = (unsigned int)(data[1] * 255.0f); + _c = (unsigned int)(data[2] * 255.0f); + _d = (unsigned int)(data[3] * 255.0f); + break; + + default: + _a = (unsigned int)data[0]; + _b = (unsigned int)data[1]; + _c = (unsigned int)data[2]; + _d = (unsigned int)data[3]; + break; + } +} diff --git a/panda/src/gobj/qpgeomVertexWriter.cxx b/panda/src/gobj/qpgeomVertexWriter.cxx new file mode 100644 index 0000000000..4d960a7c18 --- /dev/null +++ b/panda/src/gobj/qpgeomVertexWriter.cxx @@ -0,0 +1,721 @@ +// Filename: qpgeomVertexWriter.cxx +// Created by: drose (25Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "qpgeomVertexWriter.h" + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::set_data_type +// Access: Published +// Description: Sets up the writer to use the indicated data_type +// description on the given array. +// +// This also resets the current write vertex numbers to +// the start vertex (the same value passed to a previous +// call to set_vertex(), or 0 if set_vertex() was never +// called.) +// +// The return value is true if the data type is valid, +// false otherwise. +//////////////////////////////////////////////////////////////////// +bool qpGeomVertexWriter:: +set_data_type(int array, const qpGeomVertexDataType *data_type) { + // Delete the old writer, if we've got one. + if (_writer != (Writer *)NULL) { + delete _writer; + _writer = NULL; + } + + if (array < 0 || array >= _vertex_data->get_num_arrays() || + data_type == (qpGeomVertexDataType *)NULL) { + // Clear the data type. + _array = -1; + _data_type = NULL; + _stride = 0; + _write_vertex = _start_vertex; + _num_vertices = 0; + + return false; + + } else { + _array = array; + _data_type = data_type; + _stride = _vertex_data->get_format()->get_array(_array)->get_stride(); + + set_pointer(_start_vertex); + + // Now set up a new writer. + _writer = make_writer(); + _writer->_data_type = _data_type; + + return true; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::make_writer +// Access: Private +// Description: Returns a newly-allocated Writer object suitable for +// writing the current data type. +//////////////////////////////////////////////////////////////////// +qpGeomVertexWriter::Writer *qpGeomVertexWriter:: +make_writer() const { + switch (_data_type->get_contents()) { + case qpGeomVertexDataType::C_point: + case qpGeomVertexDataType::C_texcoord: + // These types are written as a 4-d homogeneous point. + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_float32: + switch (_data_type->get_num_components()) { + case 2: + return new Writer_point_float32_2; + case 3: + return new Writer_point_float32_3; + case 4: + return new Writer_point_float32_4; + + default: + break; + } + break; + default: + break; + } + return new Writer_point; + + case qpGeomVertexDataType::C_rgba: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + switch (_data_type->get_num_components()) { + case 4: + return new Writer_rgba_uint8_4; + + default: + break; + } + break; + case qpGeomVertexDataType::NT_float32: + switch (_data_type->get_num_components()) { + case 4: + return new Writer_rgba_float32_4; + + default: + break; + } + break; + default: + break; + } + return new Writer_color; + + case qpGeomVertexDataType::C_argb: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_packed_8888: + switch (_data_type->get_num_components()) { + case 1: + return new Writer_argb_packed_8888; + + default: + break; + } + break; + default: + break; + } + return new Writer_color; + + default: + // Otherwise, we just write it as a generic value. + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_float32: + switch (_data_type->get_num_components()) { + case 3: + return new Writer_float32_3; + + default: + break; + } + break; + default: + break; + } + return new Writer; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomVertexWriter::Writer:: +~Writer() { +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer::set_data1f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer:: +set_data1f(unsigned char *pointer, float data) { + switch (_data_type->get_num_values()) { + case 1: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + *pointer = maybe_scale_color(data); + break; + + case qpGeomVertexDataType::NT_uint16: + *(PN_uint16 *)pointer = (unsigned int)data; + break; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + dword._i = 0; + if (_data_type->get_contents() == qpGeomVertexDataType::C_argb) { + dword._b[1] = maybe_scale_color(data); + } else { + dword._b[0] = maybe_scale_color(data); + } + *(PN_uint32 *)pointer = dword._i; + } + break; + + case qpGeomVertexDataType::NT_float32: + *(PN_float32 *)pointer = data; + break; + } + break; + + case 2: + set_data2f(pointer, LVecBase2f(data, 0.0f)); + break; + + case 3: + set_data3f(pointer, LVecBase3f(data, 0.0f, 0.0f)); + break; + + case 4: + set_data4f(pointer, LVecBase4f(data, 0.0f, 0.0f, 0.0f)); + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer::set_data2f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer:: +set_data2f(unsigned char *pointer, const LVecBase2f &data) { + switch (_data_type->get_num_values()) { + case 1: + set_data1f(pointer, data[0]); + + case 2: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + maybe_scale_color(data); + pointer[0] = _a; + pointer[1] = _b; + break; + + case qpGeomVertexDataType::NT_uint16: + { + PN_uint16 *pi = (PN_uint16 *)pointer; + pi[0] = (unsigned int)data[0]; + pi[1] = (unsigned int)data[1]; + } + break; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + maybe_scale_color(data); + dword._i = 0; + if (_data_type->get_contents() == qpGeomVertexDataType::C_argb) { + dword._b[1] = _a; + dword._b[2] = _b; + } else { + dword._b[0] = _a; + dword._b[1] = _b; + } + *(PN_uint32 *)pointer = dword._i; + } + break; + + case qpGeomVertexDataType::NT_float32: + { + PN_float32 *pi = (PN_float32 *)pointer; + pi[0] = data[0]; + pi[1] = data[1]; + } + break; + } + break; + + case 3: + set_data3f(pointer, LVecBase3f(data[0], data[1], 0.0f)); + break; + + default: + set_data4f(pointer, LVecBase4f(data[0], data[1], 0.0f, 0.0f)); + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer::set_data3f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer:: +set_data3f(unsigned char *pointer, const LVecBase3f &data) { + switch (_data_type->get_num_values()) { + case 1: + set_data1f(pointer, data[0]); + break; + + case 2: + set_data2f(pointer, LVecBase2f(data[0], data[1])); + break; + + case 3: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + maybe_scale_color(data); + pointer[0] = _a; + pointer[1] = _b; + pointer[2] = _c; + break; + + case qpGeomVertexDataType::NT_uint16: + { + PN_uint16 *pi = (PN_uint16 *)pointer; + pi[0] = (unsigned int)data[0]; + pi[1] = (unsigned int)data[1]; + pi[2] = (unsigned int)data[2]; + } + break; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + maybe_scale_color(data); + if (_data_type->get_contents() == qpGeomVertexDataType::C_argb) { + dword._b[0] = 0; + dword._b[1] = _a; + dword._b[2] = _b; + dword._b[3] = _c; + } else { + dword._b[0] = _a; + dword._b[1] = _b; + dword._b[2] = _c; + dword._b[3] = 0; + } + *(PN_uint32 *)pointer = dword._i; + } + break; + + case qpGeomVertexDataType::NT_float32: + { + PN_float32 *pi = (PN_float32 *)pointer; + pi[0] = data[0]; + pi[1] = data[1]; + pi[2] = data[2]; + } + break; + } + break; + + default: + set_data4f(pointer, LVecBase4f(data[0], data[1], data[2], 0.0f)); + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer::set_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer:: +set_data4f(unsigned char *pointer, const LVecBase4f &data) { + switch (_data_type->get_num_values()) { + case 1: + set_data1f(pointer, data[0]); + break; + + case 2: + set_data2f(pointer, LVecBase2f(data[0], data[1])); + break; + + case 3: + set_data3f(pointer, LVecBase3f(data[0], data[1], data[2])); + break; + + default: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + maybe_scale_color(data); + pointer[0] = _a; + pointer[1] = _b; + pointer[2] = _c; + pointer[3] = _d; + break; + + case qpGeomVertexDataType::NT_uint16: + { + PN_uint16 *pi = (PN_uint16 *)pointer; + pi[0] = (unsigned int)data[0]; + pi[1] = (unsigned int)data[1]; + pi[2] = (unsigned int)data[2]; + pi[3] = (unsigned int)data[3]; + } + break; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + maybe_scale_color(data); + if (_data_type->get_contents() == qpGeomVertexDataType::C_argb) { + dword._b[0] = _d; + dword._b[1] = _a; + dword._b[2] = _b; + dword._b[3] = _c; + } else { + dword._b[0] = _a; + dword._b[1] = _b; + dword._b[2] = _c; + dword._b[3] = _d; + } + *(PN_uint32 *)pointer = dword._i; + } + break; + + case qpGeomVertexDataType::NT_float32: + { + PN_float32 *pi = (PN_float32 *)pointer; + pi[0] = data[0]; + pi[1] = data[1]; + pi[2] = data[2]; + pi[3] = data[3]; + } + break; + } + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer::set_data1i +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer:: +set_data1i(unsigned char *pointer, int data) { + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + *pointer = data; + break; + + case qpGeomVertexDataType::NT_uint16: + *(PN_uint16 *)pointer = data; + break; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + dword._i = 0; + if (_data_type->get_contents() == qpGeomVertexDataType::C_argb) { + dword._b[1] = data; + } else { + dword._b[0] = data; + } + *(PN_uint32 *)pointer = dword._i; + } + break; + + case qpGeomVertexDataType::NT_float32: + *(PN_float32 *)pointer = (float)data; + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_point::set_data1f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_point:: +set_data1f(unsigned char *pointer, float data) { + if (_data_type->get_num_values() == 4) { + set_data4f(pointer, LVecBase4f(data, 0.0f, 0.0f, 1.0f)); + } else { + Writer::set_data1f(pointer, data); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_point::set_data2f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_point:: +set_data2f(unsigned char *pointer, const LVecBase2f &data) { + if (_data_type->get_num_values() == 4) { + set_data4f(pointer, LVecBase4f(data[0], data[1], 0.0f, 1.0f)); + } else { + Writer::set_data2f(pointer, data); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_point::set_data3f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_point:: +set_data3f(unsigned char *pointer, const LVecBase3f &data) { + if (_data_type->get_num_values() == 4) { + set_data4f(pointer, LVecBase4f(data[0], data[1], data[2], 1.0f)); + } else { + Writer::set_data3f(pointer, data); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_point::set_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_point:: +set_data4f(unsigned char *pointer, const LVecBase4f &data) { + switch (_data_type->get_num_values()) { + case 1: + set_data1f(pointer, data[0] / data[3]); + break; + + case 2: + set_data2f(pointer, LVecBase2f(data[0] / data[3], data[1] / data[3])); + break; + + case 3: + set_data3f(pointer, LVecBase3f(data[0] / data[3], data[1] / data[3], data[2] / data[3])); + break; + + default: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + maybe_scale_color(data); + pointer[0] = _a; + pointer[1] = _b; + pointer[2] = _c; + pointer[3] = _d; + break; + + case qpGeomVertexDataType::NT_uint16: + { + PN_uint16 *pi = (PN_uint16 *)pointer; + pi[0] = (unsigned int)data[0]; + pi[1] = (unsigned int)data[1]; + pi[2] = (unsigned int)data[2]; + pi[3] = (unsigned int)data[3]; + } + break; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + maybe_scale_color(data); + if (_data_type->get_contents() == qpGeomVertexDataType::C_argb) { + dword._b[0] = _d; + dword._b[1] = _a; + dword._b[2] = _b; + dword._b[3] = _c; + } else { + dword._b[0] = _a; + dword._b[1] = _b; + dword._b[2] = _c; + dword._b[3] = _d; + } + *(PN_uint32 *)pointer = dword._i; + } + break; + + case qpGeomVertexDataType::NT_float32: + { + PN_float32 *pi = (PN_float32 *)pointer; + pi[0] = data[0]; + pi[1] = data[1]; + pi[2] = data[2]; + pi[3] = data[3]; + } + break; + } + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_color::set_data1f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_color:: +set_data1f(unsigned char *pointer, float data) { + if (_data_type->get_num_values() == 4) { + set_data4f(pointer, LVecBase4f(data, 0.0f, 0.0f, 1.0f)); + } else { + Writer::set_data1f(pointer, data); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_color::set_data2f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_color:: +set_data2f(unsigned char *pointer, const LVecBase2f &data) { + if (_data_type->get_num_values() == 4) { + set_data4f(pointer, LVecBase4f(data[0], data[1], 0.0f, 1.0f)); + } else { + Writer::set_data2f(pointer, data); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_color::set_data3f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_color:: +set_data3f(unsigned char *pointer, const LVecBase3f &data) { + if (_data_type->get_num_values() == 4) { + set_data4f(pointer, LVecBase4f(data[0], data[1], data[2], 1.0f)); + } else { + Writer::set_data3f(pointer, data); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_float32_3::set_data3f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_float32_3:: +set_data3f(unsigned char *pointer, const LVecBase3f &data) { + PN_float32 *pi = (PN_float32 *)pointer; + pi[0] = data[0]; + pi[1] = data[1]; + pi[2] = data[2]; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_point_float32_2::set_data2f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_point_float32_2:: +set_data2f(unsigned char *pointer, const LVecBase2f &data) { + PN_float32 *pi = (PN_float32 *)pointer; + pi[0] = data[0]; + pi[1] = data[1]; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_point_float32_3::set_data3f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_point_float32_3:: +set_data3f(unsigned char *pointer, const LVecBase3f &data) { + PN_float32 *pi = (PN_float32 *)pointer; + pi[0] = data[0]; + pi[1] = data[1]; + pi[2] = data[2]; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_point_float32_4::set_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_point_float32_4:: +set_data4f(unsigned char *pointer, const LVecBase4f &data) { + PN_float32 *pi = (PN_float32 *)pointer; + pi[0] = data[0]; + pi[1] = data[1]; + pi[2] = data[2]; + pi[3] = data[3]; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_argb_packed_8888::set_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_argb_packed_8888:: +set_data4f(unsigned char *pointer, const LVecBase4f &data) { + packed_8888 dword; + dword._b[0] = (unsigned int)(data[3] * 255.0f); + dword._b[1] = (unsigned int)(data[0] * 255.0f); + dword._b[2] = (unsigned int)(data[1] * 255.0f); + dword._b[3] = (unsigned int)(data[2] * 255.0f); + + *(PN_uint32 *)pointer = dword._i; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_rgba_uint8_4::set_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_rgba_uint8_4:: +set_data4f(unsigned char *pointer, const LVecBase4f &data) { + pointer[0] = (unsigned int)(data[0] * 255.0f); + pointer[1] = (unsigned int)(data[1] * 255.0f); + pointer[2] = (unsigned int)(data[2] * 255.0f); + pointer[3] = (unsigned int)(data[3] * 255.0f); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_rgba_float32_4::set_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_rgba_float32_4:: +set_data4f(unsigned char *pointer, const LVecBase4f &data) { + PN_float32 *pi = (PN_float32 *)pointer; + pi[0] = data[0]; + pi[1] = data[1]; + pi[2] = data[2]; + pi[3] = data[3]; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexWriter::Writer_uint16_1::set_data1i +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexWriter::Writer_uint16_1:: +set_data1i(unsigned char *pointer, int data) { + *(PN_uint16 *)pointer = data; +} diff --git a/panda/src/gobj/qpgeomVertexWriter.h b/panda/src/gobj/qpgeomVertexWriter.h new file mode 100644 index 0000000000..4b8a207776 --- /dev/null +++ b/panda/src/gobj/qpgeomVertexWriter.h @@ -0,0 +1,226 @@ +// Filename: qpgeomVertexWriter.h +// Created by: drose (25Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef qpGEOMVERTEXWRITER_H +#define qpGEOMVERTEXWRITER_H + +#include "pandabase.h" +#include "qpgeomVertexData.h" +#include "qpgeomVertexDataType.h" +#include "internalName.h" +#include "luse.h" +#include "pointerTo.h" + +//////////////////////////////////////////////////////////////////// +// Class : qpGeomVertexWriter +// Description : This object provides a high-level interface for +// quickly writing a sequence of numeric values from a +// vertex table. +// +// This object can be used both to replace existing +// vertices in the table, or to extend the table with +// new vertices. The set_data*() family of methods can +// only be used to replace existing data; it is an error +// to allow these to run past the end of the data. The +// add_data*() family of methods, on the other hand, can +// be used to replace existing data or add new data; if +// you call set_vertex() into the middle of existing +// data the add_data*() methods will behave like the +// corresponding set_data*(), but if they run past the +// end of existing data they will quietly add new data. +// +// Like GeomVertexReader, the writer is particularly +// optimized for writing a column of data values for a +// series of vertices, without changing data types +// between each number. Although you can use one +// GeomVertexWriter to write one complete row at a time, +// by calling set_data_type() repeatedly for each +// vertex, it is faster to use a different +// GeomVertexWriter for each data type. +// +// This is part of the experimental Geom rewrite. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA qpGeomVertexWriter { +PUBLISHED: + INLINE qpGeomVertexWriter(qpGeomVertexData *vertex_data); + INLINE qpGeomVertexWriter(qpGeomVertexData *vertex_data, + const string &name); + INLINE qpGeomVertexWriter(qpGeomVertexData *vertex_data, + const InternalName *name); + INLINE ~qpGeomVertexWriter(); + + INLINE qpGeomVertexData *get_vertex_data() const; + + INLINE bool set_data_type(int data_type); + INLINE bool set_data_type(const string &name); + INLINE bool set_data_type(const InternalName *name); + bool set_data_type(int array, const qpGeomVertexDataType *data_type); + + INLINE bool has_data_type() const; + INLINE int get_array() const; + INLINE const qpGeomVertexDataType *get_data_type() const; + + INLINE void set_vertex(int vertex); + + INLINE int get_start_vertex() const; + INLINE int get_write_vertex() const; + INLINE int get_num_vertices() const; + INLINE bool is_at_end() const; + + INLINE void set_data1f(float data); + INLINE void set_data2f(float x, float y); + INLINE void set_data2f(const LVecBase2f &data); + INLINE void set_data3f(float x, float y, float z); + INLINE void set_data3f(const LVecBase3f &data); + INLINE void set_data4f(float x, float y, float z, float w); + INLINE void set_data4f(const LVecBase4f &data); + + INLINE void set_data1i(int data); + + INLINE void add_data1f(float data); + INLINE void add_data2f(float x, float y); + INLINE void add_data2f(const LVecBase2f &data); + INLINE void add_data3f(float x, float y, float z); + INLINE void add_data3f(const LVecBase3f &data); + INLINE void add_data4f(float x, float y, float z, float w); + INLINE void add_data4f(const LVecBase4f &data); + + INLINE void add_data1i(int data); + +private: + class Writer; + + INLINE void set_pointer(int vertex); + INLINE unsigned char *inc_pointer(); + INLINE unsigned char *inc_add_pointer(); + Writer *make_writer() const; + + PT(qpGeomVertexData) _vertex_data; + int _array; + const qpGeomVertexDataType *_data_type; + int _stride; + + PTA_uchar _data; + unsigned char *_pointer; + + int _start_vertex; + int _write_vertex; + int _num_vertices; + + Writer *_writer; + + // This union is handy for packing an NT_packed_8888 value. + typedef union { + unsigned char _b[4]; + PN_uint32 _i; + } packed_8888; + + // This nested class provides the implementation for unpacking data + // in a very general way, but also provides the hooks for + // implementing the common, very direct code paths (for instance, + // 3-component float32 to LVecBase3f) as quickly as possible. + class Writer { + public: + virtual ~Writer(); + virtual void set_data1f(unsigned char *pointer, float data); + virtual void set_data2f(unsigned char *pointer, const LVecBase2f &data); + virtual void set_data3f(unsigned char *pointer, const LVecBase3f &data); + virtual void set_data4f(unsigned char *pointer, const LVecBase4f &data); + + virtual void set_data1i(unsigned char *pointer, int data); + + INLINE unsigned int maybe_scale_color(float data); + INLINE void maybe_scale_color(const LVecBase2f &data); + INLINE void maybe_scale_color(const LVecBase3f &data); + INLINE void maybe_scale_color(const LVecBase4f &data); + + const qpGeomVertexDataType *_data_type; + unsigned int _a, _b, _c, _d; + }; + + // This is a specialization on the generic Writer that handles + // points, which are special because the fourth component, if + // present in the data but not specified by the caller, is + // implicitly 1.0; and if it is not present in the data but is + // specified, we have to divide by it. + class Writer_point : public Writer { + public: + virtual void set_data1f(unsigned char *pointer, float data); + virtual void set_data2f(unsigned char *pointer, const LVecBase2f &data); + virtual void set_data3f(unsigned char *pointer, const LVecBase3f &data); + virtual void set_data4f(unsigned char *pointer, const LVecBase4f &data); + }; + + // This is similar to Writer_point, in that the fourth component + // (alpha) is implicitly 1.0 if unspecified, but we never divide by + // alpha. + class Writer_color : public Writer { + public: + virtual void set_data1f(unsigned char *pointer, float data); + virtual void set_data2f(unsigned char *pointer, const LVecBase2f &data); + virtual void set_data3f(unsigned char *pointer, const LVecBase3f &data); + }; + + + // These are the specializations on the generic Writer that handle + // the direct code paths. + + class Writer_float32_3 : public Writer { + public: + virtual void set_data3f(unsigned char *pointer, const LVecBase3f &value); + }; + + class Writer_point_float32_2 : public Writer_point { + public: + virtual void set_data2f(unsigned char *pointer, const LVecBase2f &value); + }; + + class Writer_point_float32_3 : public Writer_point { + public: + virtual void set_data3f(unsigned char *pointer, const LVecBase3f &value); + }; + + class Writer_point_float32_4 : public Writer_point { + public: + virtual void set_data4f(unsigned char *pointer, const LVecBase4f &value); + }; + + class Writer_argb_packed_8888 : public Writer_color { + public: + virtual void set_data4f(unsigned char *pointer, const LVecBase4f &value); + }; + + class Writer_rgba_uint8_4 : public Writer_color { + public: + virtual void set_data4f(unsigned char *pointer, const LVecBase4f &value); + }; + + class Writer_rgba_float32_4 : public Writer_color { + public: + virtual void set_data4f(unsigned char *pointer, const LVecBase4f &value); + }; + + class Writer_uint16_1 : public Writer { + public: + virtual void set_data1i(unsigned char *pointer, int value); + }; +}; + +#include "qpgeomVertexWriter.I" + +#endif diff --git a/panda/src/pgraph/geomNode.cxx b/panda/src/pgraph/geomNode.cxx index 5bcbbff4c4..0f50326c79 100644 --- a/panda/src/pgraph/geomNode.cxx +++ b/panda/src/pgraph/geomNode.cxx @@ -17,6 +17,7 @@ //////////////////////////////////////////////////////////////////// #include "geomNode.h" +#include "qpgeom.h" #include "geomTransformer.h" #include "sceneGraphReducer.h" #include "accumulatedAttribs.h" @@ -351,25 +352,35 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, int num_geoms = get_num_geoms(); for (int i = 0; i < num_geoms; i++) { const Geom *geom = get_geom(i); - Geom::VertexIterator vi = geom->make_vertex_iterator(); - int num_prims = geom->get_num_prims(); - for (int p = 0; p < num_prims; p++) { - int length = geom->get_length(p); - for (int v = 0; v < length; v++) { - Vertexf vertex = geom->get_next_vertex(vi) * mat; - - if (found_any) { - min_point.set(min(min_point[0], vertex[0]), - min(min_point[1], vertex[1]), - min(min_point[2], vertex[2])); - max_point.set(max(max_point[0], vertex[0]), - max(max_point[1], vertex[1]), - max(max_point[2], vertex[2])); - } else { - min_point = vertex; - max_point = vertex; - found_any = true; + // Temporary test until the experimental Geom rewrite is final. + if (geom->is_exact_type(qpGeom::get_class_type())) { + const qpGeom *qpgeom = DCAST(qpGeom, geom); + qpgeom->calc_tight_bounds(min_point, max_point, found_any, + qpgeom->get_vertex_data()->animate_vertices(), + !transform->is_identity(), mat); + + } else { + Geom::VertexIterator vi = geom->make_vertex_iterator(); + int num_prims = geom->get_num_prims(); + + for (int p = 0; p < num_prims; p++) { + int length = geom->get_length(p); + for (int v = 0; v < length; v++) { + Vertexf vertex = geom->get_next_vertex(vi) * mat; + + if (found_any) { + min_point.set(min(min_point[0], vertex[0]), + min(min_point[1], vertex[1]), + min(min_point[2], vertex[2])); + max_point.set(max(max_point[0], vertex[0]), + max(max_point[1], vertex[1]), + max(max_point[2], vertex[2])); + } else { + min_point = vertex; + max_point = vertex; + found_any = true; + } } } }