|
|
@@ -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;
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
|
|
|
- attrib->_planes.sort();
|
|
|
- return return_new(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;
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
|
|
|
- attrib->_planes.sort();
|
|
|
- return return_new(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;
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
|
|
|
- attrib->_planes.sort();
|
|
|
- return return_new(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,27 +438,39 @@ issue(GraphicsStateGuardianBase *gsg) const {
|
|
|
void ClipPlaneAttrib::
|
|
|
output(ostream &out) const {
|
|
|
out << get_type() << ":";
|
|
|
- if (_operation == O_set && _planes.empty()) {
|
|
|
- out << "all off";
|
|
|
+ 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";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
} else {
|
|
|
- switch (_operation) {
|
|
|
- case O_set:
|
|
|
- out << "set";
|
|
|
- break;
|
|
|
- case O_add:
|
|
|
- out << "add";
|
|
|
- break;
|
|
|
- case O_remove:
|
|
|
- out << "remove";
|
|
|
- break;
|
|
|
+ out << "off";
|
|
|
+ Planes::const_iterator fi;
|
|
|
+ for (fi = _off_planes.begin(); fi != _off_planes.end(); ++fi) {
|
|
|
+ NodePath plane = (*fi);
|
|
|
+ out << " " << plane;
|
|
|
}
|
|
|
|
|
|
- Planes::const_iterator li;
|
|
|
- for (li = _planes.begin(); li != _planes.end(); ++li) {
|
|
|
- PlaneNode *plane = (*li);
|
|
|
- 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,111 +568,115 @@ 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);
|
|
|
-
|
|
|
- } 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);
|
|
|
-
|
|
|
- } else if (_operation == O_remove) {
|
|
|
- // If our type is remove, then the other one wins.
|
|
|
- return ta;
|
|
|
-
|
|
|
- } else {
|
|
|
- // Otherwise, the result is the union.
|
|
|
- return do_add(ta, _operation);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: ClipPlaneAttrib::invert_compose_impl
|
|
|
-// Access: Protected, Virtual
|
|
|
-// Description: Intended to be overridden by derived RenderAttrib
|
|
|
-// types to specify how two consecutive RenderAttrib
|
|
|
-// objects of the same type interact.
|
|
|
-//
|
|
|
-// See invert_compose() and compose_impl().
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-CPT(RenderAttrib) ClipPlaneAttrib::
|
|
|
-invert_compose_impl(const RenderAttrib *other) const {
|
|
|
- // I think in this case the other attrib always wins. Maybe this
|
|
|
- // needs a bit more thought. It's hard to imagine that it's even
|
|
|
- // important to compute this properly.
|
|
|
- return other;
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: ClipPlaneAttrib::make_default_impl
|
|
|
-// Access: Protected, Virtual
|
|
|
-// Description: Intended to be overridden by derived ClipPlaneAttrib
|
|
|
-// types to specify what the default property for a
|
|
|
-// ClipPlaneAttrib of this type should be.
|
|
|
-//
|
|
|
-// This should return a newly-allocated ClipPlaneAttrib of
|
|
|
-// the same type that corresponds to whatever the
|
|
|
-// standard default for this kind of ClipPlaneAttrib is.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-RenderAttrib *ClipPlaneAttrib::
|
|
|
-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();
|
|
|
+ // 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();
|
|
|
|
|
|
// 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);
|
|
|
+ back_inserter(new_attrib->_on_planes);
|
|
|
+
|
|
|
+ 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 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;
|
|
|
|
|
|
- while (ai != _planes.end() && bi != other->_planes.end()) {
|
|
|
+ } 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 = *ai;
|
|
|
+ *result = *bi;
|
|
|
++ai;
|
|
|
++bi;
|
|
|
++result;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- while (ai != _planes.end()) {
|
|
|
+ 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 != other->_planes.end()) {
|
|
|
+ while (bi != ta->_on_planes.end()) {
|
|
|
*result = *bi;
|
|
|
++bi;
|
|
|
++result;
|
|
|
@@ -350,48 +686,36 @@ do_add(const ClipPlaneAttrib *other, ClipPlaneAttrib::Operation op) const {
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-// 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.
|
|
|
+// Function: ClipPlaneAttrib::invert_compose_impl
|
|
|
+// Access: Protected, Virtual
|
|
|
+// Description: Intended to be overridden by derived RenderAttrib
|
|
|
+// types to specify how two consecutive RenderAttrib
|
|
|
+// objects of the same type interact.
|
|
|
+//
|
|
|
+// See invert_compose() and compose_impl().
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
CPT(RenderAttrib) 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;
|
|
|
- }
|
|
|
+invert_compose_impl(const RenderAttrib *other) const {
|
|
|
+ // I think in this case the other attrib always wins. Maybe this
|
|
|
+ // needs a bit more thought. It's hard to imagine that it's even
|
|
|
+ // important to compute this properly.
|
|
|
+ return other;
|
|
|
+}
|
|
|
|
|
|
- return return_new(new_attrib);
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ClipPlaneAttrib::make_default_impl
|
|
|
+// Access: Protected, Virtual
|
|
|
+// Description: Intended to be overridden by derived ClipPlaneAttrib
|
|
|
+// types to specify what the default property for a
|
|
|
+// ClipPlaneAttrib of this type should be.
|
|
|
+//
|
|
|
+// This should return a newly-allocated ClipPlaneAttrib of
|
|
|
+// the same type that corresponds to whatever the
|
|
|
+// standard default for this kind of ClipPlaneAttrib is.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+RenderAttrib *ClipPlaneAttrib::
|
|
|
+make_default_impl() const {
|
|
|
+ return new ClipPlaneAttrib;
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
@@ -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);
|
|
|
+ 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);
|
|
|
- (*li) = node;
|
|
|
+ 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();
|
|
|
-
|
|
|
- for (int i = 0; i < num_planes; i++) {
|
|
|
+ // 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.
|
|
|
+
|
|
|
+ _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);
|
|
|
+ _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);
|
|
|
- _planes.push_back(NULL);
|
|
|
+ _on_planes.push_back(NULL);
|
|
|
}
|
|
|
}
|