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. }
hkpPhysicsSystem* VehicleCloning::createVehicle() { // // Create vehicle's chassis shape. // hkpConvexVerticesShape* chassisShape = VehicleApiUtils::createCarChassisShape(); // // Create the chassis body. // hkpRigidBody* chassisRigidBody; { hkpRigidBodyCinfo chassisInfo; // The mass value is reset by the vehicle SDK. 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. // mass and inertia tensor will be set by VehicleSetup chassisInfo.m_position.set(0.0f, -3.0f, -10.0f); chassisInfo.m_inertiaTensor.setDiagonal(1.0f, 1.0f, 1.0f); chassisInfo.m_centerOfMass.set( -0.037f, 0.143f, 0.0f); int chassisLayer = 1; chassisInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo( chassisLayer, 0 ); chassisRigidBody = new hkpRigidBody(chassisInfo); } // // Instantiate the vehicle components. // hkpVehicleInstance* vehicle = new hkpVehicleInstance(chassisRigidBody); { vehicle->m_data = new hkpVehicleData; vehicle->m_aerodynamics = new hkpVehicleDefaultAerodynamics; vehicle->m_brake = new hkpVehicleDefaultBrake; vehicle->m_driverInput = new hkpVehicleDefaultAnalogDriverInput; vehicle->m_engine = new hkpVehicleDefaultEngine; vehicle->m_steering = new hkpVehicleDefaultSteering; vehicle->m_suspension = new hkpVehicleDefaultSuspension; vehicle->m_transmission = new hkpVehicleDefaultTransmission; vehicle->m_velocityDamper = new hkpVehicleDefaultVelocityDamper; vehicle->m_wheelCollide = new hkpVehicleRayCastWheelCollide; VehicleSetup setup; setup.setupVehicleData( m_world, *vehicle->m_data ); // initialise the tyre marks controller with 128 tyre mark points. vehicle->m_tyreMarks = new hkpTyremarksInfo( *vehicle->m_data, 128 ); setup.setupComponent( *vehicle->m_data, *static_cast< hkpVehicleDefaultAnalogDriverInput* >(vehicle->m_driverInput) ); setup.setupComponent( *vehicle->m_data, *static_cast< hkpVehicleDefaultSteering*>(vehicle->m_steering)); setup.setupComponent( *vehicle->m_data, *static_cast< hkpVehicleDefaultEngine*>(vehicle->m_engine) ); setup.setupComponent( *vehicle->m_data, *static_cast< hkpVehicleDefaultTransmission*>(vehicle->m_transmission) ); setup.setupComponent( *vehicle->m_data, *static_cast< hkpVehicleDefaultBrake*>(vehicle->m_brake) ); setup.setupComponent( *vehicle->m_data, *static_cast< hkpVehicleDefaultSuspension*>(vehicle->m_suspension) ); setup.setupComponent( *vehicle->m_data, *static_cast< hkpVehicleDefaultAerodynamics*>(vehicle->m_aerodynamics) ); setup.setupComponent( *vehicle->m_data, *static_cast< hkpVehicleDefaultVelocityDamper*>(vehicle->m_velocityDamper) ); // The wheel collide component performs collision detection. To do this, it needs to create an // aabbPhantom from the vehicle information that has been set here already. setup.setupWheelCollide( m_world, *vehicle, *static_cast< hkpVehicleRayCastWheelCollide*>(vehicle->m_wheelCollide) ); setup.setupTyremarks( *vehicle->m_data, *static_cast< hkpTyremarksInfo*>(vehicle->m_tyreMarks) ); } // Give the driver input default values so that the vehicle will drive, even if it is in circles! { vehicle->m_deviceStatus = new hkpVehicleDriverInputAnalogStatus; hkpVehicleDriverInputAnalogStatus* deviceStatus = (hkpVehicleDriverInputAnalogStatus*)vehicle->m_deviceStatus; // Velocity. deviceStatus->m_positionY = -0.0f; // Turning. deviceStatus->m_positionX = -0.0f; // Defaults. deviceStatus->m_handbrakeButtonPressed = false; deviceStatus->m_reverseButtonPressed = false; } vehicle->init(); // Create a physics system and add the action, rigid body and the phantoms that comprise the vehicle to it. hkpPhysicsSystem* vehicleSystem = new hkpPhysicsSystem(); { vehicleSystem->addAction( vehicle ); vehicleSystem->addRigidBody( chassisRigidBody ); hkArray<hkpPhantom*> phantoms; vehicle->getPhantoms( phantoms ); const int numPhantoms = phantoms.getSize(); for ( int i = 0; i < numPhantoms; ++i ) { vehicleSystem->addPhantom( phantoms[i] ); } } chassisRigidBody->removeReference(); chassisShape->removeReference(); vehicle->removeReference(); return vehicleSystem; }
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; } }