From 9f7475dceac36c7af962661af16beed13ec5e89f Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 26 Dec 2001 20:20:21 +0000 Subject: [PATCH] flatten color scales too --- panda/src/sgraph/geomTransformer.I | 19 ++++ panda/src/sgraph/geomTransformer.cxx | 101 ++++++++++++++++++++- panda/src/sgraph/geomTransformer.h | 26 +++++- panda/src/sgraphutil/sceneGraphReducer.I | 6 +- panda/src/sgraphutil/sceneGraphReducer.cxx | 58 +++++++++++- panda/src/sgraphutil/sceneGraphReducer.h | 23 +++-- 6 files changed, 215 insertions(+), 18 deletions(-) diff --git a/panda/src/sgraph/geomTransformer.I b/panda/src/sgraph/geomTransformer.I index c70643a8be..be89a735f9 100644 --- a/panda/src/sgraph/geomTransformer.I +++ b/panda/src/sgraph/geomTransformer.I @@ -55,3 +55,22 @@ operator < (const GeomTransformer::SourceTexCoords &other) const { } return (_mat.compare_to(other._mat) < 0); } + +//////////////////////////////////////////////////////////////////// +// Function: GeomTransformer::SourceColors::Ordering Operator +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool GeomTransformer::SourceColors:: +operator < (const GeomTransformer::SourceColors &other) const { + if (_colors != other._colors) { + return _colors < other._colors; + } + if (_alpha_scale != other._alpha_scale) { + return _alpha_scale < other._alpha_scale; + } + if (_alpha_offset != other._alpha_offset) { + return _alpha_offset < other._alpha_offset; + } + return (_mat.compare_to(other._mat) < 0); +} diff --git a/panda/src/sgraph/geomTransformer.cxx b/panda/src/sgraph/geomTransformer.cxx index 7e51861f6e..20e2da8890 100644 --- a/panda/src/sgraph/geomTransformer.cxx +++ b/panda/src/sgraph/geomTransformer.cxx @@ -262,7 +262,7 @@ set_color(Geom *geom, const Colorf &color) { // 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 = _colors[color]; + PTA_Colorf &new_colors = _fcolors[color]; if (new_colors.is_null()) { // We haven't seen this color before; define a new color array. @@ -312,3 +312,102 @@ set_color(GeomNode *node, const Colorf &color) { return false; } + +//////////////////////////////////////////////////////////////////// +// Function: GeomTransformer::transform_colors +// Access: Public +// Description: Transforms the colors in the indicated +// Geom by the indicated matrix. Returns true if the +// Geom was changed, false otherwise. +//////////////////////////////////////////////////////////////////// +bool GeomTransformer:: +transform_colors(Geom *geom, const LMatrix4f &mat, + float alpha_scale, float alpha_offset) { + bool transformed = false; + + nassertr(geom != (Geom *)NULL, false); + + 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._mat = mat; + sc._alpha_scale = alpha_scale; + sc._alpha_offset = alpha_offset; + 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); + + LPoint3f temp(c[0], c[1], c[2]); + temp = temp * mat; + float alpha = (c[3] * alpha_scale) + alpha_offset; + + Colorf transformed(temp[0], temp[1], temp[2], alpha); + new_colors.push_back(transformed); + } + nassertr(new_colors.size() == colors.size(), false); + } + + geom->set_colors(new_colors, bind, index); + transformed = true; + } + + return transformed; +} + + +//////////////////////////////////////////////////////////////////// +// Function: GeomTransformer::transform_colors +// Access: Public +// Description: Transforms the colors and the normals in all of the +// Geoms within the indicated GeomNode by the indicated +// matrix. Does not destructively change Geoms; +// instead, a copy will be made of each Geom to be +// changed, in case multiple GeomNodes reference the +// same Geom. Returns true if the GeomNode was changed, +// false otherwise. +//////////////////////////////////////////////////////////////////// +bool GeomTransformer:: +transform_colors(GeomNode *node, const LMatrix4f &mat, + float alpha_scale, float alpha_offset) { + bool any_changed = false; + + GeomNode::Geoms new_geoms; + + GeomNode::Geoms::const_iterator gi; + for (gi = node->_geoms.begin(); gi != node->_geoms.end(); ++gi) { + dDrawable *drawable = (*gi); + if (drawable->is_of_type(Geom::get_class_type())) { + Geom *geom = DCAST(Geom, drawable); + PT(Geom) new_geom = geom->make_copy(); + if (transform_colors(new_geom, mat, alpha_scale, alpha_offset)) { + new_geoms.push_back(new_geom.p()); + any_changed = true; + } else { + new_geoms.push_back(geom); + } + } else { + new_geoms.push_back(drawable); + } + } + + if (any_changed) { + node->_geoms = new_geoms; + return true; + } + + return false; +} diff --git a/panda/src/sgraph/geomTransformer.h b/panda/src/sgraph/geomTransformer.h index 9624667913..afbc7d3680 100644 --- a/panda/src/sgraph/geomTransformer.h +++ b/panda/src/sgraph/geomTransformer.h @@ -56,6 +56,11 @@ public: bool set_color(Geom *geom, const Colorf &color); bool set_color(GeomNode *node, const Colorf &color); + bool transform_colors(Geom *geom, const LMatrix4f &mat, + float alpha_scale, float alpha_offset); + bool transform_colors(GeomNode *node, const LMatrix4f &mat, + float alpha_scale, float alpha_offset); + private: class SourceVertices { public: @@ -87,8 +92,25 @@ private: typedef pmap TexCoords; TexCoords _texcoords; - typedef pmap Colors; - Colors _colors; + // We have two concepts of colors: the "fixed" colors, which are + // slapped in complete replacement of the original colors (e.g. via + // a ColorTransition), and the "transformed" colors, which are + // modified from the original colors (e.g. via a + // ColorMatrixTransition). + typedef pmap FColors; + FColors _fcolors; + + class SourceColors { + public: + INLINE bool operator < (const SourceColors &other) const; + + LMatrix4f _mat; + float _alpha_scale; + float _alpha_offset; + PTA_Colorf _colors; + }; + typedef pmap TColors; + TColors _tcolors; }; #include "geomTransformer.I" diff --git a/panda/src/sgraphutil/sceneGraphReducer.I b/panda/src/sgraphutil/sceneGraphReducer.I index 3604993149..6643528c92 100644 --- a/panda/src/sgraphutil/sceneGraphReducer.I +++ b/panda/src/sgraphutil/sceneGraphReducer.I @@ -35,7 +35,9 @@ INLINE SceneGraphReducer::AccumulatedTransitions:: AccumulatedTransitions(const SceneGraphReducer::AccumulatedTransitions ©) : _transform(copy._transform), _color(copy._color), - _texture_matrix(copy._texture_matrix) + _texture_matrix(copy._texture_matrix), + _color_matrix(copy._color_matrix), + _alpha_transform(copy._alpha_transform) { } @@ -49,4 +51,6 @@ operator = (const SceneGraphReducer::AccumulatedTransitions ©) { _transform = copy._transform; _color = copy._color; _texture_matrix = copy._texture_matrix; + _color_matrix = copy._color_matrix; + _alpha_transform = copy._alpha_transform; } diff --git a/panda/src/sgraphutil/sceneGraphReducer.cxx b/panda/src/sgraphutil/sceneGraphReducer.cxx index 894286b058..580b01fc10 100644 --- a/panda/src/sgraphutil/sceneGraphReducer.cxx +++ b/panda/src/sgraphutil/sceneGraphReducer.cxx @@ -19,11 +19,11 @@ #include "sceneGraphReducer.h" #include "config_sgraphutil.h" -#include -#include -#include -#include -#include +#include "geomNode.h" +#include "geom.h" +#include "indent.h" +#include "billboardTransition.h" +#include "decalTransition.h" //////////////////////////////////////////////////////////////////// @@ -54,6 +54,18 @@ apply_to_arc(NodeRelation *arc, int transition_types) { } _texture_matrix = new TexMatrixTransition; } + + if ((transition_types & TT_color_matrix) != 0) { + if (!_color_matrix->get_matrix().almost_equal(LMatrix4f::ident_mat())) { + arc->set_transition(_color_matrix); + } + if (_alpha_transform->get_scale() != 1.0f || + _alpha_transform->get_offset() != 0.0f) { + arc->set_transition(_alpha_transform); + } + _color_matrix = new ColorMatrixTransition; + _alpha_transform = new AlphaTransformTransition; + } } //////////////////////////////////////////////////////////////////// @@ -72,6 +84,10 @@ write(ostream &out, int transition_types, int indent_level) const { if ((transition_types & TT_texture_matrix) != 0) { _texture_matrix->write(out, indent_level); } + if ((transition_types & TT_color_matrix) != 0) { + _color_matrix->write(out, indent_level); + _alpha_transform->write(out, indent_level); + } } //////////////////////////////////////////////////////////////////// @@ -114,6 +130,10 @@ apply_transitions(NodeRelation *arc, int transition_types) { if ((transition_types & TT_texture_matrix) != 0) { trans._texture_matrix = new TexMatrixTransition; } + if ((transition_types & TT_color_matrix) != 0) { + trans._color_matrix = new ColorMatrixTransition; + trans._alpha_transform = new AlphaTransformTransition; + } r_apply_transitions(arc, transition_types, trans, false); } @@ -163,6 +183,24 @@ r_apply_transitions(NodeRelation *arc, int transition_types, } } + if ((transition_types & TT_color_matrix) != 0) { + nassertv(trans._color_matrix != (ColorMatrixTransition *)NULL); + ColorMatrixTransition *cmt; + if (get_transition_into(cmt, arc)) { + trans._color_matrix = + DCAST(ColorMatrixTransition, trans._color_matrix->compose(cmt)); + arc->clear_transition(ColorMatrixTransition::get_class_type()); + } + + nassertv(trans._alpha_transform != (AlphaTransformTransition *)NULL); + AlphaTransformTransition *att; + if (get_transition_into(att, arc)) { + trans._alpha_transform = + DCAST(AlphaTransformTransition, trans._alpha_transform->compose(att)); + arc->clear_transition(AlphaTransformTransition::get_class_type()); + } + } + PT(Node) node = arc->get_child(); nassertv(node != (Node *)NULL); @@ -267,6 +305,16 @@ r_apply_transitions(NodeRelation *arc, int transition_types, trans._texture_matrix->get_matrix()); } } + if ((transition_types & TT_color_matrix) != 0) { + if (trans._color_matrix->get_matrix() != LMatrix4f::ident_mat() || + trans._alpha_transform->get_scale() != 1.0f || + trans._alpha_transform->get_offset() != 0.0f) { + _transformer.transform_colors(gnode, + trans._color_matrix->get_matrix(), + trans._alpha_transform->get_scale(), + trans._alpha_transform->get_offset()); + } + } } else { // This handles any kind of node other than a GeomNode. diff --git a/panda/src/sgraphutil/sceneGraphReducer.h b/panda/src/sgraphutil/sceneGraphReducer.h index a28206571f..766833f7a7 100644 --- a/panda/src/sgraphutil/sceneGraphReducer.h +++ b/panda/src/sgraphutil/sceneGraphReducer.h @@ -19,16 +19,18 @@ #ifndef SCENEGRAPHREDUCER_H #define SCENEGRAPHREDUCER_H -#include +#include "pandabase.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include "graphReducer.h" +#include "typedObject.h" +#include "pointerTo.h" +#include "transformTransition.h" +#include "colorTransition.h" +#include "texMatrixTransition.h" +#include "colorMatrixTransition.h" +#include "alphaTransformTransition.h" +#include "geomTransformer.h" +#include "renderRelation.h" class Geom; @@ -47,6 +49,7 @@ public: TT_transform = 0x001, TT_color = 0x002, TT_texture_matrix = 0x004, + TT_color_matrix = 0x008, }; void apply_transitions(NodeRelation *arc, int transition_types = ~0); @@ -64,6 +67,8 @@ protected: PT(TransformTransition) _transform; PT(ColorTransition) _color; PT(TexMatrixTransition) _texture_matrix; + PT(ColorMatrixTransition) _color_matrix; + PT(AlphaTransformTransition) _alpha_transform; }; void r_apply_transitions(NodeRelation *arc, int transition_types,