|
|
@@ -18,6 +18,8 @@
|
|
|
|
|
|
#include "geomTransformer.h"
|
|
|
#include "geomNode.h"
|
|
|
+#include "qpgeom.h"
|
|
|
+#include "qpgeomVertexRewriter.h"
|
|
|
#include "renderState.h"
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
@@ -51,61 +53,98 @@ transform_vertices(Geom *geom, const LMatrix4f &mat) {
|
|
|
|
|
|
nassertr(geom != (Geom *)NULL, false);
|
|
|
|
|
|
- PTA_Vertexf coords;
|
|
|
- PTA_ushort index;
|
|
|
+ if (geom->is_exact_type(qpGeom::get_class_type())) {
|
|
|
+ qpGeom *qpgeom = DCAST(qpGeom, geom);
|
|
|
|
|
|
- geom->get_coords(coords, index);
|
|
|
-
|
|
|
- if (!coords.empty()) {
|
|
|
- // Look up the Geom's coords in our table--have we already
|
|
|
- // transformed this array?
|
|
|
- SourceVertices sv;
|
|
|
+ qpSourceVertices sv;
|
|
|
sv._mat = mat;
|
|
|
- sv._coords = coords;
|
|
|
-
|
|
|
- PTA_Vertexf &new_coords = _vertices[sv];
|
|
|
+ sv._vertex_data = qpgeom->get_vertex_data();
|
|
|
+
|
|
|
+ PT(qpGeomVertexData) &new_data = _qpvertices[sv];
|
|
|
+ if (new_data.is_null()) {
|
|
|
+ // We have not yet converted these vertices. Do so now.
|
|
|
+ new_data = new qpGeomVertexData(*sv._vertex_data);
|
|
|
+ CPT(qpGeomVertexFormat) format = new_data->get_format();
|
|
|
+
|
|
|
+ int ci;
|
|
|
+ for (ci = 0; ci < format->get_num_points(); ci++) {
|
|
|
+ qpGeomVertexRewriter data(new_data, format->get_point(ci));
|
|
|
+
|
|
|
+ while (!data.is_at_end()) {
|
|
|
+ const LPoint3f &point = data.get_data3f();
|
|
|
+ data.set_data3f(point * mat);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (ci = 0; ci < format->get_num_vectors(); ci++) {
|
|
|
+ qpGeomVertexRewriter data(new_data, format->get_vector(ci));
|
|
|
|
|
|
- if (new_coords.is_null()) {
|
|
|
- // We have not transformed the array yet. Do so now.
|
|
|
- new_coords.reserve(coords.size());
|
|
|
- PTA_Vertexf::const_iterator vi;
|
|
|
- for (vi = coords.begin(); vi != coords.end(); ++vi) {
|
|
|
- new_coords.push_back((*vi) * mat);
|
|
|
+ while (!data.is_at_end()) {
|
|
|
+ const LVector3f &vector = data.get_data3f();
|
|
|
+ data.set_data3f(normalize(vector * mat));
|
|
|
+ }
|
|
|
}
|
|
|
- nassertr(new_coords.size() == coords.size(), false);
|
|
|
}
|
|
|
|
|
|
- geom->set_coords(new_coords, index);
|
|
|
+ qpgeom->set_vertex_data(new_data);
|
|
|
transformed = true;
|
|
|
- }
|
|
|
-
|
|
|
- // Now do the same thing for normals.
|
|
|
- PTA_Normalf norms;
|
|
|
- GeomBindType bind;
|
|
|
|
|
|
- geom->get_normals(norms, bind, index);
|
|
|
-
|
|
|
- if (bind != G_OFF) {
|
|
|
- SourceNormals sn;
|
|
|
- sn._mat = mat;
|
|
|
- sn._norms = norms;
|
|
|
-
|
|
|
- PTA_Normalf &new_norms = _normals[sn];
|
|
|
-
|
|
|
- if (new_norms.is_null()) {
|
|
|
- // We have not transformed the array yet. Do so now.
|
|
|
- new_norms.reserve(norms.size());
|
|
|
- PTA_Normalf::const_iterator ni;
|
|
|
- for (ni = norms.begin(); ni != norms.end(); ++ni) {
|
|
|
- Normalf new_norm = (*ni) * mat;
|
|
|
- new_norm.normalize();
|
|
|
- new_norms.push_back(new_norm);
|
|
|
+ } else {
|
|
|
+ PTA_Vertexf coords;
|
|
|
+ PTA_ushort index;
|
|
|
+
|
|
|
+ geom->get_coords(coords, index);
|
|
|
+
|
|
|
+ if (!coords.empty()) {
|
|
|
+ // Look up the Geom's coords in our table--have we already
|
|
|
+ // transformed this array?
|
|
|
+ SourceVertices sv;
|
|
|
+ sv._mat = mat;
|
|
|
+ sv._coords = coords;
|
|
|
+
|
|
|
+ PTA_Vertexf &new_coords = _vertices[sv];
|
|
|
+
|
|
|
+ if (new_coords.is_null()) {
|
|
|
+ // We have not transformed the array yet. Do so now.
|
|
|
+ new_coords.reserve(coords.size());
|
|
|
+ PTA_Vertexf::const_iterator vi;
|
|
|
+ for (vi = coords.begin(); vi != coords.end(); ++vi) {
|
|
|
+ new_coords.push_back((*vi) * mat);
|
|
|
+ }
|
|
|
+ nassertr(new_coords.size() == coords.size(), false);
|
|
|
}
|
|
|
- nassertr(new_norms.size() == norms.size(), false);
|
|
|
+
|
|
|
+ geom->set_coords(new_coords, index);
|
|
|
+ transformed = true;
|
|
|
}
|
|
|
|
|
|
- geom->set_normals(new_norms, bind, index);
|
|
|
- transformed = true;
|
|
|
+ // Now do the same thing for normals.
|
|
|
+ PTA_Normalf norms;
|
|
|
+ GeomBindType bind;
|
|
|
+
|
|
|
+ geom->get_normals(norms, bind, index);
|
|
|
+
|
|
|
+ if (bind != G_OFF) {
|
|
|
+ SourceNormals sn;
|
|
|
+ sn._mat = mat;
|
|
|
+ sn._norms = norms;
|
|
|
+
|
|
|
+ PTA_Normalf &new_norms = _normals[sn];
|
|
|
+
|
|
|
+ if (new_norms.is_null()) {
|
|
|
+ // We have not transformed the array yet. Do so now.
|
|
|
+ new_norms.reserve(norms.size());
|
|
|
+ PTA_Normalf::const_iterator ni;
|
|
|
+ for (ni = norms.begin(); ni != norms.end(); ++ni) {
|
|
|
+ Normalf new_norm = (*ni) * mat;
|
|
|
+ new_norm.normalize();
|
|
|
+ new_norms.push_back(new_norm);
|
|
|
+ }
|
|
|
+ nassertr(new_norms.size() == norms.size(), false);
|
|
|
+ }
|
|
|
+
|
|
|
+ geom->set_normals(new_norms, bind, index);
|
|
|
+ transformed = true;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return transformed;
|
|
|
@@ -155,34 +194,78 @@ transform_texcoords(Geom *geom, const InternalName *from_name,
|
|
|
bool transformed = false;
|
|
|
|
|
|
nassertr(geom != (Geom *)NULL, false);
|
|
|
+ if (geom->is_exact_type(qpGeom::get_class_type())) {
|
|
|
+ qpGeom *qpgeom = DCAST(qpGeom, geom);
|
|
|
+
|
|
|
+ qpSourceTexCoords st;
|
|
|
+ st._mat = mat;
|
|
|
+ st._from = from_name;
|
|
|
+ st._to = to_name;
|
|
|
+ st._vertex_data = qpgeom->get_vertex_data();
|
|
|
+
|
|
|
+ PT(qpGeomVertexData) &new_data = _qptexcoords[st];
|
|
|
+ if (new_data.is_null()) {
|
|
|
+ if (!st._vertex_data->has_column(from_name)) {
|
|
|
+ // No from_name column; no change.
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // We have not yet converted these texcoords. Do so now.
|
|
|
+ if (st._vertex_data->has_column(to_name)) {
|
|
|
+ new_data = new qpGeomVertexData(*st._vertex_data);
|
|
|
+ } else {
|
|
|
+ const qpGeomVertexColumn *old_column =
|
|
|
+ st._vertex_data->get_format()->get_column(from_name);
|
|
|
+ new_data = st._vertex_data->replace_column
|
|
|
+ (to_name, old_column->get_num_components(),
|
|
|
+ old_column->get_numeric_type(),
|
|
|
+ old_column->get_contents(), st._vertex_data->get_usage_hint(),
|
|
|
+ false);
|
|
|
+ }
|
|
|
|
|
|
- PTA_TexCoordf texcoords = geom->get_texcoords_array(from_name);
|
|
|
- PTA_ushort index = geom->get_texcoords_index(from_name);
|
|
|
-
|
|
|
- if (!texcoords.is_null()) {
|
|
|
- // Look up the Geom's texcoords in our table--have we already
|
|
|
- // transformed this array?
|
|
|
- SourceTexCoords stc;
|
|
|
- stc._mat = mat;
|
|
|
- stc._texcoords = texcoords;
|
|
|
-
|
|
|
- PTA_TexCoordf &new_texcoords = _texcoords[stc];
|
|
|
-
|
|
|
- if (new_texcoords.is_null()) {
|
|
|
- // We have not transformed the array yet. Do so now.
|
|
|
- new_texcoords.reserve(texcoords.size());
|
|
|
- PTA_TexCoordf::const_iterator tci;
|
|
|
- for (tci = texcoords.begin(); tci != texcoords.end(); ++tci) {
|
|
|
- const TexCoordf &tc = (*tci);
|
|
|
- LVecBase4f v4(tc[0], tc[1], 0.0f, 1.0f);
|
|
|
- v4 = v4 * mat;
|
|
|
- new_texcoords.push_back(TexCoordf(v4[0] / v4[3], v4[1] / v4[3]));
|
|
|
+ CPT(qpGeomVertexFormat) format = new_data->get_format();
|
|
|
+
|
|
|
+ qpGeomVertexWriter tdata(new_data, to_name);
|
|
|
+ qpGeomVertexReader fdata(new_data, from_name);
|
|
|
+
|
|
|
+ while (!fdata.is_at_end()) {
|
|
|
+ const LPoint4f &coord = fdata.get_data4f();
|
|
|
+ tdata.set_data4f(coord * mat);
|
|
|
}
|
|
|
- nassertr(new_texcoords.size() == texcoords.size(), false);
|
|
|
}
|
|
|
|
|
|
- geom->set_texcoords(to_name, new_texcoords, index);
|
|
|
+ qpgeom->set_vertex_data(new_data);
|
|
|
transformed = true;
|
|
|
+
|
|
|
+ } else {
|
|
|
+ PTA_TexCoordf texcoords = geom->get_texcoords_array(from_name);
|
|
|
+ PTA_ushort index = geom->get_texcoords_index(from_name);
|
|
|
+
|
|
|
+ if (!texcoords.is_null()) {
|
|
|
+ // Look up the Geom's texcoords in our table--have we already
|
|
|
+ // transformed this array?
|
|
|
+ SourceTexCoords stc;
|
|
|
+ stc._mat = mat;
|
|
|
+ stc._texcoords = texcoords;
|
|
|
+
|
|
|
+ PTA_TexCoordf &new_texcoords = _texcoords[stc];
|
|
|
+
|
|
|
+ if (new_texcoords.is_null()) {
|
|
|
+ // We have not transformed the array yet. Do so now.
|
|
|
+ new_texcoords.reserve(texcoords.size());
|
|
|
+ PTA_TexCoordf::const_iterator tci;
|
|
|
+ for (tci = texcoords.begin(); tci != texcoords.end(); ++tci) {
|
|
|
+ const TexCoordf &tc = (*tci);
|
|
|
+ LVecBase4f v4(tc[0], tc[1], 0.0f, 1.0f);
|
|
|
+ v4 = v4 * mat;
|
|
|
+ new_texcoords.push_back(TexCoordf(v4[0] / v4[3], v4[1] / v4[3]));
|
|
|
+ }
|
|
|
+ nassertr(new_texcoords.size() == texcoords.size(), false);
|
|
|
+ }
|
|
|
+
|
|
|
+ geom->set_texcoords(to_name, new_texcoords, index);
|
|
|
+ transformed = true;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return transformed;
|
|
|
@@ -229,19 +312,41 @@ transform_texcoords(GeomNode *node, const InternalName *from_name,
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
bool GeomTransformer::
|
|
|
set_color(Geom *geom, const Colorf &color) {
|
|
|
- // In this case, we always replace whatever color array was there
|
|
|
- // with a new color array containing just this color.
|
|
|
+ bool transformed = false;
|
|
|
+
|
|
|
+ if (geom->is_exact_type(qpGeom::get_class_type())) {
|
|
|
+ qpGeom *qpgeom = DCAST(qpGeom, geom);
|
|
|
+
|
|
|
+ qpSourceColors sc;
|
|
|
+ sc._color = color;
|
|
|
+ sc._vertex_data = qpgeom->get_vertex_data();
|
|
|
|
|
|
- // We do want to share this one-element array between Geoms, though.
|
|
|
- PTA_Colorf &new_colors = _fcolors[color];
|
|
|
+ CPT(qpGeomVertexData) &new_data = _qpfcolors[sc];
|
|
|
+ if (new_data.is_null()) {
|
|
|
+ // We have not yet converted these colors. Do so now.
|
|
|
+ new_data = sc._vertex_data->set_color(color);
|
|
|
+ }
|
|
|
+
|
|
|
+ qpgeom->set_vertex_data(new_data);
|
|
|
+ transformed = true;
|
|
|
|
|
|
- if (new_colors.is_null()) {
|
|
|
- // We haven't seen this color before; define a new color array.
|
|
|
- new_colors.push_back(color);
|
|
|
+ } else {
|
|
|
+ // In this case, we always replace whatever color array was there
|
|
|
+ // with a new color array containing just this color.
|
|
|
+
|
|
|
+ // We do want to share this one-element array between Geoms, though.
|
|
|
+ PTA_Colorf &new_colors = _fcolors[color];
|
|
|
+
|
|
|
+ if (new_colors.is_null()) {
|
|
|
+ // We haven't seen this color before; define a new color array.
|
|
|
+ new_colors.push_back(color);
|
|
|
+ }
|
|
|
+
|
|
|
+ geom->set_colors(new_colors, G_OVERALL);
|
|
|
+ transformed = true;
|
|
|
}
|
|
|
|
|
|
- geom->set_colors(new_colors, G_OVERALL);
|
|
|
- return true;
|
|
|
+ return transformed;
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -284,38 +389,56 @@ transform_colors(Geom *geom, const LVecBase4f &scale) {
|
|
|
|
|
|
nassertr(geom != (Geom *)NULL, false);
|
|
|
|
|
|
- PTA_Colorf colors;
|
|
|
- GeomBindType bind;
|
|
|
- PTA_ushort index;
|
|
|
+ if (geom->is_exact_type(qpGeom::get_class_type())) {
|
|
|
+ qpGeom *qpgeom = DCAST(qpGeom, geom);
|
|
|
|
|
|
- geom->get_colors(colors, bind, index);
|
|
|
+ qpSourceColors sc;
|
|
|
+ sc._color = scale;
|
|
|
+ sc._vertex_data = qpgeom->get_vertex_data();
|
|
|
|
|
|
- if (bind != G_OFF) {
|
|
|
- // Look up the Geom's colors in our table--have we already
|
|
|
- // transformed this array?
|
|
|
- SourceColors sc;
|
|
|
- sc._scale = scale;
|
|
|
- sc._colors = colors;
|
|
|
+ CPT(qpGeomVertexData) &new_data = _qptcolors[sc];
|
|
|
+ if (new_data.is_null()) {
|
|
|
+ // We have not yet converted these colors. Do so now.
|
|
|
+ new_data = sc._vertex_data->scale_color(scale);
|
|
|
+ }
|
|
|
|
|
|
- PTA_Colorf &new_colors = _tcolors[sc];
|
|
|
+ qpgeom->set_vertex_data(new_data);
|
|
|
+ transformed = true;
|
|
|
|
|
|
- if (new_colors.is_null()) {
|
|
|
- // We have not transformed the array yet. Do so now.
|
|
|
- new_colors.reserve(colors.size());
|
|
|
- PTA_Colorf::const_iterator ci;
|
|
|
- for (ci = colors.begin(); ci != colors.end(); ++ci) {
|
|
|
- const Colorf &c = (*ci);
|
|
|
- Colorf transformed(c[0] * scale[0],
|
|
|
- c[1] * scale[1],
|
|
|
- c[2] * scale[2],
|
|
|
- c[3] * scale[3]);
|
|
|
- new_colors.push_back(transformed);
|
|
|
+ } else {
|
|
|
+ PTA_Colorf colors;
|
|
|
+ GeomBindType bind;
|
|
|
+ PTA_ushort index;
|
|
|
+
|
|
|
+ geom->get_colors(colors, bind, index);
|
|
|
+
|
|
|
+ if (bind != G_OFF) {
|
|
|
+ // Look up the Geom's colors in our table--have we already
|
|
|
+ // transformed this array?
|
|
|
+ SourceColors sc;
|
|
|
+ sc._scale = scale;
|
|
|
+ sc._colors = colors;
|
|
|
+
|
|
|
+ PTA_Colorf &new_colors = _tcolors[sc];
|
|
|
+
|
|
|
+ if (new_colors.is_null()) {
|
|
|
+ // We have not transformed the array yet. Do so now.
|
|
|
+ new_colors.reserve(colors.size());
|
|
|
+ PTA_Colorf::const_iterator ci;
|
|
|
+ for (ci = colors.begin(); ci != colors.end(); ++ci) {
|
|
|
+ const Colorf &c = (*ci);
|
|
|
+ Colorf transformed(c[0] * scale[0],
|
|
|
+ c[1] * scale[1],
|
|
|
+ c[2] * scale[2],
|
|
|
+ c[3] * scale[3]);
|
|
|
+ new_colors.push_back(transformed);
|
|
|
+ }
|
|
|
+ nassertr(new_colors.size() == colors.size(), false);
|
|
|
}
|
|
|
- nassertr(new_colors.size() == colors.size(), false);
|
|
|
+
|
|
|
+ geom->set_colors(new_colors, bind, index);
|
|
|
+ transformed = true;
|
|
|
}
|
|
|
-
|
|
|
- geom->set_colors(new_colors, bind, index);
|
|
|
- transformed = true;
|
|
|
}
|
|
|
|
|
|
return transformed;
|