15 #include "renderEffects.h" 16 #include "billboardEffect.h" 17 #include "decalEffect.h" 18 #include "compassEffect.h" 19 #include "polylightEffect.h" 20 #include "showBoundsEffect.h" 21 #include "config_pgraph.h" 22 #include "bamReader.h" 23 #include "bamWriter.h" 24 #include "datagramIterator.h" 26 #include "compareTo.h" 27 #include "lightReMutexHolder.h" 28 #include "lightMutexHolder.h" 46 RenderEffects() : _lock(
"RenderEffects") {
47 if (_states == (States *)NULL) {
50 _saved_entry = _states->end();
86 nassertv(_saved_entry == _states->end());
98 Effects::const_iterator ai;
99 for (ai = _effects.
begin(); ai != _effects.
end(); ++ai) {
100 const Effect &effect = (*ai);
101 if (!effect._effect->safe_to_transform()) {
117 CPT(TransformState) RenderEffects::
118 prepare_flatten_transform(
const TransformState *net_transform)
const {
119 CPT(TransformState) result = net_transform;
120 Effects::const_iterator ai;
121 for (ai = _effects.
begin(); ai != _effects.
end(); ++ai) {
122 const Effect &effect = (*ai);
123 result = effect._effect->prepare_flatten_transform(result);
138 safe_to_combine()
const {
139 Effects::const_iterator ai;
140 for (ai = _effects.
begin(); ai != _effects.
end(); ++ai) {
141 const Effect &effect = (*ai);
142 if (!effect._effect->safe_to_combine()) {
163 back_insert_iterator<Effects> result =
164 back_inserter(new_state->_effects);
166 Effects::const_iterator ai;
167 for (ai = _effects.
begin(); ai != _effects.
end(); ++ai) {
168 const Effect &effect = (*ai);
169 Effect new_effect(effect);
170 new_effect._effect = effect._effect->xform(mat);
171 *result = new_effect;
175 return return_new(new_state);
194 return lexicographical_compare(_effects.
begin(), _effects.
end(),
195 other._effects.
begin(), other._effects.
end(),
209 Effects::const_iterator ai = _effects.find(Effect(type));
210 if (ai == _effects.
end()) {
213 return ai - _effects.
begin();
227 _empty_state = return_new(state);
242 state->_effects.insert(Effect(effect));
243 return return_new(state);
256 state->_effects.
push_back(Effect(effect1));
257 state->_effects.
push_back(Effect(effect2));
258 state->_effects.
sort();
259 return return_new(state);
273 state->_effects.
push_back(Effect(effect1));
274 state->_effects.
push_back(Effect(effect2));
275 state->_effects.
push_back(Effect(effect3));
276 state->_effects.
sort();
277 return return_new(state);
292 state->_effects.
push_back(Effect(effect1));
293 state->_effects.
push_back(Effect(effect2));
294 state->_effects.
push_back(Effect(effect3));
295 state->_effects.
push_back(Effect(effect4));
296 state->_effects.
sort();
297 return return_new(state);
311 back_insert_iterator<Effects> result =
312 back_inserter(new_state->_effects);
314 Effect new_effect(effect);
315 Effects::const_iterator ai = _effects.
begin();
317 while (ai != _effects.
end() && (*ai) < new_effect) {
322 *result = new_effect;
325 if (ai != _effects.
end() && !(new_effect < (*ai))) {
333 while (ai != _effects.
end()) {
339 return return_new(new_state);
352 back_insert_iterator<Effects> result =
353 back_inserter(new_state->_effects);
355 Effects::const_iterator ai = _effects.
begin();
357 while (ai != _effects.
end()) {
358 if ((*ai)._type != type) {
365 return return_new(new_state);
377 Effects::const_iterator ai;
378 ai = _effects.find(Effect(type));
379 if (ai != _effects.
end()) {
380 return (*ai)._effect;
425 output(ostream &out)
const {
427 if (_effects.
empty()) {
431 Effects::const_iterator ai = _effects.
begin();
432 out <<
"(" << (*ai)._type;
434 while (ai != _effects.
end()) {
435 out <<
" " << (*ai)._type;
448 write(ostream &out,
int indent_level)
const {
449 indent(out, indent_level) << _effects.
size() <<
" effects:\n";
450 Effects::const_iterator ai;
451 for (ai = _effects.
begin(); ai != _effects.
end(); ++ai) {
452 const Effect &effect = (*ai);
453 effect._effect->write(out, indent_level + 2);
466 if (_states == (
States *)NULL) {
470 return _states->size();
482 out << _states->size() <<
" states:\n";
483 States::const_iterator si;
484 for (si = _states->begin(); si != _states->end(); ++si) {
486 state->write(out, 2);
500 if (_states->empty()) {
505 States::const_iterator si = _states->begin();
506 States::const_iterator snext = si;
508 while (snext != _states->end()) {
509 if (!(*(*si) < *(*snext))) {
511 <<
"RenderEffects out of order!\n";
512 (*si)->write(pgraph_cat.error(
false), 2);
513 (*snext)->write(pgraph_cat.error(
false), 2);
516 if ((*(*snext) < *(*si))) {
518 <<
"RenderEffects::operator < not defined properly!\n";
519 pgraph_cat.error(
false)
520 <<
"a < b: " << (*(*si) < *(*snext)) <<
"\n";
521 pgraph_cat.error(
false)
522 <<
"b < a: " << (*(*snext) < *(*si)) <<
"\n";
523 (*si)->write(pgraph_cat.error(
false), 2);
524 (*snext)->write(pgraph_cat.error(
false), 2);
543 CPT(TransformState) &node_transform,
545 Effects::const_iterator ei;
546 for (ei = _effects.
begin(); ei != _effects.
end(); ++ei) {
547 (*ei)._effect->cull_callback(trav, data, node_transform, node_state);
565 CPT(TransformState) &node_transform,
567 Effects::const_iterator ei;
568 for (ei = _effects.
begin(); ei != _effects.
end(); ++ei) {
569 (*ei)._effect->adjust_transform(net_transform, node_transform, node);
592 _states_lock =
new LightReMutex(
"RenderEffects::_states_lock");
620 if (paranoid_const) {
629 nassertr(state->_saved_entry == _states->end(), state);
635 pair<States::iterator, bool> result = _states->insert(state);
639 state->_saved_entry = result.first;
640 nassertr(_states->find(state) == state->_saved_entry, pt_state);
646 return *(result.first);
662 if (_saved_entry != _states->end()) {
663 nassertv(_states->find(
this) == _saved_entry);
664 _states->erase(_saved_entry);
665 _saved_entry = _states->end();
677 if ((_flags & F_checked_decal) != 0) {
684 _flags |= F_has_decal;
686 _flags |= F_checked_decal;
695 determine_show_bounds() {
697 if ((_flags & F_checked_show_bounds) != 0) {
704 _flags |= F_has_show_bounds;
707 _flags |= F_has_show_tight_bounds;
710 _flags |= F_checked_show_bounds;
719 determine_cull_callback() {
721 if ((_flags & F_checked_cull_callback) != 0) {
726 _flags |= F_checked_cull_callback;
728 Effects::const_iterator ei;
729 for (ei = _effects.
begin(); ei != _effects.
end(); ++ei) {
730 if ((*ei)._effect->has_cull_callback()) {
731 _flags |= F_has_cull_callback;
743 determine_adjust_transform() {
745 if ((_flags & F_checked_adjust_transform) != 0) {
750 _flags |= F_checked_adjust_transform;
752 Effects::const_iterator ei;
753 for (ei = _effects.
begin(); ei != _effects.
end(); ++ei) {
754 if ((*ei)._effect->has_adjust_transform()) {
755 _flags |= F_has_adjust_transform;
782 int num_effects = _effects.
size();
783 nassertv(num_effects == (
int)(PN_uint16)num_effects);
786 Effects::const_iterator ai;
787 for (ai = _effects.
begin(); ai != _effects.
end(); ++ai) {
788 const Effect &effect = (*ai);
807 while (i < _effects.
size()) {
808 Effect &effect = _effects[i];
814 _effects.erase(_effects.
begin() + i);
818 effect._type = effect._effect->get_type();
829 nassertr(_saved_entry == _states->end(), pi);
877 if (pointer == state) {
921 parse_params(params, scan, manager);
922 state->fillin(scan, manager);
944 for (
int i = 0; i < num_effects; i++) {
949 nassertv(_saved_entry == _states->end());
static void list_states(ostream &out)
Lists all of the RenderEffects in the cache to the output stream, one per line.
A basic node of the scene graph or data graph.
An STL function object class, this is intended to be used on any ordered collection of classes that c...
static TypedWritable * change_this(TypedWritable *old_ptr, BamReader *manager)
Called immediately after complete_pointers(), this gives the object a chance to adjust its own pointe...
bool is_empty() const
Returns true if the state is empty, false otherwise.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
size_type_0 size() const
Returns the number of elements in the ordered vector.
bool safe_to_transform() const
Returns true if all of the effects in this set can safely be transformed, and therefore the complete ...
static void init_states()
Make sure the global _states map is allocated.
Base class for objects that can be written to and read from Bam files.
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
bool debug_is_locked() const
Returns true if the current thread has locked the LightReMutex, false otherwise.
A lightweight reentrant mutex.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
Applied to a GeomNode to cause a visible bounding volume to be drawn for this node.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
This is the base class for a number of special render effects that may be set on scene graph nodes to...
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
void reserve(size_type_0 n)
Informs the vector of a planned change in size; ensures that the capacity of the vector is greater th...
bool empty() const
Returns true if the ordered vector is empty, false otherwise.
bool get_tight() const
Returns true if the "tight" flag was set, meaning the effect should compute and draw the tight boundi...
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
void register_change_this(ChangeThisFunc func, TypedWritable *whom)
Called by an object reading itself from the bam file to indicate that the object pointer that will be...
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
static bool validate_states()
Ensures that the cache is still stored in sorted order.
void cull_callback(CullTraverser *trav, CullTraverserData &data, CPT(TransformState) &node_transform, CPT(RenderState) &node_state) const
Calls cull_callback() on all effects.
static Thread * get_main_thread()
Returns a pointer to the "main" Thread object–this is the Thread that started the whole process...
virtual bool require_fully_complete() const
Some objects require all of their nested pointers to have been completed before the objects themselve...
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin()...
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin()...
This is a 4-by-4 transform matrix.
Similar to MutexHolder, but for a light mutex.
void sort()
Maps to sort_unique().
An instance of this class is passed to the Factory when requesting it to do its business and construc...
static void register_with_read_factory()
Tells the BamReader how to create objects of type RenderEffects.
void register_finalize(TypedWritable *whom)
Should be called by an object reading itself from the Bam file to indicate that this particular objec...
Similar to MutexHolder, but for a light reentrant mutex.
void push_back(const value_type_0 &key)
Adds the new element to the end of the vector without regard for proper sorting.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
virtual void finalize(BamReader *manager)
Called by the BamReader to perform any final actions needed for setting up the object after all objec...
int get_ref_count() const
Returns the current reference count.
void add_uint16(PN_uint16 value)
Adds an unsigned 16-bit integer to the datagram.
virtual bool unref() const
Explicitly decrements the reference count.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
const RenderEffect * get_effect(int n) const
Returns the nth effect in the state.
void adjust_transform(CPT(TransformState) &net_transform, CPT(TransformState) &node_transform, PandaNode *node) const
Calls adjust_transform() on all effects.
This is our own Panda specialization on the default STL set.
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
virtual ~RenderEffects()
The destructor is responsible for removing the RenderEffects from the global set if it is there...
This represents a unique collection of RenderEffect objects that correspond to a particular renderabl...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
virtual bool unref() const
Explicitly decrements the reference count.
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
void read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.