| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- // Filename: texGenAttrib.cxx
- // Created by: masad (21Jun04)
- //
- ////////////////////////////////////////////////////////////////////
- //
- // PANDA 3D SOFTWARE
- // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
- //
- // All use of this software is subject to the terms of the Panda 3d
- // Software license. You should have received a copy of this license
- // along with this source code; you will also find a current copy of
- // the license at http://etc.cmu.edu/panda3d/docs/license/ .
- //
- // To contact the maintainers of this program write to
- // [email protected] .
- //
- ////////////////////////////////////////////////////////////////////
- #include "texGenAttrib.h"
- #include "texturePool.h"
- #include "graphicsStateGuardianBase.h"
- #include "bamReader.h"
- #include "bamWriter.h"
- #include "datagram.h"
- #include "datagramIterator.h"
- CPT(RenderAttrib) TexGenAttrib::_empty_attrib;
- TypeHandle TexGenAttrib::_type_handle;
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::Destructor
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- TexGenAttrib::
- ~TexGenAttrib() {
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::make
- // Access: Published, Static
- // Description: Constructs a TexGenAttrib that generates no stages at
- // all.
- ////////////////////////////////////////////////////////////////////
- CPT(RenderAttrib) TexGenAttrib::
- make() {
- // We make it a special case and store a pointer to the empty attrib
- // forever once we find it the first time, as an optimization.
- if (_empty_attrib == (RenderAttrib *)NULL) {
- _empty_attrib = return_new(new TexGenAttrib);
- }
- return _empty_attrib;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::add_stage
- // Access: Published, Static
- // Description: Returns a new TexGenAttrib just like this one,
- // with the indicated generation mode for the given
- // stage. If this stage already exists, its mode is
- // replaced.
- ////////////////////////////////////////////////////////////////////
- CPT(RenderAttrib) TexGenAttrib::
- add_stage(TextureStage *stage, TexGenAttrib::Mode mode) const {
- TexGenAttrib *attrib = new TexGenAttrib(*this);
- attrib->_stages[stage] = mode;
- if (mode != M_off) {
- attrib->_no_texcoords.insert(stage);
- }
- return return_new(attrib);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::remove_stage
- // Access: Published, Static
- // Description: Returns a new TexGenAttrib just like this one,
- // with the indicated stage removed.
- ////////////////////////////////////////////////////////////////////
- CPT(RenderAttrib) TexGenAttrib::
- remove_stage(TextureStage *stage) const {
- TexGenAttrib *attrib = new TexGenAttrib(*this);
- attrib->_stages.erase(stage);
- attrib->_no_texcoords.erase(stage);
- return return_new(attrib);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::is_empty
- // Access: Published
- // Description: Returns true if no stages are defined in the
- // TexGenAttrib, false if at least one is.
- ////////////////////////////////////////////////////////////////////
- bool TexGenAttrib::
- is_empty() const {
- return _stages.empty();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::has_stage
- // Access: Published
- // Description: Returns true if there is a mode associated with
- // the indicated stage, or false otherwise (in which
- // case get_transform(stage) will return M_off).
- ////////////////////////////////////////////////////////////////////
- bool TexGenAttrib::
- has_stage(TextureStage *stage) const {
- Stages::const_iterator mi = _stages.find(stage);
- return (mi != _stages.end());
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::get_mode
- // Access: Published
- // Description: Returns the generation mode associated with
- // the named texture stage, or M_off if
- // nothing is associated with the indicated stage.
- ////////////////////////////////////////////////////////////////////
- TexGenAttrib::Mode TexGenAttrib::
- get_mode(TextureStage *stage) const {
- Stages::const_iterator mi = _stages.find(stage);
- if (mi != _stages.end()) {
- return (*mi).second;
- }
- return M_off;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::issue
- // Access: Public, Virtual
- // Description: Calls the appropriate method on the indicated GSG
- // to issue the graphics commands appropriate to the
- // given attribute. This is normally called
- // (indirectly) only from
- // GraphicsStateGuardian::set_state() or modify_state().
- ////////////////////////////////////////////////////////////////////
- void TexGenAttrib::
- issue(GraphicsStateGuardianBase *gsg) const {
- gsg->issue_tex_gen(this);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::output
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- void TexGenAttrib::
- output(ostream &out) const {
- out << get_type() << ":";
- Stages::const_iterator mi;
- for (mi = _stages.begin(); mi != _stages.end(); ++mi) {
- TextureStage *stage = (*mi).first;
- Mode mode = (*mi).second;
- out << " " << stage->get_name() << "(";
- switch (mode) {
- case M_off:
- out << "off";
- break;
- case M_sphere_map:
- out << "sphere_map";
- break;
- case M_cube_map:
- out << "cube_map";
- break;
- case M_world_position:
- out << "world_position";
- break;
- case M_object_position:
- out << "object_position";
- break;
- case M_eye_position:
- out << "eye_position";
- break;
- }
- out << ")";
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::compare_to_impl
- // Access: Protected, Virtual
- // Description: Intended to be overridden by derived TexGenAttrib
- // types to return a unique number indicating whether
- // this TexGenAttrib is equivalent to the other one.
- //
- // This should return 0 if the two TexGenAttrib objects
- // are equivalent, a number less than zero if this one
- // should be sorted before the other one, and a number
- // greater than zero otherwise.
- //
- // This will only be called with two TexGenAttrib
- // objects whose get_type() functions return the same.
- ////////////////////////////////////////////////////////////////////
- int TexGenAttrib::
- compare_to_impl(const RenderAttrib *other) const {
- const TexGenAttrib *ta;
- DCAST_INTO_R(ta, other, 0);
-
- Stages::const_iterator ai, bi;
- ai = _stages.begin();
- bi = ta->_stages.begin();
- while (ai != _stages.end() && bi != ta->_stages.end()) {
- if ((*ai).first < (*bi).first) {
- // This stage is in a but not in b.
- return -1;
- } else if ((*bi).first < (*ai).first) {
- // 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 (int)(*ai).second < (int)(*bi).second ? -1 : 1;
- }
- ++ai;
- ++bi;
- }
- }
- if (bi != _stages.end()) {
- // a ran out first; b was longer.
- return -1;
- }
- if (ai != _stages.end()) {
- // b ran out first; a was longer.
- return 1;
- }
- return 0;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::compose_impl
- // Access: Protected, Virtual
- // Description: Intended to be overridden by derived RenderAttrib
- // types to specify how two consecutive RenderAttrib
- // objects of the same type interact.
- //
- // This should return the result of applying the other
- // RenderAttrib to a node in the scene graph below this
- // RenderAttrib, which was already applied. In most
- // cases, the result is the same as the other
- // RenderAttrib (that is, a subsequent RenderAttrib
- // completely replaces the preceding one). On the other
- // hand, some kinds of RenderAttrib (for instance,
- // ColorTransformAttrib) might combine in meaningful
- // ways.
- ////////////////////////////////////////////////////////////////////
- CPT(RenderAttrib) TexGenAttrib::
- compose_impl(const RenderAttrib *other) const {
- const TexGenAttrib *ta;
- DCAST_INTO_R(ta, other, 0);
- // The composition is the union of the two attribs. In the case
- // when a stage is in both attribs, we compose the stages.
- TexGenAttrib *attrib = new TexGenAttrib;
- Stages::const_iterator ai, bi;
- ai = _stages.begin();
- bi = ta->_stages.begin();
- while (ai != _stages.end() && bi != ta->_stages.end()) {
- if ((*ai).first < (*bi).first) {
- // This stage is in a but not in b.
- attrib->_stages.insert(attrib->_stages.end(), *ai);
- ++ai;
- } else if ((*bi).first < (*ai).first) {
- // This stage is in b but not in a.
- attrib->_stages.insert(attrib->_stages.end(), *bi);
- ++bi;
- } else {
- // This stage is in both; b wins.
- attrib->_stages.insert(attrib->_stages.end(), *bi);
- ++bi;
- ++ai;
- }
- }
- while (ai != _stages.end()) {
- // This stage is in a but not in b.
- attrib->_stages.insert(attrib->_stages.end(), *ai);
- ++ai;
- }
- while (bi != ta->_stages.end()) {
- // This stage is in b but not in a.
- attrib->_stages.insert(attrib->_stages.end(), *bi);
- ++bi;
- }
- // Now copy from _stages to _no_texcoords.
- Stages::const_iterator ri;
- for (ri = attrib->_stages.begin(); ri != attrib->_stages.end(); ++ri) {
- if ((*ri).second != M_off) {
- attrib->_no_texcoords.insert((*ri).first);
- }
- }
- return return_new(attrib);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::invert_compose_impl
- // Access: Protected, Virtual
- // Description: Intended to be overridden by derived RenderAttrib
- // types to specify how two consecutive RenderAttrib
- // objects of the same type interact.
- //
- // See invert_compose() and compose_impl().
- ////////////////////////////////////////////////////////////////////
- CPT(RenderAttrib) TexGenAttrib::
- invert_compose_impl(const RenderAttrib *other) const {
- const TexGenAttrib *ta;
- DCAST_INTO_R(ta, other, 0);
- // The inverse composition works a lot like the composition, except
- // we invert the ai stages.
- TexGenAttrib *attrib = new TexGenAttrib;
- Stages::const_iterator ai, bi;
- ai = _stages.begin();
- bi = ta->_stages.begin();
- while (ai != _stages.end() && bi != ta->_stages.end()) {
- if ((*ai).first < (*bi).first) {
- // This stage is in a but not in b. Turn a off.
- attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, M_off));
- ++ai;
- } else if ((*bi).first < (*ai).first) {
- // This stage is in b but not in a.
- attrib->_stages.insert(attrib->_stages.end(), *bi);
- ++bi;
- } else {
- // This stage is in both; b wins.
- attrib->_stages.insert(attrib->_stages.end(), *bi);
- ++bi;
- ++ai;
- }
- }
- while (ai != _stages.end()) {
- // This stage is in a but not in b.
- attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, M_off));
- ++ai;
- }
- while (bi != ta->_stages.end()) {
- // This stage is in b but not in a.
- attrib->_stages.insert(attrib->_stages.end(), *bi);
- ++bi;
- }
- // Now copy from _stages to _no_texcoords.
- Stages::const_iterator ri;
- for (ri = attrib->_stages.begin(); ri != attrib->_stages.end(); ++ri) {
- if ((*ri).second != M_off) {
- attrib->_no_texcoords.insert((*ri).first);
- }
- }
- return return_new(attrib);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::make_default_impl
- // Access: Protected, Virtual
- // Description: Intended to be overridden by derived TexGenAttrib
- // types to specify what the default property for a
- // TexGenAttrib of this type should be.
- //
- // This should return a newly-allocated TexGenAttrib of
- // the same type that corresponds to whatever the
- // standard default for this kind of TexGenAttrib is.
- ////////////////////////////////////////////////////////////////////
- RenderAttrib *TexGenAttrib::
- make_default_impl() const {
- return new TexGenAttrib;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::register_with_read_factory
- // Access: Public, Static
- // Description: Tells the BamReader how to create objects of type
- // TexGenAttrib.
- ////////////////////////////////////////////////////////////////////
- void TexGenAttrib::
- register_with_read_factory() {
- BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::write_datagram
- // Access: Public, Virtual
- // Description: Writes the contents of this object to the datagram
- // for shipping out to a Bam file.
- ////////////////////////////////////////////////////////////////////
- void TexGenAttrib::
- write_datagram(BamWriter *manager, Datagram &dg) {
- RenderAttrib::write_datagram(manager, dg);
- dg.add_uint16(_stages.size());
- Stages::const_iterator si;
- for (si = _stages.begin(); si != _stages.end(); ++si) {
- TextureStage *stage = (*si).first;
- Mode mode = (*si).second;
- manager->write_pointer(dg, stage);
- dg.add_uint8((unsigned int)mode);
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::complete_pointers
- // Access: Public, Virtual
- // Description: Receives an array of pointers, one for each time
- // manager->read_pointer() was called in fillin().
- // Returns the number of pointers processed.
- ////////////////////////////////////////////////////////////////////
- int TexGenAttrib::
- complete_pointers(TypedWritable **p_list, BamReader *manager) {
- int pi = RenderAttrib::complete_pointers(p_list, manager);
- pvector<Mode>::const_iterator mi;
- for (mi = _read_modes.begin(); mi != _read_modes.end(); ++mi) {
- Mode mode = (*mi);
- TextureStage *stage = DCAST(TextureStage, p_list[pi++]);
- _stages[stage] = mode;
- if (mode != M_off) {
- _no_texcoords.insert(stage);
- }
- }
- return pi;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::make_from_bam
- // Access: Protected, Static
- // Description: This function is called by the BamReader's factory
- // when a new object of type TexGenAttrib is encountered
- // in the Bam file. It should create the TexGenAttrib
- // and extract its information from the file.
- ////////////////////////////////////////////////////////////////////
- TypedWritable *TexGenAttrib::
- make_from_bam(const FactoryParams ¶ms) {
- TexGenAttrib *attrib = new TexGenAttrib;
- DatagramIterator scan;
- BamReader *manager;
- parse_params(params, scan, manager);
- attrib->fillin(scan, manager);
- return attrib;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TexGenAttrib::fillin
- // Access: Protected
- // Description: This internal function is called by make_from_bam to
- // read in all of the relevant data from the BamFile for
- // the new TexGenAttrib.
- ////////////////////////////////////////////////////////////////////
- void TexGenAttrib::
- fillin(DatagramIterator &scan, BamReader *manager) {
- RenderAttrib::fillin(scan, manager);
- size_t num_stages = scan.get_uint16();
- // For now, read in a linear list of the modes we will assign to
- // each associated TextureStage pointer. Later, in
- // complete_pointers, we'll fill up the map the with appropriate
- // TextureStage/Mode pairing.
- _read_modes.clear();
- _read_modes.reserve(num_stages);
- for (size_t i = 0; i < num_stages; i++) {
- manager->read_pointer(scan);
- Mode mode = (Mode)scan.get_uint8();
- _read_modes.push_back(mode);
- }
- }
|