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();

}
Exemple #2
0
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();
}