20 #if BT_BULLET_VERSION >= 285 21 static const btVector3 up_vectors[3] = {btVector3(1.0f, 0.0f, 0.0f), btVector3(0.0f, 1.0f, 0.0f), btVector3(0.0f, 0.0f, 1.0f)};
24 TypeHandle BulletCharacterControllerNode::_type_handle;
29 BulletCharacterControllerNode::
33 _sync = TransformState::make_identity();
34 _sync_disable =
false;
37 btTransform trans = btTransform::getIdentity();
40 if (!shape->is_convex()) {
41 bullet_cat.error() <<
"a convex shape is required!" << std::endl;
45 btConvexShape *convex = (btConvexShape *)(shape->ptr());
48 _ghost =
new btPairCachingGhostObject();
49 _ghost->setUserPointer(
this);
51 _ghost->setWorldTransform(trans);
52 _ghost->setInterpolationWorldTransform(trans);
53 _ghost->setCollisionShape(convex);
54 _ghost->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
57 _up = get_default_up_axis();
60 _linear_movement_is_local =
false;
61 _linear_movement.set(0.0f, 0.0f, 0.0f);
62 _angular_movement = 0.0f;
65 #if BT_BULLET_VERSION >= 285 66 _character =
new btKinematicCharacterController(_ghost, convex, step_height, up_vectors[_up]);
67 _character->setGravity(up_vectors[_up] * -(btScalar)9.81f);
69 _character =
new btKinematicCharacterController(_ghost, convex, step_height, _up);
70 _character->setGravity((btScalar)9.81f);
82 void BulletCharacterControllerNode::
83 set_linear_movement(
const LVector3 &movement,
bool is_local) {
86 nassertv(!movement.is_nan());
88 _linear_movement = movement;
89 _linear_movement_is_local = is_local;
95 void BulletCharacterControllerNode::
96 set_angular_movement(PN_stdfloat omega) {
99 _angular_movement = omega;
109 do_transform_changed();
112 btScalar angle = dt * deg_2_rad(_angular_movement);
114 btMatrix3x3 m = _ghost->getWorldTransform().getBasis();
115 btVector3 up = m[_up];
117 m *= btMatrix3x3(btQuaternion(up, angle));
119 _ghost->getWorldTransform().setBasis(m);
122 LVector3 vp = _linear_movement / (btScalar)num_substeps;
125 if (_linear_movement_is_local) {
126 btTransform
xform = _ghost->getWorldTransform();
127 xform.setOrigin(btVector3(0.0f, 0.0f, 0.0f));
128 v =
xform(LVecBase3_to_btVector3(vp));
131 v = LVecBase3_to_btVector3(vp);
135 _character->setWalkDirection(v * dt);
136 _angular_movement = 0.0f;
146 LVecBase3 scale = np.get_net_transform()->
get_scale();
148 btTransform trans = _ghost->getWorldTransform();
151 LMatrix4 m_sync = _sync->get_mat();
152 LMatrix4 m_ts = ts->get_mat();
154 if (!m_sync.almost_equal(m_ts)) {
156 _sync_disable =
true;
158 _sync_disable =
false;
165 void BulletCharacterControllerNode::
166 do_transform_changed() {
168 if (_sync_disable)
return;
173 LMatrix4 m_sync = _sync->
get_mat();
174 LMatrix4 m_ts = ts->get_mat();
176 if (!m_sync.almost_equal(m_ts)) {
180 LPoint3 pos = ts->get_pos();
181 PN_stdfloat heading = ts->get_hpr().get_x();
182 LVecBase3 scale = ts->get_scale();
185 _character->warp(LVecBase3_to_btVector3(pos));
188 btMatrix3x3 m = _ghost->getWorldTransform().getBasis();
189 btVector3 up = m[_up];
191 m = btMatrix3x3(btQuaternion(up, deg_2_rad(heading)));
193 _ghost->getWorldTransform().setBasis(m);
196 _shape->do_set_local_scale(scale);
203 void BulletCharacterControllerNode::
204 transform_changed() {
206 if (_sync_disable)
return;
210 do_transform_changed();
225 bool BulletCharacterControllerNode::
226 is_on_ground()
const {
229 return _character->onGround();
235 bool BulletCharacterControllerNode::
239 return _character->canJump();
245 void BulletCharacterControllerNode::
255 void BulletCharacterControllerNode::
256 set_fall_speed(PN_stdfloat fall_speed) {
259 _character->setFallSpeed((btScalar)fall_speed);
265 void BulletCharacterControllerNode::
266 set_jump_speed(PN_stdfloat jump_speed) {
269 _character->setJumpSpeed((btScalar)jump_speed);
275 void BulletCharacterControllerNode::
276 set_max_jump_height(PN_stdfloat max_jump_height) {
279 _character->setMaxJumpHeight((btScalar)max_jump_height);
285 void BulletCharacterControllerNode::
286 set_max_slope(PN_stdfloat max_slope) {
289 _character->setMaxSlope((btScalar)max_slope);
295 PN_stdfloat BulletCharacterControllerNode::
296 get_max_slope()
const {
299 return (PN_stdfloat)_character->getMaxSlope();
305 PN_stdfloat BulletCharacterControllerNode::
306 get_gravity()
const {
309 #if BT_BULLET_VERSION >= 285 310 return -(PN_stdfloat)_character->getGravity()[_up];
312 return (PN_stdfloat)_character->getGravity();
319 void BulletCharacterControllerNode::
320 set_gravity(PN_stdfloat gravity) {
323 #if BT_BULLET_VERSION >= 285 324 _character->setGravity(up_vectors[_up] * -(btScalar)gravity);
326 _character->setGravity((btScalar)gravity);
333 void BulletCharacterControllerNode::
334 set_use_ghost_sweep_test(
bool value) {
337 return _character->setUseGhostSweepTest(value);
A basic node of the scene graph or data graph.
virtual void do_sync_b2p()
Assumes the lock(bullet global lock) is held by the caller.
virtual void do_sync_p2b(PN_stdfloat dt, int num_substeps)
Assumes the lock(bullet global lock) is held by the caller.
void set_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Changes the complete transform object on this node.
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.
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this PandaNode by the indicated matrix, if it means anything to do so.
Similar to MutexHolder, but for a light mutex.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
LVecBase3 get_scale() const
Retrieves the scale component of the transform.
const LMatrix4 & get_mat() const
Returns the transform matrix that has been applied to the referenced node, or the identity matrix if ...
TypeHandle is the identifier used to differentiate C++ class types.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.