Пример #1
0
void ShapeQueryDemo::worldGetClosestPoints( hkpWorld* world, hkReal time, hkArray<QueryObject>& queryObjects )
{
	hkpAllCdPointCollector collector[10];

	// We setup the usual loop and call the getClosestPoints(...) method:
	{
		for ( int i = 0; i < queryObjects.getSize(); i++ )
		{
			QueryObject& qo = queryObjects[i];

			// create a new position: all objects move in a circle
			hkReal t = time + HK_REAL_PI * 2 * i / queryObjects.getSize();
			hkVector4 pos( hkMath::sin( t ) * 10.0f, 0.0f, hkMath::cos( t ) * 10.0f );
			qo.m_transform->setTranslation(pos);

			// Query for intersecting objects
			for (int j = 0; j < NUM_ITER; j++ )
			{
				MY_TIMER_BEGIN(i);
				collector[i].reset();
				world->getClosestPoints( qo.m_collidable, *world->getCollisionInput(), collector[i] );
				MY_TIMER_END();
			}
		}
	}

	// Updating our display is carried out in the usual manner:
	{
		for ( int i = 0; i < queryObjects.getSize(); i++ )
		{
			// iterate over each individual hit
			for (int j = 0; j < collector[i].getHits().getSize(); j++ )
			{
				displayRootCdPoint( world, collector[i].getHits()[j] );
			}
		}
	}

	{
		for ( int i = 0; i < queryObjects.getSize(); i++ )
		{
			QueryObject& qo = queryObjects[i];
			hkDebugDisplay::getInstance().updateGeometry( qo.m_collidable->getTransform(), (hkUlong)qo.m_collidable, 0);
		}
	}
}
hkDemo::Result WorldLinearCastMultithreadedDemo::stepDemo()
{
	if (m_jobThreadPool->getNumThreads() == 0)
	{
		 HK_WARN(0x34561f23, "This demo does not run with only one thread");
		 return DEMO_STOP;
	}

//	const WorldLinearCastMultithreadedDemoVariant& variant = g_WorldLinearCastMultithreadedDemoVariants[m_variantId];

	m_world->lock();

	//	Reset all object colors
	{
		for (int i = 0; i < m_rocksOnTheFloor.getSize(); i++)
		{
			HK_SET_OBJECT_COLOR((hkUlong)m_rocksOnTheFloor[i]->getCollidable(), hkColor::rgbFromChars(70,70,70));
		}
	}


	// For this cast we use a hkpClosestCdPointCollector to gather the results:
	hkpClosestCdPointCollector collectors[10];

	// Since we're not too concerned with perfect accuracy, we can set the early out
	// distance to give the algorithm a chance to exit more quickly:
	m_world->getCollisionInput()->m_config->m_iterativeLinearCastEarlyOutDistance = 0.1f;
	
	m_world->unlock();

	// Cast direction & length.
	hkVector4 castVector( 0.0f, -30.0f, 0.0f );

	int numQueryObjects = m_queryObjects.getSize();

	//
	// Setup the output array where the resulting collision points will be returned.
	//
	hkpRootCdPoint* collisionPoints = hkAllocateChunk<hkpRootCdPoint>(numQueryObjects, HK_MEMORY_CLASS_DEMO);

	//
	// Setup commands: one command for each query object.
	//
	hkArray<hkpWorldLinearCastCommand> commands;
	{
		for ( int i = 0; i < numQueryObjects; i++ )
		{
			QueryObject& queryObject = m_queryObjects[i];

			//
			// Let QueryObjects move in circles.
			//
			hkVector4 position;
			{
				hkReal t = m_time + HK_REAL_PI * 2 * i / m_queryObjects.getSize();
				position.set( hkMath::sin( t ) * 10.0f, 10.0f, hkMath::cos( t ) * 10.0f );
			}

			queryObject.m_transform->setTranslation(position);

			hkpWorldLinearCastCommand& command = commands.expandOne();
			{
				// Init input data.
				{
					command.m_input.m_to				  . setAdd4( position, castVector );
					command.m_input.m_maxExtraPenetration = HK_REAL_EPSILON;
					command.m_input.m_startPointTolerance = HK_REAL_EPSILON;

					command.m_collidable				  = queryObject.m_collidable;
				}

				// Init output data.
				{
					command.m_results			= &collisionPoints[i];
					command.m_resultsCapacity	= 1;
					command.m_numResultsOut		= 0;
				}
			}
		}
	}

	//
	// Create the job header.
	//
	hkpCollisionQueryJobHeader* jobHeader;
	{
		jobHeader = hkAllocateChunk<hkpCollisionQueryJobHeader>(1, HK_MEMORY_CLASS_DEMO);
	}

	//
	// Setup hkpWorldLinearCastJob.
	//
	m_world->markForRead();
	hkpWorldLinearCastJob worldLinearCastJob(m_world->getCollisionInput(), jobHeader, commands.begin(), commands.getSize(), m_world->m_broadPhase, &m_semaphore);
	m_world->unmarkForRead();

	//
	// Put the job on the queue, kick-off the PPU/SPU threads and wait for everything to finish.
	//
	{
		m_world->lockReadOnly();

		//
		// Put the raycast job on the job queue.
		//

		worldLinearCastJob.setRunsOnSpuOrPpu();
		m_jobQueue->addJob( worldLinearCastJob, hkJobQueue::JOB_LOW_PRIORITY );

		m_jobThreadPool->processAllJobs( m_jobQueue );

		m_jobThreadPool->waitForCompletion();

		//
		// Wait for the one single job we started to finish.
		//
		m_semaphore.acquire();

		m_world->unlockReadOnly();
	}

	//
	// Display results.
	//
	{
		m_world->lock();
		{
			for (int i = 0; i < commands.getSize(); i++)
			{
				QueryObject& queryObject = m_queryObjects[i];

				hkpWorldLinearCastCommand& command = commands[i];
				if ( command.m_numResultsOut > 0 )
				{
					// move our position to the hit and draw a line along the cast direction
					hkVector4& pos = queryObject.m_transform->getTranslation();
					hkVector4 to; to.setAdd4( pos, castVector );
					hkVector4 newPos; newPos.setInterpolate4( pos, to, command.m_results->m_contact.getDistance() );
					HK_DISPLAY_LINE(pos, newPos, hkColor::GREEN);

					// Update our QO
					queryObject.m_transform->setTranslation( newPos );
					hkDebugDisplay::getInstance().updateGeometry( queryObject.m_collidable->getTransform(), (hkUlong)queryObject.m_collidable, 0);

					// call a function to display the details
					displayRootCdPoint( m_world, *command.m_results );
				}
				else
				{
					// only draw a line along the cast direction
					hkVector4& pos = queryObject.m_transform->getTranslation();
					hkVector4 to; to.setAdd4( pos, castVector );
					HK_DISPLAY_LINE(pos, to, hkColor::GREEN);

					// Update our QO
					hkVector4 nirvana(10000.0f, 10000.0f, 10000.0f);
					queryObject.m_transform->setTranslation( nirvana );
					hkDebugDisplay::getInstance().updateGeometry( queryObject.m_collidable->getTransform(), (hkUlong)queryObject.m_collidable, 0);
				}
			}
		}
		m_world->unlock();
	}

	//
	// Free temporarily allocated memory.
	//
	hkDeallocateChunk( jobHeader, 1, HK_MEMORY_CLASS_DEMO );
	hkDeallocateChunk(collisionPoints, numQueryObjects, HK_MEMORY_CLASS_DEMO);

	m_time += 0.005f;

	return hkDefaultPhysicsDemo::stepDemo();
}
Пример #3
0
void ShapeQueryDemo::worldLinearCast( hkpWorld* world, hkReal time, hkArray<QueryObject>& queryObjects )
{
	// For this cast we use a hkpClosestCdPointCollector to gather the results:
	hkpClosestCdPointCollector collector[10];

	// Since we're not too concerned with perfect accuracy, we can set the early out
	// distance to give the algorithm a chance to exit more quickly:
	world->getCollisionInput()->m_config->m_iterativeLinearCastEarlyOutDistance = 0.1f;
	
	// Cast direction
	hkVector4 displacement( 0.0f, -30.0f, 0.0f );

	// Perform all queries in one go (do not interleave with examining the results,
	// as this is bad for code and data cache.

	// The core loop is very similar to the one we described for the world ray cast,
	// with several casts being performed forming a circular pattern. The only
	// real difference this time is that we get the shape to cast (and the 'from'
	// position) from our collection of 'QueryObjects'.
	{

		for ( int i = 0; i < queryObjects.getSize(); i++ )
		{
			QueryObject& qo = queryObjects[i];

			// Create a new position: all objects move in a circle
			hkReal t = time + HK_REAL_PI * 2 * i / queryObjects.getSize();
			hkVector4 pos( hkMath::sin( t ) * 10.0f, 10.0f, hkMath::cos( t ) * 10.0f );

			// Set our position in our motion state
			qo.m_transform->setTranslation(pos);

			//
			// Query for intersecting objects
			//
			for (int k = 0; k < NUM_ITER ; k++ )
			{
				MY_TIMER_BEGIN(i);
				{
					// Input
					hkpLinearCastInput input;
					input.m_to.setAdd4( pos, displacement );

					// Output
					hkpClosestCdPointCollector& coll = collector[i];
					coll.reset();

					// Call the engine
					world->linearCast( qo.m_collidable, input, coll );
				}
				MY_TIMER_END();
			}
		}
	}

	//
	//	Batch examine the results
	//

	// All that remains to do now is to display the results and update the position of our 'QueryObjects' (QO). We use the updateGeometry(...)
	// method from hkDebugDisplay to do the QO updates and once again we draw everything in GREEN:
	{
		for ( int i = 0; i < queryObjects.getSize(); i++ )
		{
			QueryObject& qo = queryObjects[i];

			// update our display
			if ( collector[i].hasHit() )
			{
				// move our position to the hit and draw a line along the cast direction
				hkVector4& pos = qo.m_transform->getTranslation();
				hkVector4 to; to.setAdd4( pos, displacement );
				hkVector4 newPos; newPos.setInterpolate4( pos, to, collector[i].getHitContact().getDistance() );
				HK_DISPLAY_LINE(pos, newPos, hkColor::GREEN);

				// Update our QO
				qo.m_transform->setTranslation( newPos );
				hkDebugDisplay::getInstance().updateGeometry( qo.m_collidable->getTransform(), (hkUlong)qo.m_collidable, 0);

				// call a function to display the details
				displayRootCdPoint( world, collector[i].getHit() );
			}
		}
	}
}