void VehicleApiDemo::createVehicle(hkpRigidBody* chassis) { // Create the basic vehicle. m_vehicle = new hkpVehicleInstance( chassis ); VehicleSetup setup; setup.buildVehicle( m_world, *m_vehicle ); ///[integrationWithSDK] /// Actions are the interface between user controllable behavior of the physical simulation and the Havok core. /// You can easily integrate the Vehicle Kit with the Havok physical simulation using the hkpVehicleInstance action, /// which establishes the connection between the two SDKs. /// /// To simulate a vehicle, you first need to create a hkpVehicleInstance instance in your game. /// You then add it to the actions of your core physical simulation, just like any other user action: /// m_world->addAction(m_vehicle); ///> /// Once you have added the action to the simulation, no extra work is required to simulate the vehicle. /// On each call to step the core physical simulation, the vehicle action will be updated automatically. }
VehicleManagerDemo::VehicleManagerDemo( hkDemoEnvironment* env, hkBool createWorld, int numWheels, int numVehicles ) : hkDefaultPhysicsDemo( env ) { const MTVehicleRayCastDemoVariant& variant = g_MTVehicleRayCastDemoVariants[m_variantId]; m_bootstrapIterations = 150; numVehicles = 50; m_numVehicles = numVehicles; m_numWheels = numWheels; m_vehicles.setSize( m_numVehicles ); setUpWorld(); if (!createWorld) { return; } m_world->lock(); // // Create a vehicle manager and a vehicle setup object. // VehicleSetup* vehicleSetup; if ( variant.m_demoType == MTVehicleRayCastDemoVariant::SINGLETHREADED_RAY_CAST || variant.m_demoType == MTVehicleRayCastDemoVariant::MULTITHREADED_RAY_CAST ) { m_vehicleManager = new hkpVehicleRayCastBatchingManager(); vehicleSetup = new VehicleSetup(); } else { m_vehicleManager = new hkpVehicleLinearCastBatchingManager(); vehicleSetup = new LinearCastVehicleSetup(); } // // Setup vehicle chassis and create vehicles // { // // Create vehicle's chassis shape. // hkpConvexVerticesShape* chassisShape = VehicleApiUtils::createCarChassisShape(); createDisplayWheels(); for ( int vehicleId = 0; vehicleId < m_vehicles.getSize(); vehicleId++ ) { // // Create the vehicle. // { // // Create the chassis body. // hkpRigidBody* chassisRigidBody; { hkpRigidBodyCinfo chassisInfo; chassisInfo.m_mass = 750.0f; chassisInfo.m_shape = chassisShape; chassisInfo.m_friction = 0.8f; chassisInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA; // Position chassis on the ground. // Inertia tensor will be set by VehicleSetupMultithreaded. chassisInfo.m_position.set(-40.0f, -4.5f, vehicleId * 5.0f); chassisInfo.m_inertiaTensor.setDiagonal(1.0f, 1.0f, 1.0f); chassisInfo.m_centerOfMass.set( -0.037f, 0.143f, 0.0f); chassisInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo( CHASSIS_LAYER, 0 ); chassisRigidBody = new hkpRigidBody( chassisInfo ); } // Create vehicle { hkpVehicleInstance *const vehicle = new hkpVehicleInstance( chassisRigidBody ); vehicleSetup->buildVehicle( m_world, *vehicle ); vehicle->addToWorld( m_world ); m_vehicleManager->addVehicle( vehicle ); m_vehicles[vehicleId].m_vehicle = vehicle; m_vehicles[vehicleId].m_lastRPM = 0.0f; m_vehicles[vehicleId].m_vehicle->m_wheelCollide->setCollisionFilterInfo( hkpGroupFilter::calcFilterInfo( WHEEL_LAYER, 0 ) ); } // This hkpAction flips the car upright if it turns over. if (vehicleId == 0) { hkVector4 rotationAxis(1.0f, 0.0f, 0.0f); hkVector4 upAxis(0.0f, 1.0f, 0.0f); m_reorientAction = new hkpReorientAction(chassisRigidBody, rotationAxis, upAxis); } chassisRigidBody->removeReference(); } } chassisShape->removeReference(); } vehicleSetup->removeReference(); // // Create the camera. // { VehicleApiUtils::createCamera( m_camera ); m_followCarView = true; } m_world->unlock(); // // Setup for multithreading. // hkpCollisionQueryJobQueueUtils::registerWithJobQueue( m_jobQueue ); // register the default addCdPoint() function; you are free to register your own implementation here though hkpFixedBufferCdPointCollector::registerDefaultAddCdPointFunction(); // Special case for this demo variant: we do not allow the # of active SPUs to drop to zero as this can cause a deadlock. if ( variant.m_demoType == MTVehicleRayCastDemoVariant::MULTITHREADED_RAY_CAST || variant.m_demoType == MTVehicleRayCastDemoVariant::MULTITHREADED_LINEAR_CAST ) { m_allowZeroActiveSpus = false; } }