Compare commits
No commits in common. "ba241417a298d5cdd0aaaf097fd33e95cbf48cb9" and "cbcf0da5ce16723d815c2a690c9c986926a3b5cd" have entirely different histories.
ba241417a2
...
cbcf0da5ce
5 changed files with 43 additions and 48 deletions
|
@ -160,3 +160,30 @@ std::optional<Vector3> ray_to_plane(const Ray &ray, const Ray &plane) {
|
||||||
ray.position.y + ray.direction.y * amount,
|
ray.position.y + ray.direction.y * amount,
|
||||||
ray.position.z + ray.direction.z * amount};
|
ray.position.z + ray.direction.z * amount};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<Vector3> ray_collision_triangle(const Ray &ray, const Vector3 &a,
|
||||||
|
const Vector3 &b,
|
||||||
|
const Vector3 &c) {
|
||||||
|
const Vector3 ab = Vector3Subtract(a, b);
|
||||||
|
const Vector3 cb = Vector3Subtract(c, b);
|
||||||
|
Vector3 ortho = Vector3CrossProduct(ab, cb);
|
||||||
|
ortho = Vector3Normalize(ortho);
|
||||||
|
|
||||||
|
Ray plane{.position = b, .direction = ortho};
|
||||||
|
|
||||||
|
auto result = ray_to_plane(ray, plane);
|
||||||
|
if (!result.has_value()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 bary = Vector3Barycenter(result.value(), a, b, c);
|
||||||
|
if (bary.x >= 0.0F && bary.x <= 1.0F && bary.y >= 0.0F && bary.y <= 1.0F &&
|
||||||
|
bary.z >= 0.0F && bary.z <= 1.0F) {
|
||||||
|
float sum = bary.x + bary.y + bary.z;
|
||||||
|
if (sum > 0.999F && sum < 1.001) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,11 @@ extern bool ray_to_xz_plane(const Ray &ray, float &x_out, float &z_out);
|
||||||
/// plane.direction is plane normal, plane.position is position on plane.
|
/// plane.direction is plane normal, plane.position is position on plane.
|
||||||
extern std::optional<Vector3> ray_to_plane(const Ray &ray, const Ray &plane);
|
extern std::optional<Vector3> ray_to_plane(const Ray &ray, const Ray &plane);
|
||||||
|
|
||||||
|
extern std::optional<Vector3> ray_collision_triangle(const Ray &ray,
|
||||||
|
const Vector3 &a,
|
||||||
|
const Vector3 &b,
|
||||||
|
const Vector3 &c);
|
||||||
|
|
||||||
// Unimplemented as this function isn't really needed and it exposes some
|
// Unimplemented as this function isn't really needed and it exposes some
|
||||||
// weirdness regarding column-major matrices.
|
// weirdness regarding column-major matrices.
|
||||||
// extern Vector4 operator*(const Matrix &m, const Vector4 &v);
|
// extern Vector4 operator*(const Matrix &m, const Vector4 &v);
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
// local includes
|
// local includes
|
||||||
#include "screen_trunner.h"
|
#include "screen_trunner.h"
|
||||||
|
|
||||||
// third party includes
|
|
||||||
#include <raymath.h>
|
|
||||||
|
|
||||||
Game::Game()
|
Game::Game()
|
||||||
: screen_stack(ScreenStack::new_instance()),
|
: screen_stack(ScreenStack::new_instance()),
|
||||||
prev_time(std::chrono::steady_clock::now()) {
|
prev_time(std::chrono::steady_clock::now()) {
|
||||||
|
@ -17,7 +14,7 @@ void Game::update() {
|
||||||
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
|
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
next_time - prev_time);
|
next_time - prev_time);
|
||||||
prev_time = next_time;
|
prev_time = next_time;
|
||||||
screen_stack->update(Clamp(((float)duration.count()) / 1000000, 0.0F, 1.0F));
|
screen_stack->update(((float)duration.count()) / 1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::draw() { screen_stack->draw(); }
|
void Game::draw() { screen_stack->draw(); }
|
||||||
|
|
|
@ -159,38 +159,6 @@ TRunnerScreen::TRunnerScreen(std::weak_ptr<ScreenStack> stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
surface.at(idx) = current;
|
surface.at(idx) = current;
|
||||||
|
|
||||||
// Calculate bounding boxes.
|
|
||||||
int x = idx % SURFACE_UNIT_WIDTH;
|
|
||||||
int y = idx / SURFACE_UNIT_WIDTH;
|
|
||||||
float xf = (float)(x)-SURFACE_X_OFFSET;
|
|
||||||
float zf = (float)(y)-SURFACE_Y_OFFSET;
|
|
||||||
surface_bbs.at(idx).min.x = xf - 0.5F;
|
|
||||||
surface_bbs.at(idx).min.z = zf - 0.5F;
|
|
||||||
surface_bbs.at(idx).max.x = xf + 0.5F;
|
|
||||||
surface_bbs.at(idx).max.z = zf + 0.5F;
|
|
||||||
|
|
||||||
surface_bbs.at(idx).min.y = current.nw;
|
|
||||||
if (current.ne < surface_bbs.at(idx).min.y) {
|
|
||||||
surface_bbs.at(idx).min.y = current.ne;
|
|
||||||
}
|
|
||||||
if (current.sw < surface_bbs.at(idx).min.y) {
|
|
||||||
surface_bbs.at(idx).min.y = current.sw;
|
|
||||||
}
|
|
||||||
if (current.se < surface_bbs.at(idx).min.y) {
|
|
||||||
surface_bbs.at(idx).min.y = current.se;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface_bbs.at(idx).max.y = current.nw;
|
|
||||||
if (current.ne > surface_bbs.at(idx).max.y) {
|
|
||||||
surface_bbs.at(idx).max.y = current.ne;
|
|
||||||
}
|
|
||||||
if (current.sw > surface_bbs.at(idx).max.y) {
|
|
||||||
surface_bbs.at(idx).max.y = current.sw;
|
|
||||||
}
|
|
||||||
if (current.se > surface_bbs.at(idx).max.y) {
|
|
||||||
surface_bbs.at(idx).max.y = current.se;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -239,7 +207,7 @@ bool TRunnerScreen::update(float dt) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::cout << "idx_hit set to " << idx_hit << std::endl;
|
std::cout << "idx_hit set to " << idx_hit << std::endl;
|
||||||
#endif
|
#endif
|
||||||
this->mouse_hit = collision;
|
this->mouse_hit = collision.value();
|
||||||
|
|
||||||
this->camera_target.x = xf;
|
this->camera_target.x = xf;
|
||||||
this->camera_target.y =
|
this->camera_target.y =
|
||||||
|
@ -258,15 +226,14 @@ bool TRunnerScreen::update(float dt) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (auto bb_collision = GetRayCollisionBox(ray, surface_bbs[idx]);
|
if (auto collision = ray_collision_triangle(ray, nw, sw, ne);
|
||||||
bb_collision.hit) {
|
collision.has_value()) {
|
||||||
if (auto collision = GetRayCollisionTriangle(ray, nw, sw, ne);
|
on_collide_fn(collision);
|
||||||
collision.hit) {
|
break;
|
||||||
on_collide_fn(collision.point);
|
} else if (auto collision = ray_collision_triangle(ray, ne, sw, se);
|
||||||
} else if (auto collision = GetRayCollisionTriangle(ray, ne, sw, se);
|
collision.has_value()) {
|
||||||
collision.hit) {
|
on_collide_fn(collision);
|
||||||
on_collide_fn(collision.point);
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,7 +260,7 @@ bool TRunnerScreen::draw() {
|
||||||
? RAYWHITE
|
? RAYWHITE
|
||||||
: Color{(unsigned char)(200 + ox * 2),
|
: Color{(unsigned char)(200 + ox * 2),
|
||||||
(unsigned char)(150 + oy * 2), 20, 255};
|
(unsigned char)(150 + oy * 2), 20, 255};
|
||||||
const auto ¤t = surface[idx].value();
|
auto ¤t = surface[idx].value();
|
||||||
DrawTriangle3D(Vector3{xf - 0.5F, current.nw, zf - 0.5F},
|
DrawTriangle3D(Vector3{xf - 0.5F, current.nw, zf - 0.5F},
|
||||||
Vector3{xf - 0.5F, current.sw, zf + 0.5F},
|
Vector3{xf - 0.5F, current.sw, zf + 0.5F},
|
||||||
Vector3{xf + 0.5F, current.ne, zf - 0.5F}, color);
|
Vector3{xf + 0.5F, current.ne, zf - 0.5F}, color);
|
||||||
|
|
|
@ -56,7 +56,6 @@ class TRunnerScreen : public Screen {
|
||||||
std::array<std::optional<SurfaceUnit>,
|
std::array<std::optional<SurfaceUnit>,
|
||||||
SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT>
|
SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT>
|
||||||
surface;
|
surface;
|
||||||
std::array<BoundingBox, SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT> surface_bbs;
|
|
||||||
Camera3D camera;
|
Camera3D camera;
|
||||||
std::bitset<64> flags;
|
std::bitset<64> flags;
|
||||||
Model TEMP_cube_model;
|
Model TEMP_cube_model;
|
||||||
|
|
Loading…
Reference in a new issue