mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-22 03:51:26 +00:00
Remove use of DelauneyTriangulator
This commit is contained in:
parent
ee272c7ee8
commit
8e6c4b98ec
2 changed files with 55 additions and 20 deletions
|
@ -1,11 +1,16 @@
|
||||||
#include "surfaceclip.h"
|
#include "surfaceclip.h"
|
||||||
|
|
||||||
typedef DelauneyTriangulator::Vertex DTVertex;
|
inline bool PointOnSide(const vec2& p, const vec2& v1, const vec2& v2, float tolerance)
|
||||||
|
|
||||||
inline bool PointOnSide(const vec2& p, const DTVertex& v1, const DTVertex& v2, float tolerance)
|
|
||||||
{
|
{
|
||||||
vec2 p2 = p - normalize(vec2(-(v2.y - v1.y), v2.x - v1.x)) * tolerance;
|
vec2 p2 = p + normalize(vec2(-(v2.y - v1.y), v2.x - v1.x)) * tolerance;
|
||||||
return (p2.y - v1.y) * (v2.x - v1.x) + (v1.x - p2.x) * (v2.y - v1.y) <= 0;
|
return (p2.y - v1.y) * (v2.x - v1.x) + (v1.x - p2.x) * (v2.y - v1.y) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool PointBeyondSide(const vec2& p, const vec2& v1, const vec2& v2)
|
||||||
|
{
|
||||||
|
vec2 p2 = p - normalize(vec2(-(v2.y - v1.y), v2.x - v1.x)); // What a hack!
|
||||||
|
return (p2.y - v1.y) * (v2.x - v1.x) + (v1.x - p2.x) * (v2.y - v1.y) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceClip::SurfaceClip(Surface* surface)
|
SurfaceClip::SurfaceClip(Surface* surface)
|
||||||
|
@ -28,15 +33,15 @@ SurfaceClip::SurfaceClip(Surface* surface)
|
||||||
mat3 inverseProjection = mat3::inverse(base);
|
mat3 inverseProjection = mat3::inverse(base);
|
||||||
|
|
||||||
// Transform vertices to XY and triangulate
|
// Transform vertices to XY and triangulate
|
||||||
triangulator.vertices.reserve(surface->verts.size());
|
vertices.reserve(surface->verts.size());
|
||||||
|
|
||||||
for (const auto& vertex : surface->verts)
|
for (const auto& vertex : surface->verts)
|
||||||
{
|
{
|
||||||
auto flattenedVertex = inverseProjection * vertex;
|
auto flattenedVertex = inverseProjection * vertex;
|
||||||
|
|
||||||
triangulator.vertices.emplace_back(flattenedVertex.x, flattenedVertex.y, nullptr);
|
vertices.emplace_back(flattenedVertex.x, flattenedVertex.y);
|
||||||
|
|
||||||
if (triangulator.vertices.empty())
|
if (vertices.empty())
|
||||||
{
|
{
|
||||||
bounds = BBox(flattenedVertex, flattenedVertex);
|
bounds = BBox(flattenedVertex, flattenedVertex);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +51,34 @@ SurfaceClip::SurfaceClip(Surface* surface)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
triangulator.triangulate();
|
// Walls have "Z" like pattern for vertices
|
||||||
|
if (surface->type != ST_CEILING && surface->type != ST_FLOOR)
|
||||||
|
{
|
||||||
|
if (vertices.size() == 4)
|
||||||
|
{
|
||||||
|
std::swap(vertices[vertices.size() - 2], vertices[vertices.size() - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto isConvex = [&]() {
|
||||||
|
for (size_t i = 2; i < vertices.size(); ++i)
|
||||||
|
{
|
||||||
|
if (!PointBeyondSide(vertices[i - 1], vertices[i - 2], vertices[i]))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PointBeyondSide(vertices[vertices.size() - 1], vertices[vertices.size() - 2], vertices[0]) && PointBeyondSide(vertices[0], vertices[vertices.size() - 1], vertices[1]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fix vertex order
|
||||||
|
if (!isConvex())
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < vertices.size() / 2; ++i)
|
||||||
|
{
|
||||||
|
std::swap(vertices[i], vertices[vertices.size() - 1 - i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Init misc. variables
|
// Init misc. variables
|
||||||
boundsWidth = bounds.max.x - bounds.min.x;
|
boundsWidth = bounds.max.x - bounds.min.x;
|
||||||
|
@ -58,18 +90,19 @@ SurfaceClip::SurfaceClip(Surface* surface)
|
||||||
tolerance = (offsetH > offsetW ? offsetH : offsetW) * 2.0f;
|
tolerance = (offsetH > offsetW ? offsetH : offsetW) * 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SurfaceClip::SampleIsInBounds(float x, float y) const
|
bool SurfaceClip::PointInBounds(const vec2& p, float tolerance) const
|
||||||
{
|
{
|
||||||
const vec2 p = vec2((x / float(sampleWidth)) * boundsWidth + bounds.min.x + offsetW, (y / float(sampleHeight)) * boundsHeight + bounds.min.y + offsetH);
|
for (size_t i = 1; i < vertices.size(); ++i)
|
||||||
|
|
||||||
for (const auto& triangle : triangulator.triangles)
|
|
||||||
{
|
{
|
||||||
if (PointOnSide(p, *triangle.A, *triangle.B, tolerance)
|
if (!PointOnSide(p, vertices[i - 1], vertices[i], tolerance))
|
||||||
&& PointOnSide(p, *triangle.B, *triangle.C, tolerance)
|
|
||||||
&& PointOnSide(p, *triangle.C, *triangle.A, tolerance))
|
|
||||||
{
|
{
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return PointOnSide(p, vertices[vertices.size() - 1], vertices[0], tolerance);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SurfaceClip::SampleIsInBounds(float x, float y) const
|
||||||
|
{
|
||||||
|
return PointInBounds(vec2((x / float(sampleWidth)) * boundsWidth + bounds.min.x + offsetW, (y / float(sampleHeight)) * boundsHeight + bounds.min.y + offsetH), tolerance);
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
class SurfaceClip
|
class SurfaceClip
|
||||||
{
|
{
|
||||||
DelauneyTriangulator triangulator;
|
std::vector<vec2> vertices;
|
||||||
|
|
||||||
float sampleWidth;
|
float sampleWidth;
|
||||||
float sampleHeight;
|
float sampleHeight;
|
||||||
|
@ -18,9 +18,11 @@ class SurfaceClip
|
||||||
float offsetH;
|
float offsetH;
|
||||||
float tolerance;
|
float tolerance;
|
||||||
|
|
||||||
|
// Local space
|
||||||
|
bool PointInBounds(const vec2& p, float tolerance) const;
|
||||||
public:
|
public:
|
||||||
SurfaceClip(Surface* surface);
|
SurfaceClip(Surface* surface);
|
||||||
|
|
||||||
// Tolerates points close enough to the surface to avoid missing used samples
|
// Task XY space. Tolerates points close enough to the surface to avoid missing used samples
|
||||||
bool SampleIsInBounds(float x, float y) const;
|
bool SampleIsInBounds(float x, float y) const;
|
||||||
};
|
};
|
Loading…
Reference in a new issue