From b0e9714a0e05879a5cf0880fcab8a24e014a27f9 Mon Sep 17 00:00:00 2001 From: karai17 Date: Tue, 26 Jul 2016 01:21:49 -0300 Subject: [PATCH] added aabb_obb test --- modules/intersect.lua | 75 +++++++++++++---------------------------- spec/intersect_spec.lua | 25 ++++++++++++-- 2 files changed, 45 insertions(+), 55 deletions(-) diff --git a/modules/intersect.lua b/modules/intersect.lua index 0c3831c..dfe6fd8 100644 --- a/modules/intersect.lua +++ b/modules/intersect.lua @@ -341,93 +341,64 @@ function intersect.aabb_obb(aabb, obb) local b = obb.extent local T = obb.position - aabb.position local rot = mat4():transpose(obb.rotation) - local reps = 1e-6 local B = {} + local t for i = 1, 3 do B[i] = {} for j = 1, 3 do assert((i - 1) * 4 + j < 16 and (i - 1) * 4 + j > 0) - B[i][j] = abs(rot[(i - 1) * 4 + j]) + reps + B[i][j] = abs(rot[(i - 1) * 4 + j]) + 1e-6 end end - local t, s - local r = 1 - t = abs(T.x) if not (t <= (b.x + a.x * B[1][1] + b.y * B[1][2] + b.z * B[1][3])) then return false end - - s = T.x * B[1][1] + T.y*B[2][1] + T.z*B[3][1] - t = abs(s) + t = abs(T.x * B[1][1] + T.y * B[2][1] + T.z * B[3][1]) if not (t <= (b.x + a.x * B[1][1] + a.y * B[2][1] + a.z * B[3][1])) then return false end - t = abs(T.y) if not (t <= (a.y + b.x * B[2][1] + b.y * B[2][2] + b.z * B[2][3])) then return false end - t = abs(T.z) if not (t <= (a.z + b.x * B[3][1] + b.y * B[3][2] + b.z * B[3][3])) then return false end - - s = T.x * B[1][2] + T.y * B[2][2] + T.z * B[3][2] - t = abs(s) + t = abs(T.x * B[1][2] + T.y * B[2][2] + T.z * B[3][2]) if not (t <= (b.y + a.x * B[1][2] + a.y * B[2][2] + a.z * B[3][2])) then return false end - - s = T.x * B[1][3] + T.y * B[2][3] + T.z * B[3][3] - t = abs(s) + t = abs(T.x * B[1][3] + T.y * B[2][3] + T.z * B[3][3]) if not (t <= (b.z + a.x * B[1][3] + a.y * B[2][3] + a.z * B[3][3])) then return false end - - s = T.z * B[2][1] - T.y * B[3][1] - t = abs(s) + t = abs(T.z * B[2][1] - T.y * B[3][1]) if not (t <= (a.y * B[3][1] + a.z * B[2][1] + b.y * B[1][3] + b.z * B[1][2])) then return false end - - s = T.z * B[2][2] - T.y * B[3][2] - t = abs(s) + t = abs(T.z * B[2][2] - T.y * B[3][2]) if not (t <= (a.y * B[3][2] + a.z * B[2][2] + b.x * B[1][3] + b.z * B[1][1])) then return false end - - s = T.z * B[2][3] - T.y * B[3][3] - t = abs(s) + t = abs(T.z * B[2][3] - T.y * B[3][3]) if not (t <= (a.y * B[3][3] + a.z * B[2][3] + b.x * B[1][2] + b.y * B[1][1])) then return false end - - s = T.x * B[3][1] - T.z * B[1][1] - t = abs(s) + t = abs(T.x * B[3][1] - T.z * B[1][1]) if not (t <= (a.x * B[3][1] + a.z * B[1][1] + b.y * B[2][3] + b.z * B[2][2])) then return false end - - s = T.x * B[3][2] - T.z * B[1][2] - t = abs(s) + t = abs(T.x * B[3][2] - T.z * B[1][2]) if not (t <= (a.x * B[3][2] + a.z * B[1][2] + b.x * B[2][3] + b.z * B[2][1])) then return false end - - s = T.x * B[3][3] - T.z * B[1][3] - t = abs(s) + t = abs(T.x * B[3][3] - T.z * B[1][3]) if not (t <= (a.x * B[3][3] + a.z * B[1][3] + b.x * B[2][2] + b.y * B[2][1])) then return false end - - s = T.y * B[1][1] - T.x * B[2][1] - t = abs(s) + t = abs(T.y * B[1][1] - T.x * B[2][1]) if not (t <= (a.x * B[2][1] + a.y * B[1][1] + b.y * B[3][3] + b.z * B[3][2])) then return false end - - s = T.y * B[1][2] - T.x * B[2][2] - t = abs(s) + t = abs(T.y * B[1][2] - T.x * B[2][2]) if not (t <= (a.x * B[2][2] + a.y * B[1][2] + b.x * B[3][3] + b.z * B[3][1])) then return false end - - s = T.y * B[1][3] - T.x * B[2][3] - t = abs(s) + t = abs(T.y * B[1][3] - T.x * B[2][3]) if not (t <= (a.x * B[2][3] + a.y * B[1][3] + b.x * B[3][2] + b.y * B[3][1])) then return false end -- https://gamedev.stackexchange.com/questions/24078/which-side-was-hit -- Minkowski Sum - local wy = (aabb.extent * 2 + obb.extent * 2) * (aabb.position.y - obb.position.y) - local hx = (aabb.extent * 2 + obb.extent * 2) * (aabb.position.x - obb.position.x) + local wy = (aabb.extent * 2 + obb.extent * 2) * (aabb.position.y - obb.position.y) + local hx = (aabb.extent * 2 + obb.extent * 2) * (aabb.position.x - obb.position.x) - if wy > hx then - if wy > -hx then - return vec3(mat4.mul_mat4x1(obb.rotation, { 0, -1, 0, 1 })) + if wy.x > hx.x and wy.y > hx.y and wy.z > hx.z then + if wy.x > -hx.x and wy.y > -hx.y and wy.z > -hx.z then + return vec3(mat4.mul_vec4({}, obb.rotation, { 0, -1, 0, 1 })) else - return vec3(mat4.mul_mat4x1(obb.rotation, { -1, 0, 0, 1 })) + return vec3(mat4.mul_vec4({}, obb.rotation, { -1, 0, 0, 1 })) end else - if wy > -hx then - return vec3(mat4.mul_mat4x1(obb.rotation, { 1, 0, 0, 1 })) + if wy.x > -hx.x and wy.y > -hx.y and wy.z > -hx.z then + return vec3(mat4.mul_vec4({}, obb.rotation, { 1, 0, 0, 1 })) else - return vec3(mat4.mul_mat4x1(obb.rotation, { 0, 1, 0, 1 })) + return vec3(mat4.mul_vec4({}, obb.rotation, { 0, 1, 0, 1 })) end end end diff --git a/spec/intersect_spec.lua b/spec/intersect_spec.lua index 06bab87..5569a79 100644 --- a/spec/intersect_spec.lua +++ b/spec/intersect_spec.lua @@ -1,5 +1,6 @@ local intersect = require "modules.intersect" local vec3 = require "modules.vec3" +local mat4 = require "modules.mat4" describe("intersect:", function() it("intersects a point with a triangle", function() @@ -148,11 +149,29 @@ describe("intersect:", function() assert.is_true(intersect.aabb_aabb(a, c)) assert.is_not_true(intersect.aabb_aabb(b, c)) end) - --[[ - it("intersects an aabb with an obb", function() + it("intersects an aabb with an obb", function() + local r = mat4() + r:rotate(r, math.pi / 4, vec3.unit_z) + + local a = { + position = vec3(), + extent = vec3(0.5) + } + local b = { + position = vec3(), + extent = vec3(0.5), + rotation = r + } + local c = { + position = vec3(0, 0, 2), + extent = vec3(0.5), + rotation = r + } + assert.is_true(vec3.is_vec3(intersect.aabb_obb(a, b))) + assert.is_not_true(intersect.aabb_obb(a, c)) end) - --]] + it("intersects an aabb with a sphere", function() local a = { min = vec3(-1),