mirror of
https://github.com/orange-cpp/omath.git
synced 2026-06-08 16:24:35 +00:00
170 lines
7.0 KiB
Lua
170 lines
7.0 KiB
Lua
local function approx(a, b, eps) return math.abs(a - b) < (eps or 1e-4) end
|
|
|
|
local function cube_points()
|
|
return {
|
|
omath.Vec3.new(-1, -1, -1),
|
|
omath.Vec3.new(1, -1, -1),
|
|
omath.Vec3.new(-1, 1, -1),
|
|
omath.Vec3.new(1, 1, -1),
|
|
omath.Vec3.new(-1, -1, 1),
|
|
omath.Vec3.new(1, -1, 1),
|
|
omath.Vec3.new(-1, 1, 1),
|
|
omath.Vec3.new(1, 1, 1),
|
|
}
|
|
end
|
|
|
|
function Collision_Aabb_constructor_and_fields()
|
|
local aabb = omath.primitives.Aabb.new(omath.Vec3.new(-1, -2, -3), omath.Vec3.new(1, 2, 3))
|
|
assert(aabb.min.x == -1 and aabb.max.z == 3)
|
|
aabb.max = omath.Vec3.new(2, 3, 4)
|
|
assert(aabb.max.x == 2 and aabb.max.y == 3 and aabb.max.z == 4)
|
|
end
|
|
|
|
function Collision_Aabb_center_extents()
|
|
local aabb = omath.primitives.Aabb.new(omath.Vec3.new(-1, -2, -3), omath.Vec3.new(3, 6, 9))
|
|
local center = aabb:center()
|
|
local extents = aabb:extents()
|
|
assert(center.x == 1 and center.y == 2 and center.z == 3)
|
|
assert(extents.x == 2 and extents.y == 4 and extents.z == 6)
|
|
end
|
|
|
|
function Collision_Aabb_top_bottom_default_axis()
|
|
local aabb = omath.primitives.Aabb.new(omath.Vec3.new(-1, -2, -3), omath.Vec3.new(3, 6, 9))
|
|
assert(aabb:top().y == 6)
|
|
assert(aabb:bottom().y == -2)
|
|
end
|
|
|
|
function Collision_Aabb_top_bottom_explicit_axis()
|
|
local aabb = omath.primitives.Aabb.new(omath.Vec3.new(-1, -2, -3), omath.Vec3.new(3, 6, 9))
|
|
assert(aabb:top(omath.primitives.UpAxis.X).x == 3)
|
|
assert(aabb:bottom(omath.primitives.UpAxis.Z).z == -3)
|
|
end
|
|
|
|
function Collision_Aabb_is_collide()
|
|
local a = omath.primitives.Aabb.new(omath.Vec3.new(-1, -1, -1), omath.Vec3.new(1, 1, 1))
|
|
local b = omath.primitives.Aabb.new(omath.Vec3.new(0, 0, 0), omath.Vec3.new(2, 2, 2))
|
|
local c = omath.primitives.Aabb.new(omath.Vec3.new(3, 3, 3), omath.Vec3.new(4, 4, 4))
|
|
assert(a:is_collide(b))
|
|
assert(not a:is_collide(c))
|
|
end
|
|
|
|
function Collision_Aabb_as_table()
|
|
local aabb = omath.primitives.Aabb.new(omath.Vec3.new(-1, -2, -3), omath.Vec3.new(1, 2, 3))
|
|
local t = aabb:as_table()
|
|
assert(t.min.x == -1 and t.max.z == 3)
|
|
end
|
|
|
|
function Collision_Obb_constructor_and_vertices()
|
|
local obb = omath.primitives.Obb.new(
|
|
omath.Vec3.new(0, 0, 0),
|
|
omath.Vec3.new(1, 0, 0),
|
|
omath.Vec3.new(0, 1, 0),
|
|
omath.Vec3.new(0, 0, 1),
|
|
omath.Vec3.new(1, 2, 3)
|
|
)
|
|
local vertices = obb:vertices()
|
|
assert(#vertices == 8)
|
|
assert(vertices[1].x == -1 and vertices[1].y == -2 and vertices[1].z == -3)
|
|
assert(vertices[8].x == 1 and vertices[8].y == 2 and vertices[8].z == 3)
|
|
end
|
|
|
|
function Collision_Ray_constructor_and_direction()
|
|
local ray = omath.collision.Ray.new(omath.Vec3.new(1, 2, 3), omath.Vec3.new(4, 6, 3), true)
|
|
local dir = ray:direction_vector()
|
|
local normal = ray:direction_vector_normalized()
|
|
assert(ray.infinite_length)
|
|
assert(dir.x == 3 and dir.y == 4 and dir.z == 0)
|
|
assert(approx(normal:length(), 1))
|
|
end
|
|
|
|
function Collision_LineTracer_triangle_hit()
|
|
local tri = omath.Triangle.new(omath.Vec3.new(0, 0, 0), omath.Vec3.new(2, 0, 0), omath.Vec3.new(0, 2, 0))
|
|
local ray = omath.collision.Ray.new(omath.Vec3.new(0.5, 0.5, -1), omath.Vec3.new(0.5, 0.5, 1))
|
|
local hit = omath.collision.LineTracer.get_ray_hit_point(ray, tri)
|
|
assert(omath.collision.LineTracer.ray_hits_triangle(ray, tri))
|
|
assert(not omath.collision.LineTracer.can_trace_line(ray, tri))
|
|
assert(approx(hit.x, 0.5) and approx(hit.y, 0.5) and approx(hit.z, 0))
|
|
end
|
|
|
|
function Collision_LineTracer_triangle_miss()
|
|
local tri = omath.Triangle.new(omath.Vec3.new(0, 0, 0), omath.Vec3.new(1, 0, 0), omath.Vec3.new(0, 1, 0))
|
|
local ray = omath.collision.Ray.new(omath.Vec3.new(2, 2, -1), omath.Vec3.new(2, 2, 1))
|
|
local hit = omath.collision.LineTracer.get_ray_hit_point(ray, tri)
|
|
assert(not omath.collision.LineTracer.ray_hits_triangle(ray, tri))
|
|
assert(omath.collision.LineTracer.can_trace_line(ray, tri))
|
|
assert(hit == ray["end"])
|
|
end
|
|
|
|
function Collision_LineTracer_aabb_hit()
|
|
local aabb = omath.primitives.Aabb.new(omath.Vec3.new(-1, -1, -1), omath.Vec3.new(1, 1, 1))
|
|
local ray = omath.collision.Ray.new(omath.Vec3.new(0, 0, -3), omath.Vec3.new(0, 0, 3))
|
|
local hit = omath.collision.LineTracer.get_ray_hit_point(ray, aabb)
|
|
assert(omath.collision.LineTracer.ray_hits_aabb(ray, aabb))
|
|
assert(approx(hit.x, 0) and approx(hit.y, 0) and approx(hit.z, -1))
|
|
end
|
|
|
|
function Collision_LineTracer_aabb_miss()
|
|
local aabb = omath.primitives.Aabb.new(omath.Vec3.new(-1, -1, -1), omath.Vec3.new(1, 1, 1))
|
|
local ray = omath.collision.Ray.new(omath.Vec3.new(0, 3, -3), omath.Vec3.new(0, 3, 3))
|
|
local hit = omath.collision.LineTracer.get_ray_hit_point(ray, aabb)
|
|
assert(not omath.collision.LineTracer.ray_hits_aabb(ray, aabb))
|
|
assert(hit == ray["end"])
|
|
end
|
|
|
|
function Collision_LineTracer_obb_hit()
|
|
local obb = omath.primitives.Obb.new(
|
|
omath.Vec3.new(0, 0, 0),
|
|
omath.Vec3.new(1, 0, 0),
|
|
omath.Vec3.new(0, 1, 0),
|
|
omath.Vec3.new(0, 0, 1),
|
|
omath.Vec3.new(1, 1, 1)
|
|
)
|
|
local ray = omath.collision.Ray.new(omath.Vec3.new(0, 0, -3), omath.Vec3.new(0, 0, 3))
|
|
local hit = omath.collision.LineTracer.get_ray_hit_point(ray, obb)
|
|
assert(omath.collision.LineTracer.ray_hits_obb(ray, obb))
|
|
assert(approx(hit.z, -1))
|
|
end
|
|
|
|
function Collision_ConvexCollider_vertices_and_support()
|
|
local collider = omath.collision.ConvexCollider.new(cube_points(), omath.Vec3.new(2, 0, 0))
|
|
assert(collider:vertex_count() == 8)
|
|
assert(#collider:vertices() == 8)
|
|
local support = collider:find_abs_furthest_vertex_position(omath.Vec3.new(1, 0, 0))
|
|
assert(support.x == 3)
|
|
end
|
|
|
|
function Collision_Gjk_support_vertex()
|
|
local a = omath.collision.ConvexCollider.new(cube_points())
|
|
local b = omath.collision.ConvexCollider.new(cube_points())
|
|
local support = omath.collision.gjk_support_vertex(a, b, omath.Vec3.new(1, 0, 0))
|
|
assert(support.x == 2 and support.y == 0 and support.z == 0)
|
|
end
|
|
|
|
function Collision_Gjk_collide_true()
|
|
local a = omath.collision.ConvexCollider.new(cube_points())
|
|
local b = omath.collision.ConvexCollider.new(cube_points(), omath.Vec3.new(1, 0, 0))
|
|
assert(omath.collision.gjk_collide(a, b))
|
|
end
|
|
|
|
function Collision_Gjk_collide_false()
|
|
local a = omath.collision.ConvexCollider.new(cube_points())
|
|
local b = omath.collision.ConvexCollider.new(cube_points(), omath.Vec3.new(5, 0, 0))
|
|
assert(not omath.collision.gjk_collide(a, b))
|
|
end
|
|
|
|
function Collision_Epa_solve_hit()
|
|
local a = omath.collision.ConvexCollider.new(cube_points())
|
|
local b = omath.collision.ConvexCollider.new(cube_points(), omath.Vec3.new(1.5, 0, 0))
|
|
local result = omath.collision.epa_solve(a, b)
|
|
assert(result ~= nil)
|
|
assert(result.depth > 0)
|
|
assert(approx(result.normal:length(), 1))
|
|
assert(approx(result.penetration_vector:length(), result.depth))
|
|
end
|
|
|
|
function Collision_Epa_solve_miss()
|
|
local a = omath.collision.ConvexCollider.new(cube_points())
|
|
local b = omath.collision.ConvexCollider.new(cube_points(), omath.Vec3.new(5, 0, 0))
|
|
assert(omath.collision.epa_solve(a, b) == nil)
|
|
end
|