sdl_runtime_compiler git · main
SDL3 game for running and compiling code at runtime
C++ 72.3% C 26.2%git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gzsrc/systems/aim.hpp raw
#pragma once
#include <SDL3/SDL.h>
#include "entities/camera.hpp"
#include "entities/game_object.hpp"
#include "systems/collision.hpp"
#include "text/handler.hpp"
#include "text/token.hpp"
#include "utils/globals.hpp"
#include "wall/wall.hpp"
namespace
Nimbin
{
namespace Aim
{
struct Result
{
Vec3 point {};
Vec3 local {};
Text::Token::Data* track { nullptr };
};
inline Result
crosshair_Target(const Camera& camera,
const DynArray<Text::TokenPtr>& words,
const DynArray<GameObjectPtr>& scenery,
const DynArray<Text::Handler*>& walls,
float world_scale)
{
const Vec3 eye = camera.pos;
const Vec3 dir = camera.fwd;
const double ws = static_cast<double>(world_scale);
double wall_t = 1e18;
auto plane = [&](double o, double d) {
if (SDL_fabs(d) < 1e-9) return;
const double t = SDL_max((ws - o) / d, (-ws - o) / d);
if (t > 0.0 && t < wall_t) wall_t = t;
};
plane(eye.x, dir.x);
plane(eye.y, dir.y);
plane(eye.z, dir.z);
if (wall_t > 1e17) wall_t = ws * 2.0;
const Vec3 seg { dir.x * wall_t, dir.y * wall_t, dir.z * wall_t };
Result out;
out.point = Vec3{ eye.x + seg.x, eye.y + seg.y, eye.z + seg.z };
double best_t = 1.0;
Text::Token::Data* win = nullptr;
auto test = [&](const Vec3& mn, const Vec3& mx, Text::Token::Data* obj) {
Collision::SweptResult sw = Collision::swept_RayAabb(eye, seg, mn, mx);
if (sw.hit && sw.t < best_t) {
best_t = sw.t;
out.point = { eye.x + seg.x * sw.t,
eye.y + seg.y * sw.t,
eye.z + seg.z * sw.t };
win = obj;
}
};
for (const Text::TokenPtr& w : words)
if (w) test(w->aabb_Min(), w->aabb_Max(), w.get());
for (const GameObjectPtr& s : scenery)
if (s) test(s->aabb_Min(), s->aabb_Max(), nullptr);
for (const Text::Handler* h : walls)
if (h)
for (const Text::Line& line : h->get_Lines())
for (const Text::TokenPtr& tp : line.tokens)
if (tp) test(tp->aabb_Min(), tp->aabb_Max(), nullptr);
if (win) {
out.track = win;
const double dx = out.point.x - win->pos.x;
const double dy = out.point.y - win->pos.y;
const double dz = out.point.z - win->pos.z;
const double cy = SDL_cos(win->yaw);
const double sy = SDL_sin(win->yaw);
out.local = { cy * dx - sy * dz,
dy,
sy * dx + cy * dz };
}
return out;
}
} // namespace Aim
} // namespace Nimbin