Deduplicate code
This commit is contained in:
@@ -52,6 +52,12 @@ namespace OpenVulkano::Math
|
|||||||
}
|
}
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr void SortPair(T& e1, T& e2)
|
||||||
|
{
|
||||||
|
if (e1 > e2) std::swap(e1, e2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> using Matrix2_SIMD = glm::tmat2x2<T, glm::aligned>;
|
template<typename T> using Matrix2_SIMD = glm::tmat2x2<T, glm::aligned>;
|
||||||
|
|||||||
@@ -11,11 +11,8 @@ namespace
|
|||||||
{
|
{
|
||||||
int SolveQuadraticEquation(float a, float b, float c, float& x0, float& x1)
|
int SolveQuadraticEquation(float a, float b, float c, float& x0, float& x1)
|
||||||
{
|
{
|
||||||
float discr = b * b - 4 * a * c;
|
const float discr = b * b - 4 * a * c;
|
||||||
if (discr < 0)
|
if (discr < 0) return 0;
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (discr == 0)
|
if (discr == 0)
|
||||||
{
|
{
|
||||||
x0 = x1 = (-b) / (2 * a);
|
x0 = x1 = (-b) / (2 * a);
|
||||||
@@ -24,10 +21,7 @@ namespace
|
|||||||
float q = (b > 0) ? -0.5 * (b + std::sqrt(discr)) : -0.5 * (b - std::sqrt(discr));
|
float q = (b > 0) ? -0.5 * (b + std::sqrt(discr)) : -0.5 * (b - std::sqrt(discr));
|
||||||
x0 = q / a;
|
x0 = q / a;
|
||||||
x1 = c / q;
|
x1 = c / q;
|
||||||
if (x0 > x1)
|
OpenVulkano::Math::Utils::SortPair(x0, x1);
|
||||||
{
|
|
||||||
std::swap(x0, x1);
|
|
||||||
}
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -50,10 +44,10 @@ namespace OpenVulkano::Scene
|
|||||||
std::optional<RayHit> Ray::IntersectTriangle(const Math::Vector3f& v0, const Math::Vector3f& v1,
|
std::optional<RayHit> Ray::IntersectTriangle(const Math::Vector3f& v0, const Math::Vector3f& v1,
|
||||||
const Math::Vector3f& v2) const
|
const Math::Vector3f& v2) const
|
||||||
{
|
{
|
||||||
RayHit hitRes;
|
|
||||||
float d;
|
float d;
|
||||||
if (intersectRayTriangle(m_origin, m_dir, v0, v1, v2, m_baryPos, d) && d >= 0)
|
if (intersectRayTriangle(m_origin, m_dir, v0, v1, v2, m_baryPos, d) && d >= 0)
|
||||||
{
|
{
|
||||||
|
RayHit hitRes;
|
||||||
hitRes.point = (1.f - m_baryPos.x - m_baryPos.y) * v0 + m_baryPos.x * v1 + m_baryPos.y * v2;
|
hitRes.point = (1.f - m_baryPos.x - m_baryPos.y) * v0 + m_baryPos.x * v1 + m_baryPos.y * v2;
|
||||||
Math::Vector3f e = v1 - v0;
|
Math::Vector3f e = v1 - v0;
|
||||||
Math::Vector3f e2 = v2 - v0;
|
Math::Vector3f e2 = v2 - v0;
|
||||||
@@ -81,11 +75,11 @@ namespace OpenVulkano::Scene
|
|||||||
std::optional<RayHit> Ray::IntersectQuad(const Math::Vector3f& v0, const Math::Vector3f& v1,
|
std::optional<RayHit> Ray::IntersectQuad(const Math::Vector3f& v0, const Math::Vector3f& v1,
|
||||||
const Math::Vector3f& v2, const Math::Vector3f& v3) const
|
const Math::Vector3f& v2, const Math::Vector3f& v3) const
|
||||||
{
|
{
|
||||||
if (auto hitRes = IntersectTriangle(v0, v1, v2))
|
if (const auto hitRes = IntersectTriangle(v0, v1, v2))
|
||||||
{
|
{
|
||||||
return hitRes;
|
return hitRes;
|
||||||
}
|
}
|
||||||
if (auto hitRes = IntersectTriangle(v0, v2, v3))
|
if (const auto hitRes = IntersectTriangle(v0, v2, v3))
|
||||||
{
|
{
|
||||||
return hitRes;
|
return hitRes;
|
||||||
}
|
}
|
||||||
@@ -102,13 +96,8 @@ namespace OpenVulkano::Scene
|
|||||||
{
|
{
|
||||||
RayHit h1, h2;
|
RayHit h1, h2;
|
||||||
const int intersections = this->IntersectAABB(bbox, h1, h2);
|
const int intersections = this->IntersectAABB(bbox, h1, h2);
|
||||||
switch (intersections)
|
if (intersections == 1) return h1;
|
||||||
{
|
if (intersections == 2) return (h1.distance2 < h2.distance2) ? h1 : h2;
|
||||||
case 1:
|
|
||||||
return h1;
|
|
||||||
case 2:
|
|
||||||
return (h1.distance2 < h2.distance2) ? h1 : h2;
|
|
||||||
}
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,18 +106,11 @@ namespace OpenVulkano::Scene
|
|||||||
auto tmin = (bbox.min - m_origin) / m_dir;
|
auto tmin = (bbox.min - m_origin) / m_dir;
|
||||||
auto tmax = (bbox.max - m_origin) / m_dir;
|
auto tmax = (bbox.max - m_origin) / m_dir;
|
||||||
|
|
||||||
if (tmin.x > tmax.x)
|
SortPair(tmin.x, tmax.x);
|
||||||
{
|
SortPair(tmin.y, tmax.y);
|
||||||
std::swap(tmin.x, tmax.x);
|
SortPair(tmin.z, tmax.z);
|
||||||
}
|
|
||||||
if (tmin.y > tmax.y)
|
if ((tmin.x > tmax.y) || (tmin.y > tmax.x)) return 0;
|
||||||
{
|
|
||||||
std::swap(tmin.y, tmax.y);
|
|
||||||
}
|
|
||||||
if ((tmin.x > tmax.y) || (tmin.y > tmax.x))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tmin.y > tmin.x)
|
if (tmin.y > tmin.x)
|
||||||
{
|
{
|
||||||
@@ -139,15 +121,7 @@ namespace OpenVulkano::Scene
|
|||||||
tmax.x = tmax.y;
|
tmax.x = tmax.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmin.z > tmax.z)
|
if ((tmin.x > tmax.z) || (tmin.z > tmax.x)) return 0;
|
||||||
{
|
|
||||||
std::swap(tmin.z, tmax.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((tmin.x > tmax.z) || (tmin.z > tmax.x))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tmin.z > tmin.x)
|
if (tmin.z > tmin.x)
|
||||||
{
|
{
|
||||||
@@ -161,10 +135,7 @@ namespace OpenVulkano::Scene
|
|||||||
int intersections = 2;
|
int intersections = 2;
|
||||||
if (tmin.x < 0)
|
if (tmin.x < 0)
|
||||||
{
|
{
|
||||||
if (tmax.x < 0)
|
if (tmax.x < 0) return 0;
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
intersections--;
|
intersections--;
|
||||||
tmin.x = tmax.x;
|
tmin.x = tmax.x;
|
||||||
}
|
}
|
||||||
@@ -197,39 +168,19 @@ namespace OpenVulkano::Scene
|
|||||||
float x1, x2;
|
float x1, x2;
|
||||||
int roots = ::SolveQuadraticEquation(a, b, c, x1, x2);
|
int roots = ::SolveQuadraticEquation(a, b, c, x1, x2);
|
||||||
|
|
||||||
if (roots == 0)
|
if (roots == 0) return 0;
|
||||||
{
|
SortPair(x1, x2);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (x1 > x2)
|
|
||||||
{
|
|
||||||
std::swap(x1, x2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (roots == 1)
|
if (roots == 1)
|
||||||
{
|
{
|
||||||
// ray intersects sphere behind the origin
|
if (x1 < 0) return 0; // ray intersects sphere behind the origin
|
||||||
if (x1 < 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
p1.point = m_origin + x1 * m_dir;
|
|
||||||
p1.distance2 = distance2(m_origin, p1.point);
|
|
||||||
p1.normal = normalize(p1.point - center);
|
|
||||||
p2 = p1;
|
p2 = p1;
|
||||||
}
|
}
|
||||||
else if (roots == 2)
|
else
|
||||||
{
|
{
|
||||||
// ray intersects sphere behind the origin
|
if (x1 < 0 && x2 < 0) return 0; // ray intersects sphere behind the origin
|
||||||
if (x1 < 0 && x2 < 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (x1 >= 0 && x2 >= 0)
|
if (x1 >= 0 && x2 >= 0)
|
||||||
{
|
{
|
||||||
p1.point = m_origin + x1 * m_dir;
|
|
||||||
p1.distance2 = distance2(m_origin, p1.point);
|
|
||||||
p1.normal = normalize(p1.point - center);
|
|
||||||
p2.point = m_origin + x2 * m_dir;
|
p2.point = m_origin + x2 * m_dir;
|
||||||
p2.distance2 = distance2(m_origin, p2.point);
|
p2.distance2 = distance2(m_origin, p2.point);
|
||||||
p2.normal = normalize(p2.point - center);
|
p2.normal = normalize(p2.point - center);
|
||||||
@@ -237,16 +188,13 @@ namespace OpenVulkano::Scene
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
--roots;
|
--roots;
|
||||||
if (x1 < 0)
|
if (x1 < 0) x1 = x2;
|
||||||
{
|
p2 = p1;
|
||||||
x1 = x2;
|
}
|
||||||
}
|
}
|
||||||
p1.point = m_origin + x1 * m_dir;
|
p1.point = m_origin + x1 * m_dir;
|
||||||
p1.distance2 = distance2(m_origin, p1.point);
|
p1.distance2 = distance2(m_origin, p1.point);
|
||||||
p1.normal = normalize(p1.point - center);
|
p1.normal = normalize(p1.point - center);
|
||||||
p2 = p1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return roots;
|
return roots;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user