Panda3D

physicsCollisionHandler.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 physicsCollisionHandler.cxx
10 * @author drose
11 * @date 2002-03-16
12 */
13
14 #include "physicsCollisionHandler.h"
15 #include "collisionNode.h"
16 #include "collisionEntry.h"
17 #include "collisionPolygon.h"
18 #include "config_collide.h"
19 #include "config_physics.h"
20 #include "actorNode.h"
21 #include "dcast.h"
22
23 using std::cerr;
24 using std::endl;
25
26 TypeHandle PhysicsCollisionHandler::_type_handle;
27
28 /**
29 *
30 */
31 PhysicsCollisionHandler::
32 PhysicsCollisionHandler() {
33 _almost_stationary_speed = 0.1f;
34 _static_friction_coef=0.9f;
35 _dynamic_friction_coef=0.5f;
36 set_horizontal(false);
37 }
38
39 /**
40 *
41 */
42 PhysicsCollisionHandler::
43 ~PhysicsCollisionHandler() {
44 }
45
46 /**
47 * The vel parameter will be modified in place to account for friction.
48 */
49 void PhysicsCollisionHandler::
50 apply_friction(ColliderDef &def, LVector3& vel, const LVector3& force,
51 PN_stdfloat angle) {
52 if (vel!=LVector3::zero()) {
53 PN_stdfloat friction_coefficient=0.0f;
54 // Determine the friction:
55 if (vel.length()<_almost_stationary_speed) {
56 physics_debug(" static friction");
57 friction_coefficient=_static_friction_coef;
58 } else {
59 physics_debug(" dynamic friction");
60 friction_coefficient=_dynamic_friction_coef;
61 }
62 // Apply the friction:
63 physics_debug(" vel pre friction "<<vel<<" len "<<vel.length());
64 PN_stdfloat friction=friction_coefficient*angle;
65 physics_debug(" friction "<<friction);
66 if (friction<0.0f || friction>1.0f) {
67 cerr<<"\n\nfriction error "<<friction<<endl;
68 friction=1.0f;
69 }
70 #if 0
71 PN_stdfloat dt=ClockObject::get_global_clock()->get_dt();
72 vel *= (1.0f-friction) * dt * dt;
73 #else
74 vel *= 1.0f-friction;
75 #endif
76 physics_debug(" vel post friction "<<vel<<" len "<<vel.length());
77 }
78 }
79
80 /**
81 *
82 */
83 void PhysicsCollisionHandler::
84 apply_net_shove(ColliderDef &def, const LVector3& net_shove,
85 const LVector3 &force) {
86 CollisionHandlerPusher::apply_net_shove(def, net_shove, force);
87 if (force == LVector3::zero()) {
88 return;
89 }
90 if (def._target.is_empty()) {
91 return;
92 }
93 ActorNode *actor;
94 DCAST_INTO_V(actor, def._target.node());
95 LVector3 vel=actor->get_physics_object()->get_velocity();
96 if (vel == LVector3::zero()) {
97 return;
98 }
99 physics_debug("apply_linear_force() {");
100 physics_debug(" vel "<<vel<<" len "<<vel.length());
101 physics_debug(" net_shove "<<net_shove<<" len "<<net_shove.length());
102 physics_debug(" force "<<force<<" len "<<force.length());
103 LVector3 old_vel=vel;
104
105 // Copy the force vector while translating it into the physics object
106 // coordinate system:
107 LVector3 adjustment=force;
108 physics_debug(
109 " adjustment set "<<adjustment<<" len "<<adjustment.length());
110
111 // NodePath np(def._node); CPT(TransformState) trans =
112 // np.get_net_transform(); adjustment=adjustment*trans->get_mat();
113 // physics_debug( " adjustment trn "<<adjustment<<" len
114 // "<<adjustment.length());
115
116 adjustment=adjustment*actor->get_physics_object()->get_lcs();
117 physics_debug(
118 " adjustment lcs "<<adjustment<<" len "<<adjustment.length());
119
120 adjustment.normalize();
121 physics_debug(
122 " adjustment nrm "<<adjustment<<" len "<<adjustment.length());
123
124 PN_stdfloat adjustmentLength=-(adjustment.dot(vel));
125 physics_debug(" adjustmentLength "<<adjustmentLength);
126 PN_stdfloat angle=-normalize(old_vel).dot(normalize(force));
127 physics_debug(" angle "<<angle);
128 // Are we in contact with something:
129 if (angle>0.0f) {
130 physics_debug(" positive contact");
131 #if 0
132 cerr<<"vel "<<vel<<endl;
133 cerr<<"net_shove "<<net_shove<<endl;
134 cerr<<"force "<<force<<endl;
135 actor->get_physics_object()->add_impact(force, -vel);
136 #else
137 adjustment*=adjustmentLength;
138 physics_debug(
139 " adjustment mul "<<adjustment<<" len "<<adjustment.length());
140
141 // This adjustment to our velocity will not reflect us off the surface,
142 // but will deflect us parallel (or tangent) to the surface:
143 vel+=adjustment;
144 physics_debug(" vel+adj "<<vel<<" len "<<vel.length());
145
146 apply_friction(def, vel, force, angle);
147 #endif
148 } else if (adjustmentLength==0.0f) {
149 physics_debug(" brushing contact");
150 } else {
151 physics_debug(" negative contact");
152 }
153
154 #ifndef NDEBUG //[
155 if (IS_THRESHOLD_EQUAL(vel.length(), old_vel.length(), 0.0001f)) {
156 // This is a check to see if vel is staying the same:
157 physics_debug(
158 " vel is about the same length: "
159 <<vel.length()<<" ~ "<<old_vel.length());
160 } else if (vel.length() > old_vel.length()) {
161 // This is a check to avoid adding engergy:
162 physics_debug(
163 " vel got larger "<<vel.length()<<" > "<<old_vel.length());
164 } else {
165 // This is a check to avoid losing engergy:
166 physics_debug(
167 " vel got smaller "<<vel.length()<<" < "<<old_vel.length());
168 }
169 if (vel.length() > 10.0f) {
170 // This is a check to see if the velocity is higher than I expect it to
171 // go. The check value is arbitrary.
172 physics_debug(" vel.length() > 10.0f "<<vel.length());
173 }
174 #endif //]
175
176 physics_debug(" force "<<force<<" len "<<force.length());
177 physics_debug(" vel "<<vel<<" len "<<vel.length());
178 physics_debug("}");
179 actor->set_contact_vector(adjustment);
180 actor->get_physics_object()->set_velocity(vel);
181 }
182
183 /**
184 *
185 */
186 void PhysicsCollisionHandler::
187 apply_linear_force(ColliderDef &def, const LVector3 &force) {
188 }
189
190 /**
191 * Called internally to validate the target passed to add_collider(). Returns
192 * true if acceptable, false otherwise.
193 */
194 bool PhysicsCollisionHandler::
195 validate_target(const NodePath &target) {
196 if (!CollisionHandlerPhysical::validate_target(target)) {
197 return false;
198 }
199 nassertr_always(target.node()->is_of_type(ActorNode::get_class_type()), false);
200 return true;
201 }
actorNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
ActorNode
Like a physical node, but with a little more.
Definition: actorNode.h:26
ClockObject::get_dt
get_dt
Returns the elapsed time for the previous frame: the number of seconds elapsed between the last two c...
Definition: clockObject.h:99
ClockObject::get_global_clock
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Definition: clockObject.I:215
NodePath
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
NodePath::node
PandaNode * node() const
Returns the referenced node of the path.
Definition: nodePath.I:227
PhysicsObject::get_velocity
get_velocity
Velocity Query per second.
Definition: physicsObject.h:107
PhysicsObject::set_velocity
set_velocity
Vector velocity assignment.
Definition: physicsObject.h:107
PhysicsObject::get_lcs
virtual LMatrix4 get_lcs() const
returns a transform matrix to this object's local coordinate system.
Definition: physicsObject.cxx:131
PhysicsObject::add_impact
virtual void add_impact(const LPoint3 &offset_from_center_of_mass, const LVector3 &impulse)
Adds an impulse and/or torque (i.e.
Definition: physicsObject.cxx:104
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
TypedObject::is_of_type
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
collisionEntry.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
collisionNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
collisionPolygon.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_collide.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_physics.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
dcast.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
physicsCollisionHandler.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.