mirror of https://github.com/mosra/magnum.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
445 lines
21 KiB
445 lines
21 KiB
|
15 years ago
|
/*
|
||
|
|
This file is part of Magnum.
|
||
|
|
|
||
|
8 years ago
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
|
||
|
12 years ago
|
Vladimír Vondruš <mosra@centrum.cz>
|
||
|
10 years ago
|
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
|
||
|
13 years ago
|
|
||
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||
|
|
copy of this software and associated documentation files (the "Software"),
|
||
|
|
to deal in the Software without restriction, including without limitation
|
||
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
||
|
|
Software is furnished to do so, subject to the following conditions:
|
||
|
|
|
||
|
|
The above copyright notice and this permission notice shall be included
|
||
|
|
in all copies or substantial portions of the Software.
|
||
|
|
|
||
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||
|
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||
|
|
DEALINGS IN THE SOFTWARE.
|
||
|
15 years ago
|
*/
|
||
|
|
|
||
|
8 years ago
|
#include <sstream>
|
||
|
12 years ago
|
#include <Corrade/TestSuite/Tester.h>
|
||
|
15 years ago
|
|
||
|
8 years ago
|
#include "Magnum/Math/Intersection.h"
|
||
|
15 years ago
|
|
||
|
8 years ago
|
namespace Magnum { namespace Math { namespace Test {
|
||
|
15 years ago
|
|
||
|
8 years ago
|
using namespace Literals;
|
||
|
|
|
||
|
11 years ago
|
struct IntersectionTest: Corrade::TestSuite::Tester {
|
||
|
|
explicit IntersectionTest();
|
||
|
14 years ago
|
|
||
|
11 years ago
|
void planeLine();
|
||
|
|
void lineLine();
|
||
|
10 years ago
|
|
||
|
10 years ago
|
void pointFrustum();
|
||
|
8 years ago
|
void rangeFrustum();
|
||
|
|
void aabbFrustum();
|
||
|
|
void sphereFrustum();
|
||
|
|
|
||
|
|
void pointCone();
|
||
|
|
void pointDoubleCone();
|
||
|
|
void sphereCone();
|
||
|
|
void sphereConeView();
|
||
|
|
void rangeCone();
|
||
|
|
void aabbCone();
|
||
|
14 years ago
|
};
|
||
|
|
|
||
|
13 years ago
|
typedef Math::Vector2<Float> Vector2;
|
||
|
13 years ago
|
typedef Math::Vector3<Float> Vector3;
|
||
|
8 years ago
|
typedef Math::Vector3<Double> Vector3d;
|
||
|
10 years ago
|
typedef Math::Vector4<Float> Vector4;
|
||
|
8 years ago
|
typedef Math::Matrix4<Float> Matrix4;
|
||
|
|
typedef Math::Matrix4<Double> Matrix4d;
|
||
|
10 years ago
|
typedef Math::Frustum<Float> Frustum;
|
||
|
12 years ago
|
typedef Math::Constants<Float> Constants;
|
||
|
10 years ago
|
typedef Math::Range3D<Float> Range3D;
|
||
|
8 years ago
|
typedef Math::Rad<Float> Rad;
|
||
|
|
typedef Math::Rad<Double> Radd;
|
||
|
15 years ago
|
|
||
|
14 years ago
|
IntersectionTest::IntersectionTest() {
|
||
|
13 years ago
|
addTests({&IntersectionTest::planeLine,
|
||
|
10 years ago
|
&IntersectionTest::lineLine,
|
||
|
10 years ago
|
|
||
|
10 years ago
|
&IntersectionTest::pointFrustum,
|
||
|
8 years ago
|
&IntersectionTest::rangeFrustum,
|
||
|
|
&IntersectionTest::aabbFrustum,
|
||
|
|
&IntersectionTest::sphereFrustum,
|
||
|
|
|
||
|
|
&IntersectionTest::pointCone,
|
||
|
|
&IntersectionTest::pointDoubleCone,
|
||
|
|
&IntersectionTest::sphereCone,
|
||
|
|
&IntersectionTest::sphereConeView,
|
||
|
|
&IntersectionTest::rangeCone,
|
||
|
|
&IntersectionTest::aabbCone});
|
||
|
14 years ago
|
}
|
||
|
|
|
||
|
14 years ago
|
void IntersectionTest::planeLine() {
|
||
|
13 years ago
|
const Vector3 planePosition(-1.0f, 1.0f, 0.5f);
|
||
|
|
const Vector3 planeNormal(0.0f, 0.0f, 1.0f);
|
||
|
14 years ago
|
|
||
|
|
/* Inside line segment */
|
||
|
13 years ago
|
CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal,
|
||
|
|
{0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 2.0f}), 0.75f);
|
||
|
14 years ago
|
|
||
|
|
/* Outside line segment */
|
||
|
13 years ago
|
CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal,
|
||
|
|
{0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}), -0.5f);
|
||
|
14 years ago
|
|
||
|
|
/* Line lies on the plane */
|
||
|
14 years ago
|
CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal,
|
||
|
12 years ago
|
{1.0f, 0.5f, 0.5f}, {-1.0f, 0.5f, 0.0f}), Constants::nan());
|
||
|
14 years ago
|
|
||
|
13 years ago
|
/* Line is parallel to the plane */
|
||
|
|
CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal,
|
||
|
12 years ago
|
{1.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}), -Constants::inf());
|
||
|
15 years ago
|
}
|
||
|
|
|
||
|
13 years ago
|
void IntersectionTest::lineLine() {
|
||
|
|
const Vector2 p(-1.0f, -1.0f);
|
||
|
|
const Vector2 r(1.0, 2.0f);
|
||
|
|
|
||
|
|
/* Inside both line segments */
|
||
|
|
CORRADE_COMPARE(Intersection::lineSegmentLineSegment(p, r,
|
||
|
|
{0.0f, 0.0f}, {-1.0f, 0.0f}), std::make_pair(0.5f, 0.5f));
|
||
|
|
CORRADE_COMPARE(Intersection::lineSegmentLine(p, r,
|
||
|
|
{0.0f, 0.0f}, {-1.0f, 0.0f}), 0.5);
|
||
|
|
|
||
|
|
/* Outside both line segments */
|
||
|
|
CORRADE_COMPARE(Intersection::lineSegmentLineSegment(p, r,
|
||
|
|
{0.0f, -2.0f}, {-1.0f, 0.0f}), std::make_pair(-0.5f, 1.5f));
|
||
|
|
CORRADE_COMPARE(Intersection::lineSegmentLine(p, r,
|
||
|
|
{0.0f, -2.0f}, {-1.0f, 0.0f}), -0.5f);
|
||
|
|
|
||
|
|
/* Collinear lines */
|
||
|
|
const auto tu = Intersection::lineSegmentLineSegment(p, r,
|
||
|
|
{0.0f, 1.0f}, {-1.0f, -2.0f});
|
||
|
12 years ago
|
CORRADE_COMPARE(tu.first, -Constants::nan());
|
||
|
|
CORRADE_COMPARE(tu.second, -Constants::nan());
|
||
|
13 years ago
|
CORRADE_COMPARE(Intersection::lineSegmentLine(p, r,
|
||
|
12 years ago
|
{0.0f, 1.0f}, {-1.0f, -2.0f}), -Constants::nan());
|
||
|
13 years ago
|
|
||
|
|
/* Parallel lines */
|
||
|
|
CORRADE_COMPARE(Intersection::lineSegmentLineSegment(p, r,
|
||
|
12 years ago
|
{0.0f, 0.0f}, {1.0f, 2.0f}), std::make_pair(Constants::inf(), Constants::inf()));
|
||
|
13 years ago
|
CORRADE_COMPARE(Intersection::lineSegmentLine(p, r,
|
||
|
12 years ago
|
{0.0f, 0.0f}, {1.0f, 2.0f}), Constants::inf());
|
||
|
13 years ago
|
}
|
||
|
|
|
||
|
10 years ago
|
void IntersectionTest::pointFrustum() {
|
||
|
|
const Frustum frustum{
|
||
|
|
{1.0f, 0.0f, 0.0f, 0.0f},
|
||
|
|
{-1.0f, 0.0f, 0.0f, 10.0f},
|
||
|
|
{0.0f, 1.0f, 0.0f, 0.0f},
|
||
|
|
{0.0f, -1.0f, 0.0f, 10.0f},
|
||
|
|
{0.0f, 0.0f, 1.0f, 0.0f},
|
||
|
|
{0.0f, 0.0f, -1.0f, 10.0f}};
|
||
|
|
|
||
|
|
/* Point on edge */
|
||
|
10 years ago
|
CORRADE_VERIFY(Intersection::pointFrustum({}, frustum));
|
||
|
10 years ago
|
/* Point inside */
|
||
|
10 years ago
|
CORRADE_VERIFY(Intersection::pointFrustum({5.0f, 5.0f, 5.0f}, frustum));
|
||
|
10 years ago
|
/* Point outside */
|
||
|
10 years ago
|
CORRADE_VERIFY(!Intersection::pointFrustum({0.0f, 0.0f, 100.0f}, frustum));
|
||
|
10 years ago
|
}
|
||
|
|
|
||
|
8 years ago
|
void IntersectionTest::rangeFrustum() {
|
||
|
10 years ago
|
const Frustum frustum{
|
||
|
|
{1.0f, 0.0f, 0.0f, 0.0f},
|
||
|
8 years ago
|
{-1.0f, 0.0f, 0.0f, 5.0f},
|
||
|
10 years ago
|
{0.0f, 1.0f, 0.0f, 0.0f},
|
||
|
8 years ago
|
{0.0f, -1.0f, 0.0f, 1.0f},
|
||
|
|
{0.0f, 0.0f, 1.0f, 0.0f},
|
||
|
|
{0.0f, 0.0f, -1.0f, 10.0f}};
|
||
|
|
|
||
|
|
/* Fully inside */
|
||
|
|
CORRADE_VERIFY(Intersection::rangeFrustum(Range3D{Vector3{1.0f}, Vector3{2.0f}}, frustum));
|
||
|
|
/* Intersects with exactly one plane each */
|
||
|
|
CORRADE_VERIFY(Intersection::rangeFrustum(Range3D::fromSize({2.4f, -0.1f, 4.9f}, Vector3{0.2f}), frustum));
|
||
|
|
CORRADE_VERIFY(Intersection::rangeFrustum(Range3D::fromSize({2.4f, 0.9f, 4.9f}, Vector3{0.2f}), frustum));
|
||
|
|
CORRADE_VERIFY(Intersection::rangeFrustum(Range3D::fromSize({-0.1f, 0.4f, 4.9f}, Vector3{0.2f}), frustum));
|
||
|
|
CORRADE_VERIFY(Intersection::rangeFrustum(Range3D::fromSize({4.9f, 0.4f, 4.9f}, Vector3{0.2f}), frustum));
|
||
|
|
CORRADE_VERIFY(Intersection::rangeFrustum(Range3D::fromSize({2.4f, 0.4f, -0.1f}, Vector3{0.2f}), frustum));
|
||
|
|
CORRADE_VERIFY(Intersection::rangeFrustum(Range3D::fromSize({2.4f, 0.4f, 9.9f}, Vector3{0.2f}), frustum));
|
||
|
|
/* Bigger than frustum, but still intersects */
|
||
|
|
CORRADE_VERIFY(Intersection::rangeFrustum(Range3D{Vector3{-100.0f}, Vector3{100.0f}}, frustum));
|
||
|
|
/* Outside of frustum */
|
||
|
|
CORRADE_VERIFY(!Intersection::rangeFrustum(Range3D{Vector3{-10.0f}, Vector3{-5.0f}}, frustum));
|
||
|
|
}
|
||
|
|
|
||
|
|
void IntersectionTest::aabbFrustum() {
|
||
|
|
const Frustum frustum{
|
||
|
|
{1.0f, 0.0f, 0.0f, 0.0f},
|
||
|
|
{-1.0f, 0.0f, 0.0f, 5.0f},
|
||
|
|
{0.0f, 1.0f, 0.0f, 0.0f},
|
||
|
|
{0.0f, -1.0f, 0.0f, 1.0f},
|
||
|
10 years ago
|
{0.0f, 0.0f, 1.0f, 0.0f},
|
||
|
|
{0.0f, 0.0f, -1.0f, 10.0f}};
|
||
|
|
|
||
|
8 years ago
|
/* Fully inside */
|
||
|
|
CORRADE_VERIFY(Intersection::aabbFrustum(Vector3{0.0f}, Vector3{1.0f}, frustum));
|
||
|
|
/* Intersects with exactly one plane each */
|
||
|
|
CORRADE_VERIFY(Intersection::aabbFrustum(Vector3{2.5f, 0.0f, 5.0f}, Vector3{0.1f}, frustum));
|
||
|
|
CORRADE_VERIFY(Intersection::aabbFrustum(Vector3{2.5f, 1.0f, 5.0f}, Vector3{0.1f}, frustum));
|
||
|
|
CORRADE_VERIFY(Intersection::aabbFrustum(Vector3{0.0f, 0.5f, 5.0f}, Vector3{0.1f}, frustum));
|
||
|
|
CORRADE_VERIFY(Intersection::aabbFrustum(Vector3{5.0f, 0.5f, 5.0f}, Vector3{0.1f}, frustum));
|
||
|
|
CORRADE_VERIFY(Intersection::aabbFrustum(Vector3{2.5f, 0.5f, 0.0f}, Vector3{0.1f}, frustum));
|
||
|
|
CORRADE_VERIFY(Intersection::aabbFrustum(Vector3{2.5f, 0.5f, 10.0f}, Vector3{0.1f}, frustum));
|
||
|
10 years ago
|
/* Bigger than frustum, but still intersects */
|
||
|
8 years ago
|
CORRADE_VERIFY(Intersection::aabbFrustum(Vector3{0.0f}, Vector3{100.0f}, frustum));
|
||
|
10 years ago
|
/* Outside of frustum */
|
||
|
8 years ago
|
CORRADE_VERIFY(!Intersection::aabbFrustum(Vector3{-7.5f}, Vector3{2.5f}, frustum));
|
||
|
|
}
|
||
|
|
|
||
|
|
void IntersectionTest::sphereFrustum() {
|
||
|
|
const Frustum frustum{
|
||
|
|
{1.0f, 0.0f, 0.0f, 0.0f},
|
||
|
|
{-1.0f, 0.0f, 0.0f, 10.0f},
|
||
|
|
{0.0f, 1.0f, 0.0f, 0.0f},
|
||
|
|
{0.0f, -1.0f, 0.0f, 10.0f},
|
||
|
|
{0.0f, 0.0f, 1.0f, 0.0f},
|
||
|
|
{0.0f, 0.0f, -1.0f, 10.0f}};
|
||
|
|
|
||
|
|
/* Sphere on edge */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereFrustum({0.0f, 0.0f, -1.0f}, 1.5f, frustum));
|
||
|
|
/* Sphere inside */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereFrustum({5.5f, 5.5f, 5.5f}, 1.5f, frustum));
|
||
|
|
/* Sphere outside */
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereFrustum({0.0f, 0.0f, 100.0f}, 0.5f, frustum));
|
||
|
|
}
|
||
|
|
|
||
|
|
void IntersectionTest::pointCone() {
|
||
|
|
const Vector3 center{0.1f, 0.2f, 0.3f};
|
||
|
|
const Vector3 normal{Vector3{0.5f, 1.0f, 2.0f}.normalized()};
|
||
|
|
const Rad angle{72.0_degf};
|
||
|
|
|
||
|
|
const Vector3d centerDouble{1.0, -2.0, 1.3};
|
||
|
|
const Vector3d normalDouble{Vector3{0.5, 1.0, 2.0}.normalized()};
|
||
|
|
const Radd angleDouble{72.0_deg};
|
||
|
|
|
||
|
|
/* Some vector along the surface of the cone */
|
||
|
|
auto axis = Math::cross(Vector3::yAxis(), normal).normalized();
|
||
|
|
auto surface = Matrix4::rotation(0.5f*angle, axis).transformVector(normal);
|
||
|
|
/* Normal on the curved surface */
|
||
|
|
auto sNormal = Matrix4::rotation(90.0_degf, axis).transformVector(surface);
|
||
|
8 years ago
|
/* Same for Double precision */
|
||
|
|
auto axisDouble = Math::cross(Vector3d::yAxis(), normalDouble).normalized();
|
||
|
|
auto surfaceDouble = Matrix4d::rotation(0.5*angleDouble, axisDouble).transformVector(normalDouble);
|
||
|
8 years ago
|
|
||
|
|
/* Point on edge */
|
||
|
|
CORRADE_VERIFY(Intersection::pointCone(center, center, normal, angle));
|
||
|
|
/* Point inside */
|
||
|
|
CORRADE_VERIFY(Intersection::pointCone(center + normal, center, normal, angle));
|
||
|
|
/* Point outside */
|
||
|
|
CORRADE_VERIFY(!Intersection::pointCone(Vector3{}, center, normal, angle));
|
||
|
|
CORRADE_VERIFY(!Intersection::pointCone(center + 5.0f*surface + 0.01f*sNormal, center, normal, angle));
|
||
|
|
/* Point behind the cone plane */
|
||
|
|
CORRADE_VERIFY(!Intersection::pointCone(-normal, center, normal, angle));
|
||
|
8 years ago
|
|
||
|
|
/* Point touching cone */
|
||
|
|
{
|
||
|
|
CORRADE_EXPECT_FAIL("Point touching cone fails, possibly because of precision.");
|
||
|
|
CORRADE_VERIFY(Intersection::pointCone(centerDouble, centerDouble + surfaceDouble, normalDouble, angleDouble));
|
||
|
|
}
|
||
|
8 years ago
|
}
|
||
|
|
|
||
|
|
void IntersectionTest::pointDoubleCone() {
|
||
|
|
const Vector3 center{0.1f, 0.2f, 0.3f};
|
||
|
|
const Vector3 normal{Vector3{0.5f, 1.0f, 2.0f}.normalized()};
|
||
|
|
const Rad angle{72.0_degf};
|
||
|
|
|
||
|
|
/* Some vector along the surface of the cone */
|
||
|
|
auto axis = Math::cross(Vector3::yAxis(), normal).normalized();
|
||
|
|
auto surface = Matrix4::rotation(0.5f*angle, axis).transformVector(normal);
|
||
|
|
/* Normal on the curved surface */
|
||
|
|
auto sNormal = Matrix4::rotation(90.0_degf, axis).transformVector(surface);
|
||
|
|
|
||
|
|
/* Point on edge */
|
||
|
|
CORRADE_VERIFY(Intersection::pointDoubleCone(center, center, normal, angle));
|
||
|
|
/* Point inside */
|
||
|
|
CORRADE_VERIFY(Intersection::pointDoubleCone(center + normal, center, normal, angle));
|
||
|
|
CORRADE_VERIFY(Intersection::pointDoubleCone(center - normal, center, normal, angle));
|
||
|
|
/* Point outside */
|
||
|
|
CORRADE_VERIFY(!Intersection::pointDoubleCone(center + sNormal, center, normal, angle));
|
||
|
|
}
|
||
|
|
|
||
|
|
void IntersectionTest::sphereCone() {
|
||
|
|
const Vector3 center{1.0f, -2.0f, 1.3f};
|
||
|
|
const Vector3 normal{Vector3{0.5f, 1.0f, 2.0f}.normalized()};
|
||
|
|
const Rad angle(72.0_degf);
|
||
|
|
|
||
|
|
/* Same for Double precision */
|
||
|
|
const Vector3d centerDouble{1.0, -2.0, 1.3};
|
||
|
|
const Vector3d normalDouble{Vector3{0.5, 1.0, 2.0}.normalized()};
|
||
|
|
const Radd angleDouble(72.0_deg);
|
||
|
|
|
||
|
|
/* Some vector along the surface of the cone */
|
||
|
|
auto axis = Math::cross(Vector3::yAxis(), normal).normalized();
|
||
|
|
auto surface = Matrix4::rotation(0.5f*angle, axis).transformVector(normal);
|
||
|
|
/* Normal on the curved surface */
|
||
|
|
auto sNormal = Matrix4::rotation(90.0_degf, axis).transformVector(surface);
|
||
|
|
|
||
|
|
/* Same for Double precision */
|
||
|
|
auto axisDouble = Math::cross(Vector3d::yAxis(), normalDouble).normalized();
|
||
|
|
auto surfaceDouble = Matrix4d::rotation(0.5*angleDouble, axisDouble).transformVector(normalDouble);
|
||
|
|
auto sNormalDouble = Matrix4d::rotation(90.0_deg, axisDouble).transformVector(surfaceDouble);
|
||
|
|
|
||
|
|
/* Sphere fully contained in cone */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereCone(center + normal*5.0f, 0.8f, center, normal, angle));
|
||
|
|
/* Sphere fully contained in double side of cone */
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereCone(center + normal*-5.0f, 0.75f, center, normal, angle));
|
||
|
|
/* Sphere fully outside of the cone */
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereCone(center + surface + sNormal*5.0f, 0.75f, center, normal, angle));
|
||
|
|
|
||
|
|
/* Sphere intersecting apex with sphere center behind the cone plane */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereCone(center - normal*0.1f, 0.55f, center, normal, angle));
|
||
|
|
/* Sphere intersecting apex with sphere center in front of the cone plane */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereCone(center + normal*0.1f, 0.55f, center, normal, angle));
|
||
|
|
|
||
|
|
/* Sphere barely touching the surface of the cone, from inside and outside the cone */
|
||
|
|
{
|
||
|
|
#ifndef CORRADE_TARGET_EMSCRIPTEN
|
||
|
|
CORRADE_EXPECT_FAIL("Cone touching from the outside fails, possibly because of precision.");
|
||
|
8 years ago
|
#else
|
||
|
|
CORRADE_EXPECT_FAIL_IF(!Intersection::sphereCone(centerDouble + 4.0*surfaceDouble + sNormalDouble*0.5, 0.5, centerDouble, normalDouble, angleDouble), "Cone touching from the outside fails on optimized Emscripten builds, possibly because of precision.");
|
||
|
8 years ago
|
#endif
|
||
|
|
CORRADE_VERIFY(Intersection::sphereCone(centerDouble + 4.0*surfaceDouble + sNormalDouble*0.5, 0.5, centerDouble, normalDouble, angleDouble));
|
||
|
|
}
|
||
|
|
CORRADE_VERIFY(Intersection::sphereCone(centerDouble + 4.0*surfaceDouble - sNormalDouble*0.5, 0.5, centerDouble, normalDouble, angleDouble));
|
||
|
|
|
||
|
|
/* Same on double side of the cone */
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereCone(center - 4.0f*surface + sNormal*0.5f, 0.5f, center, normal, angle));
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereCone(center - 4.0f*surface - sNormal*0.5f, 0.5f, center, normal, angle));
|
||
|
|
|
||
|
|
/* Sphere clearly, but not fully intersecting the cone */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereCone(center + surface + sNormal*0.25f, 0.5f, center, normal, angle));
|
||
|
|
/* Sphere with center on the cone's surface */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereCone(center + 4.0f*surface, 0.5f, center, normal, angle));
|
||
|
|
|
||
|
|
/* Same as above on double side of the cone */
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereCone(center - surface + sNormal*0.25f, 0.5f, center, normal, angle));
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereCone(center - 4.0f*surface, 0.5f, center, normal, angle));
|
||
|
|
}
|
||
|
|
|
||
|
|
void IntersectionTest::sphereConeView() {
|
||
|
|
const Vector3 center{1.0f, -2.0f, 1.3f};
|
||
|
|
const Vector3 normal{Vector3{0.5f, 1.0f, 2.0f}.normalized()};
|
||
|
|
const Matrix4 coneView = Matrix4::lookAt(center, center + normal, Vector3::yAxis()).invertedRigid();
|
||
|
|
|
||
|
|
const Vector3d centerDouble{1.0, -2.0, 1.3};
|
||
|
|
const Vector3d normalDouble{Vector3{0.5, 1.0, 2.0}.normalized()};
|
||
|
|
const Matrix4d coneViewDouble = Matrix4d::lookAt(centerDouble, centerDouble + normalDouble, Vector3d::yAxis()).invertedRigid();
|
||
|
|
|
||
|
|
const Rad angle(72.0_degf);
|
||
|
|
const Radd angleDouble(72.0_deg);
|
||
|
|
|
||
|
|
/* Some vector along the surface of the cone */
|
||
|
|
auto axis = Math::cross(Vector3::yAxis(), normal).normalized();
|
||
|
|
auto surface = Matrix4::rotation(0.5f*angle, axis).transformVector(normal);
|
||
|
|
/* Normal on the curved surface */
|
||
|
|
auto sNormal = Matrix4::rotation(90.0_degf, axis).transformVector(surface);
|
||
|
|
|
||
|
|
/* Sphere fully contained in cone */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereConeView(center + normal*5.0f, 0.8f, coneView, angle));
|
||
|
|
/* Sphere fully contained in double side of cone */
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereConeView(center + normal*-5.0f, 0.75f, coneView, angle));
|
||
|
|
/* Sphere fully outside of the cone */
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereConeView(center + surface + sNormal*5.0f, 0.75f, coneView, angle));
|
||
|
|
|
||
|
|
/* Sphere intersecting apex with sphere center behind the cone plane */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereConeView(center - normal*0.1f, 0.55f, coneView, angle));
|
||
|
|
/* Sphere intersecting apex with sphere center in front of the cone plane */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereConeView(center + normal*0.1f, 0.55f, coneView, angle));
|
||
|
|
|
||
|
|
/* Sphere barely touching the surface of the cone, from inside and outside the cone
|
||
|
|
Note: behaviour differs from sphereCone! */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereConeView(centerDouble + 4.0*Vector3d(surface) + Vector3d(sNormal)*0.5, 0.5, coneViewDouble, angleDouble));
|
||
|
|
CORRADE_VERIFY(Intersection::sphereConeView(centerDouble + 4.0*Vector3d(surface) - Vector3d(sNormal)*0.5, 0.5, coneViewDouble, angleDouble));
|
||
|
|
/* Same on double side of the cone */
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereConeView(center - 4.0f*surface + sNormal*0.5f, 0.5f, coneView, angle));
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereConeView(center - 4.0f*surface - sNormal*0.5f, 0.5f, coneView, angle));
|
||
|
|
|
||
|
|
/* Sphere clearly, but not fully intersecting the cone */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereConeView(center + surface + sNormal*0.25f, 0.5f, coneView, angle));
|
||
|
|
/* Sphere with center on the cone's surface */
|
||
|
|
CORRADE_VERIFY(Intersection::sphereConeView(center + 4.0f*surface, 0.5f, coneView, angle));
|
||
|
|
|
||
|
|
/* Same as above on double side of the cone */
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereConeView(center - surface + sNormal*0.25f, 0.5f, coneView, angle));
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereConeView(center - 4.0f*surface, 0.5f, coneView, angle));
|
||
|
|
|
||
|
|
std::ostringstream out;
|
||
|
|
Error redirectError{&out};
|
||
|
|
|
||
|
|
CORRADE_VERIFY(!Intersection::sphereConeView(center, 1.0f, Matrix4{ZeroInit}, angle));
|
||
|
8 years ago
|
CORRADE_COMPARE(out.str(), "Math::Geometry::Intersection::sphereConeView(): coneView does not represent a rigid transformation\n");
|
||
|
8 years ago
|
}
|
||
|
|
|
||
|
|
void IntersectionTest::rangeCone() {
|
||
|
|
const Vector3 center{1.0f, -2.0f, 1.3f};
|
||
|
|
const Vector3 normal{0.453154f, 0.422618f, 0.784886f};
|
||
|
|
const Rad angle{72.0_degf};
|
||
|
|
|
||
|
|
/* Box fully inside cone */
|
||
|
8 years ago
|
CORRADE_VERIFY(Intersection::rangeCone(Range3D::fromSize(
|
||
|
|
15.0f*normal - Vector3{1.0f}, Vector3{2.0f}), center, normal, angle));
|
||
|
8 years ago
|
/* Box intersecting cone */
|
||
|
8 years ago
|
CORRADE_VERIFY(Intersection::rangeCone(Range3D::fromSize(
|
||
|
|
5.0f*normal - Vector3{10.0f, 10.0f, 0.5f}, Vector3{20.0f, 20.0f, 1.0f}),
|
||
|
|
center, normal, angle));
|
||
|
|
CORRADE_VERIFY(Intersection::rangeCone(
|
||
|
|
Range3D{{-1.0f, -2.0f, -3.0f}, {1.0f, 2.0f, 3.0f}}, center, normal, angle));
|
||
|
8 years ago
|
/* Cone inside large box */
|
||
|
8 years ago
|
CORRADE_VERIFY(Intersection::rangeCone(Range3D::fromSize(
|
||
|
|
12.0f*normal - Vector3{20.0f}, Vector3{40.0f}), center, normal, angle));
|
||
|
8 years ago
|
/* Same corner chosen on all intersecting faces */
|
||
|
8 years ago
|
CORRADE_VERIFY(Intersection::rangeCone(
|
||
|
|
Range3D{{2.0f, -0.1f, -1.5f}, {3.0f, 0.1f, 1.5f}},
|
||
|
|
center, {0.353553f, 0.707107f, 0.612372f}, angle));
|
||
|
8 years ago
|
|
||
|
|
/* Boxes outside cone */
|
||
|
8 years ago
|
CORRADE_VERIFY(!Intersection::rangeCone(
|
||
|
|
Range3D{Vector3{2.0f, 2.0f, -2.0f}, Vector3{8.0f, 7.0f, 2.0f}},
|
||
|
|
center, normal, angle));
|
||
|
|
CORRADE_VERIFY(!Intersection::rangeCone(
|
||
|
|
Range3D{Vector3{6.0f, 5.0f, -7.0f}, Vector3{5.0f, 9.0f, -3.0f}},
|
||
|
|
center, normal, angle));
|
||
|
8 years ago
|
/* Box fully contained in double cone */
|
||
|
8 years ago
|
CORRADE_VERIFY(!Intersection::rangeCone(
|
||
|
|
Range3D::fromSize(-15.0f*normal - Vector3{1.0f}, Vector3{2.0f}),
|
||
|
|
center, normal, angle));
|
||
|
8 years ago
|
}
|
||
|
|
|
||
|
|
void IntersectionTest::aabbCone() {
|
||
|
|
const Vector3 center{1.0f, -2.0f, 1.3f};
|
||
|
|
const Vector3 normal{0.453154f, 0.422618f, 0.784886f};
|
||
|
|
const Rad angle{72.0_degf};
|
||
|
|
|
||
|
|
/* Box fully inside cone */
|
||
|
|
CORRADE_VERIFY(Intersection::aabbCone(15.0f*normal, Vector3{1.0f}, center, normal, angle));
|
||
|
|
/* Box intersecting cone */
|
||
|
|
CORRADE_VERIFY(Intersection::aabbCone(5.0f*normal, {10.0f, 10.0f, 0.5f}, center, normal, angle));
|
||
|
|
CORRADE_VERIFY(Intersection::aabbCone({}, { 1.0f, 2.0f, 3.0f }, center, normal, angle));
|
||
|
|
/* Cone inside large box */
|
||
|
|
CORRADE_VERIFY(Intersection::aabbCone(12.0f*normal, {20.0f, 20.0f, 20.0f}, center, normal, angle));
|
||
|
|
/* Same corner chosen on all intersecting faces */
|
||
|
|
CORRADE_VERIFY(Intersection::aabbCone({2.5f, 0.0f, 0.0f}, {0.5f, 0.1f, 1.5f}, center, {0.353553f, 0.707107f, 0.612372f}, angle));
|
||
|
|
|
||
|
|
/* Boxes outside cone */
|
||
|
|
CORRADE_VERIFY(!Intersection::aabbCone({5.0f, 5.0f, 0.0f}, {3.0f, 2.0f, 2.0f}, center, normal, angle));
|
||
|
|
CORRADE_VERIFY(!Intersection::aabbCone({8.0f, 7.0f, -5.0f}, {2.0f, 2.0f, 2.0f}, center, normal, angle));
|
||
|
|
/* Box fully contained in double cone */
|
||
|
|
CORRADE_VERIFY(!Intersection::aabbCone(-15.0f*normal, Vector3{1.0f}, center, normal, angle));
|
||
|
10 years ago
|
}
|
||
|
|
|
||
|
8 years ago
|
}}}
|
||
|
14 years ago
|
|
||
|
8 years ago
|
CORRADE_TEST_MAIN(Magnum::Math::Test::IntersectionTest)
|