collision: closest point point aabb
This commit is contained in:
parent
f6bd91824b
commit
84fbd05841
3
Makefile
3
Makefile
@ -30,7 +30,8 @@ OBJS = \
|
|||||||
src/view.o \
|
src/view.o \
|
||||||
src/minecraft.o \
|
src/minecraft.o \
|
||||||
src/hud.o \
|
src/hud.o \
|
||||||
src/lighting.o
|
src/lighting.o \
|
||||||
|
src/collision_scene.o
|
||||||
|
|
||||||
all: test.so
|
all: test.so
|
||||||
|
|
||||||
|
|||||||
25
include/collision.h
Normal file
25
include/collision.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "directxmath/directxmath.h"
|
||||||
|
|
||||||
|
namespace collision {
|
||||||
|
|
||||||
|
struct AABB {
|
||||||
|
XMVECTOR min;
|
||||||
|
XMVECTOR max;
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
7
include/collision_scene.h
Normal file
7
include/collision_scene.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace collision_scene {
|
||||||
|
void load();
|
||||||
|
void draw();
|
||||||
|
void update(int up, int down, int left, int right);
|
||||||
|
}
|
||||||
14
shader/collision_scene.frag
Normal file
14
shader/collision_scene.frag
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#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);
|
||||||
|
}
|
||||||
39
shader/collision_scene.vert
Normal file
39
shader/collision_scene.vert
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#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);
|
||||||
|
}
|
||||||
@ -1,11 +0,0 @@
|
|||||||
#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);
|
|
||||||
}
|
|
||||||
246
src/collision_scene.cpp
Normal file
246
src/collision_scene.cpp
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
#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;
|
||||||
|
|
||||||
|
#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();
|
||||||
|
|
||||||
|
point_position = XMVectorSet(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(int up, int down, int left, int right)
|
||||||
|
{
|
||||||
|
float rate = 0.1f;
|
||||||
|
float forward = (rate * up + -rate * down);
|
||||||
|
float strafe = (-rate * left + rate * right);
|
||||||
|
|
||||||
|
point_position = XMVector3Transform(point_position, XMMatrixTranslation(strafe, forward, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
XMFLOAT4X4 float_transform;
|
||||||
|
XMStoreFloat4x4(&float_transform, transform);
|
||||||
|
|
||||||
|
// grid
|
||||||
|
glUniformMatrix4fv(location.uniform.transform, 1, false, (float *)&float_transform);
|
||||||
|
glUniform3f(location.uniform.base_color, 0, 1, 0);
|
||||||
|
glUniform1i(location.uniform.use_grid_transform, 1);
|
||||||
|
glDrawArraysInstanced(GL_LINES, 0, 4, 7);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
const int circle_base_vertex = 8;
|
||||||
|
const int circle_base_index = 5 * (sizeof (unsigned short));
|
||||||
|
|
||||||
|
XMMATRIX point_scale = XMMatrixScaling(0.05, 0.05, 0.05);
|
||||||
|
|
||||||
|
// point
|
||||||
|
glUniform3f(location.uniform.base_color, 1.0, 0.5, 0.0);
|
||||||
|
|
||||||
|
XMMATRIX point_transform
|
||||||
|
= point_scale
|
||||||
|
* XMMatrixTranslationFromVector(point_position)
|
||||||
|
* transform;
|
||||||
|
set_transform(point_transform);
|
||||||
|
glDrawElementsBaseVertex(GL_LINE_STRIP, 33, GL_UNSIGNED_SHORT, (void*)(circle_base_index), circle_base_vertex);
|
||||||
|
|
||||||
|
// closest point
|
||||||
|
glUniform3f(location.uniform.base_color, 1.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
collision::AABB cube_aabb = collision::cube_aabb(cube_position, cube_half);
|
||||||
|
XMVECTOR closest_point_position = collision::closest_point_point_aabb(point_position, cube_aabb);
|
||||||
|
XMMATRIX closest_point_transform
|
||||||
|
= point_scale
|
||||||
|
* XMMatrixTranslationFromVector(closest_point_position)
|
||||||
|
* transform;
|
||||||
|
set_transform(closest_point_transform);
|
||||||
|
glDrawElementsBaseVertex(GL_LINE_STRIP, 33, GL_UNSIGNED_SHORT, (void*)(circle_base_index), circle_base_vertex);
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/test.cpp
14
src/test.cpp
@ -17,6 +17,7 @@
|
|||||||
#include "minecraft.h"
|
#include "minecraft.h"
|
||||||
#include "hud.h"
|
#include "hud.h"
|
||||||
#include "lighting.h"
|
#include "lighting.h"
|
||||||
|
#include "collision_scene.h"
|
||||||
|
|
||||||
struct line_location {
|
struct line_location {
|
||||||
struct {
|
struct {
|
||||||
@ -278,6 +279,12 @@ void load(const char * source_path)
|
|||||||
non_block::load_index_buffer();
|
non_block::load_index_buffer();
|
||||||
non_block::load_per_vertex_buffer();
|
non_block::load_per_vertex_buffer();
|
||||||
non_block::load_vertex_attributes();
|
non_block::load_vertex_attributes();
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// collision_scene
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
collision_scene::load();
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_keyboard(int up, int down, int left, int right)
|
void update_keyboard(int up, int down, int left, int right)
|
||||||
@ -285,6 +292,7 @@ void update_keyboard(int up, int down, int left, int right)
|
|||||||
//float forward = (0.1f * up + -0.1f * down);
|
//float forward = (0.1f * up + -0.1f * down);
|
||||||
//float strafe = (-0.1f * left + 0.1f * right);
|
//float strafe = (-0.1f * left + 0.1f * right);
|
||||||
//view::third_person::apply_translation(forward, strafe, 0);
|
//view::third_person::apply_translation(forward, strafe, 0);
|
||||||
|
collision_scene::update(up, down, left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int max_joysticks = 8;
|
const int max_joysticks = 8;
|
||||||
@ -452,6 +460,7 @@ void draw()
|
|||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
glClearDepth(-1.0f);
|
glClearDepth(-1.0f);
|
||||||
|
|
||||||
|
/*
|
||||||
// possibly re-initialize geometry buffer if window width/height changes
|
// possibly re-initialize geometry buffer if window width/height changes
|
||||||
init_geometry_buffer(geometry_buffer_pnc, geometry_buffer_pnc_types);
|
init_geometry_buffer(geometry_buffer_pnc, geometry_buffer_pnc_types);
|
||||||
|
|
||||||
@ -468,6 +477,11 @@ void draw()
|
|||||||
lighting::draw();
|
lighting::draw();
|
||||||
//draw_quad();
|
//draw_quad();
|
||||||
hud::draw();
|
hud::draw();
|
||||||
|
*/
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
collision_scene::draw();
|
||||||
|
|
||||||
last_frame_time = current_time;
|
last_frame_time = current_time;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user