Move renders into folders
This commit is contained in:
parent
e27702481d
commit
2659090e1c
65 changed files with 147 additions and 137 deletions
235
src/polyrenderer/math/poly_intersection.cpp
Normal file
235
src/polyrenderer/math/poly_intersection.cpp
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
** Various 3D intersection tests
|
||||
** Copyright (c) 1997-2015 The UICore Team
|
||||
**
|
||||
** This software is provided 'as-is', without any express or implied
|
||||
** warranty. In no event will the authors be held liable for any damages
|
||||
** arising from the use of this software.
|
||||
**
|
||||
** Permission is granted to anyone to use this software for any purpose,
|
||||
** including commercial applications, and to alter it and redistribute it
|
||||
** freely, subject to the following restrictions:
|
||||
**
|
||||
** 1. The origin of this software must not be misrepresented; you must not
|
||||
** claim that you wrote the original software. If you use this software
|
||||
** in a product, an acknowledgment in the product documentation would be
|
||||
** appreciated but is not required.
|
||||
** 2. Altered source versions must be plainly marked as such, and must not be
|
||||
** misrepresented as being the original software.
|
||||
** 3. This notice may not be removed or altered from any source distribution.
|
||||
**
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "templates.h"
|
||||
#include "doomdef.h"
|
||||
#include "poly_intersection.h"
|
||||
|
||||
IntersectionTest::Result IntersectionTest::plane_aabb(const Vec4f &plane, const AxisAlignedBoundingBox &aabb)
|
||||
{
|
||||
Vec3f center = aabb.center();
|
||||
Vec3f extents = aabb.extents();
|
||||
float e = extents.x * std::abs(plane.x) + extents.y * std::abs(plane.y) + extents.z * std::abs(plane.z);
|
||||
float s = center.x * plane.x + center.y * plane.y + center.z * plane.z + plane.w;
|
||||
if (s - e > 0)
|
||||
return inside;
|
||||
else if (s + e < 0)
|
||||
return outside;
|
||||
else
|
||||
return intersecting;
|
||||
}
|
||||
|
||||
IntersectionTest::Result IntersectionTest::plane_obb(const Vec4f &plane, const OrientedBoundingBox &obb)
|
||||
{
|
||||
Vec3f n(plane);
|
||||
float d = plane.w;
|
||||
float e = obb.extents.x * std::abs(Vec3f::dot(obb.axis_x, n)) + obb.extents.y * std::abs(Vec3f::dot(obb.axis_y, n)) + obb.extents.z * std::abs(Vec3f::dot(obb.axis_z, n));
|
||||
float s = Vec3f::dot(obb.center, n) + d;
|
||||
if (s - e > 0)
|
||||
return inside;
|
||||
else if (s + e < 0)
|
||||
return outside;
|
||||
else
|
||||
return intersecting;
|
||||
}
|
||||
|
||||
IntersectionTest::OverlapResult IntersectionTest::sphere(const Vec3f ¢er1, float radius1, const Vec3f ¢er2, float radius2)
|
||||
{
|
||||
Vec3f h = center1 - center2;
|
||||
float square_distance = Vec3f::dot(h, h);
|
||||
float radius_sum = radius1 + radius2;
|
||||
if (square_distance > radius_sum * radius_sum)
|
||||
return disjoint;
|
||||
else
|
||||
return overlap;
|
||||
}
|
||||
|
||||
IntersectionTest::OverlapResult IntersectionTest::sphere_aabb(const Vec3f ¢er, float radius, const AxisAlignedBoundingBox &aabb)
|
||||
{
|
||||
Vec3f a = aabb.aabb_min - center;
|
||||
Vec3f b = center - aabb.aabb_max;
|
||||
a.x = std::max(a.x, 0.0f);
|
||||
a.y = std::max(a.y, 0.0f);
|
||||
a.z = std::max(a.z, 0.0f);
|
||||
b.x = std::max(b.x, 0.0f);
|
||||
b.y = std::max(b.y, 0.0f);
|
||||
b.z = std::max(b.z, 0.0f);
|
||||
Vec3f e = a + b;
|
||||
float d = Vec3f::dot(e, e);
|
||||
if (d > radius * radius)
|
||||
return disjoint;
|
||||
else
|
||||
return overlap;
|
||||
}
|
||||
|
||||
IntersectionTest::OverlapResult IntersectionTest::aabb(const AxisAlignedBoundingBox &a, const AxisAlignedBoundingBox &b)
|
||||
{
|
||||
if (a.aabb_min.x > b.aabb_max.x || b.aabb_min.x > a.aabb_max.x ||
|
||||
a.aabb_min.y > b.aabb_max.y || b.aabb_min.y > a.aabb_max.y ||
|
||||
a.aabb_min.z > b.aabb_max.z || b.aabb_min.z > a.aabb_max.z)
|
||||
{
|
||||
return disjoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
return overlap;
|
||||
}
|
||||
}
|
||||
|
||||
IntersectionTest::Result IntersectionTest::frustum_aabb(const FrustumPlanes &frustum, const AxisAlignedBoundingBox &box)
|
||||
{
|
||||
bool is_intersecting = false;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
Result result = plane_aabb(frustum.planes[i], box);
|
||||
if (result == outside)
|
||||
return outside;
|
||||
else if (result == intersecting)
|
||||
is_intersecting = true;
|
||||
break;
|
||||
}
|
||||
if (is_intersecting)
|
||||
return intersecting;
|
||||
else
|
||||
return inside;
|
||||
}
|
||||
|
||||
IntersectionTest::Result IntersectionTest::frustum_obb(const FrustumPlanes &frustum, const OrientedBoundingBox &box)
|
||||
{
|
||||
bool is_intersecting = false;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
Result result = plane_obb(frustum.planes[i], box);
|
||||
if (result == outside)
|
||||
return outside;
|
||||
else if (result == intersecting)
|
||||
is_intersecting = true;
|
||||
}
|
||||
if (is_intersecting)
|
||||
return intersecting;
|
||||
else
|
||||
return inside;
|
||||
}
|
||||
|
||||
IntersectionTest::OverlapResult IntersectionTest::ray_aabb(const Vec3f &ray_start, const Vec3f &ray_end, const AxisAlignedBoundingBox &aabb)
|
||||
{
|
||||
Vec3f c = (ray_start + ray_end) * 0.5f;
|
||||
Vec3f w = ray_end - c;
|
||||
Vec3f h = aabb.extents();
|
||||
|
||||
c -= aabb.center();
|
||||
|
||||
Vec3f v(std::abs(w.x), std::abs(w.y), std::abs(w.z));
|
||||
|
||||
if (std::abs(c.x) > v.x + h.x || std::abs(c.y) > v.y + h.y || std::abs(c.z) > v.z + h.z)
|
||||
return disjoint;
|
||||
|
||||
if (std::abs(c.y * w.z - c.z * w.y) > h.y * v.z + h.z * v.y ||
|
||||
std::abs(c.x * w.z - c.z * w.x) > h.x * v.z + h.z * v.x ||
|
||||
std::abs(c.x * w.y - c.y * w.x) > h.x * v.y + h.y * v.x)
|
||||
return disjoint;
|
||||
|
||||
return overlap;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FrustumPlanes::FrustumPlanes()
|
||||
{
|
||||
}
|
||||
|
||||
FrustumPlanes::FrustumPlanes(const Mat4f &world_to_projection)
|
||||
{
|
||||
planes[0] = near_frustum_plane(world_to_projection);
|
||||
planes[1] = far_frustum_plane(world_to_projection);
|
||||
planes[2] = left_frustum_plane(world_to_projection);
|
||||
planes[3] = right_frustum_plane(world_to_projection);
|
||||
planes[4] = top_frustum_plane(world_to_projection);
|
||||
planes[5] = bottom_frustum_plane(world_to_projection);
|
||||
}
|
||||
|
||||
Vec4f FrustumPlanes::left_frustum_plane(const Mat4f &m)
|
||||
{
|
||||
Vec4f plane(
|
||||
m.matrix[3 + 0 * 4] + m.matrix[0 + 0 * 4],
|
||||
m.matrix[3 + 1 * 4] + m.matrix[0 + 1 * 4],
|
||||
m.matrix[3 + 2 * 4] + m.matrix[0 + 2 * 4],
|
||||
m.matrix[3 + 3 * 4] + m.matrix[0 + 3 * 4]);
|
||||
plane /= plane.length3();
|
||||
return plane;
|
||||
}
|
||||
|
||||
Vec4f FrustumPlanes::right_frustum_plane(const Mat4f &m)
|
||||
{
|
||||
Vec4f plane(
|
||||
m.matrix[3 + 0 * 4] - m.matrix[0 + 0 * 4],
|
||||
m.matrix[3 + 1 * 4] - m.matrix[0 + 1 * 4],
|
||||
m.matrix[3 + 2 * 4] - m.matrix[0 + 2 * 4],
|
||||
m.matrix[3 + 3 * 4] - m.matrix[0 + 3 * 4]);
|
||||
plane /= plane.length3();
|
||||
return plane;
|
||||
}
|
||||
|
||||
Vec4f FrustumPlanes::top_frustum_plane(const Mat4f &m)
|
||||
{
|
||||
Vec4f plane(
|
||||
m.matrix[3 + 0 * 4] - m.matrix[1 + 0 * 4],
|
||||
m.matrix[3 + 1 * 4] - m.matrix[1 + 1 * 4],
|
||||
m.matrix[3 + 2 * 4] - m.matrix[1 + 2 * 4],
|
||||
m.matrix[3 + 3 * 4] - m.matrix[1 + 3 * 4]);
|
||||
plane /= plane.length3();
|
||||
return plane;
|
||||
}
|
||||
|
||||
Vec4f FrustumPlanes::bottom_frustum_plane(const Mat4f &m)
|
||||
{
|
||||
Vec4f plane(
|
||||
m.matrix[3 + 0 * 4] + m.matrix[1 + 0 * 4],
|
||||
m.matrix[3 + 1 * 4] + m.matrix[1 + 1 * 4],
|
||||
m.matrix[3 + 2 * 4] + m.matrix[1 + 2 * 4],
|
||||
m.matrix[3 + 3 * 4] + m.matrix[1 + 3 * 4]);
|
||||
plane /= plane.length3();
|
||||
return plane;
|
||||
}
|
||||
|
||||
Vec4f FrustumPlanes::near_frustum_plane(const Mat4f &m)
|
||||
{
|
||||
Vec4f plane(
|
||||
m.matrix[3 + 0 * 4] + m.matrix[2 + 0 * 4],
|
||||
m.matrix[3 + 1 * 4] + m.matrix[2 + 1 * 4],
|
||||
m.matrix[3 + 2 * 4] + m.matrix[2 + 2 * 4],
|
||||
m.matrix[3 + 3 * 4] + m.matrix[2 + 3 * 4]);
|
||||
plane /= plane.length3();
|
||||
return plane;
|
||||
}
|
||||
|
||||
Vec4f FrustumPlanes::far_frustum_plane(const Mat4f &m)
|
||||
{
|
||||
Vec4f plane(
|
||||
m.matrix[3 + 0 * 4] - m.matrix[2 + 0 * 4],
|
||||
m.matrix[3 + 1 * 4] - m.matrix[2 + 1 * 4],
|
||||
m.matrix[3 + 2 * 4] - m.matrix[2 + 2 * 4],
|
||||
m.matrix[3 + 3 * 4] - m.matrix[2 + 3 * 4]);
|
||||
plane /= plane.length3();
|
||||
return plane;
|
||||
}
|
||||
179
src/polyrenderer/math/poly_intersection.h
Normal file
179
src/polyrenderer/math/poly_intersection.h
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
** Various 3D intersection tests
|
||||
** Copyright (c) 1997-2015 The UICore Team
|
||||
**
|
||||
** This software is provided 'as-is', without any express or implied
|
||||
** warranty. In no event will the authors be held liable for any damages
|
||||
** arising from the use of this software.
|
||||
**
|
||||
** Permission is granted to anyone to use this software for any purpose,
|
||||
** including commercial applications, and to alter it and redistribute it
|
||||
** freely, subject to the following restrictions:
|
||||
**
|
||||
** 1. The origin of this software must not be misrepresented; you must not
|
||||
** claim that you wrote the original software. If you use this software
|
||||
** in a product, an acknowledgment in the product documentation would be
|
||||
** appreciated but is not required.
|
||||
** 2. Altered source versions must be plainly marked as such, and must not be
|
||||
** misrepresented as being the original software.
|
||||
** 3. This notice may not be removed or altered from any source distribution.
|
||||
**
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "polyrenderer/drawers/poly_triangle.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
class Vec3f;
|
||||
|
||||
class Vec4f
|
||||
{
|
||||
public:
|
||||
Vec4f() = default;
|
||||
Vec4f(const Vec4f &) = default;
|
||||
Vec4f(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
|
||||
Vec4f(float v) : x(v), y(v), z(v), w(v) { }
|
||||
Vec4f(const Vec3f &xyz, float w);
|
||||
|
||||
static float dot(const Vec4f &a, const Vec4f &b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; }
|
||||
static float dot3(const Vec4f &a, const Vec4f &b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
|
||||
float length3() const { return std::sqrt(dot3(*this, *this)); }
|
||||
float magnitude() const { return std::sqrt(dot(*this, *this)); }
|
||||
|
||||
Vec4f &operator+=(const Vec4f &b) { *this = Vec4f(x + b.x, y + b.y, z + b.z, w + b.w); return *this; }
|
||||
Vec4f &operator-=(const Vec4f &b) { *this = Vec4f(x - b.x, y - b.y, z - b.z, w - b.w); return *this; }
|
||||
Vec4f &operator*=(const Vec4f &b) { *this = Vec4f(x * b.x, y * b.y, z * b.z, w * b.w); return *this; }
|
||||
Vec4f &operator/=(const Vec4f &b) { *this = Vec4f(x / b.x, y / b.y, z / b.z, w / b.w); return *this; }
|
||||
Vec4f &operator+=(float b) { *this = Vec4f(x + b, y + b, z + b, w + b); return *this; }
|
||||
Vec4f &operator-=(float b) { *this = Vec4f(x - b, y - b, z - b, w - b); return *this; }
|
||||
Vec4f &operator*=(float b) { *this = Vec4f(x * b, y * b, z * b, w * b); return *this; }
|
||||
Vec4f &operator/=(float b) { *this = Vec4f(x / b, y / b, z / b, w / b); return *this; }
|
||||
|
||||
float x, y, z, w;
|
||||
};
|
||||
|
||||
inline bool operator==(const Vec4f &a, const Vec4f &b) { return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; }
|
||||
inline bool operator!=(const Vec4f &a, const Vec4f &b) { return a.x != b.x || a.y != b.y || a.z != b.z || a.w == b.w; }
|
||||
|
||||
class Vec3f
|
||||
{
|
||||
public:
|
||||
Vec3f() = default;
|
||||
Vec3f(const Vec3f &) = default;
|
||||
Vec3f(const Vec4f &v) : x(v.x), y(v.y), z(v.z) { }
|
||||
Vec3f(float x, float y, float z) : x(x), y(y), z(z) { }
|
||||
Vec3f(float v) : x(v), y(v), z(v) { }
|
||||
|
||||
static float dot(const Vec3f &a, const Vec3f &b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
|
||||
float length() const { return std::sqrt(dot(*this, *this)); }
|
||||
|
||||
Vec3f &operator+=(const Vec3f &b) { *this = Vec3f(x + b.x, y + b.y, z + b.z); return *this; }
|
||||
Vec3f &operator-=(const Vec3f &b) { *this = Vec3f(x - b.x, y - b.y, z - b.z); return *this; }
|
||||
Vec3f &operator*=(const Vec3f &b) { *this = Vec3f(x * b.x, y * b.y, z * b.z); return *this; }
|
||||
Vec3f &operator/=(const Vec3f &b) { *this = Vec3f(x / b.x, y / b.y, z / b.z); return *this; }
|
||||
Vec3f &operator+=(float b) { *this = Vec3f(x + b, y + b, z + b); return *this; }
|
||||
Vec3f &operator-=(float b) { *this = Vec3f(x - b, y - b, z - b); return *this; }
|
||||
Vec3f &operator*=(float b) { *this = Vec3f(x * b, y * b, z * b); return *this; }
|
||||
Vec3f &operator/=(float b) { *this = Vec3f(x / b, y / b, z / b); return *this; }
|
||||
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
inline bool operator==(const Vec3f &a, const Vec3f &b) { return a.x == b.x && a.y == b.y && a.z == b.z; }
|
||||
inline bool operator!=(const Vec3f &a, const Vec3f &b) { return a.x != b.x || a.y != b.y || a.z != b.z; }
|
||||
|
||||
inline Vec3f operator+(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x + b.x, a.y + b.y, a.z + b.z); }
|
||||
inline Vec3f operator-(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x - b.x, a.y - b.y, a.z - b.z); }
|
||||
inline Vec3f operator*(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x * b.x, a.y * b.y, a.z * b.z); }
|
||||
inline Vec3f operator/(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x / b.x, a.y / b.y, a.z / b.z); }
|
||||
|
||||
inline Vec3f operator+(const Vec3f &a, float b) { return Vec3f(a.x + b, a.y + b, a.z + b); }
|
||||
inline Vec3f operator-(const Vec3f &a, float b) { return Vec3f(a.x - b, a.y - b, a.z - b); }
|
||||
inline Vec3f operator*(const Vec3f &a, float b) { return Vec3f(a.x * b, a.y * b, a.z * b); }
|
||||
inline Vec3f operator/(const Vec3f &a, float b) { return Vec3f(a.x / b, a.y / b, a.z / b); }
|
||||
|
||||
inline Vec3f operator+(float a, const Vec3f &b) { return Vec3f(a + b.x, a + b.y, a + b.z); }
|
||||
inline Vec3f operator-(float a, const Vec3f &b) { return Vec3f(a - b.x, a - b.y, a - b.z); }
|
||||
inline Vec3f operator*(float a, const Vec3f &b) { return Vec3f(a * b.x, a * b.y, a * b.z); }
|
||||
inline Vec3f operator/(float a, const Vec3f &b) { return Vec3f(a / b.x, a / b.y, a / b.z); }
|
||||
|
||||
inline Vec4f::Vec4f(const Vec3f &xyz, float w) : x(xyz.x), y(xyz.y), z(xyz.z), w(w) { }
|
||||
|
||||
typedef TriMatrix Mat4f;
|
||||
|
||||
class AxisAlignedBoundingBox
|
||||
{
|
||||
public:
|
||||
AxisAlignedBoundingBox() : aabb_min(), aabb_max() {}
|
||||
AxisAlignedBoundingBox(const Vec3f &aabb_min, const Vec3f &aabb_max) : aabb_min(aabb_min), aabb_max(aabb_max) { }
|
||||
AxisAlignedBoundingBox(const AxisAlignedBoundingBox &aabb, const Vec3f &barycentric_min, const Vec3f &barycentric_max)
|
||||
: aabb_min(mix(aabb.aabb_min, aabb.aabb_max, barycentric_min)), aabb_max(mix(aabb.aabb_min, aabb.aabb_max, barycentric_max)) { }
|
||||
|
||||
Vec3f center() const { return (aabb_max + aabb_min) * 0.5f; }
|
||||
Vec3f extents() const { return (aabb_max - aabb_min) * 0.5f; }
|
||||
|
||||
Vec3f aabb_min;
|
||||
Vec3f aabb_max;
|
||||
|
||||
private:
|
||||
template<typename A, typename B, typename C>
|
||||
inline A mix(A a, B b, C mix)
|
||||
{
|
||||
return a * (C(1) - mix) + b * mix;
|
||||
}
|
||||
};
|
||||
|
||||
class OrientedBoundingBox
|
||||
{
|
||||
public:
|
||||
Vec3f center;
|
||||
Vec3f extents;
|
||||
Vec3f axis_x;
|
||||
Vec3f axis_y;
|
||||
Vec3f axis_z;
|
||||
};
|
||||
|
||||
class FrustumPlanes
|
||||
{
|
||||
public:
|
||||
FrustumPlanes();
|
||||
explicit FrustumPlanes(const Mat4f &world_to_projection);
|
||||
|
||||
Vec4f planes[6];
|
||||
|
||||
private:
|
||||
static Vec4f left_frustum_plane(const Mat4f &matrix);
|
||||
static Vec4f right_frustum_plane(const Mat4f &matrix);
|
||||
static Vec4f top_frustum_plane(const Mat4f &matrix);
|
||||
static Vec4f bottom_frustum_plane(const Mat4f &matrix);
|
||||
static Vec4f near_frustum_plane(const Mat4f &matrix);
|
||||
static Vec4f far_frustum_plane(const Mat4f &matrix);
|
||||
};
|
||||
|
||||
class IntersectionTest
|
||||
{
|
||||
public:
|
||||
enum Result
|
||||
{
|
||||
outside,
|
||||
inside,
|
||||
intersecting,
|
||||
};
|
||||
|
||||
enum OverlapResult
|
||||
{
|
||||
disjoint,
|
||||
overlap
|
||||
};
|
||||
|
||||
static Result plane_aabb(const Vec4f &plane, const AxisAlignedBoundingBox &aabb);
|
||||
static Result plane_obb(const Vec4f &plane, const OrientedBoundingBox &obb);
|
||||
static OverlapResult sphere(const Vec3f ¢er1, float radius1, const Vec3f ¢er2, float radius2);
|
||||
static OverlapResult sphere_aabb(const Vec3f ¢er, float radius, const AxisAlignedBoundingBox &aabb);
|
||||
static OverlapResult aabb(const AxisAlignedBoundingBox &a, const AxisAlignedBoundingBox &b);
|
||||
static Result frustum_aabb(const FrustumPlanes &frustum, const AxisAlignedBoundingBox &box);
|
||||
static Result frustum_obb(const FrustumPlanes &frustum, const OrientedBoundingBox &box);
|
||||
static OverlapResult ray_aabb(const Vec3f &ray_start, const Vec3f &ray_end, const AxisAlignedBoundingBox &box);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue