flatten color scales too

This commit is contained in:
David Rose 2001-12-26 20:20:21 +00:00
parent 9733e17391
commit 9f7475dcea
6 changed files with 215 additions and 18 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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<SourceTexCoords, PTA_TexCoordf> TexCoords;
TexCoords _texcoords;
typedef pmap<Colorf, PTA_Colorf> 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<Colorf, PTA_Colorf> 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<SourceColors, PTA_Colorf> TColors;
TColors _tcolors;
};
#include "geomTransformer.I"

View File

@ -35,7 +35,9 @@ INLINE SceneGraphReducer::AccumulatedTransitions::
AccumulatedTransitions(const SceneGraphReducer::AccumulatedTransitions &copy) :
_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 &copy) {
_transform = copy._transform;
_color = copy._color;
_texture_matrix = copy._texture_matrix;
_color_matrix = copy._color_matrix;
_alpha_transform = copy._alpha_transform;
}

View File

@ -19,11 +19,11 @@
#include "sceneGraphReducer.h"
#include "config_sgraphutil.h"
#include <geomNode.h>
#include <geom.h>
#include <indent.h>
#include <billboardTransition.h>
#include <decalTransition.h>
#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.

View File

@ -19,16 +19,18 @@
#ifndef SCENEGRAPHREDUCER_H
#define SCENEGRAPHREDUCER_H
#include <pandabase.h>
#include "pandabase.h"
#include <graphReducer.h>
#include <typedObject.h>
#include <pointerTo.h>
#include <transformTransition.h>
#include <colorTransition.h>
#include <texMatrixTransition.h>
#include <geomTransformer.h>
#include <renderRelation.h>
#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,