mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 17:35:34 -04:00
add NodePath::set_light() interfaces
This commit is contained in:
parent
3896916ce6
commit
a60eb87e19
@ -676,12 +676,9 @@ issue_light(const LightAttrib *attrib) {
|
||||
bool any_bound = false;
|
||||
|
||||
int num_enabled = 0;
|
||||
int num_lights = attrib->get_num_lights();
|
||||
if (attrib->get_operation() == LightAttrib::O_remove) {
|
||||
num_lights = 0;
|
||||
}
|
||||
for (int li = 0; li < num_lights; li++) {
|
||||
Light *light = attrib->get_light(li);
|
||||
int num_on_lights = attrib->get_num_on_lights();
|
||||
for (int li = 0; li < num_on_lights; li++) {
|
||||
Light *light = attrib->get_on_light(li);
|
||||
nassertv(light != (Light *)NULL);
|
||||
|
||||
num_enabled++;
|
||||
|
@ -25,75 +25,101 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LightAttrib::
|
||||
LightAttrib() {
|
||||
_operation = O_set;
|
||||
_off_all_lights = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::get_operation
|
||||
// Access: Published
|
||||
// Description: Returns the basic operation type of the LightAttrib.
|
||||
// If this is O_set, the lights listed here completely
|
||||
// replace any lights that were already on. If this is
|
||||
// O_add, the lights here are added to the set of of
|
||||
// lights that were already on, and if O_remove, the
|
||||
// lights here are removed from the set of lights that
|
||||
// were on.
|
||||
// Function: LightAttrib::Copy Constructor
|
||||
// Access: Private
|
||||
// Description: Use LightAttrib::make() to construct a new
|
||||
// LightAttrib object. The copy constructor is only
|
||||
// defined to facilitate methods like add_on_light().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LightAttrib::Operation LightAttrib::
|
||||
get_operation() const {
|
||||
return _operation;
|
||||
INLINE LightAttrib::
|
||||
LightAttrib(const LightAttrib ©) :
|
||||
_on_lights(copy._on_lights),
|
||||
_off_lights(copy._off_lights),
|
||||
_off_all_lights(copy._off_all_lights)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::get_num_lights
|
||||
// Function: LightAttrib::get_num_on_lights
|
||||
// Access: Published
|
||||
// Description: Returns the number of lights listed in the attribute.
|
||||
// Description: Returns the number of lights that are turned on by
|
||||
// the attribute.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int LightAttrib::
|
||||
get_num_lights() const {
|
||||
return _lights.size();
|
||||
get_num_on_lights() const {
|
||||
return _on_lights.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::get_light
|
||||
// Function: LightAttrib::get_on_light
|
||||
// Access: Published
|
||||
// Description: Returns the nth lights listed in the attribute.
|
||||
// Description: Returns the nth light turned on by the attribute,
|
||||
// sorted in render order.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Light *LightAttrib::
|
||||
get_light(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_lights.size(), (Light *)NULL);
|
||||
return _lights[n];
|
||||
get_on_light(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_on_lights.size(), (Light *)NULL);
|
||||
return _on_lights[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::add_light
|
||||
// Function: LightAttrib::has_on_light
|
||||
// Access: Published
|
||||
// Description: Returns a new LightAttrib, just like this one, but
|
||||
// with the indicated light added to the list of lights.
|
||||
// Description: Returns true if the indicated light is turned on by
|
||||
// the attrib, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(RenderAttrib) LightAttrib::
|
||||
add_light(Light *light) const {
|
||||
if (_operation == O_remove) {
|
||||
return compose(make(O_remove, light));
|
||||
} else {
|
||||
return compose(make(O_add, light));
|
||||
}
|
||||
INLINE bool LightAttrib::
|
||||
has_on_light(Light *light) const {
|
||||
return _on_lights.find(light) != _on_lights.end();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::remove_light
|
||||
// Function: LightAttrib::get_num_off_lights
|
||||
// Access: Published
|
||||
// Description: Returns a new LightAttrib, just like this one, but
|
||||
// with the indicated light removed from the list of
|
||||
// lights.
|
||||
// Description: Returns the number of lights that are turned off by
|
||||
// the attribute.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(RenderAttrib) LightAttrib::
|
||||
remove_light(Light *light) const {
|
||||
if (_operation == O_remove) {
|
||||
return compose(make(O_add, light));
|
||||
} else {
|
||||
return compose(make(O_remove, light));
|
||||
}
|
||||
INLINE int LightAttrib::
|
||||
get_num_off_lights() const {
|
||||
return _off_lights.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::get_off_light
|
||||
// Access: Published
|
||||
// Description: Returns the nth light turned off by the attribute,
|
||||
// sorted in arbitrary (pointer) order.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Light *LightAttrib::
|
||||
get_off_light(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_off_lights.size(), (Light *)NULL);
|
||||
return _off_lights[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::has_off_light
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated light is turned off by
|
||||
// the attrib, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LightAttrib::
|
||||
has_off_light(Light *light) const {
|
||||
return _off_all_lights || _off_lights.find(light) != _off_lights.end();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::has_all_off
|
||||
// Access: Published
|
||||
// Description: Returns true if this attrib turns off all lights
|
||||
// (although it may also turn some on).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LightAttrib::
|
||||
has_all_off() const {
|
||||
return _off_all_lights;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -104,16 +130,5 @@ remove_light(Light *light) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LightAttrib::
|
||||
is_identity() const {
|
||||
return _operation != O_set && _lights.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::is_all_off
|
||||
// Access: Published
|
||||
// Description: Returns true if this attrib turns off all lights and
|
||||
// turns none on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LightAttrib::
|
||||
is_all_off() const {
|
||||
return _operation == O_set && _lights.empty();
|
||||
return _on_lights.empty() && _off_lights.empty() && !_off_all_lights;
|
||||
}
|
||||
|
@ -24,8 +24,307 @@
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
|
||||
CPT(RenderAttrib) LightAttrib::_empty_attrib;
|
||||
CPT(RenderAttrib) LightAttrib::_all_off_attrib;
|
||||
TypeHandle LightAttrib::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new LightAttrib object that turns on (or
|
||||
// off, according to op) the indicated light(s).
|
||||
//
|
||||
// This method is now deprecated. Use add_on_light() or
|
||||
// add_off_light() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
make(LightAttrib::Operation op, Light *light) {
|
||||
CPT(RenderAttrib) attrib;
|
||||
|
||||
switch (op) {
|
||||
case O_set:
|
||||
attrib = make_all_off();
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light);
|
||||
return attrib;
|
||||
|
||||
case O_add:
|
||||
attrib = make();
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light);
|
||||
return attrib;
|
||||
|
||||
case O_remove:
|
||||
attrib = make();
|
||||
attrib = DCAST(LightAttrib, attrib)->add_off_light(light);
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
return make();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new LightAttrib object that turns on (or
|
||||
// off, according to op) the indicate light(s).
|
||||
//
|
||||
// This method is now deprecated. Use add_on_light() or
|
||||
// add_off_light() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
make(LightAttrib::Operation op, Light *light1, Light *light2) {
|
||||
CPT(RenderAttrib) attrib;
|
||||
|
||||
switch (op) {
|
||||
case O_set:
|
||||
attrib = make_all_off();
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light1);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light2);
|
||||
return attrib;
|
||||
|
||||
case O_add:
|
||||
attrib = make();
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light1);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light2);
|
||||
return attrib;
|
||||
|
||||
case O_remove:
|
||||
attrib = make();
|
||||
attrib = DCAST(LightAttrib, attrib)->add_off_light(light1);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_off_light(light2);
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
return make();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new LightAttrib object that turns on (or
|
||||
// off, according to op) the indicate light(s).
|
||||
//
|
||||
// This method is now deprecated. Use add_on_light() or
|
||||
// add_off_light() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
make(LightAttrib::Operation op, Light *light1, Light *light2,
|
||||
Light *light3) {
|
||||
CPT(RenderAttrib) attrib;
|
||||
|
||||
switch (op) {
|
||||
case O_set:
|
||||
attrib = make_all_off();
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light1);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light2);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light3);
|
||||
return attrib;
|
||||
|
||||
case O_add:
|
||||
attrib = make();
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light1);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light2);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light3);
|
||||
return attrib;
|
||||
|
||||
case O_remove:
|
||||
attrib = make();
|
||||
attrib = DCAST(LightAttrib, attrib)->add_off_light(light1);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_off_light(light2);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_off_light(light3);
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
return make();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new LightAttrib object that turns on (or
|
||||
// off, according to op) the indicate light(s).
|
||||
//
|
||||
// This method is now deprecated. Use add_on_light() or
|
||||
// add_off_light() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
make(LightAttrib::Operation op, Light *light1, Light *light2,
|
||||
Light *light3, Light *light4) {
|
||||
CPT(RenderAttrib) attrib;
|
||||
|
||||
switch (op) {
|
||||
case O_set:
|
||||
attrib = make_all_off();
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light1);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light2);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light3);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light4);
|
||||
return attrib;
|
||||
|
||||
case O_add:
|
||||
attrib = make();
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light1);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light2);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light3);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_on_light(light4);
|
||||
return attrib;
|
||||
|
||||
case O_remove:
|
||||
attrib = make();
|
||||
attrib = DCAST(LightAttrib, attrib)->add_off_light(light1);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_off_light(light2);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_off_light(light3);
|
||||
attrib = DCAST(LightAttrib, attrib)->add_off_light(light4);
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
return make();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::get_operation
|
||||
// Access: Published
|
||||
// Description: Returns the basic operation type of the LightAttrib.
|
||||
// If this is O_set, the lights listed here completely
|
||||
// replace any lights that were already on. If this is
|
||||
// O_add, the lights here are added to the set of of
|
||||
// lights that were already on, and if O_remove, the
|
||||
// lights here are removed from the set of lights that
|
||||
// were on.
|
||||
//
|
||||
// This method is now deprecated. LightAttribs nowadays
|
||||
// have a separate list of on_lights and off_lights, so
|
||||
// this method doesn't make sense. Query the lists
|
||||
// independently.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LightAttrib::Operation LightAttrib::
|
||||
get_operation() const {
|
||||
if (has_all_off()) {
|
||||
return O_set;
|
||||
|
||||
} else if (get_num_on_lights() != 0) {
|
||||
return O_add;
|
||||
|
||||
} else {
|
||||
return O_remove;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::get_num_lights
|
||||
// Access: Published
|
||||
// Description: Returns the number of lights listed in the attribute.
|
||||
//
|
||||
// This method is now deprecated. LightAttribs nowadays
|
||||
// have a separate list of on_lights and off_lights, so
|
||||
// this method doesn't make sense. Query the lists
|
||||
// independently.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int LightAttrib::
|
||||
get_num_lights() const {
|
||||
if (get_num_on_lights() != 0) {
|
||||
return get_num_on_lights();
|
||||
} else {
|
||||
return get_num_off_lights();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::get_light
|
||||
// Access: Published
|
||||
// Description: Returns the nth lights listed in the attribute.
|
||||
//
|
||||
// This method is now deprecated. LightAttribs nowadays
|
||||
// have a separate list of on_lights and off_lights, so
|
||||
// this method doesn't make sense. Query the lists
|
||||
// independently.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Light *LightAttrib::
|
||||
get_light(int n) const {
|
||||
if (get_num_on_lights() != 0) {
|
||||
return get_on_light(n);
|
||||
} else {
|
||||
return get_off_light(n);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::has_light
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated light is listed in the
|
||||
// attrib, false otherwise.
|
||||
//
|
||||
// This method is now deprecated. LightAttribs nowadays
|
||||
// have a separate list of on_lights and off_lights, so
|
||||
// this method doesn't make sense. Query the lists
|
||||
// independently.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool LightAttrib::
|
||||
has_light(Light *light) const {
|
||||
if (get_num_on_lights() != 0) {
|
||||
return has_on_light(light);
|
||||
} else {
|
||||
return has_off_light(light);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::add_light
|
||||
// Access: Published
|
||||
// Description: Returns a new LightAttrib, just like this one, but
|
||||
// with the indicated light added to the list of lights.
|
||||
//
|
||||
// This method is now deprecated. Use add_on_light() or
|
||||
// add_off_light() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
add_light(Light *light) const {
|
||||
if (get_num_on_lights() != 0) {
|
||||
return add_on_light(light);
|
||||
} else {
|
||||
return add_off_light(light);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::remove_light
|
||||
// Access: Published
|
||||
// Description: Returns a new LightAttrib, just like this one, but
|
||||
// with the indicated light removed from the list of
|
||||
// lights.
|
||||
//
|
||||
// This method is now deprecated. Use remove_on_light()
|
||||
// or remove_off_light() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
remove_light(Light *light) const {
|
||||
if (get_num_on_lights() != 0) {
|
||||
return remove_on_light(light);
|
||||
} else {
|
||||
return remove_off_light(light);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new LightAttrib object that does
|
||||
// nothing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
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 LightAttrib);
|
||||
}
|
||||
|
||||
return _empty_attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::make_all_off
|
||||
// Access: Published, Static
|
||||
@ -34,90 +333,83 @@ TypeHandle LightAttrib::_type_handle;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
make_all_off() {
|
||||
LightAttrib *attrib = new LightAttrib;
|
||||
attrib->_operation = O_set;
|
||||
return return_new(attrib);
|
||||
// We make it a special case and store a pointer to the off attrib
|
||||
// forever once we find it the first time, as an optimization.
|
||||
if (_all_off_attrib == (RenderAttrib *)NULL) {
|
||||
LightAttrib *attrib = new LightAttrib;
|
||||
attrib->_off_all_lights = true;
|
||||
_all_off_attrib = return_new(attrib);
|
||||
}
|
||||
|
||||
return _all_off_attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new LightAttrib object that turns on (or
|
||||
// off, according to op) the indicate light(s).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
make(LightAttrib::Operation op, Light *light) {
|
||||
LightAttrib *attrib = new LightAttrib;
|
||||
attrib->_operation = op;
|
||||
attrib->_lights.push_back(light);
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new LightAttrib object that turns on (or
|
||||
// off, according to op) the indicate light(s).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
make(LightAttrib::Operation op, Light *light1, Light *light2) {
|
||||
LightAttrib *attrib = new LightAttrib;
|
||||
attrib->_operation = op;
|
||||
attrib->_lights.push_back(light1);
|
||||
attrib->_lights.push_back(light2);
|
||||
|
||||
attrib->_lights.sort();
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new LightAttrib object that turns on (or
|
||||
// off, according to op) the indicate light(s).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
make(LightAttrib::Operation op, Light *light1, Light *light2,
|
||||
Light *light3) {
|
||||
LightAttrib *attrib = new LightAttrib;
|
||||
attrib->_operation = op;
|
||||
attrib->_lights.push_back(light1);
|
||||
attrib->_lights.push_back(light2);
|
||||
attrib->_lights.push_back(light3);
|
||||
|
||||
attrib->_lights.sort();
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new LightAttrib object that turns on (or
|
||||
// off, according to op) the indicate light(s).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
make(LightAttrib::Operation op, Light *light1, Light *light2,
|
||||
Light *light3, Light *light4) {
|
||||
LightAttrib *attrib = new LightAttrib;
|
||||
attrib->_operation = op;
|
||||
attrib->_lights.push_back(light1);
|
||||
attrib->_lights.push_back(light2);
|
||||
attrib->_lights.push_back(light3);
|
||||
attrib->_lights.push_back(light4);
|
||||
|
||||
attrib->_lights.sort();
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::has_light
|
||||
// Function: LightAttrib::add_on_light
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated light is listed in the
|
||||
// attrib, false otherwise.
|
||||
// Description: Returns a new LightAttrib, just like this one, but
|
||||
// with the indicated light added to the list of lights
|
||||
// turned on by this attrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool LightAttrib::
|
||||
has_light(Light *light) const {
|
||||
return _lights.find(light) != _lights.end();
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
add_on_light(Light *light) const {
|
||||
LightAttrib *attrib = new LightAttrib(*this);
|
||||
attrib->_on_lights.insert(light);
|
||||
attrib->_off_lights.erase(light);
|
||||
|
||||
pair<Lights::iterator, bool> insert_result =
|
||||
attrib->_on_lights.insert(Lights::value_type(light));
|
||||
if (insert_result.second) {
|
||||
// Also ensure it is removed from the off_lights list.
|
||||
attrib->_off_lights.erase(light);
|
||||
}
|
||||
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::remove_on_light
|
||||
// Access: Published
|
||||
// Description: Returns a new LightAttrib, just like this one, but
|
||||
// with the indicated light removed from the list of
|
||||
// lights turned on by this attrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
remove_on_light(Light *light) const {
|
||||
LightAttrib *attrib = new LightAttrib(*this);
|
||||
attrib->_on_lights.erase(light);
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::add_off_light
|
||||
// Access: Published
|
||||
// Description: Returns a new LightAttrib, just like this one, but
|
||||
// with the indicated light added to the list of lights
|
||||
// turned off by this attrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
add_off_light(Light *light) const {
|
||||
LightAttrib *attrib = new LightAttrib(*this);
|
||||
if (!_off_all_lights) {
|
||||
attrib->_off_lights.insert(light);
|
||||
}
|
||||
attrib->_on_lights.erase(light);
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::remove_off_light
|
||||
// Access: Published
|
||||
// Description: Returns a new LightAttrib, just like this one, but
|
||||
// with the indicated light removed from the list of
|
||||
// lights turned off by this attrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
remove_off_light(Light *light) const {
|
||||
LightAttrib *attrib = new LightAttrib(*this);
|
||||
attrib->_off_lights.erase(light);
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -142,26 +434,38 @@ issue(GraphicsStateGuardianBase *gsg) const {
|
||||
void LightAttrib::
|
||||
output(ostream &out) const {
|
||||
out << get_type() << ":";
|
||||
if (_operation == O_set && _lights.empty()) {
|
||||
out << "all off";
|
||||
} else {
|
||||
switch (_operation) {
|
||||
case O_set:
|
||||
out << "set";
|
||||
break;
|
||||
case O_add:
|
||||
out << "add";
|
||||
break;
|
||||
case O_remove:
|
||||
out << "remove";
|
||||
break;
|
||||
if (_off_lights.empty()) {
|
||||
if (_on_lights.empty()) {
|
||||
if (_off_all_lights) {
|
||||
out << "all off";
|
||||
} else {
|
||||
out << "identity";
|
||||
}
|
||||
} else {
|
||||
if (_off_all_lights) {
|
||||
out << "set";
|
||||
} else {
|
||||
out << "on";
|
||||
}
|
||||
}
|
||||
|
||||
Lights::const_iterator li;
|
||||
for (li = _lights.begin(); li != _lights.end(); ++li) {
|
||||
Light *light = (*li);
|
||||
out << " " << light->get_type();
|
||||
} else {
|
||||
out << "off";
|
||||
Lights::const_iterator fi;
|
||||
for (fi = _off_lights.begin(); fi != _off_lights.end(); ++fi) {
|
||||
Light *light = (*fi);
|
||||
out << " " << *light;
|
||||
}
|
||||
|
||||
if (!_on_lights.empty()) {
|
||||
out << " on";
|
||||
}
|
||||
}
|
||||
|
||||
Lights::const_iterator li;
|
||||
for (li = _on_lights.begin(); li != _on_lights.end(); ++li) {
|
||||
Light *light = (*li);
|
||||
out << " " << *light;
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,14 +489,14 @@ compare_to_impl(const RenderAttrib *other) const {
|
||||
const LightAttrib *ta;
|
||||
DCAST_INTO_R(ta, other, 0);
|
||||
|
||||
if (_operation != ta->_operation) {
|
||||
return (int)_operation - (int)ta->_operation;
|
||||
if (_off_all_lights != ta->_off_all_lights) {
|
||||
return (int)_off_all_lights - (int)ta->_off_all_lights;
|
||||
}
|
||||
|
||||
Lights::const_iterator li = _lights.begin();
|
||||
Lights::const_iterator oli = ta->_lights.begin();
|
||||
Lights::const_iterator li = _on_lights.begin();
|
||||
Lights::const_iterator oli = ta->_on_lights.begin();
|
||||
|
||||
while (li != _lights.end() && oli != ta->_lights.end()) {
|
||||
while (li != _on_lights.end() && oli != ta->_on_lights.end()) {
|
||||
Light *light = (*li);
|
||||
Light *other_light = (*oli);
|
||||
|
||||
@ -204,10 +508,32 @@ compare_to_impl(const RenderAttrib *other) const {
|
||||
++oli;
|
||||
}
|
||||
|
||||
if (li != _lights.end()) {
|
||||
if (li != _on_lights.end()) {
|
||||
return 1;
|
||||
}
|
||||
if (oli != ta->_lights.end()) {
|
||||
if (oli != ta->_on_lights.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Lights::const_iterator fi = _off_lights.begin();
|
||||
Lights::const_iterator ofi = ta->_off_lights.begin();
|
||||
|
||||
while (fi != _off_lights.end() && ofi != ta->_off_lights.end()) {
|
||||
Light *light = (*fi);
|
||||
Light *other_light = (*ofi);
|
||||
|
||||
if (light != other_light) {
|
||||
return light < other_light ? -1 : 1;
|
||||
}
|
||||
|
||||
++fi;
|
||||
++ofi;
|
||||
}
|
||||
|
||||
if (fi != _off_lights.end()) {
|
||||
return 1;
|
||||
}
|
||||
if (ofi != ta->_off_lights.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -236,29 +562,121 @@ compose_impl(const RenderAttrib *other) const {
|
||||
const LightAttrib *ta;
|
||||
DCAST_INTO_R(ta, other, 0);
|
||||
|
||||
if (ta->_operation == O_set) {
|
||||
// If the other type is O_set, it doesn't matter what we are.
|
||||
if (ta->_off_all_lights) {
|
||||
// If the other type turns off all lights, it doesn't matter what
|
||||
// we are.
|
||||
return ta;
|
||||
}
|
||||
|
||||
if (_operation == ta->_operation) {
|
||||
// If the operation types match, the composition is simply the
|
||||
// union.
|
||||
return do_add(ta, _operation);
|
||||
// This is a three-way merge between ai, bi, and ci, except that bi
|
||||
// and ci should have no intersection and therefore needn't be
|
||||
// compared to each other.
|
||||
Lights::const_iterator ai = _on_lights.begin();
|
||||
Lights::const_iterator bi = ta->_on_lights.begin();
|
||||
Lights::const_iterator ci = ta->_off_lights.begin();
|
||||
|
||||
} else if (ta->_operation == O_remove) {
|
||||
// If the other operation type is remove, and our type is add or
|
||||
// set, then remove.
|
||||
return do_remove(ta, _operation);
|
||||
// Create a new LightAttrib that will hold the result.
|
||||
LightAttrib *new_attrib = new LightAttrib;
|
||||
back_insert_iterator<Lights> result =
|
||||
back_inserter(new_attrib->_on_lights);
|
||||
|
||||
} else if (_operation == O_remove) {
|
||||
// If our type is remove, then the other one wins.
|
||||
return ta;
|
||||
while (ai != _on_lights.end() &&
|
||||
bi != ta->_on_lights.end() &&
|
||||
ci != ta->_off_lights.end()) {
|
||||
if ((*ai) < (*bi)) {
|
||||
if ((*ai) < (*ci)) {
|
||||
// Here is a light that we have in the original, which is not
|
||||
// present in the secondary.
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++result;
|
||||
|
||||
} else {
|
||||
// Otherwise, the result is the union.
|
||||
return do_add(ta, _operation);
|
||||
} else if ((*ci) < (*ai)) {
|
||||
// Here is a light that is turned off in the secondary, but
|
||||
// was not present in the original.
|
||||
++ci;
|
||||
|
||||
} else { // (*ci) == (*ai)
|
||||
// Here is a light that is turned off in the secondary, and
|
||||
// was present in the original.
|
||||
++ai;
|
||||
++ci;
|
||||
}
|
||||
|
||||
} else if ((*bi) < (*ai)) {
|
||||
// Here is a new light we have in the secondary, that was not
|
||||
// present in the original.
|
||||
*result = *bi;
|
||||
++bi;
|
||||
++result;
|
||||
|
||||
} else { // (*bi) == (*ai)
|
||||
// Here is a light we have in both.
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++bi;
|
||||
++result;
|
||||
}
|
||||
}
|
||||
|
||||
while (ai != _on_lights.end() && bi != ta->_on_lights.end()) {
|
||||
if ((*ai) < (*bi)) {
|
||||
// Here is a light that we have in the original, which is not
|
||||
// present in the secondary.
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++result;
|
||||
|
||||
} else if ((*bi) < (*ai)) {
|
||||
// Here is a new light we have in the secondary, that was not
|
||||
// present in the original.
|
||||
*result = *bi;
|
||||
++bi;
|
||||
++result;
|
||||
|
||||
} else {
|
||||
// Here is a light we have in both.
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++bi;
|
||||
++result;
|
||||
}
|
||||
}
|
||||
|
||||
while (ai != _on_lights.end() && ci != ta->_off_lights.end()) {
|
||||
if ((*ai) < (*ci)) {
|
||||
// Here is a light that we have in the original, which is not
|
||||
// present in the secondary.
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++result;
|
||||
|
||||
} else if ((*ci) < (*ai)) {
|
||||
// Here is a light that is turned off in the secondary, but
|
||||
// was not present in the original.
|
||||
++ci;
|
||||
|
||||
} else { // (*ci) == (*ai)
|
||||
// Here is a light that is turned off in the secondary, and
|
||||
// was present in the original.
|
||||
++ai;
|
||||
++ci;
|
||||
}
|
||||
}
|
||||
|
||||
while (ai != _on_lights.end()) {
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++result;
|
||||
}
|
||||
|
||||
while (bi != ta->_on_lights.end()) {
|
||||
*result = *bi;
|
||||
++bi;
|
||||
++result;
|
||||
}
|
||||
|
||||
return return_new(new_attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -294,106 +712,6 @@ make_default_impl() const {
|
||||
return new LightAttrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::do_add
|
||||
// Access: Private
|
||||
// Description: Returns a new LightAttrib that represents all the
|
||||
// lights of this attrib, with those of the other one
|
||||
// added in.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
do_add(const LightAttrib *other, LightAttrib::Operation op) const {
|
||||
Lights::const_iterator ai = _lights.begin();
|
||||
Lights::const_iterator bi = other->_lights.begin();
|
||||
|
||||
// Create a new LightAttrib that will hold the result.
|
||||
LightAttrib *new_attrib = new LightAttrib;
|
||||
new_attrib->_operation = op;
|
||||
back_insert_iterator<Lights> result =
|
||||
back_inserter(new_attrib->_lights);
|
||||
|
||||
while (ai != _lights.end() && bi != other->_lights.end()) {
|
||||
if ((*ai) < (*bi)) {
|
||||
// Here is a light that we have in the original, which is not
|
||||
// present in the secondary.
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++result;
|
||||
} else if ((*bi) < (*ai)) {
|
||||
// Here is a new light we have in the secondary, that was not
|
||||
// present in the original.
|
||||
*result = *bi;
|
||||
++bi;
|
||||
++result;
|
||||
} else {
|
||||
// Here is a light we have in both.
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++bi;
|
||||
++result;
|
||||
}
|
||||
}
|
||||
|
||||
while (ai != _lights.end()) {
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++result;
|
||||
}
|
||||
|
||||
while (bi != other->_lights.end()) {
|
||||
*result = *bi;
|
||||
++bi;
|
||||
++result;
|
||||
}
|
||||
|
||||
return return_new(new_attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::do_remove
|
||||
// Access: Private
|
||||
// Description: Returns a new LightAttrib that represents all the
|
||||
// lights of this attrib, with those of the other one
|
||||
// removed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) LightAttrib::
|
||||
do_remove(const LightAttrib *other, LightAttrib::Operation op) const {
|
||||
Lights::const_iterator ai = _lights.begin();
|
||||
Lights::const_iterator bi = other->_lights.begin();
|
||||
|
||||
// Create a new LightAttrib that will hold the result.
|
||||
LightAttrib *new_attrib = new LightAttrib;
|
||||
new_attrib->_operation = op;
|
||||
back_insert_iterator<Lights> result =
|
||||
back_inserter(new_attrib->_lights);
|
||||
|
||||
while (ai != _lights.end() && bi != other->_lights.end()) {
|
||||
if ((*ai) < (*bi)) {
|
||||
// Here is a light that we have in the original, which is
|
||||
// not present in the secondary. Keep it.
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++result;
|
||||
} else if ((*bi) < (*ai)) {
|
||||
// Here is a new light we have in the secondary, that was
|
||||
// not present in the original. Ignore it.
|
||||
++bi;
|
||||
} else {
|
||||
// Here is a light we have in both. Drop it.
|
||||
++ai;
|
||||
++bi;
|
||||
}
|
||||
}
|
||||
|
||||
while (ai != _lights.end()) {
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++result;
|
||||
}
|
||||
|
||||
return return_new(new_attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
@ -415,14 +733,23 @@ void LightAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
|
||||
dg.add_int8((int)_operation);
|
||||
PN_uint16 num_lights = _lights.size();
|
||||
nassertv(num_lights == _lights.size());
|
||||
dg.add_uint16(num_lights);
|
||||
dg.add_bool(_off_all_lights);
|
||||
|
||||
Lights::const_iterator li;
|
||||
for (li = _lights.begin(); li != _lights.end(); ++li) {
|
||||
Light *light = (*li);
|
||||
// write the number of off_lights
|
||||
dg.add_uint16(get_num_off_lights());
|
||||
// write the off lights pointers if any
|
||||
Lights::const_iterator fi;
|
||||
for (fi = _off_lights.begin(); fi != _off_lights.end(); ++fi) {
|
||||
Light *light = (*fi);
|
||||
manager->write_pointer(dg, light->as_node());
|
||||
}
|
||||
|
||||
// write the number of on lights
|
||||
dg.add_uint16(get_num_on_lights());
|
||||
// write the on lights pointers if any
|
||||
Lights::const_iterator nti;
|
||||
for (nti = _on_lights.begin(); nti != _on_lights.end(); ++nti) {
|
||||
Light *light = (*nti);
|
||||
manager->write_pointer(dg, light->as_node());
|
||||
}
|
||||
}
|
||||
@ -438,11 +765,20 @@ int LightAttrib::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = RenderAttrib::complete_pointers(p_list, manager);
|
||||
|
||||
Lights::iterator li;
|
||||
for (li = _lights.begin(); li != _lights.end(); ++li) {
|
||||
Lights::iterator ci = _off_lights.begin();
|
||||
while (ci != _off_lights.end()) {
|
||||
PandaNode *node;
|
||||
DCAST_INTO_R(node, p_list[pi++], pi);
|
||||
(*li) = node->as_light();
|
||||
(*ci) = node->as_light();
|
||||
++ci;
|
||||
}
|
||||
|
||||
ci = _on_lights.begin();
|
||||
while (ci != _on_lights.end()) {
|
||||
PandaNode *node;
|
||||
DCAST_INTO_R(node, p_list[pi++], pi);
|
||||
(*ci) = node->as_light();
|
||||
++ci;
|
||||
}
|
||||
|
||||
return pi;
|
||||
@ -479,11 +815,31 @@ void LightAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
|
||||
_operation = (Operation)scan.get_int8();
|
||||
int num_lights = scan.get_uint16();
|
||||
// We cheat a little bit here. In the middle of bam version 4.10,
|
||||
// we completely redefined the bam storage definition for
|
||||
// LightAttribs, without bothering to up the bam version or even to
|
||||
// attempt to read the old definition. We get away with this,
|
||||
// knowing that the egg loader doesn't create LightAttribs, and
|
||||
// hence no old bam files have the old definition for LightAttrib
|
||||
// within them.
|
||||
|
||||
for (int i = 0; i < num_lights; i++) {
|
||||
_off_all_lights = scan.get_bool();
|
||||
|
||||
int num_off_lights = scan.get_uint16();
|
||||
|
||||
// Push back a NULL pointer for each off Light for now, until
|
||||
// we get the actual list of pointers later in complete_pointers().
|
||||
_off_lights.reserve(num_off_lights);
|
||||
int i;
|
||||
for (i = 0; i < num_off_lights; i++) {
|
||||
manager->read_pointer(scan);
|
||||
_lights.push_back(NULL);
|
||||
_off_lights.push_back(NULL);
|
||||
}
|
||||
|
||||
int num_on_lights = scan.get_uint16();
|
||||
_on_lights.reserve(num_on_lights);
|
||||
for (i = 0; i < num_on_lights; i++) {
|
||||
manager->read_pointer(scan);
|
||||
_on_lights.push_back(NULL);
|
||||
}
|
||||
}
|
||||
|
@ -35,15 +35,18 @@
|
||||
class EXPCL_PANDA LightAttrib : public RenderAttrib {
|
||||
private:
|
||||
INLINE LightAttrib();
|
||||
INLINE LightAttrib(const LightAttrib ©);
|
||||
|
||||
PUBLISHED:
|
||||
|
||||
// This is the old, deprecated interface to LightAttrib. Do not use
|
||||
// any of these methods for new code; these methods will be removed
|
||||
// soon.
|
||||
enum Operation {
|
||||
O_set,
|
||||
O_add,
|
||||
O_remove
|
||||
};
|
||||
|
||||
static CPT(RenderAttrib) make_all_off();
|
||||
static CPT(RenderAttrib) make(Operation op,
|
||||
Light *light);
|
||||
static CPT(RenderAttrib) make(Operation op,
|
||||
@ -55,17 +58,36 @@ PUBLISHED:
|
||||
Light *light1, Light *light2,
|
||||
Light *light3, Light *light4);
|
||||
|
||||
INLINE Operation get_operation() const;
|
||||
Operation get_operation() const;
|
||||
|
||||
INLINE int get_num_lights() const;
|
||||
INLINE Light *get_light(int n) const;
|
||||
int get_num_lights() const;
|
||||
Light *get_light(int n) const;
|
||||
bool has_light(Light *light) const;
|
||||
|
||||
INLINE CPT(RenderAttrib) add_light(Light *light) const;
|
||||
INLINE CPT(RenderAttrib) remove_light(Light *light) const;
|
||||
CPT(RenderAttrib) add_light(Light *light) const;
|
||||
CPT(RenderAttrib) remove_light(Light *light) const;
|
||||
|
||||
|
||||
// The following is the new, more general interface to the
|
||||
// LightAttrib.
|
||||
static CPT(RenderAttrib) make();
|
||||
static CPT(RenderAttrib) make_all_off();
|
||||
|
||||
INLINE int get_num_on_lights() const;
|
||||
INLINE Light *get_on_light(int n) const;
|
||||
INLINE bool has_on_light(Light *light) const;
|
||||
|
||||
INLINE int get_num_off_lights() const;
|
||||
INLINE Light *get_off_light(int n) const;
|
||||
INLINE bool has_off_light(Light *light) const;
|
||||
INLINE bool has_all_off() const;
|
||||
|
||||
INLINE bool is_identity() const;
|
||||
INLINE bool is_all_off() const;
|
||||
|
||||
CPT(RenderAttrib) add_on_light(Light *light) const;
|
||||
CPT(RenderAttrib) remove_on_light(Light *light) const;
|
||||
CPT(RenderAttrib) add_off_light(Light *light) const;
|
||||
CPT(RenderAttrib) remove_off_light(Light *light) const;
|
||||
|
||||
public:
|
||||
virtual void issue(GraphicsStateGuardianBase *gsg) const;
|
||||
@ -78,13 +100,12 @@ protected:
|
||||
virtual RenderAttrib *make_default_impl() const;
|
||||
|
||||
private:
|
||||
CPT(RenderAttrib) do_add(const LightAttrib *other, Operation op) const;
|
||||
CPT(RenderAttrib) do_remove(const LightAttrib *other, Operation op) const;
|
||||
|
||||
private:
|
||||
Operation _operation;
|
||||
typedef ov_set< PT(Light) > Lights;
|
||||
Lights _lights;
|
||||
Lights _on_lights, _off_lights;
|
||||
bool _off_all_lights;
|
||||
|
||||
static CPT(RenderAttrib) _empty_attrib;
|
||||
static CPT(RenderAttrib) _all_off_attrib;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "cullBinAttrib.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "materialAttrib.h"
|
||||
#include "lightAttrib.h"
|
||||
#include "polylightEffect.h"
|
||||
#include "fogAttrib.h"
|
||||
#include "renderModeAttrib.h"
|
||||
#include "cullFaceAttrib.h"
|
||||
@ -2014,6 +2016,295 @@ get_color_scale() const {
|
||||
return ident_scale;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_light
|
||||
// Access: Published
|
||||
// Description: Adds the indicated light to the list of lights that
|
||||
// illuminate geometry at this node and below. The
|
||||
// light itself should be parented into the scene graph
|
||||
// elsewhere, to represent the light's position in
|
||||
// space; but until set_light() is called it will
|
||||
// illuminate no geometry.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_light(Light *light, int priority) {
|
||||
nassertv_always(!is_empty());
|
||||
|
||||
const RenderAttrib *attrib =
|
||||
node()->get_attrib(LightAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
priority = max(priority,
|
||||
node()->get_state()->get_override(LightAttrib::get_class_type()));
|
||||
const LightAttrib *la = DCAST(LightAttrib, attrib);
|
||||
|
||||
// Modify the existing LightAttrib to add the indicated
|
||||
// light.
|
||||
node()->set_attrib(la->add_on_light(light), priority);
|
||||
|
||||
} else {
|
||||
// Create a new LightAttrib for this node.
|
||||
CPT(LightAttrib) la = DCAST(LightAttrib, LightAttrib::make());
|
||||
node()->set_attrib(la->add_on_light(light), priority);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_light_off
|
||||
// Access: Published
|
||||
// Description: Sets the geometry at this level and below to render
|
||||
// using no lights at all. This is different
|
||||
// from not specifying a light; rather, this
|
||||
// specifically contradicts set_light() at a higher
|
||||
// node level (or, with a priority, overrides a
|
||||
// set_light() at a lower level).
|
||||
//
|
||||
// If no lights are in effect on a particular piece of
|
||||
// geometry, that geometry is rendered with lighting
|
||||
// disabled.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_light_off(int priority) {
|
||||
nassertv_always(!is_empty());
|
||||
node()->set_attrib(LightAttrib::make_all_off(), priority);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_light_off
|
||||
// Access: Published
|
||||
// Description: Sets the geometry at this level and below to render
|
||||
// using without the indicated light. This is different
|
||||
// from not specifying the light; rather, this
|
||||
// specifically contradicts set_light() at a higher node
|
||||
// level (or, with a priority, overrides a set_light()
|
||||
// at a lower level).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_light_off(Light *light, int priority) {
|
||||
nassertv_always(!is_empty());
|
||||
|
||||
const RenderAttrib *attrib =
|
||||
node()->get_attrib(LightAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
priority = max(priority,
|
||||
node()->get_state()->get_override(LightAttrib::get_class_type()));
|
||||
const LightAttrib *la = DCAST(LightAttrib, attrib);
|
||||
|
||||
// Modify the existing LightAttrib to add the indicated light
|
||||
// to the "off" list. This also, incidentally, removes it from
|
||||
// the "on" list if it is there.
|
||||
node()->set_attrib(la->add_off_light(light), priority);
|
||||
|
||||
} else {
|
||||
// Create a new LightAttrib for this node that turns off the
|
||||
// indicated light.
|
||||
CPT(LightAttrib) la = DCAST(LightAttrib, LightAttrib::make());
|
||||
node()->set_attrib(la->add_off_light(light), priority);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::clear_light
|
||||
// Access: Published
|
||||
// Description: Completely removes any lighting operations that may
|
||||
// have been set via set_light() or set_light_off()
|
||||
// from this particular node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
clear_light() {
|
||||
nassertv_always(!is_empty());
|
||||
node()->clear_attrib(LightAttrib::get_class_type());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::clear_light
|
||||
// Access: Published
|
||||
// Description: Removes any reference to the indicated light
|
||||
// from the NodePath.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
clear_light(Light *light) {
|
||||
nassertv_always(!is_empty());
|
||||
|
||||
const RenderAttrib *attrib =
|
||||
node()->get_attrib(LightAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
CPT(LightAttrib) la = DCAST(LightAttrib, attrib);
|
||||
la = DCAST(LightAttrib, la->remove_on_light(light));
|
||||
la = DCAST(LightAttrib, la->remove_off_light(light));
|
||||
|
||||
if (la->is_identity()) {
|
||||
node()->clear_attrib(LightAttrib::get_class_type());
|
||||
|
||||
} else {
|
||||
int priority = node()->get_state()->get_override(LightAttrib::get_class_type());
|
||||
node()->set_attrib(la, priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::has_light
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated light has been
|
||||
// specifically enabled on this particular node. This
|
||||
// means that someone called set_light() on this node
|
||||
// with the indicated light.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodePath::
|
||||
has_light(Light *light) const {
|
||||
nassertr_always(!is_empty(), false);
|
||||
|
||||
const RenderAttrib *attrib =
|
||||
node()->get_attrib(LightAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
const LightAttrib *la = DCAST(LightAttrib, attrib);
|
||||
return la->has_on_light(light);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::has_light_off
|
||||
// Access: Published
|
||||
// Description: Returns true if all lights have been specifically
|
||||
// disabled on this particular node. This means that
|
||||
// someone called set_light_off() on this node with no
|
||||
// parameters.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodePath::
|
||||
has_light_off() const {
|
||||
nassertr_always(!is_empty(), false);
|
||||
const RenderAttrib *attrib =
|
||||
node()->get_attrib(LightAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
const LightAttrib *la = DCAST(LightAttrib, attrib);
|
||||
return la->has_all_off();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::has_light_off
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated light has been
|
||||
// specifically disabled on this particular node. This
|
||||
// means that someone called set_light_off() on this
|
||||
// node with the indicated light.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodePath::
|
||||
has_light_off(Light *light) const {
|
||||
nassertr_always(!is_empty(), false);
|
||||
|
||||
const RenderAttrib *attrib =
|
||||
node()->get_attrib(LightAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
const LightAttrib *la = DCAST(LightAttrib, attrib);
|
||||
return la->has_off_light(light);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_light
|
||||
// Access: Published
|
||||
// Description: Adds a PolylightEffect to the geometry at this node
|
||||
// and below. This makes the geometry at this point in
|
||||
// the scene graph grow brighter or dimmer according to
|
||||
// its proximity to the indicated PolylightNode; this is
|
||||
// an effect similar to lighting, but is not related to
|
||||
// traditional hardware T&L.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_light(PolylightNode *) {
|
||||
// Not yet implemented.
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::clear_light
|
||||
// Access: Published
|
||||
// Description: Removes the indicated PolylightEffect from the
|
||||
// geometry. This undoes a previous set_light() call.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
clear_light(PolylightNode *) {
|
||||
// Not yet implemented.
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::has_light
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated PolylightNode was added
|
||||
// to this node, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodePath::
|
||||
has_light(PolylightNode *) {
|
||||
// Not yet implemented.
|
||||
nassertr(false, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_light
|
||||
// Access: Published
|
||||
// Description: Adds a Light or Polylight to the geometry at this
|
||||
// node and below.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_light(const NodePath &light) {
|
||||
if (!light.is_empty()) {
|
||||
PandaNode *node = light.node();
|
||||
Light *light_obj = node->as_light();
|
||||
if (light_obj != (Light *)NULL) {
|
||||
set_light(light_obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
nassert_raise("Not a light object.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::clear_light
|
||||
// Access: Published
|
||||
// Description: Removes the indicated PolylightEffect from the
|
||||
// geometry. This undoes a previous set_light() call.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
clear_light(const NodePath &light) {
|
||||
if (!light.is_empty()) {
|
||||
PandaNode *node = light.node();
|
||||
Light *light_obj = node->as_light();
|
||||
if (light_obj != (Light *)NULL) {
|
||||
clear_light(light_obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
nassert_raise("Not a light object.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::has_light
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated PolylightNode was added
|
||||
// to this node, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodePath::
|
||||
has_light(const NodePath &light) {
|
||||
if (!light.is_empty()) {
|
||||
PandaNode *node = light.node();
|
||||
Light *light_obj = node->as_light();
|
||||
if (light_obj != (Light *)NULL) {
|
||||
return has_light(light_obj);
|
||||
}
|
||||
}
|
||||
nassert_raise("Not a light object.");
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_bin
|
||||
// Access: Published
|
||||
|
@ -35,6 +35,8 @@ class NodePathCollection;
|
||||
class TextureCollection;
|
||||
class FindApproxPath;
|
||||
class FindApproxLevelEntry;
|
||||
class Light;
|
||||
class PolylightNode;
|
||||
class Texture;
|
||||
class Material;
|
||||
class Fog;
|
||||
@ -481,6 +483,23 @@ PUBLISHED:
|
||||
INLINE float get_sb() const;
|
||||
INLINE float get_sa() const;
|
||||
|
||||
void set_light(Light *light, int priority = 0);
|
||||
void set_light_off(int priority = 0);
|
||||
void set_light_off(Light *light, int priority = 0);
|
||||
void clear_light();
|
||||
void clear_light(Light *light);
|
||||
bool has_light(Light *light) const;
|
||||
bool has_light_off() const;
|
||||
bool has_light_off(Light *light) const;
|
||||
|
||||
void set_light(PolylightNode *light);
|
||||
void clear_light(PolylightNode *light);
|
||||
bool has_light(PolylightNode *light);
|
||||
|
||||
void set_light(const NodePath &light);
|
||||
void clear_light(const NodePath &light);
|
||||
bool has_light(const NodePath &light);
|
||||
|
||||
void set_bin(const string &bin_name, int draw_order, int priority = 0);
|
||||
void clear_bin();
|
||||
bool has_bin() const;
|
||||
|
@ -568,6 +568,23 @@ get_attrib(TypeHandle type) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::get_override
|
||||
// Access: Published, Virtual
|
||||
// Description: Looks for a RenderAttrib of the indicated type in the
|
||||
// state, and returns its override value if it is found,
|
||||
// or 0 if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int RenderState::
|
||||
get_override(TypeHandle type) const {
|
||||
Attributes::const_iterator ai;
|
||||
ai = _attributes.find(Attribute(type));
|
||||
if (ai != _attributes.end()) {
|
||||
return (*ai)._override;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::output
|
||||
// Access: Published, Virtual
|
||||
@ -842,11 +859,7 @@ issue_delta_modify(const RenderState *other,
|
||||
if ((*ai)._attrib != (*bi)._attrib) {
|
||||
any_changed = true;
|
||||
(*bi)._attrib->issue(gsg);
|
||||
|
||||
} else if ((*bi)._attrib->always_reissue()) {
|
||||
(*bi)._attrib->issue(gsg);
|
||||
}
|
||||
|
||||
*result = *bi;
|
||||
++ai;
|
||||
++bi;
|
||||
@ -914,7 +927,7 @@ issue_delta_set(const RenderState *other,
|
||||
} else {
|
||||
// Here is an attribute we have in both. Issue the new one if
|
||||
// it's different.
|
||||
if ((*ai)._attrib != (*bi)._attrib || (*bi)._attrib->always_reissue()) {
|
||||
if ((*ai)._attrib != (*bi)._attrib) {
|
||||
(*bi)._attrib->issue(gsg);
|
||||
}
|
||||
++ai;
|
||||
@ -1020,20 +1033,17 @@ do_compose(const RenderState *other) const {
|
||||
++bi;
|
||||
++result;
|
||||
} else {
|
||||
// Here is an attribute we have in both. Does one override the
|
||||
// other?
|
||||
// Here is an attribute we have in both. Does A override B?
|
||||
const Attribute &a = (*ai);
|
||||
const Attribute &b = (*bi);
|
||||
if (a._override < b._override) {
|
||||
// B overrides.
|
||||
*result = *bi;
|
||||
|
||||
} else if (b._override < a._override) {
|
||||
if (b._override < a._override) {
|
||||
// A overrides.
|
||||
*result = *ai;
|
||||
|
||||
} else {
|
||||
// No, they're equivalent, so compose them.
|
||||
// Either they have the same override value, or B is higher.
|
||||
// In either case, the result is the composition of the two,
|
||||
// with B's override value.
|
||||
*result = Attribute(a._attrib->compose(b._attrib), b._override);
|
||||
}
|
||||
++ai;
|
||||
|
@ -89,6 +89,7 @@ PUBLISHED:
|
||||
CPT(RenderState) adjust_all_priorities(int adjustment) const;
|
||||
|
||||
const RenderAttrib *get_attrib(TypeHandle type) const;
|
||||
int get_override(TypeHandle type) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user