Panda3D

physxController.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 physxController.cxx
10 * @author enn0x
11 * @date 2009-09-24
12 */
13
14 #include "event.h"
15 #include "eventQueue.h"
16 #include "eventParameter.h"
17
18 #include "physxController.h"
19 #include "physxManager.h"
20 #include "physxActor.h"
21 #include "physxBoxController.h"
22 #include "physxCapsuleController.h"
23
24 TypeHandle PhysxController::_type_handle;
25
26 /**
27 *
28 */
29 void PhysxController::
30 release() {
31
32 nassertv(_error_type == ET_ok);
33
34 NxControllerManager *cm = get_actor()->get_scene()->cm();
35 unlink();
36 cm->releaseController(*ptr());
37 }
38
39 /**
40 *
41 */
42 PhysxController *PhysxController::
43 factory(NxControllerType controllerType) {
44
45 switch (controllerType) {
46
47 case NX_CONTROLLER_BOX:
48 return new PhysxBoxController();
49
50 case NX_CONTROLLER_CAPSULE:
51 return new PhysxCapsuleController();
52
53 default:
54 break;
55 }
56
57 physx_cat.error() << "Unknown controller type.\n";
58 return nullptr;
59 }
60
61
62 /**
63 * Retrieves the actor which this controller is associated with.
64 */
65 PhysxActor *PhysxController::
66 get_actor() const {
67
68 nassertr(_error_type == ET_ok, nullptr);
69 return (PhysxActor *)(ptr()->getActor()->userData);
70 }
71
72 /**
73 * Sets the position of the controller is global space. This can be used for
74 * initial placement or for teleporting the character.
75 */
76 void PhysxController::
77 set_pos(const LPoint3f &pos) {
78
79 nassertv(_error_type == ET_ok);
80 ptr()->setPosition(PhysxManager::point3_to_nxExtVec3(pos));
81 }
82
83 /**
84 * Retruns the position of the controller is global space.
85 */
86 LPoint3f PhysxController::
87 get_pos() const {
88
89 nassertr(_error_type == ET_ok, LPoint3f::zero());
90 return PhysxManager::nxExtVec3_to_point3(ptr()->getPosition());
91 }
92
93 /**
94 * Sharpness is used to smooth motion with a feedback filter, having a value
95 * between 0 (so smooth it doesn't move) and 1 (no smoothing = unfiltered
96 * motion). Sharpness can ease the motion curve when the auto-step feature is
97 * used with boxes. Default value is 1.0.
98 */
99 void PhysxController::
100 set_sharpness(float sharpness) {
101
102 nassertv(_error_type == ET_ok);
103 nassertv(sharpness > 0.0f);
104 nassertv(sharpness <= 1.0f);
105
106 _sharpness = sharpness;
107 }
108
109 /**
110 * Returns the sharpness used to ease the motion curve when the auto-step
111 * feature is used. Default value is 1.0.
112 */
113 float PhysxController::
114 get_sharpness() const {
115
116 nassertr(_error_type == ET_ok, 0.0f);
117 return _sharpness;
118 }
119
120 /**
121 * Enable/Disable collisions for this controller and actor.
122 */
123 void PhysxController::
124 set_collision(bool enable) {
125
126 nassertv(_error_type == ET_ok);
127 ptr()->setCollision(enable);
128 }
129
130 /**
131 * Sets the the minimum travelled distance to consider when moving the
132 * controller. If travelled distance is smaller, the character doesn't move.
133 * This is used to stop the recursive motion algorithm when remaining distance
134 * to travel is small. The default value is 0.0001.
135 */
136 void PhysxController::
137 set_min_distance(float min_dist) {
138
139 nassertv(_error_type == ET_ok);
140 nassertv(min_dist > 0.0f);
141
142 _min_dist = min_dist;
143 }
144
145 /**
146 * Sets the step height/offset for the controller.
147 */
148 void PhysxController::
149 set_step_offset(float offset) {
150
151 nassertv(_error_type == ET_ok);
152 nassertv(offset > 0.0f);
153
154 ptr()->setStepOffset(offset);
155 }
156
157 /**
158 * Sets the linear speed of the controller in global space.
159 */
160 void PhysxController::
161 set_global_speed(const LVector3f &speed) {
162
163 nassertv(_error_type == ET_ok);
164 nassertv_always(!speed.is_nan());
165
166 _speed = NxVec3(speed.get_x(), speed.get_y(), speed.get_z());
167 }
168
169 /**
170 * Sets the linear speed of the controller in local coordinates.
171 */
172 void PhysxController::
173 set_local_speed(const LVector3f &speed) {
174
175 nassertv(_error_type == ET_ok);
176 nassertv_always(!speed.is_nan());
177
178 NodePath np = get_actor()->get_node_path();
179 nassertv(!np.is_empty());
180
181 NxQuat q = ptr()->getActor()->getGlobalOrientationQuat();
182 NxVec3 s = NxVec3(speed.get_x(), speed.get_y(), speed.get_z());
183 _speed = (q * _up_quat_inv).rot(s);
184 }
185
186 /**
187 * Sets the angular velocity (degrees per second) of the controller. The
188 * angular velocity is used to compute the new heading when updating the
189 * controller.
190 */
191 void PhysxController::
192 set_omega(float omega) {
193
194 nassertv(_error_type == ET_ok);
195 _omega = omega;
196 }
197
198 /**
199 * Sets the heading of the controller is global space. Note: only heading is
200 * supported. Pitch and roll are constrained by PhysX in order to alyways
201 * keep the character upright.
202 */
203 void PhysxController::
204 set_h(float heading) {
205
206 nassertv(_error_type == ET_ok);
207
208 _heading = heading;
209 NxQuat q(_heading, _up_vector);
210 ptr()->getActor()->moveGlobalOrientationQuat(_up_quat * q);
211 }
212
213 /**
214 * Returns the heading of the controller in global space.
215 */
216 float PhysxController::
217 get_h() const {
218
219 nassertr(_error_type == ET_ok, 0.0f);
220 return _heading;
221 }
222
223 /**
224 * The character controller uses caching in order to speed up collision
225 * testing, this caching can not detect when static objects have changed in
226 * the scene. You need to call this method when such changes have been made.
227 */
228 void PhysxController::
229 report_scene_changed() {
230
231 nassertv(_error_type == ET_ok);
232 ptr()->reportSceneChanged();
233 }
234
235 /**
236 *
237 */
238 void PhysxController::
239 update_controller(float dt) {
240
241 nassertv(_error_type == ET_ok);
242
243 // Speed
244 NxU32 mask = 0xFFFFFFFF;
245 NxU32 collision_flags;
246 NxVec3 gravity;
247
248 ptr()->getActor()->getScene().getGravity(gravity);
249
250 NxVec3 d = (_speed + gravity) * dt;
251
252 NxReal heightDelta = get_jump_height(dt, gravity);
253 if (heightDelta != 0.0f) {
254 ((_up_axis == NX_Z) ? d.z : d.y) += heightDelta;
255 }
256
257 ptr()->move(d, mask, _min_dist, collision_flags, _sharpness);
258
259 if (collision_flags & NXCC_COLLISION_DOWN) {
260 stop_jump();
261 }
262
263 // Omega
264 if (_omega != 0.0f) {
265 NxReal delta = _omega * dt;
266 _heading += delta;
267 NxQuat q(_heading, _up_vector);
268 ptr()->getActor()->moveGlobalOrientationQuat(_up_quat * q);
269 }
270
271 // Reset speed and omega
272 _speed.zero();
273 _omega = 0.0f;
274 }
275
276 /**
277 *
278 */
279 NxReal PhysxController::
280 get_jump_height(float dt, NxVec3 &gravity) {
281
282 if (_jumping == false) {
283 return 0.0f;
284 }
285
286 _jump_time += dt;
287
288 float G = (_up_axis == NX_Z) ? gravity.z : gravity.y;
289 float h = 2.0f * G * _jump_time * _jump_time + _jump_v0 * _jump_time;
290 return (h - G) * dt;
291 }
292
293 /**
294 * Enters the jump mode. The parameter is the intial upward velocity of the
295 * character.
296 */
297 void PhysxController::
298 start_jump(float v0) {
299
300 nassertv(_error_type == ET_ok);
301
302 if (_jumping == true) {
303 return;
304 }
305
306 _jumping = true;
307 _jump_time = 0.0f;
308 _jump_v0 = v0;
309 }
310
311 /**
312 * Leaves the jump mode. This method is automatically called if a ground
313 * collision is detected. Usually users need not call this method.
314 */
315 void PhysxController::
316 stop_jump() {
317
318 nassertv(_error_type == ET_ok);
319
320 if (_jumping == false) {
321 return;
322 }
323
324 _jumping = false;
325
326 // NxVec3 v = ptr()->getActor()->getLinearVelocity(); double velocity =
327 // (_up_axis == NX_Z) ? v.z : v.y;
328
329 Event *event = new Event("physx-controller-down");
330 event->add_parameter(EventParameter(this));
331 // event->add_parameter(EventParameter(velocity));
332 EventQueue::get_global_event_queue()->queue_event(event);
333 }
EventParameter
An optional parameter associated with an event.
Definition: eventParameter.h:35
EventQueue::get_global_event_queue
static EventQueue * get_global_event_queue()
Returns a pointer to the one global EventQueue object.
Definition: eventQueue.I:19
Event
A named event, possibly with parameters.
Definition: event.h:33
NodePath
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
NodePath::is_empty
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:188
PhysxActor
Actors are the main simulation objects.
Definition: physxActor.h:44
PhysxActor::get_node_path
NodePath get_node_path() const
Retrieves a previously attached NodePath.
Definition: physxActor.cxx:348
PhysxActor::get_scene
PhysxScene * get_scene() const
Retrieves the scene which this actor belongs to.
Definition: physxActor.cxx:359
PhysxBoxController
Box character controller.
Definition: physxBoxController.h:26
PhysxCapsuleController
A capsule character controller.
Definition: physxCapsuleController.h:37
PhysxController
Abstract base class for character controllers.
Definition: physxController.h:30
PhysxController::set_sharpness
void set_sharpness(float sharpness)
Sharpness is used to smooth motion with a feedback filter, having a value between 0 (so smooth it doe...
Definition: physxController.cxx:100
PhysxController::get_h
float get_h() const
Returns the heading of the controller in global space.
Definition: physxController.cxx:217
PhysxController::get_actor
PhysxActor * get_actor() const
Retrieves the actor which this controller is associated with.
Definition: physxController.cxx:66
PhysxController::get_sharpness
float get_sharpness() const
Returns the sharpness used to ease the motion curve when the auto-step feature is used.
Definition: physxController.cxx:114
PhysxController::set_min_distance
void set_min_distance(float min_dist)
Sets the the minimum travelled distance to consider when moving the controller.
Definition: physxController.cxx:137
PhysxController::stop_jump
void stop_jump()
Leaves the jump mode.
Definition: physxController.cxx:316
PhysxController::set_global_speed
void set_global_speed(const LVector3f &speed)
Sets the linear speed of the controller in global space.
Definition: physxController.cxx:161
PhysxController::set_h
void set_h(float heading)
Sets the heading of the controller is global space.
Definition: physxController.cxx:204
PhysxController::set_step_offset
void set_step_offset(float offset)
Sets the step height/offset for the controller.
Definition: physxController.cxx:149
PhysxController::start_jump
void start_jump(float v0)
Enters the jump mode.
Definition: physxController.cxx:298
PhysxController::report_scene_changed
void report_scene_changed()
The character controller uses caching in order to speed up collision testing, this caching can not de...
Definition: physxController.cxx:229
PhysxController::set_omega
void set_omega(float omega)
Sets the angular velocity (degrees per second) of the controller.
Definition: physxController.cxx:192
PhysxController::get_pos
LPoint3f get_pos() const
Retruns the position of the controller is global space.
Definition: physxController.cxx:87
PhysxController::set_local_speed
void set_local_speed(const LVector3f &speed)
Sets the linear speed of the controller in local coordinates.
Definition: physxController.cxx:173
PhysxController::set_collision
void set_collision(bool enable)
Enable/Disable collisions for this controller and actor.
Definition: physxController.cxx:124
PhysxController::set_pos
void set_pos(const LPoint3f &pos)
Sets the position of the controller is global space.
Definition: physxController.cxx:77
PhysxManager::point3_to_nxExtVec3
static NxExtendedVec3 point3_to_nxExtVec3(const LPoint3f &p)
Converts from LPoint3f to NxExtendedVec3.
Definition: physxManager.I:81
PhysxManager::nxExtVec3_to_point3
static LPoint3f nxExtVec3_to_point3(const NxExtendedVec3 &p)
Converts from NxExtendedVec3 to LPoint3f.
Definition: physxManager.I:90
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
eventParameter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
eventQueue.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
event.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
physxActor.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
physxBoxController.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
physxCapsuleController.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
physxController.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
physxManager.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.