15 #include "collisionHandlerFluidPusher.h"
16 #include "collisionNode.h"
17 #include "collisionEntry.h"
18 #include "collisionPolygon.h"
19 #include "collisionSphere.h"
20 #include "config_collide.h"
23 TypeHandle CollisionHandlerFluidPusher::_type_handle;
30 CollisionHandlerFluidPusher::
31 CollisionHandlerFluidPusher() {
32 _wants_all_potential_collidees =
true;
67 bool CollisionHandlerFluidPusher::
111 FromEntries::iterator fei;
112 for (fei = _from_entries.begin(); fei != _from_entries.end(); ++fei) {
113 NodePath from_node_path = fei->first;
114 Entries *orig_entries = &fei->second;
116 Colliders::iterator ci;
117 ci = _colliders.find(from_node_path);
118 if (ci == _colliders.end()) {
123 <<
"CollisionHandlerFluidPusher doesn't know about "
124 << from_node_path <<
", disabling.\n";
127 ColliderDef &def = (*ci).second;
133 Entries entries(*orig_entries);
141 CPT(TransformState) prev_trans(from_node_path.get_prev_transform(wrt_node));
142 const
LPoint3 orig_prev_pos(prev_trans->get_pos());
146 DCAST_INTO_R(sphere, entries.front()->get_from(), 0);
148 from_node_path.set_pos(wrt_node, 0,0,0);
150 from_node_path.get_transform(wrt_node)->get_mat());
151 from_node_path.set_pos(wrt_node, orig_pos);
154 LPoint3 candidate_final_pos(orig_pos);
156 LPoint3 uncollided_pos(candidate_final_pos);
160 reverse_vec.normalize();
170 Entries::const_iterator cei;
171 for (cei = entries.begin(); cei != entries.end(); ++cei) {
190 collide_cat.warning()
191 <<
"Cannot shove on " << from_node_path <<
" for collision into "
196 contact_pos -= sphere_offset;
198 uncollided_pos = candidate_final_pos;
199 candidate_final_pos = contact_pos;
201 LVector3 proj_surface_normal(contact_normal);
203 LVector3 norm_proj_surface_normal(proj_surface_normal);
204 norm_proj_surface_normal.normalize();
206 LVector3 blocked_movement(uncollided_pos - contact_pos);
208 PN_stdfloat push_magnitude(-blocked_movement.dot(proj_surface_normal));
209 if (push_magnitude < 0.0f) {
211 candidate_final_pos = contact_pos;
215 candidate_final_pos = uncollided_pos + (norm_proj_surface_normal * push_magnitude);
218 from_node_path.
set_pos(wrt_node, candidate_final_pos);
219 CPT(TransformState) prev_trans(from_node_path.get_prev_transform(wrt_node));
220 prev_trans = prev_trans->set_pos(contact_pos);
221 from_node_path.set_prev_transform(wrt_node, prev_trans);
225 CPT(TransformState) new_prev_trans(from_node_path.get_prev_transform(wrt_node));
226 const
LPoint3 new_prev_pos(new_prev_trans->get_pos());
230 N = from_node_path.get_pos_delta(wrt_node);
233 Entries::iterator ei;
235 for (ei = entries.begin(); ei != entries.end(); ++ei) {
240 entry->_from_node_path = from_node_path;
242 PT(
CollisionEntry) result = entry->get_from()->test_intersection(**ei);
244 new_entries.push_back(result);
248 entries.swap(new_entries);
252 from_node_path.
set_pos(wrt_node, orig_pos);
255 prev_trans = prev_trans->set_pos(orig_prev_pos);
258 LVector3 net_shove(candidate_final_pos - orig_pos);
260 force_normal.normalize();
263 def._target.set_pos(wrt_node, candidate_final_pos);
267 apply_net_shove(def, net_shove, force_normal);
268 apply_linear_force(def, force_normal);
const NodePath & get_center() const
Returns the NodePath specified with set_center, or the empty NodePath if nothing has been specified...
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
const CollisionSolid * get_from() const
Returns the CollisionSolid pointer for the particular solid that triggered this collision.
void set_pos(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the translation component of the transform, leaving rotation and scale untouched.
PN_stdfloat get_t() const
returns time value for this collision relative to other CollisionEntries
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
A spherical collision volume or object.
LPoint3 get_pos() const
Retrieves the translation component of the transform.
Defines a single collision event.
const CollisionSolid * get_into() const
Returns the CollisionSolid pointer for the particular solid was collided into.
bool get_all_contact_info(const NodePath &space, LPoint3 &contact_pos, LVector3 &contact_normal) const
Simultaneously transforms the contact position and contact normal of the collision into the indicated...
bool is_tangible() const
Returns whether the solid is considered 'tangible' or not.
NodePath get_into_node_path() const
Returns the NodePath that represents the specific CollisionNode or GeomNode instance that was collide...
virtual void add_entry(CollisionEntry *entry)
Called between a begin_group() .
NodePath get_from_node_path() const
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
LVector3 get_pos_delta() const
Returns the delta vector from this node's position in the previous frame (according to set_prev_trans...
void set_prev_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Sets the transform that represents this node's "previous" position, one frame ago, for the purposes of detecting motion for accurate collision calculations.
TypeHandle is the identifier used to differentiate C++ class types.
bool collided() const
returns true if this represents an actual collision as opposed to a potential collision, needed for iterative collision resolution where path of collider changes mid-frame
const TransformState * get_prev_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the transform that has been set as this node's "previous" position.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
virtual void add_entry(CollisionEntry *entry)
Called between a begin_group() .
void reset_collided()
prepare for another collision test
bool has_into() const
Returns true if the "into" solid is, in fact, a CollisionSolid, and its pointer is known (in which ca...