Beispiel #1
0
// Verify that BeginContact() and EndContact() are called for collisions
// between particles.
TEST_F(BodyContactTests, ParticleContactListener)
{
	// Drop particle B on top of particle A.
	b2ParticleDef pd;
	pd.flags = b2_particleContactListenerParticle;
	pd.position.Set(0.0f, m_particleDiameter);
	pd.velocity.Set(0.0f, -m_particleDiameter);
	const int32 particleA = m_particleSystem->CreateParticle(pd);
	pd.position.Set(0.0f, m_particleDiameter * 3.0f);
	pd.velocity.Set(0.0f, m_particleDiameter * -2.0f);
	const int32 particleB = m_particleSystem->CreateParticle(pd);

	ParticleContactListener listener(m_particleSystem);
	m_world->SetContactListener(&listener);

	RunStep(60.0f, 2.0f);
	EXPECT_GT(listener.m_beginParticleContacts.size(), 0U);
	EXPECT_EQ(listener.m_endParticleContacts.size(), 0U);

	for (uint32 i = 0; i < listener.m_beginParticleContacts.size(); ++i)
	{
		b2ParticleContact contact = listener.m_beginParticleContacts[i];
		EXPECT_TRUE(contact.indexA == particleA ? contact.indexB == particleB :
					contact.indexB == particleA);
	}

	// Push particleB away from particleA.
	b2Vec2* velocities = m_particleSystem->GetVelocityBuffer();
	velocities[particleB].x = m_particleDiameter;
	velocities[particleB].y = 0.0f;
	listener.m_beginParticleContacts.clear();
	RunStep(60.0f, 0.5f);
	EXPECT_EQ(listener.m_beginParticleContacts.size(), 0U);
	EXPECT_GT(listener.m_endParticleContacts.size(), 0U);
}
Beispiel #2
0
// Verify that it's possible to enable / disable collisions between fixtures
// and particles.
TEST_F(BodyContactTests, EnableDisableFixtureParticleContactsWithContactFilter)
{
	// Create a fixture to drop particles on to.
	b2Fixture* const groundFixture = CreateGroundBox();

	// Create a particle above the ground and drop it.
	b2ParticleDef pd;
	pd.flags = b2_fixtureContactFilterParticle;
	pd.position.Set(0.0f, m_particleDiameter * 2.0f);
	pd.velocity.Set(0.0f, -m_particleDiameter);
	m_particleSystem->CreateParticle(pd);

	// Leave contacts enabled.
	ParticleContactDisabler contactDisabler;
	m_world->SetContactFilter(&contactDisabler);

	// Run the simulation and verify the particle is on top of the ground
	// fixture.
	RunStep(60.0f, 2.0f);
	EXPECT_GE(m_particleSystem->GetPositionBuffer()[0].y,
			  groundFixture->GetAABB(0).upperBound.y);

	// Disable fixture / particle contacts.
	contactDisabler.m_enableFixtureParticleCollisions = false;

	// Run the simulation and verify the particle falls through the ground.
	RunStep(60.0f, 2.0f);
	EXPECT_LT(m_particleSystem->GetPositionBuffer()[0].y,
			  groundFixture->GetAABB(0).upperBound.y);

}
// Verify that it's possible to enable / disable collisions between particles.
TEST_F(BodyContactTests, EnableDisableParticleContactsWithContactFilter)
{
	m_world->SetGravity(b2Vec2_zero);

	// Through two particles horizontally at each other
	// (A moving right, B moving left).
	b2ParticleDef pd;
	pd.flags = b2_particleContactFilterParticle;
	pd.position.Set(-m_particleDiameter * 2.0f, 0.0f);
	pd.velocity.Set(m_particleDiameter, 0.0f);
	int32 particleIndexA = m_particleSystem->CreateParticle(pd);

	pd.flags = b2_particleContactFilterParticle;
	pd.position.Set(m_particleDiameter * 2.0f, 0.0f);
	pd.velocity.Set(-m_particleDiameter, 0.0f);
	int32 particleIndexB = m_particleSystem->CreateParticle(pd);

	// Leave contacts enabled.
	ParticleContactDisabler contactDisabler;
	m_world->SetContactFilter(&contactDisabler);

	// Run the simulation and verify that particles don't pass each other.
	RunStep(60.0f, 3.0f);
	// WARNING: This assumes particle indicies have not been reallocated during
	// the simulation.
	b2Vec2* positions = m_particleSystem->GetPositionBuffer();
	b2Vec2* velocities = m_particleSystem->GetVelocityBuffer();
	EXPECT_LT(positions[particleIndexA].x, positions[particleIndexB].x);
	EXPECT_LT(b2Abs(velocities[particleIndexA].x), m_particleDiameter);
	EXPECT_LT(b2Abs(velocities[particleIndexB].x), m_particleDiameter);

	// Disable particle / particle contacts.
	contactDisabler.m_enableParticleParticleCollisions = false;

	// Reset the positions and velocities of the particles.
	positions[particleIndexA].Set(-m_particleDiameter * 2.0f, 0.0f);
	velocities[particleIndexA].Set(m_particleDiameter, 0.0f);
	positions[particleIndexB].Set(m_particleDiameter * 2.0f, 0.0f);
	velocities[particleIndexB].Set(-m_particleDiameter, 0.0f);

	// Run the simulation and verify that particles now pass each other (i.e
	// they no longer collide).
	RunStep(60.0f, 3.0f);
	positions = m_particleSystem->GetPositionBuffer();
	velocities = m_particleSystem->GetVelocityBuffer();
	EXPECT_GT(positions[particleIndexA].x, positions[particleIndexB].x);
	EXPECT_FLOAT_EQ(velocities[particleIndexA].x, m_particleDiameter);
	EXPECT_FLOAT_EQ(velocities[particleIndexB].x, -m_particleDiameter);
}
Beispiel #4
0
// Verify that it's possible to detect collisions between
TEST_F(BodyContactTests, ParticleParticleContactFilter)
{
	// Drop particle B on top of particle A.
	b2ParticleDef pd;
	pd.flags = b2_particleContactFilterParticle;
	pd.position.Set(0.0f, m_particleDiameter);
	pd.velocity.Set(0.0f, -m_particleDiameter);
	const int32 particleA = m_particleSystem->CreateParticle(pd);
	pd.position.Set(0.0f, m_particleDiameter * 3.0f);
	pd.velocity.Set(0.0f, m_particleDiameter * -2.0f);
	const int32 particleB = m_particleSystem->CreateParticle(pd);

	ParticleContactTracker tracker(m_particleSystem);
	m_world->SetContactFilter(&tracker);

	RunStep(60.0f, 2.0f);
	EXPECT_EQ(tracker.m_fixtureParticleContacts.size(), 0U);
	EXPECT_GT(tracker.m_particleContacts.size(), 0U);

	for (uint32 i = 0; i < tracker.m_particleContacts.size(); ++i)
	{
		const ParticleContactTracker::ParticleContact contact =
			tracker.m_particleContacts[i];
		EXPECT_TRUE(contact.first == particleA || contact.first == particleB);
		EXPECT_TRUE(contact.first == particleA ? contact.second == particleB :
						contact.second == particleA);
	}
}
Beispiel #5
0
void CNetServerWorker::Run()
{
	// The script runtime uses the profiler and therefore the thread must be registered before the runtime is created
	g_Profiler2.RegisterCurrentThread("Net server");
	
	// To avoid the need for JS_SetContextThread, we create and use and destroy
	// the script interface entirely within this network thread
	m_ScriptInterface = new ScriptInterface("Engine", "Net server", ScriptInterface::CreateRuntime(g_ScriptRuntime));
	m_GameAttributes.set(m_ScriptInterface->GetJSRuntime(), JS::UndefinedValue());

	while (true)
	{
		if (!RunStep())
			break;

		// Implement autostart mode
		if (m_State == SERVER_STATE_PREGAME && (int)m_PlayerAssignments.size() == m_AutostartPlayers)
			StartGame();

		// Update profiler stats
		m_Stats->LatchHostState(m_Host);
	}
	
	// Clear roots before deleting their context
	m_GameAttributes.clear();
	m_SavedCommands.clear();

	SAFE_DELETE(m_ScriptInterface);
}
Beispiel #6
0
// Verify that BeginContact() and EndContact() are called for collisions
// between fixtures and particles.
TEST_F(BodyContactTests, ParticleFixtureContactListener)
{
	// Create a fixture to drop particles on to.
	b2Fixture* const groundFixture = CreateGroundBox();

	// Create a particle above the ground and drop it.
	b2ParticleDef pd;
	pd.flags = b2_fixtureContactListenerParticle;
	pd.position.Set(0.0f, m_particleDiameter * 2.0f);
	pd.velocity.Set(0.0f, -m_particleDiameter);
	const int32 particleIndex = m_particleSystem->CreateParticle(pd);

	// Listen for particle / fixture contacts.
	ParticleContactListener tracker(m_particleSystem);
	m_world->SetContactListener(&tracker);

	// Run the simulation and verify that the particle contacts with the
	// fixture.
	RunStep(60.0f, 3.0f);
	EXPECT_EQ(tracker.m_beginFixtureContacts.size(), 1U);
	EXPECT_EQ(tracker.m_endFixtureContacts.size(), 0U);
	for (uint32 i = 0; i < tracker.m_beginFixtureContacts.size(); ++i)
	{
		const b2ParticleBodyContact contact =
			tracker.m_beginFixtureContacts[i];
		EXPECT_EQ(contact.index, particleIndex);
		EXPECT_EQ(contact.fixture, groundFixture);
	}
	tracker.m_beginFixtureContacts.clear();

	// Throw the particle above the ground fixture and verify it's no longer
	// touching.
	m_particleSystem->GetVelocityBuffer()[particleIndex].y =
		m_particleDiameter * 2.0f;
	RunStep(60.0f, 0.5f);
	EXPECT_EQ(tracker.m_beginFixtureContacts.size(), 0U);
	EXPECT_EQ(tracker.m_endFixtureContacts.size(), 1U);

	for (uint32 i = 0; i < tracker.m_endFixtureContacts.size(); ++i)
	{
		const FixtureParticleContact contact =
			tracker.m_endFixtureContacts[i];
		EXPECT_EQ(contact.first, groundFixture);
		EXPECT_EQ(contact.second, particleIndex);
	}
}
void dgWorld::UpdateAsync (dgFloat32 timestep)
{
	m_concurrentUpdate = true;
	Sync ();
	m_savetimestep = timestep;
	#ifdef DG_USE_THREAD_EMULATION
		dgFloatExceptions exception;
		dgSetPrecisionDouble precision;
		RunStep ();
	#else 
		// execute one update, but do not wait for the update to finish, instead return immediately to the caller
		Tick();
	#endif
}
void dgWorld::Update (dgFloat32 timestep)
{
	m_concurrentUpdate = false;
	m_savetimestep = timestep;
	#ifdef DG_USE_THREAD_EMULATION
		dgFloatExceptions exception;
		dgSetPrecisionDouble precision;
		RunStep ();
	#else 
		// runs the update in a separate thread and wait until the update is completed before it returns.
		// this will run well on single core systems, since the two thread are mutually exclusive 
		Tick();
		SuspendExecution(dgWorld::m_mutex);
	#endif
}
Beispiel #9
0
// Verify that it's possible to detect particle / body collisions using
// a contact filter.
TEST_F(BodyContactTests, FixtureParticleContactFilter)
{
	// Create the ground.
	b2Fixture* const groundFixture = CreateGroundBox();
	{
		// Create a particle above the ground and slightly to the left of the
		// particle with the contact filter enabled.
		b2ParticleDef pd;
		pd.position.Set(2.0f * m_particleDiameter, 2.0f * m_particleDiameter);
		pd.position.Set(0.0f, -m_particleDiameter);
		m_particleSystem->CreateParticle(pd);
	}

	// Create a particle above the ground and drop it.
	int32 contactFilterParticleIndex;
	{
		b2ParticleDef pd;
		pd.flags = b2_fixtureContactFilterParticle;
		pd.position.Set(0.0f, 2.0f * m_particleDiameter);
		pd.position.Set(0.0f, -m_particleDiameter);
		// WARNING: This assumes that this particle index will not change
		// between simulation steps.
		contactFilterParticleIndex = m_particleSystem->CreateParticle(pd);
	}

	// Set the tracker as a contact listener.
	ParticleContactTracker tracker(m_particleSystem);
	m_world->SetContactFilter(&tracker);

	RunStep(60.0f, 1.0f);
	EXPECT_EQ(tracker.m_particleContacts.size(), 0U);
	EXPECT_GT(tracker.m_fixtureParticleContacts.size(), 0U);

	for (uint32 i = 0; i < tracker.m_fixtureParticleContacts.size(); ++i)
	{
		const FixtureParticleContact contact =
			tracker.m_fixtureParticleContacts[i];
		// Verify the contact is with the ground fixture.
		EXPECT_EQ(contact.first, groundFixture);
		// Since there is only one particle, the index will always be zero.
		EXPECT_EQ(contact.second, contactFilterParticleIndex);
	}
}
void dgWorld::TickCallback (dgInt32 threadID)
{
	RunStep ();
}