add PlaneNode::set_clip_effect

This commit is contained in:
David Rose 2007-05-15 20:44:08 +00:00
parent f89ef1f257
commit 7e08d7b759
6 changed files with 167 additions and 99 deletions

View File

@ -613,12 +613,19 @@ test_intersection_from_line(const CollisionEntry &entry) const {
if (cpa != (ClipPlaneAttrib *)NULL) {
// We have a clip plane; apply it.
Points new_points;
apply_clip_plane(new_points, cpa, entry.get_into_node_path().get_net_transform());
if (new_points.size() < 3) {
return NULL;
}
if (!point_is_inside(p, new_points)) {
return NULL;
if (apply_clip_plane(new_points, cpa, entry.get_into_node_path().get_net_transform())) {
// All points are behind the clip plane.
if (!point_is_inside(p, _points)) {
return NULL;
}
} else {
if (new_points.size() < 3) {
return NULL;
}
if (!point_is_inside(p, new_points)) {
return NULL;
}
}
} else {
@ -682,12 +689,19 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
if (cpa != (ClipPlaneAttrib *)NULL) {
// We have a clip plane; apply it.
Points new_points;
apply_clip_plane(new_points, cpa, entry.get_into_node_path().get_net_transform());
if (new_points.size() < 3) {
return NULL;
}
if (!point_is_inside(p, new_points)) {
return NULL;
if (apply_clip_plane(new_points, cpa, entry.get_into_node_path().get_net_transform())) {
// All points are behind the clip plane.
if (!point_is_inside(p, _points)) {
return NULL;
}
} else {
if (new_points.size() < 3) {
return NULL;
}
if (!point_is_inside(p, new_points)) {
return NULL;
}
}
} else {
@ -753,12 +767,19 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
if (cpa != (ClipPlaneAttrib *)NULL) {
// We have a clip plane; apply it.
Points new_points;
apply_clip_plane(new_points, cpa, entry.get_into_node_path().get_net_transform());
if (new_points.size() < 3) {
return NULL;
}
if (!point_is_inside(p, new_points)) {
return NULL;
if (apply_clip_plane(new_points, cpa, entry.get_into_node_path().get_net_transform())) {
// All points are behind the clip plane.
if (!point_is_inside(p, _points)) {
return NULL;
}
} else {
if (new_points.size() < 3) {
return NULL;
}
if (!point_is_inside(p, new_points)) {
return NULL;
}
}
} else {
@ -1165,28 +1186,27 @@ apply_clip_plane(CollisionPolygon::Points &new_points,
bool all_in = true;
int num_planes = cpa->get_num_on_planes();
if (num_planes > 0) {
bool first_plane = true;
for (int i = 0; i < num_planes; i++) {
NodePath plane_path = cpa->get_on_plane(0);
PlaneNode *plane_node = DCAST(PlaneNode, plane_path.node());
CPT(TransformState) new_transform =
net_transform->invert_compose(plane_path.get_net_transform());
Planef plane = plane_node->get_plane() * new_transform->get_mat();
if (!clip_polygon(new_points, _points, plane)) {
all_in = false;
}
for (int i = 1; i < num_planes; i++) {
NodePath plane_path = cpa->get_on_plane(0);
PlaneNode *plane_node = DCAST(PlaneNode, plane_path.node());
if ((plane_node->get_clip_effect() & PlaneNode::CE_collision) != 0) {
CPT(TransformState) new_transform =
net_transform->invert_compose(plane_path.get_net_transform());
Planef plane = plane_node->get_plane() * new_transform->get_mat();
Points last_points;
last_points.swap(new_points);
if (!clip_polygon(new_points, last_points, plane)) {
all_in = false;
if (first_plane) {
first_plane = false;
if (!clip_polygon(new_points, _points, plane)) {
all_in = false;
}
} else {
Points last_points;
last_points.swap(new_points);
if (!clip_polygon(new_points, last_points, plane)) {
all_in = false;
}
}
}
}

View File

@ -1431,78 +1431,80 @@ do_issue_clip_plane() {
for (int li = 0; li < num_on_planes; li++) {
NodePath plane = new_attrib->get_on_plane(li);
nassertv(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type()));
PlaneNode *plane_node = (PlaneNode *)plane.node();
if ((plane_node->get_clip_effect() & PlaneNode::CE_visible) != 0) {
num_enabled++;
num_enabled++;
// Clipping should be enabled before we apply any planes.
enable_clip_planes(true);
_clip_planes_enabled = true;
_clip_planes_enabled_this_frame = true;
// Check to see if this plane has already been bound to an id
int cur_plane_id = -1;
for (i = 0; i < cur_max_planes; i++) {
if (_clip_plane_info[i]._plane == plane) {
// Plane has already been bound to an id, we only need to
// enable the plane, not reapply it.
cur_plane_id = -2;
enable_clip_plane(i, true);
_clip_plane_info[i]._enabled = true;
_clip_plane_info[i]._next_enabled = true;
break;
}
}
// See if there are any unbound plane ids
if (cur_plane_id == -1) {
// Clipping should be enabled before we apply any planes.
enable_clip_planes(true);
_clip_planes_enabled = true;
_clip_planes_enabled_this_frame = true;
// Check to see if this plane has already been bound to an id
int cur_plane_id = -1;
for (i = 0; i < cur_max_planes; i++) {
if (_clip_plane_info[i]._plane.is_empty()) {
_clip_plane_info[i]._plane = plane;
cur_plane_id = i;
if (_clip_plane_info[i]._plane == plane) {
// Plane has already been bound to an id, we only need to
// enable the plane, not reapply it.
cur_plane_id = -2;
enable_clip_plane(i, true);
_clip_plane_info[i]._enabled = true;
_clip_plane_info[i]._next_enabled = true;
break;
}
}
}
// If there were no unbound plane ids, see if we can replace
// a currently unused but previously bound id
if (cur_plane_id == -1) {
for (i = 0; i < cur_max_planes; i++) {
if (!new_attrib->has_on_plane(_clip_plane_info[i]._plane)) {
_clip_plane_info[i]._plane = plane;
cur_plane_id = i;
break;
// See if there are any unbound plane ids
if (cur_plane_id == -1) {
for (i = 0; i < cur_max_planes; i++) {
if (_clip_plane_info[i]._plane.is_empty()) {
_clip_plane_info[i]._plane = plane;
cur_plane_id = i;
break;
}
}
}
}
// If we *still* don't have a plane id, slot a new one.
if (cur_plane_id == -1) {
if (_max_clip_planes < 0 || cur_max_planes < _max_clip_planes) {
cur_plane_id = cur_max_planes;
_clip_plane_info.push_back(ClipPlaneInfo());
cur_max_planes++;
nassertv(cur_max_planes == (int)_clip_plane_info.size());
// If there were no unbound plane ids, see if we can replace
// a currently unused but previously bound id
if (cur_plane_id == -1) {
for (i = 0; i < cur_max_planes; i++) {
if (!new_attrib->has_on_plane(_clip_plane_info[i]._plane)) {
_clip_plane_info[i]._plane = plane;
cur_plane_id = i;
break;
}
}
}
}
if (cur_plane_id >= 0) {
enable_clip_plane(cur_plane_id, true);
_clip_plane_info[cur_plane_id]._enabled = true;
_clip_plane_info[cur_plane_id]._next_enabled = true;
if (!any_bound) {
begin_bind_clip_planes();
any_bound = true;
// If we *still* don't have a plane id, slot a new one.
if (cur_plane_id == -1) {
if (_max_clip_planes < 0 || cur_max_planes < _max_clip_planes) {
cur_plane_id = cur_max_planes;
_clip_plane_info.push_back(ClipPlaneInfo());
cur_max_planes++;
nassertv(cur_max_planes == (int)_clip_plane_info.size());
}
}
if (cur_plane_id >= 0) {
enable_clip_plane(cur_plane_id, true);
_clip_plane_info[cur_plane_id]._enabled = true;
_clip_plane_info[cur_plane_id]._next_enabled = true;
if (!any_bound) {
begin_bind_clip_planes();
any_bound = true;
}
// This is the first time this frame that this plane has been
// bound to this particular id.
bind_clip_plane(plane, cur_plane_id);
} else if (cur_plane_id == -1) {
gsg_cat.warning()
<< "Failed to bind " << plane << " to id.\n";
}
// This is the first time this frame that this plane has been
// bound to this particular id.
bind_clip_plane(plane, cur_plane_id);
} else if (cur_plane_id == -1) {
gsg_cat.warning()
<< "Failed to bind " << plane << " to id.\n";
}
}

View File

@ -133,6 +133,34 @@ INLINE int PlaneNode::
get_priority() const {
return _priority;
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::set_clip_effect
// Access: Published
// Description: Specifies the sort of things this plane will actually
// clip (when it is used as a clip plane). This is a
// bitmask union of ClipEffect values. If it includes
// CE_visible, then it will clip visible geometry; if it
// includes CE_collision, then it will clip collision
// polygons. If it includes neither bit, it will still
// affect culling, but objects will either be wholly
// behind the clipping plane, or wholly present.
////////////////////////////////////////////////////////////////////
INLINE void PlaneNode::
set_clip_effect(int clip_effect) {
_clip_effect = clip_effect;
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::get_clip_effect
// Access: Published
// Description: Returns the clip_effect bits for this clip plane.
// See set_clip_effect().
////////////////////////////////////////////////////////////////////
INLINE int PlaneNode::
get_clip_effect() const {
return _clip_effect;
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::get_sort_seq

View File

@ -75,7 +75,8 @@ fillin(DatagramIterator &scan, BamReader *) {
PlaneNode::
PlaneNode(const string &name, const Planef &plane) :
PandaNode(name),
_priority(0)
_priority(0),
_clip_effect(~0)
{
set_cull_callback();
@ -94,6 +95,7 @@ PlaneNode::
PlaneNode(const PlaneNode &copy) :
PandaNode(copy),
_priority(copy._priority),
_clip_effect(copy._clip_effect),
_cycler(copy._cycler)
{
}
@ -316,6 +318,7 @@ write_datagram(BamWriter *manager, Datagram &dg) {
PandaNode::write_datagram(manager, dg);
manager->write_cdata(dg, _cycler);
dg.add_int32(_priority);
dg.add_uint8(_clip_effect);
}
////////////////////////////////////////////////////////////////////
@ -350,4 +353,10 @@ fillin(DatagramIterator &scan, BamReader *manager) {
PandaNode::fillin(scan, manager);
manager->read_cdata(scan, _cycler);
_priority = scan.get_int32();
if (manager->get_file_minor_ver() < 9) {
_clip_effect = ~0;
} else {
_clip_effect = scan.get_uint8();
}
}

View File

@ -65,6 +65,13 @@ PUBLISHED:
INLINE void set_priority(int priority);
INLINE int get_priority() const;
enum ClipEffect {
CE_visible = 0x0001,
CE_collision = 0x0002,
};
INLINE void set_clip_effect(int clip_effect);
INLINE int get_clip_effect() const;
public:
INLINE static UpdateSeq get_sort_seq();
@ -77,6 +84,7 @@ private:
// so, and cycling it makes it difficult to synchronize with the
// ClipPlaneAttribs.
int _priority;
int _clip_effect;
static UpdateSeq _sort_seq;
// This is the data that must be cycled between pipeline stages.

View File

@ -36,7 +36,7 @@ static const unsigned short _bam_major_ver = 6;
// Bumped to major version 5 on 5/6/05 for new Geom implementation.
// Bumped to major version 6 on 2/11/06 to factor out PandaNode::CData.
static const unsigned short _bam_minor_ver = 8;
static const unsigned short _bam_minor_ver = 9;
// Bumped to minor version 1 on 3/12/06 to add Texture::_compression.
// Bumped to minor version 2 on 3/17/06 to add PandaNode::_draw_control_mask.
// Bumped to minor version 3 on 3/21/06 to add Texture::_ram_images.
@ -45,6 +45,7 @@ static const unsigned short _bam_minor_ver = 8;
// Bumped to minor version 6 on 2/5/07 to change GeomPrimitive::_num_vertices.
// Bumped to minor version 7 on 2/15/07 to change SliderTable.
// Bumped to minor version 8 on 5/12/07 to change GeomVertexArrayData::_data.
// Bumped to minor version 9 on 5/15/07 to add PlaneNode::_clip_effect.
#endif