From 91e6231a3c948d3e011512bc81ed778f054a2f54 Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 6 May 2010 01:12:34 +0000 Subject: [PATCH] apply per-attrib override to TexMatrixAttrib also --- direct/src/interval/cLerpNodePathInterval.cxx | 10 +- panda/src/pgraph/texMatrixAttrib.I | 71 +++++-- panda/src/pgraph/texMatrixAttrib.cxx | 177 ++++++++++-------- panda/src/pgraph/texMatrixAttrib.h | 30 ++- panda/src/pgraph/textureAttrib.I | 17 ++ panda/src/pgraph/textureAttrib.cxx | 1 + panda/src/pgraph/textureAttrib.h | 1 + panda/src/putil/bam.h | 3 +- 8 files changed, 205 insertions(+), 105 deletions(-) diff --git a/direct/src/interval/cLerpNodePathInterval.cxx b/direct/src/interval/cLerpNodePathInterval.cxx index 3cd294f663..de70486cba 100644 --- a/direct/src/interval/cLerpNodePathInterval.cxx +++ b/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)); } diff --git a/panda/src/pgraph/texMatrixAttrib.I b/panda/src/pgraph/texMatrixAttrib.I index d469a88b69..ffb18df5f4 100644 --- a/panda/src/pgraph/texMatrixAttrib.I +++ b/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 ©) : - _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; } diff --git a/panda/src/pgraph/texMatrixAttrib.cxx b/panda/src/pgraph/texMatrixAttrib.cxx index 6a2809a8a8..8b74ce1766 100644 --- a/panda/src/pgraph/texMatrixAttrib.cxx +++ b/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); } } diff --git a/panda/src/pgraph/texMatrixAttrib.h b/panda/src/pgraph/texMatrixAttrib.h index 9a3cc4df6d..662f51f97d 100644 --- a/panda/src/pgraph/texMatrixAttrib.h +++ b/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,17 +74,26 @@ private: INLINE void check_stage_list() const; void rebuild_stage_list(); - typedef pmap< PT(TextureStage), CPT(TransformState) > Stages; +private: + class StageNode { + public: + INLINE StageNode(const TextureStage *stage); + + INLINE bool operator < (const StageNode &other) const; + + PT(TextureStage) _stage; + CPT(TransformState) _transform; + int _override; + }; + + class CompareTextureStagePointer { + public: + INLINE bool operator () (const TexMatrixAttrib::StageNode &a, const TexMatrixAttrib::StageNode &b) const; + }; + + typedef ov_set Stages; Stages _stages; - typedef pvector StageList; - StageList _stage_list; - bool _stage_list_stale; - - // This element is only used during reading from a bam file. It has - // no meaningful value any other time. - size_t _num_stages; - static CPT(RenderAttrib) _empty_attrib; PUBLISHED: diff --git a/panda/src/pgraph/textureAttrib.I b/panda/src/pgraph/textureAttrib.I index 97a294d5d5..8ec117ab0f 100644 --- a/panda/src/pgraph/textureAttrib.I +++ b/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 diff --git a/panda/src/pgraph/textureAttrib.cxx b/panda/src/pgraph/textureAttrib.cxx index 47634b7a9e..8cfc4c21ee 100644 --- a/panda/src/pgraph/textureAttrib.cxx +++ b/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(); diff --git a/panda/src/pgraph/textureAttrib.h b/panda/src/pgraph/textureAttrib.h index 5daa1b3382..123a3584bb 100644 --- a/panda/src/pgraph/textureAttrib.h +++ b/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; diff --git a/panda/src/putil/bam.h b/panda/src/putil/bam.h index c43324fb57..e903515df8 100644 --- a/panda/src/putil/bam.h +++ b/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