Panda3D
collisionHandlerPhysical.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file collisionHandlerPhysical.cxx
10  * @author drose
11  * @date 2002-03-16
12  */
13 
15 #include "config_collide.h"
16 
17 #include "transformState.h"
18 
19 TypeHandle CollisionHandlerPhysical::_type_handle;
20 
21 
22 /**
23  *
24  */
25 CollisionHandlerPhysical::
26 CollisionHandlerPhysical() {
27  _has_contact = false;
28 }
29 
30 /**
31  *
32  */
33 CollisionHandlerPhysical::
34 ~CollisionHandlerPhysical() {
35 }
36 
37 /**
38  * Will be called by the CollisionTraverser before a new traversal is begun.
39  * It instructs the handler to reset itself in preparation for a number of
40  * CollisionEntries to be sent.
41  */
45  _from_entries.clear();
46  _has_contact = false;
47 }
48 
49 /**
50  * Called between a begin_group() .. end_group() sequence for each collision
51  * that is detected.
52  */
55  nassertv(entry != nullptr);
57 
58  if (entry->get_from()->is_tangible() &&
59  (!entry->has_into() || entry->get_into()->is_tangible())) {
60 
61  if (has_center()) {
62  // If a center is specified, we have to make sure the surface is more-
63  // or-less facing it.
64  if (!entry->has_surface_point() || !entry->has_surface_normal()) {
65  return;
66  }
67 
68  LPoint3 point = entry->get_surface_point(_center);
69  LVector3 normal = entry->get_surface_normal(_center);
70  if (point.dot(normal) > 0) {
71  return;
72  }
73  }
74 
75  _from_entries[entry->get_from_node_path()].push_back(entry);
76  _has_contact = true;
77  }
78 }
79 
80 /**
81  * Called by the CollisionTraverser at the completion of all collision
82  * detections for this traversal. It should do whatever finalization is
83  * required for the handler.
84  */
87  bool result = handle_entries();
89 
90  return result;
91 }
92 
93 /**
94  * Adds a new collider to the list with a NodePath that will be updated with
95  * the collider's new position, or updates the existing collider with a new
96  * NodePath object.
97  */
99 add_collider(const NodePath &collider, const NodePath &target) {
100  nassertv(!collider.is_empty() && collider.node()->is_collision_node());
101  nassertv(validate_target(target));
102  _colliders[collider].set_target(target);
103 }
104 
105 /**
106  * Adds a new collider to the list with a NodePath that will be updated with
107  * the collider's new position, or updates the existing collider with a new
108  * NodePath object.
109  *
110  * The indicated DriveInterface will also be updated with the target's new
111  * transform each frame. This method should be used when the target is
112  * directly controlled by a DriveInterface.
113  */
115 add_collider(const NodePath &collider, const NodePath &target,
116  DriveInterface *drive_interface) {
117  nassertv(!collider.is_empty() && collider.node()->is_collision_node());
118  nassertv(validate_target(target));
119  _colliders[collider].set_target(target, drive_interface);
120 }
121 
122 /**
123  * Removes the collider from the list of colliders that this handler knows
124  * about.
125  */
127 remove_collider(const NodePath &collider) {
128  Colliders::iterator ci = _colliders.find(collider);
129  if (ci == _colliders.end()) {
130  return false;
131  }
132  _colliders.erase(ci);
133  return true;
134 }
135 
136 /**
137  * Returns true if the handler knows about the indicated collider, false
138  * otherwise.
139  */
141 has_collider(const NodePath &target) const {
142  Colliders::const_iterator ci = _colliders.find(target);
143  return (ci != _colliders.end());
144 }
145 
146 /**
147  * Completely empties the list of colliders this handler knows about.
148  */
151  _colliders.clear();
152 }
153 
154 /**
155  * Called internally to validate the target passed to add_collider(). Returns
156  * true if acceptable, false otherwise.
157  */
158 bool CollisionHandlerPhysical::
159 validate_target(const NodePath &target) {
160  nassertr_always(!target.is_empty(), false);
161  return true;
162 }
virtual bool end_group()
Called by the CollisionTraverser at the completion of all collision detections for this traversal.
bool has_surface_point() const
Returns true if the surface point has been specified, false otherwise.
virtual bool end_group()
Called by the CollisionTraverser at the completion of all collision detections for this traversal.
get_from_node_path
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
LPoint3 get_surface_point(const NodePath &space) const
Returns the point, on the surface of the "into" object, at which a collision is detected.
This is a TFormer, similar to Trackball, that moves around a transform matrix in response to mouse in...
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.
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:188
virtual void begin_group()
Will be called by the CollisionTraverser before a new traversal is begun.
bool has_into() const
Returns true if the "into" solid is, in fact, a CollisionSolid, and its pointer is known (in which ca...
bool has_surface_normal() const
Returns true if the surface normal has been specified, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void begin_group()
Will be called by the CollisionTraverser before a new traversal is begun.
void clear_colliders()
Completely empties the list of colliders this handler knows about.
virtual bool is_collision_node() const
A simple downcast check.
Definition: pandaNode.cxx:2092
Defines a single collision event.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool remove_collider(const NodePath &collider)
Removes the collider from the list of colliders that this handler knows about.
has_center
Returns true if a NodePath has been specified with set_center(), false otherwise.
virtual void add_entry(CollisionEntry *entry)
Called between a begin_group() .
PandaNode * node() const
Returns the referenced node of the path.
Definition: nodePath.I:227
get_into
Returns the CollisionSolid pointer for the particular solid was collided into.
get_from
Returns the CollisionSolid pointer for the particular solid that triggered this collision.
bool has_collider(const NodePath &collider) const
Returns true if the handler knows about the indicated collider, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
void add_collider(const NodePath &collider, const NodePath &target)
Adds a new collider to the list with a NodePath that will be updated with the collider's new position...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
virtual void add_entry(CollisionEntry *entry)
Called between a begin_group() .