Panda3D
|
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