summaryrefslogtreecommitdiff
path: root/game/geoData.cpp
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2023-11-26 13:51:33 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2023-11-26 14:14:13 +0000
commit7fba471728f2216d7e3b7900297fc3b3531e286c (patch)
tree5caef3b2efc23aefccb215ec9005cd8e7d2e91b8 /game/geoData.cpp
parentFix todo for handling a terrain walk from outside the mesh (diff)
parentModel positions as integers (diff)
downloadilt-7fba471728f2216d7e3b7900297fc3b3531e286c.tar.bz2
ilt-7fba471728f2216d7e3b7900297fc3b3531e286c.tar.xz
ilt-7fba471728f2216d7e3b7900297fc3b3531e286c.zip
Merge branch 'ints' into terrain
Conflicts fix, compiles, some test failures remain. Trees not added, possibility of OM invalid handle assertion failures, normals broken due to integer overflow in Newell's method.
Diffstat (limited to 'game/geoData.cpp')
-rw-r--r--game/geoData.cpp71
1 files changed, 42 insertions, 29 deletions
diff --git a/game/geoData.cpp b/game/geoData.cpp
index 61dedda..7710efe 100644
--- a/game/geoData.cpp
+++ b/game/geoData.cpp
@@ -21,16 +21,20 @@ GeoData::loadFromAsciiGrid(const std::filesystem::path & input)
f >> *properties.at(property);
properties.erase(property);
}
+ xllcorner *= 1000;
+ yllcorner *= 1000;
+ cellsize *= 1000;
std::vector<VertexHandle> vertices;
vertices.reserve(ncols * nrows);
GeoData mesh;
- mesh.lowerExtent = {xllcorner, yllcorner, std::numeric_limits<float>::max()};
+ mesh.lowerExtent = {xllcorner, yllcorner, std::numeric_limits<GlobalDistance>::max()};
mesh.upperExtent = {xllcorner + (cellsize * (ncols - 1)), yllcorner + (cellsize * (nrows - 1)),
- std::numeric_limits<float>::min()};
+ std::numeric_limits<GlobalDistance>::min()};
for (size_t row = 0; row < nrows; ++row) {
for (size_t col = 0; col < ncols; ++col) {
- float height = 0;
- f >> height;
+ float heightf = 0;
+ f >> heightf;
+ const auto height = static_cast<GlobalDistance>(std::round(heightf * 1000.F));
mesh.upperExtent.z = std::max(mesh.upperExtent.z, height);
mesh.lowerExtent.z = std::min(mesh.lowerExtent.z, height);
vertices.push_back(mesh.add_vertex({xllcorner + (col * cellsize), yllcorner + (row * cellsize), height}));
@@ -60,12 +64,12 @@ GeoData::loadFromAsciiGrid(const std::filesystem::path & input)
};
GeoData
-GeoData::createFlat(glm::vec2 lower, glm::vec2 upper, float h)
+GeoData::createFlat(GlobalPosition2D lower, GlobalPosition2D upper, GlobalDistance h)
{
GeoData mesh;
- mesh.lowerExtent = lower ^ h;
- mesh.upperExtent = upper ^ h;
+ mesh.lowerExtent = {lower, h};
+ mesh.upperExtent = {upper, h};
const auto ll = mesh.add_vertex({lower.x, lower.y, h}), lu = mesh.add_vertex({lower.x, upper.y, h}),
ul = mesh.add_vertex({upper.x, lower.y, h}), uu = mesh.add_vertex({upper.x, upper.y, h});
@@ -80,14 +84,17 @@ GeoData::createFlat(glm::vec2 lower, glm::vec2 upper, float h)
}
OpenMesh::FaceHandle
-GeoData::findPoint(glm::vec2 p) const
+GeoData::findPoint(GlobalPosition2D p) const
{
return findPoint(p, *faces_begin());
}
-GeoData::PointFace::PointFace(const glm::vec2 p, const GeoData * mesh) : PointFace {p, mesh, *mesh->faces_begin()} { }
+GeoData::PointFace::PointFace(const GlobalPosition2D p, const GeoData * mesh) :
+ PointFace {p, mesh, *mesh->faces_begin()}
+{
+}
-GeoData::PointFace::PointFace(const glm::vec2 p, const GeoData * mesh, FaceHandle start) :
+GeoData::PointFace::PointFace(const GlobalPosition2D p, const GeoData * mesh, FaceHandle start) :
PointFace {p, mesh->findPoint(p, start)}
{
}
@@ -113,9 +120,9 @@ GeoData::PointFace::face(const GeoData * mesh) const
namespace {
template<template<typename> typename Op>
[[nodiscard]] constexpr inline auto
- pointLineOp(const glm::vec2 p, const glm::vec2 e1, const glm::vec2 e2)
+ pointLineOp(const GlobalPosition2D p, const GlobalPosition2D e1, const GlobalPosition2D e2)
{
- return Op {}((e2.x - e1.x) * (p.y - e1.y), (e2.y - e1.y) * (p.x - e1.x));
+ return Op {}(int64_t(e2.x - e1.x) * int64_t(p.y - e1.y), int64_t(e2.y - e1.y) * int64_t(p.x - e1.x));
}
constexpr auto pointLeftOfLine = pointLineOp<std::greater>;
@@ -125,9 +132,13 @@ namespace {
static_assert(pointLeftOfLine({2, 1}, {2, 2}, {1, 1}));
static_assert(pointLeftOfLine({2, 2}, {1, 2}, {2, 1}));
static_assert(pointLeftOfLine({1, 1}, {2, 1}, {1, 2}));
+ static_assert(pointLeftOfOrOnLine({310000000, 490000000}, {310000000, 490000000}, {310050000, 490050000}));
+ static_assert(pointLeftOfOrOnLine({310000000, 490000000}, {310050000, 490050000}, {310000000, 490050000}));
+ static_assert(pointLeftOfOrOnLine({310000000, 490000000}, {310000000, 490050000}, {310000000, 490000000}));
[[nodiscard]] constexpr inline bool
- linesCross(const glm::vec2 a1, const glm::vec2 a2, const glm::vec2 b1, const glm::vec2 b2)
+ linesCross(
+ const GlobalPosition2D a1, const GlobalPosition2D a2, const GlobalPosition2D b1, const GlobalPosition2D b2)
{
return (pointLeftOfLine(a2, b1, b2) == pointLeftOfLine(a1, b2, b1))
&& (pointLeftOfLine(b1, a1, a2) == pointLeftOfLine(b2, a2, a1));
@@ -137,7 +148,8 @@ namespace {
static_assert(linesCross({2, 2}, {1, 1}, {1, 2}, {2, 1}));
[[nodiscard]] constexpr inline bool
- linesCrossLtR(const glm::vec2 a1, const glm::vec2 a2, const glm::vec2 b1, const glm::vec2 b2)
+ linesCrossLtR(
+ const GlobalPosition2D a1, const GlobalPosition2D a2, const GlobalPosition2D b1, const GlobalPosition2D b2)
{
return pointLeftOfLine(a2, b1, b2) && pointLeftOfLine(a1, b2, b1) && pointLeftOfLine(b1, a1, a2)
&& pointLeftOfLine(b2, a2, a1);
@@ -148,7 +160,7 @@ namespace {
}
OpenMesh::FaceHandle
-GeoData::findPoint(glm::vec2 p, OpenMesh::FaceHandle f) const
+GeoData::findPoint(GlobalPosition2D p, OpenMesh::FaceHandle f) const
{
while (f.is_valid() && !triangleContainsPoint(p, triangle<2>(f))) {
for (auto next = cfh_iter(f); next.is_valid(); ++next) {
@@ -166,30 +178,31 @@ GeoData::findPoint(glm::vec2 p, OpenMesh::FaceHandle f) const
return f;
}
-glm::vec3
+GlobalPosition3D
GeoData::positionAt(const PointFace & p) const
{
- glm::vec3 out {};
+ RelativePosition3D out {};
const auto t = triangle<3>(p.face(this));
- glm::intersectLineTriangle(p.point ^ 0.F, up, t[0], t[1], t[2], out);
- return p.point ^ out[0];
+ glm::intersectLineTriangle<RelativePosition3D>({p.point, 0}, up, t[0], t[1], t[2], out);
+ return {p.point, out[0]};
}
-[[nodiscard]] std::optional<glm::vec3>
+[[nodiscard]] std::optional<GlobalPosition3D>
GeoData::intersectRay(const Ray & ray) const
{
return intersectRay(ray, findPoint(ray.start));
}
-[[nodiscard]] std::optional<glm::vec3>
+[[nodiscard]] std::optional<GlobalPosition3D>
GeoData::intersectRay(const Ray & ray, FaceHandle face) const
{
- std::optional<glm::vec3> out;
+ std::optional<GlobalPosition3D> out;
walkUntil(PointFace {ray.start, face}, ray.start + (ray.direction * 10000.F), [&out, &ray, this](FaceHandle face) {
- glm::vec2 bari {};
+ BaryPosition bari {};
float dist {};
const auto t = triangle<3>(face);
- if (glm::intersectRayTriangle(ray.start, ray.direction, t[0], t[1], t[2], bari, dist)) {
+ if (glm::intersectRayTriangle<RelativePosition3D::value_type, glm::defaultp>(
+ ray.start, ray.direction, t[0], t[1], t[2], bari, dist)) {
out = t * bari;
return true;
}
@@ -199,7 +212,7 @@ GeoData::intersectRay(const Ray & ray, FaceHandle face) const
}
void
-GeoData::walk(const PointFace & from, const glm::vec2 to, const std::function<void(FaceHandle)> & op) const
+GeoData::walk(const PointFace & from, const GlobalPosition2D to, const std::function<void(FaceHandle)> & op) const
{
walkUntil(from, to, [&op](const auto & fh) {
op(fh);
@@ -208,7 +221,7 @@ GeoData::walk(const PointFace & from, const glm::vec2 to, const std::function<vo
}
void
-GeoData::walkUntil(const PointFace & from, const glm::vec2 to, const std::function<bool(FaceHandle)> & op) const
+GeoData::walkUntil(const PointFace & from, const GlobalPosition2D to, const std::function<bool(FaceHandle)> & op) const
{
auto f = from.face(this);
if (!f.is_valid()) {
@@ -269,7 +282,7 @@ GeoData::boundaryWalkUntil(const std::function<bool(HalfedgeHandle)> & op, Halfe
}
GeoData::HalfedgeHandle
-GeoData::findEntry(const glm::vec2 from, const glm::vec2 to) const
+GeoData::findEntry(const GlobalPosition2D from, const GlobalPosition2D to) const
{
HalfedgeHandle entry;
boundaryWalkUntil([this, from, to, &entry](auto he) {
@@ -285,14 +298,14 @@ GeoData::findEntry(const glm::vec2 from, const glm::vec2 to) const
}
bool
-GeoData::triangleContainsPoint(const glm::vec2 p, const Triangle<2> & t)
+GeoData::triangleContainsPoint(const GlobalPosition2D p, const Triangle<2> & t)
{
return pointLeftOfOrOnLine(p, t[0], t[1]) && pointLeftOfOrOnLine(p, t[1], t[2])
&& pointLeftOfOrOnLine(p, t[2], t[0]);
}
bool
-GeoData::triangleContainsPoint(const glm::vec2 p, FaceHandle face) const
+GeoData::triangleContainsPoint(const GlobalPosition2D p, FaceHandle face) const
{
return triangleContainsPoint(p, triangle<2>(face));
}