15 #include "collisionHandlerGravity.h" 16 #include "collisionNode.h" 17 #include "collisionEntry.h" 18 #include "config_collide.h" 19 #include "collisionPlane.h" 20 #include "clockObject.h" 22 TypeHandle CollisionHandlerGravity::_type_handle;
29 CollisionHandlerGravity::
30 CollisionHandlerGravity() {
33 _airborne_height = 0.0f;
34 _impact_velocity = 0.0f;
36 _current_velocity = 0.0f;
37 _max_velocity = 400.0f;
47 CollisionHandlerGravity::
48 ~CollisionHandlerGravity() {
62 #define OLD_COLLISION_HANDLER_GRAVITY 0 63 #if OLD_COLLISION_HANDLER_GRAVITY 64 PN_stdfloat CollisionHandlerGravity::
65 set_highest_collision(
const NodePath &target_node_path,
const NodePath &from_node_path,
const Entries &entries) {
68 PN_stdfloat max_height = 0.0f;
71 Entries::const_iterator ei;
72 for (ei = entries.begin(); ei != entries.end(); ++ei) {
79 if (collide_cat.is_debug()) {
81 <<
"Intersection point detected at " << point <<
"\n";
84 PN_stdfloat height = point[2];
85 if (!got_max || height > max_height) {
95 cout<<
"\ncolliding with:\n";
96 for (Colliding::const_iterator i = _current_colliding.begin(); i != _current_colliding.end(); ++i) {
100 highest->write(cout, 2);
107 _current_colliding.clear();
115 PN_stdfloat CollisionHandlerGravity::
116 set_highest_collision(
const NodePath &target_node_path,
const NodePath &from_node_path,
const Entries &entries) {
122 bool got_max =
false;
123 bool got_min =
false;
124 PN_stdfloat max_height = 0.0f;
125 PN_stdfloat min_height = 0.0f;
131 Entries::const_iterator ei;
132 for (ei = entries.begin(); ei != entries.end(); ++ei) {
139 if (collide_cat.is_debug()) {
141 <<
"Intersection point detected at " << point <<
"\n";
143 PN_stdfloat height = point[2];
144 if(height < _offset + _reach) {
145 valid_entries.push_back(entry);
146 if (!got_max || height > max_height) {
152 if (!got_min || height < min_height) {
159 if (!got_max && got_min) {
164 max_height = min_height;
166 valid_entries.push_back(lowest);
171 cout<<
"\ncolliding with:\n";
172 for (Colliding::const_iterator i = _current_colliding.begin(); i != _current_colliding.end(); ++i) {
173 (**i).write(cout, 2);
175 cout<<
"\nhighest:\n";
176 highest->write(cout, 2);
182 _current_colliding.clear();
189 for (vi = valid_entries.begin(); vi != valid_entries.end(); ++vi) {
227 bool CollisionHandlerGravity::
231 FromEntries::const_iterator fi;
232 for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) {
233 const NodePath &from_node_path = (*fi).first;
234 const Entries &entries = (*fi).second;
236 Colliders::iterator ci;
237 ci = _colliders.
find(from_node_path);
238 if (ci == _colliders.end()) {
243 << get_type() <<
" doesn't know about " 244 << from_node_path <<
", disabling.\n";
247 ColliderDef &def = (*ci).second;
248 PN_stdfloat max_height = set_highest_collision(def._target, from_node_path, entries);
251 #if OLD_COLLISION_HANDLER_GRAVITY 252 PN_stdfloat adjust = max_height + _offset;
254 PN_stdfloat adjust = max_height + _offset;
256 if (_current_velocity > 0.0f || !IS_THRESHOLD_ZERO(adjust, 0.001)) {
257 if (collide_cat.is_debug()) {
259 <<
"Adjusting height by " << adjust <<
"\n";
262 if (_current_velocity > 0.0f || adjust) {
268 PN_stdfloat gravity_adjust = _current_velocity * dt + 0.5 * -_gravity * dt * dt;
273 adjust += max((PN_stdfloat)0.0, gravity_adjust);
276 adjust = max(adjust, gravity_adjust);
278 _current_velocity -= _gravity * dt;
280 _airborne_height = -(max_height + _offset) + adjust;
281 assert(_airborne_height >= -0.001f);
284 if (_airborne_height < 0.001f && _current_velocity < 0.001f) {
286 _impact_velocity = _current_velocity;
288 _current_velocity = _airborne_height = 0.0f;
289 }
else if (_legacy_mode) {
291 _current_colliding.clear();
294 CPT(TransformState) trans = def._target.get_transform();
297 def._target.set_transform(trans->set_pos(pos));
298 def.updated_transform();
300 apply_linear_force(def,
LVector3(0.0f, 0.0f, adjust));
303 _current_velocity = _airborne_height = 0.0f;
304 if (collide_cat.is_spam()) {
306 <<
"Leaving height unchanged.\n";
320 void CollisionHandlerGravity::
321 apply_linear_force(ColliderDef &def,
const LVector3 &force) {
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
bool has_surface_point() const
Returns true if the surface point has been specified, false otherwise.
This is the base class for all three-component vectors and points.
LPoint3 get_surface_point(const NodePath &space) const
Returns the point, on the surface of the "into" object, at which a collision is detected.
NodePath get_into_node_path() const
Returns the NodePath that represents the specific CollisionNode or GeomNode instance that was collide...
LVector3 get_surface_normal(const NodePath &space) const
Returns the surface normal of the "into" object at the point at which a collision is detected...
static const LVector3f & zero()
Returns a zero-length vector.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
This is our own Panda specialization on the default STL vector.
NodePath find(const string &path) const
Searches for a node below the referenced node that matches the indicated string.
const CollisionSolid * get_into() const
Returns the CollisionSolid pointer for the particular solid was collided into.
Defines a single collision event.
virtual void add_entry(CollisionEntry *entry)
Called between a begin_group() .
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
NodePath get_from_node_path() const
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
TypeHandle is the identifier used to differentiate C++ class types.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
double get_dt(Thread *current_thread=Thread::get_current_thread()) const
Returns the elapsed time for the previous frame: the number of seconds elapsed between the last two c...