mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
new NodePath::set_attrib(), set_clip_plane(), etc.
This commit is contained in:
parent
0dd3363dd1
commit
10242ea013
@ -19,81 +19,108 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::Constructor
|
||||
// Access: Private
|
||||
// Access: Protected
|
||||
// Description: Use ClipPlaneAttrib::make() to construct a new
|
||||
// ClipPlaneAttrib object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ClipPlaneAttrib::
|
||||
ClipPlaneAttrib() {
|
||||
_operation = O_set;
|
||||
_off_all_planes = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::get_operation
|
||||
// Access: Published
|
||||
// Description: Returns the basic operation type of the ClipPlaneAttrib.
|
||||
// If this is O_set, the planes listed here completely
|
||||
// replace any planes that were already on. If this is
|
||||
// O_add, the planes here are added to the set of of
|
||||
// planes that were already on, and if O_remove, the
|
||||
// planes here are removed from the set of planes that
|
||||
// were on.
|
||||
// Function: ClipPlaneAttrib::Copy Constructor
|
||||
// Access: Protected
|
||||
// Description: Use ClipPlaneAttrib::make() to construct a new
|
||||
// ClipPlaneAttrib object. The copy constructor is only
|
||||
// defined to facilitate methods like add_on_plane().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ClipPlaneAttrib::Operation ClipPlaneAttrib::
|
||||
get_operation() const {
|
||||
return _operation;
|
||||
INLINE ClipPlaneAttrib::
|
||||
ClipPlaneAttrib(const ClipPlaneAttrib ©) :
|
||||
_on_planes(copy._on_planes),
|
||||
_off_planes(copy._off_planes),
|
||||
_off_all_planes(copy._off_all_planes)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::get_num_planes
|
||||
// Function: ClipPlaneAttrib::get_num_on_planes
|
||||
// Access: Published
|
||||
// Description: Returns the number of planes listed in the attribute.
|
||||
// Description: Returns the number of planes that are enabled by
|
||||
// the attribute.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int ClipPlaneAttrib::
|
||||
get_num_planes() const {
|
||||
return _planes.size();
|
||||
get_num_on_planes() const {
|
||||
return _on_planes.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::get_plane
|
||||
// Function: ClipPlaneAttrib::get_on_plane
|
||||
// Access: Published
|
||||
// Description: Returns the nth planes listed in the attribute.
|
||||
// Description: Returns the nth plane enabled by the attribute,
|
||||
// sorted in render order.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PlaneNode *ClipPlaneAttrib::
|
||||
get_plane(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_planes.size(), (PlaneNode *)NULL);
|
||||
return _planes[n];
|
||||
INLINE NodePath ClipPlaneAttrib::
|
||||
get_on_plane(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_on_planes.size(), NodePath::fail());
|
||||
return _on_planes[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::add_plane
|
||||
// Function: ClipPlaneAttrib::has_on_plane
|
||||
// Access: Published
|
||||
// Description: Returns a new ClipPlaneAttrib, just like this one, but
|
||||
// with the indicated plane added to the list of planes.
|
||||
// Description: Returns true if the indicated plane is enabled by
|
||||
// the attrib, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
add_plane(PlaneNode *plane) const {
|
||||
if (_operation == O_remove) {
|
||||
return compose(make(O_remove, plane));
|
||||
} else {
|
||||
return compose(make(O_add, plane));
|
||||
}
|
||||
INLINE bool ClipPlaneAttrib::
|
||||
has_on_plane(const NodePath &plane) const {
|
||||
return _on_planes.find(plane) != _on_planes.end();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::remove_plane
|
||||
// Function: ClipPlaneAttrib::get_num_off_planes
|
||||
// Access: Published
|
||||
// Description: Returns a new ClipPlaneAttrib, just like this one, but
|
||||
// with the indicated plane removed from the list of
|
||||
// planes.
|
||||
// Description: Returns the number of planes that are disabled by
|
||||
// the attribute.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
remove_plane(PlaneNode *plane) const {
|
||||
if (_operation == O_remove) {
|
||||
return compose(make(O_add, plane));
|
||||
} else {
|
||||
return compose(make(O_remove, plane));
|
||||
}
|
||||
INLINE int ClipPlaneAttrib::
|
||||
get_num_off_planes() const {
|
||||
return _off_planes.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::get_off_plane
|
||||
// Access: Published
|
||||
// Description: Returns the nth plane disabled by the attribute,
|
||||
// sorted in arbitrary (pointer) order.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodePath ClipPlaneAttrib::
|
||||
get_off_plane(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_off_planes.size(), NodePath::fail());
|
||||
return _off_planes[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::has_off_plane
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated plane is disabled by
|
||||
// the attrib, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ClipPlaneAttrib::
|
||||
has_off_plane(const NodePath &plane) const {
|
||||
return _off_planes.find(plane) != _off_planes.end() ||
|
||||
(_off_all_planes && !has_on_plane(plane));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::has_all_off
|
||||
// Access: Published
|
||||
// Description: Returns true if this attrib disables all planes
|
||||
// (although it may also enable some).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ClipPlaneAttrib::
|
||||
has_all_off() const {
|
||||
return _off_all_planes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -104,16 +131,5 @@ remove_plane(PlaneNode *plane) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ClipPlaneAttrib::
|
||||
is_identity() const {
|
||||
return _operation != O_set && _planes.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::is_all_off
|
||||
// Access: Published
|
||||
// Description: Returns true if this attrib turns off all planes and
|
||||
// turns none on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ClipPlaneAttrib::
|
||||
is_all_off() const {
|
||||
return _operation == O_set && _planes.empty();
|
||||
return _on_planes.empty() && _off_planes.empty() && !_off_all_planes;
|
||||
}
|
||||
|
@ -24,33 +24,42 @@
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::_empty_attrib;
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::_all_off_attrib;
|
||||
TypeHandle ClipPlaneAttrib::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::make_all_off
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new ClipPlaneAttrib object that turns off
|
||||
// all planes (and hence disables planeing).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
make_all_off() {
|
||||
ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
|
||||
attrib->_operation = O_set;
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new ClipPlaneAttrib object that turns on (or
|
||||
// off, according to op) the indicate plane(s).
|
||||
// Description: Constructs a new ClipPlaneAttrib object that enables (or
|
||||
// disables, according to op) the indicated plane(s).
|
||||
//
|
||||
// This method is now deprecated. Use add_on_plane() or
|
||||
// add_off_plane() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
make(ClipPlaneAttrib::Operation op, PlaneNode *plane) {
|
||||
ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
|
||||
attrib->_operation = op;
|
||||
attrib->_planes.push_back(plane);
|
||||
return return_new(attrib);
|
||||
CPT(RenderAttrib) attrib;
|
||||
|
||||
switch (op) {
|
||||
case O_set:
|
||||
attrib = make_all_off();
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane));
|
||||
return attrib;
|
||||
|
||||
case O_add:
|
||||
attrib = make();
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane));
|
||||
return attrib;
|
||||
|
||||
case O_remove:
|
||||
attrib = make();
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane));
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
return make();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -58,16 +67,36 @@ make(ClipPlaneAttrib::Operation op, PlaneNode *plane) {
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new ClipPlaneAttrib object that turns on (or
|
||||
// off, according to op) the indicate plane(s).
|
||||
//
|
||||
// This method is now deprecated. Use add_on_plane() or
|
||||
// add_off_plane() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2) {
|
||||
ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
|
||||
attrib->_operation = op;
|
||||
attrib->_planes.push_back(plane1);
|
||||
attrib->_planes.push_back(plane2);
|
||||
CPT(RenderAttrib) attrib;
|
||||
|
||||
attrib->_planes.sort();
|
||||
return return_new(attrib);
|
||||
switch (op) {
|
||||
case O_set:
|
||||
attrib = make_all_off();
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane1));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane2));
|
||||
return attrib;
|
||||
|
||||
case O_add:
|
||||
attrib = make();
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane1));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane2));
|
||||
return attrib;
|
||||
|
||||
case O_remove:
|
||||
attrib = make();
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane1));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane2));
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
return make();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -75,18 +104,40 @@ make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2) {
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new ClipPlaneAttrib object that turns on (or
|
||||
// off, according to op) the indicate plane(s).
|
||||
//
|
||||
// This method is now deprecated. Use add_on_plane() or
|
||||
// add_off_plane() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2,
|
||||
PlaneNode *plane3) {
|
||||
ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
|
||||
attrib->_operation = op;
|
||||
attrib->_planes.push_back(plane1);
|
||||
attrib->_planes.push_back(plane2);
|
||||
attrib->_planes.push_back(plane3);
|
||||
CPT(RenderAttrib) attrib;
|
||||
|
||||
attrib->_planes.sort();
|
||||
return return_new(attrib);
|
||||
switch (op) {
|
||||
case O_set:
|
||||
attrib = make_all_off();
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane1));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane2));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane3));
|
||||
return attrib;
|
||||
|
||||
case O_add:
|
||||
attrib = make();
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane1));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane2));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane3));
|
||||
return attrib;
|
||||
|
||||
case O_remove:
|
||||
attrib = make();
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane1));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane2));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane3));
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
return make();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -94,19 +145,110 @@ make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2,
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new ClipPlaneAttrib object that turns on (or
|
||||
// off, according to op) the indicate plane(s).
|
||||
//
|
||||
// This method is now deprecated. Use add_on_plane() or
|
||||
// add_off_plane() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2,
|
||||
PlaneNode *plane3, PlaneNode *plane4) {
|
||||
ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
|
||||
attrib->_operation = op;
|
||||
attrib->_planes.push_back(plane1);
|
||||
attrib->_planes.push_back(plane2);
|
||||
attrib->_planes.push_back(plane3);
|
||||
attrib->_planes.push_back(plane4);
|
||||
CPT(RenderAttrib) attrib;
|
||||
|
||||
attrib->_planes.sort();
|
||||
return return_new(attrib);
|
||||
switch (op) {
|
||||
case O_set:
|
||||
attrib = make_all_off();
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane1));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane2));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane3));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane4));
|
||||
return attrib;
|
||||
|
||||
case O_add:
|
||||
attrib = make();
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane1));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane2));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane3));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane4));
|
||||
return attrib;
|
||||
|
||||
case O_remove:
|
||||
attrib = make();
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane1));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane2));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane3));
|
||||
attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane4));
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
return make();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::get_operation
|
||||
// Access: Published
|
||||
// Description: Returns the basic operation type of the ClipPlaneAttrib.
|
||||
// If this is O_set, the planes listed here completely
|
||||
// replace any planes that were already on. If this is
|
||||
// O_add, the planes here are added to the set of of
|
||||
// planes that were already on, and if O_remove, the
|
||||
// planes here are removed from the set of planes that
|
||||
// were on.
|
||||
//
|
||||
// This method is now deprecated. ClipPlaneAttribs
|
||||
// nowadays have a separate list of on_planes and
|
||||
// off_planes, so this method doesn't make sense. Query
|
||||
// the lists independently.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ClipPlaneAttrib::Operation ClipPlaneAttrib::
|
||||
get_operation() const {
|
||||
if (has_all_off()) {
|
||||
return O_set;
|
||||
|
||||
} else if (get_num_off_planes() == 0) {
|
||||
return O_add;
|
||||
|
||||
} else {
|
||||
return O_remove;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::get_num_planes
|
||||
// Access: Published
|
||||
// Description: Returns the number of planes listed in the attribute.
|
||||
//
|
||||
// This method is now deprecated. ClipPlaneAttribs
|
||||
// nowadays have a separate list of on_planes and
|
||||
// off_planes, so this method doesn't make sense. Query
|
||||
// the lists independently.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ClipPlaneAttrib::
|
||||
get_num_planes() const {
|
||||
if (get_num_off_planes() == 0) {
|
||||
return get_num_on_planes();
|
||||
} else {
|
||||
return get_num_off_planes();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::get_plane
|
||||
// Access: Published
|
||||
// Description: Returns the nth plane listed in the attribute.
|
||||
//
|
||||
// This method is now deprecated. ClipPlaneAttribs
|
||||
// nowadays have a separate list of on_planes and
|
||||
// off_planes, so this method doesn't make sense. Query
|
||||
// the lists independently.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PlaneNode *ClipPlaneAttrib::
|
||||
get_plane(int n) const {
|
||||
if (get_num_off_planes() == 0) {
|
||||
return DCAST(PlaneNode, get_on_plane(n).node());
|
||||
} else {
|
||||
return DCAST(PlaneNode, get_off_plane(n).node());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -114,10 +256,164 @@ make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2,
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated plane is listed in the
|
||||
// attrib, false otherwise.
|
||||
//
|
||||
// This method is now deprecated. ClipPlaneAttribs
|
||||
// nowadays have a separate list of on_planes and
|
||||
// off_planes, so this method doesn't make sense. Query
|
||||
// the lists independently.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ClipPlaneAttrib::
|
||||
has_plane(PlaneNode *plane) const {
|
||||
return _planes.find(plane) != _planes.end();
|
||||
if (get_num_off_planes() == 0) {
|
||||
return has_on_plane(NodePath(plane));
|
||||
} else {
|
||||
return has_off_plane(NodePath(plane));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::add_plane
|
||||
// Access: Published
|
||||
// Description: Returns a new ClipPlaneAttrib, just like this one, but
|
||||
// with the indicated plane added to the list of planes.
|
||||
//
|
||||
// This method is now deprecated. Use add_on_plane() or
|
||||
// add_off_plane() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
add_plane(PlaneNode *plane) const {
|
||||
if (get_num_off_planes() == 0) {
|
||||
return add_on_plane(NodePath(plane));
|
||||
} else {
|
||||
return add_off_plane(NodePath(plane));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::remove_plane
|
||||
// Access: Published
|
||||
// Description: Returns a new ClipPlaneAttrib, just like this one, but
|
||||
// with the indicated plane removed from the list of
|
||||
// planes.
|
||||
//
|
||||
// This method is now deprecated. Use remove_on_plane()
|
||||
// or remove_off_plane() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
remove_plane(PlaneNode *plane) const {
|
||||
if (get_num_off_planes() == 0) {
|
||||
return remove_on_plane(NodePath(plane));
|
||||
} else {
|
||||
return remove_off_plane(NodePath(plane));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new ClipPlaneAttrib object that does
|
||||
// nothing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
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 ClipPlaneAttrib);
|
||||
}
|
||||
|
||||
return _empty_attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::make_all_off
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new ClipPlaneAttrib object that disables
|
||||
// all planes (and hence disables clipping).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
make_all_off() {
|
||||
// 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) {
|
||||
ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
|
||||
attrib->_off_all_planes = true;
|
||||
_all_off_attrib = return_new(attrib);
|
||||
}
|
||||
|
||||
return _all_off_attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::add_on_plane
|
||||
// Access: Published
|
||||
// Description: Returns a new ClipPlaneAttrib, just like this one, but
|
||||
// with the indicated plane added to the list of planes
|
||||
// enabled by this attrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
add_on_plane(const NodePath &plane) const {
|
||||
nassertr(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type()), this);
|
||||
ClipPlaneAttrib *attrib = new ClipPlaneAttrib(*this);
|
||||
attrib->_on_planes.insert(plane);
|
||||
attrib->_off_planes.erase(plane);
|
||||
|
||||
pair<Planes::iterator, bool> insert_result =
|
||||
attrib->_on_planes.insert(Planes::value_type(plane));
|
||||
if (insert_result.second) {
|
||||
// Also ensure it is removed from the off_planes list.
|
||||
attrib->_off_planes.erase(plane);
|
||||
}
|
||||
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::remove_on_plane
|
||||
// Access: Published
|
||||
// Description: Returns a new ClipPlaneAttrib, just like this one, but
|
||||
// with the indicated plane removed from the list of
|
||||
// planes enabled by this attrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
remove_on_plane(const NodePath &plane) const {
|
||||
nassertr(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type()), this);
|
||||
ClipPlaneAttrib *attrib = new ClipPlaneAttrib(*this);
|
||||
attrib->_on_planes.erase(plane);
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::add_off_plane
|
||||
// Access: Published
|
||||
// Description: Returns a new ClipPlaneAttrib, just like this one, but
|
||||
// with the indicated plane added to the list of planes
|
||||
// disabled by this attrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
add_off_plane(const NodePath &plane) const {
|
||||
nassertr(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type()), this);
|
||||
ClipPlaneAttrib *attrib = new ClipPlaneAttrib(*this);
|
||||
if (!_off_all_planes) {
|
||||
attrib->_off_planes.insert(plane);
|
||||
}
|
||||
attrib->_on_planes.erase(plane);
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::remove_off_plane
|
||||
// Access: Published
|
||||
// Description: Returns a new ClipPlaneAttrib, just like this one, but
|
||||
// with the indicated plane removed from the list of
|
||||
// planes disabled by this attrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
remove_off_plane(const NodePath &plane) const {
|
||||
nassertr(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type()), this);
|
||||
ClipPlaneAttrib *attrib = new ClipPlaneAttrib(*this);
|
||||
attrib->_off_planes.erase(plane);
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -142,26 +438,38 @@ issue(GraphicsStateGuardianBase *gsg) const {
|
||||
void ClipPlaneAttrib::
|
||||
output(ostream &out) const {
|
||||
out << get_type() << ":";
|
||||
if (_operation == O_set && _planes.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_planes.empty()) {
|
||||
if (_on_planes.empty()) {
|
||||
if (_off_all_planes) {
|
||||
out << "all off";
|
||||
} else {
|
||||
out << "identity";
|
||||
}
|
||||
} else {
|
||||
if (_off_all_planes) {
|
||||
out << "set";
|
||||
} else {
|
||||
out << "on";
|
||||
}
|
||||
}
|
||||
|
||||
Planes::const_iterator li;
|
||||
for (li = _planes.begin(); li != _planes.end(); ++li) {
|
||||
PlaneNode *plane = (*li);
|
||||
out << " " << *plane;
|
||||
} else {
|
||||
out << "off";
|
||||
Planes::const_iterator fi;
|
||||
for (fi = _off_planes.begin(); fi != _off_planes.end(); ++fi) {
|
||||
NodePath plane = (*fi);
|
||||
out << " " << plane;
|
||||
}
|
||||
|
||||
if (!_on_planes.empty()) {
|
||||
out << " on";
|
||||
}
|
||||
}
|
||||
|
||||
Planes::const_iterator li;
|
||||
for (li = _on_planes.begin(); li != _on_planes.end(); ++li) {
|
||||
NodePath plane = (*li);
|
||||
out << " " << plane;
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,10 +480,10 @@ output(ostream &out) const {
|
||||
// types to return a unique number indicating whether
|
||||
// this ClipPlaneAttrib is equivalent to the other one.
|
||||
//
|
||||
// This should return 0 if the two ClipPlaneAttrib 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 should return 0 if the two ClipPlaneAttrib
|
||||
// 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 ClipPlaneAttrib
|
||||
// objects whose get_type() functions return the same.
|
||||
@ -185,29 +493,53 @@ compare_to_impl(const RenderAttrib *other) const {
|
||||
const ClipPlaneAttrib *ta;
|
||||
DCAST_INTO_R(ta, other, 0);
|
||||
|
||||
if (_operation != ta->_operation) {
|
||||
return (int)_operation - (int)ta->_operation;
|
||||
if (_off_all_planes != ta->_off_all_planes) {
|
||||
return (int)_off_all_planes - (int)ta->_off_all_planes;
|
||||
}
|
||||
|
||||
Planes::const_iterator li = _planes.begin();
|
||||
Planes::const_iterator oli = ta->_planes.begin();
|
||||
Planes::const_iterator li = _on_planes.begin();
|
||||
Planes::const_iterator oli = ta->_on_planes.begin();
|
||||
|
||||
while (li != _planes.end() && oli != ta->_planes.end()) {
|
||||
PlaneNode *plane = (*li);
|
||||
PlaneNode *other_plane = (*oli);
|
||||
while (li != _on_planes.end() && oli != ta->_on_planes.end()) {
|
||||
NodePath plane = (*li);
|
||||
NodePath other_plane = (*oli);
|
||||
|
||||
if (plane != other_plane) {
|
||||
return plane < other_plane ? -1 : 1;
|
||||
int compare = plane.compare_to(other_plane);
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
|
||||
++li;
|
||||
++oli;
|
||||
}
|
||||
|
||||
if (li != _planes.end()) {
|
||||
if (li != _on_planes.end()) {
|
||||
return 1;
|
||||
}
|
||||
if (oli != ta->_planes.end()) {
|
||||
if (oli != ta->_on_planes.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Planes::const_iterator fi = _off_planes.begin();
|
||||
Planes::const_iterator ofi = ta->_off_planes.begin();
|
||||
|
||||
while (fi != _off_planes.end() && ofi != ta->_off_planes.end()) {
|
||||
NodePath plane = (*fi);
|
||||
NodePath other_plane = (*ofi);
|
||||
|
||||
int compare = plane.compare_to(other_plane);
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
|
||||
++fi;
|
||||
++ofi;
|
||||
}
|
||||
|
||||
if (fi != _off_planes.end()) {
|
||||
return 1;
|
||||
}
|
||||
if (ofi != ta->_off_planes.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -236,29 +568,121 @@ compose_impl(const RenderAttrib *other) const {
|
||||
const ClipPlaneAttrib *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_planes) {
|
||||
// If the other type turns off all planes, 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.
|
||||
Planes::const_iterator ai = _on_planes.begin();
|
||||
Planes::const_iterator bi = ta->_on_planes.begin();
|
||||
Planes::const_iterator ci = ta->_off_planes.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 ClipPlaneAttrib that will hold the result.
|
||||
ClipPlaneAttrib *new_attrib = new ClipPlaneAttrib;
|
||||
back_insert_iterator<Planes> result =
|
||||
back_inserter(new_attrib->_on_planes);
|
||||
|
||||
} else if (_operation == O_remove) {
|
||||
// If our type is remove, then the other one wins.
|
||||
return ta;
|
||||
while (ai != _on_planes.end() &&
|
||||
bi != ta->_on_planes.end() &&
|
||||
ci != ta->_off_planes.end()) {
|
||||
if ((*ai) < (*bi)) {
|
||||
if ((*ai) < (*ci)) {
|
||||
// Here is a plane 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 plane that is disabled in the secondary, but
|
||||
// was not present in the original.
|
||||
++ci;
|
||||
|
||||
} else { // (*ci) == (*ai)
|
||||
// Here is a plane that is disabled in the secondary, and
|
||||
// was present in the original.
|
||||
++ai;
|
||||
++ci;
|
||||
}
|
||||
|
||||
} else if ((*bi) < (*ai)) {
|
||||
// Here is a new plane we have in the secondary, that was not
|
||||
// present in the original.
|
||||
*result = *bi;
|
||||
++bi;
|
||||
++result;
|
||||
|
||||
} else { // (*bi) == (*ai)
|
||||
// Here is a plane we have in both.
|
||||
*result = *bi;
|
||||
++ai;
|
||||
++bi;
|
||||
++result;
|
||||
}
|
||||
}
|
||||
|
||||
while (ai != _on_planes.end() && bi != ta->_on_planes.end()) {
|
||||
if ((*ai) < (*bi)) {
|
||||
// Here is a plane 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 plane we have in the secondary, that was not
|
||||
// present in the original.
|
||||
*result = *bi;
|
||||
++bi;
|
||||
++result;
|
||||
|
||||
} else {
|
||||
// Here is a plane we have in both.
|
||||
*result = *bi;
|
||||
++ai;
|
||||
++bi;
|
||||
++result;
|
||||
}
|
||||
}
|
||||
|
||||
while (ai != _on_planes.end() && ci != ta->_off_planes.end()) {
|
||||
if ((*ai) < (*ci)) {
|
||||
// Here is a plane that we have in the original, which is not
|
||||
// present in the secondary.
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++result;
|
||||
|
||||
} else if ((*ci) < (*ai)) {
|
||||
// Here is a plane that is disabled in the secondary, but
|
||||
// was not present in the original.
|
||||
++ci;
|
||||
|
||||
} else { // (*ci) == (*ai)
|
||||
// Here is a plane that is disabled in the secondary, and
|
||||
// was present in the original.
|
||||
++ai;
|
||||
++ci;
|
||||
}
|
||||
}
|
||||
|
||||
while (ai != _on_planes.end()) {
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++result;
|
||||
}
|
||||
|
||||
while (bi != ta->_on_planes.end()) {
|
||||
*result = *bi;
|
||||
++bi;
|
||||
++result;
|
||||
}
|
||||
|
||||
return return_new(new_attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -294,106 +718,6 @@ make_default_impl() const {
|
||||
return new ClipPlaneAttrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::do_add
|
||||
// Access: Private
|
||||
// Description: Returns a new ClipPlaneAttrib that represents all the
|
||||
// planes of this attrib, with those of the other one
|
||||
// added in.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
do_add(const ClipPlaneAttrib *other, ClipPlaneAttrib::Operation op) const {
|
||||
Planes::const_iterator ai = _planes.begin();
|
||||
Planes::const_iterator bi = other->_planes.begin();
|
||||
|
||||
// Create a new ClipPlaneAttrib that will hold the result.
|
||||
ClipPlaneAttrib *new_attrib = new ClipPlaneAttrib;
|
||||
new_attrib->_operation = op;
|
||||
back_insert_iterator<Planes> result =
|
||||
back_inserter(new_attrib->_planes);
|
||||
|
||||
while (ai != _planes.end() && bi != other->_planes.end()) {
|
||||
if ((*ai) < (*bi)) {
|
||||
// Here is a plane 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 plane we have in the secondary, that was not
|
||||
// present in the original.
|
||||
*result = *bi;
|
||||
++bi;
|
||||
++result;
|
||||
} else {
|
||||
// Here is a plane we have in both.
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++bi;
|
||||
++result;
|
||||
}
|
||||
}
|
||||
|
||||
while (ai != _planes.end()) {
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++result;
|
||||
}
|
||||
|
||||
while (bi != other->_planes.end()) {
|
||||
*result = *bi;
|
||||
++bi;
|
||||
++result;
|
||||
}
|
||||
|
||||
return return_new(new_attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::do_remove
|
||||
// Access: Private
|
||||
// Description: Returns a new ClipPlaneAttrib that represents all the
|
||||
// planes of this attrib, with those of the other one
|
||||
// removed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ClipPlaneAttrib::
|
||||
do_remove(const ClipPlaneAttrib *other, ClipPlaneAttrib::Operation op) const {
|
||||
Planes::const_iterator ai = _planes.begin();
|
||||
Planes::const_iterator bi = other->_planes.begin();
|
||||
|
||||
// Create a new ClipPlaneAttrib that will hold the result.
|
||||
ClipPlaneAttrib *new_attrib = new ClipPlaneAttrib;
|
||||
new_attrib->_operation = op;
|
||||
back_insert_iterator<Planes> result =
|
||||
back_inserter(new_attrib->_planes);
|
||||
|
||||
while (ai != _planes.end() && bi != other->_planes.end()) {
|
||||
if ((*ai) < (*bi)) {
|
||||
// Here is a plane 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 plane we have in the secondary, that was
|
||||
// not present in the original. Ignore it.
|
||||
++bi;
|
||||
} else {
|
||||
// Here is a plane we have in both. Drop it.
|
||||
++ai;
|
||||
++bi;
|
||||
}
|
||||
}
|
||||
|
||||
while (ai != _planes.end()) {
|
||||
*result = *ai;
|
||||
++ai;
|
||||
++result;
|
||||
}
|
||||
|
||||
return return_new(new_attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
@ -415,15 +739,26 @@ void ClipPlaneAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
|
||||
dg.add_int8((int)_operation);
|
||||
PN_uint16 num_planes = _planes.size();
|
||||
nassertv(num_planes == _planes.size());
|
||||
dg.add_uint16(num_planes);
|
||||
dg.add_bool(_off_all_planes);
|
||||
|
||||
Planes::const_iterator li;
|
||||
for (li = _planes.begin(); li != _planes.end(); ++li) {
|
||||
PlaneNode *plane = (*li);
|
||||
manager->write_pointer(dg, plane);
|
||||
// write the number of off_planes
|
||||
dg.add_uint16(get_num_off_planes());
|
||||
// write the off planes pointers if any
|
||||
Planes::const_iterator fi;
|
||||
for (fi = _off_planes.begin(); fi != _off_planes.end(); ++fi) {
|
||||
NodePath plane = (*fi);
|
||||
|
||||
// Whoops, we don't have a way to write out a NodePath right now.
|
||||
manager->write_pointer(dg, plane.node());
|
||||
}
|
||||
|
||||
// write the number of on planes
|
||||
dg.add_uint16(get_num_on_planes());
|
||||
// write the on planes pointers if any
|
||||
Planes::const_iterator nti;
|
||||
for (nti = _on_planes.begin(); nti != _on_planes.end(); ++nti) {
|
||||
NodePath plane = (*nti);
|
||||
manager->write_pointer(dg, plane.node());
|
||||
}
|
||||
}
|
||||
|
||||
@ -438,11 +773,22 @@ int ClipPlaneAttrib::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = RenderAttrib::complete_pointers(p_list, manager);
|
||||
|
||||
Planes::iterator li;
|
||||
for (li = _planes.begin(); li != _planes.end(); ++li) {
|
||||
PlaneNode *node;
|
||||
Planes::iterator ci = _off_planes.begin();
|
||||
while (ci != _off_planes.end()) {
|
||||
PandaNode *node;
|
||||
DCAST_INTO_R(node, p_list[pi++], pi);
|
||||
(*li) = node;
|
||||
NodePath np(node);
|
||||
(*ci) = np;
|
||||
++ci;
|
||||
}
|
||||
|
||||
ci = _on_planes.begin();
|
||||
while (ci != _on_planes.end()) {
|
||||
PandaNode *node;
|
||||
DCAST_INTO_R(node, p_list[pi++], pi);
|
||||
NodePath np(node);
|
||||
(*ci) = np;
|
||||
++ci;
|
||||
}
|
||||
|
||||
return pi;
|
||||
@ -479,11 +825,31 @@ void ClipPlaneAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
|
||||
_operation = (Operation)scan.get_int8();
|
||||
int num_planes = 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
|
||||
// ClipPlaneAttribs, 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 ClipPlaneAttribs, and
|
||||
// hence no old bam files have the old definition for ClipPlaneAttrib
|
||||
// within them.
|
||||
|
||||
for (int i = 0; i < num_planes; i++) {
|
||||
_off_all_planes = scan.get_bool();
|
||||
|
||||
int num_off_planes = scan.get_uint16();
|
||||
|
||||
// Push back a NULL pointer for each off Plane for now, until
|
||||
// we get the actual list of pointers later in complete_pointers().
|
||||
_off_planes.reserve(num_off_planes);
|
||||
int i;
|
||||
for (i = 0; i < num_off_planes; i++) {
|
||||
manager->read_pointer(scan);
|
||||
_planes.push_back(NULL);
|
||||
_off_planes.push_back(NULL);
|
||||
}
|
||||
|
||||
int num_on_planes = scan.get_uint16();
|
||||
_on_planes.reserve(num_on_planes);
|
||||
for (i = 0; i < num_on_planes; i++) {
|
||||
manager->read_pointer(scan);
|
||||
_on_planes.push_back(NULL);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "planeNode.h"
|
||||
#include "renderAttrib.h"
|
||||
#include "ordered_vector.h"
|
||||
#include "nodePath.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ClipPlaneAttrib
|
||||
@ -36,15 +37,19 @@
|
||||
class EXPCL_PANDA ClipPlaneAttrib : public RenderAttrib {
|
||||
private:
|
||||
INLINE ClipPlaneAttrib();
|
||||
INLINE ClipPlaneAttrib(const ClipPlaneAttrib ©);
|
||||
|
||||
PUBLISHED:
|
||||
|
||||
// This is the old, deprecated interface to ClipPlaneAttrib. 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,
|
||||
PlaneNode *plane);
|
||||
static CPT(RenderAttrib) make(Operation op,
|
||||
@ -65,8 +70,27 @@ PUBLISHED:
|
||||
INLINE CPT(RenderAttrib) add_plane(PlaneNode *plane) const;
|
||||
INLINE CPT(RenderAttrib) remove_plane(PlaneNode *plane) const;
|
||||
|
||||
|
||||
// The following is the new, more general interface to the
|
||||
// ClipPlaneAttrib.
|
||||
static CPT(RenderAttrib) make();
|
||||
static CPT(RenderAttrib) make_all_off();
|
||||
|
||||
INLINE int get_num_on_planes() const;
|
||||
INLINE NodePath get_on_plane(int n) const;
|
||||
INLINE bool has_on_plane(const NodePath &plane) const;
|
||||
|
||||
INLINE int get_num_off_planes() const;
|
||||
INLINE NodePath get_off_plane(int n) const;
|
||||
INLINE bool has_off_plane(const NodePath &plane) const;
|
||||
INLINE bool has_all_off() const;
|
||||
|
||||
INLINE bool is_identity() const;
|
||||
INLINE bool is_all_off() const;
|
||||
|
||||
CPT(RenderAttrib) add_on_plane(const NodePath &plane) const;
|
||||
CPT(RenderAttrib) remove_on_plane(const NodePath &plane) const;
|
||||
CPT(RenderAttrib) add_off_plane(const NodePath &plane) const;
|
||||
CPT(RenderAttrib) remove_off_plane(const NodePath &plane) const;
|
||||
|
||||
public:
|
||||
virtual void issue(GraphicsStateGuardianBase *gsg) const;
|
||||
@ -79,13 +103,12 @@ protected:
|
||||
virtual RenderAttrib *make_default_impl() const;
|
||||
|
||||
private:
|
||||
CPT(RenderAttrib) do_add(const ClipPlaneAttrib *other, Operation op) const;
|
||||
CPT(RenderAttrib) do_remove(const ClipPlaneAttrib *other, Operation op) const;
|
||||
typedef ov_set<NodePath> Planes;
|
||||
Planes _on_planes, _off_planes;
|
||||
bool _off_all_planes;
|
||||
|
||||
private:
|
||||
Operation _operation;
|
||||
typedef ov_set< PT(PlaneNode) > Planes;
|
||||
Planes _planes;
|
||||
static CPT(RenderAttrib) _empty_attrib;
|
||||
static CPT(RenderAttrib) _all_off_attrib;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
@ -509,6 +509,149 @@ get_net_state() const {
|
||||
return r_get_net_state(_head);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_attrib
|
||||
// Access: Published
|
||||
// Description: Adds the indicated render attribute to the scene
|
||||
// graph on this node. This attribute will now apply to
|
||||
// this node and everything below. If there was already
|
||||
// an attribute of the same type, it is replaced.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
set_attrib(const RenderAttrib *attrib, int priority) {
|
||||
nassertv_always(!is_empty());
|
||||
node()->set_attrib(attrib, priority);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_attrib
|
||||
// Access: Published
|
||||
// Description: Returns the render attribute of the indicated type,
|
||||
// if it is defined on the node, or NULL if it is not.
|
||||
// This checks only what is set on this particular node
|
||||
// level, and has nothing to do with what render
|
||||
// attributes may be inherited from parent nodes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const RenderAttrib *NodePath::
|
||||
get_attrib(TypeHandle type) const {
|
||||
nassertr_always(!is_empty(), NULL);
|
||||
return node()->get_attrib(type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::has_attrib
|
||||
// Access: Published
|
||||
// Description: Returns true if there is a render attribute of the
|
||||
// indicated type defined on this node, or false if
|
||||
// there is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodePath::
|
||||
has_attrib(TypeHandle type) const {
|
||||
nassertr_always(!is_empty(), false);
|
||||
return node()->has_attrib(type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::clear_attrib
|
||||
// Access: Published
|
||||
// Description: Removes the render attribute of the given type from
|
||||
// this node. This node, and the subgraph below, will
|
||||
// now inherit the indicated render attribute from the
|
||||
// nodes above this one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
clear_attrib(TypeHandle type) {
|
||||
nassertv_always(!is_empty());
|
||||
node()->clear_attrib(type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_effect
|
||||
// Access: Published
|
||||
// Description: Adds the indicated render effect to the scene
|
||||
// graph on this node. If there was already an effect
|
||||
// of the same type, it is replaced.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
set_effect(const RenderEffect *effect) {
|
||||
nassertv_always(!is_empty());
|
||||
node()->set_effect(effect);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_effect
|
||||
// Access: Published
|
||||
// Description: Returns the render effect of the indicated type,
|
||||
// if it is defined on the node, or NULL if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const RenderEffect *NodePath::
|
||||
get_effect(TypeHandle type) const {
|
||||
nassertr_always(!is_empty(), NULL);
|
||||
return node()->get_effect(type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::has_effect
|
||||
// Access: Published
|
||||
// Description: Returns true if there is a render effect of the
|
||||
// indicated type defined on this node, or false if
|
||||
// there is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodePath::
|
||||
has_effect(TypeHandle type) const {
|
||||
nassertr_always(!is_empty(), false);
|
||||
return node()->has_effect(type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::clear_effect
|
||||
// Access: Published
|
||||
// Description: Removes the render effect of the given type from
|
||||
// this node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
clear_effect(TypeHandle type) {
|
||||
nassertv_always(!is_empty());
|
||||
node()->clear_effect(type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_effects
|
||||
// Access: Published
|
||||
// Description: Sets the complete RenderEffects that will be applied
|
||||
// this node. This completely replaces whatever has
|
||||
// been set on this node via repeated calls to
|
||||
// set_attrib().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
set_effects(const RenderEffects *effects) {
|
||||
nassertv_always(!is_empty());
|
||||
node()->set_effects(effects);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_effects
|
||||
// Access: Published
|
||||
// Description: Returns the complete RenderEffects that will be
|
||||
// applied to this node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const RenderEffects *NodePath::
|
||||
get_effects() const {
|
||||
nassertr_always(!is_empty(), RenderEffects::make_empty());
|
||||
return node()->get_effects();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::clear_effects
|
||||
// Access: Published
|
||||
// Description: Resets this node to have no render effects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
clear_effects() {
|
||||
nassertv_always(!is_empty());
|
||||
node()->clear_effects();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_transform
|
||||
// Access: Published
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "texMatrixAttrib.h"
|
||||
#include "materialAttrib.h"
|
||||
#include "lightAttrib.h"
|
||||
#include "clipPlaneAttrib.h"
|
||||
#include "polylightEffect.h"
|
||||
#include "fogAttrib.h"
|
||||
#include "renderModeAttrib.h"
|
||||
@ -41,6 +42,7 @@
|
||||
#include "transparencyAttrib.h"
|
||||
#include "antialiasAttrib.h"
|
||||
#include "texProjectorEffect.h"
|
||||
#include "planeNode.h"
|
||||
#include "lensNode.h"
|
||||
#include "materialPool.h"
|
||||
#include "look_at.h"
|
||||
@ -2286,7 +2288,7 @@ set_light_off(int 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
|
||||
// without using 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()
|
||||
@ -2472,6 +2474,214 @@ has_light_off(const NodePath &light) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_clip_plane
|
||||
// Access: Published
|
||||
// Description: Adds the indicated clipping plane to the list of
|
||||
// planes that apply to geometry at this node and below.
|
||||
// The clipping plane itself, a PlaneNode, should be
|
||||
// parented into the scene graph elsewhere, to represent
|
||||
// the plane's position in space; but until
|
||||
// set_clip_plane() is called it will clip no geometry.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_clip_plane(const NodePath &clip_plane, int priority) {
|
||||
nassertv_always(!is_empty());
|
||||
if (!clip_plane.is_empty() && clip_plane.node()->is_of_type(PlaneNode::get_class_type())) {
|
||||
const RenderAttrib *attrib =
|
||||
node()->get_attrib(ClipPlaneAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
priority = max(priority,
|
||||
node()->get_state()->get_override(ClipPlaneAttrib::get_class_type()));
|
||||
const ClipPlaneAttrib *la = DCAST(ClipPlaneAttrib, attrib);
|
||||
|
||||
// Modify the existing ClipPlaneAttrib to add the indicated
|
||||
// clip_plane.
|
||||
node()->set_attrib(la->add_on_plane(clip_plane), priority);
|
||||
|
||||
} else {
|
||||
// Create a new ClipPlaneAttrib for this node.
|
||||
CPT(ClipPlaneAttrib) la = DCAST(ClipPlaneAttrib, ClipPlaneAttrib::make());
|
||||
node()->set_attrib(la->add_on_plane(clip_plane), priority);
|
||||
}
|
||||
return;
|
||||
}
|
||||
nassert_raise("Not a PlaneNode object.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_clip_plane_off
|
||||
// Access: Published
|
||||
// Description: Sets the geometry at this level and below to render
|
||||
// using no clip_planes at all. This is different
|
||||
// from not specifying a clip_plane; rather, this
|
||||
// specifically contradicts set_clip_plane() at a higher
|
||||
// node level (or, with a priority, overrides a
|
||||
// set_clip_plane() at a lower level).
|
||||
//
|
||||
// If no clip_planes are in effect on a particular piece
|
||||
// of geometry, that geometry is rendered without being
|
||||
// clipped (other than by the viewing frustum).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_clip_plane_off(int priority) {
|
||||
nassertv_always(!is_empty());
|
||||
node()->set_attrib(ClipPlaneAttrib::make_all_off(), priority);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_clip_plane_off
|
||||
// Access: Published
|
||||
// Description: Sets the geometry at this level and below to render
|
||||
// without being clipped by the indicated PlaneNode.
|
||||
// This is different from not specifying the PlaneNode;
|
||||
// rather, this specifically contradicts
|
||||
// set_clip_plane() at a higher node level (or, with a
|
||||
// priority, overrides a set_clip_plane() at a lower
|
||||
// level).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_clip_plane_off(const NodePath &clip_plane, int priority) {
|
||||
nassertv_always(!is_empty());
|
||||
|
||||
if (!clip_plane.is_empty() && clip_plane.node()->is_of_type(PlaneNode::get_class_type())) {
|
||||
const RenderAttrib *attrib =
|
||||
node()->get_attrib(ClipPlaneAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
priority = max(priority,
|
||||
node()->get_state()->get_override(ClipPlaneAttrib::get_class_type()));
|
||||
const ClipPlaneAttrib *la = DCAST(ClipPlaneAttrib, attrib);
|
||||
|
||||
// Modify the existing ClipPlaneAttrib to add the indicated clip_plane
|
||||
// to the "off" list. This also, incidentally, removes it from
|
||||
// the "on" list if it is there.
|
||||
node()->set_attrib(la->add_off_plane(clip_plane), priority);
|
||||
|
||||
} else {
|
||||
// Create a new ClipPlaneAttrib for this node that turns off the
|
||||
// indicated clip_plane.
|
||||
CPT(ClipPlaneAttrib) la = DCAST(ClipPlaneAttrib, ClipPlaneAttrib::make());
|
||||
node()->set_attrib(la->add_off_plane(clip_plane), priority);
|
||||
}
|
||||
return;
|
||||
}
|
||||
nassert_raise("Not a PlaneNode object.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::clear_clip_plane
|
||||
// Access: Published
|
||||
// Description: Completely removes any clip planes that may have been
|
||||
// set via set_clip_plane() or set_clip_plane_off() from
|
||||
// this particular node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
clear_clip_plane() {
|
||||
nassertv_always(!is_empty());
|
||||
node()->clear_attrib(ClipPlaneAttrib::get_class_type());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::clear_clip_plane
|
||||
// Access: Published
|
||||
// Description: Removes any reference to the indicated clipping plane
|
||||
// from the NodePath.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
clear_clip_plane(const NodePath &clip_plane) {
|
||||
nassertv_always(!is_empty());
|
||||
|
||||
if (!clip_plane.is_empty() && clip_plane.node()->is_of_type(PlaneNode::get_class_type())) {
|
||||
const RenderAttrib *attrib =
|
||||
node()->get_attrib(ClipPlaneAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
CPT(ClipPlaneAttrib) la = DCAST(ClipPlaneAttrib, attrib);
|
||||
la = DCAST(ClipPlaneAttrib, la->remove_on_plane(clip_plane));
|
||||
la = DCAST(ClipPlaneAttrib, la->remove_off_plane(clip_plane));
|
||||
|
||||
if (la->is_identity()) {
|
||||
node()->clear_attrib(ClipPlaneAttrib::get_class_type());
|
||||
|
||||
} else {
|
||||
int priority = node()->get_state()->get_override(ClipPlaneAttrib::get_class_type());
|
||||
node()->set_attrib(la, priority);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
nassert_raise("Not a PlaneNode object.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::has_clip_plane
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated clipping plane has been
|
||||
// specifically applied to this particular node. This
|
||||
// means that someone called set_clip_plane() on this
|
||||
// node with the indicated clip_plane.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodePath::
|
||||
has_clip_plane(const NodePath &clip_plane) const {
|
||||
nassertr_always(!is_empty(), false);
|
||||
|
||||
if (!clip_plane.is_empty() && clip_plane.node()->is_of_type(PlaneNode::get_class_type())) {
|
||||
const RenderAttrib *attrib =
|
||||
node()->get_attrib(ClipPlaneAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
const ClipPlaneAttrib *la = DCAST(ClipPlaneAttrib, attrib);
|
||||
return la->has_on_plane(clip_plane);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
nassert_raise("Not a PlaneNode object.");
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::has_clip_plane_off
|
||||
// Access: Published
|
||||
// Description: Returns true if all clipping planes have been
|
||||
// specifically disabled on this particular node. This
|
||||
// means that someone called set_clip_plane_off() on
|
||||
// this node with no parameters.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodePath::
|
||||
has_clip_plane_off() const {
|
||||
nassertr_always(!is_empty(), false);
|
||||
|
||||
const RenderAttrib *attrib =
|
||||
node()->get_attrib(ClipPlaneAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
const ClipPlaneAttrib *la = DCAST(ClipPlaneAttrib, attrib);
|
||||
return la->has_all_off();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::has_clip_plane_off
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated clipping plane has been
|
||||
// specifically disabled on this particular node. This
|
||||
// means that someone called set_clip_plane_off() on
|
||||
// this node with the indicated clip_plane.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodePath::
|
||||
has_clip_plane_off(const NodePath &clip_plane) const {
|
||||
nassertr_always(!is_empty(), false);
|
||||
if (!clip_plane.is_empty() && clip_plane.node()->is_of_type(PlaneNode::get_class_type())) {
|
||||
const RenderAttrib *attrib =
|
||||
node()->get_attrib(ClipPlaneAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
const ClipPlaneAttrib *la = DCAST(ClipPlaneAttrib, attrib);
|
||||
return la->has_off_plane(clip_plane);
|
||||
}
|
||||
}
|
||||
nassert_raise("Not a PlaneNode object.");
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_bin
|
||||
// Access: Published
|
||||
|
@ -246,6 +246,20 @@ PUBLISHED:
|
||||
void set_state(const NodePath &other, const RenderState *state);
|
||||
INLINE CPT(RenderState) get_net_state() const;
|
||||
|
||||
INLINE void set_attrib(const RenderAttrib *attrib, int priority = 0);
|
||||
INLINE const RenderAttrib *get_attrib(TypeHandle type) const;
|
||||
INLINE bool has_attrib(TypeHandle type) const;
|
||||
INLINE void clear_attrib(TypeHandle type);
|
||||
|
||||
INLINE void set_effect(const RenderEffect *effect);
|
||||
INLINE const RenderEffect *get_effect(TypeHandle type) const;
|
||||
INLINE bool has_effect(TypeHandle type) const;
|
||||
INLINE void clear_effect(TypeHandle type);
|
||||
|
||||
INLINE void set_effects(const RenderEffects *effects);
|
||||
INLINE const RenderEffects *get_effects() const;
|
||||
INLINE void clear_effects();
|
||||
|
||||
INLINE const TransformState *get_transform() const;
|
||||
INLINE void clear_transform();
|
||||
INLINE void set_transform(const TransformState *transform);
|
||||
@ -512,6 +526,15 @@ PUBLISHED:
|
||||
bool has_light_off() const;
|
||||
bool has_light_off(const NodePath &light) const;
|
||||
|
||||
void set_clip_plane(const NodePath &clip_plane, int priority = 0);
|
||||
void set_clip_plane_off(int priority = 0);
|
||||
void set_clip_plane_off(const NodePath &clip_plane, int priority = 0);
|
||||
void clear_clip_plane();
|
||||
void clear_clip_plane(const NodePath &clip_plane);
|
||||
bool has_clip_plane(const NodePath &clip_plane) const;
|
||||
bool has_clip_plane_off() const;
|
||||
bool has_clip_plane_off(const NodePath &clip_plane) const;
|
||||
|
||||
void set_bin(const string &bin_name, int draw_order, int priority = 0);
|
||||
void clear_bin();
|
||||
bool has_bin() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user