WorldLinearCastMultithreadedDemo::WorldLinearCastMultithreadedDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env), m_time(0), m_semaphore(0,1000) { const WorldLinearCastMultithreadedDemoVariant& variant = g_WorldLinearCastMultithreadedDemoVariants[m_variantId]; // // Setup the camera. // { hkVector4 from(0.0f, 10.0f, 30.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.m_gravity.set(0.0f, -9.81f, 0.0f); info.setBroadPhaseWorldSize( 100.0f ); info.m_collisionTolerance = .001f; info.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED; } m_world = new hkpWorld(info); m_world->lock(); // Register collision agents hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher()); setupGraphics(); } // // Create the underlying landscape // hkAabb aabb; { hkVector4 scaling(1.0f, 0.3f, 1.0f ); m_groundShapeFactory.setScaling( scaling ); m_groundShapeFactory.setTriangleRadius( 0.0f ); hkpMoppBvTreeShape* groundShape = m_groundShapeFactory.createMoppShapeForSpu(); { hkpRigidBodyCinfo groundInfo; groundInfo.m_shape = groundShape; groundInfo.m_motionType = hkpMotion::MOTION_FIXED; hkpRigidBody* b = new hkpRigidBody(groundInfo); b->getCollidable()->getShape()->getAabb( b->getTransform(), 0.0f, aabb ); m_world->addEntity(b); b->removeReference(); } groundShape->removeReference(); } // Create a selection of shapes hkArray<hkpShape*> shapes; createShapes( shapes ); // We would like to ensure that each object is placed on the surface of the landscape such // that it is not penetrating and is resting on the surface. To do this we make use of world // linear casting which will allow us to shape cast our objects against the landscape. // Using the results of this cast we can easily position our objects in the desired manner. { hkPseudoRandomGenerator random(501); int xRes = 8; int yRes = 8; for (int i = 0; i < xRes * yRes; i ++ ) { // create a fixed rigid body info with a random orientation hkpRigidBodyCinfo ci; ci.m_shape = shapes[ random.getRandChar( shapes.getSize() ) ]; ci.m_motionType = hkpMotion::MOTION_FIXED; random.getRandomRotation( ci.m_rotation ); // place it above the plane ci.m_position.set( (1.8f * aabb.m_max(0)) * (-.5f + (i%xRes)/ float(xRes)), aabb.m_max(1) + 10.0f, (1.8f * aabb.m_max(2)) * (-.5f + (i/xRes)/ float(yRes)) ); // create the rigid body hkpRigidBody* b = new hkpRigidBody(ci); // To perform the linear casting we use a hkpLinearCastInput structure and // set the end position of the cast (the start position is given by the // location of our object). We then create a hkpClosestCdPointCollector // to gather the results of the cast and then ask the world to perform // the cast: { hkpLinearCastInput li; li.m_to.set( ci.m_position(0), aabb.m_min(1), ci.m_position(2) ); hkpClosestCdPointCollector hitCollector; m_world->linearCast( b->getCollidable(), li, hitCollector ); // Check for hits if ( hitCollector.hasHit() ) { hkVector4 position; position.setInterpolate4( ci.m_position, li.m_to, hitCollector.getHitContact().getDistance() ); b->setPosition( position ); } } m_world->addEntity( b ); m_rocksOnTheFloor.pushBack( b ); } } hkPseudoRandomGenerator generator(3245); // Create query objects and phantoms from shapes buildQueryObects( shapes, m_queryObjects ); // Remove shape references { for (int i = 0; i < shapes.getSize(); i++) { shapes[i]->removeReference(); shapes[i] = 0; } } m_world->unlock(); hkpCollisionQueryJobQueueUtils::registerWithJobQueue(m_jobQueue); // 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 == WorldLinearCastMultithreadedDemoVariant::MULTITHREADED_ON_SPU ) m_allowZeroActiveSpus = false; // register the default addCdPoint() function; you are free to register your own implementation here though hkpFixedBufferCdPointCollector::registerDefaultAddCdPointFunction(); }
ShapeQueryDemo::ShapeQueryDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env), m_time(0) { // Setup the camera. { hkVector4 from(0.0f, 10.0f, 30.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.m_gravity.set(0.0f, -9.81f, 0.0f); info.setBroadPhaseWorldSize( 100.0f ); info.m_collisionTolerance = .001f; m_world = new hkpWorld(info); m_world->lock(); setupGraphics(); } // Register collision agents hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() ); // // Create the underlying landscape // hkAabb aabb; { hkVector4 scaling(1.0f, 0.3f, 1.0f ); m_groundShapeFactory.setScaling( scaling ); m_groundShapeFactory.setTriangleRadius( 0.0f ); hkpMoppBvTreeShape* groundShape = m_groundShapeFactory.createMoppShape(); { hkpRigidBodyCinfo groundInfo; groundInfo.m_shape = groundShape; groundInfo.m_motionType = hkpMotion::MOTION_FIXED; hkpRigidBody* b = new hkpRigidBody(groundInfo); b->getCollidable()->getShape()->getAabb( b->getTransform(), 0.0f, aabb ); m_world->addEntity(b); b->removeReference(); } groundShape->removeReference(); } // Create a selection of shapes hkArray<hkpShape*> shapes; createShapes( shapes ); // We would like to ensure that each object is placed on the surface of the landscape such // that it is not penetrating and is resting on the surface. To do this we make use of world // linear casting which will allow us to shape cast our objects against the landscape. // Using the results of this cast we can easily position our objects in the desired manner. { hkPseudoRandomGenerator random(501); int xRes = 8; int yRes = 8; for (int i = 0; i < xRes * yRes; i ++ ) { // create a fixed rigid body info with a random orientation hkpRigidBodyCinfo ci; ci.m_shape = shapes[ random.getRandChar( shapes.getSize() ) ]; ci.m_motionType = hkpMotion::MOTION_FIXED; random.getRandomRotation( ci.m_rotation ); // place it above the plane ci.m_position.set( (1.8f * aabb.m_max(0)) * (-.5f + (i%xRes)/ float(xRes)), aabb.m_max(1) + 10.0f, (1.8f * aabb.m_max(2)) * (-.5f + (i/xRes)/ float(yRes)) ); // create the rigid body hkpRigidBody* b = new hkpRigidBody(ci); // To perform the linear casting we use a hkpLinearCastInput structure and // set the end position of the cast (the start position is given by the // location of our object). We then create a hkpClosestCdPointCollector // to gather the results of the cast and then ask the world to perform // the cast: { hkpLinearCastInput li; li.m_to.set( ci.m_position(0), aabb.m_min(1), ci.m_position(2) ); hkpClosestCdPointCollector hitCollector; m_world->linearCast( b->getCollidable(), li, hitCollector ); // Check for hits if ( hitCollector.hasHit() ) { hkVector4 position; position.setInterpolate4( ci.m_position, li.m_to, hitCollector.getHitContact().getDistance() ); b->setPosition( position ); } } m_world->addEntity( b ); m_fixedSmallBodies.pushBack( b ); } } hkPseudoRandomGenerator generator(3245); // Create query objects and phantoms from our shapes if (m_variantId == 0) { // Only AABB phantoms are needed for the raycast variant buildAabbPhantoms( m_world, 10, m_rayCastPhantoms, generator ); } else { // Create query objects and phantoms from shapes buildQueryObects( shapes, m_queryObjects ); buildSimplePhantoms( m_world, shapes, m_simplePhantoms, generator ); buildCachingPhantoms( m_world, shapes, m_cachingPhantoms, generator ); } // Remove shape references { for (int i = 0; i < shapes.getSize(); i++) { shapes[i]->removeReference(); shapes[i] = 0; } } m_world->unlock(); }