generated from rpuzonas/raylib-cpp-template
split main.cpp
This commit is contained in:
parent
68920c625f
commit
c8cf27fb98
47
src/boid-playground.hpp
Normal file
47
src/boid-playground.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
#include <raylib-cpp.hpp>
|
||||
|
||||
#define ARRAY_LEN(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
#define LogTrace(...) TraceLog(LOG_TRACE, __VA_ARGS__)
|
||||
#define ASSERT(...) assert(__VA_ARGS__)
|
||||
|
||||
struct Boid {
|
||||
Vector2 pos;
|
||||
Vector2 dir;
|
||||
};
|
||||
|
||||
struct Obstacle {
|
||||
Vector2 center;
|
||||
std::vector<Vector2> points;
|
||||
};
|
||||
|
||||
struct RayHitResult {
|
||||
float hit = -1;
|
||||
|
||||
// TODO: `line1` and `line2` are not used, maybe remove them?
|
||||
Vector2 line1;
|
||||
Vector2 line2;
|
||||
};
|
||||
|
||||
struct World {
|
||||
std::vector<Boid> boids;
|
||||
std::vector<Obstacle> obstacles;
|
||||
|
||||
float boid_view_radius = 100;
|
||||
float boid_view_angle = PI*2;
|
||||
float boid_speed = 80;
|
||||
float boid_turn_speed = PI*2;
|
||||
|
||||
float avoidance_distance = 75;
|
||||
float avoidance_ray_angle = PI/1.5;
|
||||
int avoidance_ray_count = 4;
|
||||
|
||||
Vector2 size;
|
||||
};
|
||||
|
||||
struct Visuals {
|
||||
float boid_edge_size = 20;
|
||||
};
|
128
src/main.cpp
128
src/main.cpp
@ -2,51 +2,10 @@
|
||||
#include "raymath.h"
|
||||
#include "rlgl.h"
|
||||
#include <cmath>
|
||||
#include <assert.h>
|
||||
#include <optional>
|
||||
#include <raylib-cpp.hpp>
|
||||
|
||||
#define ARRAY_LEN(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
#define LogTrace(...) TraceLog(LOG_TRACE, __VA_ARGS__)
|
||||
#define ASSERT(...) assert(__VA_ARGS__)
|
||||
|
||||
struct Boid {
|
||||
Vector2 pos;
|
||||
Vector2 dir;
|
||||
};
|
||||
|
||||
struct Obstacle {
|
||||
Vector2 center;
|
||||
std::vector<Vector2> points;
|
||||
};
|
||||
|
||||
struct RayHitResult {
|
||||
float hit = -1;
|
||||
|
||||
// TODO: `line1` and `line2` are not used, maybe remove them?
|
||||
Vector2 line1;
|
||||
Vector2 line2;
|
||||
};
|
||||
|
||||
struct World {
|
||||
std::vector<Boid> boids;
|
||||
std::vector<Obstacle> obstacles;
|
||||
|
||||
float boid_view_radius = 100;
|
||||
float boid_view_angle = PI*2;
|
||||
float boid_speed = 80;
|
||||
float boid_turn_speed = PI*2;
|
||||
|
||||
float avoidance_distance = 75;
|
||||
float avoidance_ray_angle = PI/1.5;
|
||||
int avoidance_ray_count = 4;
|
||||
|
||||
Vector2 size;
|
||||
};
|
||||
|
||||
struct Visuals {
|
||||
float boid_edge_size = 20;
|
||||
};
|
||||
#include "boid-playground.hpp"
|
||||
#include "raycast.cpp"
|
||||
|
||||
static void boid_rand_init(Boid *boid, int min_x, int max_x, int min_y, int max_y)
|
||||
{
|
||||
@ -92,82 +51,6 @@ static void draw_obstacle(Obstacle *obstacle, Color color)
|
||||
rlEnd();
|
||||
}
|
||||
|
||||
static float get_intersect_point(Vector2 ray_origin, Vector2 ray_dir, Vector2 line1, Vector2 line2) {
|
||||
Vector2 line_dir = Vector2Subtract(line2, line1);
|
||||
float D = ray_dir.x * line_dir.y - ray_dir.y * line_dir.x;
|
||||
float u = ((line1.x - ray_origin.x) * ray_dir.y - (line1.y - ray_origin.y) * ray_dir.x) / D;
|
||||
float t = ((line1.x - ray_origin.x) * line_dir.y - (line1.y - ray_origin.y) * line_dir.x) / D;
|
||||
if (0 <= u && u <= 1 && t >= 0) {
|
||||
return t;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_nearest_hit(RayHitResult *nearest_hit, float hit, Vector2 line1, Vector2 line2) {
|
||||
bool got_hit = hit >= 0;
|
||||
bool is_gotten_hit_better = (nearest_hit->hit < 0 || nearest_hit->hit > hit);
|
||||
if (got_hit && is_gotten_hit_better) {
|
||||
nearest_hit->hit = hit;
|
||||
nearest_hit->line1 = line1;
|
||||
nearest_hit->line2 = line2;
|
||||
}
|
||||
}
|
||||
|
||||
static void get_intersect_with_polygon(RayHitResult *result, Vector2 ray_origin, Vector2 ray_dir, Vector2 *points, int point_count) {
|
||||
if (point_count < 2) return;
|
||||
|
||||
for (int i = 0; i < point_count-1; i++) {
|
||||
Vector2 p1 = points[i];
|
||||
Vector2 p2 = points[i+1];
|
||||
float hit = get_intersect_point(ray_origin, ray_dir, p1, p2);
|
||||
set_nearest_hit(result, hit, p1, p2);
|
||||
}
|
||||
|
||||
if (point_count > 2) {
|
||||
Vector2 p1 = points[0];
|
||||
Vector2 p2 = points[point_count-1];
|
||||
float hit = get_intersect_point(ray_origin, ray_dir, p1, p2);
|
||||
set_nearest_hit(result, hit, p1, p2);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_intersect_with_obstacles(RayHitResult *result, Vector2 ray_origin, Vector2 ray_dir, std::vector<Obstacle> *obstacles) {
|
||||
for (int i = 0; i < (*obstacles).size(); i++) {
|
||||
Obstacle *obstacle = &(*obstacles)[i];
|
||||
get_intersect_with_polygon(result, ray_origin, ray_dir, obstacle->points.data(), obstacle->points.size());
|
||||
}
|
||||
}
|
||||
|
||||
static void get_intersect_with_world(RayHitResult *result, Vector2 ray_origin, Vector2 ray_dir, World *world) {
|
||||
get_intersect_with_obstacles(result, ray_origin, ray_dir, &world->obstacles);
|
||||
|
||||
if (result->hit == -1) {
|
||||
Vector2 lines[] = {
|
||||
{ 0 , 0 },
|
||||
{ world->size.x, 0 },
|
||||
{ world->size.x, world->size.y },
|
||||
{ 0 , world->size.y }
|
||||
};
|
||||
|
||||
get_intersect_with_polygon(result, ray_origin, ray_dir, lines, 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_avoidance_ray_angles(float *rays, int ray_count, float ray_angle) {
|
||||
ASSERT(ray_count >= 1 && "Ray count must be at least 1");
|
||||
ASSERT(((ray_count - 1) % 2 == 0) && "Ray count must be a multiple of 2n+1");
|
||||
|
||||
rays[0] = 0;
|
||||
|
||||
int side_ray_count = ((ray_count-1)/2);
|
||||
float ray_angle_step = ray_angle / side_ray_count;
|
||||
for (int i = 0; i < side_ray_count; i++) {
|
||||
rays[2*i+0 + 1] = ray_angle_step * (i+1);
|
||||
rays[2*i+1 + 1] = -ray_angle_step * (i+1);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_debug_boid_obstacle_avoidance(Visuals *visuals, World *world, Boid *boid) {
|
||||
Vector2 pos = boid->pos;
|
||||
|
||||
@ -271,8 +154,7 @@ static int get_boids_in_view_cone(Boid **boids_in_view, Boid *boid, float view_r
|
||||
|
||||
Vector2 dir_to_boid = Vector2Normalize(Vector2Subtract(boids[i].pos, boid->pos));
|
||||
float dot = Vector2DotProduct(boid->dir, dir_to_boid);
|
||||
// TODO: if (dot >= dot_threshold && Vector2Distance(boids[i].pos, boid->pos) <= view_radius) {
|
||||
if (Vector2Distance(boids[i].pos, boid->pos) <= view_radius) {
|
||||
if (dot >= dot_threshold && Vector2Distance(boids[i].pos, boid->pos) <= view_radius) {
|
||||
boids_in_view[count] = &boids[i];
|
||||
count++;
|
||||
}
|
||||
@ -311,14 +193,12 @@ int main() {
|
||||
// world.boids.push_back({ .pos = { 200, 180 }, .dir = { 0, -1 }});
|
||||
|
||||
// Main game loop
|
||||
while (!window.ShouldClose())
|
||||
{
|
||||
while (!window.ShouldClose()) {
|
||||
// TODO: Show this on screen
|
||||
// LogTrace("%d", count_out_of_bounds_boids(&world));
|
||||
|
||||
float dt = GetFrameTime();
|
||||
for (int i = 0; i < world.boids.size(); i++) {
|
||||
LogTrace("i:%d", i);
|
||||
Boid *boid = &world.boids[i];
|
||||
|
||||
Vector2 step = Vector2Multiply(boid->dir, { world.boid_speed * dt, world.boid_speed * dt });
|
||||
|
77
src/raycast.cpp
Normal file
77
src/raycast.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
#include "boid-playground.hpp"
|
||||
|
||||
static float get_intersect_point(Vector2 ray_origin, Vector2 ray_dir, Vector2 line1, Vector2 line2) {
|
||||
Vector2 line_dir = Vector2Subtract(line2, line1);
|
||||
float D = ray_dir.x * line_dir.y - ray_dir.y * line_dir.x;
|
||||
float u = ((line1.x - ray_origin.x) * ray_dir.y - (line1.y - ray_origin.y) * ray_dir.x) / D;
|
||||
float t = ((line1.x - ray_origin.x) * line_dir.y - (line1.y - ray_origin.y) * line_dir.x) / D;
|
||||
if (0 <= u && u <= 1 && t >= 0) {
|
||||
return t;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_nearest_hit(RayHitResult *nearest_hit, float hit, Vector2 line1, Vector2 line2) {
|
||||
bool got_hit = hit >= 0;
|
||||
bool is_gotten_hit_better = (nearest_hit->hit < 0 || nearest_hit->hit > hit);
|
||||
if (got_hit && is_gotten_hit_better) {
|
||||
nearest_hit->hit = hit;
|
||||
nearest_hit->line1 = line1;
|
||||
nearest_hit->line2 = line2;
|
||||
}
|
||||
}
|
||||
|
||||
static void get_intersect_with_polygon(RayHitResult *result, Vector2 ray_origin, Vector2 ray_dir, Vector2 *points, int point_count) {
|
||||
if (point_count < 2) return;
|
||||
|
||||
for (int i = 0; i < point_count-1; i++) {
|
||||
Vector2 p1 = points[i];
|
||||
Vector2 p2 = points[i+1];
|
||||
float hit = get_intersect_point(ray_origin, ray_dir, p1, p2);
|
||||
set_nearest_hit(result, hit, p1, p2);
|
||||
}
|
||||
|
||||
if (point_count > 2) {
|
||||
Vector2 p1 = points[0];
|
||||
Vector2 p2 = points[point_count-1];
|
||||
float hit = get_intersect_point(ray_origin, ray_dir, p1, p2);
|
||||
set_nearest_hit(result, hit, p1, p2);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_intersect_with_obstacles(RayHitResult *result, Vector2 ray_origin, Vector2 ray_dir, std::vector<Obstacle> *obstacles) {
|
||||
for (int i = 0; i < (*obstacles).size(); i++) {
|
||||
Obstacle *obstacle = &(*obstacles)[i];
|
||||
get_intersect_with_polygon(result, ray_origin, ray_dir, obstacle->points.data(), obstacle->points.size());
|
||||
}
|
||||
}
|
||||
|
||||
static void get_intersect_with_world(RayHitResult *result, Vector2 ray_origin, Vector2 ray_dir, World *world) {
|
||||
get_intersect_with_obstacles(result, ray_origin, ray_dir, &world->obstacles);
|
||||
|
||||
if (result->hit == -1) {
|
||||
Vector2 lines[] = {
|
||||
{ 0 , 0 },
|
||||
{ world->size.x, 0 },
|
||||
{ world->size.x, world->size.y },
|
||||
{ 0 , world->size.y }
|
||||
};
|
||||
|
||||
get_intersect_with_polygon(result, ray_origin, ray_dir, lines, 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_avoidance_ray_angles(float *rays, int ray_count, float ray_angle) {
|
||||
ASSERT(ray_count >= 1 && "Ray count must be at least 1");
|
||||
ASSERT(((ray_count - 1) % 2 == 0) && "Ray count must be a multiple of 2n+1");
|
||||
|
||||
rays[0] = 0;
|
||||
|
||||
int side_ray_count = ((ray_count-1)/2);
|
||||
float ray_angle_step = ray_angle / side_ray_count;
|
||||
for (int i = 0; i < side_ray_count; i++) {
|
||||
rays[2*i+0 + 1] = ray_angle_step * (i+1);
|
||||
rays[2*i+1 + 1] = -ray_angle_step * (i+1);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user