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 
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 }
dcast.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
ClockObject::get_global_clock
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Definition: clockObject.I:215
actorNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
collisionNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PhysicsObject::set_velocity
void set_velocity(const LVector3 &vel)
Vector velocity assignment.
Definition: physicsObject.I:75
PhysicsObject::get_lcs
virtual LMatrix4 get_lcs() const
returns a transform matrix to this object's local coordinate system.
Definition: physicsObject.cxx:131
PhysicsObject::get_velocity
LVector3 get_velocity() const
Velocity Query per second.
Definition: physicsObject.I:178
collisionEntry.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NodePath
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
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
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
physicsCollisionHandler.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_physics.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
ActorNode
Like a physical node, but with a little more.
Definition: actorNode.h:26
collisionPolygon.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_collide.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NodePath::node
PandaNode * node() const
Returns the referenced node of the path.
Definition: nodePath.I:227
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