Panda3D

bulletCharacterControllerNode.cxx

00001 // Filename: bulletCharacterControllerNode.cxx
00002 // Created by:  enn0x (21Nov10)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "bulletCharacterControllerNode.h"
00016 
00017 TypeHandle BulletCharacterControllerNode::_type_handle;
00018 
00019 ////////////////////////////////////////////////////////////////////
00020 //     Function: BulletCharacterControllerNode::Constructor
00021 //       Access: Published
00022 //  Description:
00023 ////////////////////////////////////////////////////////////////////
00024 BulletCharacterControllerNode::
00025 BulletCharacterControllerNode(BulletShape *shape, PN_stdfloat step_height, const char *name) : BulletBaseCharacterControllerNode(name) {
00026 
00027   // Synchronised transform
00028   _sync = TransformState::make_identity();
00029   _sync_disable = false;
00030 
00031   // Initial transform
00032   btTransform trans = btTransform::getIdentity();
00033 
00034   // Get convex shape (for ghost object)
00035   if (!shape->is_convex()) {
00036     bullet_cat.error() << "a convex shape is required!" << endl;
00037     return;
00038   }
00039 
00040   btConvexShape *convex = (btConvexShape *)(shape->ptr());
00041 
00042   // Ghost object
00043   _ghost = new btPairCachingGhostObject();
00044   _ghost->setUserPointer(this);
00045 
00046   _ghost->setWorldTransform(trans);
00047   _ghost->setInterpolationWorldTransform(trans);
00048   _ghost->setCollisionShape(convex);
00049   _ghost->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
00050 
00051   // Up axis
00052   _up = get_default_up_axis();
00053 
00054   // Initialise movement
00055   _linear_movement_is_local = false;
00056   _linear_movement.set(0.0f, 0.0f, 0.0f);
00057   _angular_movement = 0.0f;
00058 
00059   // Character controller
00060   _character = new btKinematicCharacterController(_ghost, convex, step_height, _up);
00061   _character->setGravity((btScalar)9.81f);
00062 
00063   // Retain a pointer to the shape
00064   _shape = shape;
00065 
00066   // Default collide mask
00067   // TODO set_into_collide_mask(CollideMask::all_on());
00068 }
00069 
00070 ////////////////////////////////////////////////////////////////////
00071 //     Function: BulletCharacterControllerNode::set_linear_movement
00072 //       Access: Published
00073 //  Description:
00074 ////////////////////////////////////////////////////////////////////
00075 void BulletCharacterControllerNode::
00076 set_linear_movement(const LVector3 &movement, bool is_local) {
00077 
00078   nassertv(!movement.is_nan());
00079 
00080   _linear_movement = movement;
00081   _linear_movement_is_local = is_local;
00082 }
00083 
00084 ////////////////////////////////////////////////////////////////////
00085 //     Function: BulletCharacterControllerNode::set_angular_movement
00086 //       Access: Published
00087 //  Description:
00088 ////////////////////////////////////////////////////////////////////
00089 void BulletCharacterControllerNode::
00090 set_angular_movement(PN_stdfloat omega) {
00091 
00092   _angular_movement = omega;
00093 }
00094 
00095 ////////////////////////////////////////////////////////////////////
00096 //     Function: BulletCharacterControllerNode::sync_p2b
00097 //       Access: Public
00098 //  Description:
00099 ////////////////////////////////////////////////////////////////////
00100 void BulletCharacterControllerNode::
00101 sync_p2b(PN_stdfloat dt, int num_substeps) {
00102 
00103   // Synchronise global transform
00104   transform_changed();
00105 
00106   // Angular rotation
00107   btScalar angle = dt * deg_2_rad(_angular_movement);
00108 
00109   btMatrix3x3 m = _ghost->getWorldTransform().getBasis();
00110   btVector3 up = m[_up];
00111 
00112   m *= btMatrix3x3(btQuaternion(up, angle));
00113 
00114   _ghost->getWorldTransform().setBasis(m);
00115 
00116   // Linear movement
00117   LVector3 vp = _linear_movement / (btScalar)num_substeps;
00118 
00119   btVector3 v;
00120   if (_linear_movement_is_local) {
00121     btTransform xform = _ghost->getWorldTransform();
00122     xform.setOrigin(btVector3(0.0f, 0.0f, 0.0f));
00123     v = xform(LVecBase3_to_btVector3(vp));
00124   }
00125   else {
00126     v = LVecBase3_to_btVector3(vp);
00127   }
00128 
00129   //_character->setVelocityForTimeInterval(v, dt);
00130   _character->setWalkDirection(v * dt);
00131   _angular_movement = 0.0f;
00132 }
00133 
00134 ////////////////////////////////////////////////////////////////////
00135 //     Function: BulletCharacterControllerNode::sync_b2p
00136 //       Access: Public
00137 //  Description:
00138 ////////////////////////////////////////////////////////////////////
00139 void BulletCharacterControllerNode::
00140 sync_b2p() {
00141 
00142   NodePath np = NodePath::any_path((PandaNode *)this);
00143   LVecBase3 scale = np.get_net_transform()->get_scale();
00144 
00145   btTransform trans = _ghost->getWorldTransform();
00146   CPT(TransformState) ts = btTrans_to_TransformState(trans, scale);
00147 
00148   LMatrix4 m_sync = _sync->get_mat();
00149   LMatrix4 m_ts = ts->get_mat();
00150 
00151   if (!m_sync.almost_equal(m_ts)) {
00152     _sync = ts;
00153     _sync_disable = true;
00154     np.set_transform(NodePath(), ts);
00155     _sync_disable = false;
00156   }
00157 }
00158 
00159 ////////////////////////////////////////////////////////////////////
00160 //     Function: BulletCharacterControllerNode::transform_changed
00161 //       Access: Protected
00162 //  Description:
00163 ////////////////////////////////////////////////////////////////////
00164 void BulletCharacterControllerNode::
00165 transform_changed() {
00166 
00167   if (_sync_disable) return;
00168 
00169   NodePath np = NodePath::any_path((PandaNode *)this);
00170   CPT(TransformState) ts = np.get_net_transform();
00171 
00172   LMatrix4 m_sync = _sync->get_mat();
00173   LMatrix4 m_ts = ts->get_mat();
00174 
00175   if (!m_sync.almost_equal(m_ts)) {
00176     _sync = ts;
00177 
00178     // Get translation, heading and scale
00179     LPoint3 pos = ts->get_pos();
00180     PN_stdfloat heading = ts->get_hpr().get_x();
00181     LVecBase3 scale = ts->get_scale();
00182 
00183     // Set translation
00184     _character->warp(LVecBase3_to_btVector3(pos));
00185 
00186     // Set Heading
00187     btMatrix3x3 m = _ghost->getWorldTransform().getBasis();
00188     btVector3 up = m[_up];
00189 
00190     m = btMatrix3x3(btQuaternion(up, heading));
00191 
00192     _ghost->getWorldTransform().setBasis(m);
00193 
00194     // Set scale
00195     _shape->set_local_scale(scale);
00196   }
00197 }
00198 
00199 ////////////////////////////////////////////////////////////////////
00200 //     Function: BulletCharacterControllerNode::get_shape
00201 //       Access: Published
00202 //  Description:
00203 ////////////////////////////////////////////////////////////////////
00204 BulletShape *BulletCharacterControllerNode::
00205 get_shape() const {
00206 
00207   return _shape;
00208 }
00209 
00210 ////////////////////////////////////////////////////////////////////
00211 //     Function: BulletCharacterControllerNode::is_on_ground
00212 //       Access: Published
00213 //  Description:
00214 ////////////////////////////////////////////////////////////////////
00215 bool BulletCharacterControllerNode::
00216 is_on_ground() const {
00217 
00218   return _character->onGround();
00219 }
00220 
00221 ////////////////////////////////////////////////////////////////////
00222 //     Function: BulletCharacterControllerNode::can_jump
00223 //       Access: Published
00224 //  Description:
00225 ////////////////////////////////////////////////////////////////////
00226 bool BulletCharacterControllerNode::
00227 can_jump() const {
00228 
00229   return _character->canJump();
00230 }
00231 
00232 ////////////////////////////////////////////////////////////////////
00233 //     Function: BulletCharacterControllerNode::do_jump
00234 //       Access: Published
00235 //  Description:
00236 ////////////////////////////////////////////////////////////////////
00237 void BulletCharacterControllerNode::
00238 do_jump() {
00239 
00240   _character->jump();
00241 }
00242 
00243 ////////////////////////////////////////////////////////////////////
00244 //     Function: BulletCharacterControllerNode::set_fall_speed
00245 //       Access: Published
00246 //  Description:
00247 ////////////////////////////////////////////////////////////////////
00248 void BulletCharacterControllerNode::
00249 set_fall_speed(PN_stdfloat fall_speed) {
00250 
00251   _character->setFallSpeed((btScalar)fall_speed);
00252 }
00253 
00254 ////////////////////////////////////////////////////////////////////
00255 //     Function: BulletCharacterControllerNode::set_jump_speed
00256 //       Access: Published
00257 //  Description:
00258 ////////////////////////////////////////////////////////////////////
00259 void BulletCharacterControllerNode::
00260 set_jump_speed(PN_stdfloat jump_speed) {
00261 
00262   _character->setJumpSpeed((btScalar)jump_speed);
00263 }
00264 
00265 ////////////////////////////////////////////////////////////////////
00266 //     Function: BulletCharacterControllerNode::set_max_jump_height
00267 //       Access: Published
00268 //  Description:
00269 ////////////////////////////////////////////////////////////////////
00270 void BulletCharacterControllerNode::
00271 set_max_jump_height(PN_stdfloat max_jump_height) {
00272 
00273   _character->setMaxJumpHeight((btScalar)max_jump_height);
00274 }
00275 
00276 ////////////////////////////////////////////////////////////////////
00277 //     Function: BulletCharacterControllerNode::set_max_slope
00278 //       Access: Published
00279 //  Description:
00280 ////////////////////////////////////////////////////////////////////
00281 void BulletCharacterControllerNode::
00282 set_max_slope(PN_stdfloat max_slope) {
00283 
00284   _character->setMaxSlope((btScalar)max_slope);
00285 }
00286 
00287 ////////////////////////////////////////////////////////////////////
00288 //     Function: BulletCharacterControllerNode::get_max_slope
00289 //       Access: Published
00290 //  Description:
00291 ////////////////////////////////////////////////////////////////////
00292 PN_stdfloat BulletCharacterControllerNode::
00293 get_max_slope() const {
00294 
00295   return (PN_stdfloat)_character->getMaxSlope();
00296 }
00297 
00298 ////////////////////////////////////////////////////////////////////
00299 //     Function: BulletCharacterControllerNode::get_gravity
00300 //  Description:
00301 ////////////////////////////////////////////////////////////////////
00302 PN_stdfloat BulletCharacterControllerNode::
00303 get_gravity() const {
00304 
00305   return (PN_stdfloat)_character->getGravity();
00306 }
00307 
00308 ////////////////////////////////////////////////////////////////////
00309 //     Function: BulletCharacterControllerNode::set_gravity
00310 //  Description:
00311 ////////////////////////////////////////////////////////////////////
00312 void BulletCharacterControllerNode::
00313 set_gravity(PN_stdfloat gravity) {
00314 
00315   _character->setGravity((btScalar)gravity);
00316 }
00317 
00318 
00319 ////////////////////////////////////////////////////////////////////
00320 //     Function: BulletCharacterControllerNode::set_use_ghost_sweep_test
00321 //  Description:
00322 ////////////////////////////////////////////////////////////////////
00323 void BulletCharacterControllerNode::
00324 set_use_ghost_sweep_test(bool value) {
00325 
00326   return _character->setUseGhostSweepTest(value);
00327 }
00328 
 All Classes Functions Variables Enumerations