Non functional collision
This commit is contained in:
parent
d10ffb17f0
commit
30d70e178e
138
src/app.cpp
138
src/app.cpp
@ -1,6 +1,7 @@
|
||||
#include "app.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include "collision/capsule_triangle_sweep.hpp"
|
||||
|
||||
App::App()
|
||||
{
|
||||
@ -21,27 +22,140 @@ App::App()
|
||||
|
||||
world_.LinkPortals(s1, "NDoor", s2, "WDoor");
|
||||
world_.LinkPortals(s2, "NDoor", s2, "SDoor");
|
||||
|
||||
player_ = world_.Spawn<game::Entity>(s1, glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
}
|
||||
|
||||
void App::Frame()
|
||||
{
|
||||
float aspect = static_cast<float>(m_viewport_size.x) / static_cast<float>(m_viewport_size.y);
|
||||
float delta_time = time_ - prev_time_;
|
||||
prev_time_ = time_;
|
||||
|
||||
renderer_.Begin(m_viewport_size.x, m_viewport_size.y);
|
||||
if (delta_time < 0.0f)
|
||||
{
|
||||
delta_time = 0.0f; // Prevent negative delta time
|
||||
}
|
||||
else if (delta_time > 0.1f)
|
||||
{
|
||||
delta_time = 0.1f; // Cap delta time to avoid large jumps
|
||||
}
|
||||
|
||||
float cameraDistance = 2.0f;
|
||||
float angle = m_time * 0.1f; // Rotate over time
|
||||
float aspect = static_cast<float>(viewport_size_.x) / static_cast<float>(viewport_size_.y);
|
||||
|
||||
renderer_.Begin(viewport_size_.x, viewport_size_.y);
|
||||
|
||||
//float cameraDistance = 2.0f;
|
||||
//float angle = time_ * 0.1f; // Rotate over time
|
||||
//
|
||||
//glm::vec3 cameraPos = glm::vec3(
|
||||
// cameraDistance * cos(angle),
|
||||
// cameraDistance * sin(angle),
|
||||
// cameraDistance * 0.13f
|
||||
//);
|
||||
|
||||
//glm::vec3 center(0.0f, 0.0f, 1.5f);
|
||||
//glm::vec3 up(0.0f, 0.0f, 1.0f);
|
||||
|
||||
//renderer_.DrawWorld(world_, 1, center + cameraPos, -cameraPos, up, aspect, 60.0f);
|
||||
|
||||
static glm::vec3 position(0.0f, 0.0f, 1.5f);
|
||||
|
||||
glm::vec3 velocity(0.0f);
|
||||
if (input_ & game::PI_FORWARD)
|
||||
velocity.y += 1.0f;
|
||||
|
||||
if (input_ & game::PI_BACKWARD)
|
||||
velocity.y -= 1.0f;
|
||||
|
||||
if (input_ & game::PI_LEFT)
|
||||
velocity.x -= 1.0f;
|
||||
|
||||
if (input_ & game::PI_RIGHT)
|
||||
velocity.x += 1.0f;
|
||||
|
||||
if (input_ & game::PI_JUMP)
|
||||
velocity.z += 1.0f;
|
||||
|
||||
if (input_ & game::PI_CROUCH)
|
||||
velocity.z -= 1.0f;
|
||||
|
||||
|
||||
//velocity.z = -1.0f;
|
||||
|
||||
|
||||
glm::vec3 cameraDir = glm::vec3(1.0f, 0.0f, 0.0f);
|
||||
auto tris = world_.GetSector(0).GetMesh()->GetCollisionMesh()->GetTriangles();
|
||||
|
||||
glm::vec3 cameraPos = glm::vec3(
|
||||
cameraDistance * cos(angle),
|
||||
cameraDistance * sin(angle),
|
||||
cameraDistance * 0.13f
|
||||
);
|
||||
glm::vec3 c0 = position;
|
||||
c0.z -= 0.1f;
|
||||
glm::vec3 c1 = position;
|
||||
c1.z += 0.1f;
|
||||
|
||||
glm::vec3 center(0.0f, 0.0f, 1.5f);
|
||||
glm::vec3 up(0.0f, 0.0f, 1.0f);
|
||||
|
||||
renderer_.DrawWorld(world_, 1, center + cameraPos, -cameraPos, up, aspect, 60.0f);
|
||||
bool found = false;
|
||||
|
||||
glm::vec3 u = velocity * delta_time;
|
||||
|
||||
if (glm::length(velocity) > 0.001f)
|
||||
{
|
||||
//velocity = glm::normalize(velocity);
|
||||
|
||||
//collision::ResolveCollisions(
|
||||
// position,
|
||||
// velocity,
|
||||
// 0.5f,
|
||||
// 0.2f,
|
||||
// delta_time,
|
||||
// tris
|
||||
//);
|
||||
|
||||
Sweep sweep;
|
||||
|
||||
static std::vector<collision::Triangle> sweep_tris;
|
||||
sweep_tris.clear();
|
||||
|
||||
for (const auto& tri : tris) {
|
||||
float dot = glm::dot(tri.verts[1] - tri.verts[0], tri.verts[2] - tri.verts[0]);
|
||||
if (glm::abs(dot) < 0.001f) {
|
||||
printf("degen!!!!!!!!!\n");
|
||||
continue; // Skip degenerate triangles
|
||||
}
|
||||
|
||||
//found = found || collision::SweepCapsuleTriangle(
|
||||
// sweep,
|
||||
// c0,
|
||||
// c1,
|
||||
// 0.2f,
|
||||
// u,
|
||||
// tri.verts[0], tri.verts[1], tri.verts[2]
|
||||
//);
|
||||
|
||||
sweep_tris.push_back(tri);
|
||||
}
|
||||
|
||||
collision::ResolveCollisions(
|
||||
position,
|
||||
velocity,
|
||||
0.5f, // Capsule radius
|
||||
0.2f, // Capsule height
|
||||
delta_time,
|
||||
sweep_tris
|
||||
);
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
position += velocity * delta_time;
|
||||
}
|
||||
|
||||
printf("position: %.2f, %.2f, %.2f\n", position.x, position.y, position.z);
|
||||
printf("found: %s\n", found ? "true" : "false");
|
||||
|
||||
renderer_.DrawWorld(world_, 0, position, cameraDir, glm::vec3(0.0f, 0.0f, 1.0f), aspect, 60.0f);
|
||||
}
|
||||
|
||||
void App::MouseMove(const glm::vec2& delta)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
15
src/app.hpp
15
src/app.hpp
@ -3,14 +3,19 @@
|
||||
#include "assets/sectordef.hpp"
|
||||
|
||||
#include "game/world.hpp"
|
||||
#include "game/player_input.hpp"
|
||||
#include "gfx/renderer.hpp"
|
||||
|
||||
class App
|
||||
{
|
||||
float m_time = 0.0f;
|
||||
glm::ivec2 m_viewport_size = { 800, 600 };
|
||||
float time_ = 0.0f;
|
||||
glm::ivec2 viewport_size_ = { 800, 600 };
|
||||
game::PlayerInputFlags input_ = 0;
|
||||
|
||||
float prev_time_ = 0.0f;
|
||||
|
||||
game::World world_;
|
||||
game::Entity* player_ = nullptr;
|
||||
|
||||
gfx::Renderer renderer_;
|
||||
|
||||
@ -19,8 +24,10 @@ public:
|
||||
|
||||
void Frame();
|
||||
|
||||
void SetTime(float time) { m_time = time; }
|
||||
void SetViewportSize(int width, int height) { m_viewport_size = { width, height }; }
|
||||
void SetTime(float time) { time_ = time; }
|
||||
void SetViewportSize(int width, int height) { viewport_size_ = { width, height }; }
|
||||
void SetInput(game::PlayerInputFlags input) { input_ = input; }
|
||||
void MouseMove(const glm::vec2& delta);
|
||||
|
||||
~App();
|
||||
};
|
||||
|
||||
@ -2,14 +2,6 @@
|
||||
|
||||
#define EPSILON 1e-5f // Used to test if float is close to 0. Tweak this if you get problems.
|
||||
|
||||
struct Sweep
|
||||
{
|
||||
float time; // Non-negative time of first contact.
|
||||
float depth; // Non-negative penetration depth if objects start initially colliding.
|
||||
glm::vec3 point; // Point of first-contact. Only updated when contact occurs.
|
||||
glm::vec3 normal; // Unit-length collision normal. Only updated when contact occurs.
|
||||
};
|
||||
|
||||
// Return whether point P is contained inside 3D region delimited by triangle T0,T1,T2 edges.
|
||||
static bool PointInsideTriangle(const glm::vec3& p, const glm::vec3& t0, const glm::vec3& t1, const glm::vec3& t2)
|
||||
{
|
||||
@ -59,8 +51,8 @@ static bool PointInsideTriangularPrism(
|
||||
glm::vec3 faces[5][3] = { { a0,a1,a2 }, { b0,b2,b1 }, { a0,b0,a1 }, { a1,b1,a2 }, { a2,b2,a0 } };
|
||||
float sgn = 0;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
const glm::vec3& p0 = faces[i][0];
|
||||
const glm::vec3& p1 = faces[i][1];
|
||||
const glm::vec3& p0 = faces[i][1];
|
||||
const glm::vec3& p1 = faces[i][0];
|
||||
const glm::vec3& p2 = faces[i][2];
|
||||
|
||||
// Check which side of plane point is in. If it's always on the same side, it's colliding.
|
||||
@ -284,7 +276,7 @@ static bool SweepPointUncappedCylinder(
|
||||
// v capsule velocity
|
||||
// t0,t1,t2 3 triangle vertices
|
||||
// returns whether the capsule and triangle intersect
|
||||
static bool SweepCapsuleTriangle(
|
||||
bool collision::SweepCapsuleTriangle(
|
||||
Sweep& s,
|
||||
const glm::vec3& c0,
|
||||
const glm::vec3& c1,
|
||||
@ -398,7 +390,7 @@ static bool SweepCapsuleTriangle(
|
||||
// r - capsule radius
|
||||
// dt - time-step length
|
||||
// triangles - list of triangles to collide with
|
||||
void ResolveCollisions(glm::vec3& p, glm::vec3& v, float h, float r, float dt, std::span<collision::Triangle> triangles) {
|
||||
void collision::ResolveCollisions(glm::vec3& p, glm::vec3& v, float h, float r, float dt, std::span<const collision::Triangle> triangles) {
|
||||
// Store the leftover movement in this vector.
|
||||
glm::vec3 u = dt * v;
|
||||
|
||||
|
||||
@ -3,7 +3,26 @@
|
||||
#include "capsule.hpp"
|
||||
#include "trianglemesh.hpp"
|
||||
|
||||
struct Sweep
|
||||
{
|
||||
float time = 1.0f; // Non-negative time of first contact.
|
||||
float depth = 0.0f; // Non-negative penetration depth if objects start initially colliding.
|
||||
glm::vec3 point = glm::vec3(0.0f); // Point of first-contact. Only updated when contact occurs.
|
||||
glm::vec3 normal = glm::vec3(0.0f); // Unit-length collision normal. Only updated when contact occurs.
|
||||
};
|
||||
|
||||
namespace collision
|
||||
{
|
||||
|
||||
bool SweepCapsuleTriangle(
|
||||
Sweep& s,
|
||||
const glm::vec3& c0,
|
||||
const glm::vec3& c1,
|
||||
float r,
|
||||
const glm::vec3& v,
|
||||
const glm::vec3& t0,
|
||||
const glm::vec3& t1,
|
||||
const glm::vec3& t2);
|
||||
|
||||
void ResolveCollisions(glm::vec3& p, glm::vec3& v, float h, float r, float dt, std::span<const collision::Triangle> triangles);
|
||||
}
|
||||
6
src/game/entity.cpp
Normal file
6
src/game/entity.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "entity.hpp"
|
||||
|
||||
game::Entity::Entity(World* world, size_t sector_idx, const glm::vec3& position)
|
||||
{
|
||||
|
||||
}
|
||||
@ -1,9 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "sector.hpp"
|
||||
|
||||
namespace game
|
||||
{
|
||||
class World;
|
||||
|
||||
class EntityOccurrence
|
||||
{
|
||||
const Sector* sector_;
|
||||
|
||||
float radius_;
|
||||
glm::vec3 position_;
|
||||
glm::vec3 up_;
|
||||
|
||||
glm::mat3 trans_;
|
||||
glm::mat3 inv_trans_;
|
||||
|
||||
};
|
||||
|
||||
class Entity
|
||||
{
|
||||
World* world_;
|
||||
|
||||
std::unique_ptr<EntityOccurrence> occu_;
|
||||
std::unique_ptr<EntityOccurrence> other_occu_;
|
||||
|
||||
glm::vec3 velocity_;
|
||||
|
||||
public:
|
||||
Entity(World* world, size_t sector_idx, const glm::vec3& position);
|
||||
|
||||
|
||||
};
|
||||
|
||||
18
src/game/player_input.hpp
Normal file
18
src/game/player_input.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
namespace game
|
||||
{
|
||||
enum PlayerInput
|
||||
{
|
||||
PI_FORWARD = 1 << 0,
|
||||
PI_BACKWARD = 1 << 1,
|
||||
PI_LEFT = 1 << 2,
|
||||
PI_RIGHT = 1 << 3,
|
||||
PI_JUMP = 1 << 4,
|
||||
PI_CROUCH = 1 << 5,
|
||||
PI_USE = 1 << 6,
|
||||
PI_ATTACK = 1 << 7,
|
||||
};
|
||||
|
||||
using PlayerInputFlags = unsigned int;
|
||||
}
|
||||
@ -132,7 +132,7 @@ void gfx::Renderer::DrawSector(const DrawSectorParams& params)
|
||||
|
||||
void gfx::Renderer::DrawPortal(const DrawSectorParams& params, const game::Portal& portal)
|
||||
{
|
||||
if (params.recursion > 10)
|
||||
if (params.recursion > max_portal_recursion_)
|
||||
{
|
||||
return; // Recursion limit reached
|
||||
}
|
||||
|
||||
@ -42,6 +42,8 @@ namespace gfx
|
||||
std::shared_ptr<VertexArray> portal_vao_;
|
||||
void SetupPortalVAO();
|
||||
|
||||
size_t max_portal_recursion_ = 24;
|
||||
|
||||
glm::mat4 proj_;
|
||||
|
||||
void DrawSector(const DrawSectorParams& params);
|
||||
|
||||
28
src/main.cpp
28
src/main.cpp
@ -94,7 +94,7 @@ static bool InitGL()
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glDebugMessageCallback(GLDebugCallback, 0);
|
||||
|
||||
SDL_GL_SetSwapInterval(0);
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
#endif
|
||||
|
||||
|
||||
@ -143,6 +143,32 @@ static void Frame()
|
||||
int width, height;
|
||||
SDL_GetWindowSize(s_window, &width, &height);
|
||||
s_app->SetViewportSize(width, height);
|
||||
|
||||
game::PlayerInputFlags input = 0;
|
||||
const uint8_t* state = SDL_GetKeyboardState(nullptr);
|
||||
|
||||
if (state[SDL_GetScancodeFromKey(SDLK_w)])
|
||||
input |= game::PI_FORWARD;
|
||||
|
||||
if (state[SDL_GetScancodeFromKey(SDLK_s)])
|
||||
input |= game::PI_BACKWARD;
|
||||
|
||||
if (state[SDL_GetScancodeFromKey(SDLK_a)])
|
||||
input |= game::PI_LEFT;
|
||||
|
||||
if (state[SDL_GetScancodeFromKey(SDLK_d)])
|
||||
input |= game::PI_RIGHT;
|
||||
|
||||
if (state[SDL_GetScancodeFromKey(SDLK_SPACE)])
|
||||
input |= game::PI_JUMP;
|
||||
|
||||
if (state[SDL_GetScancodeFromKey(SDLK_LCTRL)])
|
||||
input |= game::PI_CROUCH;
|
||||
|
||||
if (state[SDL_GetScancodeFromKey(SDLK_e)])
|
||||
input |= game::PI_USE;
|
||||
|
||||
s_app->SetInput(input);
|
||||
|
||||
s_app->Frame();
|
||||
SDL_GL_SwapWindow(s_window);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user