Browse Source

flatten color scales too

David Rose 24 years ago
parent
commit
9f7475dcea

+ 19 - 0
panda/src/sgraph/geomTransformer.I

@@ -55,3 +55,22 @@ operator < (const GeomTransformer::SourceTexCoords &other) const {
   }
   }
   return (_mat.compare_to(other._mat) < 0);
   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);
+}

+ 100 - 1
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.
   // with a new color array containing just this color.
 
 
   // We do want to share this one-element array between Geoms, though.
   // 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()) {
   if (new_colors.is_null()) {
     // We haven't seen this color before; define a new color array.
     // 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;
   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;
+}

+ 24 - 2
panda/src/sgraph/geomTransformer.h

@@ -56,6 +56,11 @@ public:
   bool set_color(Geom *geom, const Colorf &color);
   bool set_color(Geom *geom, const Colorf &color);
   bool set_color(GeomNode *node, 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:
 private:
   class SourceVertices {
   class SourceVertices {
   public:
   public:
@@ -87,8 +92,25 @@ private:
   typedef pmap<SourceTexCoords, PTA_TexCoordf> TexCoords;
   typedef pmap<SourceTexCoords, PTA_TexCoordf> TexCoords;
   TexCoords _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"
 #include "geomTransformer.I"

+ 5 - 1
panda/src/sgraphutil/sceneGraphReducer.I

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

+ 53 - 5
panda/src/sgraphutil/sceneGraphReducer.cxx

@@ -19,11 +19,11 @@
 #include "sceneGraphReducer.h"
 #include "sceneGraphReducer.h"
 #include "config_sgraphutil.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;
     _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) {
   if ((transition_types & TT_texture_matrix) != 0) {
     _texture_matrix->write(out, indent_level);
     _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) {
   if ((transition_types & TT_texture_matrix) != 0) {
     trans._texture_matrix = new TexMatrixTransition;
     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);
   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();
   PT(Node) node = arc->get_child();
   nassertv(node != (Node *)NULL);
   nassertv(node != (Node *)NULL);
 
 
@@ -267,6 +305,16 @@ r_apply_transitions(NodeRelation *arc, int transition_types,
                                          trans._texture_matrix->get_matrix());
                                          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 {
   } else {
     // This handles any kind of node other than a GeomNode.
     // This handles any kind of node other than a GeomNode.

+ 15 - 10
panda/src/sgraphutil/sceneGraphReducer.h

@@ -19,16 +19,18 @@
 #ifndef SCENEGRAPHREDUCER_H
 #ifndef SCENEGRAPHREDUCER_H
 #define SCENEGRAPHREDUCER_H
 #define SCENEGRAPHREDUCER_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 "pandabase.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;
 class Geom;
 
 
@@ -47,6 +49,7 @@ public:
     TT_transform       = 0x001,
     TT_transform       = 0x001,
     TT_color           = 0x002,
     TT_color           = 0x002,
     TT_texture_matrix  = 0x004,
     TT_texture_matrix  = 0x004,
+    TT_color_matrix    = 0x008,
   };
   };
 
 
   void apply_transitions(NodeRelation *arc, int transition_types = ~0);
   void apply_transitions(NodeRelation *arc, int transition_types = ~0);
@@ -64,6 +67,8 @@ protected:
     PT(TransformTransition) _transform;
     PT(TransformTransition) _transform;
     PT(ColorTransition) _color;
     PT(ColorTransition) _color;
     PT(TexMatrixTransition) _texture_matrix;
     PT(TexMatrixTransition) _texture_matrix;
+    PT(ColorMatrixTransition) _color_matrix;
+    PT(AlphaTransformTransition) _alpha_transform;
   };
   };
 
 
   void r_apply_transitions(NodeRelation *arc, int transition_types,
   void r_apply_transitions(NodeRelation *arc, int transition_types,