mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
flattening qpgeom
This commit is contained in:
parent
08241a99ea
commit
c6bcbe88f5
@ -87,12 +87,12 @@ munge_data_impl(const qpGeomVertexData *data) {
|
|||||||
_contents);
|
_contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
qpGeomVertexAnimationSpec animation = data->get_format()->get_animation();
|
qpGeomVertexAnimationSpec animation = new_data->get_format()->get_animation();
|
||||||
if (hardware_animated_vertices &&
|
if (hardware_animated_vertices &&
|
||||||
animation.get_animation_type() == qpGeomVertexAnimationSpec::AT_panda &&
|
animation.get_animation_type() == qpGeomVertexAnimationSpec::AT_panda &&
|
||||||
data->get_slider_table() == (SliderTable *)NULL) {
|
new_data->get_slider_table() == (SliderTable *)NULL) {
|
||||||
// Maybe we can animate the vertices with hardware.
|
// Maybe we can animate the vertices with hardware.
|
||||||
const TransformBlendPalette *palette = data->get_transform_blend_palette();
|
const TransformBlendPalette *palette = new_data->get_transform_blend_palette();
|
||||||
if (palette != (TransformBlendPalette *)NULL &&
|
if (palette != (TransformBlendPalette *)NULL &&
|
||||||
palette->get_max_simultaneous_transforms() <=
|
palette->get_max_simultaneous_transforms() <=
|
||||||
_gsg->get_max_vertex_transforms()) {
|
_gsg->get_max_vertex_transforms()) {
|
||||||
@ -121,15 +121,15 @@ munge_data_impl(const qpGeomVertexData *data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPT(qpGeomVertexFormat) orig_format = data->get_format();
|
CPT(qpGeomVertexFormat) orig_format = new_data->get_format();
|
||||||
CPT(qpGeomVertexFormat) new_format = munge_format(orig_format, animation);
|
CPT(qpGeomVertexFormat) new_format = munge_format(orig_format, animation);
|
||||||
|
|
||||||
if (new_format == orig_format) {
|
if (new_format == orig_format) {
|
||||||
// Trivial case.
|
// Trivial case.
|
||||||
return data;
|
return new_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return data->convert_to(new_format);
|
return new_data->convert_to(new_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -74,6 +74,18 @@ get_usage_hint() const {
|
|||||||
return _usage_hint;
|
return _usage_hint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomVertexData::has_column
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if the data has the named column,
|
||||||
|
// false otherwise. This is really just a shortcut for
|
||||||
|
// asking the same thing from the format.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool qpGeomVertexData::
|
||||||
|
has_column(const InternalName *name) const {
|
||||||
|
return _format->has_column(name);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomVertexData::set_num_vertices
|
// Function: qpGeomVertexData::set_num_vertices
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -85,6 +85,7 @@ qpGeomVertexData(const qpGeomVertexData ©) :
|
|||||||
TypedWritableReferenceCount(copy),
|
TypedWritableReferenceCount(copy),
|
||||||
_name(copy._name),
|
_name(copy._name),
|
||||||
_format(copy._format),
|
_format(copy._format),
|
||||||
|
_usage_hint(copy._usage_hint),
|
||||||
_cycler(copy._cycler),
|
_cycler(copy._cycler),
|
||||||
_app_char_pcollector(copy._app_char_pcollector),
|
_app_char_pcollector(copy._app_char_pcollector),
|
||||||
_cull_char_pcollector(copy._cull_char_pcollector)
|
_cull_char_pcollector(copy._cull_char_pcollector)
|
||||||
@ -101,6 +102,10 @@ operator = (const qpGeomVertexData ©) {
|
|||||||
TypedWritableReferenceCount::operator = (copy);
|
TypedWritableReferenceCount::operator = (copy);
|
||||||
_name = copy._name;
|
_name = copy._name;
|
||||||
_format = copy._format;
|
_format = copy._format;
|
||||||
|
|
||||||
|
// The assignment operator does not copy the usage_hint, which is
|
||||||
|
// not supposed to change over the lifetime of a GeomVertexData.
|
||||||
|
|
||||||
_cycler = copy._cycler;
|
_cycler = copy._cycler;
|
||||||
_app_char_pcollector = copy._app_char_pcollector;
|
_app_char_pcollector = copy._app_char_pcollector;
|
||||||
_cull_char_pcollector = copy._cull_char_pcollector;
|
_cull_char_pcollector = copy._cull_char_pcollector;
|
||||||
@ -727,10 +732,10 @@ set_color(const Colorf &color, int num_components,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
PT(qpGeomVertexData) qpGeomVertexData::
|
PT(qpGeomVertexData) qpGeomVertexData::
|
||||||
replace_column(const InternalName *name, int num_components,
|
replace_column(const InternalName *name, int num_components,
|
||||||
qpGeomVertexColumn::NumericType numeric_type,
|
qpGeomVertexColumn::NumericType numeric_type,
|
||||||
qpGeomVertexColumn::Contents contents,
|
qpGeomVertexColumn::Contents contents,
|
||||||
qpGeomUsageHint::UsageHint usage_hint,
|
qpGeomUsageHint::UsageHint usage_hint,
|
||||||
bool keep_animation) const {
|
bool keep_animation) const {
|
||||||
PT(qpGeomVertexFormat) new_format = new qpGeomVertexFormat(*_format);
|
PT(qpGeomVertexFormat) new_format = new qpGeomVertexFormat(*_format);
|
||||||
|
|
||||||
// Remove the old description of the type from the format.
|
// Remove the old description of the type from the format.
|
||||||
@ -818,7 +823,7 @@ output(ostream &out) const {
|
|||||||
if (!get_name().empty()) {
|
if (!get_name().empty()) {
|
||||||
out << get_name() << " ";
|
out << get_name() << " ";
|
||||||
}
|
}
|
||||||
out << get_num_vertices() << ": " << *get_format();
|
out << get_num_vertices() << " vertices: " << *get_format();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -831,7 +836,7 @@ write(ostream &out, int indent_level) const {
|
|||||||
if (!get_name().empty()) {
|
if (!get_name().empty()) {
|
||||||
indent(out, indent_level) << get_name() << "\n";
|
indent(out, indent_level) << get_name() << "\n";
|
||||||
}
|
}
|
||||||
_format->write_with_data(out, indent_level, this);
|
_format->write_with_data(out, indent_level + 2, this);
|
||||||
if (get_transform_blend_palette() != (TransformBlendPalette *)NULL) {
|
if (get_transform_blend_palette() != (TransformBlendPalette *)NULL) {
|
||||||
indent(out, indent_level)
|
indent(out, indent_level)
|
||||||
<< "Transform blend palette:\n";
|
<< "Transform blend palette:\n";
|
||||||
|
@ -83,6 +83,8 @@ PUBLISHED:
|
|||||||
INLINE const qpGeomVertexFormat *get_format() const;
|
INLINE const qpGeomVertexFormat *get_format() const;
|
||||||
INLINE qpGeomUsageHint::UsageHint get_usage_hint() const;
|
INLINE qpGeomUsageHint::UsageHint get_usage_hint() const;
|
||||||
|
|
||||||
|
INLINE bool has_column(const InternalName *name) const;
|
||||||
|
|
||||||
int get_num_vertices() const;
|
int get_num_vertices() const;
|
||||||
INLINE bool set_num_vertices(int n);
|
INLINE bool set_num_vertices(int n);
|
||||||
void clear_vertices();
|
void clear_vertices();
|
||||||
@ -129,10 +131,10 @@ PUBLISHED:
|
|||||||
|
|
||||||
PT(qpGeomVertexData)
|
PT(qpGeomVertexData)
|
||||||
replace_column(const InternalName *name, int num_components,
|
replace_column(const InternalName *name, int num_components,
|
||||||
qpGeomVertexColumn::NumericType numeric_type,
|
qpGeomVertexColumn::NumericType numeric_type,
|
||||||
qpGeomVertexColumn::Contents contents,
|
qpGeomVertexColumn::Contents contents,
|
||||||
qpGeomUsageHint::UsageHint usage_hint,
|
qpGeomUsageHint::UsageHint usage_hint,
|
||||||
bool keep_animation) const;
|
bool keep_animation) const;
|
||||||
|
|
||||||
void output(ostream &out) const;
|
void output(ostream &out) const;
|
||||||
void write(ostream &out, int indent_level = 0) const;
|
void write(ostream &out, int indent_level = 0) const;
|
||||||
|
@ -17,6 +17,51 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomTransformer::qpSourceVertices::Ordering Operator
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool GeomTransformer::qpSourceVertices::
|
||||||
|
operator < (const GeomTransformer::qpSourceVertices &other) const {
|
||||||
|
if (_vertex_data != other._vertex_data) {
|
||||||
|
return _vertex_data < other._vertex_data;
|
||||||
|
}
|
||||||
|
return (_mat.compare_to(other._mat) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomTransformer::qpSourceTexCoords::Ordering Operator
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool GeomTransformer::qpSourceTexCoords::
|
||||||
|
operator < (const GeomTransformer::qpSourceTexCoords &other) const {
|
||||||
|
if (_vertex_data != other._vertex_data) {
|
||||||
|
return _vertex_data < other._vertex_data;
|
||||||
|
}
|
||||||
|
if (_from != other._from) {
|
||||||
|
return _from < other._from;
|
||||||
|
}
|
||||||
|
if (_to != other._to) {
|
||||||
|
return _to < other._to;
|
||||||
|
}
|
||||||
|
return (_mat.compare_to(other._mat) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomTransformer::qpSourceColors::Ordering Operator
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool GeomTransformer::qpSourceColors::
|
||||||
|
operator < (const GeomTransformer::qpSourceColors &other) const {
|
||||||
|
if (_vertex_data != other._vertex_data) {
|
||||||
|
return _vertex_data < other._vertex_data;
|
||||||
|
}
|
||||||
|
return (_color.compare_to(other._color) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GeomTransformer::SourceVertices::Ordering Operator
|
// Function: GeomTransformer::SourceVertices::Ordering Operator
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#include "geomTransformer.h"
|
#include "geomTransformer.h"
|
||||||
#include "geomNode.h"
|
#include "geomNode.h"
|
||||||
|
#include "qpgeom.h"
|
||||||
|
#include "qpgeomVertexRewriter.h"
|
||||||
#include "renderState.h"
|
#include "renderState.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -51,61 +53,98 @@ transform_vertices(Geom *geom, const LMatrix4f &mat) {
|
|||||||
|
|
||||||
nassertr(geom != (Geom *)NULL, false);
|
nassertr(geom != (Geom *)NULL, false);
|
||||||
|
|
||||||
PTA_Vertexf coords;
|
if (geom->is_exact_type(qpGeom::get_class_type())) {
|
||||||
PTA_ushort index;
|
qpGeom *qpgeom = DCAST(qpGeom, geom);
|
||||||
|
|
||||||
geom->get_coords(coords, index);
|
qpSourceVertices sv;
|
||||||
|
|
||||||
if (!coords.empty()) {
|
|
||||||
// Look up the Geom's coords in our table--have we already
|
|
||||||
// transformed this array?
|
|
||||||
SourceVertices sv;
|
|
||||||
sv._mat = mat;
|
sv._mat = mat;
|
||||||
sv._coords = coords;
|
sv._vertex_data = qpgeom->get_vertex_data();
|
||||||
|
|
||||||
PTA_Vertexf &new_coords = _vertices[sv];
|
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();
|
||||||
|
|
||||||
if (new_coords.is_null()) {
|
int ci;
|
||||||
// We have not transformed the array yet. Do so now.
|
for (ci = 0; ci < format->get_num_points(); ci++) {
|
||||||
new_coords.reserve(coords.size());
|
qpGeomVertexRewriter data(new_data, format->get_point(ci));
|
||||||
PTA_Vertexf::const_iterator vi;
|
|
||||||
for (vi = coords.begin(); vi != coords.end(); ++vi) {
|
while (!data.is_at_end()) {
|
||||||
new_coords.push_back((*vi) * mat);
|
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));
|
||||||
|
|
||||||
|
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;
|
transformed = true;
|
||||||
}
|
|
||||||
|
|
||||||
// Now do the same thing for normals.
|
} else {
|
||||||
PTA_Normalf norms;
|
PTA_Vertexf coords;
|
||||||
GeomBindType bind;
|
PTA_ushort index;
|
||||||
|
|
||||||
geom->get_normals(norms, bind, index);
|
geom->get_coords(coords, index);
|
||||||
|
|
||||||
if (bind != G_OFF) {
|
if (!coords.empty()) {
|
||||||
SourceNormals sn;
|
// Look up the Geom's coords in our table--have we already
|
||||||
sn._mat = mat;
|
// transformed this array?
|
||||||
sn._norms = norms;
|
SourceVertices sv;
|
||||||
|
sv._mat = mat;
|
||||||
PTA_Normalf &new_norms = _normals[sn];
|
sv._coords = coords;
|
||||||
|
|
||||||
if (new_norms.is_null()) {
|
PTA_Vertexf &new_coords = _vertices[sv];
|
||||||
// We have not transformed the array yet. Do so now.
|
|
||||||
new_norms.reserve(norms.size());
|
if (new_coords.is_null()) {
|
||||||
PTA_Normalf::const_iterator ni;
|
// We have not transformed the array yet. Do so now.
|
||||||
for (ni = norms.begin(); ni != norms.end(); ++ni) {
|
new_coords.reserve(coords.size());
|
||||||
Normalf new_norm = (*ni) * mat;
|
PTA_Vertexf::const_iterator vi;
|
||||||
new_norm.normalize();
|
for (vi = coords.begin(); vi != coords.end(); ++vi) {
|
||||||
new_norms.push_back(new_norm);
|
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);
|
// Now do the same thing for normals.
|
||||||
transformed = true;
|
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;
|
return transformed;
|
||||||
@ -155,34 +194,78 @@ transform_texcoords(Geom *geom, const InternalName *from_name,
|
|||||||
bool transformed = false;
|
bool transformed = false;
|
||||||
|
|
||||||
nassertr(geom != (Geom *)NULL, false);
|
nassertr(geom != (Geom *)NULL, false);
|
||||||
|
if (geom->is_exact_type(qpGeom::get_class_type())) {
|
||||||
|
qpGeom *qpgeom = DCAST(qpGeom, geom);
|
||||||
|
|
||||||
PTA_TexCoordf texcoords = geom->get_texcoords_array(from_name);
|
qpSourceTexCoords st;
|
||||||
PTA_ushort index = geom->get_texcoords_index(from_name);
|
st._mat = mat;
|
||||||
|
st._from = from_name;
|
||||||
|
st._to = to_name;
|
||||||
|
st._vertex_data = qpgeom->get_vertex_data();
|
||||||
|
|
||||||
if (!texcoords.is_null()) {
|
PT(qpGeomVertexData) &new_data = _qptexcoords[st];
|
||||||
// Look up the Geom's texcoords in our table--have we already
|
if (new_data.is_null()) {
|
||||||
// transformed this array?
|
if (!st._vertex_data->has_column(from_name)) {
|
||||||
SourceTexCoords stc;
|
// No from_name column; no change.
|
||||||
stc._mat = mat;
|
return false;
|
||||||
stc._texcoords = texcoords;
|
}
|
||||||
|
|
||||||
PTA_TexCoordf &new_texcoords = _texcoords[stc];
|
// We have not yet converted these texcoords. Do so now.
|
||||||
|
if (st._vertex_data->has_column(to_name)) {
|
||||||
if (new_texcoords.is_null()) {
|
new_data = new qpGeomVertexData(*st._vertex_data);
|
||||||
// We have not transformed the array yet. Do so now.
|
} else {
|
||||||
new_texcoords.reserve(texcoords.size());
|
const qpGeomVertexColumn *old_column =
|
||||||
PTA_TexCoordf::const_iterator tci;
|
st._vertex_data->get_format()->get_column(from_name);
|
||||||
for (tci = texcoords.begin(); tci != texcoords.end(); ++tci) {
|
new_data = st._vertex_data->replace_column
|
||||||
const TexCoordf &tc = (*tci);
|
(to_name, old_column->get_num_components(),
|
||||||
LVecBase4f v4(tc[0], tc[1], 0.0f, 1.0f);
|
old_column->get_numeric_type(),
|
||||||
v4 = v4 * mat;
|
old_column->get_contents(), st._vertex_data->get_usage_hint(),
|
||||||
new_texcoords.push_back(TexCoordf(v4[0] / v4[3], v4[1] / v4[3]));
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
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;
|
return transformed;
|
||||||
@ -229,19 +312,41 @@ transform_texcoords(GeomNode *node, const InternalName *from_name,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool GeomTransformer::
|
bool GeomTransformer::
|
||||||
set_color(Geom *geom, const Colorf &color) {
|
set_color(Geom *geom, const Colorf &color) {
|
||||||
// In this case, we always replace whatever color array was there
|
bool transformed = false;
|
||||||
// with a new color array containing just this color.
|
|
||||||
|
|
||||||
// We do want to share this one-element array between Geoms, though.
|
if (geom->is_exact_type(qpGeom::get_class_type())) {
|
||||||
PTA_Colorf &new_colors = _fcolors[color];
|
qpGeom *qpgeom = DCAST(qpGeom, geom);
|
||||||
|
|
||||||
if (new_colors.is_null()) {
|
qpSourceColors sc;
|
||||||
// We haven't seen this color before; define a new color array.
|
sc._color = color;
|
||||||
new_colors.push_back(color);
|
sc._vertex_data = qpgeom->get_vertex_data();
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
} 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 transformed;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -284,38 +389,56 @@ transform_colors(Geom *geom, const LVecBase4f &scale) {
|
|||||||
|
|
||||||
nassertr(geom != (Geom *)NULL, false);
|
nassertr(geom != (Geom *)NULL, false);
|
||||||
|
|
||||||
PTA_Colorf colors;
|
if (geom->is_exact_type(qpGeom::get_class_type())) {
|
||||||
GeomBindType bind;
|
qpGeom *qpgeom = DCAST(qpGeom, geom);
|
||||||
PTA_ushort index;
|
|
||||||
|
|
||||||
geom->get_colors(colors, bind, index);
|
qpSourceColors sc;
|
||||||
|
sc._color = scale;
|
||||||
|
sc._vertex_data = qpgeom->get_vertex_data();
|
||||||
|
|
||||||
if (bind != G_OFF) {
|
CPT(qpGeomVertexData) &new_data = _qptcolors[sc];
|
||||||
// Look up the Geom's colors in our table--have we already
|
if (new_data.is_null()) {
|
||||||
// transformed this array?
|
// We have not yet converted these colors. Do so now.
|
||||||
SourceColors sc;
|
new_data = sc._vertex_data->scale_color(scale);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
geom->set_colors(new_colors, bind, index);
|
qpgeom->set_vertex_data(new_data);
|
||||||
transformed = true;
|
transformed = true;
|
||||||
|
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
geom->set_colors(new_colors, bind, index);
|
||||||
|
transformed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return transformed;
|
return transformed;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "geom.h"
|
#include "geom.h"
|
||||||
#include "luse.h"
|
#include "luse.h"
|
||||||
|
#include "qpgeomVertexData.h"
|
||||||
|
|
||||||
class GeomNode;
|
class GeomNode;
|
||||||
class RenderState;
|
class RenderState;
|
||||||
@ -68,6 +69,44 @@ public:
|
|||||||
bool apply_state(GeomNode *node, const RenderState *state);
|
bool apply_state(GeomNode *node, const RenderState *state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
class qpSourceVertices {
|
||||||
|
public:
|
||||||
|
INLINE bool operator < (const qpSourceVertices &other) const;
|
||||||
|
|
||||||
|
LMatrix4f _mat;
|
||||||
|
CPT(qpGeomVertexData) _vertex_data;
|
||||||
|
};
|
||||||
|
typedef pmap<qpSourceVertices, PT(qpGeomVertexData) > NewVertices;
|
||||||
|
NewVertices _qpvertices;
|
||||||
|
|
||||||
|
class qpSourceTexCoords {
|
||||||
|
public:
|
||||||
|
INLINE bool operator < (const qpSourceTexCoords &other) const;
|
||||||
|
|
||||||
|
LMatrix4f _mat;
|
||||||
|
CPT(InternalName) _from;
|
||||||
|
CPT(InternalName) _to;
|
||||||
|
CPT(qpGeomVertexData) _vertex_data;
|
||||||
|
};
|
||||||
|
typedef pmap<qpSourceTexCoords, PT(qpGeomVertexData) > NewTexCoords;
|
||||||
|
NewTexCoords _qptexcoords;
|
||||||
|
|
||||||
|
class qpSourceColors {
|
||||||
|
public:
|
||||||
|
INLINE bool operator < (const qpSourceColors &other) const;
|
||||||
|
|
||||||
|
LVecBase4f _color;
|
||||||
|
CPT(qpGeomVertexData) _vertex_data;
|
||||||
|
};
|
||||||
|
typedef pmap<qpSourceColors, CPT(qpGeomVertexData) > NewColors;
|
||||||
|
|
||||||
|
// We have two concepts of colors: the "fixed" colors, which are
|
||||||
|
// slapped in complete replacement of the original colors (e.g. via
|
||||||
|
// a ColorAttrib), and the "transformed" colors, which are modified
|
||||||
|
// from the original colors (e.g. via a ColorScaleAttrib).
|
||||||
|
NewColors _qpfcolors, _qptcolors;
|
||||||
|
|
||||||
|
|
||||||
class SourceVertices {
|
class SourceVertices {
|
||||||
public:
|
public:
|
||||||
INLINE bool operator < (const SourceVertices &other) const;
|
INLINE bool operator < (const SourceVertices &other) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user