Skip to content
Snippets Groups Projects
ball.cpp 1.41 KiB
Newer Older
Noé's avatar
Noé committed
#include "ball.hpp"
#include "terrain.hpp"

void ball::initialize()
{

	N = 10;
	pos.resize(N);
	v.resize(N);
	color.resize(N);

	mesh.initialize_data_on_gpu(mesh_primitive_sphere(0.1f));

	for (int i = 0; i < N; i++) {
		color[i] = { rand_interval(0.0f, 1.0f), rand_interval(0.0f, 1.0f), rand_interval(0.0f, 1.0f) };
		pos[i] = { 0,0,40 };
Noé's avatar
Noé committed
		v[i] = { 2 * cos(360 * i / N) ,2 * sin(360 * i / N),10 };
	}
}

void ball::simulate(float dt, float terrain_length) {
	for (int i = 0; i < N; i++) {
		if (pos[i][2] < -1 || cgp::abs(pos[i][0]) > terrain_length / 2 || cgp::abs(pos[i][1]) > terrain_length / 2) {
Noé's avatar
Noé committed
			pos[i] = { 0,0, evaluate_terrain_height(0,0, terrain_length) };
Noé's avatar
Noé committed
			v[i] = { 3 * rand_interval(), 3 * rand_interval(), 4 + i };
		}
		else {
			pos[i] += v[i] * dt;
			v[i][2] -= 10 * dt;
		}

Noé's avatar
Noé committed
		if (pos[i][2] < evaluate_terrain_height(pos[i][0], pos[i][1], terrain_length)) {
			vec3 normal = normalize(terrain_orientation(pos[i][0], pos[i][1], terrain_length));
Noé's avatar
Noé committed

			vec3 temp = v[i] - dot(v[i], normal) * normal;

			v[i] -= 2 * temp;
			v[i] = -v[i];

			float diffusion = 1.1;
			v[i] /= diffusion;
Noé's avatar
Noé committed
vec3 terrain_orientation(float x, float y, float terrain_length) {
	float z = evaluate_terrain_height(x, y, terrain_length);
Noé's avatar
Noé committed
	float step = 0.1f;
Noé's avatar
Noé committed
	vec3 u = { step, 0, evaluate_terrain_height(x + step,y, terrain_length) - z };
	vec3 v = { 0, step, evaluate_terrain_height(x,y + step, terrain_length) - z };
Noé's avatar
Noé committed

	return cross(v, u);
}