示例#1
0
文件: Game.cpp 项目: s0n4m/physics-2d
Game::Game() :		m_circleId(0), start(0), bPeriodEnd(false), m_totalObjects(0), m_elasticity(0.2f), m_friction(0.02f),
									m_airjetForce(0.0f), massId(0), mAppliedAirJet(true), mAirjetMagnitude(0.0f), mPause(false)
{

	bRope = false;

	setElasticity(0.8f);
	setFriction(0.02f);
	Primitive::setGame(this);

	// init rope
	int ropePoints = 8;
	m_rope.init(10.0f, ropePoints, Vector(-4,12), Vector(4,12), true, true);
	
	// Initial values for components' frequencies
	m_physicsFreq = 200;
	m_networkFreq = 50;
	m_graphicsFreq = 60;

	
	createLines();
	m_circles.reserve(50);
	m_manifold = new ContactManifold();
}
bool CollisionManager::ball_vs_wall(Ball *object1, Walls *object2)
{
	// set radians
	float radians;
	radians = -(object2->getOrientation()) * (float)RADIANS;

	// calculate the distance between circle and the wall
	math::Vector2D distance;
	distance = object2->getCentrePoints() - object1->getPosition();

	float distanceX = (distance.getX() * cosf(radians)) + (distance.getY() * -sinf(radians));
	float distanceY = (distance.getX() * sinf(radians)) + (distance.getY() * cosf(radians));

	distance.setX(distanceX);
	distance.setY(distanceY);

	// set the clamps
	math::Vector2D clamps = object2->getHalfExtents();

	if (distance.getX() >= 0)
	{
		clamps.setX(std::min(distance.getX(), object2->getHalfExtents().getX()));
	}
	if (distance.getX() < 0)
	{
		clamps.setX(std::max(distance.getX(), -object2->getHalfExtents().getX()));
	}
	if (distance.getY() >= 0)
	{
		clamps.setY(std::min(distance.getY(), object2->getHalfExtents().getY()));
	}
	if (distance.getY() < 0)
	{
		clamps.setY(std::max(distance.getY(), -object2->getHalfExtents().getY()));
	}

	// total distance and magnitude
	distance = distance - clamps;

	float totalDistance;
	totalDistance = distance.magnitude();
	totalDistance = totalDistance - object1->getRadius();

	if (totalDistance < 0)
	{
		float magnitude = distance.magnitude();
		if (magnitude == 0)
		{
			magnitude = 0.01f;
		}

		setDepth(totalDistance);
		setSlop(0.01f);
		setPercentCorrection(0.2f);
		setElasticity(1.f);

		float normalX = ((distance.getX() / magnitude) * cosf(radians)) + ((distance.getY() / magnitude) * sinf(radians));
		float normalY = ((distance.getX() / magnitude) * (-sinf(radians))) + ((distance.getY() / magnitude) * cosf(radians));
		m_normal.setX(normalX);
		m_normal.setY(normalY);

		// impulse resolution
		math::Vector2D relativeVel;
		relativeVel = object1->getVelocity() - object2->getVelocity();

		float relativeVelocity;
		relativeVelocity = relativeVel.dotProduct(m_normal);
		if (relativeVelocity < 0)
		{
			collision = false;
			return false;
		}

		float e = std::min(object1->getElasticity(), object2->getElasticity());
		float j = ((-(1.0f + e) * relativeVelocity) / object1->getInverseMass());
		object1->setVelocity(object1->getVelocity() + (m_normal * (j * object1->getInverseMass())));
		//object2->setVelocity(object2->getVelocity() - ((m_normal * j) * object2->getInverseMass()));


		if (object1->getMass() == 0)
		{
			object1->m_inverseMass = 0;
		}
		else
		{
			object1->getInverseMass();
		}

		// position correction
		math::Vector2D posCorrection;
		posCorrection = m_normal * (std::max((getDepth() - getSlop()), 0.0f) / (object1->getInverseMass() + object2->getInverseMass()) * getPercentCorrection());
		object1->setPosition(object1->getPosition() + posCorrection);

		collision = true;
		return true;
	}
	else
	{
		collision = false;
		return false;
	}
}
bool CollisionManager::ball_vs_bumper(Ball *object1, Bumper *object2)
{
	// distance to circle
	math::Vector2D distance;
	distance = object2->getPosition() - object1->getPosition();

	// length of distance
	float distanceLength;
	distanceLength = distance.magnitude();

	if (distanceLength < (object1->getRadius() + object2->getRadius()))
	{
		float length;
		length = distance.magnitude();
		if (length == 0)
		{
			length = 0.01f;
		}

		// collidable attributes
		setDepth(distanceLength - (object1->getRadius() + object2->getRadius()));
		setSlop(0.03f);
		setPercentCorrection(0.7f);
		setElasticity(1.f);
		m_normal = math::Vector2D((distance.getX() / length), (distance.getY() / length));

		// position correction
		math::Vector2D positionCorrection;
		float temp = (std::max(getDepth() - getSlop(), 0.0f));
		temp = temp / (object1->getInverseMass() + object2->getInverseMass());
		temp = getPercentCorrection() * temp;

		positionCorrection = m_normal * temp;

		object1->setPosition(object1->getPosition() + (positionCorrection * object1->getInverseMass()));
		object2->setPosition(object2->getPosition() + (positionCorrection * object2->getInverseMass()));

		// calculate the relative velocity
		math::Vector2D relativeVel;
		relativeVel = object1->getVelocity() - object2->getVelocity();
		float relativeNorm;
		relativeNorm = relativeVel.dotProduct(m_normal);

		// impulse resolution
		float j;
		j = -(1.0f + getElasticity());
		j = j * relativeNorm;
		j = j / (object1->getInverseMass() + object2->getInverseMass());

		// update impulse velocity
		object1->setVelocity(object1->getVelocity() + ((m_normal * j) * object1->getInverseMass()));
		object2->setVelocity(object2->getVelocity() - ((m_normal * j) * object2->getInverseMass()));

		collision = true;
		return true;
	}
	else
	{
		collision = false;
		return false;
	}
}
示例#4
0
	Collision::Collision(float scale,float elasticity) :
		Modifier(),
		scale(scale)
	{
		setElasticity(elasticity);
	}