00001 // Filename: bulletVehicle.cxx 00002 // Created by: enn0x (16Feb10) 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 "bulletVehicle.h" 00016 #include "bulletWorld.h" 00017 #include "bulletRigidBodyNode.h" 00018 #include "bulletWheel.h" 00019 00020 TypeHandle BulletVehicle::_type_handle; 00021 00022 //////////////////////////////////////////////////////////////////// 00023 // Function: BulletVehicle::Constructor 00024 // Access: Published 00025 // Description: Creates a new BulletVehicle instance in the given 00026 // world and with a chassis node. 00027 //////////////////////////////////////////////////////////////////// 00028 BulletVehicle:: 00029 BulletVehicle(BulletWorld *world, BulletRigidBodyNode *chassis) { 00030 00031 btRigidBody *body = btRigidBody::upcast(chassis->get_object()); 00032 00033 _raycaster = new btDefaultVehicleRaycaster(world->get_world()); 00034 _vehicle = new btRaycastVehicle(_tuning._, body, _raycaster); 00035 00036 set_coordinate_system(get_default_up_axis()); 00037 } 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Function: BulletVehicle::set_coordinate_system 00041 // Access: Published 00042 // Description: Specifies which axis is "up". Nessecary for the 00043 // vehicle's suspension to work properly! 00044 //////////////////////////////////////////////////////////////////// 00045 void BulletVehicle:: 00046 set_coordinate_system(BulletUpAxis up) { 00047 00048 switch (up) { 00049 case X_up: 00050 _vehicle->setCoordinateSystem(1, 0, 2); 00051 break; 00052 case Y_up: 00053 _vehicle->setCoordinateSystem(0, 1, 2); 00054 break; 00055 case Z_up: 00056 _vehicle->setCoordinateSystem(0, 2, 1); 00057 break; 00058 default: 00059 bullet_cat.error() << "invalid up axis:" << up << endl; 00060 break; 00061 } 00062 } 00063 00064 //////////////////////////////////////////////////////////////////// 00065 // Function: BulletVehicle::get_forward_vector 00066 // Access: Published 00067 // Description: Returns the forward vector representing the car's 00068 // actual direction of movement. The forward vetcor 00069 // is given in global coordinates. 00070 //////////////////////////////////////////////////////////////////// 00071 LVector3 BulletVehicle:: 00072 get_forward_vector() const { 00073 00074 return btVector3_to_LVector3(_vehicle->getForwardVector()); 00075 } 00076 00077 //////////////////////////////////////////////////////////////////// 00078 // Function: BulletVehicle::get_chassis 00079 // Access: Published 00080 // Description: Returns the chassis of this vehicle. The chassis 00081 // is a rigid body node. 00082 //////////////////////////////////////////////////////////////////// 00083 BulletRigidBodyNode *BulletVehicle:: 00084 get_chassis() { 00085 00086 btRigidBody *bodyPtr = _vehicle->getRigidBody(); 00087 return (bodyPtr) ? (BulletRigidBodyNode *)bodyPtr->getUserPointer() : NULL; 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: BulletVehicle::get_current_speed_km_hour 00092 // Access: Published 00093 // Description: Returns the current speed in kilometers per hour. 00094 // Convert to miles using: km/h * 0.62 = mph 00095 //////////////////////////////////////////////////////////////////// 00096 PN_stdfloat BulletVehicle:: 00097 get_current_speed_km_hour() const { 00098 00099 return (PN_stdfloat)_vehicle->getCurrentSpeedKmHour(); 00100 } 00101 00102 //////////////////////////////////////////////////////////////////// 00103 // Function: BulletVehicle::reset_suspension 00104 // Access: Published 00105 // Description: Resets the vehicle's suspension. 00106 //////////////////////////////////////////////////////////////////// 00107 void BulletVehicle:: 00108 reset_suspension() { 00109 00110 _vehicle->resetSuspension(); 00111 } 00112 00113 //////////////////////////////////////////////////////////////////// 00114 // Function: BulletVehicle::get_steering_value 00115 // Access: Published 00116 // Description: Returns the steering angle of the wheel with index 00117 // idx in degrees. 00118 //////////////////////////////////////////////////////////////////// 00119 PN_stdfloat BulletVehicle:: 00120 get_steering_value(int idx) const { 00121 00122 nassertr(idx < get_num_wheels(), 0.0f); 00123 return rad_2_deg(_vehicle->getSteeringValue(idx)); 00124 } 00125 00126 //////////////////////////////////////////////////////////////////// 00127 // Function: BulletVehicle::set_steering_value 00128 // Access: Published 00129 // Description: Sets the steering value (in degrees) of the wheel 00130 // with index idx. 00131 //////////////////////////////////////////////////////////////////// 00132 void BulletVehicle:: 00133 set_steering_value(PN_stdfloat steering, int idx) { 00134 00135 nassertv(idx < get_num_wheels()); 00136 _vehicle->setSteeringValue(deg_2_rad(steering), idx); 00137 } 00138 00139 //////////////////////////////////////////////////////////////////// 00140 // Function: BulletVehicle::apply_engine_force 00141 // Access: Published 00142 // Description: Applies force at the wheel with index idx for 00143 // acceleration. 00144 //////////////////////////////////////////////////////////////////// 00145 void BulletVehicle:: 00146 apply_engine_force(PN_stdfloat force, int idx) { 00147 00148 nassertv(idx < get_num_wheels()); 00149 _vehicle->applyEngineForce(force, idx); 00150 } 00151 00152 //////////////////////////////////////////////////////////////////// 00153 // Function: BulletVehicle::set_brake 00154 // Access: Published 00155 // Description: Applies braking force to the wheel with index idx. 00156 //////////////////////////////////////////////////////////////////// 00157 void BulletVehicle:: 00158 set_brake(PN_stdfloat brake, int idx) { 00159 00160 nassertv(idx < get_num_wheels()); 00161 _vehicle->setBrake(brake, idx); 00162 } 00163 00164 //////////////////////////////////////////////////////////////////// 00165 // Function: BulletVehicle::set_pitch_control 00166 // Access: Published 00167 // Description: 00168 //////////////////////////////////////////////////////////////////// 00169 void BulletVehicle:: 00170 set_pitch_control(PN_stdfloat pitch) { 00171 00172 _vehicle->setPitchControl(pitch); 00173 } 00174 00175 //////////////////////////////////////////////////////////////////// 00176 // Function: BulletVehicle::create_wheel 00177 // Access: Published 00178 // Description: Factory method for creating wheels for this 00179 // vehicle instance. 00180 //////////////////////////////////////////////////////////////////// 00181 BulletWheel BulletVehicle:: 00182 create_wheel() { 00183 00184 btVector3 pos(0.0, 0.0, 0.0); 00185 btVector3 direction = get_axis(_vehicle->getUpAxis()); 00186 btVector3 axle = get_axis(_vehicle->getRightAxis()); 00187 00188 btScalar suspension(0.4); 00189 btScalar radius(0.3); 00190 00191 btWheelInfo &info = _vehicle->addWheel(pos, direction, axle, suspension, radius, _tuning._, false); 00192 00193 info.m_clientInfo = NULL; 00194 00195 return BulletWheel(info); 00196 } 00197 00198 //////////////////////////////////////////////////////////////////// 00199 // Function: BulletVehicle::get_axis 00200 // Access: Private 00201 // Description: 00202 //////////////////////////////////////////////////////////////////// 00203 btVector3 BulletVehicle:: 00204 get_axis(int idx) { 00205 00206 switch (idx) { 00207 case 0: 00208 return btVector3(1.0, 0.0, 0.0); 00209 case 1: 00210 return btVector3(0.0, 1.0, 0.0); 00211 case 2: 00212 return btVector3(0.0, 0.0, 1.0); 00213 default: 00214 return btVector3(0.0, 0.0, 0.0); 00215 } 00216 } 00217 00218 //////////////////////////////////////////////////////////////////// 00219 // Function: BulletVehicle::get_wheel 00220 // Access: Published 00221 // Description: Returns the BulletWheel with index idx. Causes an 00222 // AssertionError if idx is equal or larger than the 00223 // number of wheels. 00224 //////////////////////////////////////////////////////////////////// 00225 BulletWheel BulletVehicle:: 00226 get_wheel(int idx) const { 00227 00228 nassertr(idx < get_num_wheels(), BulletWheel::empty()); 00229 return BulletWheel(_vehicle->getWheelInfo(idx)); 00230 } 00231 00232 //////////////////////////////////////////////////////////////////// 00233 // Function: BulletVehicle::sync_b2p 00234 // Access: Public 00235 // Description: 00236 //////////////////////////////////////////////////////////////////// 00237 void BulletVehicle:: 00238 sync_b2p() { 00239 00240 for (int i=0; i < get_num_wheels(); i++) { 00241 btWheelInfo info = _vehicle->getWheelInfo(i); 00242 00243 PandaNode *node = (PandaNode *)info.m_clientInfo; 00244 if (node) { 00245 00246 CPT(TransformState) ts = btTrans_to_TransformState(info.m_worldTransform); 00247 00248 // <A> Transform relative to wheel node's parent 00249 //node->set_transform(ts); 00250 00251 // <B> Transform absolute 00252 NodePath np = NodePath::any_path(node); 00253 np.set_transform(np.get_top(), ts); 00254 } 00255 } 00256 } 00257