Compare commits
No commits in common. "e08c74e0c1a31aa22f8f1f62116d2f478abff71b" and "f6bd91824b46c37ef44827b88d683a1098921a98" have entirely different histories.
e08c74e0c1
...
f6bd91824b
6
Makefile
6
Makefile
@ -2,7 +2,7 @@
|
||||
CC=$(PREFIX)gcc
|
||||
CXX=$(PREFIX)g++
|
||||
|
||||
OPT = -O2 -march=x86-64-v3
|
||||
OPT = -O0 -march=x86-64-v3
|
||||
|
||||
CSTD = -std=gnu23
|
||||
CXXSTD = -std=gnu++23
|
||||
@ -12,7 +12,6 @@ CFLAGS += -I./include
|
||||
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -Wno-error=unused-but-set-variable
|
||||
CFLAGS += -Wno-error=unknown-pragmas -Wno-unknown-pragmas
|
||||
CFLAGS += $(shell pkg-config --cflags glfw3)
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
|
||||
LDFLAGS += -lm
|
||||
LDFLAGS += $(shell pkg-config --libs glfw3)
|
||||
@ -31,8 +30,7 @@ OBJS = \
|
||||
src/view.o \
|
||||
src/minecraft.o \
|
||||
src/hud.o \
|
||||
src/lighting.o \
|
||||
src/collision_scene.o
|
||||
src/lighting.o
|
||||
|
||||
all: test.so
|
||||
|
||||
|
||||
@ -1,253 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "directxmath/directxmath.h"
|
||||
|
||||
namespace collision {
|
||||
|
||||
struct AABB {
|
||||
XMVECTOR min;
|
||||
XMVECTOR max;
|
||||
};
|
||||
|
||||
struct Sphere {
|
||||
XMVECTOR center;
|
||||
float radius;
|
||||
};
|
||||
|
||||
struct Capsule {
|
||||
XMVECTOR a;
|
||||
XMVECTOR b;
|
||||
float radius;
|
||||
};
|
||||
|
||||
static inline AABB cube_aabb(XMVECTOR const & center, float half)
|
||||
{
|
||||
half = fabsf(half);
|
||||
XMVECTOR min = center + XMVectorReplicate(-half);
|
||||
XMVECTOR max = center + XMVectorReplicate( half);
|
||||
return AABB(min, max);
|
||||
}
|
||||
|
||||
static inline XMVECTOR closest_point_point_aabb(XMVECTOR const & p, AABB const & aabb)
|
||||
{
|
||||
return XMVectorClamp(p, aabb.min, aabb.max);
|
||||
}
|
||||
|
||||
static inline bool test_sphere_aabb(Sphere const & sphere, AABB const & aabb, XMVECTOR & point)
|
||||
{
|
||||
point = closest_point_point_aabb(sphere.center, aabb);
|
||||
|
||||
XMVECTOR v = point - sphere.center;
|
||||
return XMVectorGetX(XMVector3Dot(v, v)) <= sphere.radius * sphere.radius;
|
||||
}
|
||||
|
||||
static inline void vector_swap_control(XMVECTOR & a, XMVECTOR & b, XMVECTOR const & control)
|
||||
{
|
||||
XMVECTOR tmp = XMVectorSelect(a, b, control);
|
||||
b = XMVectorSelect(b, a, control);
|
||||
a = tmp;
|
||||
}
|
||||
|
||||
static inline bool intersect_ray_aabb(XMVECTOR const & point, XMVECTOR const & direction, AABB const & aabb, float & t_result, XMVECTOR & v_result)
|
||||
{
|
||||
// check parallel
|
||||
XMVECTOR parallel = XMVectorLess(XMVectorAbs(direction), XMVectorSplatEpsilon());
|
||||
XMVECTOR point_lt_aabb = XMVectorLess(point, aabb.min);
|
||||
XMVECTOR point_gt_aabb = XMVectorGreater(point, aabb.max);
|
||||
if (XMVectorGetX(parallel) != 0) // if (x < epsilon)
|
||||
if (XMVectorGetX(point_lt_aabb) != 0 || XMVectorGetX(point_gt_aabb) != 0)
|
||||
return false; // direction x is parallel and point x outside aabb
|
||||
if (XMVectorGetY(parallel) != 0) // if (y < epsilon)
|
||||
if (XMVectorGetY(point_lt_aabb) != 0 || XMVectorGetY(point_gt_aabb) != 0)
|
||||
return false; // direction y is parallel and point y outside aabb
|
||||
if (XMVectorGetZ(parallel) != 0) // if (z < epsilon)
|
||||
if (XMVectorGetZ(point_lt_aabb) != 0 || XMVectorGetZ(point_gt_aabb) != 0)
|
||||
return false; // direction z is parallel and point z outside aabb
|
||||
|
||||
XMVECTOR direction_reciprocal = XMVectorReciprocalEst(direction);
|
||||
XMVECTOR t1 = (aabb.min - point) * direction_reciprocal;
|
||||
XMVECTOR t2 = (aabb.max - point) * direction_reciprocal;
|
||||
vector_swap_control(t2, t1, XMVectorGreater(t1, t2));
|
||||
|
||||
float tmin = XMVectorGetX(t1);
|
||||
if (XMVectorGetY(t1) > tmin) tmin = XMVectorGetY(t1);
|
||||
if (XMVectorGetZ(t1) > tmin) tmin = XMVectorGetZ(t1);
|
||||
float tmax = XMVectorGetX(t2);
|
||||
if (XMVectorGetY(t2) < tmax) tmax = XMVectorGetY(t2);
|
||||
if (XMVectorGetZ(t2) < tmax) tmax = XMVectorGetZ(t2);
|
||||
if (tmin > tmax) return false; // no intersection
|
||||
|
||||
t_result = tmin;
|
||||
v_result = point + direction * tmin;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline float clamp(float f, float min, float max)
|
||||
{
|
||||
if (f < min) return min;
|
||||
if (f > max) return max;
|
||||
return f;
|
||||
}
|
||||
|
||||
static inline void closest_point_segment_segment(XMVECTOR const & a1, XMVECTOR const & b1, // segment 1
|
||||
XMVECTOR const & a2, XMVECTOR const & b2, // segment 2
|
||||
float & t1, // (s)
|
||||
float & t2, // (t)
|
||||
XMVECTOR & c1, // closest point to segment 1
|
||||
XMVECTOR & c2) // closest point to segment 2
|
||||
{
|
||||
const float epsilon = 1.192092896e-7f;
|
||||
|
||||
XMVECTOR d1 = b1 - a1;
|
||||
XMVECTOR d2 = b2 - a2;
|
||||
XMVECTOR r = a1 - a2;
|
||||
float l1 = XMVectorGetX(XMVector3Dot(d1, d1)); // squared length of segment 1 (a)
|
||||
float l2 = XMVectorGetX(XMVector3Dot(d2, d2)); // squared length of segment 2 (e)
|
||||
float d1r = XMVectorGetX(XMVector3Dot(d1, r)); // (c)
|
||||
float d2r = XMVectorGetX(XMVector3Dot(d2, r)); // (f)
|
||||
|
||||
if (l1 <= epsilon && l2 <= epsilon) {
|
||||
// both segments are points
|
||||
t1 = 0.0f;
|
||||
t2 = 0.0f;
|
||||
c1 = a1;
|
||||
c2 = a2;
|
||||
return;
|
||||
}
|
||||
if (l1 <= epsilon) {
|
||||
// segment 1 is a point
|
||||
t1 = 0.0f;
|
||||
t2 = clamp(d2r / l2, 0.0f, 1.0f);
|
||||
} else if (l2 <= epsilon) {
|
||||
// segment 2 is a point
|
||||
t1 = clamp(-d1r / l1, 0.0, 1.0f);
|
||||
t2 = 0.0f;
|
||||
} else {
|
||||
float b = XMVectorGetX(XMVector3Dot(d1, d2));
|
||||
float denom = l1 * l2 - b * b;
|
||||
if (denom != 0.0f) {
|
||||
// segments are not parallel
|
||||
t1 = clamp((b * d2r - d1r * l2) / denom, 0.0f, 1.0f);
|
||||
} else {
|
||||
t1 = 0.0f;
|
||||
}
|
||||
t2 = (b * t1 + d2r) / l2;
|
||||
if (t2 < 0.0f) {
|
||||
t2 = 0.0f;
|
||||
t1 = clamp(-d1r / l1, 0.0f, 1.0f);
|
||||
} else if (t2 > 1.0f) {
|
||||
t2 = 1.0f;
|
||||
t1 = clamp((b - d1r) / l1, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
c1 = a1 + d1 * t1;
|
||||
c2 = a2 + d2 * t2;
|
||||
}
|
||||
|
||||
static inline bool intersect_capsule_capsule(Capsule const & capsule1, Capsule const & capsule2,
|
||||
XMVECTOR & p1, XMVECTOR & p2)
|
||||
{
|
||||
float t1;
|
||||
float t2;
|
||||
XMVECTOR c1; // closest point in capsule1
|
||||
XMVECTOR c2; // closest point in capsule2
|
||||
closest_point_segment_segment(capsule1.a, capsule1.b,
|
||||
capsule2.a, capsule2.b,
|
||||
t1, t2,
|
||||
c1, c2);
|
||||
float distance2 = XMVectorGetX(XMVector3Dot(c1 - c2, c1 - c2));
|
||||
float radius = capsule1.radius + capsule2.radius;
|
||||
if (distance2 >= radius * radius)
|
||||
return false;
|
||||
|
||||
float length = XMVectorGetX(XMVector3Length(c1 - c2));
|
||||
XMVECTOR normal = XMVector3NormalizeEst(c2 - c1);
|
||||
printf("length2 %f\n", capsule1.radius - length);
|
||||
p1 = c1 + normal * capsule1.radius;
|
||||
p2 = c2 + normal;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const float interval_epsilon = 0.001f;
|
||||
|
||||
static inline bool intersect_moving_sphere_aabb(Sphere const & sphere, XMVECTOR const & direction,
|
||||
float t0, float t1, AABB const & aabb,
|
||||
float & t, XMVECTOR & point)
|
||||
{
|
||||
float mid = (t0 + t1) * 0.5f;
|
||||
XMVECTOR center = sphere.center + direction * mid;
|
||||
float radius = (mid - t0) * XMVectorGetX(XMVector3Length(direction)) + sphere.radius;
|
||||
Sphere bound(center, radius);
|
||||
if (!test_sphere_aabb(bound, aabb, point))
|
||||
return false;
|
||||
|
||||
if (t1 - t0 < interval_epsilon) {
|
||||
t = t0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (intersect_moving_sphere_aabb(sphere, direction, t0, mid, aabb, t, point))
|
||||
return true;
|
||||
|
||||
return intersect_moving_sphere_aabb(sphere, direction, mid, t1, aabb, t, point);
|
||||
}
|
||||
|
||||
static inline AABB moving_sphere_aabb(Sphere const & sphere, XMVECTOR const & direction)
|
||||
{
|
||||
XMVECTOR min = sphere.center + XMVectorReplicate(-sphere.radius);
|
||||
XMVECTOR max = sphere.center + XMVectorReplicate( sphere.radius);
|
||||
|
||||
min = XMVectorMin(min, min + direction);
|
||||
max = XMVectorMax(max, max + direction);
|
||||
return AABB(min, max);
|
||||
}
|
||||
|
||||
struct state {
|
||||
float t;
|
||||
bool intersected;
|
||||
XMVECTOR intersection_point;
|
||||
XMVECTOR intersection_position;
|
||||
};
|
||||
|
||||
static inline void check_collision(collision::Sphere const & sphere, XMVECTOR const & direction,
|
||||
XMVECTOR const & cube_center, float cube_half,
|
||||
state & state)
|
||||
{
|
||||
collision::AABB aabb = collision::cube_aabb(cube_center, cube_half);
|
||||
float t;
|
||||
XMVECTOR intersection_point;
|
||||
bool intersected = collision::intersect_moving_sphere_aabb(sphere, direction,
|
||||
0, 1, aabb,
|
||||
t, intersection_point);
|
||||
XMVECTOR intersection_position = sphere.center + direction * t;
|
||||
if (intersected && t < state.t) {
|
||||
state.t = t;
|
||||
state.intersected = true;
|
||||
state.intersection_point = intersection_point;
|
||||
state.intersection_position = intersection_position;
|
||||
}
|
||||
}
|
||||
|
||||
static inline XMVECTOR sphere_collision_response(Sphere const & sphere, XMVECTOR const & direction,
|
||||
XMVECTOR const & intersection_point,
|
||||
XMVECTOR const & intersection_position,
|
||||
XMVECTOR & intersection_normal)
|
||||
{
|
||||
XMVECTOR origin = intersection_point;
|
||||
XMVECTOR normal = XMVector3Normalize(intersection_position - intersection_point);
|
||||
XMVECTOR destination = sphere.center + direction;
|
||||
XMVECTOR distance = XMVector3Dot(destination, normal) - XMVector3Dot(normal, origin);
|
||||
XMVECTOR new_destination = (destination - normal * distance) + normal * sphere.radius;
|
||||
XMVECTOR new_direction = new_destination - intersection_position;
|
||||
|
||||
intersection_normal = normal;
|
||||
|
||||
return new_direction;
|
||||
}
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace collision_scene {
|
||||
void load();
|
||||
void draw();
|
||||
void update(int up, int down, int left, int right,
|
||||
int w, int s, int a, int d,
|
||||
int t, int g, int f, int h,
|
||||
int i, int k, int j, int l);
|
||||
}
|
||||
@ -6,10 +6,7 @@ extern "C" {
|
||||
|
||||
void load(const char * source_path);
|
||||
void draw();
|
||||
void update_keyboard(int up, int down, int left, int right,
|
||||
int w, int s, int a, int d,
|
||||
int t, int g, int f, int h,
|
||||
int i, int k, int j, int l);
|
||||
void update_keyboard(int up, int down, int left, int right);
|
||||
void update_mouse(int x, int y);
|
||||
void update_joystick(int joystick_index,
|
||||
float lx, float ly, float rx, float ry, float tl, float tr,
|
||||
|
||||
@ -33,13 +33,11 @@ namespace view {
|
||||
}
|
||||
|
||||
namespace third_person {
|
||||
XMVECTOR apply_transform(float forward, float strafe, float elevation,
|
||||
void apply_transform(float forward, float strafe, float elevation,
|
||||
float delta_yaw, float delta_pitch);
|
||||
}
|
||||
|
||||
void apply_fov(float delta);
|
||||
void update_transforms();
|
||||
void load();
|
||||
|
||||
const float at_distance = 10;
|
||||
}
|
||||
|
||||
22
main.lua
22
main.lua
@ -11,10 +11,7 @@ function init()
|
||||
void load(const char * source_path);
|
||||
void update_window(int width, int height);
|
||||
void draw();
|
||||
void update_keyboard(int up, int down, int left, int right,
|
||||
int w, int s, int a, int d,
|
||||
int t, int g, int f, int h,
|
||||
int i, int k, int j, int l);
|
||||
void update_keyboard(int kbup, int kbdown, int kbleft, int kbright);
|
||||
void update_mouse(int x, int y);
|
||||
void update_joystick(int joystick_index,
|
||||
float lx, float ly, float rx, float ry, float tl, float tr,
|
||||
@ -64,22 +61,7 @@ local update = function(time)
|
||||
local down = love.keyboard.isDown("down")
|
||||
local left = love.keyboard.isDown("left")
|
||||
local right = love.keyboard.isDown("right")
|
||||
local w = love.keyboard.isDown("w")
|
||||
local s = love.keyboard.isDown("s")
|
||||
local a = love.keyboard.isDown("a")
|
||||
local d = love.keyboard.isDown("d")
|
||||
local t = love.keyboard.isDown("t")
|
||||
local g = love.keyboard.isDown("g")
|
||||
local f = love.keyboard.isDown("f")
|
||||
local h = love.keyboard.isDown("h")
|
||||
local i = love.keyboard.isDown("i")
|
||||
local k = love.keyboard.isDown("k")
|
||||
local j = love.keyboard.isDown("j")
|
||||
local l = love.keyboard.isDown("l")
|
||||
test.update_keyboard(up, down, left, right,
|
||||
w, s, a, d,
|
||||
t, g, f, h,
|
||||
i, k, j, l);
|
||||
test.update_keyboard(up, down, left, right);
|
||||
|
||||
test.update(time)
|
||||
end
|
||||
|
||||
@ -1,269 +0,0 @@
|
||||
# Blender 5.0.0
|
||||
# www.blender.org
|
||||
o Icosphere
|
||||
v 0.000000 -1.000000 0.000000
|
||||
v 0.723607 -0.447220 0.525725
|
||||
v -0.276388 -0.447220 0.850649
|
||||
v -0.894426 -0.447216 0.000000
|
||||
v -0.276388 -0.447220 -0.850649
|
||||
v 0.723607 -0.447220 -0.525725
|
||||
v 0.276388 0.447220 0.850649
|
||||
v -0.723607 0.447220 0.525725
|
||||
v -0.723607 0.447220 -0.525725
|
||||
v 0.276388 0.447220 -0.850649
|
||||
v 0.894426 0.447216 0.000000
|
||||
v 0.000000 1.000000 0.000000
|
||||
v -0.162456 -0.850654 0.499995
|
||||
v 0.425323 -0.850654 0.309011
|
||||
v 0.262869 -0.525738 0.809012
|
||||
v 0.850648 -0.525736 0.000000
|
||||
v 0.425323 -0.850654 -0.309011
|
||||
v -0.525730 -0.850652 0.000000
|
||||
v -0.688189 -0.525736 0.499997
|
||||
v -0.162456 -0.850654 -0.499995
|
||||
v -0.688189 -0.525736 -0.499997
|
||||
v 0.262869 -0.525738 -0.809012
|
||||
v 0.951058 0.000000 0.309013
|
||||
v 0.951058 0.000000 -0.309013
|
||||
v 0.000000 0.000000 1.000000
|
||||
v 0.587786 0.000000 0.809017
|
||||
v -0.951058 0.000000 0.309013
|
||||
v -0.587786 0.000000 0.809017
|
||||
v -0.587786 0.000000 -0.809017
|
||||
v -0.951058 0.000000 -0.309013
|
||||
v 0.587786 0.000000 -0.809017
|
||||
v 0.000000 0.000000 -1.000000
|
||||
v 0.688189 0.525736 0.499997
|
||||
v -0.262869 0.525738 0.809012
|
||||
v -0.850648 0.525736 0.000000
|
||||
v -0.262869 0.525738 -0.809012
|
||||
v 0.688189 0.525736 -0.499997
|
||||
v 0.162456 0.850654 0.499995
|
||||
v 0.525730 0.850652 0.000000
|
||||
v -0.425323 0.850654 0.309011
|
||||
v -0.425323 0.850654 -0.309011
|
||||
v 0.162456 0.850654 -0.499995
|
||||
vn 0.1024 -0.9435 0.3151
|
||||
vn 0.7002 -0.6617 0.2680
|
||||
vn -0.2680 -0.9435 0.1947
|
||||
vn -0.2680 -0.9435 -0.1947
|
||||
vn 0.1024 -0.9435 -0.3151
|
||||
vn 0.9050 -0.3304 0.2680
|
||||
vn 0.0247 -0.3304 0.9435
|
||||
vn -0.8897 -0.3304 0.3151
|
||||
vn -0.5746 -0.3304 -0.7488
|
||||
vn 0.5346 -0.3304 -0.7779
|
||||
vn 0.8026 -0.1256 0.5831
|
||||
vn -0.3066 -0.1256 0.9435
|
||||
vn -0.9921 -0.1256 -0.0000
|
||||
vn -0.3066 -0.1256 -0.9435
|
||||
vn 0.8026 -0.1256 -0.5831
|
||||
vn 0.4089 0.6617 0.6284
|
||||
vn -0.4713 0.6617 0.5831
|
||||
vn -0.7002 0.6617 -0.2680
|
||||
vn 0.0385 0.6617 -0.7488
|
||||
vn 0.7240 0.6617 -0.1947
|
||||
vn 0.2680 0.9435 -0.1947
|
||||
vn 0.4911 0.7947 -0.3568
|
||||
vn 0.4089 0.6617 -0.6284
|
||||
vn -0.1024 0.9435 -0.3151
|
||||
vn -0.1876 0.7947 -0.5773
|
||||
vn -0.4713 0.6617 -0.5831
|
||||
vn -0.3313 0.9435 -0.0000
|
||||
vn -0.6071 0.7947 -0.0000
|
||||
vn -0.7002 0.6617 0.2680
|
||||
vn -0.1024 0.9435 0.3151
|
||||
vn -0.1876 0.7947 0.5773
|
||||
vn 0.0385 0.6617 0.7488
|
||||
vn 0.2680 0.9435 0.1947
|
||||
vn 0.4911 0.7947 0.3568
|
||||
vn 0.7240 0.6617 0.1947
|
||||
vn 0.8897 0.3304 -0.3151
|
||||
vn 0.7947 0.1876 -0.5773
|
||||
vn 0.5746 0.3304 -0.7488
|
||||
vn -0.0247 0.3304 -0.9435
|
||||
vn -0.3035 0.1876 -0.9342
|
||||
vn -0.5346 0.3304 -0.7779
|
||||
vn -0.9050 0.3304 -0.2680
|
||||
vn -0.9822 0.1876 -0.0000
|
||||
vn -0.9050 0.3304 0.2680
|
||||
vn -0.5346 0.3304 0.7779
|
||||
vn -0.3035 0.1876 0.9342
|
||||
vn -0.0247 0.3304 0.9435
|
||||
vn 0.5746 0.3304 0.7488
|
||||
vn 0.7947 0.1876 0.5773
|
||||
vn 0.8897 0.3304 0.3151
|
||||
vn 0.3066 0.1256 -0.9435
|
||||
vn 0.3035 -0.1876 -0.9342
|
||||
vn 0.0247 -0.3304 -0.9435
|
||||
vn -0.8026 0.1256 -0.5831
|
||||
vn -0.7947 -0.1876 -0.5773
|
||||
vn -0.8897 -0.3304 -0.3151
|
||||
vn -0.8026 0.1256 0.5831
|
||||
vn -0.7947 -0.1876 0.5773
|
||||
vn -0.5746 -0.3304 0.7488
|
||||
vn 0.3066 0.1256 0.9435
|
||||
vn 0.3035 -0.1876 0.9342
|
||||
vn 0.5346 -0.3304 0.7779
|
||||
vn 0.9921 0.1256 -0.0000
|
||||
vn 0.9822 -0.1876 -0.0000
|
||||
vn 0.9050 -0.3304 -0.2680
|
||||
vn 0.4713 -0.6617 -0.5831
|
||||
vn 0.1876 -0.7947 -0.5773
|
||||
vn -0.0385 -0.6617 -0.7488
|
||||
vn -0.4089 -0.6617 -0.6284
|
||||
vn -0.4911 -0.7947 -0.3568
|
||||
vn -0.7240 -0.6617 -0.1947
|
||||
vn -0.7240 -0.6617 0.1947
|
||||
vn -0.4911 -0.7947 0.3568
|
||||
vn -0.4089 -0.6617 0.6284
|
||||
vn 0.7002 -0.6617 -0.2680
|
||||
vn 0.6071 -0.7947 -0.0000
|
||||
vn 0.3313 -0.9435 -0.0000
|
||||
vn -0.0385 -0.6617 0.7488
|
||||
vn 0.1876 -0.7947 0.5773
|
||||
vn 0.4713 -0.6617 0.5831
|
||||
vt 0.181819 0.000000
|
||||
vt 0.227273 0.078731
|
||||
vt 0.136365 0.078731
|
||||
vt 0.272728 0.157461
|
||||
vt 0.318182 0.078731
|
||||
vt 0.363637 0.157461
|
||||
vt 0.909091 0.000000
|
||||
vt 0.954545 0.078731
|
||||
vt 0.863636 0.078731
|
||||
vt 0.727273 0.000000
|
||||
vt 0.772727 0.078731
|
||||
vt 0.681818 0.078731
|
||||
vt 0.545455 0.000000
|
||||
vt 0.590909 0.078731
|
||||
vt 0.500000 0.078731
|
||||
vt 0.318182 0.236191
|
||||
vt 0.090910 0.157461
|
||||
vt 0.181819 0.157461
|
||||
vt 0.136365 0.236191
|
||||
vt 0.818182 0.157461
|
||||
vt 0.909091 0.157461
|
||||
vt 0.863636 0.236191
|
||||
vt 0.636364 0.157461
|
||||
vt 0.727273 0.157461
|
||||
vt 0.681818 0.236191
|
||||
vt 0.454546 0.157461
|
||||
vt 0.545455 0.157461
|
||||
vt 0.500000 0.236191
|
||||
vt 0.227273 0.236191
|
||||
vt 0.045455 0.236191
|
||||
vt 0.772727 0.236191
|
||||
vt 0.590909 0.236191
|
||||
vt 0.409092 0.236191
|
||||
vt 0.181819 0.314921
|
||||
vt 0.272728 0.314921
|
||||
vt 0.227273 0.393651
|
||||
vt 0.000000 0.314921
|
||||
vt 0.090910 0.314921
|
||||
vt 0.045455 0.393651
|
||||
vt 0.727273 0.314921
|
||||
vt 0.818182 0.314921
|
||||
vt 0.772727 0.393651
|
||||
vt 0.545455 0.314921
|
||||
vt 0.636364 0.314921
|
||||
vt 0.590909 0.393651
|
||||
vt 0.363637 0.314921
|
||||
vt 0.454546 0.314921
|
||||
vt 0.409092 0.393651
|
||||
vt 0.500000 0.393651
|
||||
vt 0.454546 0.472382
|
||||
vt 0.681818 0.393651
|
||||
vt 0.636364 0.472382
|
||||
vt 0.863636 0.393651
|
||||
vt 0.818182 0.472382
|
||||
vt 0.909091 0.314921
|
||||
vt 0.136365 0.393651
|
||||
vt 0.090910 0.472382
|
||||
vt 0.318182 0.393651
|
||||
vt 0.272728 0.472382
|
||||
vt 0.954545 0.236191
|
||||
vt 1.000000 0.157461
|
||||
vt 0.409092 0.078731
|
||||
vt 0.363637 0.000000
|
||||
s 0
|
||||
f 1/1/1 14/2/1 13/3/1
|
||||
f 2/4/2 14/5/2 16/6/2
|
||||
f 1/7/3 13/8/3 18/9/3
|
||||
f 1/10/4 18/11/4 20/12/4
|
||||
f 1/13/5 20/14/5 17/15/5
|
||||
f 2/4/6 16/6/6 23/16/6
|
||||
f 3/17/7 15/18/7 25/19/7
|
||||
f 4/20/8 19/21/8 27/22/8
|
||||
f 5/23/9 21/24/9 29/25/9
|
||||
f 6/26/10 22/27/10 31/28/10
|
||||
f 2/4/11 23/16/11 26/29/11
|
||||
f 3/17/12 25/19/12 28/30/12
|
||||
f 4/20/13 27/22/13 30/31/13
|
||||
f 5/23/14 29/25/14 32/32/14
|
||||
f 6/26/15 31/28/15 24/33/15
|
||||
f 7/34/16 33/35/16 38/36/16
|
||||
f 8/37/17 34/38/17 40/39/17
|
||||
f 9/40/18 35/41/18 41/42/18
|
||||
f 10/43/19 36/44/19 42/45/19
|
||||
f 11/46/20 37/47/20 39/48/20
|
||||
f 39/48/21 42/49/21 12/50/21
|
||||
f 39/48/22 37/47/22 42/49/22
|
||||
f 37/47/23 10/43/23 42/49/23
|
||||
f 42/45/24 41/51/24 12/52/24
|
||||
f 42/45/25 36/44/25 41/51/25
|
||||
f 36/44/26 9/40/26 41/51/26
|
||||
f 41/42/27 40/53/27 12/54/27
|
||||
f 41/42/28 35/41/28 40/53/28
|
||||
f 35/41/29 8/55/29 40/53/29
|
||||
f 40/39/30 38/56/30 12/57/30
|
||||
f 40/39/31 34/38/31 38/56/31
|
||||
f 34/38/32 7/34/32 38/56/32
|
||||
f 38/36/33 39/58/33 12/59/33
|
||||
f 38/36/34 33/35/34 39/58/34
|
||||
f 33/35/35 11/46/35 39/58/35
|
||||
f 24/33/36 37/47/36 11/46/36
|
||||
f 24/33/37 31/28/37 37/47/37
|
||||
f 31/28/38 10/43/38 37/47/38
|
||||
f 32/32/39 36/44/39 10/43/39
|
||||
f 32/32/40 29/25/40 36/44/40
|
||||
f 29/25/41 9/40/41 36/44/41
|
||||
f 30/31/42 35/41/42 9/40/42
|
||||
f 30/31/43 27/22/43 35/41/43
|
||||
f 27/22/44 8/55/44 35/41/44
|
||||
f 28/30/45 34/38/45 8/37/45
|
||||
f 28/30/46 25/19/46 34/38/46
|
||||
f 25/19/47 7/34/47 34/38/47
|
||||
f 26/29/48 33/35/48 7/34/48
|
||||
f 26/29/49 23/16/49 33/35/49
|
||||
f 23/16/50 11/46/50 33/35/50
|
||||
f 31/28/51 32/32/51 10/43/51
|
||||
f 31/28/52 22/27/52 32/32/52
|
||||
f 22/27/53 5/23/53 32/32/53
|
||||
f 29/25/54 30/31/54 9/40/54
|
||||
f 29/25/55 21/24/55 30/31/55
|
||||
f 21/24/56 4/20/56 30/31/56
|
||||
f 27/22/57 28/60/57 8/55/57
|
||||
f 27/22/58 19/21/58 28/60/58
|
||||
f 19/21/59 3/61/59 28/60/59
|
||||
f 25/19/60 26/29/60 7/34/60
|
||||
f 25/19/61 15/18/61 26/29/61
|
||||
f 15/18/62 2/4/62 26/29/62
|
||||
f 23/16/63 24/33/63 11/46/63
|
||||
f 23/16/64 16/6/64 24/33/64
|
||||
f 16/6/65 6/26/65 24/33/65
|
||||
f 17/15/66 22/27/66 6/26/66
|
||||
f 17/15/67 20/14/67 22/27/67
|
||||
f 20/14/68 5/23/68 22/27/68
|
||||
f 20/12/69 21/24/69 5/23/69
|
||||
f 20/12/70 18/11/70 21/24/70
|
||||
f 18/11/71 4/20/71 21/24/71
|
||||
f 18/9/72 19/21/72 4/20/72
|
||||
f 18/9/73 13/8/73 19/21/73
|
||||
f 13/8/74 3/61/74 19/21/74
|
||||
f 16/6/75 17/62/75 6/26/75
|
||||
f 16/6/76 14/5/76 17/62/76
|
||||
f 14/5/77 1/63/77 17/62/77
|
||||
f 13/3/78 15/18/78 3/17/78
|
||||
f 13/3/79 14/2/79 15/18/79
|
||||
f 14/2/80 2/4/80 15/18/80
|
||||
@ -5,7 +5,7 @@ def main():
|
||||
index_buffer = []
|
||||
index_lookup = {}
|
||||
|
||||
obj_write.write_obj(vertex_buffer, index_buffer, index_lookup, "icosphere.obj")
|
||||
obj_write.write_obj(vertex_buffer, index_buffer, index_lookup, "rounded-rectangle.obj")
|
||||
|
||||
with open("../non_block.idx", "wb") as f:
|
||||
obj_write.write_indices(f, "<H", index_buffer)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 480 B After Width: | Height: | Size: 600 B |
Binary file not shown.
@ -1,14 +0,0 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 Color;
|
||||
|
||||
flat in int InstanceID;
|
||||
|
||||
uniform vec3 BaseColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float intensity = (InstanceID == 0) ? 0.7 : 0.3;
|
||||
|
||||
Color = vec4(BaseColor * intensity, 1);
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
#version 330 core
|
||||
|
||||
// per-vertex
|
||||
in vec2 Position;
|
||||
|
||||
flat out int InstanceID;
|
||||
|
||||
uniform mat4 Transform;
|
||||
uniform bool UseGridTransform;
|
||||
|
||||
vec2 world_translation()
|
||||
{
|
||||
if (gl_InstanceID == 0)
|
||||
return vec2(0, 0);
|
||||
int instance = gl_InstanceID + 1;
|
||||
float negative = ((instance % 2) == 0) ? -1.0 : 1.0;
|
||||
|
||||
vec2 translation = (Position.x == 0) ? vec2(1, 0) : vec2(0, 1);
|
||||
|
||||
return translation * negative * (instance >> 1);
|
||||
}
|
||||
|
||||
vec2 grid_transform(vec2 position)
|
||||
{
|
||||
return position * 4 + world_translation();
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
InstanceID = gl_InstanceID;
|
||||
|
||||
vec2 position;
|
||||
if (UseGridTransform)
|
||||
position = grid_transform(Position);
|
||||
else
|
||||
position = Position;
|
||||
|
||||
gl_Position = Transform * vec4(position, 0, 1);
|
||||
}
|
||||
11
src/collision.cpp
Normal file
11
src/collision.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "directxmath/directxmath.h"
|
||||
|
||||
struct AABB {
|
||||
XMVECTOR min;
|
||||
XMVECTOR max;
|
||||
};
|
||||
|
||||
XMVECTOR closest_point_point_aabb(XMVECTOR const &p, AABB const& aabb)
|
||||
{
|
||||
return XMVectorClamp(p, aabb.min, aabb.max);
|
||||
}
|
||||
@ -1,481 +0,0 @@
|
||||
#include "glad/gl.h"
|
||||
#include "directxmath/directxmath.h"
|
||||
#include "opengl.h"
|
||||
|
||||
#include "collision.h"
|
||||
#include "collision_scene.h"
|
||||
|
||||
namespace collision_scene {
|
||||
|
||||
struct location {
|
||||
struct {
|
||||
unsigned int position;
|
||||
} attrib;
|
||||
struct {
|
||||
unsigned int transform;
|
||||
unsigned int use_grid_transform;
|
||||
unsigned int base_color;
|
||||
} uniform;
|
||||
};
|
||||
|
||||
static unsigned int program;
|
||||
static location location;
|
||||
|
||||
static unsigned int vertex_array_object;
|
||||
static unsigned int per_vertex_buffer;
|
||||
|
||||
static unsigned int index_buffer;
|
||||
|
||||
static XMVECTOR point_position[4];
|
||||
|
||||
static unsigned int ray_vertex_buffer;
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnarrowing"
|
||||
const _Float16 vertex_data[] = {
|
||||
// 0: lines
|
||||
-1.0, 0.0, 1.0, 0.0, // horizontal, left to right
|
||||
0.0, 1.0, 0.0, -1.0, // vertical, top to bottom
|
||||
|
||||
// 4: "cube"
|
||||
-1.0, 1.0, // tl
|
||||
1.0, 1.0, // tr
|
||||
1.0, -1.0, // br
|
||||
-1.0, -1.0, // bl
|
||||
|
||||
// 8: "circle"
|
||||
0.000000, -1.000000,
|
||||
-0.195090, -0.980785,
|
||||
-0.382683, -0.923880,
|
||||
-0.555570, -0.831470,
|
||||
-0.707107, -0.707107,
|
||||
-0.831470, -0.555570,
|
||||
-0.923880, -0.382683,
|
||||
-0.980785, -0.195090,
|
||||
-1.000000, 0.000000,
|
||||
-0.980785, 0.195090,
|
||||
-0.923880, 0.382683,
|
||||
-0.831470, 0.555570,
|
||||
-0.707107, 0.707107,
|
||||
-0.555570, 0.831470,
|
||||
-0.382683, 0.923880,
|
||||
-0.195090, 0.980785,
|
||||
0.000000, 1.000000,
|
||||
0.195090, 0.980785,
|
||||
0.382683, 0.923880,
|
||||
0.555570, 0.831470,
|
||||
0.707107, 0.707107,
|
||||
0.831470, 0.555570,
|
||||
0.923880, 0.382683,
|
||||
0.980785, 0.195090,
|
||||
1.000000, 0.000000,
|
||||
0.980785, -0.195090,
|
||||
0.923880, -0.382683,
|
||||
0.831470, -0.555570,
|
||||
0.707107, -0.707107,
|
||||
0.555570, -0.831470,
|
||||
0.382683, -0.923880,
|
||||
0.195090, -0.980785,
|
||||
};
|
||||
#pragma GCC diagnostic pop
|
||||
const int vertex_data_size = (sizeof (vertex_data));
|
||||
|
||||
const int per_vertex_size = (sizeof (_Float16)) * 2;
|
||||
|
||||
const unsigned short index_data[] = {
|
||||
// "cube" (line strip)
|
||||
0, 1, 2, 3, 0,
|
||||
|
||||
// "circle" (line strip)
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
0,
|
||||
};
|
||||
const int index_data_size = (sizeof (index_data));
|
||||
|
||||
void load_program()
|
||||
{
|
||||
program = compile_from_files("shader/collision_scene.vert",
|
||||
nullptr,
|
||||
"shader/collision_scene.frag");
|
||||
|
||||
location.attrib.position = glGetAttribLocation(program, "Position");
|
||||
|
||||
location.uniform.transform = glGetUniformLocation(program, "Transform");
|
||||
location.uniform.use_grid_transform = glGetUniformLocation(program, "UseGridTransform");
|
||||
location.uniform.base_color = glGetUniformLocation(program, "BaseColor");
|
||||
}
|
||||
|
||||
void load_vertex_attributes()
|
||||
{
|
||||
glGenVertexArrays(1, &vertex_array_object);
|
||||
glBindVertexArray(vertex_array_object);
|
||||
|
||||
glVertexBindingDivisor(0, 0);
|
||||
|
||||
glEnableVertexAttribArray(location.attrib.position);
|
||||
glVertexAttribFormat(location.attrib.position, 2, GL_HALF_FLOAT, GL_FALSE, 0);
|
||||
glVertexAttribBinding(location.attrib.position, 0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void load_per_vertex_buffer()
|
||||
{
|
||||
glGenBuffers(1, &per_vertex_buffer);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, per_vertex_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertex_data_size, vertex_data, GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void load_index_buffer()
|
||||
{
|
||||
glGenBuffers(1, &index_buffer);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data_size, index_data, GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void load()
|
||||
{
|
||||
load_program();
|
||||
load_vertex_attributes();
|
||||
|
||||
load_per_vertex_buffer();
|
||||
|
||||
load_index_buffer();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
point_position[i] = XMVectorSet(-1, -1, 0, 1);
|
||||
|
||||
// ray buffer
|
||||
glGenBuffers(1, &ray_vertex_buffer);
|
||||
}
|
||||
|
||||
void load_ray_vertex_buffer(XMVECTOR const & a, XMVECTOR const & b)
|
||||
{
|
||||
_Float16 data[] = {
|
||||
(_Float16)XMVectorGetX(a), (_Float16)XMVectorGetY(a),
|
||||
(_Float16)XMVectorGetX(b), (_Float16)XMVectorGetY(b),
|
||||
};
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, ray_vertex_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, 2 * 4, data, GL_DYNAMIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
static inline XMMATRIX view()
|
||||
{
|
||||
XMVECTOR eye = XMVectorSet(0, 0, 1, 0);
|
||||
XMVECTOR at = XMVectorSet(0, 0, 0, 0);
|
||||
XMVECTOR up = XMVectorSet(0, 1, 0, 0);
|
||||
return XMMatrixLookAtRH(eye, at, up);
|
||||
}
|
||||
|
||||
static inline XMMATRIX projection()
|
||||
{
|
||||
return XMMatrixOrthographicRH(10, 10, 0, 10);
|
||||
}
|
||||
|
||||
const float point_radius = 0.05f;
|
||||
|
||||
void update(int up, int down, int left, int right,
|
||||
int w, int s, int a, int d,
|
||||
int t, int g, int f, int h,
|
||||
int i, int k, int j, int l)
|
||||
{
|
||||
float rate = 0.05f;
|
||||
|
||||
float forward[4];
|
||||
float strafe[4];
|
||||
|
||||
forward[0] = (rate * up + -rate * down);
|
||||
strafe[0] = (-rate * left + rate * right);
|
||||
|
||||
forward[1] = (rate * w + -rate * s);
|
||||
strafe[1] = (-rate * a + rate * d);
|
||||
|
||||
forward[2] = (rate * t + -rate * g);
|
||||
strafe[2] = (-rate * f + rate * h);
|
||||
|
||||
forward[3] = (rate * i + -rate * k);
|
||||
strafe[3] = (-rate * j + rate * l);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
point_position[i] = XMVector3Transform(point_position[i], XMMatrixTranslation(strafe[i], forward[i], 0));
|
||||
}
|
||||
|
||||
static inline void set_transform(XMMATRIX const & transform)
|
||||
{
|
||||
XMFLOAT4X4 float_transform;
|
||||
XMStoreFloat4x4(&float_transform, transform);
|
||||
glUniformMatrix4fv(location.uniform.transform, 1, false, (float *)&float_transform);
|
||||
}
|
||||
|
||||
const int circle_base_vertex = 8;
|
||||
const int circle_base_index = 5 * (sizeof (unsigned short));
|
||||
|
||||
void draw_line(XMMATRIX const & transform, XMVECTOR const & a, XMVECTOR const & b)
|
||||
{
|
||||
load_ray_vertex_buffer(a, b);
|
||||
set_transform(transform);
|
||||
glBindVertexBuffer(0, ray_vertex_buffer, 0, per_vertex_size);
|
||||
glDrawArrays(GL_LINES, 0, 4);
|
||||
}
|
||||
|
||||
void draw_sphere(XMMATRIX const & transform, XMVECTOR const & center, float radius)
|
||||
{
|
||||
XMMATRIX sphere_transform
|
||||
= XMMatrixScaling(radius, radius, radius)
|
||||
* XMMatrixTranslationFromVector(center)
|
||||
* transform;
|
||||
set_transform(sphere_transform);
|
||||
glBindVertexBuffer(0, per_vertex_buffer, 0, per_vertex_size);
|
||||
glDrawElementsBaseVertex(GL_LINE_STRIP, 33, GL_UNSIGNED_SHORT, (void*)(circle_base_index), circle_base_vertex);
|
||||
}
|
||||
|
||||
void draw_capsule(XMMATRIX const & transform, XMVECTOR a, XMVECTOR b, float radius)
|
||||
{
|
||||
draw_sphere(transform, a, radius);
|
||||
draw_sphere(transform, b, radius);
|
||||
|
||||
XMVECTOR abn = XMVector3Normalize(a - b);
|
||||
XMVECTOR p = XMVectorSet(0, 0, 1, 0);
|
||||
XMVECTOR pxabn = XMVector3Cross(abn, p);
|
||||
|
||||
draw_line(transform, a + pxabn * radius, b + pxabn * radius);
|
||||
draw_line(transform, a - pxabn * radius, b - pxabn * radius);
|
||||
}
|
||||
|
||||
void draw_cube(XMMATRIX const & transform, XMVECTOR const & position)
|
||||
{
|
||||
float cube_half = 0.5;
|
||||
XMMATRIX cube_transform
|
||||
= XMMatrixScaling(cube_half, cube_half, cube_half)
|
||||
* XMMatrixTranslationFromVector(position)
|
||||
* transform;
|
||||
set_transform(cube_transform);
|
||||
const int cube_base_vertex = 4;
|
||||
const int cube_base_index = 0;
|
||||
glDrawElementsBaseVertex(GL_LINE_STRIP, 5, GL_UNSIGNED_SHORT, (void*)(cube_base_index), cube_base_vertex);
|
||||
}
|
||||
|
||||
static const XMVECTOR cubes[] = {
|
||||
XMVectorSet(1, 1, 0, 1),
|
||||
XMVectorSet(-1, 1, 0, 1),
|
||||
XMVectorSet(-2, 1, 0, 1),
|
||||
XMVectorSet(-2, -2, 0, 1),
|
||||
XMVectorSet(-2, -3, 0, 1),
|
||||
};
|
||||
static const int cubes_length = (sizeof (cubes)) / (sizeof (cubes[0]));
|
||||
|
||||
void check_collisions(collision::Sphere const & sphere, XMVECTOR const & direction,
|
||||
collision::state & state)
|
||||
{
|
||||
state.t = FLT_MAX;
|
||||
state.intersected = false;
|
||||
|
||||
collision::AABB sphere_aabb = collision::moving_sphere_aabb(sphere, direction);
|
||||
XMVECTOR min_floor = XMVectorFloor(sphere_aabb.min);
|
||||
XMVECTOR max_ceiling = XMVectorCeiling(sphere_aabb.max);
|
||||
|
||||
for (int i = 0; i < cubes_length; i++) {
|
||||
XMVECTOR cube_center = cubes[i];
|
||||
// coarse filter
|
||||
XMVECTOR le = XMVectorLessOrEqual(min_floor, cube_center);
|
||||
XMVECTOR ge = XMVectorGreaterOrEqual(max_ceiling, cube_center);
|
||||
if (XMVectorGetX(le) == 0 || XMVectorGetY(le) == 0 || XMVectorGetZ(le) == 0 ||
|
||||
XMVectorGetX(ge) == 0 || XMVectorGetY(ge) == 0 || XMVectorGetZ(ge) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float cube_half = 0.5;
|
||||
collision::check_collision(sphere, direction, cube_center, cube_half, state);
|
||||
}
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
glUseProgram(program);
|
||||
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
|
||||
glBindVertexArray(vertex_array_object);
|
||||
glBindVertexBuffer(0, per_vertex_buffer, 0, per_vertex_size);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
|
||||
|
||||
XMMATRIX transform = view() * projection();
|
||||
|
||||
// grid
|
||||
glLineWidth(1.0f);
|
||||
set_transform(transform);
|
||||
glUniform3f(location.uniform.base_color, 0, 1, 0);
|
||||
glUniform1i(location.uniform.use_grid_transform, 1);
|
||||
glDrawArraysInstanced(GL_LINES, 0, 4, 7);
|
||||
|
||||
glUniform1i(location.uniform.use_grid_transform, 0);
|
||||
|
||||
collision::Sphere sphere(point_position[0], 0.48);
|
||||
XMVECTOR direction = point_position[1] - point_position[0];
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// reset intersections
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
glLineWidth(3.0f);
|
||||
for (int i = 0; i < cubes_length; i++) {
|
||||
XMVECTOR center = cubes[i];
|
||||
draw_cube(transform, center);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// collision response
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
glUniform3f(location.uniform.base_color, 0, 0.0, 1.0);
|
||||
draw_sphere(transform, sphere.center, sphere.radius);
|
||||
glUniform3f(location.uniform.base_color, 0, 0.5, 1.0);
|
||||
draw_sphere(transform, sphere.center + direction, point_radius);
|
||||
draw_line(transform, sphere.center, sphere.center + direction);
|
||||
|
||||
int intersections = 0;
|
||||
while (intersections < 10) {
|
||||
|
||||
collision::state state;
|
||||
check_collisions(sphere, direction, state);
|
||||
if (!state.intersected)
|
||||
break;
|
||||
|
||||
XMVECTOR intersection_normal;
|
||||
XMVECTOR new_direction = collision::sphere_collision_response(sphere, direction,
|
||||
state.intersection_point,
|
||||
state.intersection_position,
|
||||
intersection_normal);
|
||||
|
||||
glUniform3f(location.uniform.base_color, 1.0, 0.5, 1.0);
|
||||
draw_line(transform, state.intersection_position, state.intersection_position + new_direction);
|
||||
|
||||
glUniform3f(location.uniform.base_color, 1.0, 0.5, 0.0);
|
||||
draw_sphere(transform, state.intersection_position, sphere.radius);
|
||||
glUniform3f(location.uniform.base_color, 1.0, 0.0, 0.0);
|
||||
draw_sphere(transform, state.intersection_point, point_radius);
|
||||
|
||||
// collide again
|
||||
sphere.center = state.intersection_position;
|
||||
direction = new_direction;
|
||||
printf("intersection %d\n", intersections);
|
||||
|
||||
intersections += 1;
|
||||
}
|
||||
if (intersections == 10) {
|
||||
//direction == XMVectorZero();
|
||||
} else {
|
||||
glUniform3f(location.uniform.base_color, 1.0, 1.0, 0.0);
|
||||
draw_sphere(transform, sphere.center + direction, sphere.radius);
|
||||
}
|
||||
|
||||
/*
|
||||
XMVECTOR pa = XMVectorSelect(sphere_aabb.min, sphere_aabb.max, g_XMSelect1000);
|
||||
XMVECTOR pb = XMVectorSelect(sphere_aabb.min, sphere_aabb.max, g_XMSelect0101);
|
||||
draw_line(transform, sphere_aabb.min, pa);
|
||||
draw_line(transform, pa, sphere_aabb.max);
|
||||
draw_line(transform, sphere_aabb.max, pb);
|
||||
draw_line(transform, pb, sphere_aabb.min);
|
||||
*/
|
||||
//sphere_aabb.max,
|
||||
|
||||
/*
|
||||
// segments
|
||||
glUniform3f(location.uniform.base_color, 0, 0.5, 1.0);
|
||||
draw_line(transform, point_position[0], point_position[1]);
|
||||
glUniform3f(location.uniform.base_color, 0, 1.0, 0.5);
|
||||
draw_line(transform, point_position[2], point_position[3]);
|
||||
|
||||
// points
|
||||
glUniform3f(location.uniform.base_color, 0, 0.5, 1.0);
|
||||
draw_sphere(transform, point_position[0], point_radius);
|
||||
draw_sphere(transform, point_position[1], point_radius);
|
||||
|
||||
glUniform3f(location.uniform.base_color, 0, 1.0, 0.5);
|
||||
draw_sphere(transform, point_position[2], point_radius);
|
||||
draw_sphere(transform, point_position[3], point_radius);
|
||||
|
||||
float t1, t2;
|
||||
XMVECTOR c1, c2;
|
||||
collision::closest_point_segment_segment(point_position[0], point_position[1],
|
||||
point_position[2], point_position[3],
|
||||
t1, t2, c1, c2);
|
||||
glUniform3f(location.uniform.base_color, 0.0, 0.5, 1.0);
|
||||
draw_sphere(transform, c1, point_radius);
|
||||
glUniform3f(location.uniform.base_color, 0.0, 1.0, 0.5);
|
||||
draw_sphere(transform, c2, point_radius);
|
||||
|
||||
collision::Capsule capsule1(point_position[0], point_position[1], 0.5);
|
||||
collision::Capsule capsule2(point_position[2], point_position[3], 0.0);
|
||||
glUniform3f(location.uniform.base_color, 0, 0.5, 1.0);
|
||||
draw_capsule(transform, capsule1.a, capsule1.b, capsule1.radius);
|
||||
glUniform3f(location.uniform.base_color, 0, 1.0, 0.5);
|
||||
//draw_capsule(transform, capsule2.a, capsule2.b, capsule2.radius);
|
||||
|
||||
XMVECTOR c1_point;
|
||||
XMVECTOR c2_point;
|
||||
bool collided = collision::intersect_capsule_capsule(capsule1, capsule2, c1_point, c2_point);
|
||||
if (collided) {
|
||||
glUniform3f(location.uniform.base_color, 1.0, 0.0, 0.0);
|
||||
draw_sphere(transform, c1_point, point_radius);
|
||||
|
||||
glUniform3f(location.uniform.base_color, 1.0, 0.5, 0.0);
|
||||
draw_sphere(transform, c2_point, point_radius);
|
||||
}
|
||||
*/
|
||||
|
||||
// cube
|
||||
/*
|
||||
float cube_half = 0.5;
|
||||
XMVECTOR cube_position = XMVectorSet(1, 0, 0, 0);
|
||||
XMMATRIX cube_transform
|
||||
= XMMatrixScaling(cube_half, cube_half, cube_half)
|
||||
* XMMatrixTranslationFromVector(cube_position)
|
||||
* transform;
|
||||
set_transform(cube_transform);
|
||||
glUniform3f(location.uniform.base_color, 0, 0.5, 1.0);
|
||||
glUniform1i(location.uniform.use_grid_transform, 0);
|
||||
const int cube_base_vertex = 4;
|
||||
const int cube_base_index = 0;
|
||||
glDrawElementsBaseVertex(GL_LINE_STRIP, 5, GL_UNSIGNED_SHORT, (void*)(cube_base_index), cube_base_vertex);
|
||||
|
||||
// circle
|
||||
|
||||
glUniform3f(location.uniform.base_color, 1.0, 0.5, 0.0);
|
||||
draw_sphere(transform, point_position, point_radius);
|
||||
draw_sphere(transform, point_1_position, point_radius);
|
||||
|
||||
XMVECTOR direction = XMVector3Normalize(point_1_position - point_position);
|
||||
collision::AABB cube_aabb = collision::cube_aabb(cube_position, cube_half);
|
||||
XMVECTOR intersection_point;
|
||||
float t;
|
||||
bool intersection = intersect_ray_aabb(point_position, direction, cube_aabb, t, intersection_point);
|
||||
if (intersection && t > 0.0f) {
|
||||
glUniform3f(location.uniform.base_color, 0.9, 0.0, 0.0);
|
||||
draw_line(transform, point_position, intersection_point);
|
||||
draw_sphere(transform, intersection_point, point_radius);
|
||||
} else {
|
||||
glUniform3f(location.uniform.base_color, 0.5, 0.5, 0.5);
|
||||
draw_line(transform, point_position, point_position + direction * 20.0f);
|
||||
}
|
||||
|
||||
glUniform3f(location.uniform.base_color, 0.5, 0.0, 0.5);
|
||||
XMVECTOR ca = XMVectorSet(1, 2.5, 0, 0);
|
||||
XMVECTOR cb = XMVectorSet(-1, 2, 0, 0);
|
||||
draw_capsule(transform, ca, cb, 0.5);
|
||||
*/
|
||||
}
|
||||
}
|
||||
@ -127,8 +127,7 @@ namespace non_block {
|
||||
glBindVertexBuffer(0, per_vertex_buffer, 0, per_vertex_size);
|
||||
|
||||
void const * indices = (void *)(0);
|
||||
// element_count from vertex_buffer_non_block.py stdout
|
||||
int element_count = 240;
|
||||
int element_count = 300;
|
||||
glDrawElements(GL_TRIANGLES, element_count, GL_UNSIGNED_SHORT, indices);
|
||||
}
|
||||
}
|
||||
|
||||
96
src/test.cpp
96
src/test.cpp
@ -17,8 +17,6 @@
|
||||
#include "minecraft.h"
|
||||
#include "hud.h"
|
||||
#include "lighting.h"
|
||||
#include "collision_scene.h"
|
||||
#include "collision.h"
|
||||
|
||||
struct line_location {
|
||||
struct {
|
||||
@ -280,62 +278,13 @@ void load(const char * source_path)
|
||||
non_block::load_index_buffer();
|
||||
non_block::load_per_vertex_buffer();
|
||||
non_block::load_vertex_attributes();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// collision_scene
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
collision_scene::load();
|
||||
}
|
||||
|
||||
void update_keyboard(int up, int down, int left, int right,
|
||||
int w, int s, int a, int d,
|
||||
int t, int g, int f, int h,
|
||||
int i, int k, int j, int l)
|
||||
void update_keyboard(int up, int down, int left, int right)
|
||||
{
|
||||
//float forward = (0.1f * up + -0.1f * down);
|
||||
//float strafe = (-0.1f * left + 0.1f * right);
|
||||
//view::third_person::apply_translation(forward, strafe, 0);
|
||||
collision_scene::update(up, down, left, right,
|
||||
w, s, a, d,
|
||||
t, g, f, h,
|
||||
i, k, j, l);
|
||||
}
|
||||
|
||||
void check_collisions(collision::Sphere const & sphere, XMVECTOR const & direction,
|
||||
collision::state & state)
|
||||
{
|
||||
state.t = FLT_MAX;
|
||||
state.intersected = false;
|
||||
|
||||
collision::AABB sphere_aabb = collision::moving_sphere_aabb(sphere, direction);
|
||||
XMVECTOR min_floor = XMVectorFloor(sphere_aabb.min);
|
||||
XMVECTOR max_ceiling = XMVectorCeiling(sphere_aabb.max);
|
||||
|
||||
int min_x = XMVectorGetX(min_floor);
|
||||
int min_y = XMVectorGetZ(min_floor); // swizzle
|
||||
int min_z = XMVectorGetY(min_floor); // swizzle
|
||||
|
||||
int max_x = XMVectorGetX(max_ceiling);
|
||||
int max_y = XMVectorGetZ(max_ceiling); // swizzle
|
||||
int max_z = XMVectorGetY(max_ceiling); // swizzle
|
||||
|
||||
for (int x = min_x; x <= max_x; x++) {
|
||||
for (int y = min_y; y <= max_y; y++) {
|
||||
for (int z = min_z; z <= max_z; z++) {
|
||||
global_entry * const entry = world_lookup(x, y, z);
|
||||
if (entry == NULL)
|
||||
continue;
|
||||
|
||||
// there is a block at x, y, z
|
||||
XMVECTOR cube_center = XMVectorSet(x, z, y, 1); // swizzle
|
||||
float cube_half = 0.5f;
|
||||
collision::check_collision(sphere, direction,
|
||||
cube_center, cube_half,
|
||||
state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int max_joysticks = 8;
|
||||
@ -352,45 +301,10 @@ void update_joystick(int joystick_index,
|
||||
float elevation = (tl - tr) * 0.5;
|
||||
float delta_yaw = rx * -0.035;
|
||||
float delta_pitch = ry * -0.035;
|
||||
|
||||
XMVECTOR direction = view::third_person::apply_transform(forward, strafe, elevation,
|
||||
view::third_person::apply_transform(forward, strafe, elevation,
|
||||
delta_yaw, delta_pitch);
|
||||
view::apply_fov(0.01 * up + -0.01 * down);
|
||||
|
||||
XMVECTOR sphere_position = view::state.at;
|
||||
|
||||
float sphere_radius = 0.48;
|
||||
collision::Sphere sphere(sphere_position, sphere_radius);
|
||||
int intersections = 0;
|
||||
collision::state state;
|
||||
while (intersections < 500) {
|
||||
check_collisions(sphere, direction, state);
|
||||
if (!state.intersected)
|
||||
break;
|
||||
|
||||
XMVECTOR intersection_normal;
|
||||
XMVECTOR new_direction = collision::sphere_collision_response(sphere, direction,
|
||||
state.intersection_point,
|
||||
state.intersection_position,
|
||||
intersection_normal);
|
||||
// collide again
|
||||
sphere.center = state.intersection_position + intersection_normal * 0.01f;
|
||||
direction = new_direction * 0.9f;
|
||||
if (XMVectorGetX(XMVector3Length(direction)) < 0.001f) {
|
||||
direction = XMVectorZero();
|
||||
break;
|
||||
}
|
||||
intersections += 1;
|
||||
}
|
||||
if (intersections == 500) { // too many recursive collisions
|
||||
printf("too many recursive collisions\n");
|
||||
} else {
|
||||
// apply the last direction impulse
|
||||
view::state.at = sphere.center + direction;
|
||||
}
|
||||
|
||||
view::state.eye = view::state.at - view::state.direction * view::at_distance;
|
||||
|
||||
/*
|
||||
lighting.quadratic += 0.01 * a + -0.01 * b;
|
||||
if (lighting.quadratic < 0.0f)
|
||||
@ -555,11 +469,5 @@ void draw()
|
||||
//draw_quad();
|
||||
hud::draw();
|
||||
|
||||
/*
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
collision_scene::draw();
|
||||
*/
|
||||
|
||||
last_frame_time = current_time;
|
||||
}
|
||||
|
||||
13
src/view.cpp
13
src/view.cpp
@ -8,6 +8,8 @@ constexpr bool third_person = false;
|
||||
namespace view {
|
||||
view_state state = {};
|
||||
|
||||
const float at_distance = 10;
|
||||
|
||||
static inline XMMATRIX current_projection()
|
||||
{
|
||||
float fov_angle_y = XMConvertToRadians(45 * state.fov);
|
||||
@ -59,7 +61,7 @@ namespace view {
|
||||
}
|
||||
|
||||
namespace third_person {
|
||||
XMVECTOR apply_transform(float forward, float strafe, float elevation,
|
||||
void apply_transform(float forward, float strafe, float elevation,
|
||||
float delta_yaw, float delta_pitch)
|
||||
{
|
||||
state.pitch = clamp_pitch(delta_pitch);
|
||||
@ -68,11 +70,8 @@ namespace view {
|
||||
state.normal = get_normal(); // on forward change
|
||||
state.direction = get_direction(); // on forward/normal/pitch change
|
||||
|
||||
/*
|
||||
state.at += state.forward * forward + state.normal * strafe + state.up * elevation;
|
||||
state.eye = state.at - state.direction * at_distance;
|
||||
*/
|
||||
return state.forward * forward + state.normal * strafe + state.up * elevation;
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,14 +96,14 @@ namespace view {
|
||||
state.up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
state.fov = 1.5;
|
||||
state.pitch = -0.7;
|
||||
state.pitch = 0;
|
||||
|
||||
state.forward = XMVector3Normalize(XMVectorSet(-0.64, 0.77, 0, 0));
|
||||
state.forward = XMVector3Normalize(XMVectorSet(-0.63, 0.78, 0, 0));
|
||||
state.normal = get_normal(); // on forward change
|
||||
state.direction = get_direction(); // on forward/normal/pitch change
|
||||
|
||||
// position
|
||||
state.eye = XMVectorSet(-45.5f, 43.25f, 63.0f, 1);
|
||||
state.eye = XMVectorSet(-55.5f, 48.25f, 50.0f, 1);
|
||||
state.at = state.eye + state.direction * at_distance;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user