Pārlūkot izejas kodu

apply per-attrib override to TexMatrixAttrib also

David Rose 15 gadi atpakaļ
vecāks
revīzija
91e6231a3c

+ 4 - 6
direct/src/interval/cLerpNodePathInterval.cxx

@@ -463,10 +463,12 @@ priv_step(double t) {
 
       const RenderAttrib *attrib =
         state->get_attrib(TexMatrixAttrib::get_class_type());
-      const TexMatrixAttrib *tma = NULL;
+      CPT(TexMatrixAttrib) tma;
       if (attrib != (const TexMatrixAttrib *)NULL) {
         tma = DCAST(TexMatrixAttrib, attrib);
         transform = tma->get_transform(_texture_stage);
+      } else {
+        tma = DCAST(TexMatrixAttrib, TexMatrixAttrib::make());
       }
 
       if ((_flags & F_end_tex_offset) != 0) {
@@ -512,11 +514,7 @@ priv_step(double t) {
       }
 
       // Apply the modified transform back to the state.
-      if (tma != (TexMatrixAttrib *)NULL) {
-        state = state->add_attrib(tma->add_stage(_texture_stage, transform), _override);
-      } else {
-        state = state->add_attrib(TexMatrixAttrib::make(_texture_stage, transform), _override);
-      }
+      state = state->set_attrib(tma->add_stage(_texture_stage, transform, _override));
     }    
 
 

+ 58 - 11
panda/src/pgraph/texMatrixAttrib.I

@@ -20,7 +20,7 @@
 //               TexMatrixAttrib object.
 ////////////////////////////////////////////////////////////////////
 INLINE TexMatrixAttrib::
-TexMatrixAttrib() : _stage_list_stale(true) {
+TexMatrixAttrib() {
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -31,11 +31,27 @@ TexMatrixAttrib() : _stage_list_stale(true) {
 ////////////////////////////////////////////////////////////////////
 INLINE TexMatrixAttrib::
 TexMatrixAttrib(const TexMatrixAttrib &copy) :
-  _stages(copy._stages),
-  _stage_list_stale(true)
+  _stages(copy._stages)
 {
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::get_override
+//       Access: Published
+//  Description: Returns the override value associated with the
+//               indicated stage.
+////////////////////////////////////////////////////////////////////
+INLINE int TexMatrixAttrib::
+get_override(TextureStage *stage) const {
+  Stages::const_iterator si;
+  si = _stages.find(StageNode(stage));
+  if (si != _stages.end()) {
+    return (*si)._override;
+  }
+  nassert_raise("Specified TextureStage not included in attrib");
+  return 0;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TexMatrixAttrib::get_geom_rendering
 //       Access: Published
@@ -56,14 +72,45 @@ get_geom_rendering(int geom_rendering) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: TexMatrixAttrib::check_stage_list
-//       Access: Private
-//  Description: Builds the linear list of TextureStages if it needs
-//               to be built.
+//     Function: TexMatrixAttrib::StageNode::Constructor
+//       Access: Public
+//  Description: 
 ////////////////////////////////////////////////////////////////////
-INLINE void TexMatrixAttrib::
-check_stage_list() const {
-  if (_stage_list_stale) {
-    ((TexMatrixAttrib *)this)->rebuild_stage_list();
+INLINE TexMatrixAttrib::StageNode::
+StageNode(const TextureStage *stage) :
+  // Yeah, we cast away the constness here.  Just too much trouble to
+  // deal with it properly.
+  _stage((TextureStage *)stage),
+  _override(0)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::StageNode::operator <
+//       Access: Public
+//  Description: Compares the full attributes of StageNodes (as
+//               opposed to just the pointer compared by
+//               CompareTextureStagePointer, below).
+////////////////////////////////////////////////////////////////////
+INLINE bool TexMatrixAttrib::StageNode::
+operator < (const TexMatrixAttrib::StageNode &other) const {
+  if (_stage != other._stage) {
+    return _stage < other._stage;
+  }
+  if (_transform != other._transform) {
+    return _transform < other._transform;
   }
+  return _override < other._override;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::CompareTextureStagePointer::operator ()
+//       Access: Public
+//  Description: This STL function object is used to sort a list of
+//               texture stages in order by pointer.
+////////////////////////////////////////////////////////////////////
+INLINE bool TexMatrixAttrib::CompareTextureStagePointer::
+operator () (const TexMatrixAttrib::StageNode &a, 
+             const TexMatrixAttrib::StageNode &b) const {
+  return a._stage < b._stage;
 }

+ 101 - 76
panda/src/pgraph/texMatrixAttrib.cxx

@@ -19,6 +19,7 @@
 #include "bamWriter.h"
 #include "datagram.h"
 #include "datagramIterator.h"
+#include "textureStagePool.h"
 
 CPT(RenderAttrib) TexMatrixAttrib::_empty_attrib;
 TypeHandle TexMatrixAttrib::_type_handle;
@@ -76,12 +77,7 @@ make(const LMatrix4f &mat) {
 ////////////////////////////////////////////////////////////////////
 CPT(RenderAttrib) TexMatrixAttrib::
 make(TextureStage *stage, const TransformState *transform) {
-  if (transform->is_identity()) {
-    return make();
-  }
-  TexMatrixAttrib *attrib = new TexMatrixAttrib;
-  attrib->_stages.insert(Stages::value_type(stage, transform));
-  return return_new(attrib);
+  return DCAST(TexMatrixAttrib, make())->add_stage(stage, transform);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -104,12 +100,13 @@ make_default() {
 //               this stage already exists, its transform is replaced.
 ////////////////////////////////////////////////////////////////////
 CPT(RenderAttrib) TexMatrixAttrib::
-add_stage(TextureStage *stage, const TransformState *transform) const {
-  if (transform->is_identity()) {
-    return remove_stage(stage);
-  }
+add_stage(TextureStage *stage, const TransformState *transform,
+          int override) const {
   TexMatrixAttrib *attrib = new TexMatrixAttrib(*this);
-  attrib->_stages[stage] = transform;
+  Stages::iterator si = attrib->_stages.insert(StageNode(stage)).first;
+  (*si)._transform = transform;
+  (*si)._override = override;
+
   return return_new(attrib);
 }
 
@@ -122,7 +119,7 @@ add_stage(TextureStage *stage, const TransformState *transform) const {
 CPT(RenderAttrib) TexMatrixAttrib::
 remove_stage(TextureStage *stage) const {
   TexMatrixAttrib *attrib = new TexMatrixAttrib(*this);
-  attrib->_stages.erase(stage);
+  attrib->_stages.erase(StageNode(stage));
   return return_new(attrib);
 }
 
@@ -158,7 +155,7 @@ is_empty() const {
 ////////////////////////////////////////////////////////////////////
 bool TexMatrixAttrib::
 has_stage(TextureStage *stage) const {
-  Stages::const_iterator mi = _stages.find(stage);
+  Stages::const_iterator mi = _stages.find(StageNode(stage));
   return (mi != _stages.end());
 }
 
@@ -183,38 +180,33 @@ get_num_stages() const {
 TextureStage *TexMatrixAttrib::
 get_stage(int n) const {
   nassertr(n >= 0 && n < (int)_stages.size(), NULL);
-  check_stage_list();
-  return _stage_list[n];
+  return _stages[n]._stage;
 }
 
 ////////////////////////////////////////////////////////////////////
 //     Function: TexMatrixAttrib::get_mat
 //       Access: Published
 //  Description: Returns the transformation matrix associated with
-//               the named texture stage, or identity matrix if
+//               the indicated texture stage, or identity matrix if
 //               nothing is associated with the indicated stage.
 ////////////////////////////////////////////////////////////////////
 const LMatrix4f &TexMatrixAttrib::
 get_mat(TextureStage *stage) const {
-  Stages::const_iterator mi = _stages.find(stage);
-  if (mi != _stages.end()) {
-    return (*mi).second->get_mat();
-  }
-  return LMatrix4f::ident_mat();
+  return get_transform(stage)->get_mat();
 }
 
 ////////////////////////////////////////////////////////////////////
 //     Function: TexMatrixAttrib::get_transform
 //       Access: Published
 //  Description: Returns the transformation associated with
-//               the named texture stage, or identity matrix if
+//               the indicated texture stage, or identity matrix if
 //               nothing is associated with the indicated stage.
 ////////////////////////////////////////////////////////////////////
 CPT(TransformState) TexMatrixAttrib::
 get_transform(TextureStage *stage) const {
-  Stages::const_iterator mi = _stages.find(stage);
+  Stages::const_iterator mi = _stages.find(StageNode(stage));
   if (mi != _stages.end()) {
-    return (*mi).second;
+    return (*mi)._transform;
   }
   return TransformState::make_identity();
 }
@@ -230,9 +222,11 @@ output(ostream &out) const {
 
   Stages::const_iterator mi;
   for (mi = _stages.begin(); mi != _stages.end(); ++mi) {
-    TextureStage *stage = (*mi).first;
-    const TransformState *transform = (*mi).second;
-    out << " " << stage->get_name() << "(" << *transform << ")";
+    const StageNode &sn = (*mi);
+    out << " " << sn._stage->get_name() << "(" << *sn._transform << ")";
+    if (sn._override != 0) {
+      out << "^" << sn._override;
+    }
   }
 }
 
@@ -260,19 +254,16 @@ compare_to_impl(const RenderAttrib *other) const {
   ai = _stages.begin();
   bi = ta->_stages.begin();
   while (ai != _stages.end() && bi != ta->_stages.end()) {
-    if ((*ai).first < (*bi).first) {
+    if ((*ai) < (*bi)) {
       // This stage is in a but not in b.
       return -1;
 
-    } else if ((*bi).first < (*ai).first) {
+    } else if ((*bi) < (*ai)) {
       // This stage is in b but not in a.
       return 1;
 
     } else {
-      // This stage is in both; compare the stages.
-      if ((*ai).second != (*bi).second) {
-        return (*ai).second < (*bi).second ? -1 : 1;
-      }
+      // This stage is in both.
       ++ai;
       ++bi;
     }
@@ -322,20 +313,33 @@ compose_impl(const RenderAttrib *other) const {
   ai = _stages.begin();
   bi = ta->_stages.begin();
   while (ai != _stages.end() && bi != ta->_stages.end()) {
-    if ((*ai).first < (*bi).first) {
+    if ((*ai)._stage < (*bi)._stage) {
       // This stage is in a but not in b.
       attrib->_stages.insert(attrib->_stages.end(), *ai);
       ++ai;
 
-    } else if ((*bi).first < (*ai).first) {
+    } else if ((*bi)._stage < (*ai)._stage) {
       // This stage is in b but not in a.
       attrib->_stages.insert(attrib->_stages.end(), *bi);
       ++bi;
 
     } else {
-      // This stage is in both; compose the stages.
-      CPT(TransformState) new_transform = (*ai).second->compose((*bi).second);
-      attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, new_transform));
+      // This stage is in both.
+      if ((*ai)._override == (*bi)._override) {
+        // Same override; compose them.
+        CPT(TransformState) new_transform = (*ai)._transform->compose((*bi)._transform);
+        StageNode sn((*ai)._stage);
+        sn._transform = new_transform;
+        sn._override = (*ai)._override;
+        attrib->_stages.insert(attrib->_stages.end(), sn);
+      } else if ((*ai)._override < (*bi)._override) {
+        // Override b wins.
+        attrib->_stages.insert(attrib->_stages.end(), *bi);
+      } else {
+        // Override a wins.
+        attrib->_stages.insert(attrib->_stages.end(), *ai);
+      }
+
       ++ai;
       ++bi;
     }
@@ -379,23 +383,45 @@ invert_compose_impl(const RenderAttrib *other) const {
   ai = _stages.begin();
   bi = ta->_stages.begin();
   while (ai != _stages.end() && bi != ta->_stages.end()) {
-    if ((*ai).first < (*bi).first) {
+    if ((*ai)._stage < (*bi)._stage) {
       // This stage is in a but not in b.
       CPT(TransformState) inv_a = 
-        (*ai).second->invert_compose(TransformState::make_identity());
-      attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, inv_a));
+        (*ai)._transform->invert_compose(TransformState::make_identity());
+      StageNode sn((*ai)._stage);
+      sn._transform = inv_a;
+      sn._override = (*ai)._override;
+      attrib->_stages.insert(attrib->_stages.end(), sn);
       ++ai;
 
-    } else if ((*bi).first < (*ai).first) {
+    } else if ((*bi)._stage < (*ai)._stage) {
       // This stage is in b but not in a.
       attrib->_stages.insert(attrib->_stages.end(), *bi);
       ++bi;
 
     } else {
-      // This stage is in both; compose the stages.
-      CPT(TransformState) new_transform = 
-        (*ai).second->invert_compose((*bi).second);
-      attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, new_transform));
+      // This stage is in both.
+      if ((*ai)._override == (*bi)._override) {
+        // Same override; compose them.
+        CPT(TransformState) new_transform = (*ai)._transform->invert_compose((*bi)._transform);
+        StageNode sn((*ai)._stage);
+        sn._transform = new_transform;
+        sn._override = (*ai)._override;
+        attrib->_stages.insert(attrib->_stages.end(), sn);
+
+      } else if ((*ai)._override < (*bi)._override) {
+        // Override b wins.
+        attrib->_stages.insert(attrib->_stages.end(), *bi);
+
+      } else {
+        // Override a wins.
+        CPT(TransformState) inv_a = 
+          (*ai)._transform->invert_compose(TransformState::make_identity());
+        StageNode sn((*ai)._stage);
+        sn._transform = inv_a;
+        sn._override = (*ai)._override;
+        attrib->_stages.insert(attrib->_stages.end(), sn);
+      }
+
       ++ai;
       ++bi;
     }
@@ -404,8 +430,11 @@ invert_compose_impl(const RenderAttrib *other) const {
   while (ai != _stages.end()) {
     // This stage is in a but not in b.
     CPT(TransformState) inv_a = 
-      (*ai).second->invert_compose(TransformState::make_identity());
-    attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, inv_a));
+      (*ai)._transform->invert_compose(TransformState::make_identity());
+    StageNode sn((*ai)._stage);
+    sn._transform = inv_a;
+    sn._override = (*ai)._override;
+    attrib->_stages.insert(attrib->_stages.end(), sn);
     ++ai;
   }
 
@@ -418,25 +447,6 @@ invert_compose_impl(const RenderAttrib *other) const {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: TexMatrixAttrib::rebuild_stage_list
-//       Access: Private
-//  Description: Builds the linear list of TextureStages, the first
-//               time someone asks for it.
-////////////////////////////////////////////////////////////////////
-void TexMatrixAttrib::
-rebuild_stage_list() {
-  _stage_list.clear();
-  _stage_list.reserve(_stages.size());
-
-  Stages::const_iterator si;
-  for (si = _stages.begin(); si != _stages.end(); ++si) {
-    _stage_list.push_back((*si).first);
-  }
-
-  _stage_list_stale = false;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TexMatrixAttrib::register_with_read_factory
 //       Access: Public, Static
@@ -462,11 +472,11 @@ write_datagram(BamWriter *manager, Datagram &dg) {
 
   Stages::const_iterator si;
   for (si = _stages.begin(); si != _stages.end(); ++si) {
-    TextureStage *stage = (*si).first;
-    const TransformState *transform = (*si).second;
+    const StageNode &sn = (*si);
 
-    manager->write_pointer(dg, stage);
-    manager->write_pointer(dg, transform);
+    manager->write_pointer(dg, sn._stage);
+    manager->write_pointer(dg, sn._transform);
+    dg.add_int32(sn._override);
   }
 }
 
@@ -481,11 +491,18 @@ int TexMatrixAttrib::
 complete_pointers(TypedWritable **p_list, BamReader *manager) {
   int pi = RenderAttrib::complete_pointers(p_list, manager);
 
-  for (size_t i = 0; i < _num_stages; i++) {
-    TextureStage *stage = DCAST(TextureStage, p_list[pi++]);
+  for (size_t sni = 0; sni < _stages.size(); ++sni) {
+    // Filter the TextureStage through the TextureStagePool.
+    PT(TextureStage) ts = DCAST(TextureStage, p_list[pi++]);
+    ts = TextureStagePool::get_stage(ts);
+
     const TransformState *transform = DCAST(TransformState, p_list[pi++]);
-    _stages[stage] = transform;
+    
+    StageNode &sn = _stages[sni];
+    sn._stage = ts;
+    sn._transform = transform;
   }
+  _stages.sort();
 
   return pi;
 }
@@ -521,9 +538,17 @@ void TexMatrixAttrib::
 fillin(DatagramIterator &scan, BamReader *manager) {
   RenderAttrib::fillin(scan, manager);
 
-  _num_stages = scan.get_uint16();
-  for (size_t i = 0; i < _num_stages; i++) {
+  size_t num_stages = scan.get_uint16();
+  for (size_t i = 0; i < num_stages; i++) {
     manager->read_pointer(scan);
     manager->read_pointer(scan);
+    int override = 0;
+    if (manager->get_file_minor_ver() >= 24) {
+      override = scan.get_int32();
+    }
+
+    StageNode sn(NULL);
+    sn._override = override;
+    _stages.push_back(sn);
   }
 }

+ 19 - 9
panda/src/pgraph/texMatrixAttrib.h

@@ -44,7 +44,7 @@ PUBLISHED:
   static CPT(RenderAttrib) make(TextureStage *stage, const TransformState *transform);
   static CPT(RenderAttrib) make_default();
 
-  CPT(RenderAttrib) add_stage(TextureStage *stage, const TransformState *transform) const;
+  CPT(RenderAttrib) add_stage(TextureStage *stage, const TransformState *transform, int override = 0) const;
   CPT(RenderAttrib) remove_stage(TextureStage *stage) const;
 
   bool is_empty() const;
@@ -58,6 +58,7 @@ PUBLISHED:
   const LMatrix4f &get_mat(TextureStage *stage) const;
 
   CPT(TransformState) get_transform(TextureStage *stage) const;
+  INLINE int get_override(TextureStage *stage) const;
 
   INLINE int get_geom_rendering(int geom_rendering) const;
 
@@ -73,16 +74,25 @@ private:
   INLINE void check_stage_list() const;
   void rebuild_stage_list();
 
-  typedef pmap< PT(TextureStage), CPT(TransformState) > Stages;
-  Stages _stages;
+private:
+  class StageNode {
+  public:
+    INLINE StageNode(const TextureStage *stage);
+
+    INLINE bool operator < (const StageNode &other) const;
 
-  typedef pvector<TextureStage *> StageList;
-  StageList _stage_list;
-  bool _stage_list_stale;
+    PT(TextureStage) _stage;
+    CPT(TransformState) _transform;
+    int _override;
+  };
 
-  // This element is only used during reading from a bam file.  It has
-  // no meaningful value any other time.
-  size_t _num_stages;
+  class CompareTextureStagePointer {
+  public:
+    INLINE bool operator () (const TexMatrixAttrib::StageNode &a, const TexMatrixAttrib::StageNode &b) const;
+  };
+
+  typedef ov_set<StageNode, CompareTextureStagePointer> Stages;
+  Stages _stages;
 
   static CPT(RenderAttrib) _empty_attrib;
 

+ 17 - 0
panda/src/pgraph/textureAttrib.I

@@ -175,6 +175,23 @@ get_on_texture(TextureStage *stage) const {
   return NULL;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TextureAttrib::get_on_stage_override
+//       Access: Published
+//  Description: Returns the override value associated with the
+//               indicated stage.
+////////////////////////////////////////////////////////////////////
+INLINE int TextureAttrib::
+get_on_stage_override(TextureStage *stage) const {
+  Stages::const_iterator si;
+  si = _on_stages.find(StageNode(stage));
+  if (si != _on_stages.end()) {
+    return (*si)._override;
+  }
+  nassert_raise("Specified TextureStage not included in attrib");
+  return 0;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureAttrib::get_num_off_stages
 //       Access: Published

+ 1 - 0
panda/src/pgraph/textureAttrib.cxx

@@ -773,6 +773,7 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
       _on_stages.erase(_on_stages.begin() + sni);
     }
   }
+  _on_stages.sort();
   _sort_seq = UpdateSeq::old();
   _filtered_seq = UpdateSeq::old();
 

+ 1 - 0
panda/src/pgraph/textureAttrib.h

@@ -61,6 +61,7 @@ PUBLISHED:
   INLINE int get_ff_tc_index(int n) const;
   INLINE bool has_on_stage(TextureStage *stage) const;
   INLINE Texture *get_on_texture(TextureStage *stage) const;
+  INLINE int get_on_stage_override(TextureStage *stage) const;
 
   int find_on_stage(const TextureStage *stage) const;
 

+ 2 - 1
panda/src/putil/bam.h

@@ -33,7 +33,7 @@ static const unsigned short _bam_major_ver = 6;
 // Bumped to major version 6 on 2/11/06 to factor out PandaNode::CData.
 
 static const unsigned short _bam_first_minor_ver = 14;
-static const unsigned short _bam_minor_ver = 23;
+static const unsigned short _bam_minor_ver = 24;
 // Bumped to minor version 14 on 12/19/07 to change default ColorAttrib.
 // Bumped to minor version 15 on 4/9/08 to add TextureAttrib::_implicit_sort.
 // Bumped to minor version 16 on 5/13/08 to add Texture::_quality_level.
@@ -44,6 +44,7 @@ static const unsigned short _bam_minor_ver = 23;
 // Bumped to minor version 21 on 2/26/08 to add BamEnums::BamObjectCode.
 // Bumped to minor version 22 on 7/31/09 to add UvScrollNode R speed.
 // Bumped to minor version 23 on 5/4/10 to add internal TextureAttrib overrides.
+// Bumped to minor version 24 on 5/4/10 to add internal TexMatrixAttrib overrides.
 
 
 #endif