fluid pusher almost working
This commit is contained in:
parent
56a1e82988
commit
519ae6bdac
|
|
@ -7,6 +7,7 @@
|
|||
#include "collisionHandlerGravity.cxx"
|
||||
#include "collisionHandlerPhysical.cxx"
|
||||
#include "collisionHandlerPusher.cxx"
|
||||
#include "collisionHandlerFluidPusher.cxx"
|
||||
#include "collisionHandlerQueue.cxx"
|
||||
#include "collisionDSSolid.cxx"
|
||||
#include "collisionInvSphere.cxx"
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
INLINE CollisionEntry::
|
||||
CollisionEntry() {
|
||||
_flags = 0;
|
||||
_t = 1.f;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -125,6 +126,28 @@ get_into_node_path() const {
|
|||
return _into_node_path;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::set_t
|
||||
// Access: Published
|
||||
// Description: Sets a time value for this collision relative to
|
||||
// other CollisionEntries
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionEntry::
|
||||
set_t(float t) {
|
||||
_t = t;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::set_t
|
||||
// Access: Published
|
||||
// Description: returns time value for this collision relative to
|
||||
// other CollisionEntries
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float CollisionEntry::
|
||||
get_t() const {
|
||||
return _t;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_respect_prev_transform
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ CollisionEntry(const CollisionEntry ©) :
|
|||
_from_node_path(copy._from_node_path),
|
||||
_into_node_path(copy._into_node_path),
|
||||
_into_clip_planes(copy._into_clip_planes),
|
||||
_t(copy._t),
|
||||
_flags(copy._flags),
|
||||
_surface_point(copy._surface_point),
|
||||
_surface_normal(copy._surface_normal),
|
||||
|
|
@ -57,6 +58,7 @@ operator = (const CollisionEntry ©) {
|
|||
_from_node_path = copy._from_node_path;
|
||||
_into_node_path = copy._into_node_path;
|
||||
_into_clip_planes = copy._into_clip_planes;
|
||||
_t = copy._t;
|
||||
_flags = copy._flags;
|
||||
_surface_point = copy._surface_point;
|
||||
_surface_normal = copy._surface_normal;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,9 @@ PUBLISHED:
|
|||
INLINE NodePath get_from_node_path() const;
|
||||
INLINE NodePath get_into_node_path() const;
|
||||
|
||||
INLINE void set_t(float t);
|
||||
INLINE float get_t() const;
|
||||
|
||||
INLINE bool get_respect_prev_transform() const;
|
||||
|
||||
INLINE void set_surface_point(const LPoint3f &point);
|
||||
|
|
@ -108,6 +111,7 @@ private:
|
|||
NodePath _from_node_path;
|
||||
NodePath _into_node_path;
|
||||
CPT(ClipPlaneAttrib) _into_clip_planes;
|
||||
float _t;
|
||||
|
||||
enum Flags {
|
||||
F_has_surface_point = 0x0001,
|
||||
|
|
@ -141,6 +145,7 @@ private:
|
|||
static TypeHandle _type_handle;
|
||||
|
||||
friend class CollisionTraverser;
|
||||
friend class CollisionHandlerFluidPusher;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const CollisionEntry &entry);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
// Filename: collisionHandler.I
|
||||
// Created by: WDIG (15Aug07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandler::wants_all_potential_collidees
|
||||
// Access: Private
|
||||
// Description: Returns true if handler wants to know about all
|
||||
// solids that are within the collider's bounding
|
||||
// volume
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CollisionHandler::
|
||||
wants_all_potential_collidees() const {
|
||||
return _wants_all_potential_collidees;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandler::set_root
|
||||
// Access: Private
|
||||
// Description: Sets the root of the collision traversal. Only set
|
||||
// if wants_all_potential_collidees is true
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionHandler::
|
||||
set_root(const NodePath &root) {
|
||||
_root = &root;
|
||||
}
|
||||
|
|
@ -20,6 +20,16 @@
|
|||
|
||||
TypeHandle CollisionHandler::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandler::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CollisionHandler::
|
||||
CollisionHandler() {
|
||||
_wants_all_potential_collidees = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionHandler::begin_group
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
#include "typedReferenceCount.h"
|
||||
#include "nodePath.h"
|
||||
|
||||
class CollisionEntry;
|
||||
|
||||
|
|
@ -35,10 +36,15 @@ class CollisionEntry;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_COLLIDE CollisionHandler : public TypedReferenceCount {
|
||||
public:
|
||||
CollisionHandler();
|
||||
|
||||
virtual void begin_group();
|
||||
virtual void add_entry(CollisionEntry *entry);
|
||||
virtual bool end_group();
|
||||
|
||||
INLINE bool wants_all_potential_collidees() const;
|
||||
INLINE void set_root(const NodePath &root);
|
||||
|
||||
PUBLISHED:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
@ -55,12 +61,18 @@ public:
|
|||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
protected:
|
||||
bool _wants_all_potential_collidees;
|
||||
const NodePath *_root;
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class CollisionTraverser;
|
||||
};
|
||||
|
||||
#include "collisionHandler.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -102,13 +102,13 @@ handle_entries() {
|
|||
7. go to 2
|
||||
*/
|
||||
bool okflag = true;
|
||||
|
||||
|
||||
if (!_horizontal) {
|
||||
collide_cat.error() << "collisionHandlerFluidPusher::handle_entries is only supported in "
|
||||
"horizontal mode" << endl;
|
||||
nassertr(false, false);
|
||||
}
|
||||
|
||||
|
||||
// for every fluid mover being pushed...
|
||||
FromEntries::iterator fei;
|
||||
for (fei = _from_entries.begin(); fei != _from_entries.end(); ++fei) {
|
||||
|
|
@ -129,17 +129,30 @@ handle_entries() {
|
|||
ColliderDef &def = (*ci).second;
|
||||
|
||||
// extract the collision entries into a vector that we can safely modify
|
||||
Entries SCS(*entries);
|
||||
Entries entries(*entries);
|
||||
Entries next_entries;
|
||||
|
||||
// extract out the initial set of collision solids
|
||||
CollisionSolids SCS;
|
||||
|
||||
Entries::iterator ei;
|
||||
for (ei = entries.begin(); ei != entries.end(); ++ei) {
|
||||
SCS.push_back((*ei)->get_into());
|
||||
}
|
||||
|
||||
// currently we only support spheres as the collider
|
||||
const CollisionSphere *sphere;
|
||||
DCAST_INTO_R(sphere, (*SCS.front()).get_from(), 0);
|
||||
DCAST_INTO_R(sphere, (*entries.front()).get_from(), 0);
|
||||
// use a slightly larger radius value so that when we move along
|
||||
// collision planes we don't re-collide
|
||||
float sphere_radius = sphere->get_radius() * 1.001;
|
||||
|
||||
// make a copy of the original from_nodepath that we can mess with
|
||||
// in the process of calculating the final position
|
||||
_from_node_path_copy = from_node_path.copy_to(from_node_path.get_parent());
|
||||
|
||||
LPoint3f N(from_node_path.get_pos_delta(*_root));
|
||||
const LPoint3f orig_pos(from_node_path.get_pos());
|
||||
const LPoint3f orig_pos(_from_node_path_copy.get_pos());
|
||||
// this will hold the final calculated position
|
||||
LPoint3f PosX(orig_pos);
|
||||
|
||||
|
|
@ -157,20 +170,17 @@ handle_entries() {
|
|||
// if both of these become true, we're stuck in a 'corner'
|
||||
bool left_halfspace_obstructed = false;
|
||||
bool right_halfspace_obstructed = false;
|
||||
LVector3f left_plane_normal;
|
||||
LVector3f right_plane_normal;
|
||||
float left_plane_dot = 200.0f;
|
||||
float right_plane_dot = 200.0f;
|
||||
|
||||
// iterate until the mover runs out of movement or gets stuck
|
||||
while (true) {
|
||||
CollisionEntry *C = 0;
|
||||
Entries::iterator ei;
|
||||
// find the first (earliest) collision
|
||||
for (ei = SCS.begin(); ei != SCS.end(); ++ei) {
|
||||
for (ei = entries.begin(); ei != entries.end(); ++ei) {
|
||||
CollisionEntry *entry = (*ei);
|
||||
nassertr(entry != (CollisionEntry *)NULL, false);
|
||||
if (entry->get_t() < C->get_t()) {
|
||||
if ((C == 0) || (entry->get_t() < C->get_t())) {
|
||||
nassertr(from_node_path == entry->get_from_node_path(), false);
|
||||
C = entry;
|
||||
break;
|
||||
|
|
@ -186,12 +196,12 @@ handle_entries() {
|
|||
nassertr(C->has_surface_point(), true);
|
||||
nassertr(C->has_surface_normal(), true);
|
||||
nassertr(C->has_interior_point(), true);
|
||||
LVector3f surface_normal = C->get_surface_normal(from_node_path);
|
||||
LVector3f surface_normal = C->get_surface_normal(_from_node_path_copy);
|
||||
if (_horizontal) {
|
||||
surface_normal[2] = 0.0f;
|
||||
}
|
||||
surface_normal.normalize();
|
||||
PosX = C->get_surface_point(from_node_path) + (sphere_radius * surface_normal);
|
||||
PosX = C->get_surface_point(_from_node_path_copy) + (sphere_radius * surface_normal);
|
||||
|
||||
// check to see if we're stuck, given this collision
|
||||
float dot = right_unit.dot(surface_normal);
|
||||
|
|
@ -204,7 +214,6 @@ handle_entries() {
|
|||
break;
|
||||
}
|
||||
left_halfspace_obstructed = true;
|
||||
left_plane_normal = surface_normal;
|
||||
}
|
||||
} else {
|
||||
// negative dot means plane is coming from the right (looking along original
|
||||
|
|
@ -216,11 +225,29 @@ handle_entries() {
|
|||
break;
|
||||
}
|
||||
right_halfspace_obstructed = true;
|
||||
right_plane_normal = surface_normal;
|
||||
}
|
||||
}
|
||||
|
||||
// set up new current/last positions, re-calculate collisions
|
||||
CPT(TransformState) prev_trans(_from_node_path_copy.get_prev_transform());
|
||||
prev_trans->set_pos(_from_node_path_copy.get_pos());
|
||||
_from_node_path_copy.set_prev_transform(prev_trans);
|
||||
_from_node_path_copy.set_pos(PosX);
|
||||
|
||||
// calculate new collisions given new movement vector
|
||||
CollisionEntry new_entry;
|
||||
new_entry._from_node_path = _from_node_path_copy;
|
||||
new_entry._from = sphere;
|
||||
next_entries.clear();
|
||||
CollisionSolids::iterator csi;
|
||||
for (csi = SCS.begin(); csi != SCS.end(); ++csi) {
|
||||
PT(CollisionEntry) result = (*csi)->test_intersection_from_sphere(new_entry);
|
||||
if (result != (CollisionEntry *)NULL) {
|
||||
next_entries.push_back(result);
|
||||
}
|
||||
}
|
||||
// swap in the new set of collision events
|
||||
entries.swap(next_entries);
|
||||
}
|
||||
|
||||
LVector3f net_shove(PosX - orig_pos);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "collisionSolid.h"
|
||||
#include "collisionHandlerPusher.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -37,8 +38,12 @@ public:
|
|||
virtual void add_entry(CollisionEntry *entry);
|
||||
|
||||
protected:
|
||||
typedef pvector< CPT(CollisionSolid) > CollisionSolids;
|
||||
|
||||
virtual bool handle_entries();
|
||||
|
||||
NodePath _from_node_path_copy;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ protected:
|
|||
const LVector3f &force_normal);
|
||||
virtual void apply_linear_force(ColliderDef &def, const LVector3f &force);
|
||||
|
||||
private:
|
||||
bool _horizontal;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
// is as good as any other.
|
||||
surface_normal.set(1.0, 0.0, 0.0);
|
||||
} else {
|
||||
surface_normal = -vec / vec_length;
|
||||
surface_normal = vec / -vec_length;
|
||||
}
|
||||
|
||||
LVector3f normal = (has_effective_normal() && sphere->get_respect_effective_normal()) ? get_effective_normal() : surface_normal;
|
||||
|
|
|
|||
|
|
@ -414,6 +414,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
LPoint3f orig_center = sphere->get_center() * wrt_mat;
|
||||
LPoint3f from_center = orig_center;
|
||||
bool moved_from_center = false;
|
||||
float t = 1.0f;
|
||||
|
||||
if (wrt_prev_space != wrt_space) {
|
||||
// If we have a delta between the previous position and the
|
||||
|
|
@ -439,13 +440,15 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
// at the point along its path that is closest to intersecting
|
||||
// the plane. This may be the actual intersection point, or it
|
||||
// may be the starting point or the final point.
|
||||
float t = -(dist_to_plane(a) / dot);
|
||||
t = -(dist_to_plane(a) / dot);
|
||||
if (t >= 1.0f) {
|
||||
// Leave it where it is.
|
||||
t = 1.0f;
|
||||
|
||||
} else if (t < 0.0f) {
|
||||
from_center = a;
|
||||
moved_from_center = true;
|
||||
t = 0.0f;
|
||||
|
||||
} else {
|
||||
from_center = a + t * delta;
|
||||
|
|
@ -556,6 +559,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
new_entry->set_surface_normal(normal);
|
||||
new_entry->set_surface_point(from_center - normal * dist);
|
||||
new_entry->set_interior_point(from_center - normal * (dist + into_depth));
|
||||
new_entry->set_t(t);
|
||||
|
||||
return new_entry;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ private:
|
|||
friend class CollisionLine;
|
||||
friend class CollisionRay;
|
||||
friend class CollisionSegment;
|
||||
friend class CollisionHandlerFluidPusher;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const CollisionSolid &cs) {
|
||||
|
|
|
|||
|
|
@ -288,6 +288,7 @@ traverse(const NodePath &root) {
|
|||
|
||||
Handlers::iterator hi;
|
||||
for (hi = _handlers.begin(); hi != _handlers.end(); ++hi) {
|
||||
(*hi).first->set_root(root);
|
||||
(*hi).first->begin_group();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -213,6 +213,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
into_intersection_point = from_a + t1 * from_direction;
|
||||
}
|
||||
set_intersection_point(new_entry, into_intersection_point, from_radius);
|
||||
new_entry->set_t(t1);
|
||||
|
||||
return new_entry;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue