some more collision work. A new handler that only passes along the highest entry, as well as a small tweak to the collision gravity handler to ensure that only entries within the ray's bounds are sent

This commit is contained in:
Zachary Pavlov 2009-08-11 17:16:07 +00:00
parent 61f4c5c113
commit 0c4b08731a
6 changed files with 180 additions and 9 deletions

View File

@ -14,6 +14,7 @@
collisionGeom.I collisionGeom.h \
collisionHandler.I collisionHandler.h \
collisionHandlerEvent.I collisionHandlerEvent.h \
collisionHandlerHighestEvent.h \
collisionHandlerFloor.I collisionHandlerFloor.h \
collisionHandlerGravity.I collisionHandlerGravity.h \
collisionHandlerPhysical.I collisionHandlerPhysical.h \
@ -46,6 +47,7 @@
collisionGeom.cxx \
collisionHandler.cxx \
collisionHandlerEvent.cxx \
collisionHandlerHighestEvent.cxx \
collisionHandlerFloor.cxx \
collisionHandlerGravity.cxx \
collisionHandlerPhysical.cxx \
@ -78,6 +80,7 @@
collisionGeom.I collisionGeom.h \
collisionHandler.I collisionHandler.h \
collisionHandlerEvent.I collisionHandlerEvent.h \
collisionHandlerHighestEvent.h \
collisionHandlerFloor.I collisionHandlerFloor.h \
collisionHandlerGravity.I collisionHandlerGravity.h \
collisionHandlerPhysical.I collisionHandlerPhysical.h \

View File

@ -3,6 +3,7 @@
#include "collisionGeom.cxx"
#include "collisionHandler.cxx"
#include "collisionHandlerEvent.cxx"
#include "collisionHandlerHighestEvent.cxx"
#include "collisionHandlerFloor.cxx"
#include "collisionHandlerGravity.cxx"
#include "collisionHandlerPhysical.cxx"

View File

@ -66,7 +66,7 @@ set_highest_collision(const NodePath &target_node_path, const NodePath &from_nod
bool got_max = false;
float max_height = 0.0f;
CollisionEntry *highest = NULL;
Entries::const_iterator ei;
for (ei = entries.begin(); ei != entries.end(); ++ei) {
CollisionEntry *entry = (*ei);
@ -123,6 +123,8 @@ set_highest_collision(const NodePath &target_node_path, const NodePath &from_nod
CollisionEntry *highest = NULL;
CollisionEntry *lowest = NULL;
pvector<PT(CollisionEntry)> valid_entries;
Entries::const_iterator ei;
for (ei = entries.begin(); ei != entries.end(); ++ei) {
CollisionEntry *entry = (*ei);
@ -135,13 +137,14 @@ set_highest_collision(const NodePath &target_node_path, const NodePath &from_nod
collide_cat.debug()
<< "Intersection point detected at " << point << "\n";
}
float height = point[2];
if (height < _offset + _reach &&
(!got_max || height > max_height)) {
got_max = true;
max_height = height;
highest = entry;
if(height < _offset + _reach) {
valid_entries.push_back(entry);
if (!got_max || height > max_height) {
got_max = true;
max_height = height;
highest = entry;
}
}
if (!got_min || height < min_height) {
got_min = true;
@ -157,6 +160,7 @@ set_highest_collision(const NodePath &target_node_path, const NodePath &from_nod
got_max = true;
max_height = min_height;
highest = lowest;
valid_entries.push_back(lowest);
}
//#*#_has_contact = got_max;
@ -172,9 +176,10 @@ set_highest_collision(const NodePath &target_node_path, const NodePath &from_nod
// We only collide with things we are impacting with.
// Remove the collisions:
//_current_colliding.clear();
_current_colliding.clear();
// Add only the one that we're impacting with:
//add_entry(highest);
_current_colliding.insert(valid_entries.begin(), valid_entries.end());
// Set the contact normal so that other code can make use of the
// surface slope:

View File

@ -0,0 +1,90 @@
// Filename: collisionHandlerEvent.cxx
// Created by: drose (16Mar02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "collisionHandlerHighestEvent.h"
#include "config_collide.h"
#include "eventParameter.h"
#include "throw_event.h"
TypeHandle CollisionHandlerHighestEvent::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::Constructor
// Access: Public
// Description: The default CollisionHandlerEvent will throw no
// events. Its pattern strings must first be set via a
// call to add_in_pattern() and/or add_out_pattern().
////////////////////////////////////////////////////////////////////
CollisionHandlerHighestEvent::
CollisionHandlerHighestEvent() {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::begin_group
// Access: Public, Virtual
// Description: Will be called by the CollisionTraverser before a new
// traversal is begun. It instructs the handler to
// reset itself in preparation for a number of
// CollisionEntries to be sent.
////////////////////////////////////////////////////////////////////
void CollisionHandlerHighestEvent::
begin_group() {
if (collide_cat.is_spam()) {
collide_cat.spam()
<< "begin_group.\n";
}
_last_colliding.clear();
if(_closest_collider)
bool inserted = _last_colliding.insert(_closest_collider).second;
_current_colliding.clear();
_collider_distance = 10000000000;
_closest_collider = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::add_entry
// Access: Public, Virtual
// Description: Called between a begin_group() .. end_group()
// sequence for each collision that is detected.
////////////////////////////////////////////////////////////////////
void CollisionHandlerHighestEvent::
add_entry(CollisionEntry *entry) {
nassertv(entry != (CollisionEntry *)NULL);
LVector3f vec =
entry->get_surface_point(entry->get_from_node_path()) -
entry->get_from()->get_collision_origin();
double dist = vec.length_squared();
if(dist < _collider_distance) {
_collider_distance = dist;
_closest_collider = entry;
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::end_group
// Access: Public, Virtual
// Description: Called by the CollisionTraverser at the completion of
// all collision detections for this traversal. It
// should do whatever finalization is required for the
// handler.
////////////////////////////////////////////////////////////////////
bool CollisionHandlerHighestEvent::
end_group() {
if(_closest_collider)
bool inserted = _current_colliding.insert(_closest_collider).second;
return CollisionHandlerEvent::end_group();
}

View File

@ -0,0 +1,70 @@
// Filename: collisionHandlerEvent.h
// Created by: drose (16Mar02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef COLLISIONHANDLERHIGHESTEVENT_H
#define COLLISIONHANDLERHIGHESTEVENT_H
#include "pandabase.h"
#include "collisionHandlerEvent.h"
#include "collisionNode.h"
#include "collisionEntry.h"
#include "vector_string.h"
#include "pointerTo.h"
////////////////////////////////////////////////////////////////////
// Class : CollisionHandlerEvent
// Description : A specialized kind of CollisionHandler that throws an
// event for each collision detected. The event thrown
// may be based on the name of the moving object or the
// struck object, or both. The first parameter of the
// event will be a pointer to the CollisionEntry that
// triggered it.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_COLLIDE CollisionHandlerHighestEvent : public CollisionHandlerEvent {
PUBLISHED:
CollisionHandlerHighestEvent();
public:
virtual void begin_group();
virtual void add_entry(CollisionEntry *entry);
virtual bool end_group();
private:
double _collider_distance;
PT(CollisionEntry) _closest_collider;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
CollisionHandler::init_type();
register_type(_type_handle, "CollisionHandlerHighestEvent",
CollisionHandler::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -16,6 +16,7 @@
#include "collisionEntry.h"
#include "collisionHandler.h"
#include "collisionHandlerEvent.h"
#include "collisionHandlerHighestEvent.h"
#include "collisionHandlerFloor.h"
#include "collisionHandlerGravity.h"
#include "collisionHandlerPhysical.h"
@ -121,6 +122,7 @@ init_libcollide() {
CollisionEntry::init_type();
CollisionHandler::init_type();
CollisionHandlerEvent::init_type();
CollisionHandlerHighestEvent::init_type();
CollisionHandlerFloor::init_type();
CollisionHandlerGravity::init_type();
CollisionHandlerPhysical::init_type();