mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
added collsionHandlerGravity
This commit is contained in:
parent
d8f3a308ac
commit
50d377f8f0
@ -14,6 +14,7 @@
|
||||
collisionHandler.h \
|
||||
collisionHandlerEvent.I collisionHandlerEvent.h \
|
||||
collisionHandlerFloor.I collisionHandlerFloor.h \
|
||||
collisionHandlerGravity.I collisionHandlerGravity.h \
|
||||
collisionHandlerPhysical.I collisionHandlerPhysical.h \
|
||||
collisionHandlerPusher.I collisionHandlerPusher.h \
|
||||
collisionHandlerQueue.h \
|
||||
@ -36,6 +37,7 @@
|
||||
collisionHandler.cxx \
|
||||
collisionHandlerEvent.cxx \
|
||||
collisionHandlerFloor.cxx \
|
||||
collisionHandlerGravity.cxx \
|
||||
collisionHandlerPhysical.cxx \
|
||||
collisionHandlerPusher.cxx \
|
||||
collisionHandlerQueue.cxx \
|
||||
@ -57,6 +59,7 @@
|
||||
collisionHandler.h \
|
||||
collisionHandlerEvent.I collisionHandlerEvent.h \
|
||||
collisionHandlerFloor.I collisionHandlerFloor.h \
|
||||
collisionHandlerGravity.I collisionHandlerGravity.h \
|
||||
collisionHandlerPhysical.I collisionHandlerPhysical.h \
|
||||
collisionHandlerPusher.I collisionHandlerPusher.h \
|
||||
collisionHandlerQueue.h \
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "collisionHandler.cxx"
|
||||
#include "collisionHandlerEvent.cxx"
|
||||
#include "collisionHandlerFloor.cxx"
|
||||
#include "collisionHandlerGravity.cxx"
|
||||
#include "collisionHandlerPhysical.cxx"
|
||||
#include "collisionHandlerPusher.cxx"
|
||||
#include "collisionHandlerQueue.cxx"
|
||||
|
@ -124,7 +124,6 @@ handle_entries() {
|
||||
def.updated_transform();
|
||||
|
||||
apply_linear_force(def, LVector3f(0.0f, 0.0f, adjust));
|
||||
|
||||
} else {
|
||||
if (collide_cat.is_spam()) {
|
||||
collide_cat.spam()
|
||||
|
157
panda/src/collide/collisionHandlerGravity.I
Executable file
157
panda/src/collide/collisionHandlerGravity.I
Executable file
@ -0,0 +1,157 @@
|
||||
// Filename: CollisionHandlerGravity.I
|
||||
// Created by: drose (16Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::set_offset
|
||||
// Access: Public
|
||||
// Description: Sets the linear offset to add to (or subtract from)
|
||||
// the highest detected collision point to determine the
|
||||
// actual height at which to set the collider.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionHandlerGravity::
|
||||
set_offset(float offset) {
|
||||
_offset = offset;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::get_offset
|
||||
// Access: Public
|
||||
// Description: Returns the linear offset to add to (or subtract from)
|
||||
// the highest detected collision point to determine the
|
||||
// actual height at which to set the collider.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float CollisionHandlerGravity::
|
||||
get_offset() const {
|
||||
return _offset;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::get_airborne_height
|
||||
// Access: Public
|
||||
// Description: Return the height of the object from the ground.
|
||||
//
|
||||
// The object might not necessarily be at rest. Use
|
||||
// is_on_ground() if you want to know whether the
|
||||
// object is on the ground and at rest.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float CollisionHandlerGravity::
|
||||
get_airborne_height() const {
|
||||
return _airborne_height;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::is_on_ground
|
||||
// Access: Public
|
||||
// Description: Is the object at rest?
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CollisionHandlerGravity::
|
||||
is_on_ground() const {
|
||||
// Testing for 0.0f here is not as foolhardy as it may appear. The
|
||||
// handle_entries() function will set these values to 0.0f if they
|
||||
// are within a threshold.
|
||||
return get_airborne_height() == 0.0f && _current_velocity == 0.0f;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::add_velocity
|
||||
// Access: Public
|
||||
// Description: Adds the sepcified amount to the current velocity.
|
||||
// This is mostly here allow this common operation to
|
||||
// be faster for scripting, but it's also more concise
|
||||
// even in cpp.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionHandlerGravity::
|
||||
add_velocity(float velocity) {
|
||||
_current_velocity += velocity;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::set_velocity
|
||||
// Access: Public
|
||||
// Description: Sets the current vertical velocity.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionHandlerGravity::
|
||||
set_velocity(float velocity) {
|
||||
_current_velocity = velocity;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::get_velocity
|
||||
// Access: Public
|
||||
// Description: Gets the current vertical velocity.
|
||||
//
|
||||
// Generally, negative values mean the object is in
|
||||
// free fall; while postive values mean the object has
|
||||
// vertical thrust.
|
||||
//
|
||||
// A zero value does not necessarily mean the object
|
||||
// on the ground, it may also be weightless and/or at
|
||||
// the apex of its jump.
|
||||
//
|
||||
// See Also: is_on_ground() and get_gravity()
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float CollisionHandlerGravity::
|
||||
get_velocity() const {
|
||||
return _current_velocity;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::set_gravity
|
||||
// Access: Public
|
||||
// Description: Sets the linear gravity force (always plumb).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionHandlerGravity::
|
||||
set_gravity(float gravity) {
|
||||
_gravity = gravity;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::get_gravity
|
||||
// Access: Public
|
||||
// Description: Gets the linear gravity force (always plumb).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float CollisionHandlerGravity::
|
||||
get_gravity() const {
|
||||
return _gravity;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::set_max_velocity
|
||||
// Access: Public
|
||||
// Description: Sets the maximum speed at which the object will be
|
||||
// allowed to descend towards a floor below it, in units
|
||||
// per second. Set this to zero to allow it to
|
||||
// instantly teleport any distance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionHandlerGravity::
|
||||
set_max_velocity(float max_velocity) {
|
||||
_max_velocity = max_velocity;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::get_max_velocity
|
||||
// Access: Public
|
||||
// Description: Retrieves the maximum speed at which the object will
|
||||
// be allowed to descend towards a floor below it, in
|
||||
// units per second. See set_max_velocity().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float CollisionHandlerGravity::
|
||||
get_max_velocity() const {
|
||||
return _max_velocity;
|
||||
}
|
175
panda/src/collide/collisionHandlerGravity.cxx
Executable file
175
panda/src/collide/collisionHandlerGravity.cxx
Executable file
@ -0,0 +1,175 @@
|
||||
// Filename: CollisionHandlerGravity.cxx
|
||||
// Created by: drose (16Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "CollisionHandlerGravity.h"
|
||||
#include "collisionNode.h"
|
||||
#include "collisionEntry.h"
|
||||
#include "config_collide.h"
|
||||
|
||||
#include "clockObject.h"
|
||||
|
||||
TypeHandle CollisionHandlerGravity::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CollisionHandlerGravity::
|
||||
CollisionHandlerGravity() {
|
||||
_offset = 0.0f;
|
||||
_airborne_height = 0.0f;
|
||||
_gravity = 32.174f;
|
||||
_current_velocity = 0.0f;
|
||||
_max_velocity = 400.0f;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CollisionHandlerGravity::
|
||||
~CollisionHandlerGravity() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::handle_entries
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called by the parent class after all collisions have
|
||||
// been detected, this manages the various collisions
|
||||
// and moves around the nodes as necessary.
|
||||
//
|
||||
// The return value is normally true, but it may be
|
||||
// false to indicate the CollisionTraverser should
|
||||
// disable this handler from being called in the future.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CollisionHandlerGravity::
|
||||
handle_entries() {
|
||||
bool okflag = true;
|
||||
|
||||
FromEntries::const_iterator fi;
|
||||
for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) {
|
||||
const NodePath &from_node_path = (*fi).first;
|
||||
const Entries &entries = (*fi).second;
|
||||
|
||||
Colliders::iterator ci;
|
||||
ci = _colliders.find(from_node_path);
|
||||
if (ci == _colliders.end()) {
|
||||
// Hmm, someone added a CollisionNode to a traverser and gave
|
||||
// it this CollisionHandler pointer--but they didn't tell us
|
||||
// about the node.
|
||||
collide_cat.error()
|
||||
<< get_type() << " doesn't know about "
|
||||
<< from_node_path << ", disabling.\n";
|
||||
okflag = false;
|
||||
} else {
|
||||
ColliderDef &def = (*ci).second;
|
||||
{
|
||||
// Get the maximum height for all collisions with this node.
|
||||
bool got_max = false;
|
||||
float max_height = 0.0f;
|
||||
|
||||
Entries::const_iterator ei;
|
||||
for (ei = entries.begin(); ei != entries.end(); ++ei) {
|
||||
CollisionEntry *entry = (*ei);
|
||||
nassertr(entry != (CollisionEntry *)NULL, false);
|
||||
nassertr(from_node_path == entry->get_from_node_path(), false);
|
||||
|
||||
if (entry->has_surface_point()) {
|
||||
LPoint3f point = entry->get_surface_point(def._target);
|
||||
if (collide_cat.is_debug()) {
|
||||
collide_cat.debug()
|
||||
<< "Intersection point detected at " << point << "\n";
|
||||
}
|
||||
|
||||
float height = point[2];
|
||||
if (!got_max || height > max_height) {
|
||||
got_max = true;
|
||||
max_height = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now set our height accordingly.
|
||||
float adjust = max_height + _offset;
|
||||
if (_current_velocity > 0.0f || !IS_THRESHOLD_ZERO(adjust, 0.001)) {
|
||||
if (collide_cat.is_debug()) {
|
||||
collide_cat.debug()
|
||||
<< "Adjusting height by " << adjust << "\n";
|
||||
}
|
||||
|
||||
if (_current_velocity > 0.0f || adjust < -0.001f) {
|
||||
// ...we have a vertical thrust,
|
||||
// ...or the node is above the floor, so it is airborne.
|
||||
float dt = min(ClockObject::get_global_clock()->get_dt(), 0.1f);
|
||||
// The sign in this equation is reversed from normal. This is
|
||||
// because _current_velocity is a scaler and the equation normally
|
||||
// has a vector. I suppose the sign of _gravity could have been
|
||||
// reversed, but I think it makes the get_*() set_*()
|
||||
// more intuitive to do it this way.
|
||||
float gravity_adjust = _current_velocity * dt - 0.5 * _gravity * dt * dt;
|
||||
if (adjust > 0.0f) {
|
||||
// ...the node is under the floor, so it has landed.
|
||||
// Keep the adjust to bring us up to the ground and
|
||||
// then add the gravity_adjust to get us airborne:
|
||||
adjust += max(0.0f, gravity_adjust);
|
||||
} else {
|
||||
// ...the node is above the floor, so it is airborne.
|
||||
adjust = max(adjust, gravity_adjust);
|
||||
}
|
||||
_current_velocity -= _gravity * dt;
|
||||
// Record the airborne height in case someone else needs it:
|
||||
_airborne_height = -max_height + adjust;
|
||||
}
|
||||
|
||||
if (_airborne_height < 0.001f && _current_velocity < 0.001f) {
|
||||
// ...the node is under the floor, so it has landed.
|
||||
// These values are used by is_on_ground().
|
||||
_current_velocity = _airborne_height = 0.0f;
|
||||
}
|
||||
|
||||
CPT(TransformState) trans = def._target.get_transform();
|
||||
LVecBase3f pos = trans->get_pos();
|
||||
pos[2] += adjust;
|
||||
def._target.set_transform(trans->set_pos(pos));
|
||||
def.updated_transform();
|
||||
|
||||
apply_linear_force(def, LVector3f(0.0f, 0.0f, adjust));
|
||||
} else {
|
||||
_current_velocity = _airborne_height = 0.0f;
|
||||
if (collide_cat.is_spam()) {
|
||||
collide_cat.spam()
|
||||
<< "Leaving height unchanged.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return okflag;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandlerGravity::apply_linear_force
|
||||
// Access: Protected, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CollisionHandlerGravity::
|
||||
apply_linear_force(ColliderDef &def, const LVector3f &force) {
|
||||
}
|
91
panda/src/collide/collisionHandlerGravity.h
Executable file
91
panda/src/collide/collisionHandlerGravity.h
Executable file
@ -0,0 +1,91 @@
|
||||
// Filename: CollisionHandlerGravity.h
|
||||
// Created by: drose (16Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef CollisionHandlerGravity_H
|
||||
#define CollisionHandlerGravity_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "collisionHandlerPhysical.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : CollisionHandlerGravity
|
||||
// Description : A specialized kind of CollisionHandler that sets the
|
||||
// Z height of the collider to a fixed linear offset
|
||||
// from the highest detected collision point each frame.
|
||||
// It's intended to implement walking around on a floor
|
||||
// of varying height by casting a ray down from the
|
||||
// avatar's head.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA CollisionHandlerGravity : public CollisionHandlerPhysical {
|
||||
PUBLISHED:
|
||||
CollisionHandlerGravity();
|
||||
virtual ~CollisionHandlerGravity();
|
||||
|
||||
INLINE void set_offset(float offset);
|
||||
INLINE float get_offset() const;
|
||||
|
||||
INLINE float get_airborne_height() const;
|
||||
INLINE bool is_on_ground() const;
|
||||
|
||||
INLINE void add_velocity(float velocity);
|
||||
INLINE void set_velocity(float velocity);
|
||||
INLINE float get_velocity() const;
|
||||
|
||||
INLINE void set_gravity(float gravity);
|
||||
INLINE float get_gravity() const;
|
||||
|
||||
INLINE void set_max_velocity(float max_vel);
|
||||
INLINE float get_max_velocity() const;
|
||||
|
||||
protected:
|
||||
virtual bool handle_entries();
|
||||
virtual void apply_linear_force(ColliderDef &def, const LVector3f &force);
|
||||
|
||||
private:
|
||||
float _offset;
|
||||
float _airborne_height;
|
||||
float _gravity;
|
||||
float _current_velocity;
|
||||
float _max_velocity;
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
CollisionHandlerPhysical::init_type();
|
||||
register_type(_type_handle, "CollisionHandlerGravity",
|
||||
CollisionHandlerPhysical::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;
|
||||
};
|
||||
|
||||
#include "CollisionHandlerGravity.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user