Example #1
0
void Physics::IterateCollisions() {
	for( int I = 0; I < Iterations; I++ ) { //Repeat this a few times to give more exact results

		//A small 'hack' that keeps the vertices inside the screen. You could of course implement static objects and create
		//four to serve as screen boundaries, but the max/min method is faster
		for( int T = 0; T < VertexCount; T++ ) {
			Vec2& Pos = Vertices[ T ]->Position;
	
			Pos.X = MAX( MIN( Pos.X, (float)GWidth  ), 0.0f );
			Pos.Y = MAX( MIN( Pos.Y, (float)GHeight ), 0.0f );
		}

		UpdateEdges(); //Edge correction step

		for( int I = 0; I < BodyCount; I++ ) {
			Bodies[ I ]->CalculateCenter(); //Recalculate the center
		}

		for( int B1 = 0; B1 < BodyCount; B1++ ) { //Iterate trough all bodies
			for( int B2 = 0; B2 < BodyCount; B2++ ) {
				if( B1 != B2 )
					if( BodiesOverlap( Bodies[ B1 ], Bodies[ B2 ] ) ) //Test the bounding boxes
						if( DetectCollision( Bodies[ B1 ], Bodies[ B2 ] ) ) //If there is a collision, respond to it
							ProcessCollision();
			}
		}
	}
}
Example #2
0
void CW::PhysicsEngine::Iterate(void)
{
	for(int i = 0; i < m_Iterations; ++i) 
	{
		// Apply edge constraints
		UpdateEdges();

		for (PhysicsBody* b : m_Bodies)
		{
			b->CalculateCenter();
		}

		for (PhysicsBody* b1 : m_Bodies) 
		{ 
			for(PhysicsBody* b2 : m_Bodies) 
			{
				if(b1 != b2)
				{
					if (BoundingBox::CheckIntersection(&(b1->BoundingBox), &(b2->BoundingBox)))
					{
						if (DetectCollision(b1, b2))
						{
							// Process collision info with CollisionInfo data
							ProcessCollision();
						}
					}
				}
			}
		}
	}
}
Example #3
0
//----------------------------------------------------------------------------
void CreateEnvelope::UpdateAllEdges (int numEdges, EdgeMap** edgeMaps)
{
	// Construct the axis-aligned bounding boxes of the edgeMaps.
	RPoint2* rmin = new1<RPoint2>(numEdges);
	RPoint2* rmax = new1<RPoint2>(numEdges);
	int i;
	for (i = 0; i < numEdges; ++i)
	{
		EdgeMap& edgeMap = *edgeMaps[i];

		RPoint2& end0 = edgeMap[ZERO];
		RPoint2& end1 = edgeMap[ONE];

		if (end0.X() <= end1.X())
		{
			rmin[i].X() = end0.X();
			rmax[i].X() = end1.X();
		}
		else
		{
			rmin[i].X() = end1.X();
			rmax[i].X() = end0.X();
		}

		if (end0.Y() <= end1.Y())
		{
			rmin[i].Y() = end0.Y();
			rmax[i].Y() = end1.Y();
		}
		else
		{
			rmin[i].Y() = end1.Y();
			rmax[i].Y() = end0.Y();
		}
	}

	// Store the x-extremes for the AABBs in a data structure to be sorted.
	// The "Type" field indicates whether the x-value is the minimum (Type
	// is 0) or maximum (Type is 1).  The "Index" field stores the edge
	// index for use as a lookup in the overlap tests.
	int numEndpoints = 2*numEdges;
	std::vector<Endpoint> xEndpoints(numEndpoints);
	int j;
	for (i = 0, j = 0; i < numEdges; ++i)
	{
		xEndpoints[j].Type = 0;
		xEndpoints[j].Value = rmin[i].X();
		xEndpoints[j].Index = i;
		++j;

		xEndpoints[j].Type = 1;
		xEndpoints[j].Value = rmax[i].X();
		xEndpoints[j].Index = i;
		++j;
	}

	// Sort the x-values.
	std::sort(xEndpoints.begin(), xEndpoints.end());

	// The active set of rectangles (stored by index in array).
	std::set<int> active;

	// The set of overlapping rectangles (stored by index pairs in array).
	std::set<std::pair<int,int> > overlap;

	// Sweep through the endpoints to determine overlapping x-intervals.
	for (i = 0; i < numEndpoints; ++i)
	{
		Endpoint& end = xEndpoints[i];
		int index = end.Index;
		if (end.Type == 0)  // an interval 'begin' value
		{
			// The current AABB overlaps in the x-direction with all the
			// active intervals.  Now check for y-overlap.
			std::set<int>::iterator iter = active.begin();
			for (/**/; iter != active.end(); ++iter)
			{
				// Rectangles iAIndex and index overlap in the x-dimension.
				// Test for overlap in the y-dimension.
				int activeIndex = *iter;
				if (rmax[activeIndex].Y() >= rmin[activeIndex].Y()
				        &&  rmin[activeIndex].Y() <= rmax[activeIndex].Y())
				{
					// If the edgeMaps share an endpoint, there is no need to
					// test later for overlap.
					EdgeMap& edgeMap0 = *edgeMaps[index];
					EdgeMap& edgeMap1 = *edgeMaps[activeIndex];
					RPoint2& E0P0 = edgeMap0[ZERO];
					RPoint2& E0P1 = edgeMap0[ONE];
					RPoint2& E1P0 = edgeMap1[ZERO];
					RPoint2& E1P1 = edgeMap1[ONE];
					if (E0P0 == E1P0 || E0P0 == E1P1
					        ||  E0P1 == E1P0 || E0P1 == E1P1)
					{
						continue;
					}

					overlap.insert(std::make_pair(activeIndex, index));
				}
			}
			active.insert(index);
		}
		else  // an interval 'end' value
		{
			active.erase(index);
		}
	}

	// Search for edge-edge intersections by comparing only those edgeMaps whose
	// AABBs overlap.
	std::set<std::pair<int,int> >::const_iterator iter = overlap.begin();
	std::set<std::pair<int,int> >::const_iterator end = overlap.end();
	for (/**/; iter != end; ++iter)
	{
		int i0 = iter->first;
		int i1 = iter->second;
		EdgeMap& edgeMap0 = *edgeMaps[i0];
		EdgeMap& edgeMap1 = *edgeMaps[i1];
		UpdateEdges(edgeMap0, edgeMap1);
	}

	delete1(rmax);
	delete1(rmin);
}