15 #include "bulletCharacterControllerNode.h" 17 #if BT_BULLET_VERSION >= 285 18 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)};
21 TypeHandle BulletCharacterControllerNode::_type_handle;
28 BulletCharacterControllerNode::
32 _sync = TransformState::make_identity();
33 _sync_disable =
false;
36 btTransform trans = btTransform::getIdentity();
39 if (!shape->is_convex()) {
40 bullet_cat.error() <<
"a convex shape is required!" << endl;
44 btConvexShape *convex = (btConvexShape *)(shape->ptr());
47 _ghost =
new btPairCachingGhostObject();
48 _ghost->setUserPointer(
this);
50 _ghost->setWorldTransform(trans);
51 _ghost->setInterpolationWorldTransform(trans);
52 _ghost->setCollisionShape(convex);
53 _ghost->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
56 _up = get_default_up_axis();
59 _linear_movement_is_local =
false;
60 _linear_movement.set(0.0f, 0.0f, 0.0f);
61 _angular_movement = 0.0f;
64 #if BT_BULLET_VERSION >= 285 65 _character =
new btKinematicCharacterController(_ghost, convex, step_height, up_vectors[_up]);
66 _character->setGravity(up_vectors[_up] * -(btScalar)9.81f);
68 _character =
new btKinematicCharacterController(_ghost, convex, step_height, _up);
69 _character->setGravity((btScalar)9.81f);
84 void BulletCharacterControllerNode::
85 set_linear_movement(
const LVector3 &movement,
bool is_local) {
87 nassertv(!movement.
is_nan());
89 _linear_movement = movement;
90 _linear_movement_is_local = is_local;
98 void BulletCharacterControllerNode::
99 set_angular_movement(PN_stdfloat omega) {
101 _angular_movement = omega;
109 void BulletCharacterControllerNode::
110 sync_p2b(PN_stdfloat dt,
int num_substeps) {
116 btScalar angle = dt * deg_2_rad(_angular_movement);
118 btMatrix3x3 m = _ghost->getWorldTransform().getBasis();
119 btVector3 up = m[_up];
121 m *= btMatrix3x3(btQuaternion(up, angle));
123 _ghost->getWorldTransform().setBasis(m);
126 LVector3 vp = _linear_movement / (btScalar)num_substeps;
129 if (_linear_movement_is_local) {
130 btTransform xform = _ghost->getWorldTransform();
131 xform.setOrigin(btVector3(0.0f, 0.0f, 0.0f));
132 v = xform(LVecBase3_to_btVector3(vp));
135 v = LVecBase3_to_btVector3(vp);
139 _character->setWalkDirection(v * dt);
140 _angular_movement = 0.0f;
148 void BulletCharacterControllerNode::
154 btTransform trans = _ghost->getWorldTransform();
155 CPT(TransformState) ts = btTrans_to_TransformState(trans, scale);
162 _sync_disable =
true;
164 _sync_disable =
false;
173 void BulletCharacterControllerNode::
174 transform_changed() {
176 if (_sync_disable)
return;
179 CPT(TransformState) ts = np.get_net_transform();
189 PN_stdfloat heading = ts->get_hpr().get_x();
193 _character->warp(LVecBase3_to_btVector3(pos));
196 btMatrix3x3 m = _ghost->getWorldTransform().getBasis();
197 btVector3 up = m[_up];
199 m = btMatrix3x3(btQuaternion(up, deg_2_rad(heading)));
201 _ghost->getWorldTransform().setBasis(m);
204 _shape->set_local_scale(scale);
224 bool BulletCharacterControllerNode::
225 is_on_ground()
const {
227 return _character->onGround();
235 bool BulletCharacterControllerNode::
238 return _character->canJump();
246 void BulletCharacterControllerNode::
257 void BulletCharacterControllerNode::
258 set_fall_speed(PN_stdfloat fall_speed) {
260 _character->setFallSpeed((btScalar)fall_speed);
268 void BulletCharacterControllerNode::
269 set_jump_speed(PN_stdfloat jump_speed) {
271 _character->setJumpSpeed((btScalar)jump_speed);
279 void BulletCharacterControllerNode::
280 set_max_jump_height(PN_stdfloat max_jump_height) {
282 _character->setMaxJumpHeight((btScalar)max_jump_height);
290 void BulletCharacterControllerNode::
291 set_max_slope(PN_stdfloat max_slope) {
293 _character->setMaxSlope((btScalar)max_slope);
301 PN_stdfloat BulletCharacterControllerNode::
302 get_max_slope()
const {
304 return (PN_stdfloat)_character->getMaxSlope();
311 PN_stdfloat BulletCharacterControllerNode::
312 get_gravity()
const {
313 #if BT_BULLET_VERSION >= 285 314 return -(PN_stdfloat)_character->getGravity()[_up];
316 return (PN_stdfloat)_character->getGravity();
324 void BulletCharacterControllerNode::
325 set_gravity(PN_stdfloat gravity) {
326 #if BT_BULLET_VERSION >= 285 327 _character->setGravity(up_vectors[_up] * -(btScalar)gravity);
329 _character->setGravity((btScalar)gravity);
338 void BulletCharacterControllerNode::
339 set_use_ghost_sweep_test(
bool value) {
341 return _character->setUseGhostSweepTest(value);
A basic node of the scene graph or data graph.
This is the base class for all three-component vectors and points.
bool almost_equal(const LMatrix4f &other, float threshold) const
Returns true if two matrices are memberwise equal within a specified tolerance.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
bool is_nan() const
Returns true if any component of the vector is not-a-number, false otherwise.
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...
This is a 4-by-4 transform matrix.
LVecBase3 get_scale() const
Retrieves the scale component of the transform.
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...