Panda3D
Loading...
Searching...
No Matches
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
23using std::cerr;
24using std::endl;
25
26TypeHandle PhysicsCollisionHandler::_type_handle;
27
28/**
29 *
30 */
31PhysicsCollisionHandler::
32PhysicsCollisionHandler() {
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 */
42PhysicsCollisionHandler::
43~PhysicsCollisionHandler() {
44}
45
46/**
47 * The vel parameter will be modified in place to account for friction.
48 */
49void PhysicsCollisionHandler::
50apply_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 */
83void PhysicsCollisionHandler::
84apply_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 */
186void PhysicsCollisionHandler::
187apply_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 */
194bool PhysicsCollisionHandler::
195validate_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}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Like a physical node, but with a little more.
Definition actorNode.h:26
get_dt
Returns the elapsed time for the previous frame: the number of seconds elapsed between the last two c...
Definition clockObject.h:99
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition nodePath.h:159
PandaNode * node() const
Returns the referenced node of the path.
Definition nodePath.I:227
get_velocity
Velocity Query per second.
set_velocity
Vector velocity assignment.
virtual LMatrix4 get_lcs() const
returns a transform matrix to this object's local coordinate system.
virtual void add_impact(const LPoint3 &offset_from_center_of_mass, const LVector3 &impulse)
Adds an impulse and/or torque (i.e.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition typedObject.I:28
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.