collision: intersect moving sphere aabb
This commit is contained in:
parent
157f493167
commit
ce2260e078
@ -174,28 +174,27 @@ namespace collision {
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool intersect_moving_sphere_aabb(Sphere const & sphere, XMVECTOR const & direction, AABB const & aabb, float & t)
|
||||
{
|
||||
AABB expand(expand.min - XMVectorReplicate(sphere.radius),
|
||||
expand.max + XMVectorReplicate(sphere.radius));
|
||||
static const float interval_epsilon = 0.02f;
|
||||
|
||||
// intersect ray against expand
|
||||
XMVECTOR point;
|
||||
bool intersection = intersect_ray_aabb(sphere.center, direction, expand, t, point);
|
||||
if (!intersection || t > 1.0f)
|
||||
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;
|
||||
|
||||
XMVECTOR lt = XMVectorLess(point, aabb.min);
|
||||
int u = 0;
|
||||
if (XMVectorGetX(lt) != 0) u |= 1;
|
||||
if (XMVectorGetY(lt) != 0) u |= 2;
|
||||
if (XMVectorGetZ(lt) != 0) u |= 4;
|
||||
XMVECTOR gt = XMVectorGreater(point, aabb.max);
|
||||
int v = 0;
|
||||
if (XMVectorGetX(gt) != 0) v |= 1;
|
||||
if (XMVectorGetY(gt) != 0) v |= 2;
|
||||
if (XMVectorGetZ(gt) != 0) v |= 4;
|
||||
if (t1 - t0 < interval_epsilon) {
|
||||
t = t0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int mask = u + v;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ namespace collision_scene {
|
||||
load_index_buffer();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
point_position[i] = XMVectorSet(0, 0, 0, 1);
|
||||
point_position[i] = XMVectorSet(-1, -1, 0, 1);
|
||||
|
||||
// ray buffer
|
||||
glGenBuffers(1, &ray_vertex_buffer);
|
||||
@ -252,6 +252,19 @@ namespace collision_scene {
|
||||
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);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
glUseProgram(program);
|
||||
@ -267,6 +280,7 @@ namespace collision_scene {
|
||||
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);
|
||||
@ -274,6 +288,36 @@ namespace collision_scene {
|
||||
|
||||
glUniform1i(location.uniform.use_grid_transform, 0);
|
||||
|
||||
|
||||
glLineWidth(3.0f);
|
||||
glUniform3f(location.uniform.base_color, 0.5, 1.0, 0.0);
|
||||
XMVECTOR cube_center = XMVectorSet(1, 1, 0, 1);
|
||||
draw_cube(transform, cube_center);
|
||||
|
||||
glUniform3f(location.uniform.base_color, 0, 0.0, 1.0);
|
||||
draw_sphere(transform, point_position[0], 0.5);
|
||||
glUniform3f(location.uniform.base_color, 0, 0.5, 1.0);
|
||||
draw_sphere(transform, point_position[1], point_radius);
|
||||
draw_line(transform, point_position[0], point_position[1]);
|
||||
|
||||
collision::Sphere sphere(point_position[0], 0.5);
|
||||
XMVECTOR direction = point_position[1] - point_position[0];
|
||||
collision::AABB aabb = collision::cube_aabb(cube_center, 0.5);
|
||||
float t;
|
||||
XMVECTOR intersection_point;
|
||||
bool intersected = collision::intersect_moving_sphere_aabb(sphere, direction,
|
||||
0, 1, aabb,
|
||||
t, intersection_point);
|
||||
|
||||
if (intersected){
|
||||
glUniform3f(location.uniform.base_color, 1.0, 0.5, 0.0);
|
||||
XMVECTOR intersection_position = point_position[0] + direction * t;
|
||||
draw_sphere(transform, intersection_position, 0.5);
|
||||
glUniform3f(location.uniform.base_color, 1.0, 0.0, 0.0);
|
||||
draw_sphere(transform, intersection_point, point_radius);
|
||||
}
|
||||
|
||||
/*
|
||||
// segments
|
||||
glUniform3f(location.uniform.base_color, 0, 0.5, 1.0);
|
||||
draw_line(transform, point_position[0], point_position[1]);
|
||||
@ -316,6 +360,7 @@ namespace collision_scene {
|
||||
glUniform3f(location.uniform.base_color, 1.0, 0.5, 0.0);
|
||||
draw_sphere(transform, c2_point, point_radius);
|
||||
}
|
||||
*/
|
||||
|
||||
// cube
|
||||
/*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user