Beispiel #1
0
bool collideCircleAARectangle(vec2 cp, float cr, vec2 r) {
	// Adapted from http://stackoverflow.com/a/402010
	vec2 circDist = {std::abs(cp.x) - r.x, std::abs(cp.y) - r.y};

	if (circDist.x > cr || circDist.y > cr) {
		return false;
	}

	if (circDist.x <= 0.0f || circDist.y <= 0.0f) {
		return true;
	}

	return length_sqr(circDist) <= cr*cr;
}
Beispiel #2
0
// Returns the nearest point in line segment a-b to point p.
vec2 pointLineSegmentNearestPoint(vec2 p, vec2 a, vec2 b) {
	// Taken from http://stackoverflow.com/a/1501725
	const float l2 = length_sqr(b - a);
	if (l2 == 0.0f) {
		return a;
	}

	const float t = dot(p - a, b - a) / l2;
	if (t < 0.0f) {
		return a;
	} else if (t > 1.0f) {
		return b;
	} else {
		return a + t * (b - a);
	}
}
Beispiel #3
0
void collideBallWithPaddle(Gem& ball, const Paddle& paddle) {
	SpriteMatrix matrix = paddle.getSpriteMatrix();

	// Left sphere
	vec2 left = {-24, 0};
	// Right sphere
	vec2 right = {24, 0};

	matrix.transform(&left.x, &left.y);
	matrix.transform(&right.x, &right.y);

	static const int PADDLE_RADIUS = 8;

	fixed24_8 rel_ball_x = ball.pos_x - paddle.pos_x;
	fixed24_8 rel_ball_y = ball.pos_y - paddle.pos_y;
	vec2 rel_ball = {rel_ball_x.toFloat(), rel_ball_y.toFloat()};

	vec2 nearest_point = pointLineSegmentNearestPoint(rel_ball, left, right);
	vec2 penetration = rel_ball - nearest_point;
	float d_sqr = length_sqr(penetration);
	float r = PADDLE_RADIUS + Gem::RADIUS;
	if (d_sqr < r*r) {
		vec2 vel = {ball.vel_x.toFloat(), ball.vel_y.toFloat()};
		int score_addition = static_cast<int>(ball.score_value * (ball.vel_y.toFloat() / 128.f));
		ball.score_value = std::min(ball.score_value + std::max(score_addition, 0), Gem::MAX_VALUE);

		float d = std::sqrt(d_sqr);
		float sz = r - d;

		vec2 normal = penetration / d;
		fixed24_8 push_back_x(sz * normal.x);
		fixed24_8 push_back_y(sz * normal.y);

		ball.pos_x += push_back_x;
		ball.pos_y += push_back_y;

		vec2 par, perp;
		splitVector(vel, normal, &par, &perp);
		vel = perp - par;

		ball.vel_x = fixed16_16(vel.x);
		ball.vel_y = fixed16_16(vel.y);
	}
}
Beispiel #4
0
float point::length() const
{
	return std::sqrt(length_sqr());
}
Beispiel #5
0
void collideBallWithBall(Gem& a, Gem& b) {
	vec2 dv = {(a.pos_x - b.pos_x).toFloat(), (a.pos_y - b.pos_y).toFloat()};
	float d_sqr = length_sqr(dv);

	if (d_sqr < (2*Gem::RADIUS)*(2*Gem::RADIUS)) {
		fixed16_16 rel_vel_x = a.vel_x - b.vel_x;
		fixed16_16 rel_vel_y = a.vel_y - b.vel_y;
		vec2 rel_vel = {rel_vel_x.toFloat(), rel_vel_y.toFloat()};
		float rel_speed_sqr = length_sqr(rel_vel);
		
		if (rel_speed_sqr >= Gem::MERGE_SPEED*Gem::MERGE_SPEED) {
			fixed32_0 two(2);
			a.pos_x = (a.pos_x + b.pos_x) / two;
			a.pos_y = (a.pos_y + b.pos_y) / two;

			a.vel_x = a.vel_x + b.vel_x;
			a.vel_y = a.vel_y + b.vel_y;

			a.score_value += b.score_value;

			b.pos_x = -9999;
			b.pos_y = 9999;
			b.vel_x = b.vel_y = 0;
			b.score_value = 0;
		} else {
			float d = std::sqrt(d_sqr);
			float sz = Gem::RADIUS - d / 2.0f;

			vec2 normal = dv / d;
			fixed24_8 push_back_x(sz * normal.x);
			fixed24_8 push_back_y(sz * normal.y);

			a.pos_x += push_back_x;
			a.pos_y += push_back_y;
			b.pos_x -= push_back_x;
			b.pos_y -= push_back_y;

			vec2 a_par, a_perp;
			vec2 b_par, b_perp;

			vec2 a_vel = {a.vel_x.toFloat(), a.vel_y.toFloat()};
			vec2 b_vel = {b.vel_x.toFloat(), b.vel_y.toFloat()};
			splitVector(a_vel, normal, &a_par, &a_perp);
			splitVector(b_vel, -normal, &b_par, &b_perp);

			static const float friction = 1.0f;
			static const float bounce = 0.9f;

			float A = (1.0f + bounce) / 2.0f;
			float B = (1.0f - bounce) / 2.0f;

			a_vel = A*b_par + B*a_par + friction*a_perp;
			b_vel = A*a_par + B*b_par + friction*b_perp;

			a.vel_x = fixed16_16(a_vel.x);
			a.vel_y = fixed16_16(a_vel.y);

			b.vel_x = fixed16_16(b_vel.x);
			b.vel_y = fixed16_16(b_vel.y);
		}
	}
}
Beispiel #6
0
	vec3 cosine_weighted_point_on_hemisphere(const float u1, const float u2, const vec3 up) {
		const vec2 p = uniform_point_on_disk(u1, u2);
		return reorient_vector(mvec3(p[0], std::sqrt(1.0f - length_sqr(p)), p[1]), up);
	}
Beispiel #7
0
float distance_sqr(float4 p, float4 q)
{
	return length_sqr(q - p);
}