correct confusion between info_surface_normal and from_surface_normal

This commit is contained in:
David Rose 2003-04-16 18:49:07 +00:00
parent 909aa78199
commit 350dd5cda1
7 changed files with 136 additions and 24 deletions

View File

@ -294,6 +294,46 @@ get_into_surface_normal() const {
return _into_surface_normal;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::set_from_surface_normal
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CollisionEntry::
set_from_surface_normal(const LVector3f &normal) {
_from_surface_normal = normal;
_flags |= F_has_from_surface_normal;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::has_from_surface_normal
// Access: Public
// Description: Returns true if the detected collision knows the
// surface normal of the collided-into object at the
// point of the collision, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionEntry::
has_from_surface_normal() const {
return (_flags & (F_has_into_surface_normal | F_has_from_surface_normal)) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_from_surface_normal
// Access: Public
// Description: Returns the surface normal of the collided-into
// object at the point of the collision, in the space of
// the collided-from object. It is an error to call
// this if has_from_surface_normal() returns false.
////////////////////////////////////////////////////////////////////
INLINE const LVector3f &CollisionEntry::
get_from_surface_normal() const {
nassertr(has_from_surface_normal(), _from_surface_normal);
if ((_flags & F_has_from_surface_normal) == 0) {
((CollisionEntry *)this)->compute_from_surface_normal();
}
return _from_surface_normal;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::set_into_depth
@ -333,3 +373,42 @@ get_into_depth() const {
nassertr(has_into_depth(), 0.0);
return _into_depth;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::set_from_depth
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CollisionEntry::
set_from_depth(float depth) {
_from_depth = depth;
_flags |= F_has_from_depth;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::has_from_depth
// Access: Public
// Description: Returns true if the collision entry knows how "deep"
// the collision was from the collided-from object; that
// is, how far from the surface of the collided-from
// object the colliding object has penetrated.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionEntry::
has_from_depth() const {
return (_flags & F_has_from_depth) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_from_depth
// Access: Public
// Description: Returns how "deep" the collision was from the
// collided-from object; that is, how far from the
// surface of the collided-from object the colliding
// object has penetrated. It is an error to call this
// if has_from_depth() returns false.
////////////////////////////////////////////////////////////////////
INLINE float CollisionEntry::
get_from_depth() const {
nassertr(has_from_depth(), 0.0);
return _from_depth;
}

View File

@ -64,3 +64,16 @@ operator = (const CollisionEntry &copy) {
_into_surface_normal = copy._into_surface_normal;
_into_depth = copy._into_depth;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::compute_from_surface_normal
// Access: Private
// Description: Computes the "from" surface normal by converting the
// "into" surface normal into the colliding object's
// space.
////////////////////////////////////////////////////////////////////
void CollisionEntry::
compute_from_surface_normal() {
_from_surface_normal = get_into_surface_normal() * get_inv_wrt_space();
_flags |= F_has_from_surface_normal;
}

View File

@ -78,11 +78,21 @@ PUBLISHED:
INLINE bool has_into_surface_normal() const;
INLINE const LVector3f &get_into_surface_normal() const;
INLINE void set_from_surface_normal(const LVector3f &normal);
INLINE bool has_from_surface_normal() const;
INLINE const LVector3f &get_from_surface_normal() const;
INLINE void set_into_depth(float depth);
INLINE bool has_into_depth() const;
INLINE float get_into_depth() const;
INLINE void set_from_depth(float depth);
INLINE bool has_from_depth() const;
INLINE float get_from_depth() const;
private:
void compute_from_surface_normal();
CPT(CollisionSolid) _from;
CPT(CollisionSolid) _into;
@ -97,8 +107,10 @@ private:
enum Flags {
F_has_into_intersection_point = 0x0001,
F_has_into_surface_normal = 0x0002,
F_has_into_depth = 0x0004,
F_has_from_velocity = 0x0008,
F_has_from_surface_normal = 0x0004,
F_has_into_depth = 0x0008,
F_has_from_depth = 0x0010,
F_has_from_velocity = 0x0020,
};
int _flags;
@ -106,7 +118,9 @@ private:
LVector3f _from_velocity;
LPoint3f _into_intersection_point;
LVector3f _into_surface_normal;
LVector3f _from_surface_normal;
float _into_depth;
float _from_depth;
public:
static TypeHandle get_class_type() {

View File

@ -117,8 +117,8 @@ handle_entries() {
nassertr(entry != (CollisionEntry *)NULL, false);
nassertr(from_node == entry->get_from_node(), false);
if (!entry->has_into_surface_normal() ||
!entry->has_into_depth()) {
if (!entry->has_from_surface_normal() ||
!entry->has_from_depth()) {
#ifndef NDEBUG
if (collide_cat.is_debug()) {
collide_cat.debug()
@ -129,8 +129,8 @@ handle_entries() {
} else {
// Shove it just enough to clear the volume.
if (entry->get_into_depth() != 0.0f) {
LVector3f normal = entry->get_into_surface_normal();
if (entry->get_from_depth() != 0.0f) {
LVector3f normal = entry->get_from_surface_normal();
if (_horizontal) {
normal[2] = 0.0f;
}
@ -141,7 +141,7 @@ handle_entries() {
ShoveData sd;
sd._vector = normal;
sd._length = entry->get_into_depth();
sd._length = entry->get_from_depth();
sd._valid = true;
sd._entry = entry;

View File

@ -141,11 +141,13 @@ test_intersection_from_sphere(CollisionHandler *record,
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
LVector3f into_normal = get_normal() * entry.get_inv_wrt_space();
float into_depth = from_radius - dist;
LVector3f from_normal = get_normal() * entry.get_inv_wrt_space();
float from_depth = from_radius - dist;
new_entry->set_into_surface_normal(into_normal);
new_entry->set_into_depth(into_depth);
new_entry->set_into_surface_normal(get_normal());
new_entry->set_from_surface_normal(from_normal);
new_entry->set_from_depth(from_depth);
new_entry->set_into_intersection_point(from_center);
record->add_entry(new_entry);
return 1;
@ -184,6 +186,7 @@ test_intersection_from_ray(CollisionHandler *record,
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
LPoint3f into_intersection_point = from_origin + t * from_direction;
new_entry->set_into_surface_normal(get_normal());
new_entry->set_into_intersection_point(into_intersection_point);
record->add_entry(new_entry);

View File

@ -364,17 +364,18 @@ test_intersection_from_sphere(CollisionHandler *record,
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
LVector3f into_normal = get_normal() * entry.get_inv_wrt_space();
float into_depth = from_radius - dist;
LVector3f from_normal = get_normal() * entry.get_inv_wrt_space();
float from_depth = from_radius - dist;
if (moved_from_center) {
// We have to base the depth of intersection on the sphere's final
// resting point, not the point from which we tested the
// intersection.
into_depth = from_radius - dist_to_plane(orig_center);
from_depth = from_radius - dist_to_plane(orig_center);
}
new_entry->set_into_surface_normal(into_normal);
new_entry->set_into_depth(into_depth);
new_entry->set_into_surface_normal(get_normal());
new_entry->set_from_surface_normal(from_normal);
new_entry->set_from_depth(from_depth);
new_entry->set_into_intersection_point(from_center);
record->add_entry(new_entry);
@ -423,11 +424,9 @@ test_intersection_from_ray(CollisionHandler *record,
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
new_entry->set_into_surface_normal(get_normal());
new_entry->set_into_intersection_point(plane_point);
LVector3f into_normal = get_normal() * entry.get_inv_wrt_space();
new_entry->set_into_surface_normal(into_normal);
record->add_entry(new_entry);
return 1;
}
@ -476,11 +475,9 @@ test_intersection_from_segment(CollisionHandler *record,
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
new_entry->set_into_surface_normal(get_normal());
new_entry->set_into_intersection_point(plane_point);
LVector3f into_normal = get_normal() * entry.get_inv_wrt_space();
new_entry->set_into_surface_normal(into_normal);
record->add_entry(new_entry);
return 1;
}

View File

@ -150,10 +150,16 @@ test_intersection_from_sphere(CollisionHandler *record,
LPoint3f into_intersection_point = into_normal * (dist - from_radius);
float into_depth = into_radius + from_radius - dist;
new_entry->set_into_surface_normal(into_normal * entry.get_inv_wrt_space());
new_entry->set_into_intersection_point(into_intersection_point * entry.get_inv_wrt_space());
new_entry->set_into_surface_normal(into_normal);
new_entry->set_into_intersection_point(into_intersection_point);
new_entry->set_into_depth(into_depth);
// This is a bit of a hack. This result is incorrect if there is a
// scale between the colliding object and this sphere. We need to
// account for that scale, but to account for it correctly
// (especially including non-uniform scales) is rather complicated.
new_entry->set_from_depth(into_depth);
record->add_entry(new_entry);
return 1;
}