fix translated GeomNode problem
This commit is contained in:
parent
c598485e8e
commit
63f4a07801
|
|
@ -191,7 +191,9 @@ get_inv_space(int n) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpCollisionLevelState::get_local_bound
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description: Returns the bounding volume of the indicated
|
||||
// collider, transformed into the current node's
|
||||
// transform space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeometricBoundingVolume *qpCollisionLevelState::
|
||||
get_local_bound(int n) const {
|
||||
|
|
@ -207,6 +209,27 @@ get_local_bound(int n) const {
|
|||
return *(_local_bounds + n);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpCollisionLevelState::get_parent_bound
|
||||
// Access: Public
|
||||
// Description: Returns the bounding volume of the indicated
|
||||
// collider, transformed into the previous node's
|
||||
// transform space, but not transformed by the current
|
||||
// node's transform. This is appropriate for testing
|
||||
// against the bounding volume of the current node
|
||||
// (which does not have its own transform applied to
|
||||
// it).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeometricBoundingVolume *qpCollisionLevelState::
|
||||
get_parent_bound(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_colliders.size(), NULL);
|
||||
nassertr(has_collider(n), NULL);
|
||||
nassertr(n >= 0 && n < (int)_parent_bounds.size(), NULL);
|
||||
|
||||
// But it can figure out this equivalent line.
|
||||
return *(_parent_bounds + n);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpCollisionLevelState::omit_collider
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ void qpCollisionLevelState::
|
|||
clear() {
|
||||
_colliders.clear();
|
||||
_local_bounds.clear();
|
||||
_parent_bounds.clear();
|
||||
_current = 0;
|
||||
_colliders_with_geom = 0;
|
||||
}
|
||||
|
|
@ -71,6 +72,7 @@ prepare_collider(const ColliderDef &def) {
|
|||
if (def._node->get_collide_geom()) {
|
||||
_colliders_with_geom |= get_mask(index);
|
||||
}
|
||||
_parent_bounds = _local_bounds;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -85,6 +87,16 @@ prepare_collider(const ColliderDef &def) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool qpCollisionLevelState::
|
||||
any_in_bounds() {
|
||||
#ifndef NDEBUG
|
||||
int indent_level = 0;
|
||||
if (collide_cat.is_spam()) {
|
||||
indent_level = _node_path.get_num_nodes() * 2;
|
||||
collide_cat.spam();
|
||||
indent(collide_cat.spam(false), indent_level)
|
||||
<< "Considering " << _node_path.get_node_path() << "\n";
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
const BoundingVolume &node_bv = node()->get_bound();
|
||||
if (node_bv.is_of_type(GeometricBoundingVolume::get_class_type())) {
|
||||
const GeometricBoundingVolume *node_gbv;
|
||||
|
|
@ -108,6 +120,15 @@ any_in_bounds() {
|
|||
get_local_bound(c);
|
||||
if (col_gbv != (GeometricBoundingVolume *)NULL) {
|
||||
is_in = (node_gbv->contains(col_gbv) != 0);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (collide_cat.is_spam()) {
|
||||
collide_cat.spam();
|
||||
indent(collide_cat.spam(false), indent_level)
|
||||
<< "Comparing " << c << ": " << *col_gbv
|
||||
<< " to " << *node_gbv << ", is_in = " << is_in << "\n";
|
||||
}
|
||||
#endif // NDEBUG
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -120,6 +141,22 @@ any_in_bounds() {
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (collide_cat.is_spam()) {
|
||||
int num_active_colliders = 0;
|
||||
int num_colliders = get_num_colliders();
|
||||
for (int c = 0; c < num_colliders; c++) {
|
||||
if (has_collider(c)) {
|
||||
num_active_colliders++;
|
||||
}
|
||||
}
|
||||
|
||||
collide_cat.spam();
|
||||
indent(collide_cat.spam(false), indent_level)
|
||||
<< _node_path.get_node_path() << " has " << num_active_colliders
|
||||
<< " interested colliders.\n";
|
||||
}
|
||||
#endif // NDEBUG
|
||||
return has_any_collider();
|
||||
}
|
||||
|
||||
|
|
@ -131,6 +168,11 @@ any_in_bounds() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void qpCollisionLevelState::
|
||||
apply_transform() {
|
||||
// The "parent" bounds list remembers the bounds list of the
|
||||
// previous node.
|
||||
_parent_bounds = _local_bounds;
|
||||
|
||||
// Recompute the bounds list of this node (if we have a transform).
|
||||
const TransformState *node_transform = node()->get_transform();
|
||||
if (!node_transform->is_identity()) {
|
||||
CPT(TransformState) inv_transform =
|
||||
|
|
|
|||
|
|
@ -75,10 +75,16 @@ public:
|
|||
INLINE const LMatrix4f &get_space(int n) const;
|
||||
INLINE const LMatrix4f &get_inv_space(int n) const;
|
||||
INLINE const GeometricBoundingVolume *get_local_bound(int n) const;
|
||||
INLINE const GeometricBoundingVolume *get_parent_bound(int n) const;
|
||||
|
||||
INLINE void omit_collider(int n);
|
||||
|
||||
//private:
|
||||
private:
|
||||
// ColliderMask here is a locally-defined value that simply serves
|
||||
// to keep track of the colliders that are still interested in the
|
||||
// current node. Don't confuse it with CollideMask, which is a set
|
||||
// of user-defined bits that specify which CollisionSolids may
|
||||
// possibly intersect with each other.
|
||||
typedef int ColliderMask;
|
||||
|
||||
INLINE ColliderMask get_mask(int n) const;
|
||||
|
|
@ -92,6 +98,7 @@ public:
|
|||
|
||||
typedef PTA(CPT(GeometricBoundingVolume)) BoundingVolumes;
|
||||
BoundingVolumes _local_bounds;
|
||||
BoundingVolumes _parent_bounds;
|
||||
};
|
||||
|
||||
#include "qpcollisionLevelState.I"
|
||||
|
|
|
|||
|
|
@ -380,15 +380,22 @@ r_traverse(qpCollisionLevelState &level_state) {
|
|||
entry._inv_wrt_space =
|
||||
entry._into_space * level_state.get_inv_space(c);
|
||||
|
||||
const GeometricBoundingVolume *col_gbv =
|
||||
level_state.get_local_bound(c);
|
||||
|
||||
compare_collider_to_node(entry, col_gbv, node_gbv);
|
||||
compare_collider_to_node(entry,
|
||||
level_state.get_parent_bound(c),
|
||||
level_state.get_local_bound(c),
|
||||
node_gbv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (node->is_geom_node() && level_state.has_any_collide_geom()) {
|
||||
#ifndef NDEBUG
|
||||
if (collide_cat.is_spam()) {
|
||||
collide_cat.spam()
|
||||
<< "Reached " << *node << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
qpGeomNode *gnode;
|
||||
DCAST_INTO_V(gnode, node);
|
||||
const BoundingVolume &node_bv = gnode->get_bound();
|
||||
|
|
@ -417,10 +424,10 @@ r_traverse(qpCollisionLevelState &level_state) {
|
|||
entry._inv_wrt_space =
|
||||
entry._into_space * level_state.get_inv_space(c);
|
||||
|
||||
const GeometricBoundingVolume *col_gbv =
|
||||
level_state.get_local_bound(c);
|
||||
|
||||
compare_collider_to_geom_node(entry, col_gbv, node_gbv);
|
||||
compare_collider_to_geom_node(entry,
|
||||
level_state.get_parent_bound(c),
|
||||
level_state.get_local_bound(c),
|
||||
node_gbv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -439,12 +446,13 @@ r_traverse(qpCollisionLevelState &level_state) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void qpCollisionTraverser::
|
||||
compare_collider_to_node(qpCollisionEntry &entry,
|
||||
const GeometricBoundingVolume *from_parent_gbv,
|
||||
const GeometricBoundingVolume *from_node_gbv,
|
||||
const GeometricBoundingVolume *into_node_gbv) {
|
||||
bool within_node_bounds = true;
|
||||
if (from_node_gbv != (GeometricBoundingVolume *)NULL &&
|
||||
if (from_parent_gbv != (GeometricBoundingVolume *)NULL &&
|
||||
into_node_gbv != (GeometricBoundingVolume *)NULL) {
|
||||
within_node_bounds = (into_node_gbv->contains(from_node_gbv) != 0);
|
||||
within_node_bounds = (into_node_gbv->contains(from_parent_gbv) != 0);
|
||||
}
|
||||
|
||||
if (within_node_bounds) {
|
||||
|
|
@ -479,12 +487,13 @@ compare_collider_to_node(qpCollisionEntry &entry,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void qpCollisionTraverser::
|
||||
compare_collider_to_geom_node(qpCollisionEntry &entry,
|
||||
const GeometricBoundingVolume *from_parent_gbv,
|
||||
const GeometricBoundingVolume *from_node_gbv,
|
||||
const GeometricBoundingVolume *into_node_gbv) {
|
||||
bool within_node_bounds = true;
|
||||
if (from_node_gbv != (GeometricBoundingVolume *)NULL &&
|
||||
if (from_parent_gbv != (GeometricBoundingVolume *)NULL &&
|
||||
into_node_gbv != (GeometricBoundingVolume *)NULL) {
|
||||
within_node_bounds = (into_node_gbv->contains(from_node_gbv) != 0);
|
||||
within_node_bounds = (into_node_gbv->contains(from_parent_gbv) != 0);
|
||||
}
|
||||
|
||||
if (within_node_bounds) {
|
||||
|
|
|
|||
|
|
@ -62,9 +62,11 @@ private:
|
|||
void r_traverse(qpCollisionLevelState &level_state);
|
||||
|
||||
void compare_collider_to_node(qpCollisionEntry &entry,
|
||||
const GeometricBoundingVolume *from_parent_gbv,
|
||||
const GeometricBoundingVolume *from_node_gbv,
|
||||
const GeometricBoundingVolume *into_node_gbv);
|
||||
void compare_collider_to_geom_node(qpCollisionEntry &entry,
|
||||
const GeometricBoundingVolume *from_parent_gbv,
|
||||
const GeometricBoundingVolume *from_node_gbv,
|
||||
const GeometricBoundingVolume *into_node_gbv);
|
||||
void compare_collider_to_solid(qpCollisionEntry &entry,
|
||||
|
|
|
|||
Loading…
Reference in New Issue