void PairCollisionFilter::createFloor() { hkVector4 fixedBoxSize(5.f, .5f, 5.f); hkpBoxShape* fixedBoxShape = new hkpBoxShape(fixedBoxSize, 0); hkpRigidBodyCinfo info; info.m_shape = fixedBoxShape; info.m_motionType = hkpMotion::MOTION_FIXED; info.m_position.set(0.f, -1.f, 0.f); hkpRigidBody* lowerFloor = new hkpRigidBody(info); m_world->addEntity(lowerFloor); lowerFloor->removeReference(); fixedBoxShape->removeReference(); }
hkpRigidBody* PairCollisionFilter::create2ndFloor() { hkVector4 fixedBoxSize(3.f, .5f, 3.f); hkpBoxShape* fixedBoxShape = new hkpBoxShape(fixedBoxSize, 0); hkpRigidBodyCinfo info; info.m_shape = fixedBoxShape; info.m_motionType = hkpMotion::MOTION_FIXED; info.m_position.set(0.f, 4.f, 0.f); hkpRigidBody* upperFloor = new hkpRigidBody(info); m_world->addEntity(upperFloor); upperFloor->removeReference(); fixedBoxShape->removeReference(); return upperFloor; }
UserCollisionFilterDemo::UserCollisionFilterDemo( hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { // // Setup the camera // { hkVector4 from(10.0f, 10.0f, 15.0f); hkVector4 to(0.0f, 3.0f, 0.0f); hkVector4 up(0.0f, 1.0f, 0.0f); setupDefaultCameras( env, from, to, up ); } // // Create the world // { hkpWorldCinfo info; m_world = new hkpWorld( info ); m_world->lock(); setupGraphics(); } // // Register the box-box collision agent // { hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() ); } /// To add the filter to the world we simply instantiate a new filter and set it to be active: // // Create the my collision filter // { MyCollisionFilter* filter = new MyCollisionFilter(); m_world->setCollisionFilter( filter ); filter->removeReference(); } // NOTE: You must set the collision filter prior to adding any entities to the world otherwise the pre-filter // added entities could cause undesirable behaviour before the filter is active. // All three objects are hkpBoxShape shapes, two of which are fixed and the third dynamic. In order to allow // our filters work correctly we must assign each of the objects a collision 'group'. Both the lower floor // and the dynamic box have their collision 'group' set to zero: // // Create the floor with collisioninfo = 0 // { hkpRigidBodyCinfo info; hkVector4 fixedBoxSize(5.0f, .5f , 5.0f ); hkpBoxShape* fixedBoxShape = new hkpBoxShape( fixedBoxSize , 0 ); info.m_shape = fixedBoxShape; info.m_motionType = hkpMotion::MOTION_FIXED; info.m_position.set(0.0f, -1.0f, 0.0f); // Create fixed box hkpRigidBody* floor = new hkpRigidBody(info); floor->setCollisionFilterInfo(0); m_world->addEntity(floor); floor->removeReference(); fixedBoxShape->removeReference(); } // Whereas the upper floor belongs to the 'one' group: // // Create the floor with collisioninfo = 1 // { hkpRigidBodyCinfo info; hkVector4 fixedBoxSize(3.0f, .5f , 3.0f ); hkpBoxShape* fixedBoxShape = new hkpBoxShape( fixedBoxSize , 0 ); info.m_shape = fixedBoxShape; info.m_motionType = hkpMotion::MOTION_FIXED; info.m_position.set(0.0f,4.0f,0.0f); // Create fixed box hkpRigidBody* floor = new hkpRigidBody(info); fixedBoxShape->removeReference(); floor->setCollisionFilterInfo(1); m_world->addEntity(floor); floor->removeReference(); } // In this way only the lower floor and the dynamic box will interact based on the rule we defined in // MyCollisionFilter::isCollisionEnabled(...). // // Create a moving box with collisioninfo = 0, so it will collide with only the "bottom" floor // { hkpRigidBodyCinfo boxInfo; hkVector4 boxSize( .5f, .5f ,.5f ); hkpShape* boxShape = new hkpBoxShape( boxSize , 0 ); boxInfo.m_shape = boxShape; boxInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA; // Compute the box inertia tensor hkReal boxMass = 1.0f; hkpMassProperties massProperties; hkpInertiaTensorComputer::computeBoxVolumeMassProperties( boxSize, boxMass, massProperties ); boxInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA; boxInfo.m_mass = boxMass; boxInfo.m_inertiaTensor = massProperties.m_inertiaTensor; boxInfo.m_position.set(0.0f, 7.0f, 0.0f); hkpRigidBody* boxRigidBody = new hkpRigidBody( boxInfo ); boxShape->removeReference(); boxRigidBody->setCollisionFilterInfo(0); // HERE WE SET THE COLLISION FILTER INFO m_world->addEntity( boxRigidBody ); boxRigidBody->removeReference(); } m_world->unlock(); }
ExtendedUserDataDemo::ExtendedUserDataDemo( hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { // // Setup the camera // { hkVector4 from(3.0f, 4.0f, 8.0f); hkVector4 to(0.0f, 1.0f, 0.0f); hkVector4 up(0.0f, 1.0f, 0.0f); setupDefaultCameras( env, from, to, up ); } // // Create the world // { hkpWorldCinfo info; info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM); info.setBroadPhaseWorldSize( 100.0f ); info.m_simulationType = info.SIMULATION_TYPE_CONTINUOUS; // Turn off deactivation so we can see continuous contact point processing info.m_enableDeactivation = false; m_world = new hkpWorld( info ); m_world->lock(); setupGraphics(); } // // Register the box-box collision agent // { hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher()); } // // Create the floor // { hkpRigidBodyCinfo info; hkVector4 fixedBoxSize(5.0f, 0.5f , 5.0f ); hkpBoxShape* fixedBoxShape = new hkpBoxShape( fixedBoxSize , 0 ); info.m_shape = fixedBoxShape; info.m_motionType = hkpMotion::MOTION_FIXED; info.m_position.setZero4(); // Add some bounce. info.m_restitution = 0.8f; info.m_friction = 1.0f; // Force this to collide on PPU and raise all callbacks info.m_forceCollideOntoPpu = true; // Force this to collide on PPU and raise all callbacks info.m_forceCollideOntoPpu = true; // Create fixed box hkpRigidBody* floor = new hkpRigidBody(info); m_world->addEntity(floor); floor->removeReference(); fixedBoxShape->removeReference(); } // For this demo we simply have two box shapes which are constructed in the usual manner using a hkpRigidBodyCinfo 'blueprint'. // The dynamic box creation code in presented below. There are two key things to note in this example; // the 'm_restitution' member variable, which we have explicitly set to value of 0.9. // The restitution is over twice the default value of // 0.4 and is set to give the box (the floor has been set likewise) a more 'bouncy' nature. // // Create a moving object // { hkpRigidBodyCinfo multiSpheresInfo; hkVector4 boxSize( .5f, .5f ,.5f ); // Build listShape of spheres // { hkpSphereShape* sphere = new hkpSphereShape(0.2f); hkReal size = 0.5f; hkpShape* shapes[8]; for (int i = 0; i < 8; i++) { hkReal px = i&0x1 ? -size : size; hkReal py = i&0x2 ? -size : size; hkReal pz = i&0x4 ? -size : size; hkVector4 translation(px, py, pz); shapes[i] = new hkpConvexTranslateShape(sphere, translation); } sphere->removeReference(); hkpListShape* list = new hkpListShape(shapes, 8); for(int i = 0; i < 8; i++) { shapes[i]->removeReference(); } multiSpheresInfo.m_shape = list; } // Compute the box inertia tensor hkpInertiaTensorComputer::setShapeVolumeMassProperties( multiSpheresInfo.m_shape, 1.0f, multiSpheresInfo ); multiSpheresInfo.m_qualityType = HK_COLLIDABLE_QUALITY_CRITICAL; multiSpheresInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA; // Place the box so it bounces interestingly multiSpheresInfo.m_position.set(0.0f, 5.0f, 0.0f); hkVector4 axis(1.0f, 2.0f, 3.0f); axis.normalize3(); multiSpheresInfo.m_rotation.setAxisAngle(axis, -0.7f); // Add some bounce. multiSpheresInfo.m_restitution = 0.5f; multiSpheresInfo.m_friction = 0.1f; multiSpheresInfo.m_numUserDatasInContactPointProperties = 3; hkpRigidBody* multiSphereRigidBody = new hkpRigidBody( multiSpheresInfo ); // remove reference from boxShape since rigid body "owns" it multiSpheresInfo.m_shape->removeReference(); m_world->addEntity( multiSphereRigidBody ); multiSphereRigidBody->removeReference(); // Add the collision event listener to the rigid body m_listener = new MyExtendedUserDataListener( multiSphereRigidBody ); } m_world->unlock(); }
SlidingWorldDemo::SlidingWorldDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env), m_time(0.0f), m_ticks(1), m_currentMode(MANUAL_SHIFT), m_delayBetweenAutomaticShifts(90) { // Disable warnings: hkError::getInstance().setEnabled(0xf0ff00a1, false); //'Attempting to remove an entity twice)' // Set up the camera. { hkVector4 from(0.0f, 75.0f, 30.0f); hkVector4 to(0.0f, 3.0f, 0.0f); hkVector4 up(0.0f, 1.0f, 0.0f); setupDefaultCameras( env, from, to, up ); } m_centers[0].set(10, 0, 0); m_centers[1].set(10, 0, 10); m_centers[2].set(0, 0, 10); m_centers[3].set(-10, 0, 10); m_centers[4].set(-10, 0, 0); m_centers[5].set(-10, 0, -10); m_centers[6].set(0, 0, -10); m_centers[7].set(10, 0, -10); m_currentCenter.setAll(0); // Create the world. { hkpWorldCinfo info; info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM); //info.setBroadPhaseWorldSize( 120.0f ); info.setBroadPhaseWorldSize( 30.0f ); m_world = new hkpWorld( info ); m_world->m_wantDeactivation = true; m_world->lock(); // N.B. We need this border 'for safety': it should play no part in the 'broadphase moving' or the 'coordinate shfting' - // the border callbacks are *not* fired as a result of calls to hkBroadphase::shiftBroadPhase() or hkBroadphase::shiftAllObjects(). // They will be fired as a result of body addition or world stepping, so this will ensure that bodies added or moved // (under integration) get correctly removed from simulation so that the only body not fully contained inside the broadphase // is a single fixed body (assumed to be a large, level-encompassing landscape tile. SlidingWorldBroadphaseBorder *border = new SlidingWorldBroadphaseBorder( m_world ); m_world->setBroadPhaseBorder(border); border->removeReference(); // Setup the rest of the default viewers: setupGraphics(); // Register all collision agents hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() ); } // Create the fixed floor box. { hkVector4 fixedBoxSize(30.0f, .5f , 30.0f ); hkpRigidBodyCinfo info; info.m_shape = new hkpBoxShape( fixedBoxSize , 0 ); info.m_motionType = hkpMotion::MOTION_FIXED; // Create fixed box. hkpRigidBody* box = new hkpRigidBody(info); m_world->addEntity(box)->removeReference(); info.m_shape->removeReference(); } { // Create a single shape, and reuse it for all bodies. hkVector4 boxSize( .75f, .75f ,.75f ); hkpShape* boxShape = new hkpBoxShape( boxSize , 0 ); hkpRigidBodyCinfo boxInfo; boxInfo.m_shape = boxShape; boxInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA; // Compute the box inertia tensor. hkpInertiaTensorComputer::setShapeVolumeMassProperties(boxInfo.m_shape, 5.0f, boxInfo); boxInfo.m_rigidBodyDeactivatorType = hkpRigidBodyDeactivator::DEACTIVATOR_NEVER; for (int i = -20; i <= 20; i += 5) { for (int j = -20; j <= 20; j += 5) { boxInfo.m_position.set( (hkReal)i, 2.0f, (hkReal)j ); hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo); m_world->addEntity( boxRigidBody); m_boxes.pushBack(boxRigidBody); } } boxShape->removeReference(); } m_world->unlock(); }
PhantomEventsDemo::PhantomEventsDemo( hkDemoEnvironment* env ) : hkDefaultPhysicsDemo(env, DEMO_FLAGS_NO_SERIALIZE) { // // Setup the camera // { hkVector4 from(13.0f, 10.0f, 13.0f); hkVector4 to (0.0f, 0.0f, 0.0f); hkVector4 up (0.0f, 1.0f, 0.0f); setupDefaultCameras( env, from, to, up ); } // // Create the world // { hkpWorldCinfo info; info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM); info.setBroadPhaseWorldSize( 100.0f ); info.m_enableDeactivation = false; m_world = new hkpWorld( info ); m_world->lock(); setupGraphics(); } // // Register the collision agents // { hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() ); } // In this demo we have three different objects; the wall, the sphere and a phantom volume. Both the wall, which is simply a box, // and the sphere are created in the usual manner using a hkpRigidBodyCinfo 'blueprint' and are added to the world. // // Create the wall box // { hkpRigidBodyCinfo info; hkVector4 fixedBoxSize( 0.5f, 5.0f , 5.0f ); hkpBoxShape* fixedBoxShape = new hkpBoxShape( fixedBoxSize , 0 ); info.m_shape = fixedBoxShape; info.m_motionType = hkpMotion::MOTION_FIXED; info.m_position.set(-2.0f, 0.0f ,0.0f); // Add some bounce. info.m_restitution = 0.9f; // Create fixed box hkpRigidBody* floor = new hkpRigidBody(info); m_world->addEntity(floor); floor->removeReference(); fixedBoxShape->removeReference(); } // // Create a moving sphere // { hkReal radius = 0.5f; hkpConvexShape* sphereShape = new hkpSphereShape(radius); // To illustrate using the shape, create a rigid body. hkpRigidBodyCinfo sphereInfo; sphereInfo.m_shape = sphereShape; sphereInfo.m_position.set(2.0f, 0.0f, 0.0f); sphereInfo.m_restitution = 0.9f; sphereInfo.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA; // If we need to compute mass properties, we'll do this using the hkpInertiaTensorComputer. if (sphereInfo.m_motionType != hkpMotion::MOTION_FIXED) { sphereInfo.m_mass = 10.0f; hkpMassProperties massProperties; hkpInertiaTensorComputer::computeSphereVolumeMassProperties(radius, sphereInfo.m_mass, massProperties); sphereInfo.m_inertiaTensor = massProperties.m_inertiaTensor; sphereInfo.m_centerOfMass = massProperties.m_centerOfMass; sphereInfo.m_mass = massProperties.m_mass; } // Create a rigid body (using the template above) hkpRigidBody* sphereRigidBody = new hkpRigidBody(sphereInfo); // Remove reference since the body now "owns" the Shape sphereShape->removeReference(); // Finally add body so we can see it, and remove reference since the world now "owns" it. m_world->addEntity(sphereRigidBody); sphereRigidBody->removeReference(); } // Given below is the construction code for the phantom volume: // // Create a PHANTOM floor // { hkpRigidBodyCinfo boxInfo; hkVector4 boxSize( 4.0f, 1.5f , 2.0f ); hkpShape* boxShape = new hkpBoxShape( boxSize , 0 ); boxInfo.m_motionType = hkpMotion::MOTION_FIXED; boxInfo.m_position.set(2.0f, -4.0f, 0.0f); MyPhantomShape* myPhantomShape = new MyPhantomShape(); hkpBvShape* bvShape = new hkpBvShape( boxShape, myPhantomShape ); boxShape->removeReference(); myPhantomShape->removeReference(); boxInfo.m_shape = bvShape; hkpRigidBody* boxRigidBody = new hkpRigidBody( boxInfo ); bvShape->removeReference(); m_world->addEntity( boxRigidBody ); // the color can only be changed after the entity has been added to the world HK_SET_OBJECT_COLOR((hkUlong)boxRigidBody->getCollidable(), hkColor::rgbFromChars(255, 255, 255, 50)); boxRigidBody->removeReference(); } // The phantom volume is created using a hkpBvShape using a hkpBoxShape as the bounding volume and a // hkpPhantomCallbackShape as the child shape. The volume is set to be fixed in space and coloured with a slight alpha blend. // // Once the simulation starts the ball drops into the phantom volume, upon notification of this event we colour the ball // RED and wait for an exit event. As soon as this event is raised we colour the ball GREEN and apply an impulse upwards // back towards the wall and the simulation repeats. m_world->unlock(); }
// A demo which shows drag being applied to several objects. PrevailingWindDemo::PrevailingWindDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { // X and Z are the half-extents of the floor, and Y is the height of the walls. hkReal x = 20.0f; hkReal y = 4.0f; hkReal z = 20.0f; // // Setup the camera. // { hkVector4 from( 0.0f, y * (4.0f), z * 2.0f ); hkVector4 to(0.0f, 0.0f, 0.0f); hkVector4 up(0.0f, 1.0f, 0.0f); setupDefaultCameras( env, from, to, up ); } // // Create the world. // { hkpWorldCinfo info; m_world = new hkpWorld( info ); m_world->lock(); setupGraphics(); } // // Register all collision agents. // { hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() ); } // Create the wind { m_wind = new hkpPrevailingWind( hkVector4( 1.0f, 0.5f, 0.5f ) ); m_wind->addOscillation( hkVector4( 0.6f, 0.0f, 0.2f ), 5.0f, 1.0f, 0.75f); m_wind->addOscillation( hkVector4( 1.5f, 1.0f, 0.0f ), 13.0f); m_wind->addOscillation( hkVector4( 2.5f, 0.0f, 1.0f ), 31.0f, 2.0f ); // Let the wind update the oscillators. m_world->addWorldPostSimulationListener( m_wind ); } hkVector4 areaSize( x, y, z ); // Create the floor { hkpRigidBody* lowerFloor; hkVector4 fixedBoxSize( 15.0f , 0.5f , 15.0f ); hkpBoxShape* fixedBoxShape = new hkpBoxShape( fixedBoxSize , 0 ); hkpRigidBodyCinfo info; { info.m_shape = fixedBoxShape; info.m_motionType = hkpMotion::MOTION_FIXED; info.m_position.set(0.0f, -0.5f, 0.0f); } lowerFloor = new hkpRigidBody(info); m_world->addEntity(lowerFloor); lowerFloor->removeReference(); fixedBoxShape->removeReference(); } createWindmill ( m_world, m_wind, hkVector4( -4.0f, 0.0f, 2.0f ) ); createPalmTree ( m_world, m_wind, hkVector4( 4.0f, 0.0f, -3.0f ) ); createPalmTree ( m_world, m_wind, hkVector4( 8.0f, 0.0f, 5.0f ) ); m_world->unlock(); }
CollisionEventsDemo::CollisionEventsDemo( hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { // // Setup the camera // { hkVector4 from(3.0f, 4.0f, 8.0f); hkVector4 to(0.0f, 1.0f, 0.0f); hkVector4 up(0.0f, 1.0f, 0.0f); setupDefaultCameras( env, from, to, up ); } // // Create the world // { hkpWorldCinfo info; info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM); info.setBroadPhaseWorldSize( 100.0f ); info.m_simulationType = info.SIMULATION_TYPE_CONTINUOUS; // Turn off deactivation so we can see continuous contact point processing info.m_enableDeactivation = false; m_world = new hkpWorld( info ); m_world->lock(); setupGraphics(); } // // Register the box-box collision agent // { hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher()); } // // Create the floor // { hkpRigidBodyCinfo info; hkVector4 fixedBoxSize(5.0f, 0.5f , 5.0f ); hkpBoxShape* fixedBoxShape = new hkpBoxShape( fixedBoxSize , 0 ); info.m_shape = fixedBoxShape; info.m_motionType = hkpMotion::MOTION_FIXED; info.m_position.setZero4(); // Add some bounce. info.m_restitution = 0.8f; info.m_friction = 1.0f; // Create fixed box hkpRigidBody* floor = new hkpRigidBody(info); m_world->addEntity(floor); floor->removeReference(); fixedBoxShape->removeReference(); } // For this demo we simply have two box shapes which are constructed in the usual manner using a hkpRigidBodyCinfo 'blueprint'. // The dynamic box creation code in presented below. There are two key things to note in this example; // the 'm_restitution' member variable, which we have explicitly set to value of 0.9. // The restitution is over twice the default value of // 0.4 and is set to give the box (the floor has been set likewise) a more 'bouncy' nature. // // Create a moving box // { hkpRigidBodyCinfo boxInfo; hkVector4 boxSize( .5f, .5f ,.5f ); boxInfo.m_shape = new hkpBoxShape( boxSize , 0 ); // Compute the box inertia tensor hkpInertiaTensorComputer::setShapeVolumeMassProperties( boxInfo.m_shape, 1.0f, boxInfo ); boxInfo.m_qualityType = HK_COLLIDABLE_QUALITY_DEBRIS; boxInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA; // Place the box so it bounces interestingly boxInfo.m_position.set(0.0f, 5.0f, 0.0f); hkVector4 axis(1.0f, 2.0f, 3.0f); axis.normalize3(); boxInfo.m_rotation.setAxisAngle(axis, -0.7f); // Add some bounce. boxInfo.m_restitution = 0.5f; boxInfo.m_friction = 0.1f; hkpRigidBody* boxRigidBody = new hkpRigidBody( boxInfo ); // remove reference from boxShape since rigid body "owns" it boxInfo.m_shape->removeReference(); m_world->addEntity( boxRigidBody ); boxRigidBody->removeReference(); // Add the collision event listener to the rigid body MyCollisionListener* listener = new MyCollisionListener( boxRigidBody ); listener->m_reportLevel = m_env->m_reportingLevel; } m_world->unlock(); }