Panda3D
 All Classes Functions Variables Enumerations
bulletCharacterControllerNode.cxx
1 // Filename: bulletCharacterControllerNode.cxx
2 // Created by: enn0x (21Nov10)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "bulletCharacterControllerNode.h"
16 
17 TypeHandle BulletCharacterControllerNode::_type_handle;
18 
19 ////////////////////////////////////////////////////////////////////
20 // Function: BulletCharacterControllerNode::Constructor
21 // Access: Published
22 // Description:
23 ////////////////////////////////////////////////////////////////////
24 BulletCharacterControllerNode::
25 BulletCharacterControllerNode(BulletShape *shape, PN_stdfloat step_height, const char *name) : BulletBaseCharacterControllerNode(name) {
26 
27  // Synchronised transform
28  _sync = TransformState::make_identity();
29  _sync_disable = false;
30 
31  // Initial transform
32  btTransform trans = btTransform::getIdentity();
33 
34  // Get convex shape (for ghost object)
35  if (!shape->is_convex()) {
36  bullet_cat.error() << "a convex shape is required!" << endl;
37  return;
38  }
39 
40  btConvexShape *convex = (btConvexShape *)(shape->ptr());
41 
42  // Ghost object
43  _ghost = new btPairCachingGhostObject();
44  _ghost->setUserPointer(this);
45 
46  _ghost->setWorldTransform(trans);
47  _ghost->setInterpolationWorldTransform(trans);
48  _ghost->setCollisionShape(convex);
49  _ghost->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
50 
51  // Up axis
52  _up = get_default_up_axis();
53 
54  // Initialise movement
55  _linear_movement_is_local = false;
56  _linear_movement.set(0.0f, 0.0f, 0.0f);
57  _angular_movement = 0.0f;
58 
59  // Character controller
60  _character = new btKinematicCharacterController(_ghost, convex, step_height, _up);
61  _character->setGravity((btScalar)9.81f);
62 
63  // Retain a pointer to the shape
64  _shape = shape;
65 
66  // Default collide mask
67  // TODO set_into_collide_mask(CollideMask::all_on());
68 }
69 
70 ////////////////////////////////////////////////////////////////////
71 // Function: BulletCharacterControllerNode::set_linear_movement
72 // Access: Published
73 // Description:
74 ////////////////////////////////////////////////////////////////////
75 void BulletCharacterControllerNode::
76 set_linear_movement(const LVector3 &movement, bool is_local) {
77 
78  nassertv(!movement.is_nan());
79 
80  _linear_movement = movement;
81  _linear_movement_is_local = is_local;
82 }
83 
84 ////////////////////////////////////////////////////////////////////
85 // Function: BulletCharacterControllerNode::set_angular_movement
86 // Access: Published
87 // Description:
88 ////////////////////////////////////////////////////////////////////
89 void BulletCharacterControllerNode::
90 set_angular_movement(PN_stdfloat omega) {
91 
92  _angular_movement = omega;
93 }
94 
95 ////////////////////////////////////////////////////////////////////
96 // Function: BulletCharacterControllerNode::sync_p2b
97 // Access: Public
98 // Description:
99 ////////////////////////////////////////////////////////////////////
100 void BulletCharacterControllerNode::
101 sync_p2b(PN_stdfloat dt, int num_substeps) {
102 
103  // Synchronise global transform
104  transform_changed();
105 
106  // Angular rotation
107  btScalar angle = dt * deg_2_rad(_angular_movement);
108 
109  btMatrix3x3 m = _ghost->getWorldTransform().getBasis();
110  btVector3 up = m[_up];
111 
112  m *= btMatrix3x3(btQuaternion(up, angle));
113 
114  _ghost->getWorldTransform().setBasis(m);
115 
116  // Linear movement
117  LVector3 vp = _linear_movement / (btScalar)num_substeps;
118 
119  btVector3 v;
120  if (_linear_movement_is_local) {
121  btTransform xform = _ghost->getWorldTransform();
122  xform.setOrigin(btVector3(0.0f, 0.0f, 0.0f));
123  v = xform(LVecBase3_to_btVector3(vp));
124  }
125  else {
126  v = LVecBase3_to_btVector3(vp);
127  }
128 
129  //_character->setVelocityForTimeInterval(v, dt);
130  _character->setWalkDirection(v * dt);
131  _angular_movement = 0.0f;
132 }
133 
134 ////////////////////////////////////////////////////////////////////
135 // Function: BulletCharacterControllerNode::sync_b2p
136 // Access: Public
137 // Description:
138 ////////////////////////////////////////////////////////////////////
139 void BulletCharacterControllerNode::
140 sync_b2p() {
141 
142  NodePath np = NodePath::any_path((PandaNode *)this);
143  LVecBase3 scale = np.get_net_transform()->get_scale();
144 
145  btTransform trans = _ghost->getWorldTransform();
146  CPT(TransformState) ts = btTrans_to_TransformState(trans, scale);
147 
148  LMatrix4 m_sync = _sync->get_mat();
149  LMatrix4 m_ts = ts->get_mat();
150 
151  if (!m_sync.almost_equal(m_ts)) {
152  _sync = ts;
153  _sync_disable = true;
154  np.set_transform(NodePath(), ts);
155  _sync_disable = false;
156  }
157 }
158 
159 ////////////////////////////////////////////////////////////////////
160 // Function: BulletCharacterControllerNode::transform_changed
161 // Access: Protected
162 // Description:
163 ////////////////////////////////////////////////////////////////////
164 void BulletCharacterControllerNode::
165 transform_changed() {
166 
167  if (_sync_disable) return;
168 
169  NodePath np = NodePath::any_path((PandaNode *)this);
170  CPT(TransformState) ts = np.get_net_transform();
171 
172  LMatrix4 m_sync = _sync->get_mat();
173  LMatrix4 m_ts = ts->get_mat();
174 
175  if (!m_sync.almost_equal(m_ts)) {
176  _sync = ts;
177 
178  // Get translation, heading and scale
179  LPoint3 pos = ts->get_pos();
180  PN_stdfloat heading = ts->get_hpr().get_x();
181  LVecBase3 scale = ts->get_scale();
182 
183  // Set translation
184  _character->warp(LVecBase3_to_btVector3(pos));
185 
186  // Set Heading
187  btMatrix3x3 m = _ghost->getWorldTransform().getBasis();
188  btVector3 up = m[_up];
189 
190  m = btMatrix3x3(btQuaternion(up, deg_2_rad(heading)));
191 
192  _ghost->getWorldTransform().setBasis(m);
193 
194  // Set scale
195  _shape->set_local_scale(scale);
196  }
197 }
198 
199 ////////////////////////////////////////////////////////////////////
200 // Function: BulletCharacterControllerNode::get_shape
201 // Access: Published
202 // Description:
203 ////////////////////////////////////////////////////////////////////
204 BulletShape *BulletCharacterControllerNode::
205 get_shape() const {
206 
207  return _shape;
208 }
209 
210 ////////////////////////////////////////////////////////////////////
211 // Function: BulletCharacterControllerNode::is_on_ground
212 // Access: Published
213 // Description:
214 ////////////////////////////////////////////////////////////////////
215 bool BulletCharacterControllerNode::
216 is_on_ground() const {
217 
218  return _character->onGround();
219 }
220 
221 ////////////////////////////////////////////////////////////////////
222 // Function: BulletCharacterControllerNode::can_jump
223 // Access: Published
224 // Description:
225 ////////////////////////////////////////////////////////////////////
226 bool BulletCharacterControllerNode::
227 can_jump() const {
228 
229  return _character->canJump();
230 }
231 
232 ////////////////////////////////////////////////////////////////////
233 // Function: BulletCharacterControllerNode::do_jump
234 // Access: Published
235 // Description:
236 ////////////////////////////////////////////////////////////////////
237 void BulletCharacterControllerNode::
238 do_jump() {
239 
240  _character->jump();
241 }
242 
243 ////////////////////////////////////////////////////////////////////
244 // Function: BulletCharacterControllerNode::set_fall_speed
245 // Access: Published
246 // Description:
247 ////////////////////////////////////////////////////////////////////
248 void BulletCharacterControllerNode::
249 set_fall_speed(PN_stdfloat fall_speed) {
250 
251  _character->setFallSpeed((btScalar)fall_speed);
252 }
253 
254 ////////////////////////////////////////////////////////////////////
255 // Function: BulletCharacterControllerNode::set_jump_speed
256 // Access: Published
257 // Description:
258 ////////////////////////////////////////////////////////////////////
259 void BulletCharacterControllerNode::
260 set_jump_speed(PN_stdfloat jump_speed) {
261 
262  _character->setJumpSpeed((btScalar)jump_speed);
263 }
264 
265 ////////////////////////////////////////////////////////////////////
266 // Function: BulletCharacterControllerNode::set_max_jump_height
267 // Access: Published
268 // Description:
269 ////////////////////////////////////////////////////////////////////
270 void BulletCharacterControllerNode::
271 set_max_jump_height(PN_stdfloat max_jump_height) {
272 
273  _character->setMaxJumpHeight((btScalar)max_jump_height);
274 }
275 
276 ////////////////////////////////////////////////////////////////////
277 // Function: BulletCharacterControllerNode::set_max_slope
278 // Access: Published
279 // Description:
280 ////////////////////////////////////////////////////////////////////
281 void BulletCharacterControllerNode::
282 set_max_slope(PN_stdfloat max_slope) {
283 
284  _character->setMaxSlope((btScalar)max_slope);
285 }
286 
287 ////////////////////////////////////////////////////////////////////
288 // Function: BulletCharacterControllerNode::get_max_slope
289 // Access: Published
290 // Description:
291 ////////////////////////////////////////////////////////////////////
292 PN_stdfloat BulletCharacterControllerNode::
293 get_max_slope() const {
294 
295  return (PN_stdfloat)_character->getMaxSlope();
296 }
297 
298 ////////////////////////////////////////////////////////////////////
299 // Function: BulletCharacterControllerNode::get_gravity
300 // Description:
301 ////////////////////////////////////////////////////////////////////
302 PN_stdfloat BulletCharacterControllerNode::
303 get_gravity() const {
304 
305  return (PN_stdfloat)_character->getGravity();
306 }
307 
308 ////////////////////////////////////////////////////////////////////
309 // Function: BulletCharacterControllerNode::set_gravity
310 // Description:
311 ////////////////////////////////////////////////////////////////////
312 void BulletCharacterControllerNode::
313 set_gravity(PN_stdfloat gravity) {
314 
315  _character->setGravity((btScalar)gravity);
316 }
317 
318 
319 ////////////////////////////////////////////////////////////////////
320 // Function: BulletCharacterControllerNode::set_use_ghost_sweep_test
321 // Description:
322 ////////////////////////////////////////////////////////////////////
323 void BulletCharacterControllerNode::
324 set_use_ghost_sweep_test(bool value) {
325 
326  return _character->setUseGhostSweepTest(value);
327 }
328 
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:100
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
bool is_nan() const
Returns true if any component of the vector is not-a-number, false otherwise.
Definition: lvecBase3.h:463
void set_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Changes the complete transform object on this node.
Definition: nodePath.I:718
static NodePath any_path(PandaNode *node, Thread *current_thread=Thread::get_current_thread())
Returns a new NodePath that represents any arbitrary path from the root to the indicated node...
Definition: nodePath.I:77
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this PandaNode by the indicated matrix, if it means anything to do so...
Definition: pandaNode.cxx:377
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
LVecBase3 get_scale() const
Retrieves the scale component of the transform.
Definition: nodePath.cxx:1331
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:165