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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_sharpness(float sharpness)
Sharpness is used to smooth motion with a feedback filter, having a value between 0 (so smooth it doe...
void report_scene_changed()
The character controller uses caching in order to speed up collision testing, this caching can not de...
void set_global_speed(const LVector3f &speed)
Sets the linear speed of the controller in global space.
void set_h(float heading)
Sets the heading of the controller is global space.
An optional parameter associated with an event.
A capsule character controller.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_collision(bool enable)
Enable/Disable collisions for this controller and actor.
PhysxActor * get_actor() const
Retrieves the actor which this controller is associated with.
void stop_jump()
Leaves the jump mode.
LPoint3f get_pos() const
Retruns the position of the controller is global space.
static EventQueue * get_global_event_queue()
Returns a pointer to the one global EventQueue object.
Definition: eventQueue.I:19
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static NxExtendedVec3 point3_to_nxExtVec3(const LPoint3f &p)
Converts from LPoint3f to NxExtendedVec3.
Definition: physxManager.I:81
void set_min_distance(float min_dist)
Sets the the minimum travelled distance to consider when moving the controller.
static LPoint3f nxExtVec3_to_point3(const NxExtendedVec3 &p)
Converts from NxExtendedVec3 to LPoint3f.
Definition: physxManager.I:90
Box character controller.
Abstract base class for character controllers.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Actors are the main simulation objects.
Definition: physxActor.h:44
void set_step_offset(float offset)
Sets the step height/offset for the controller.
float get_h() const
Returns the heading of the controller in global space.
float get_sharpness() const
Returns the sharpness used to ease the motion curve when the auto-step feature is used.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_omega(float omega)
Sets the angular velocity (degrees per second) of the controller.
A named event, possibly with parameters.
Definition: event.h:33
void set_local_speed(const LVector3f &speed)
Sets the linear speed of the controller in local coordinates.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PhysxScene * get_scene() const
Retrieves the scene which this actor belongs to.
Definition: physxActor.cxx:359
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
NodePath get_node_path() const
Retrieves a previously attached NodePath.
Definition: physxActor.cxx:348
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
void start_jump(float v0)
Enters the jump mode.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_pos(const LPoint3f &pos)
Sets the position of the controller is global space.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.