|
@@ -19,6 +19,7 @@
|
|
|
#include "bamWriter.h"
|
|
#include "bamWriter.h"
|
|
|
#include "datagram.h"
|
|
#include "datagram.h"
|
|
|
#include "datagramIterator.h"
|
|
#include "datagramIterator.h"
|
|
|
|
|
+#include "textureStagePool.h"
|
|
|
|
|
|
|
|
CPT(RenderAttrib) TexMatrixAttrib::_empty_attrib;
|
|
CPT(RenderAttrib) TexMatrixAttrib::_empty_attrib;
|
|
|
TypeHandle TexMatrixAttrib::_type_handle;
|
|
TypeHandle TexMatrixAttrib::_type_handle;
|
|
@@ -76,12 +77,7 @@ make(const LMatrix4f &mat) {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
CPT(RenderAttrib) TexMatrixAttrib::
|
|
CPT(RenderAttrib) TexMatrixAttrib::
|
|
|
make(TextureStage *stage, const TransformState *transform) {
|
|
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.
|
|
// this stage already exists, its transform is replaced.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
CPT(RenderAttrib) TexMatrixAttrib::
|
|
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);
|
|
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);
|
|
return return_new(attrib);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -122,7 +119,7 @@ add_stage(TextureStage *stage, const TransformState *transform) const {
|
|
|
CPT(RenderAttrib) TexMatrixAttrib::
|
|
CPT(RenderAttrib) TexMatrixAttrib::
|
|
|
remove_stage(TextureStage *stage) const {
|
|
remove_stage(TextureStage *stage) const {
|
|
|
TexMatrixAttrib *attrib = new TexMatrixAttrib(*this);
|
|
TexMatrixAttrib *attrib = new TexMatrixAttrib(*this);
|
|
|
- attrib->_stages.erase(stage);
|
|
|
|
|
|
|
+ attrib->_stages.erase(StageNode(stage));
|
|
|
return return_new(attrib);
|
|
return return_new(attrib);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -158,7 +155,7 @@ is_empty() const {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
bool TexMatrixAttrib::
|
|
bool TexMatrixAttrib::
|
|
|
has_stage(TextureStage *stage) const {
|
|
has_stage(TextureStage *stage) const {
|
|
|
- Stages::const_iterator mi = _stages.find(stage);
|
|
|
|
|
|
|
+ Stages::const_iterator mi = _stages.find(StageNode(stage));
|
|
|
return (mi != _stages.end());
|
|
return (mi != _stages.end());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -183,38 +180,33 @@ get_num_stages() const {
|
|
|
TextureStage *TexMatrixAttrib::
|
|
TextureStage *TexMatrixAttrib::
|
|
|
get_stage(int n) const {
|
|
get_stage(int n) const {
|
|
|
nassertr(n >= 0 && n < (int)_stages.size(), NULL);
|
|
nassertr(n >= 0 && n < (int)_stages.size(), NULL);
|
|
|
- check_stage_list();
|
|
|
|
|
- return _stage_list[n];
|
|
|
|
|
|
|
+ return _stages[n]._stage;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: TexMatrixAttrib::get_mat
|
|
// Function: TexMatrixAttrib::get_mat
|
|
|
// Access: Published
|
|
// Access: Published
|
|
|
// Description: Returns the transformation matrix associated with
|
|
// 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.
|
|
// nothing is associated with the indicated stage.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
const LMatrix4f &TexMatrixAttrib::
|
|
const LMatrix4f &TexMatrixAttrib::
|
|
|
get_mat(TextureStage *stage) const {
|
|
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
|
|
// Function: TexMatrixAttrib::get_transform
|
|
|
// Access: Published
|
|
// Access: Published
|
|
|
// Description: Returns the transformation associated with
|
|
// 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.
|
|
// nothing is associated with the indicated stage.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
CPT(TransformState) TexMatrixAttrib::
|
|
CPT(TransformState) TexMatrixAttrib::
|
|
|
get_transform(TextureStage *stage) const {
|
|
get_transform(TextureStage *stage) const {
|
|
|
- Stages::const_iterator mi = _stages.find(stage);
|
|
|
|
|
|
|
+ Stages::const_iterator mi = _stages.find(StageNode(stage));
|
|
|
if (mi != _stages.end()) {
|
|
if (mi != _stages.end()) {
|
|
|
- return (*mi).second;
|
|
|
|
|
|
|
+ return (*mi)._transform;
|
|
|
}
|
|
}
|
|
|
return TransformState::make_identity();
|
|
return TransformState::make_identity();
|
|
|
}
|
|
}
|
|
@@ -230,9 +222,11 @@ output(ostream &out) const {
|
|
|
|
|
|
|
|
Stages::const_iterator mi;
|
|
Stages::const_iterator mi;
|
|
|
for (mi = _stages.begin(); mi != _stages.end(); ++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();
|
|
ai = _stages.begin();
|
|
|
bi = ta->_stages.begin();
|
|
bi = ta->_stages.begin();
|
|
|
while (ai != _stages.end() && bi != ta->_stages.end()) {
|
|
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.
|
|
// This stage is in a but not in b.
|
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
|
|
- } else if ((*bi).first < (*ai).first) {
|
|
|
|
|
|
|
+ } else if ((*bi) < (*ai)) {
|
|
|
// This stage is in b but not in a.
|
|
// This stage is in b but not in a.
|
|
|
return 1;
|
|
return 1;
|
|
|
|
|
|
|
|
} else {
|
|
} 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;
|
|
++ai;
|
|
|
++bi;
|
|
++bi;
|
|
|
}
|
|
}
|
|
@@ -322,20 +313,33 @@ compose_impl(const RenderAttrib *other) const {
|
|
|
ai = _stages.begin();
|
|
ai = _stages.begin();
|
|
|
bi = ta->_stages.begin();
|
|
bi = ta->_stages.begin();
|
|
|
while (ai != _stages.end() && bi != ta->_stages.end()) {
|
|
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.
|
|
// This stage is in a but not in b.
|
|
|
attrib->_stages.insert(attrib->_stages.end(), *ai);
|
|
attrib->_stages.insert(attrib->_stages.end(), *ai);
|
|
|
++ai;
|
|
++ai;
|
|
|
|
|
|
|
|
- } else if ((*bi).first < (*ai).first) {
|
|
|
|
|
|
|
+ } else if ((*bi)._stage < (*ai)._stage) {
|
|
|
// This stage is in b but not in a.
|
|
// This stage is in b but not in a.
|
|
|
attrib->_stages.insert(attrib->_stages.end(), *bi);
|
|
attrib->_stages.insert(attrib->_stages.end(), *bi);
|
|
|
++bi;
|
|
++bi;
|
|
|
|
|
|
|
|
} else {
|
|
} 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;
|
|
++ai;
|
|
|
++bi;
|
|
++bi;
|
|
|
}
|
|
}
|
|
@@ -379,23 +383,45 @@ invert_compose_impl(const RenderAttrib *other) const {
|
|
|
ai = _stages.begin();
|
|
ai = _stages.begin();
|
|
|
bi = ta->_stages.begin();
|
|
bi = ta->_stages.begin();
|
|
|
while (ai != _stages.end() && bi != ta->_stages.end()) {
|
|
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.
|
|
// This stage is in a but not in b.
|
|
|
CPT(TransformState) inv_a =
|
|
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;
|
|
++ai;
|
|
|
|
|
|
|
|
- } else if ((*bi).first < (*ai).first) {
|
|
|
|
|
|
|
+ } else if ((*bi)._stage < (*ai)._stage) {
|
|
|
// This stage is in b but not in a.
|
|
// This stage is in b but not in a.
|
|
|
attrib->_stages.insert(attrib->_stages.end(), *bi);
|
|
attrib->_stages.insert(attrib->_stages.end(), *bi);
|
|
|
++bi;
|
|
++bi;
|
|
|
|
|
|
|
|
} else {
|
|
} 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;
|
|
++ai;
|
|
|
++bi;
|
|
++bi;
|
|
|
}
|
|
}
|
|
@@ -404,8 +430,11 @@ invert_compose_impl(const RenderAttrib *other) const {
|
|
|
while (ai != _stages.end()) {
|
|
while (ai != _stages.end()) {
|
|
|
// This stage is in a but not in b.
|
|
// This stage is in a but not in b.
|
|
|
CPT(TransformState) inv_a =
|
|
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;
|
|
++ai;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -418,25 +447,6 @@ invert_compose_impl(const RenderAttrib *other) const {
|
|
|
return return_new(attrib);
|
|
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
|
|
// Function: TexMatrixAttrib::register_with_read_factory
|
|
|
// Access: Public, Static
|
|
// Access: Public, Static
|
|
@@ -462,11 +472,11 @@ write_datagram(BamWriter *manager, Datagram &dg) {
|
|
|
|
|
|
|
|
Stages::const_iterator si;
|
|
Stages::const_iterator si;
|
|
|
for (si = _stages.begin(); si != _stages.end(); ++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) {
|
|
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
|
|
int pi = RenderAttrib::complete_pointers(p_list, 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++]);
|
|
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;
|
|
return pi;
|
|
|
}
|
|
}
|
|
@@ -521,9 +538,17 @@ void TexMatrixAttrib::
|
|
|
fillin(DatagramIterator &scan, BamReader *manager) {
|
|
fillin(DatagramIterator &scan, BamReader *manager) {
|
|
|
RenderAttrib::fillin(scan, 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);
|
|
|
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);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|