summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--application/main.cpp18
-rw-r--r--assetFactory/assetFactory.h5
-rw-r--r--assetFactory/assimp.cpp1
-rw-r--r--assetFactory/cuboid.cpp2
-rw-r--r--assetFactory/cylinder.cpp6
-rw-r--r--assetFactory/faceController.h3
-rw-r--r--assetFactory/factoryMesh.cpp2
-rw-r--r--assetFactory/factoryMesh.h3
-rw-r--r--assetFactory/modelFactoryMesh.h9
-rw-r--r--assetFactory/mutation.cpp1
-rw-r--r--assetFactory/mutation.h7
-rw-r--r--assetFactory/object.h1
-rw-r--r--assetFactory/plane.cpp2
-rw-r--r--assetFactory/shape.cpp4
-rw-r--r--assetFactory/shape.h3
-rw-r--r--assetFactory/style.cpp15
-rw-r--r--assetFactory/style.h6
-rw-r--r--assetFactory/texturePacker.cpp4
-rw-r--r--assetFactory/texturePacker.h9
-rw-r--r--assetFactory/use.cpp1
-rw-r--r--assetFactory/use.h1
-rw-r--r--config/types.h48
-rw-r--r--game/activity.h2
-rw-r--r--game/gamestate.h1
-rw-r--r--game/geoData.cpp71
-rw-r--r--game/geoData.h50
-rw-r--r--game/network/link.cpp14
-rw-r--r--game/network/link.h14
-rw-r--r--game/network/network.cpp18
-rw-r--r--game/network/network.h44
-rw-r--r--game/network/network.impl.h12
-rw-r--r--game/network/rail.cpp45
-rw-r--r--game/network/rail.h12
-rw-r--r--game/objective.h2
-rw-r--r--game/orders.h1
-rw-r--r--game/scenary/foliage.cpp3
-rw-r--r--game/scenary/foliage.h3
-rw-r--r--game/scenary/plant.cpp2
-rw-r--r--game/scenary/plant.h2
-rw-r--r--game/selectable.h3
-rw-r--r--game/vehicles/linkHistory.cpp2
-rw-r--r--game/vehicles/railVehicle.cpp54
-rw-r--r--game/vehicles/railVehicle.h8
-rw-r--r--game/vehicles/railVehicleClass.cpp8
-rw-r--r--game/vehicles/railVehicleClass.h2
-rw-r--r--game/vehicles/train.cpp2
-rw-r--r--game/vehicles/train.h2
-rw-r--r--game/vehicles/vehicle.h1
-rw-r--r--gfx/followCameraController.cpp4
-rw-r--r--gfx/gl/bufferedLocation.cpp23
-rw-r--r--gfx/gl/bufferedLocation.h32
-rw-r--r--gfx/gl/camera.cpp24
-rw-r--r--gfx/gl/camera.h33
-rw-r--r--gfx/gl/instanceVertices.h13
-rw-r--r--gfx/gl/program.h3
-rw-r--r--gfx/gl/sceneProvider.cpp1
-rw-r--r--gfx/gl/sceneRenderer.cpp16
-rw-r--r--gfx/gl/sceneRenderer.h14
-rw-r--r--gfx/gl/sceneShader.cpp40
-rw-r--r--gfx/gl/sceneShader.h21
-rw-r--r--gfx/gl/shader.h1
-rw-r--r--gfx/gl/shaders/commonPoint.glsl2
-rw-r--r--gfx/gl/shaders/commonShadowPoint.glsl3
-rw-r--r--gfx/gl/shaders/dynamicPoint.vs2
-rw-r--r--gfx/gl/shaders/dynamicPointInst.vs2
-rw-r--r--gfx/gl/shaders/fixedPoint.vs2
-rw-r--r--gfx/gl/shaders/landmass.fs6
-rw-r--r--gfx/gl/shaders/pointLight.fs2
-rw-r--r--gfx/gl/shaders/pointLight.gs1
-rw-r--r--gfx/gl/shaders/pointLight.vs5
-rw-r--r--gfx/gl/shaders/shadowDynamicPoint.vs2
-rw-r--r--gfx/gl/shaders/shadowDynamicPointInst.vs2
-rw-r--r--gfx/gl/shaders/shadowFixedPoint.vs2
-rw-r--r--gfx/gl/shaders/spotLight.fs2
-rw-r--r--gfx/gl/shaders/spotLight.gs1
-rw-r--r--gfx/gl/shaders/spotLight.vs5
-rw-r--r--gfx/gl/shaders/water.fs2
-rw-r--r--gfx/gl/shaders/water.vs7
-rw-r--r--gfx/gl/shadowMapper.cpp85
-rw-r--r--gfx/gl/shadowMapper.h17
-rw-r--r--gfx/gl/uiShader.cpp4
-rw-r--r--gfx/gl/uiShader.h3
-rw-r--r--gfx/gl/vertexArrayObject.h5
-rw-r--r--gfx/image.h2
-rw-r--r--gfx/models/texture.cpp9
-rw-r--r--gfx/models/texture.h5
-rw-r--r--gfx/models/tga.h4
-rw-r--r--gfx/models/vertex.h12
-rw-r--r--gfx/renderable.cpp1
-rw-r--r--lib/cache.h1
-rw-r--r--lib/collections.h3
-rw-r--r--lib/enumDetails.h6
-rw-r--r--lib/geometricPlane.cpp4
-rw-r--r--lib/geometricPlane.h10
-rw-r--r--lib/glArrays.h3
-rw-r--r--lib/glContainer.h6
-rw-r--r--lib/gl_traits.h12
-rw-r--r--lib/jsonParse-persistence.cpp3
-rw-r--r--lib/location.cpp4
-rw-r--r--lib/location.h12
-rw-r--r--lib/maths.cpp46
-rw-r--r--lib/maths.h61
-rw-r--r--lib/persistence.cpp1
-rw-r--r--lib/persistence.h9
-rw-r--r--lib/ptr.h1
-rw-r--r--lib/ray.cpp8
-rw-r--r--lib/ray.h15
-rw-r--r--lib/resource.h1
-rw-r--r--lib/saxParse-persistence.h1
-rw-r--r--lib/stdTypeDefs.h4
-rw-r--r--lib/unicode.h2
-rw-r--r--lib/worker.h3
-rw-r--r--res/brush47.xml2
-rw-r--r--test/perf-geoData.cpp6
-rw-r--r--test/test-assetFactory.cpp21
-rw-r--r--test/test-geoData.cpp122
-rw-r--r--test/test-glContextBhvr.cpp2
-rw-r--r--test/test-maths.cpp12
-rw-r--r--test/test-render.cpp26
-rw-r--r--test/testRenderOutput.cpp2
-rw-r--r--test/testRenderOutput.h7
-rw-r--r--test/testStructures.h5
-rw-r--r--thirdparty/openmesh/glmcompat.h13
-rw-r--r--ui/builders/freeExtend.h2
-rw-r--r--ui/builders/straight.cpp2
-rw-r--r--ui/builders/straight.h4
-rw-r--r--ui/editNetwork.h2
-rw-r--r--ui/font.cpp1
-rw-r--r--ui/font.h1
-rw-r--r--ui/gameMainSelector.cpp12
-rw-r--r--ui/gameMainSelector.h3
-rw-r--r--ui/gameMainWindow.cpp8
-rw-r--r--ui/iconButton.h1
-rw-r--r--ui/manualCameraController.cpp4
-rw-r--r--ui/manualCameraController.h6
-rw-r--r--ui/modeHelper.h1
-rw-r--r--ui/text.cpp1
-rw-r--r--ui/text.h1
-rw-r--r--ui/uiComponent.cpp1
-rw-r--r--ui/uiComponent.h1
-rw-r--r--ui/uiComponentPlacer.cpp1
-rw-r--r--ui/window.h3
142 files changed, 864 insertions, 574 deletions
diff --git a/application/main.cpp b/application/main.cpp
index 9e4ca33..5db2539 100644
--- a/application/main.cpp
+++ b/application/main.cpp
@@ -26,7 +26,6 @@
#include <ui/applicationBase.h>
#include <ui/gameMainWindow.h>
#include <ui/window.h>
-#include <vector>
static const int DISPLAY_WIDTH = 1280;
static const int DISPLAY_HEIGHT = 1024;
@@ -48,10 +47,10 @@ public:
{
auto rl = world.create<RailLinks>();
- const glm::vec3 j {-1120, -1100, 3}, k {-1100, -1000, 15}, l {-1000, -800, 20}, m {-900, -600, 30},
- n {-600, -500, 32}, o {-500, -800, 30}, p {-600, -900, 25}, q {-1025, -1175, 10},
- r {-925, -1075, 10};
- const glm::vec3 s {-1100, -500, 15}, t {-1100, -450, 15}, u {-1000, -400, 15};
+ const Position3D j {-1120000, -1100000, 3000}, k {-1100000, -1000000, 15000}, l {-1000000, -800000, 20000},
+ m {-900000, -600000, 30000}, n {-600000, -500000, 32000}, o {-500000, -800000, 30000},
+ p {-600000, -900000, 25000}, q {-1025000, -1175000, 10000}, r {-925000, -1075000, 10000};
+ const Position3D s {-1100000, -500000, 15000}, t {-1100000, -450000, 15000}, u {-1000000, -400000, 15000};
auto l3 = rl->addLinksBetween(j, k);
rl->addLinksBetween(k, l);
rl->addLinksBetween(l, m);
@@ -75,13 +74,14 @@ public:
train->create<RailVehicle>(b47);
}
train->orders.removeAll();
- train->orders.create<GoTo>(&train->orders, l3->ends[1], l3->length, rl->findNodeAt({-1100, -450, 15}));
+ train->orders.create<GoTo>(
+ &train->orders, l3->ends[1], l3->length, rl->findNodeAt({-1100000, -450000, 15000}));
train->currentActivity = train->orders.current()->createActivity();
// auto foliage = std::dynamic_pointer_cast<Foliage>(assets.at("Tree-01-1"));
- // for (float x = 900; x < 1100; x += 3) {
- // for (float y = 900; y < 1100; y += 3) {
- // world.create<Plant>(foliage, Location {terrainMesh->positionAt(glm::vec2 {-x, -y})});
+ // for (float x = 900000; x < 1100000; x += 5000) {
+ // for (float y = 900000; y < 1100000; y += 5000) {
+ // world.create<Plant>(foliage, Location {geoData->positionAt({{-x, -y}})});
//}
//}
}
diff --git a/assetFactory/assetFactory.h b/assetFactory/assetFactory.h
index e449ce2..787f0a4 100644
--- a/assetFactory/assetFactory.h
+++ b/assetFactory/assetFactory.h
@@ -15,10 +15,9 @@ public:
using Assets = std::map<std::string, Asset::Ptr, std::less<>>;
using AssImps = std::map<std::string, AssImp::Ptr, std::less<>>;
using TextureFragments = std::map<std::string, TextureFragment::Ptr, std::less<>>;
- using Colour = glm::vec3;
- using ColourAlpha = glm::vec4;
+ using Colour = RGB;
+ using ColourAlpha = RGBA;
using Colours = std::map<std::string, Colour, std::less<>>;
- using TextureFragmentCoords = std::array<glm::vec2, 4>;
AssetFactory();
[[nodiscard]] static std::shared_ptr<AssetFactory> loadXML(const std::filesystem::path &);
diff --git a/assetFactory/assimp.cpp b/assetFactory/assimp.cpp
index 9dc7842..bd5467b 100644
--- a/assetFactory/assimp.cpp
+++ b/assetFactory/assimp.cpp
@@ -30,6 +30,7 @@ operator!(const aiVector3t<T> & v)
}
using SceneCPtr = std::shared_ptr<const aiScene>;
+
class AssImpNode : public Shape {
public:
AssImpNode(SceneCPtr scene, const aiNode * node) : scene(std::move(scene)), node(node) { }
diff --git a/assetFactory/cuboid.cpp b/assetFactory/cuboid.cpp
index a8ddcd9..cfb6cfb 100644
--- a/assetFactory/cuboid.cpp
+++ b/assetFactory/cuboid.cpp
@@ -4,7 +4,7 @@
Cuboid::CreatedFaces
Cuboid::createMesh(ModelFactoryMesh & mesh, float) const
{
- static constexpr std::array<glm::vec3, 8> VERTICES {{
+ static constexpr std::array<Position3D, 8> VERTICES {{
// bottom
{n, n, z},
{n, y, z},
diff --git a/assetFactory/cylinder.cpp b/assetFactory/cylinder.cpp
index 7d22e36..ed034fd 100644
--- a/assetFactory/cylinder.cpp
+++ b/assetFactory/cylinder.cpp
@@ -9,8 +9,8 @@ Cylinder::createMesh(ModelFactoryMesh & mesh, float lodf) const
const auto step = two_pi / static_cast<float>(P);
// Generate 2D circumference points
- std::vector<glm::vec2> circumference(P);
- std::generate(circumference.begin(), circumference.end(), [a = 0.f, step]() mutable {
+ std::vector<Position2D> circumference(P);
+ std::generate(circumference.begin(), circumference.end(), [a = 0.F, step]() mutable {
return sincosf(a += step) * .5F;
});
@@ -19,7 +19,7 @@ Cylinder::createMesh(ModelFactoryMesh & mesh, float lodf) const
// Generate bottom face vertices
std::vector<OpenMesh::VertexHandle> bottom(P);
std::transform(circumference.begin(), circumference.end(), bottom.begin(), [&mesh](const auto & xy) {
- return mesh.add_vertex(xy ^ 0.f);
+ return mesh.add_vertex(xy ^ 0.F);
});
surface.insert(mesh.add_namedFace("bottom", bottom));
}
diff --git a/assetFactory/faceController.h b/assetFactory/faceController.h
index 0376241..fb89d25 100644
--- a/assetFactory/faceController.h
+++ b/assetFactory/faceController.h
@@ -18,12 +18,14 @@ public:
private:
friend Persistence::SelectionPtrBase<std::unique_ptr<Split>>;
bool persist(Persistence::PersistenceStore & store) override;
+
std::string
getId() const override
{
return {};
};
};
+
using FaceControllers = std::map<std::string, std::unique_ptr<FaceController>>;
using Splits = std::map<std::string, std::unique_ptr<Split>>;
@@ -38,6 +40,7 @@ public:
private:
friend Persistence::SelectionPtrBase<std::unique_ptr<FaceController>>;
bool persist(Persistence::PersistenceStore & store) override;
+
std::string
getId() const override
{
diff --git a/assetFactory/factoryMesh.cpp b/assetFactory/factoryMesh.cpp
index 46bcf6f..3caf5e8 100644
--- a/assetFactory/factoryMesh.cpp
+++ b/assetFactory/factoryMesh.cpp
@@ -30,7 +30,7 @@ FactoryMesh::createMesh() const
const auto & point = mesh.point(vertex);
const auto & normal = useVertexNormals ? mesh.property(mesh.vertex_normals_pph(), vertex)
: mesh.property(mesh.face_normals_pph(), face);
- Vertex outVertex {point, textureUV, normal, colour, material};
+ Vertex outVertex {point * 1000.F, textureUV, normal, colour, material};
if (const auto existingItr = std::find(vertices.rbegin(), vertices.rend(), outVertex);
existingItr != vertices.rend()) {
faceIndices.push_back(static_cast<unsigned int>(std::distance(existingItr, vertices.rend()) - 1));
diff --git a/assetFactory/factoryMesh.h b/assetFactory/factoryMesh.h
index f71c737..b09b54f 100644
--- a/assetFactory/factoryMesh.h
+++ b/assetFactory/factoryMesh.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config/types.h"
#include "gfx/models/mesh.h"
#include "stdTypeDefs.h"
#include "use.h"
@@ -9,7 +10,7 @@ public:
Mesh::Ptr createMesh() const;
std::string id;
- glm::vec3 size;
+ Size3D size;
Use::Collection uses;
private:
diff --git a/assetFactory/modelFactoryMesh.h b/assetFactory/modelFactoryMesh.h
index 2129fb5..06fd7b8 100644
--- a/assetFactory/modelFactoryMesh.h
+++ b/assetFactory/modelFactoryMesh.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config/types.h"
#include "modelFactoryMesh_fwd.h"
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
#include <glad/gl.h>
@@ -13,10 +14,10 @@ struct ModelFactoryTraits : public OpenMesh::DefaultTraits {
EdgeAttributes(OpenMesh::Attributes::Status);
VertexAttributes(OpenMesh::Attributes::Normal | OpenMesh::Attributes::Status);
HalfedgeAttributes(OpenMesh::Attributes::TexCoord2D);
- using Point = glm::vec3;
- using Normal = glm::vec3;
- using Color = glm::vec4;
- using TexCoord2D = glm::vec2;
+ using Point = Position3D;
+ using Normal = Normal3D;
+ using Color = RGBA;
+ using TexCoord2D = TextureRelCoord;
};
struct ModelFactoryMesh : public OpenMesh::PolyMesh_ArrayKernelT<ModelFactoryTraits> {
diff --git a/assetFactory/mutation.cpp b/assetFactory/mutation.cpp
index 9a6a988..c5c3f5b 100644
--- a/assetFactory/mutation.cpp
+++ b/assetFactory/mutation.cpp
@@ -27,6 +27,7 @@ Mutation::relativeLevelOfDetail() const
{
return std::max({scale.x, scale.y, scale.z});
}
+
bool
Mutation::persist(Persistence::PersistenceStore & store)
{
diff --git a/assetFactory/mutation.h b/assetFactory/mutation.h
index 2432174..b571dea 100644
--- a/assetFactory/mutation.h
+++ b/assetFactory/mutation.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config/types.h"
#include "persistence.h"
#include <glm/mat4x4.hpp>
#include <glm/vec3.hpp>
@@ -13,9 +14,9 @@ struct Mutation {
float relativeLevelOfDetail() const;
- glm::vec3 position {};
- glm::vec3 rotation {};
- glm::vec3 scale {1};
+ Position3D position {};
+ Rotation3D rotation {};
+ Scale3D scale {1};
protected:
bool persist(Persistence::PersistenceStore & store);
diff --git a/assetFactory/object.h b/assetFactory/object.h
index f47c512..77e1469 100644
--- a/assetFactory/object.h
+++ b/assetFactory/object.h
@@ -18,6 +18,7 @@ public:
private:
friend Persistence::SelectionPtrBase<std::shared_ptr<Object>>;
bool persist(Persistence::PersistenceStore & store) override;
+
std::string
getId() const override
{
diff --git a/assetFactory/plane.cpp b/assetFactory/plane.cpp
index c6e1b5a..28fb690 100644
--- a/assetFactory/plane.cpp
+++ b/assetFactory/plane.cpp
@@ -4,7 +4,7 @@
Plane::CreatedFaces
Plane::createMesh(ModelFactoryMesh & mesh, float) const
{
- static constexpr std::array<glm::vec3, 4> VERTICES {{
+ static constexpr std::array<Position3D, 4> VERTICES {{
{n, n, z},
{y, n, z},
{y, y, z},
diff --git a/assetFactory/shape.cpp b/assetFactory/shape.cpp
index 1bfbdbb..0f83ee5 100644
--- a/assetFactory/shape.cpp
+++ b/assetFactory/shape.cpp
@@ -1,11 +1,9 @@
#include "shape.h"
-#include "gfx/models/vertex.h"
-#include "maths.h"
#include "modelFactoryMesh.h"
#include "shape.h"
std::vector<OpenMesh::VertexHandle>
-Shape::addToMesh(ModelFactoryMesh & mesh, const std::span<const glm::vec3> vertices)
+Shape::addToMesh(ModelFactoryMesh & mesh, const std::span<const Position3D> vertices)
{
std::vector<OpenMesh::VertexHandle> vhs;
std::transform(vertices.begin(), vertices.end(), std::back_inserter(vhs), [&mesh](const auto & p) {
diff --git a/assetFactory/shape.h b/assetFactory/shape.h
index ea3e4e7..136e24f 100644
--- a/assetFactory/shape.h
+++ b/assetFactory/shape.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config/types.h"
#include "modelFactoryMesh_fwd.h"
#include "stdTypeDefs.h"
#include <OpenMesh/Core/Mesh/Handles.hh>
@@ -21,5 +22,5 @@ public:
virtual CreatedFaces createMesh(ModelFactoryMesh &, float levelOfDetailFactor) const = 0;
static std::vector<OpenMesh::VertexHandle> addToMesh(
- ModelFactoryMesh & mesh, const std::span<const glm::vec3> vertices);
+ ModelFactoryMesh & mesh, const std::span<const Position3D> vertices);
};
diff --git a/assetFactory/style.cpp b/assetFactory/style.cpp
index ea67fc2..265becb 100644
--- a/assetFactory/style.cpp
+++ b/assetFactory/style.cpp
@@ -33,10 +33,10 @@ Style::applyStyle(
const auto material = mf->getMaterialIndex(texture);
mesh.property(mesh.materialFaceProperty, face) = material;
static constexpr std::array<ModelFactoryTraits::TexCoord2D, 4> coords {{
- {0.f, 0.f},
- {1.f, 0.f},
- {1.f, 1.f},
- {0.f, 1.f},
+ {0.F, 0.F},
+ {1.F, 0.F},
+ {1.F, 1.F},
+ {0.F, 1.F},
}};
auto coord = coords.begin();
// Wild assumption that face is a quad and the texture should apply linearly
@@ -58,9 +58,10 @@ Style::getColour(const StyleStack & parents)
bool
Style::persist(Persistence::PersistenceStore & store)
{
- struct ColourParser : public Persistence::SelectionV<ColourAlpha> {
- using Persistence::SelectionV<ColourAlpha>::SelectionV;
- using Persistence::SelectionV<ColourAlpha>::setValue;
+ struct ColourParser : public Persistence::SelectionV<RGBA> {
+ using Persistence::SelectionV<RGBA>::SelectionV;
+ using Persistence::SelectionV<RGBA>::setValue;
+
void
setValue(std::string && str) override
{
diff --git a/assetFactory/style.h b/assetFactory/style.h
index d931f98..2a437aa 100644
--- a/assetFactory/style.h
+++ b/assetFactory/style.h
@@ -10,9 +10,7 @@
class Style {
public:
using StyleStack = std::vector<const Style *>;
- using Colour = glm::vec3;
- using ColourAlpha = glm::vec4;
- using EffectiveColour = std::optional<std::reference_wrapper<const ColourAlpha>>;
+ using EffectiveColour = std::optional<std::reference_wrapper<const RGBA>>;
void applyStyle(ModelFactoryMesh &, const StyleStack & parents, const Shape::CreatedFaces &) const;
void applyStyle(ModelFactoryMesh &, const StyleStack & parents, const ModelFactoryMesh::FaceHandle &) const;
@@ -30,7 +28,7 @@ public:
static EffectiveColour getColour(const StyleStack & parents);
- ColourAlpha colour {};
+ RGBA colour {};
std::optional<bool> smooth;
std::string texture;
std::string textureRotation; // Multiples of 90deg, no int/enum support
diff --git a/assetFactory/texturePacker.cpp b/assetFactory/texturePacker.cpp
index dbafc4b..0d0fdb6 100644
--- a/assetFactory/texturePacker.cpp
+++ b/assetFactory/texturePacker.cpp
@@ -14,9 +14,7 @@ TexturePacker::TexturePacker(std::span<const Image> in) :
std::sort(sortedIndexes.rbegin(), sortedIndexes.rend(), [this](const auto a, const auto b) {
return area(inputImages[a]) < area(inputImages[b]);
});
- int mts;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mts);
- maxTextureSize = static_cast<unsigned int>(mts);
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
}
TexturePacker::Result
diff --git a/assetFactory/texturePacker.h b/assetFactory/texturePacker.h
index a1b270b..05e3204 100644
--- a/assetFactory/texturePacker.h
+++ b/assetFactory/texturePacker.h
@@ -1,13 +1,14 @@
#pragma once
+#include "config/types.h"
#include <glm/vec2.hpp>
#include <span>
#include <vector>
class TexturePacker {
public:
- using Position = glm::uvec2;
- using Size = glm::uvec2;
+ using Position = TextureAbsCoord;
+ using Size = TextureAbsCoord;
struct Area {
#ifndef __cpp_aggregate_paren_init
@@ -16,12 +17,14 @@ public:
Position position;
Size size;
+
bool
operator<(const Area & other) const
{
return area(size) < area(other.size);
}
};
+
using Image = Size;
using Space = Area;
using Positions = std::vector<Position>;
@@ -38,5 +41,5 @@ public:
private:
std::span<const Image> inputImages;
std::vector<size_t> sortedIndexes;
- unsigned int maxTextureSize;
+ GLsizei maxTextureSize;
};
diff --git a/assetFactory/use.cpp b/assetFactory/use.cpp
index 5314321..0994c8c 100644
--- a/assetFactory/use.cpp
+++ b/assetFactory/use.cpp
@@ -35,6 +35,7 @@ Use::createMesh(ModelFactoryMesh & mesh, float levelOfDetailFactor) const
struct Lookup : public Persistence::SelectionV<Shape::CPtr> {
using Persistence::SelectionV<Shape::CPtr>::SelectionV;
using Persistence::SelectionV<Shape::CPtr>::setValue;
+
void
setValue(std::string && str) override
{
diff --git a/assetFactory/use.h b/assetFactory/use.h
index a91685b..289bf6e 100644
--- a/assetFactory/use.h
+++ b/assetFactory/use.h
@@ -19,6 +19,7 @@ public:
private:
friend Persistence::SelectionPtrBase<std::shared_ptr<Use>>;
bool persist(Persistence::PersistenceStore & store) override;
+
std::string
getId() const override
{
diff --git a/config/types.h b/config/types.h
new file mode 100644
index 0000000..6fc7b61
--- /dev/null
+++ b/config/types.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "glad/gl.h"
+#include <glm/geometric.hpp>
+
+using Distance = float; // deprecate
+using RelativeDistance = float;
+using GlobalDistance = int32_t;
+using Angle = float;
+
+template<glm::length_t D> using Position = glm::vec<D, Distance>; // deprecate
+template<glm::length_t D> using RelativePosition = glm::vec<D, RelativeDistance>;
+template<glm::length_t D> using GlobalPosition = glm::vec<D, GlobalDistance>;
+template<glm::length_t D> using Size = glm::vec<D, Distance>;
+template<glm::length_t D> using Scale = glm::vec<D, float>;
+template<glm::length_t D> using Direction = glm::vec<D, float>;
+template<glm::length_t D> using Normal = Direction<D>;
+template<glm::length_t D> using Rotation = glm::vec<D, Angle>;
+template<glm::length_t Channels> using Colour = glm::vec<Channels, float>;
+
+using Position2D = Position<2>; // deprecate
+using Position3D = Position<3>; // deprecate
+using BaryPosition = glm::vec<2, float>;
+using RelativePosition2D = RelativePosition<2>;
+using RelativePosition3D = RelativePosition<3>;
+using RelativePosition4D = RelativePosition<4>;
+using GlobalPosition2D = GlobalPosition<2>;
+using GlobalPosition3D = GlobalPosition<3>;
+using GlobalPosition4D = GlobalPosition<4>;
+using Size2D = Size<2>;
+using Size3D = Size<3>;
+using Scale2D = Scale<2>;
+using Scale3D = Scale<3>;
+using Direction2D = Direction<2>;
+using Direction3D = Direction<3>;
+using Normal2D = Normal<2>;
+using Normal3D = Normal<3>;
+using Rotation2D = Rotation<2>;
+using Rotation3D = Rotation<3>;
+using TextureRelCoord = glm::vec<2, float>;
+using TextureRelRegion = glm::vec<4, float>;
+using TextureAbsCoord = glm::vec<2, GLsizei>;
+using TextureAbsRegion = glm::vec<4, GLsizei>;
+using RGB = Colour<3>;
+using RGBA = Colour<4>;
+using ScreenRelCoord = glm::vec<2, float>;
+using ScreenAbsCoord = glm::vec<2, uint16_t>;
+using ViewPort = glm::vec<4, GLsizei>;
diff --git a/game/activity.h b/game/activity.h
index e0585f7..38f6524 100644
--- a/game/activity.h
+++ b/game/activity.h
@@ -16,10 +16,12 @@ public:
template<typename T> class Of;
};
+
using ActivityPtr = std::unique_ptr<Activity>;
template<typename T>
concept ActivityConcept = std::is_base_of_v<Activity, T>;
+
template<ActivityConcept AC> class Can {
public:
Can() = default;
diff --git a/game/gamestate.h b/game/gamestate.h
index 6f3f382..f07f844 100644
--- a/game/gamestate.h
+++ b/game/gamestate.h
@@ -19,4 +19,5 @@ public:
std::shared_ptr<GeoData> geoData;
AssetFactory::Assets assets;
};
+
extern GameState * gameState;
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));
}
diff --git a/game/geoData.h b/game/geoData.h
index 474731b..3141dbe 100644
--- a/game/geoData.h
+++ b/game/geoData.h
@@ -1,6 +1,7 @@
#pragma once
#include "collections.h" // IWYU pragma: keep IterableCollection
+#include "config/types.h"
#include "ray.h"
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <filesystem>
@@ -13,8 +14,8 @@ struct GeoDataTraits : public OpenMesh::DefaultTraits {
EdgeAttributes(OpenMesh::Attributes::Status);
VertexAttributes(OpenMesh::Attributes::Normal | OpenMesh::Attributes::Status);
HalfedgeAttributes(OpenMesh::Attributes::Normal | OpenMesh::Attributes::Status);
- using Point = glm::vec3;
- using Normal = glm::vec3;
+ using Point = GlobalPosition3D;
+ using Normal = Normal3D;
};
class GeoData : public OpenMesh::TriMesh_ArrayKernelT<GeoDataTraits> {
@@ -23,18 +24,18 @@ private:
public:
static GeoData loadFromAsciiGrid(const std::filesystem::path &);
- static GeoData createFlat(glm::vec2 lower, glm::vec2, float h);
+ static GeoData createFlat(GlobalPosition2D lower, GlobalPosition2D upper, GlobalDistance h);
struct PointFace {
// NOLINTNEXTLINE(hicpp-explicit-conversions)
- PointFace(const glm::vec2 p) : point {p} { }
+ PointFace(const GlobalPosition2D p) : point {p} { }
- PointFace(const glm::vec2 p, FaceHandle face) : point {p}, _face {face} { }
+ PointFace(const GlobalPosition2D p, FaceHandle face) : point {p}, _face {face} { }
- PointFace(const glm::vec2 p, const GeoData *);
- PointFace(const glm::vec2 p, const GeoData *, FaceHandle start);
+ PointFace(const GlobalPosition2D p, const GeoData *);
+ PointFace(const GlobalPosition2D p, const GeoData *, FaceHandle start);
- const glm::vec2 point;
+ const GlobalPosition2D point;
[[nodiscard]] FaceHandle face(const GeoData *) const;
[[nodiscard]] FaceHandle face(const GeoData *, FaceHandle start) const;
@@ -48,8 +49,8 @@ public:
mutable FaceHandle _face {};
};
- template<glm::length_t Dim> struct Triangle : public glm::vec<3, glm::vec<Dim, glm::vec2::value_type>> {
- using base = glm::vec<3, glm::vec<Dim, glm::vec2::value_type>>;
+ template<glm::length_t Dim> struct Triangle : public glm::vec<3, glm::vec<Dim, GlobalDistance>> {
+ using base = glm::vec<3, glm::vec<Dim, GlobalDistance>>;
using base::base;
template<IterableCollection Range> Triangle(const GeoData * m, Range range)
@@ -60,30 +61,31 @@ public:
});
}
- glm::vec<Dim, glm::vec2::value_type>
- operator*(glm::vec2 bari) const
+ glm::vec<Dim, GlobalDistance>
+ operator*(BaryPosition bari) const
{
const auto & t {*this};
- return t[0] + ((t[1] - t[0]) * bari.x) + ((t[2] - t[1]) * bari.y);
+ return t[0] + GlobalPosition<Dim>(RelativePosition<Dim>(t[1] - t[0]) * bari.x)
+ + GlobalPosition<Dim>(RelativePosition<Dim>(t[2] - t[1]) * bari.y);
}
};
- [[nodiscard]] FaceHandle findPoint(glm::vec2) const;
- [[nodiscard]] FaceHandle findPoint(glm::vec2, FaceHandle start) const;
+ [[nodiscard]] FaceHandle findPoint(GlobalPosition2D) const;
+ [[nodiscard]] FaceHandle findPoint(GlobalPosition2D, FaceHandle start) const;
- [[nodiscard]] glm::vec3 positionAt(const PointFace &) const;
- [[nodiscard]] std::optional<glm::vec3> intersectRay(const Ray &) const;
- [[nodiscard]] std::optional<glm::vec3> intersectRay(const Ray &, FaceHandle start) const;
+ [[nodiscard]] GlobalPosition3D positionAt(const PointFace &) const;
+ [[nodiscard]] std::optional<GlobalPosition3D> intersectRay(const Ray &) const;
+ [[nodiscard]] std::optional<GlobalPosition3D> intersectRay(const Ray &, FaceHandle start) const;
- void walk(const PointFace & from, const glm::vec2 to, const std::function<void(FaceHandle)> & op) const;
- void walkUntil(const PointFace & from, const glm::vec2 to, const std::function<bool(FaceHandle)> & op) const;
+ void walk(const PointFace & from, const GlobalPosition2D to, const std::function<void(FaceHandle)> & op) const;
+ void walkUntil(const PointFace & from, const GlobalPosition2D to, const std::function<bool(FaceHandle)> & op) const;
void boundaryWalk(const std::function<void(HalfedgeHandle)> &) const;
void boundaryWalk(const std::function<void(HalfedgeHandle)> &, HalfedgeHandle start) const;
void boundaryWalkUntil(const std::function<bool(HalfedgeHandle)> &) const;
void boundaryWalkUntil(const std::function<bool(HalfedgeHandle)> &, HalfedgeHandle start) const;
- [[nodiscard]] HalfedgeHandle findEntry(const glm::vec2 from, const glm::vec2 to) const;
+ [[nodiscard]] HalfedgeHandle findEntry(const GlobalPosition2D from, const GlobalPosition2D to) const;
[[nodiscard]] auto
getExtents() const
@@ -99,10 +101,10 @@ protected:
return {this, fv_range(f)};
}
- [[nodiscard]] static bool triangleContainsPoint(const glm::vec2, const Triangle<2> &);
- [[nodiscard]] bool triangleContainsPoint(const glm::vec2, FaceHandle) const;
+ [[nodiscard]] static bool triangleContainsPoint(const GlobalPosition2D, const Triangle<2> &);
+ [[nodiscard]] bool triangleContainsPoint(const GlobalPosition2D, FaceHandle) const;
[[nodiscard]] HalfedgeHandle findBoundaryStart() const;
private:
- glm::vec3 lowerExtent {}, upperExtent {};
+ GlobalPosition3D lowerExtent {}, upperExtent {};
};
diff --git a/game/network/link.cpp b/game/network/link.cpp
index bb27a52..498afe4 100644
--- a/game/network/link.cpp
+++ b/game/network/link.cpp
@@ -8,10 +8,10 @@
Link::Link(End a, End b, float l) : ends {{std::move(a), std::move(b)}}, length {l} { }
-LinkCurve::LinkCurve(glm::vec3 c, float r, Arc a) : centreBase {c}, radius {r}, arc {std::move(a)} { }
+LinkCurve::LinkCurve(Position3D c, float r, Arc a) : centreBase {c}, radius {r}, arc {std::move(a)} { }
bool
-operator<(const glm::vec3 & a, const glm::vec3 & b)
+operator<(const Position3D & a, const Position3D & b)
{
// NOLINTNEXTLINE(hicpp-use-nullptr,modernize-use-nullptr)
return std::tie(a.x, a.y, a.z) < std::tie(b.x, b.y, b.z);
@@ -48,7 +48,7 @@ LinkCurve::positionAt(float dist, unsigned char start) const
const auto ang {as.first + ((as.second - as.first) * frac)};
const auto relPos {!sincosf(ang) * radius};
const auto relClimb {vehiclePositionOffset()
- + glm::vec3 {0, 0, es.first->pos.z - centreBase.z + ((es.second->pos.z - es.first->pos.z) * frac)}};
+ + Position3D {0, 0, es.first->pos.z - centreBase.z + ((es.second->pos.z - es.first->pos.z) * frac)}};
const auto pitch {vector_pitch({0, 0, (es.second->pos.z - es.first->pos.z) / length})};
return Location {relPos + relClimb + centreBase, {pitch, normalize(ang + dirOffset[start]), 0}};
}
@@ -60,14 +60,14 @@ LinkCurve::intersectRay(const Ray & ray) const
const auto & e1p {ends[1].node->pos};
const auto slength = round_frac(length / 2.F, 5.F);
const auto segs = std::round(15.F * slength / std::pow(radius, 0.7F));
- const auto step {glm::vec3 {arc_length(arc), e1p.z - e0p.z, slength} / segs};
+ const auto step {Position3D {arc_length(arc), e1p.z - e0p.z, slength} / segs};
const auto trans {glm::translate(centreBase)};
auto segCount = static_cast<std::size_t>(std::lround(segs)) + 1;
- std::vector<glm::vec3> points;
+ std::vector<Position3D> points;
points.reserve(segCount);
- for (glm::vec3 swing = {arc.first, centreBase.z - e0p.z, 0.F}; segCount; swing += step, --segCount) {
- const auto t {trans * glm::rotate(half_pi - swing.x, up) * glm::translate(glm::vec3 {radius, 0.F, swing.y})};
+ for (Position3D swing = {arc.first, centreBase.z - e0p.z, 0.F}; segCount; swing += step, --segCount) {
+ const auto t {trans * glm::rotate(half_pi - swing.x, up) * glm::translate(Position3D {radius, 0.F, swing.y})};
points.emplace_back(t * glm::vec4 {0, 0, 0, 1});
}
return ray.passesCloseToEdges(points, 1.F);
diff --git a/game/network/link.h b/game/network/link.h
index 4a9f83f..78d3e91 100644
--- a/game/network/link.h
+++ b/game/network/link.h
@@ -17,12 +17,12 @@ class Ray;
// it has location
class Node : public StdTypeDefs<Node> {
public:
- explicit Node(glm::vec3 p) noexcept : pos(p) {};
+ explicit Node(Position3D p) noexcept : pos(p) {};
virtual ~Node() noexcept = default;
NO_COPY(Node);
NO_MOVE(Node);
- glm::vec3 pos;
+ Position3D pos;
};
// Generic network link
@@ -51,14 +51,14 @@ public:
float length;
protected:
- [[nodiscard]] virtual glm::vec3
+ [[nodiscard]] virtual Position3D
vehiclePositionOffset() const
{
return {};
}
};
-bool operator<(const glm::vec3 & a, const glm::vec3 & b);
+bool operator<(const Position3D & a, const Position3D & b);
bool operator<(const Node & a, const Node & b);
class LinkStraight : public virtual Link {
@@ -71,20 +71,22 @@ public:
[[nodiscard]] Location positionAt(float dist, unsigned char start) const override;
[[nodiscard]] bool intersectRay(const Ray &) const override;
};
+
LinkStraight::~LinkStraight() = default;
class LinkCurve : public virtual Link {
public:
inline ~LinkCurve() override = 0;
- LinkCurve(glm::vec3, float, Arc);
+ LinkCurve(Position3D, float, Arc);
NO_COPY(LinkCurve);
NO_MOVE(LinkCurve);
[[nodiscard]] Location positionAt(float dist, unsigned char start) const override;
[[nodiscard]] bool intersectRay(const Ray &) const override;
- glm::vec3 centreBase;
+ Position3D centreBase;
float radius;
Arc arc;
};
+
LinkCurve::~LinkCurve() = default;
diff --git a/game/network/network.cpp b/game/network/network.cpp
index 083b08e..d18345c 100644
--- a/game/network/network.cpp
+++ b/game/network/network.cpp
@@ -14,13 +14,13 @@
Network::Network(const std::string & tn) : texture {Texture::cachedTexture.get(tn)} { }
Node::Ptr
-Network::nodeAt(glm::vec3 pos)
+Network::nodeAt(Position3D pos)
{
return newNodeAt(pos).first;
}
Network::NodeInsertion
-Network::newNodeAt(glm::vec3 pos)
+Network::newNodeAt(Position3D pos)
{
if (auto [n, i] = candidateNodeAt(pos); i == NodeIs::NotInNetwork) {
return {*nodes.insert(std::move(n)).first, i};
@@ -31,7 +31,7 @@ Network::newNodeAt(glm::vec3 pos)
}
Node::Ptr
-Network::findNodeAt(glm::vec3 pos) const
+Network::findNodeAt(Position3D pos) const
{
if (const auto n = nodes.find(pos); n != nodes.end()) {
return *n;
@@ -40,7 +40,7 @@ Network::findNodeAt(glm::vec3 pos) const
}
Network::NodeInsertion
-Network::candidateNodeAt(glm::vec3 pos) const
+Network::candidateNodeAt(Position3D pos) const
{
if (const auto n = nodes.find(pos); n != nodes.end()) {
return {*n, NodeIs::InNetwork};
@@ -54,7 +54,7 @@ Network::intersectRayNodes(const Ray & ray) const
// Click within 2m of a node
if (const auto node = std::find_if(nodes.begin(), nodes.end(),
[&ray](const Node::Ptr & node) {
- glm::vec3 ipos, inorm;
+ Position3D ipos, inorm;
return glm::intersectRaySphere(ray.start, ray.direction, node->pos, 2.F, ipos, inorm);
});
node != nodes.end()) {
@@ -79,7 +79,7 @@ Network::joinLinks(const Link::Ptr & l, const Link::Ptr & ol)
}
Link::Nexts
-Network::routeFromTo(const Link::End & start, glm::vec3 dest) const
+Network::routeFromTo(const Link::End & start, Position3D dest) const
{
auto destNode {findNodeAt(dest)};
if (!destNode) {
@@ -95,7 +95,7 @@ Network::routeFromTo(const Link::End & end, const Node::Ptr & dest) const
}
GenCurveDef
-Network::genCurveDef(const glm::vec3 & start, const glm::vec3 & end, float startDir)
+Network::genCurveDef(const Position3D & start, const Position3D & end, float startDir)
{
const auto diff {end - start};
const auto vy {vector_yaw(diff)};
@@ -111,11 +111,11 @@ Network::genCurveDef(const glm::vec3 & start, const glm::vec3 & end, float start
}
std::pair<GenCurveDef, GenCurveDef>
-Network::genCurveDef(const glm::vec3 & start, const glm::vec3 & end, float startDir, float endDir)
+Network::genCurveDef(const Position3D & start, const Position3D & end, float startDir, float endDir)
{
startDir += pi;
endDir += pi;
- const glm::vec2 flatStart {!start}, flatEnd {!end};
+ const Position2D flatStart {!start}, flatEnd {!end};
auto midheight = [&](auto mid) {
const auto sm = glm::distance(flatStart, mid), em = glm::distance(flatEnd, mid);
return start.z + ((end.z - start.z) * (sm / (sm + em)));
diff --git a/game/network/network.h b/game/network/network.h
index b9316eb..8af06a9 100644
--- a/game/network/network.h
+++ b/game/network/network.h
@@ -16,7 +16,7 @@ class Texture;
class SceneShader;
class Ray;
-template<size_t... n> using GenDef = std::tuple<glm::vec<n, float>...>;
+template<size_t... n> using GenDef = std::tuple<glm::vec<n, Distance>...>;
using GenCurveDef = GenDef<3, 3, 2>;
class Network {
@@ -26,32 +26,32 @@ public:
virtual ~Network() = default;
DEFAULT_MOVE_NO_COPY(Network);
- [[nodiscard]] Node::Ptr findNodeAt(glm::vec3) const;
- [[nodiscard]] Node::Ptr nodeAt(glm::vec3);
+ [[nodiscard]] Node::Ptr findNodeAt(Position3D) const;
+ [[nodiscard]] Node::Ptr nodeAt(Position3D);
enum class NodeIs { InNetwork, NotInNetwork };
using NodeInsertion = std::pair<Node::Ptr, NodeIs>;
- [[nodiscard]] NodeInsertion newNodeAt(glm::vec3);
- [[nodiscard]] NodeInsertion candidateNodeAt(glm::vec3) const;
+ [[nodiscard]] NodeInsertion newNodeAt(Position3D);
+ [[nodiscard]] NodeInsertion candidateNodeAt(Position3D) const;
[[nodiscard]] virtual Link::Ptr intersectRayLinks(const Ray &) const = 0;
[[nodiscard]] virtual Node::Ptr intersectRayNodes(const Ray &) const;
- [[nodiscard]] Link::Nexts routeFromTo(const Link::End &, glm::vec3) const;
+ [[nodiscard]] Link::Nexts routeFromTo(const Link::End &, Position3D) const;
[[nodiscard]] Link::Nexts routeFromTo(const Link::End &, const Node::Ptr &) const;
- virtual Link::CCollection candidateStraight(glm::vec3, glm::vec3) = 0;
- virtual Link::CCollection candidateJoins(glm::vec3, glm::vec3) = 0;
- virtual Link::CCollection candidateExtend(glm::vec3, glm::vec3) = 0;
- virtual Link::CCollection addStraight(glm::vec3, glm::vec3) = 0;
- virtual Link::CCollection addJoins(glm::vec3, glm::vec3) = 0;
- virtual Link::CCollection addExtend(glm::vec3, glm::vec3) = 0;
+ virtual Link::CCollection candidateStraight(Position3D, Position3D) = 0;
+ virtual Link::CCollection candidateJoins(Position3D, Position3D) = 0;
+ virtual Link::CCollection candidateExtend(Position3D, Position3D) = 0;
+ virtual Link::CCollection addStraight(Position3D, Position3D) = 0;
+ virtual Link::CCollection addJoins(Position3D, Position3D) = 0;
+ virtual Link::CCollection addExtend(Position3D, Position3D) = 0;
[[nodiscard]] virtual float findNodeDirection(Node::AnyCPtr) const = 0;
protected:
static void joinLinks(const Link::Ptr & l, const Link::Ptr & ol);
- static GenCurveDef genCurveDef(const glm::vec3 & start, const glm::vec3 & end, float startDir);
+ static GenCurveDef genCurveDef(const Position3D & start, const Position3D & end, float startDir);
static std::pair<GenCurveDef, GenCurveDef> genCurveDef(
- const glm::vec3 & start, const glm::vec3 & end, float startDir, float endDir);
+ const Position3D & start, const Position3D & end, float startDir, float endDir);
using Nodes = std::set<Node::Ptr, PtrMemberSorter<Node::Ptr, &Node::pos>>;
Nodes nodes;
@@ -71,7 +71,7 @@ protected:
public:
template<typename L, typename... Params>
std::shared_ptr<L>
- candidateLink(glm::vec3 a, glm::vec3 b, Params &&... params)
+ candidateLink(Position3D a, Position3D b, Params &&... params)
requires std::is_base_of_v<T, L>
{
const auto node1 = candidateNodeAt(a).first, node2 = candidateNodeAt(b).first;
@@ -80,7 +80,7 @@ public:
template<typename L, typename... Params>
std::shared_ptr<L>
- addLink(glm::vec3 a, glm::vec3 b, Params &&... params)
+ addLink(Position3D a, Position3D b, Params &&... params)
requires std::is_base_of_v<T, L>
{
const auto node1 = nodeAt(a), node2 = nodeAt(b);
@@ -89,12 +89,12 @@ public:
return l;
}
- Link::CCollection candidateStraight(glm::vec3 n1, glm::vec3 n2) override;
- Link::CCollection candidateJoins(glm::vec3, glm::vec3) override;
- Link::CCollection candidateExtend(glm::vec3, glm::vec3) override;
- Link::CCollection addStraight(glm::vec3 n1, glm::vec3 n2) override;
- Link::CCollection addJoins(glm::vec3, glm::vec3) override;
- Link::CCollection addExtend(glm::vec3, glm::vec3) override;
+ Link::CCollection candidateStraight(Position3D n1, Position3D n2) override;
+ Link::CCollection candidateJoins(Position3D, Position3D) override;
+ Link::CCollection candidateExtend(Position3D, Position3D) override;
+ Link::CCollection addStraight(Position3D n1, Position3D n2) override;
+ Link::CCollection addJoins(Position3D, Position3D) override;
+ Link::CCollection addExtend(Position3D, Position3D) override;
[[nodiscard]] float findNodeDirection(Node::AnyCPtr) const override;
diff --git a/game/network/network.impl.h b/game/network/network.impl.h
index 045335f..8e9e85c 100644
--- a/game/network/network.impl.h
+++ b/game/network/network.impl.h
@@ -54,14 +54,14 @@ NetworkOf<T>::findNodeDirection(Node::AnyCPtr n) const
template<typename T>
Link::CCollection
-NetworkOf<T>::candidateStraight(glm::vec3 n1, glm::vec3 n2)
+NetworkOf<T>::candidateStraight(Position3D n1, Position3D n2)
{
return {candidateLink<typename T::StraightLink>(n1, n2)};
}
template<typename T>
Link::CCollection
-NetworkOf<T>::candidateJoins(glm::vec3 start, glm::vec3 end)
+NetworkOf<T>::candidateJoins(Position3D start, Position3D end)
{
if (glm::distance(start, end) < 2.F) {
return {};
@@ -75,7 +75,7 @@ NetworkOf<T>::candidateJoins(glm::vec3 start, glm::vec3 end)
template<typename T>
Link::CCollection
-NetworkOf<T>::candidateExtend(glm::vec3 start, glm::vec3 end)
+NetworkOf<T>::candidateExtend(Position3D start, Position3D end)
{
const auto [cstart, cend, centre] = genCurveDef(start, end, findNodeDirection(candidateNodeAt(start).first));
return {candidateLink<typename T::CurveLink>(cstart, cend, centre)};
@@ -83,14 +83,14 @@ NetworkOf<T>::candidateExtend(glm::vec3 start, glm::vec3 end)
template<typename T>
Link::CCollection
-NetworkOf<T>::addStraight(glm::vec3 n1, glm::vec3 n2)
+NetworkOf<T>::addStraight(Position3D n1, Position3D n2)
{
return {addLink<typename T::StraightLink>(n1, n2)};
}
template<typename T>
Link::CCollection
-NetworkOf<T>::addJoins(glm::vec3 start, glm::vec3 end)
+NetworkOf<T>::addJoins(Position3D start, Position3D end)
{
if (glm::distance(start, end) < 2.F) {
return {};
@@ -103,7 +103,7 @@ NetworkOf<T>::addJoins(glm::vec3 start, glm::vec3 end)
template<typename T>
Link::CCollection
-NetworkOf<T>::addExtend(glm::vec3 start, glm::vec3 end)
+NetworkOf<T>::addExtend(Position3D start, Position3D end)
{
const auto [cstart, cend, centre] = genCurveDef(start, end, findNodeDirection(nodeAt(start)));
return {addLink<typename T::CurveLink>(cstart, cend, centre)};
diff --git a/game/network/rail.cpp b/game/network/rail.cpp
index bd24a2b..ff101d4 100644
--- a/game/network/rail.cpp
+++ b/game/network/rail.cpp
@@ -18,16 +18,17 @@
template class NetworkOf<RailLink>;
constexpr auto RAIL_CROSSSECTION_VERTICES {5U};
-constexpr glm::vec3 RAIL_HEIGHT {0, 0, .25F};
+constexpr Size3D RAIL_HEIGHT {0, 0, 250.F};
RailLinks::RailLinks() : NetworkOf<RailLink> {"rails.jpg"} { }
+
void
RailLinks::tick(TickDuration)
{
}
std::shared_ptr<RailLink>
-RailLinks::addLinksBetween(glm::vec3 start, glm::vec3 end)
+RailLinks::addLinksBetween(Position3D start, Position3D end)
{
auto node1ins = newNodeAt(start), node2ins = newNodeAt(end);
if (node1ins.second == NodeIs::NotInNetwork && node2ins.second == NodeIs::NotInNetwork) {
@@ -44,7 +45,7 @@ RailLinks::addLinksBetween(glm::vec3 start, glm::vec3 end)
if (dir == vector_yaw(end - start)) {
return addLink<RailLinkStraight>(start, end);
}
- const glm::vec2 flatStart {!start}, flatEnd {!end};
+ const Position2D flatStart {!start}, flatEnd {!end};
if (node2ins.second == NodeIs::InNetwork) {
auto midheight = [&](auto mid) {
const auto sm = glm::distance(flatStart, mid), em = glm::distance(flatEnd, mid);
@@ -99,15 +100,15 @@ RailLink::render(const SceneShader &) const
mesh->Draw();
}
-constexpr const std::array<std::pair<glm::vec3, float>, RAIL_CROSSSECTION_VERTICES> railCrossSection {{
+constexpr const std::array<std::pair<Position3D, float>, RAIL_CROSSSECTION_VERTICES> railCrossSection {{
// ___________
// _/ \_
// left to right
- {{-1.9F, 0.F, 0.F}, 0.F},
- {{-.608F, 0.F, RAIL_HEIGHT.z}, 0.34F},
- {{0, 0.F, RAIL_HEIGHT.z * .7F}, 0.5F},
- {{.608F, 0.F, RAIL_HEIGHT.z}, 0.66F},
- {{1.9F, 0.F, 0.F}, 1.F},
+ {{-1900.F, 0.F, 0.F}, 0.F},
+ {{-608.F, 0.F, RAIL_HEIGHT.z}, .34F},
+ {{0, 0.F, RAIL_HEIGHT.z * .7F}, .5F},
+ {{608.F, 0.F, RAIL_HEIGHT.z}, .66F},
+ {{1900.F, 0.F, 0.F}, 1.F},
}};
constexpr auto sleepers {5.F}; // There are 5 repetitions of sleepers in the texture
@@ -121,31 +122,31 @@ RailLinkStraight::RailLinkStraight(const Node::Ptr & a, const Node::Ptr & b) : R
{
}
-RailLinkStraight::RailLinkStraight(Node::Ptr a, Node::Ptr b, const glm::vec3 & diff) :
+RailLinkStraight::RailLinkStraight(Node::Ptr a, Node::Ptr b, const Position3D & diff) :
Link({std::move(a), vector_yaw(diff)}, {std::move(b), vector_yaw(-diff)}, glm::length(diff))
{
if (glGenVertexArrays) {
std::vector<Vertex> vertices;
vertices.reserve(2 * railCrossSection.size());
- const auto len = round_sleepers(length / 2.F);
+ const auto len = round_sleepers(length / 2000.F);
const auto e {flat_orientation(diff)};
for (auto ei : {1U, 0U}) {
const auto trans {glm::translate(ends[ei].node->pos) * e};
for (const auto & rcs : railCrossSection) {
- const glm::vec3 m {(trans * glm::vec4 {rcs.first, 1})};
- vertices.emplace_back(m, glm::vec2 {rcs.second, len * static_cast<float>(ei)}, up);
+ const Position3D m {(trans * (rcs.first ^ 1))};
+ vertices.emplace_back(m, Position2D {rcs.second, len * static_cast<float>(ei)}, up);
}
}
mesh = defaultMesh(vertices);
}
}
-RailLinkCurve::RailLinkCurve(const Node::Ptr & a, const Node::Ptr & b, glm::vec2 c) :
+RailLinkCurve::RailLinkCurve(const Node::Ptr & a, const Node::Ptr & b, Position2D c) :
RailLinkCurve(a, b, c ^ a->pos.z, {!c, a->pos, b->pos})
{
}
-RailLinkCurve::RailLinkCurve(const Node::Ptr & a, const Node::Ptr & b, glm::vec3 c, const Arc arc) :
+RailLinkCurve::RailLinkCurve(const Node::Ptr & a, const Node::Ptr & b, Position3D c, const Arc arc) :
Link({a, normalize(arc.first + half_pi)}, {b, normalize(arc.second - half_pi)},
(glm::length(a->pos - c)) * arc_length(arc)),
LinkCurve {c, glm::length(ends[0].node->pos - c), arc}
@@ -154,26 +155,26 @@ RailLinkCurve::RailLinkCurve(const Node::Ptr & a, const Node::Ptr & b, glm::vec3
const auto & e0p {ends[0].node->pos};
const auto & e1p {ends[1].node->pos};
const auto slength = round_sleepers(length / 2.F);
- const auto segs = std::round(15.F * slength / std::pow(radius, 0.7F));
- const auto step {glm::vec3 {arc_length(arc), e1p.z - e0p.z, slength} / segs};
+ const auto segs = std::round(slength / std::pow(radius, 0.7F));
+ const auto step {Position3D {arc_length(arc), e1p.z - e0p.z, slength / 1000.F} / segs};
const auto trans {glm::translate(centreBase)};
auto segCount = static_cast<std::size_t>(std::lround(segs)) + 1;
std::vector<Vertex> vertices;
vertices.reserve(segCount * railCrossSection.size());
- for (glm::vec3 swing = {arc.first, centreBase.z - e0p.z, 0.F}; segCount; swing += step, --segCount) {
+ for (Position3D swing = {arc.first, centreBase.z - e0p.z, 0.F}; segCount; swing += step, --segCount) {
const auto t {
- trans * glm::rotate(half_pi - swing.x, up) * glm::translate(glm::vec3 {radius, 0.F, swing.y})};
+ trans * glm::rotate(half_pi - swing.x, up) * glm::translate(Position3D {radius, 0.F, swing.y})};
for (const auto & rcs : railCrossSection) {
- const glm::vec3 m {(t * glm::vec4 {rcs.first, 1})};
- vertices.emplace_back(m, glm::vec2 {rcs.second, swing.z}, up);
+ const Position3D m {(t * (rcs.first ^ 1))};
+ vertices.emplace_back(m, Position2D {rcs.second, swing.z}, up);
}
}
mesh = defaultMesh(vertices);
}
}
-glm::vec3
+Position3D
RailLink::vehiclePositionOffset() const
{
return RAIL_HEIGHT;
diff --git a/game/network/rail.h b/game/network/rail.h
index 611eb67..4a1932f 100644
--- a/game/network/rail.h
+++ b/game/network/rail.h
@@ -18,6 +18,7 @@ struct Arc;
// A piece of rail track
class RailLinkStraight;
class RailLinkCurve;
+
class RailLink : public virtual Link, public Renderable {
public:
RailLink() = default;
@@ -31,11 +32,12 @@ public:
NO_MOVE(RailLink);
protected:
- [[nodiscard]] glm::vec3 vehiclePositionOffset() const override;
+ [[nodiscard]] Position3D vehiclePositionOffset() const override;
[[nodiscard]] static Mesh::Ptr defaultMesh(const std::span<Vertex> vertices);
Mesh::Ptr mesh;
};
+
RailLink::~RailLink() = default;
class RailLinkStraight : public RailLink, public LinkStraight {
@@ -43,22 +45,22 @@ public:
RailLinkStraight(const Node::Ptr &, const Node::Ptr &);
private:
- RailLinkStraight(Node::Ptr, Node::Ptr, const glm::vec3 & diff);
+ RailLinkStraight(Node::Ptr, Node::Ptr, const Position3D & diff);
};
class RailLinkCurve : public RailLink, public LinkCurve {
public:
- RailLinkCurve(const Node::Ptr &, const Node::Ptr &, glm::vec2);
+ RailLinkCurve(const Node::Ptr &, const Node::Ptr &, Position2D);
private:
- RailLinkCurve(const Node::Ptr &, const Node::Ptr &, glm::vec3, const Arc);
+ RailLinkCurve(const Node::Ptr &, const Node::Ptr &, Position3D, const Arc);
};
class RailLinks : public NetworkOf<RailLink>, public WorldObject {
public:
RailLinks();
- std::shared_ptr<RailLink> addLinksBetween(glm::vec3 start, glm::vec3 end);
+ std::shared_ptr<RailLink> addLinksBetween(Position3D start, Position3D end);
private:
void tick(TickDuration elapsed) override;
diff --git a/game/objective.h b/game/objective.h
index 130015f..f5c6e48 100644
--- a/game/objective.h
+++ b/game/objective.h
@@ -10,6 +10,7 @@ class Orders;
class Objective {
public:
explicit Objective(Orders * os) : orders(os) { }
+
DEFAULT_MOVE_COPY(Objective);
virtual ~Objective() = default;
@@ -19,4 +20,5 @@ public:
Orders * orders;
};
+
using ObjectivePtr = std::unique_ptr<Objective>;
diff --git a/game/orders.h b/game/orders.h
index f29e208..ca5cfdb 100644
--- a/game/orders.h
+++ b/game/orders.h
@@ -10,4 +10,5 @@ public:
[[nodiscard]] Objective * current() const;
Objective * next();
};
+
using OrdersPtr = std::shared_ptr<Orders>;
diff --git a/game/scenary/foliage.cpp b/game/scenary/foliage.cpp
index 702a52c..c258b77 100644
--- a/game/scenary/foliage.cpp
+++ b/game/scenary/foliage.cpp
@@ -15,7 +15,8 @@ void
Foliage::postLoad()
{
texture = getTexture();
- bodyMesh->configureVAO(instanceVAO).addAttribs<glm::mat4>(instances.bufferName(), 1);
+ bodyMesh->configureVAO(instanceVAO)
+ .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(instances.bufferName(), 1);
}
void
diff --git a/game/scenary/foliage.h b/game/scenary/foliage.h
index b72a9c2..bbb6200 100644
--- a/game/scenary/foliage.h
+++ b/game/scenary/foliage.h
@@ -15,7 +15,8 @@ class Foliage : public Asset, public Renderable, public StdTypeDefs<Foliage> {
glVertexArray instanceVAO;
public:
- mutable InstanceVertices<glm::mat4> instances;
+ using LocationVertex = std::pair<glm::mat4, GlobalPosition3D>;
+ mutable InstanceVertices<LocationVertex> instances;
void render(const SceneShader &) const override;
void shadows(const ShadowMapper &) const override;
diff --git a/game/scenary/plant.cpp b/game/scenary/plant.cpp
index 4fb3cb5..b39c28b 100644
--- a/game/scenary/plant.cpp
+++ b/game/scenary/plant.cpp
@@ -2,6 +2,6 @@
#include "location.h"
Plant::Plant(std::shared_ptr<const Foliage> type, const Location & position) :
- type {std::move(type)}, location {this->type->instances.acquire(position.getTransform())}
+ type {std::move(type)}, location {this->type->instances.acquire(position.getRotationTransform(), position.pos)}
{
}
diff --git a/game/scenary/plant.h b/game/scenary/plant.h
index 82ab0e5..77c9ff7 100644
--- a/game/scenary/plant.h
+++ b/game/scenary/plant.h
@@ -7,7 +7,7 @@ class Location;
class Plant : public WorldObject {
std::shared_ptr<const Foliage> type;
- InstanceVertices<glm::mat4>::InstanceProxy location;
+ InstanceVertices<Foliage::LocationVertex>::InstanceProxy location;
void
tick(TickDuration) override
diff --git a/game/selectable.h b/game/selectable.h
index 31287d8..9732dca 100644
--- a/game/selectable.h
+++ b/game/selectable.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config/types.h"
#include <glm/glm.hpp>
#include <special_members.h>
@@ -11,5 +12,5 @@ public:
virtual ~Selectable() = default;
DEFAULT_MOVE_COPY(Selectable);
- [[nodiscard]] virtual bool intersectRay(const Ray &, glm::vec2 *, float *) const = 0;
+ [[nodiscard]] virtual bool intersectRay(const Ray &, Position2D *, float *) const = 0;
};
diff --git a/game/vehicles/linkHistory.cpp b/game/vehicles/linkHistory.cpp
index 2802109..e6bab36 100644
--- a/game/vehicles/linkHistory.cpp
+++ b/game/vehicles/linkHistory.cpp
@@ -8,7 +8,7 @@ LinkHistory::add(const Link::WPtr & l, unsigned char d)
links.insert(links.begin(), {l, d});
const auto lp = l.lock();
totalLen += lp->length;
- while (totalLen >= 1000.F && !links.empty()) {
+ while (totalLen >= 1000000.F && !links.empty()) {
totalLen -= links.back().first.lock()->length;
links.pop_back();
}
diff --git a/game/vehicles/railVehicle.cpp b/game/vehicles/railVehicle.cpp
index 2d820b6..30b615c 100644
--- a/game/vehicles/railVehicle.cpp
+++ b/game/vehicles/railVehicle.cpp
@@ -12,10 +12,22 @@
#include <ray.h>
RailVehicle::RailVehicle(RailVehicleClassPtr rvc) :
- RailVehicleClass::Instance {rvc->instances.acquire()}, rvClass {std::move(rvc)}, location {&LV::body, *this},
+ RailVehicleClass::Instance {rvc->instances.acquire()}, rvClass {std::move(rvc)},
+ location {[this](const BufferedLocation * l) {
+ this->get()->body = l->getRotationTransform();
+ this->get()->bodyPos = l->position();
+ }},
bogies {{
- {&LV::front, *this, glm::vec3 {0, rvClass->wheelBase / 2.F, 0}},
- {&LV::back, *this, glm::vec3 {0, -rvClass->wheelBase / 2.F, 0}},
+ {[this](const BufferedLocation * l) {
+ this->get()->front = l->getRotationTransform();
+ this->get()->frontPos = l->position();
+ },
+ Position3D {0, rvClass->wheelBase / 2.F, 0}},
+ {[this](const BufferedLocation * l) {
+ this->get()->back = l->getRotationTransform();
+ this->get()->backPos = l->position();
+ },
+ Position3D {0, -rvClass->wheelBase / 2.F, 0}},
}}
{
}
@@ -26,29 +38,29 @@ RailVehicle::move(const Train * t, float & trailBy)
const auto overhang {(rvClass->length - rvClass->wheelBase) / 2};
const auto & b1Pos = bogies[0] = t->getBogiePosition(t->linkDist, trailBy += overhang);
const auto & b2Pos = bogies[1] = t->getBogiePosition(t->linkDist, trailBy += rvClass->wheelBase);
- const auto diff = glm::normalize(b2Pos.position() - b1Pos.position());
- location.setLocation((b1Pos.position() + b2Pos.position()) / 2.F, {vector_pitch(diff), vector_yaw(diff), 0});
- trailBy += 0.6F + overhang;
+ const auto diff = glm::normalize(RelativePosition3D(b2Pos.position() - b1Pos.position()));
+ location.setLocation((b1Pos.position() + b2Pos.position()) / 2, {vector_pitch(diff), vector_yaw(diff), 0});
+ trailBy += 600.F + overhang;
}
bool
-RailVehicle::intersectRay(const Ray & ray, glm::vec2 * baryPos, float * distance) const
+RailVehicle::intersectRay(const Ray & ray, Position2D * baryPos, float * distance) const
{
- constexpr const auto X = 1.35F;
+ constexpr const auto X = 1350.F;
const auto Y = this->rvClass->length / 2.F;
- constexpr const auto Z = 3.9F;
- const auto moveBy = location.getTransform();
- const std::array<glm::vec3, 8> cornerVertices {{
- moveBy * glm::vec4 {-X, Y, 0, 1}, // LFB
- moveBy * glm::vec4 {X, Y, 0, 1}, // RFB
- moveBy * glm::vec4 {-X, Y, Z, 1}, // LFT
- moveBy * glm::vec4 {X, Y, Z, 1}, // RFT
- moveBy * glm::vec4 {-X, -Y, 0, 1}, // LBB
- moveBy * glm::vec4 {X, -Y, 0, 1}, // RBB
- moveBy * glm::vec4 {-X, -Y, Z, 1}, // LBT
- moveBy * glm::vec4 {X, -Y, Z, 1}, // RBT
+ constexpr const auto Z = 3900.F;
+ const auto moveBy = location.getRotationTransform();
+ const std::array<Position3D, 8> cornerVertices {{
+ location.position() + GlobalPosition3D(moveBy * glm::vec4 {-X, Y, 0, 1}).xyz(), // LFB
+ location.position() + GlobalPosition3D(moveBy * glm::vec4 {X, Y, 0, 1}).xyz(), // RFB
+ location.position() + GlobalPosition3D(moveBy * glm::vec4 {-X, Y, Z, 1}).xyz(), // LFT
+ location.position() + GlobalPosition3D(moveBy * glm::vec4 {X, Y, Z, 1}).xyz(), // RFT
+ location.position() + GlobalPosition3D(moveBy * glm::vec4 {-X, -Y, 0, 1}).xyz(), // LBB
+ location.position() + GlobalPosition3D(moveBy * glm::vec4 {X, -Y, 0, 1}).xyz(), // RBB
+ location.position() + GlobalPosition3D(moveBy * glm::vec4 {-X, -Y, Z, 1}).xyz(), // LBT
+ location.position() + GlobalPosition3D(moveBy * glm::vec4 {X, -Y, Z, 1}).xyz(), // RBT
}};
- static constexpr const std::array<glm::uvec3, 10> triangles {{
+ static constexpr const std::array<glm::vec<3, uint8_t>, 10> triangles {{
// Front
{0, 1, 2},
{1, 2, 3},
@@ -66,7 +78,7 @@ RailVehicle::intersectRay(const Ray & ray, glm::vec2 * baryPos, float * distance
{3, 6, 7},
}};
return std::any_of(
- triangles.begin(), triangles.end(), [&cornerVertices, &ray, &baryPos, &distance](const glm::uvec3 idx) {
+ triangles.begin(), triangles.end(), [&cornerVertices, &ray, &baryPos, &distance](const auto & idx) {
return glm::intersectRayTriangle(ray.start, ray.direction, cornerVertices[idx[0]],
cornerVertices[idx[1]], cornerVertices[idx[2]], *baryPos, *distance);
});
diff --git a/game/vehicles/railVehicle.h b/game/vehicles/railVehicle.h
index f34643e..20d1ea1 100644
--- a/game/vehicles/railVehicle.h
+++ b/game/vehicles/railVehicle.h
@@ -17,12 +17,12 @@ public:
void move(const Train *, float & trailBy);
- [[nodiscard]] bool intersectRay(const Ray &, glm::vec2 *, float *) const override;
+ [[nodiscard]] bool intersectRay(const Ray &, Position2D *, float *) const override;
RailVehicleClassPtr rvClass;
using LV = RailVehicleClass::LocationVertex;
- using BLocation = BufferedLocationT<glm::mat4 LV::*, RailVehicleClass::Instance &>;
- BLocation location;
- std::array<BLocation, 2> bogies;
+ BufferedLocationUpdater location;
+ std::array<BufferedLocationUpdater, 2> bogies;
};
+
using RailVehiclePtr = std::unique_ptr<RailVehicle>;
diff --git a/game/vehicles/railVehicleClass.cpp b/game/vehicles/railVehicleClass.cpp
index 324148c..7a6a9fe 100644
--- a/game/vehicles/railVehicleClass.cpp
+++ b/game/vehicles/railVehicleClass.cpp
@@ -35,13 +35,15 @@ void
RailVehicleClass::postLoad()
{
texture = getTexture();
- bodyMesh->configureVAO(instanceVAO).addAttribs<LocationVertex, &LocationVertex::body>(instances.bufferName(), 1);
+ bodyMesh->configureVAO(instanceVAO)
+ .addAttribs<LocationVertex, &LocationVertex::body, &LocationVertex::bodyPos>(instances.bufferName(), 1);
bogies.front()
->configureVAO(instancesBogiesVAO.front())
- .addAttribs<LocationVertex, &LocationVertex::front>(instances.bufferName(), 1);
+ .addAttribs<LocationVertex, &LocationVertex::front, &LocationVertex::frontPos>(instances.bufferName(), 1);
bogies.back()
->configureVAO(instancesBogiesVAO.back())
- .addAttribs<LocationVertex, &LocationVertex::back>(instances.bufferName(), 1);
+ .addAttribs<LocationVertex, &LocationVertex::back, &LocationVertex::backPos>(instances.bufferName(), 1);
+ static_assert(sizeof(LocationVertex) == 228UL);
}
void
diff --git a/game/vehicles/railVehicleClass.h b/game/vehicles/railVehicleClass.h
index 80b3fda..913feea 100644
--- a/game/vehicles/railVehicleClass.h
+++ b/game/vehicles/railVehicleClass.h
@@ -20,6 +20,7 @@ public:
struct LocationVertex {
glm::mat4 body, front, back;
+ GlobalPosition3D bodyPos, frontPos, backPos;
};
std::array<Mesh::Ptr, 2> bogies;
@@ -41,4 +42,5 @@ private:
glVertexArray instanceVAO;
std::array<glVertexArray, 2> instancesBogiesVAO;
};
+
using RailVehicleClassPtr = std::shared_ptr<RailVehicleClass>;
diff --git a/game/vehicles/train.cpp b/game/vehicles/train.cpp
index 6f3b036..4aa24dc 100644
--- a/game/vehicles/train.cpp
+++ b/game/vehicles/train.cpp
@@ -20,7 +20,7 @@ Train::getBogiePosition(float linkDist, float dist) const
}
bool
-Train::intersectRay(const Ray & ray, glm::vec2 * baryPos, float * distance) const
+Train::intersectRay(const Ray & ray, Position2D * baryPos, float * distance) const
{
return applyOne(&RailVehicle::intersectRay, ray, baryPos, distance) != end();
}
diff --git a/game/vehicles/train.h b/game/vehicles/train.h
index 20c3bc4..7f0bb99 100644
--- a/game/vehicles/train.h
+++ b/game/vehicles/train.h
@@ -27,7 +27,7 @@ public:
return objects.front()->location;
}
- [[nodiscard]] bool intersectRay(const Ray &, glm::vec2 *, float *) const override;
+ [[nodiscard]] bool intersectRay(const Ray &, Position2D *, float *) const override;
void tick(TickDuration elapsed) override;
void doActivity(Go *, TickDuration) override;
diff --git a/game/vehicles/vehicle.h b/game/vehicles/vehicle.h
index 763ade9..354f904 100644
--- a/game/vehicles/vehicle.h
+++ b/game/vehicles/vehicle.h
@@ -27,4 +27,5 @@ protected:
void move(TickDuration dur);
LinkHistory linkHist;
};
+
using VehicleWPtr = std::weak_ptr<Vehicle>;
diff --git a/gfx/followCameraController.cpp b/gfx/followCameraController.cpp
index 5b08483..aee2187 100644
--- a/gfx/followCameraController.cpp
+++ b/gfx/followCameraController.cpp
@@ -24,11 +24,11 @@ FollowCameraController::updateCamera(Camera * camera) const
break;
case Mode::Ride:
- camera->setView(pos + (up * 4.8F), !-sincosf(rot.y));
+ camera->setView(pos + GlobalPosition3D(up * 4.8F), !-sincosf(rot.y));
break;
case Mode::ISO:
- camera->setView(pos + ((up + north + east) * 40.F), glm::normalize(down + south + west),
+ camera->setView(pos + GlobalPosition3D((up + north + east) * 40.F), glm::normalize(down + south + west),
glm::normalize(up - north - east));
break;
}
diff --git a/gfx/gl/bufferedLocation.cpp b/gfx/gl/bufferedLocation.cpp
index eb3dac3..d6a63b9 100644
--- a/gfx/gl/bufferedLocation.cpp
+++ b/gfx/gl/bufferedLocation.cpp
@@ -1,9 +1,8 @@
#include "bufferedLocation.h"
#include "location.h"
-#include "maths.h"
#include <glm/gtx/transform.hpp>
-BufferedLocation::BufferedLocation(glm::vec3 p, glm::vec3 r) : BufferedLocation {Location {p, r}} { }
+BufferedLocation::BufferedLocation(GlobalPosition3D p, Rotation3D r) : BufferedLocation {Location {p, r}} { }
BufferedLocation::BufferedLocation(const Location & l) : loc {l} { }
@@ -20,20 +19,20 @@ BufferedLocation::operator=(const Location & l)
return *this;
}
-glm::vec3
+GlobalPosition3D
BufferedLocation::position() const
{
return loc.pos;
}
-glm::vec3
+Position3D
BufferedLocation::rotation() const
{
return loc.rot;
}
void
-BufferedLocation::setPosition(glm::vec3 p, bool update)
+BufferedLocation::setPosition(GlobalPosition3D p, bool update)
{
loc.pos = p;
if (update) {
@@ -42,7 +41,7 @@ BufferedLocation::setPosition(glm::vec3 p, bool update)
}
void
-BufferedLocation::setRotation(glm::vec3 r, bool update)
+BufferedLocation::setRotation(Position3D r, bool update)
{
loc.rot = r;
if (update) {
@@ -51,7 +50,7 @@ BufferedLocation::setRotation(glm::vec3 r, bool update)
}
void
-BufferedLocation::setLocation(glm::vec3 p, glm::vec3 r)
+BufferedLocation::setLocation(GlobalPosition3D p, Rotation3D r)
{
loc.pos = p;
loc.rot = r;
@@ -59,7 +58,13 @@ BufferedLocation::setLocation(glm::vec3 p, glm::vec3 r)
}
glm::mat4
-BufferedLocation::getTransform() const
+BufferedLocation::getRotationTransform() const
{
- return loc.getTransform();
+ return loc.getRotationTransform();
+}
+
+void
+BufferedLocationUpdater::updateBuffer() const
+{
+ onUpdate(this);
}
diff --git a/gfx/gl/bufferedLocation.h b/gfx/gl/bufferedLocation.h
index 8096489..87b957f 100644
--- a/gfx/gl/bufferedLocation.h
+++ b/gfx/gl/bufferedLocation.h
@@ -4,11 +4,11 @@
#include <functional>
#include <glm/mat4x4.hpp>
#include <glm/vec3.hpp>
-#include <tuple>
+#include <utility>
class BufferedLocation {
public:
- BufferedLocation(glm::vec3 = {}, glm::vec3 = {});
+ BufferedLocation(GlobalPosition3D = {}, Rotation3D = {});
BufferedLocation(const Location &);
virtual ~BufferedLocation() = default;
@@ -16,25 +16,25 @@ public:
operator const Location &() const;
- glm::vec3 position() const;
- glm::vec3 rotation() const;
- void setPosition(glm::vec3, bool update = true);
- void setRotation(glm::vec3, bool update = true);
- void setLocation(glm::vec3, glm::vec3);
+ [[nodiscard]] GlobalPosition3D position() const;
+ [[nodiscard]] Rotation3D rotation() const;
+ void setPosition(GlobalPosition3D, bool update = true);
+ void setRotation(Rotation3D, bool update = true);
+ void setLocation(GlobalPosition3D, Rotation3D);
- glm::mat4 getTransform() const;
+ [[nodiscard]] glm::mat4 getRotationTransform() const;
private:
- virtual void updateBuffer() = 0;
+ virtual void updateBuffer() const = 0;
Location loc;
};
-template<typename... Target> class BufferedLocationT : public BufferedLocation {
+class BufferedLocationUpdater : public BufferedLocation {
public:
template<typename... LocationArgs>
- BufferedLocationT(Target &&... target, LocationArgs &&... t) :
- BufferedLocation {std::forward<LocationArgs>(t)...}, target {std::forward<Target>(target)...}
+ BufferedLocationUpdater(std::function<void(const BufferedLocation *)> onUpdate, LocationArgs &&... t) :
+ BufferedLocation {std::forward<LocationArgs>(t)...}, onUpdate {std::move(onUpdate)}
{
updateBuffer();
}
@@ -42,11 +42,7 @@ public:
using BufferedLocation::operator=;
private:
- void
- updateBuffer() override
- {
- std::apply(std::invoke<const Target &...>, target) = getTransform();
- }
+ void updateBuffer() const override;
- std::tuple<Target...> target;
+ std::function<void(const BufferedLocation *)> onUpdate;
};
diff --git a/gfx/gl/camera.cpp b/gfx/gl/camera.cpp
index c4c9544..15f76c4 100644
--- a/gfx/gl/camera.cpp
+++ b/gfx/gl/camera.cpp
@@ -2,19 +2,19 @@
#include <collections.h>
#include <glm/gtx/intersect.hpp> // IWYU pragma: keep
#include <glm/gtx/transform.hpp> // IWYU pragma: keep
+#include <math.h>
#include <maths.h>
#include <ray.h>
-Camera::Camera(glm::vec3 pos, float fov, float aspect, float zNear, float zFar) :
+Camera::Camera(Position3D pos, Angle fov, Angle aspect, Distance zNear, Distance zFar) :
position {pos}, forward {::north}, up {::up}, near {zNear}, far {zFar},
- projection {glm::perspective(fov, aspect, zNear, zFar)},
- viewProjection {projection * glm::lookAt(position, position + forward, up)},
- inverseViewProjection {glm::inverse(viewProjection)}
+ projection {glm::perspective(fov, aspect, zNear, zFar)}, viewProjection {}, inverseViewProjection {}
{
+ updateView();
}
Ray
-Camera::unProject(const glm::vec2 & mouse) const
+Camera::unProject(const ScreenRelCoord & mouse) const
{
static constexpr const glm::vec4 screen {0, 0, 1, 1};
const auto mouseProjection = glm::lookAt(::origin, forward, up);
@@ -24,12 +24,12 @@ Camera::unProject(const glm::vec2 & mouse) const
void
Camera::updateView()
{
- viewProjection = projection * glm::lookAt(position, position + forward, up);
- inverseViewProjection = glm::inverse(viewProjection);
+ viewProjection = projection * glm::lookAt(origin, forward, up);
+ inverseViewProjection = glm::inverse(projection * glm::lookAt(position, position + forward, up));
}
-glm::vec3
-Camera::upFromForward(const glm::vec3 & forward)
+Direction3D
+Camera::upFromForward(const Direction3D & forward)
{
const auto right = glm::cross(forward, ::down);
return glm::cross(forward, right);
@@ -38,11 +38,11 @@ Camera::upFromForward(const glm::vec3 & forward)
std::array<glm::vec4, 4>
Camera::extentsAtDist(const float dist) const
{
- const auto clampToSeaFloor = [this, dist](const glm::vec3 & target) {
+ const auto clampToSeaFloor = [this, dist](const Position3D & target) {
if (target.z < -1.5F) {
const auto vec = glm::normalize(target - position);
- constexpr glm::vec3 seafloor {0, 0, -1.5F};
- float outdist;
+ constexpr Position3D seafloor {0, 0, -1.5F};
+ float outdist {};
if (glm::intersectRayPlane(position, vec, seafloor, ::up, outdist)) {
return (vec * outdist + position) ^ outdist;
}
diff --git a/gfx/gl/camera.h b/gfx/gl/camera.h
index 3f1c3a7..469df0d 100644
--- a/gfx/gl/camera.h
+++ b/gfx/gl/camera.h
@@ -1,60 +1,69 @@
#pragma once
+#include "config/types.h"
#include <glm/glm.hpp>
#include <maths.h>
#include <ray.h>
class Camera {
public:
- Camera(glm::vec3 pos, float fov, float aspect, float zNear, float zFar);
+ Camera(Position3D, Angle fov, Angle aspect, Distance zNear, Distance zFar);
[[nodiscard]] glm::mat4
getViewProjection() const
{
return viewProjection;
}
- [[nodiscard]] Ray unProject(const glm::vec2 &) const;
+
+ [[nodiscard]] Ray unProject(const ScreenRelCoord &) const;
void
- setPosition(const glm::vec3 & p)
+ setPosition(const Position3D & p)
{
position = p;
updateView();
}
+
void
- setForward(const glm::vec3 & f)
+ setForward(const Direction3D & f)
{
setForward(f, upFromForward(f));
}
+
void
- setForward(const glm::vec3 & f, const glm::vec3 & u)
+ setForward(const Direction3D & f, const Direction3D & u)
{
forward = f;
up = u;
updateView();
}
+
void
- setView(const glm::vec3 & p, const glm::vec3 & f)
+ setView(const Position3D & p, const Direction3D & f)
{
position = p;
setForward(f);
}
+
void
- setView(const glm::vec3 & p, const glm::vec3 & f, const glm::vec3 & u)
+ setView(const Position3D & p, const Direction3D & f, const Direction3D & u)
{
position = p;
setView(f, u);
}
+
void
- lookAt(const glm::vec3 & target)
+ lookAt(const Position3D & target)
{
setForward(glm::normalize(target - position));
}
+
[[nodiscard]] auto
getForward() const
{
return forward;
}
+
[[nodiscard]] auto
getPosition() const
{
@@ -63,14 +72,14 @@ public:
[[nodiscard]] std::array<glm::vec4, 4> extentsAtDist(float) const;
- [[nodiscard]] static glm::vec3 upFromForward(const glm::vec3 & forward);
+ [[nodiscard]] static Direction3D upFromForward(const Direction3D & forward);
private:
void updateView();
- glm::vec3 position;
- glm::vec3 forward;
- glm::vec3 up;
+ Position3D position;
+ Direction3D forward;
+ Direction3D up;
float near, far;
glm::mat4 projection;
diff --git a/gfx/gl/instanceVertices.h b/gfx/gl/instanceVertices.h
index 7b0341b..a89aa78 100644
--- a/gfx/gl/instanceVertices.h
+++ b/gfx/gl/instanceVertices.h
@@ -13,9 +13,11 @@ public:
class [[nodiscard]] InstanceProxy {
public:
InstanceProxy(InstanceVertices * iv, std::size_t idx) : instances {iv}, index {idx} { }
+
InstanceProxy(InstanceProxy && other) : instances {std::exchange(other.instances, nullptr)}, index {other.index}
{
}
+
NO_COPY(InstanceProxy);
~InstanceProxy()
@@ -35,6 +37,7 @@ public:
index = other.index;
return *this;
}
+
template<typename U>
T &
operator=(U && v)
@@ -42,40 +45,46 @@ public:
return instances->lookup(index) = std::forward<U>(v);
}
- [[nodiscard]]
- operator T &()
+ [[nodiscard]] operator T &()
{
return instances->lookup(index);
}
+
[[nodiscard]] operator const T &() const
{
return instances->lookup(index);
}
+
[[nodiscard]] T *
get()
{
return &instances->lookup(index);
}
+
[[nodiscard]] const T *
get() const
{
return &instances->lookup(index);
}
+
[[nodiscard]] T *
operator->()
{
return get();
}
+
[[nodiscard]] const T *
operator->() const
{
return get();
}
+
[[nodiscard]] T &
operator*()
{
return instances->lookup(index);
}
+
[[nodiscard]] const T &
operator*() const
{
diff --git a/gfx/gl/program.h b/gfx/gl/program.h
index 76b6742..1a1c306 100644
--- a/gfx/gl/program.h
+++ b/gfx/gl/program.h
@@ -9,6 +9,7 @@
class Location;
using ProgramRef = glRef<GLuint, &glCreateProgram, &glDeleteProgram>;
+
class Program {
public:
template<typename... S> explicit Program(const S &... srcs)
@@ -16,12 +17,14 @@ public:
(glAttachShader(m_program, srcs.compile()), ...);
linkAndValidate();
}
+
virtual ~Program() = default;
DEFAULT_MOVE_NO_COPY(Program);
class UniformLocation {
public:
UniformLocation(GLuint prog, const char * name);
+
// NOLINTNEXTLINE(hicpp-explicit-conversions)
operator auto() const
{
diff --git a/gfx/gl/sceneProvider.cpp b/gfx/gl/sceneProvider.cpp
index 0163b36..2e8604c 100644
--- a/gfx/gl/sceneProvider.cpp
+++ b/gfx/gl/sceneProvider.cpp
@@ -7,6 +7,7 @@ SceneProvider::environment(const SceneShader &, const SceneRenderer & renderer)
renderer.setAmbientLight({0.5F, 0.5F, 0.5F});
renderer.setDirectionalLight({0.6F, 0.6F, 0.6F}, {-1, 1, -1}, *this);
}
+
void
SceneProvider::shadows(const ShadowMapper &) const
{
diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp
index aa9453a..53178e5 100644
--- a/gfx/gl/sceneRenderer.cpp
+++ b/gfx/gl/sceneRenderer.cpp
@@ -13,8 +13,9 @@ static constexpr const std::array<const glm::i8vec4, 4> displayVAOdata {{
{1, 1, 1, 1},
{1, -1, 1, 0},
}};
-SceneRenderer::SceneRenderer(glm::ivec2 s, GLuint o) :
- camera {{-1250.0F, -1250.0F, 35.0F}, quarter_pi, ratio(s), 0.1F, 10000.0F}, size {s}, output {o},
+
+SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o) :
+ camera {{-1250000.0F, -1250000.0F, 35.0F}, quarter_pi, ratio(s), 100.F, 10000000.0F}, size {s}, output {o},
lighting {lighting_vs, lighting_fs}, shadowMapper {{2048, 2048}}
{
shader.setViewPort({0, 0, size.x, size.y});
@@ -51,7 +52,7 @@ SceneRenderer::SceneRenderer(glm::ivec2 s, GLuint o) :
void
SceneRenderer::render(const SceneProvider & scene) const
{
- shader.setViewProjection(camera.getViewProjection());
+ shader.setViewProjection(camera.getPosition(), camera.getViewProjection());
glViewport(0, 0, size.x, size.y);
// Geometry pass
@@ -96,7 +97,7 @@ SceneRenderer::render(const SceneProvider & scene) const
}
void
-SceneRenderer::setAmbientLight(const glm::vec3 & colour) const
+SceneRenderer::setAmbientLight(const RGB & colour) const
{
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glClearColor(colour.r, colour.g, colour.b, 1.0F);
@@ -104,8 +105,7 @@ SceneRenderer::setAmbientLight(const glm::vec3 & colour) const
}
void
-SceneRenderer::setDirectionalLight(
- const glm::vec3 & colour, const glm::vec3 & direction, const SceneProvider & scene) const
+SceneRenderer::setDirectionalLight(const RGB & colour, const Direction3D & direction, const SceneProvider & scene) const
{
if (colour.r > 0 || colour.g > 0 || colour.b > 0) {
const auto lvp = shadowMapper.update(scene, direction, camera);
@@ -134,8 +134,8 @@ SceneRenderer::DirectionalLightProgram::DirectionalLightProgram() :
}
void
-SceneRenderer::DirectionalLightProgram::setDirectionalLight(const glm::vec3 & c, const glm::vec3 & d,
- const std::span<const glm::mat4x4> lvp, const std::span<const glm::vec4> shadowMapRegions,
+SceneRenderer::DirectionalLightProgram::setDirectionalLight(const RGB & c, const Direction3D & d,
+ const std::span<const glm::mat4x4> lvp, const std::span<const TextureRelRegion> shadowMapRegions,
std::size_t maps) const
{
glUniform3fv(colourLoc, 1, glm::value_ptr(c));
diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h
index d4af665..30fd8d3 100644
--- a/gfx/gl/sceneRenderer.h
+++ b/gfx/gl/sceneRenderer.h
@@ -11,34 +11,36 @@
class SceneRenderer {
public:
- explicit SceneRenderer(glm::ivec2 size, GLuint output);
+ explicit SceneRenderer(ScreenAbsCoord size, GLuint output);
void render(const SceneProvider &) const;
- void setAmbientLight(const glm::vec3 & colour) const;
- void setDirectionalLight(const glm::vec3 & colour, const glm::vec3 & direction, const SceneProvider &) const;
+ void setAmbientLight(const RGB & colour) const;
+ void setDirectionalLight(const RGB & colour, const Direction3D & direction, const SceneProvider &) const;
Camera camera;
private:
void renderQuad() const;
- glm::ivec2 size;
+ ScreenAbsCoord size;
GLuint output;
glFrameBuffer gBuffer;
glTexture gPosition, gNormal, gAlbedoSpec, gIllumination;
glRenderBuffer depth;
+
class DeferredLightProgram : public Program {
public:
using Program::Program;
using Program::use;
};
+
class DirectionalLightProgram : public Program {
public:
DirectionalLightProgram();
using Program::use;
- void setDirectionalLight(const glm::vec3 &, const glm::vec3 &, const std::span<const glm::mat4x4>,
- const std::span<const glm::vec4>, std::size_t maps) const;
+ void setDirectionalLight(const RGB &, const Direction3D &, const std::span<const glm::mat4x4>,
+ const std::span<const TextureRelRegion>, std::size_t maps) const;
private:
RequiredUniformLocation directionLoc, colourLoc, lightViewProjectionLoc, lightViewProjectionCountLoc,
diff --git a/gfx/gl/sceneShader.cpp b/gfx/gl/sceneShader.cpp
index 1354611..59a9748 100644
--- a/gfx/gl/sceneShader.cpp
+++ b/gfx/gl/sceneShader.cpp
@@ -26,16 +26,16 @@ SceneShader::SceneShader() :
}
void
-SceneShader::setViewProjection(const glm::mat4 & viewProjection) const
+SceneShader::setViewProjection(const Position3D & viewPoint, const glm::mat4 & viewProjection) const
{
for (const auto & prog : std::array<const SceneProgram *, 7> {
&basic, &basicInst, &water, &landmass, &absolute, &pointLight, &spotLight}) {
- prog->setViewProjection(viewProjection);
+ prog->setViewProjection(viewPoint, viewProjection);
}
}
void
-SceneShader::setViewPort(const glm::ivec4 & viewPort) const
+SceneShader::setViewPort(const ViewPort & viewPort) const
{
for (const auto & prog : std::array<const SceneProgram *, 7> {
&basic, &basicInst, &water, &landmass, &absolute, &pointLight, &spotLight}) {
@@ -44,14 +44,15 @@ SceneShader::setViewPort(const glm::ivec4 & viewPort) const
}
void
-SceneShader::SceneProgram::setViewProjection(const glm::mat4 & viewProjection) const
+SceneShader::SceneProgram::setViewProjection(const Position3D & viewPoint, const glm::mat4 & viewProjection) const
{
glUseProgram(*this);
glUniformMatrix4fv(viewProjectionLoc, 1, GL_FALSE, glm::value_ptr(viewProjection));
+ glUniform3fv(viewPointLoc, 1, glm::value_ptr(viewPoint));
}
void
-SceneShader::SceneProgram::setViewPort(const glm::ivec4 & viewPort) const
+SceneShader::SceneProgram::setViewPort(const ViewPort & viewPort) const
{
if (viewPortLoc >= 0) {
glUseProgram(*this);
@@ -59,13 +60,16 @@ SceneShader::SceneProgram::setViewPort(const glm::ivec4 & viewPort) const
}
}
-SceneShader::BasicProgram::BasicProgram() : SceneProgram {dynamicPoint_vs, material_fs}, modelLoc {*this, "model"} { }
+SceneShader::BasicProgram::BasicProgram() :
+ SceneProgram {dynamicPoint_vs, material_fs}, modelLoc {*this, "model"}, modelPosLoc {*this, "modelPos"}
+{
+}
void
SceneShader::BasicProgram::setModel(Location const & location) const
{
- const auto model {glm::translate(location.pos) * rotate_ypr(location.rot)};
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
+ glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(rotate_ypr(location.rot)));
+ glUniform3iv(modelPosLoc, 1, glm::value_ptr(location.pos));
}
void
@@ -81,38 +85,40 @@ void
SceneShader::WaterProgram::use(float waveCycle) const
{
Program::use();
- glm::vec3 waves {waveCycle, 0.F, 0.F};
+ Position3D waves {waveCycle, 0.F, 0.F};
glUniform3fv(waveLoc, 1, glm::value_ptr(waves));
}
SceneShader::PointLightShader::PointLightShader() :
- SceneProgram {pointLight_vs, pointLight_gs, pointLight_fs}, colourLoc {*this, "colour"}, kqLoc {*this, "kq"}
+ SceneProgram {pointLight_vs, pointLight_gs, pointLight_fs}, colourLoc {*this, "colour"}, kqLoc {*this, "kq"},
+ viewPointLoc {*this, "viewPoint"}
{
- VertexArrayObject {va}.addAttribs<glm::vec3>(b);
+ VertexArrayObject {va}.addAttribs<Position3D>(b);
}
void
-SceneShader::PointLightShader::add(const glm::vec3 & position, const glm::vec3 & colour, const float kq) const
+SceneShader::PointLightShader::add(const Position3D & position, const RGB & colour, const float kq) const
{
Program::use();
glBindVertexArray(va);
glBindBuffer(GL_ARRAY_BUFFER, b);
glUniform3fv(colourLoc, 1, glm::value_ptr(colour));
glUniform1f(kqLoc, kq);
- glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3), glm::value_ptr(position), GL_DYNAMIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(Position3D), glm::value_ptr(position), GL_DYNAMIC_DRAW);
glDrawArrays(GL_POINTS, 0, 1);
}
SceneShader::SpotLightShader::SpotLightShader() :
SceneProgram {spotLight_vs, spotLight_gs, spotLight_fs}, directionLoc {*this, "v_direction"},
- colourLoc {*this, "colour"}, kqLoc {*this, "kq"}, arcLoc {*this, "arc"}
+ colourLoc {*this, "colour"}, kqLoc {*this, "kq"}, arcLoc {*this, "arc"}, viewPointLoc {*this, "viewPoint"}
+
{
- using v3pair = std::pair<glm::vec3, glm::vec3>;
+ using v3pair = std::pair<Position3D, Direction3D>;
VertexArrayObject {va}.addAttribs<v3pair, &v3pair::first, &v3pair::second>(b);
}
void
-SceneShader::SpotLightShader::add(const glm::vec3 & position, const glm::vec3 & direction, const glm::vec3 & colour,
+SceneShader::SpotLightShader::add(const Position3D & position, const Direction3D & direction, const RGB & colour,
const float kq, const float arc) const
{
Program::use();
@@ -122,6 +128,6 @@ SceneShader::SpotLightShader::add(const glm::vec3 & position, const glm::vec3 &
glUniform3fv(directionLoc, 1, glm::value_ptr(direction));
glUniform1f(kqLoc, kq);
glUniform1f(arcLoc, arc);
- glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3), glm::value_ptr(position), GL_DYNAMIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(Position3D), glm::value_ptr(position), GL_DYNAMIC_DRAW);
glDrawArrays(GL_POINTS, 0, 1);
}
diff --git a/gfx/gl/sceneShader.h b/gfx/gl/sceneShader.h
index ead184e..83c234c 100644
--- a/gfx/gl/sceneShader.h
+++ b/gfx/gl/sceneShader.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config/types.h"
#include "program.h"
#include <glArrays.h>
@@ -10,15 +11,16 @@ class SceneShader {
public:
template<typename... S>
inline explicit SceneProgram(const S &... srcs) :
- Program {srcs...}, viewProjectionLoc {*this, "viewProjection"}, viewPortLoc {*this, "viewPort"}
+ Program {srcs...}, viewProjectionLoc {*this, "viewProjection"}, viewPointLoc {*this, "viewPoint"},
+ viewPortLoc {*this, "viewPort"}
{
}
- void setViewProjection(const glm::mat4 &) const;
- void setViewPort(const glm::ivec4 &) const;
+ void setViewProjection(const Position3D &, const glm::mat4 &) const;
+ void setViewPort(const ViewPort &) const;
private:
- RequiredUniformLocation viewProjectionLoc;
+ RequiredUniformLocation viewProjectionLoc, viewPointLoc;
UniformLocation viewPortLoc;
};
@@ -30,6 +32,7 @@ class SceneShader {
private:
RequiredUniformLocation modelLoc;
+ RequiredUniformLocation modelPosLoc;
};
class AbsolutePosProgram : public SceneProgram {
@@ -52,11 +55,12 @@ class SceneShader {
public:
PointLightShader();
- void add(const glm::vec3 & position, const glm::vec3 & colour, const float kq) const;
+ void add(const Position3D & position, const RGB & colour, const float kq) const;
private:
UniformLocation colourLoc;
UniformLocation kqLoc;
+ UniformLocation viewPointLoc;
glVertexArray va;
glBuffer b;
};
@@ -65,7 +69,7 @@ class SceneShader {
public:
SpotLightShader();
- void add(const glm::vec3 & position, const glm::vec3 & direction, const glm::vec3 & colour, const float kq,
+ void add(const Position3D & position, const Direction3D & direction, const RGB & colour, const float kq,
const float arc) const;
private:
@@ -73,6 +77,7 @@ class SceneShader {
UniformLocation colourLoc;
UniformLocation kqLoc;
UniformLocation arcLoc;
+ UniformLocation viewPointLoc;
glVertexArray va;
glBuffer b;
};
@@ -86,6 +91,6 @@ public:
PointLightShader pointLight;
SpotLightShader spotLight;
- void setViewProjection(const glm::mat4 & viewProjection) const;
- void setViewPort(const glm::ivec4 & viewPort) const;
+ void setViewProjection(const Position3D & viewPoint, const glm::mat4 & viewProjection) const;
+ void setViewPort(const ViewPort & viewPort) const;
};
diff --git a/gfx/gl/shader.h b/gfx/gl/shader.h
index 0810e6b..cff2281 100644
--- a/gfx/gl/shader.h
+++ b/gfx/gl/shader.h
@@ -8,6 +8,7 @@
class Shader {
public:
using ShaderRef = glRef<GLuint, &glCreateShader, &glDeleteShader>;
+
constexpr Shader(const GLchar * text, GLint len, GLuint type) : text {text}, len {len}, type {type} { }
[[nodiscard]] ShaderRef compile() const;
diff --git a/gfx/gl/shaders/commonPoint.glsl b/gfx/gl/shaders/commonPoint.glsl
index 35510e1..046da27 100644
--- a/gfx/gl/shaders/commonPoint.glsl
+++ b/gfx/gl/shaders/commonPoint.glsl
@@ -24,5 +24,5 @@ main()
Colour = colour;
Material = getMaterialDetail(material);
- gl_Position = viewProjection * worldPos;
+ gl_Position = viewProjection * vec4(FragPos - viewPoint + modelPos, 1);
}
diff --git a/gfx/gl/shaders/commonShadowPoint.glsl b/gfx/gl/shaders/commonShadowPoint.glsl
index c7cbd3e..216642e 100644
--- a/gfx/gl/shaders/commonShadowPoint.glsl
+++ b/gfx/gl/shaders/commonShadowPoint.glsl
@@ -1,6 +1,7 @@
void
main()
{
- gl_Position = viewProjection * model * vec4(position, 1.0);
+ vec4 worldPos = model * vec4(position, 1.0);
+ gl_Position = viewProjection * vec4(worldPos.xyz - viewPoint + modelPos, 1);
gl_Position.z = max(gl_Position.z, -1);
}
diff --git a/gfx/gl/shaders/dynamicPoint.vs b/gfx/gl/shaders/dynamicPoint.vs
index 961535c..667f247 100644
--- a/gfx/gl/shaders/dynamicPoint.vs
+++ b/gfx/gl/shaders/dynamicPoint.vs
@@ -5,6 +5,8 @@ include(`meshIn.glsl')
include(`materialInterface.glsl')
uniform mat4 viewProjection;
+uniform vec3 viewPoint;
uniform mat4 model;
+uniform ivec3 modelPos;
include(`commonPoint.glsl')
diff --git a/gfx/gl/shaders/dynamicPointInst.vs b/gfx/gl/shaders/dynamicPointInst.vs
index 2d6cee5..adf39bd 100644
--- a/gfx/gl/shaders/dynamicPointInst.vs
+++ b/gfx/gl/shaders/dynamicPointInst.vs
@@ -5,6 +5,8 @@ include(`meshIn.glsl')
include(`materialInterface.glsl')
uniform mat4 viewProjection;
+uniform vec3 viewPoint;
layout(location = 5) in mat4 model;
+layout(location = 9) in ivec3 modelPos;
include(`commonPoint.glsl')
diff --git a/gfx/gl/shaders/fixedPoint.vs b/gfx/gl/shaders/fixedPoint.vs
index ed78c96..6e1ab49 100644
--- a/gfx/gl/shaders/fixedPoint.vs
+++ b/gfx/gl/shaders/fixedPoint.vs
@@ -5,6 +5,8 @@ include(`meshIn.glsl')
include(`materialInterface.glsl')
uniform mat4 viewProjection;
+uniform vec3 viewPoint;
const mat4 model = mat4(1);
+const vec3 modelPos = ivec3(0);
include(`commonPoint.glsl')
diff --git a/gfx/gl/shaders/landmass.fs b/gfx/gl/shaders/landmass.fs
index 4dc92bb..9865d11 100644
--- a/gfx/gl/shaders/landmass.fs
+++ b/gfx/gl/shaders/landmass.fs
@@ -11,9 +11,9 @@ const vec3 rock = vec3(.2, .2, .1);
const vec3 sand = vec3(.76, .7, .5);
const vec3 snow = vec3(.97, .97, .99);
-const float beachline = .5;
-const float snowline_low = 28;
-const float snowline_high = 30;
+const float beachline = 500;
+const float snowline_low = 28000;
+const float snowline_high = 30000;
const float slope_min = .99;
const float slope_mid = .95;
diff --git a/gfx/gl/shaders/pointLight.fs b/gfx/gl/shaders/pointLight.fs
index bd32c05..1a68df8 100644
--- a/gfx/gl/shaders/pointLight.fs
+++ b/gfx/gl/shaders/pointLight.fs
@@ -26,5 +26,5 @@ main()
if (normalDot < 0) {
discard;
}
- FragColor = (colour * normalDot) / (1 + (kq * pow(lightDist, 2)));
+ FragColor = (colour * normalDot) / (1 + (kq * pow(lightDist / 1000.0, 2)));
}
diff --git a/gfx/gl/shaders/pointLight.gs b/gfx/gl/shaders/pointLight.gs
index 03d131d..ec089f5 100644
--- a/gfx/gl/shaders/pointLight.gs
+++ b/gfx/gl/shaders/pointLight.gs
@@ -19,6 +19,7 @@ const vec3[] cube = vec3[]( // http://www.cs.umd.edu/gvil/papers/av_ts.pdf
vec3(1, 1, -1) // Back-top-right
);
uniform mat4 viewProjection;
+uniform vec3 viewPoint;
in vec3 centre[];
in float size[];
diff --git a/gfx/gl/shaders/pointLight.vs b/gfx/gl/shaders/pointLight.vs
index 35682fa..7694a25 100644
--- a/gfx/gl/shaders/pointLight.vs
+++ b/gfx/gl/shaders/pointLight.vs
@@ -4,6 +4,7 @@ layout(location = 0) in vec3 position;
uniform vec3 colour;
uniform float kq;
+uniform vec3 viewPoint;
out vec3 centre;
out float size;
@@ -12,6 +13,6 @@ void
main()
{
centre = position;
- size = (8 * sqrt(max(max(colour.r, colour.g), colour.b))) / sqrt(kq);
- gl_Position = vec4(centre, 0);
+ size = (8000 * sqrt(max(max(colour.r, colour.g), colour.b))) / sqrt(kq);
+ gl_Position = vec4(centre - viewPoint, 0);
}
diff --git a/gfx/gl/shaders/shadowDynamicPoint.vs b/gfx/gl/shaders/shadowDynamicPoint.vs
index f3ed533..e20d31a 100644
--- a/gfx/gl/shaders/shadowDynamicPoint.vs
+++ b/gfx/gl/shaders/shadowDynamicPoint.vs
@@ -3,6 +3,8 @@
include(`meshIn.glsl')
uniform mat4 viewProjection;
+uniform vec3 viewPoint;
uniform mat4 model;
+uniform ivec3 modelPos;
include(`commonShadowPoint.glsl')
diff --git a/gfx/gl/shaders/shadowDynamicPointInst.vs b/gfx/gl/shaders/shadowDynamicPointInst.vs
index 1bf74ef..ab3e976 100644
--- a/gfx/gl/shaders/shadowDynamicPointInst.vs
+++ b/gfx/gl/shaders/shadowDynamicPointInst.vs
@@ -3,6 +3,8 @@
include(`meshIn.glsl')
uniform mat4 viewProjection;
+uniform vec3 viewPoint;
layout(location = 5) in mat4 model;
+layout(location = 9) in ivec3 modelPos;
include(`commonShadowPoint.glsl')
diff --git a/gfx/gl/shaders/shadowFixedPoint.vs b/gfx/gl/shaders/shadowFixedPoint.vs
index 8921707..a9fb4a3 100644
--- a/gfx/gl/shaders/shadowFixedPoint.vs
+++ b/gfx/gl/shaders/shadowFixedPoint.vs
@@ -3,6 +3,8 @@
include(`meshIn.glsl')
uniform mat4 viewProjection;
+uniform vec3 viewPoint;
const mat4 model = mat4(1);
+const ivec3 modelPos = ivec3(0);
include(`commonShadowPoint.glsl')
diff --git a/gfx/gl/shaders/spotLight.fs b/gfx/gl/shaders/spotLight.fs
index add86fd..78b8f72 100644
--- a/gfx/gl/shaders/spotLight.fs
+++ b/gfx/gl/shaders/spotLight.fs
@@ -30,5 +30,5 @@ main()
if (normalDot < 0) {
discard;
}
- FragColor = (colour * normalDot) / (1 + (kq * pow(lightDist, 2)));
+ FragColor = (colour * normalDot) / (1 + (kq * pow(lightDist / 1000.0, 2)));
}
diff --git a/gfx/gl/shaders/spotLight.gs b/gfx/gl/shaders/spotLight.gs
index ad65675..0529614 100644
--- a/gfx/gl/shaders/spotLight.gs
+++ b/gfx/gl/shaders/spotLight.gs
@@ -10,6 +10,7 @@ const vec3[] pyramid = vec3[]( // four-sided
vec3(1, -1, 1) // Front-right
);
uniform mat4 viewProjection;
+uniform vec3 viewPoint;
uniform float arc;
in vec3 position[];
diff --git a/gfx/gl/shaders/spotLight.vs b/gfx/gl/shaders/spotLight.vs
index dca0854..08197a4 100644
--- a/gfx/gl/shaders/spotLight.vs
+++ b/gfx/gl/shaders/spotLight.vs
@@ -6,6 +6,7 @@ uniform vec3 v_direction;
uniform vec3 colour;
uniform float kq;
uniform float arc;
+uniform vec3 viewPoint;
out vec3 position;
out vec3 direction;
@@ -17,7 +18,7 @@ main()
{
position = v_position;
direction = normalize(v_direction);
- size = (8 * sqrt(max(max(colour.r, colour.g), colour.b))) / sqrt(kq);
+ size = (8000 * sqrt(max(max(colour.r, colour.g), colour.b))) / sqrt(kq);
cosarc = cos(arc / 2);
- gl_Position = vec4(position, 0);
+ gl_Position = vec4(position - viewPoint, 0);
}
diff --git a/gfx/gl/shaders/water.fs b/gfx/gl/shaders/water.fs
index 04aa94c..2ccc924 100644
--- a/gfx/gl/shaders/water.fs
+++ b/gfx/gl/shaders/water.fs
@@ -13,5 +13,5 @@ main()
gPosition = vec4(FragPos, 1);
gNormal = vec4(Normal, 1);
gAlbedoSpec = texture(texture0, TexCoords);
- gAlbedoSpec.a *= clamp(-FragPos.z * .7, .1, 1.0);
+ gAlbedoSpec.a *= clamp(-FragPos.z * .0007, .1, 1.0);
}
diff --git a/gfx/gl/shaders/water.vs b/gfx/gl/shaders/water.vs
index a21b49f..03eabb2 100644
--- a/gfx/gl/shaders/water.vs
+++ b/gfx/gl/shaders/water.vs
@@ -4,17 +4,18 @@ include(`meshIn.glsl')
include(`materialInterface.glsl')
uniform mat4 viewProjection;
+uniform vec3 viewPoint;
uniform vec3 waves;
void
main()
{
- vec4 wpos = vec4(position.x + cos(waves.x), position.y + cos(waves.x * waves.y / 2),
- cos(waves.x + position.x + (position.y / 8)) * .3, 1.0);
+ vec3 wpos = vec3(position.x + (cos(waves.x) * 1000.0), position.y + (cos(waves.x * waves.y / 2) * 1000.0),
+ cos(waves.x + (position.x / 1000.0) + (position.y * 125.0)) * 300.0);
FragPos = vec3(wpos.xy, position.z);
TexCoords = texCoord;
Normal = normal;
- gl_Position = viewProjection * wpos;
+ gl_Position = viewProjection * vec4(wpos - viewPoint, 1.0);
}
diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp
index 55d986c..07db6a1 100644
--- a/gfx/gl/shadowMapper.cpp
+++ b/gfx/gl/shadowMapper.cpp
@@ -15,7 +15,7 @@
#include <tuple>
#include <vector>
-ShadowMapper::ShadowMapper(const glm::ivec2 & s) :
+ShadowMapper::ShadowMapper(const TextureAbsCoord & s) :
fixedPoint {shadowFixedPoint_vs}, dynamicPointInst {shadowDynamicPointInst_vs}, size {s}
{
glBindTexture(GL_TEXTURE_2D, depthMap);
@@ -24,7 +24,7 @@ ShadowMapper::ShadowMapper(const glm::ivec2 & s) :
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
- static constexpr glm::vec4 border {std::numeric_limits<float>::infinity()};
+ static constexpr RGBA border {std::numeric_limits<RGBA::value_type>::infinity()};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::value_ptr(border));
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
@@ -37,7 +37,7 @@ ShadowMapper::ShadowMapper(const glm::ivec2 & s) :
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
-constexpr std::array<std::array<glm::ivec4, ShadowMapper::SHADOW_BANDS>, ShadowMapper::SHADOW_BANDS> viewports {{
+constexpr std::array<std::array<TextureAbsRegion, ShadowMapper::SHADOW_BANDS>, ShadowMapper::SHADOW_BANDS> viewports {{
{{
{31, 31, 0, 0}, // full
}},
@@ -57,33 +57,34 @@ constexpr std::array<std::array<glm::ivec4, ShadowMapper::SHADOW_BANDS>, ShadowM
{1, 1, 1, 1}, // upper right
}},
}};
-constexpr std::array<std::array<glm::vec4, ShadowMapper::SHADOW_BANDS>, ShadowMapper::SHADOW_BANDS> shadowMapRegions {{
- {{
- {0.5F, 0.5F, 0.5F, 0.5F}, // full
- }},
- {{
- {0.5F, 0.25F, 0.5F, 0.25F}, // lower half
- {0.5F, 0.25F, 0.5F, 0.75F}, // upper half
- }},
- {{
- {0.5F, 0.25F, 0.5F, 0.25F}, // lower half
- {0.25F, 0.25F, 0.25F, 0.75F}, // upper left
- {0.25F, 0.25F, 0.75F, 0.75F}, // upper right
- }},
-
- {{
- {0.25F, 0.25F, 0.25F, 0.25F}, // lower left
- {0.25F, 0.25F, 0.75F, 0.25F}, // lower right
- {0.25F, 0.25F, 0.25F, 0.75F}, // upper left
- {0.25F, 0.25F, 0.75F, 0.75F}, // upper right
- }},
-}};
+constexpr std::array<std::array<TextureRelRegion, ShadowMapper::SHADOW_BANDS>, ShadowMapper::SHADOW_BANDS>
+ shadowMapRegions {{
+ {{
+ {0.5F, 0.5F, 0.5F, 0.5F}, // full
+ }},
+ {{
+ {0.5F, 0.25F, 0.5F, 0.25F}, // lower half
+ {0.5F, 0.25F, 0.5F, 0.75F}, // upper half
+ }},
+ {{
+ {0.5F, 0.25F, 0.5F, 0.25F}, // lower half
+ {0.25F, 0.25F, 0.25F, 0.75F}, // upper left
+ {0.25F, 0.25F, 0.75F, 0.75F}, // upper right
+ }},
+
+ {{
+ {0.25F, 0.25F, 0.25F, 0.25F}, // lower left
+ {0.25F, 0.25F, 0.75F, 0.25F}, // lower right
+ {0.25F, 0.25F, 0.25F, 0.75F}, // upper left
+ {0.25F, 0.25F, 0.75F, 0.75F}, // upper right
+ }},
+ }};
constexpr std::array<float, ShadowMapper::SHADOW_BANDS + 1> shadowBands {
- 1.F,
- 250.F,
- 750.F,
- 2500.F,
- 10000.F,
+ 1000.F,
+ 250000.F,
+ 750000.F,
+ 2500000.F,
+ 10000000.F,
};
static_assert(viewports.size() == shadowMapRegions.size());
static_assert(shadowBands.size() == shadowMapRegions.size() + 1);
@@ -94,22 +95,24 @@ struct DefinitionsInserter {
{
return out.maps++;
};
+
auto
operator*()
{
return std::tie(out.projections[out.maps], out.regions[out.maps]);
}
+
ShadowMapper::Definitions & out;
};
-std::vector<std::array<glm::vec3, 4>>
+std::vector<std::array<Position3D, 4>>
ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightView)
{
- std::vector<std::array<glm::vec3, 4>> bandViewExtents;
+ std::vector<std::array<Position3D, 4>> bandViewExtents;
for (const auto dist : shadowBands) {
const auto extents = camera.extentsAtDist(dist);
- bandViewExtents.emplace_back(extents * [&lightView](const auto & e) -> glm::vec3 {
- return lightView * glm::vec4(glm::vec3 {e}, 1);
+ bandViewExtents.emplace_back(extents * [&lightView](const auto & e) -> Position3D {
+ return lightView * glm::vec4(Position3D {e}, 1);
});
if (std::none_of(extents.begin(), extents.end(), [targetDist = dist * 0.99F](const glm::vec4 & e) {
return e.w > targetDist;
@@ -121,7 +124,7 @@ ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightV
}
ShadowMapper::Definitions
-ShadowMapper::update(const SceneProvider & scene, const glm::vec3 & dir, const Camera & camera) const
+ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const Camera & camera) const
{
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glClear(GL_DEPTH_BUFFER_BIT);
@@ -161,12 +164,14 @@ ShadowMapper::update(const SceneProvider & scene, const glm::vec3 & dir, const C
}
ShadowMapper::FixedPoint::FixedPoint(const Shader & vs) : Program {vs}, viewProjectionLoc {*this, "viewProjection"} { }
+
void
ShadowMapper::FixedPoint::setViewProjection(const glm::mat4 & viewProjection) const
{
use();
glUniformMatrix4fv(viewProjectionLoc, 1, GL_FALSE, glm::value_ptr(viewProjection));
}
+
void
ShadowMapper::FixedPoint::use() const
{
@@ -174,26 +179,28 @@ ShadowMapper::FixedPoint::use() const
}
ShadowMapper::DynamicPoint::DynamicPoint() :
- Program {shadowDynamicPoint_vs}, viewProjectionLoc {*this, "viewProjection"}, modelLoc {*this, "model"}
+ Program {shadowDynamicPoint_vs}, viewProjectionLoc {*this, "viewProjection"}, modelLoc {*this, "model"},
+ modelPosLoc {*this, "modelPos"}
{
}
+
void
ShadowMapper::DynamicPoint::setViewProjection(const glm::mat4 & viewProjection) const
{
glUseProgram(*this);
glUniformMatrix4fv(viewProjectionLoc, 1, GL_FALSE, glm::value_ptr(viewProjection));
}
+
void
ShadowMapper::DynamicPoint::use(const Location & location) const
{
glUseProgram(*this);
setModel(location);
- const auto model = glm::translate(location.pos) * rotate_ypr(location.rot);
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
}
+
void
ShadowMapper::DynamicPoint::setModel(const Location & location) const
{
- const auto model = glm::translate(location.pos) * rotate_ypr(location.rot);
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
+ glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(rotate_ypr(location.rot)));
+ glUniform3iv(modelPosLoc, 1, glm::value_ptr(location.pos));
}
diff --git a/gfx/gl/shadowMapper.h b/gfx/gl/shadowMapper.h
index 36371eb..b53a7f1 100644
--- a/gfx/gl/shadowMapper.h
+++ b/gfx/gl/shadowMapper.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config/types.h"
#include "lib/glArrays.h"
#include "program.h"
#include <glm/vec2.hpp>
@@ -8,17 +9,20 @@ class SceneProvider;
class Camera;
#include <gfx/models/texture.h>
+
class ShadowMapper {
public:
- explicit ShadowMapper(const glm::ivec2 & size);
+ explicit ShadowMapper(const TextureAbsCoord & size);
static constexpr std::size_t SHADOW_BANDS {4};
+
struct Definitions {
std::array<glm::mat4x4, SHADOW_BANDS> projections {};
- std::array<glm::vec4, SHADOW_BANDS> regions {};
+ std::array<TextureRelRegion, SHADOW_BANDS> regions {};
size_t maps {};
};
- [[nodiscard]] Definitions update(const SceneProvider &, const glm::vec3 & direction, const Camera &) const;
+
+ [[nodiscard]] Definitions update(const SceneProvider &, const Direction3D & direction, const Camera &) const;
class FixedPoint : public Program {
public:
@@ -29,6 +33,7 @@ public:
private:
RequiredUniformLocation viewProjectionLoc;
};
+
class DynamicPoint : public Program {
public:
DynamicPoint();
@@ -39,7 +44,9 @@ public:
private:
RequiredUniformLocation viewProjectionLoc;
RequiredUniformLocation modelLoc;
+ RequiredUniformLocation modelPosLoc;
};
+
FixedPoint fixedPoint, dynamicPointInst;
DynamicPoint dynamicPoint;
@@ -50,9 +57,9 @@ public:
}
private:
- [[nodiscard]] static std::vector<std::array<glm::vec3, 4>> getBandViewExtents(
+ [[nodiscard]] static std::vector<std::array<Position3D, 4>> getBandViewExtents(
const Camera &, const glm::mat4 & lightView);
glFrameBuffer depthMapFBO;
glTexture depthMap;
- glm::ivec2 size;
+ TextureAbsCoord size;
};
diff --git a/gfx/gl/uiShader.cpp b/gfx/gl/uiShader.cpp
index 78e0064..dc4f4dc 100644
--- a/gfx/gl/uiShader.cpp
+++ b/gfx/gl/uiShader.cpp
@@ -9,6 +9,7 @@
#include <initializer_list>
UIShader::IconProgram::IconProgram(const glm::mat4 & vp) : UIProgram {vp, uiShader_vs, uiShader_fs} { }
+
UIShader::TextProgram::TextProgram(const glm::mat4 & vp) :
UIProgram {vp, uiShader_vs, uiShaderFont_fs}, colorLoc {*this, "colour"}
{
@@ -18,10 +19,11 @@ UIShader::UIShader(size_t width, size_t height) :
UIShader {glm::ortho<float>(0, static_cast<float>(width), 0, static_cast<float>(height))}
{
}
+
UIShader::UIShader(const glm::mat4 & viewProjection) : icon {viewProjection}, text {viewProjection} { }
void
-UIShader::TextProgram::use(const glm::vec3 & colour) const
+UIShader::TextProgram::use(const RGB & colour) const
{
Program::use();
glUniform3fv(colorLoc, 1, glm::value_ptr(colour));
diff --git a/gfx/gl/uiShader.h b/gfx/gl/uiShader.h
index 2766af8..362e90c 100644
--- a/gfx/gl/uiShader.h
+++ b/gfx/gl/uiShader.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config/types.h"
#include "program.h"
#include <cstddef>
#include <glad/gl.h>
@@ -33,7 +34,7 @@ private:
class TextProgram : public UIProgram {
public:
explicit TextProgram(const glm::mat4 & vp);
- void use(const glm::vec3 & colour) const;
+ void use(const RGB & colour) const;
private:
RequiredUniformLocation colorLoc;
diff --git a/gfx/gl/vertexArrayObject.h b/gfx/gl/vertexArrayObject.h
index fa6baa3..57daaf3 100644
--- a/gfx/gl/vertexArrayObject.h
+++ b/gfx/gl/vertexArrayObject.h
@@ -11,22 +11,27 @@ public:
{
glBindVertexArray(arrayObject);
}
+
~VertexArrayObject()
{
glBindVertexArray(0);
}
+
NO_MOVE(VertexArrayObject);
NO_COPY(VertexArrayObject);
template<typename m, typename T> struct MP {
constexpr MP(m T::*p) : P {p} { }
+
operator void *() const
{
return &(static_cast<T *>(nullptr)->*P);
}
+
m T::*P;
using value_type = m;
};
+
template<typename m, typename T> MP(m T::*) -> MP<m, T>;
template<typename VertexT, MP... attribs>
diff --git a/gfx/image.h b/gfx/image.h
index 8bb4067..6fbbdd1 100644
--- a/gfx/image.h
+++ b/gfx/image.h
@@ -7,7 +7,9 @@
class Image {
public:
Image(const char * fileName, int flags);
+
Image(const std::string & fileName, int flags) : Image(fileName.c_str(), flags) { }
+
Image(std::span<unsigned char> data, int flags);
~Image();
diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp
index 380f2e0..1685d34 100644
--- a/gfx/models/texture.cpp
+++ b/gfx/models/texture.cpp
@@ -1,4 +1,5 @@
#include "texture.h"
+#include "config/types.h"
#include "glArrays.h"
#include "tga.h"
#include <cache.h>
@@ -60,10 +61,10 @@ Texture::bind(GLenum unit) const
glBindTexture(type, m_texture);
}
-glm::ivec2
+TextureAbsCoord
Texture::getSize(const glTexture & texture)
{
- glm::ivec2 size;
+ TextureAbsCoord size;
glGetTextureLevelParameteriv(texture, 0, GL_TEXTURE_WIDTH, &size.x);
glGetTextureLevelParameteriv(texture, 0, GL_TEXTURE_HEIGHT, &size.y);
return size;
@@ -136,14 +137,16 @@ TextureAtlas::bind(GLenum unit) const
}
GLuint
-TextureAtlas::add(glm::ivec2 position, glm::ivec2 size, void * data, TextureOptions to)
+TextureAtlas::add(TextureAbsCoord position, TextureAbsCoord size, void * data, TextureOptions to)
{
glTextureSubImage2D(m_texture, 0, position.x, position.y, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
struct Material {
glm::vec<2, uint16_t> position, size;
TextureOptions::MapMode wrapU;
TextureOptions::MapMode wrapV;
} material {position, size, to.wrapU, to.wrapV};
+
static_assert(sizeof(Material) <= 32);
glTextureSubImage2D(m_atlas, 0, 0, static_cast<GLsizei>(used), 2, 1, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, &material);
return ++used;
diff --git a/gfx/models/texture.h b/gfx/models/texture.h
index 1b66c64..5e1b440 100644
--- a/gfx/models/texture.h
+++ b/gfx/models/texture.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config/types.h"
#include <cache.h>
#include <filesystem>
#include <glArrays.h>
@@ -42,7 +43,7 @@ public:
protected:
static void save(const glTexture &, GLenum, GLenum, uint8_t channels, const char * path, uint8_t tgaFormat);
- static glm::ivec2 getSize(const glTexture &);
+ static TextureAbsCoord getSize(const glTexture &);
glTexture m_texture;
GLenum type;
@@ -53,7 +54,7 @@ public:
TextureAtlas(GLsizei width, GLsizei height, GLuint count);
void bind(GLenum unit = GL_TEXTURE0) const override;
- GLuint add(glm::ivec2 position, glm::ivec2 size, void * data, TextureOptions = {});
+ GLuint add(TextureAbsCoord position, TextureAbsCoord size, void * data, TextureOptions = {});
private:
glTexture m_atlas;
diff --git a/gfx/models/tga.h b/gfx/models/tga.h
index 1f400ef..3d072fb 100644
--- a/gfx/models/tga.h
+++ b/gfx/models/tga.h
@@ -4,11 +4,13 @@
#include <glm/vec2.hpp>
struct TGAHead {
+ using XY = glm::vec<2, uint16_t>;
uint8_t idLength {}, colorMapType {}, format {};
uint16_t __attribute__((packed)) colorMapFirst {}, colorMapLength {};
uint8_t colorMapEntrySize {};
- glm::vec<2, uint16_t> origin {}, size {};
+ XY origin {}, size {};
uint8_t pixelDepth {};
uint8_t descriptor {};
};
+
static_assert(sizeof(TGAHead) == 18);
diff --git a/gfx/models/vertex.h b/gfx/models/vertex.h
index 0464ea7..5635fa1 100644
--- a/gfx/models/vertex.h
+++ b/gfx/models/vertex.h
@@ -1,12 +1,12 @@
#pragma once
+#include "config/types.h"
#include <glad/gl.h>
-#include <glm/glm.hpp>
class Vertex {
public:
#ifndef __cpp_aggregate_paren_init
- constexpr Vertex(glm::vec3 pos, glm::vec2 texCoord, glm::vec3 normal, glm::vec4 colour = {}, GLuint material = 0) :
+ constexpr Vertex(Position3D pos, TextureRelCoord texCoord, Normal3D normal, RGBA colour = {}, GLuint material = 0) :
pos {std::move(pos)}, texCoord {std::move(texCoord)}, normal {std::move(normal)}, colour {std::move(colour)},
material {material}
{
@@ -15,9 +15,9 @@ public:
bool operator==(const Vertex &) const = default;
- glm::vec3 pos;
- glm::vec2 texCoord;
- glm::vec3 normal;
- glm::vec4 colour {};
+ Position3D pos {};
+ TextureRelCoord texCoord {};
+ Normal3D normal {};
+ RGBA colour {};
GLuint material {};
};
diff --git a/gfx/renderable.cpp b/gfx/renderable.cpp
index 539efb1..0340189 100644
--- a/gfx/renderable.cpp
+++ b/gfx/renderable.cpp
@@ -4,6 +4,7 @@ void
Renderable::lights(const SceneShader &) const
{
}
+
void
Renderable::shadows(const ShadowMapper &) const
{
diff --git a/lib/cache.h b/lib/cache.h
index 2c3975b..f5fd227 100644
--- a/lib/cache.h
+++ b/lib/cache.h
@@ -35,4 +35,5 @@ public:
private:
std::map<Key, Ptr, std::less<>> cached;
};
+
// IWYU pragma: no_forward_declare Cache
diff --git a/lib/collections.h b/lib/collections.h
index 7d78ef9..943b986 100644
--- a/lib/collections.h
+++ b/lib/collections.h
@@ -149,11 +149,14 @@ template<typename T> struct pair_range {
{
return pair.first;
}
+
constexpr auto &
end() const noexcept
{
return pair.second;
}
+
const std::pair<T, T> & pair;
};
+
template<typename T> pair_range(std::pair<T, T>) -> pair_range<T>;
diff --git a/lib/enumDetails.h b/lib/enumDetails.h
index 5966be2..b6ff046 100644
--- a/lib/enumDetails.h
+++ b/lib/enumDetails.h
@@ -26,11 +26,13 @@ template<typename E> struct EnumTypeDetails : EnumDetailsBase {
protected:
#endif
constexpr static std::string_view SEARCH_TYPE {"E = "};
+
constexpr static auto
typeraw()
{
return std::string_view {__PRETTY_FUNCTION__};
};
+
constexpr static auto typeNameStart {typeraw().find(SEARCH_TYPE) + SEARCH_TYPE.length()};
constexpr static auto typeNameEnd {typeraw().find_first_of("];", typeNameStart)};
constexpr static auto typeNameLen {typeNameEnd - typeNameStart};
@@ -47,11 +49,13 @@ template<auto value> struct EnumValueDetails : public EnumTypeDetails<decltype(v
private:
#endif
using T = EnumTypeDetails<decltype(value)>;
+
constexpr static auto
raw()
{
return std::string_view {__PRETTY_FUNCTION__};
};
+
constexpr static auto nameStart {raw().find_last_of(": ") + 1};
constexpr static auto nameEnd {raw().find_first_of("];", nameStart)};
constexpr static auto nameLen {nameEnd - nameStart};
@@ -84,12 +88,14 @@ private:
return std::array {EnumValueDetails<static_cast<E>(n)>::valid...};
#pragma GCC diagnostic pop
}
+
template<auto... n>
constexpr static auto
get_values(std::integer_sequence<int, n...>)
{
return std::array {EnumValueDetails<static_cast<E>(n)>::raw_value...};
}
+
template<auto... n>
constexpr static auto
get_valueNames(std::integer_sequence<int, n...>)
diff --git a/lib/geometricPlane.cpp b/lib/geometricPlane.cpp
index ea4f02d..567f98a 100644
--- a/lib/geometricPlane.cpp
+++ b/lib/geometricPlane.cpp
@@ -4,10 +4,10 @@
#include <glm/gtx/intersect.hpp>
GeometricPlane::PlaneRelation
-GeometricPlane::getRelation(glm::vec3 p) const
+GeometricPlane::getRelation(Position3D p) const
{
const auto d = glm::dot(normal, p - origin);
- return d < 0.f ? PlaneRelation::Below : d > 0.f ? PlaneRelation::Above : PlaneRelation::On;
+ return d < 0.F ? PlaneRelation::Below : d > 0.F ? PlaneRelation::Above : PlaneRelation::On;
}
bool
diff --git a/lib/geometricPlane.h b/lib/geometricPlane.h
index dc8df50..c74beff 100644
--- a/lib/geometricPlane.h
+++ b/lib/geometricPlane.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config/types.h"
#include <glm/vec3.hpp>
#include <optional>
@@ -9,14 +10,15 @@ class GeometricPlane {
public:
struct DistAndPosition {
float dist;
- glm::vec3 position;
+ Position3D position;
};
enum class PlaneRelation { Above, Below, On };
- glm::vec3 origin, normal;
+ Position3D origin;
+ Normal3D normal;
- PlaneRelation getRelation(glm::vec3 point) const;
- std::optional<DistAndPosition> getRayIntersectPosition(const Ray &) const;
+ [[nodiscard]] PlaneRelation getRelation(Position3D point) const;
+ [[nodiscard]] std::optional<DistAndPosition> getRayIntersectPosition(const Ray &) const;
static bool isIntersect(PlaneRelation a, PlaneRelation b);
};
diff --git a/lib/glArrays.h b/lib/glArrays.h
index 86385d9..787ea17 100644
--- a/lib/glArrays.h
+++ b/lib/glArrays.h
@@ -15,7 +15,8 @@ public:
CUSTOM_MOVE(glArraysBase);
// NOLINTNEXTLINE(hicpp-explicit-conversions)
- inline operator GLuint() const
+ inline
+ operator GLuint() const
{
static_assert(N == 1, "Implicit cast only if N == 1");
return ids.front();
diff --git a/lib/glContainer.h b/lib/glContainer.h
index 993170e..8177618 100644
--- a/lib/glContainer.h
+++ b/lib/glContainer.h
@@ -9,6 +9,7 @@
template<typename I, typename Direction> class basic_glContainer_iterator {
public:
explicit basic_glContainer_iterator(I * i) : i {i} { }
+
template<typename OtherI>
basic_glContainer_iterator(const basic_glContainer_iterator<OtherI, Direction> & other) : i {&*other}
{
@@ -20,17 +21,20 @@ public:
i = Direction {}(i, 1);
return *this;
}
+
auto
operator++(int) noexcept
{
return basic_glContainer_iterator<I, Direction> {std::exchange(i, Direction {}(i, 1))};
}
+
auto &
operator--() noexcept
{
i = Direction {}(i, -1);
return *this;
}
+
auto
operator--(int) noexcept
{
@@ -76,6 +80,7 @@ public:
{
return this->i == other.i;
}
+
[[nodiscard]] bool
operator!=(const basic_glContainer_iterator & other) const noexcept
{
@@ -87,6 +92,7 @@ public:
{
return i;
}
+
[[nodiscard]] auto &
operator*() const noexcept
{
diff --git a/lib/gl_traits.h b/lib/gl_traits.h
index a930eba..934b505 100644
--- a/lib/gl_traits.h
+++ b/lib/gl_traits.h
@@ -6,9 +6,11 @@
#include <glm/fwd.hpp>
template<typename T> struct gl_traits;
+
struct gl_traits_base {
static constexpr GLint size {1};
};
+
struct gl_traits_float : public gl_traits_base {
static constexpr auto vertexAttribFunc {
[](GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) -> GLuint {
@@ -16,6 +18,7 @@ struct gl_traits_float : public gl_traits_base {
return 1;
}};
};
+
struct gl_traits_longfloat : public gl_traits_base {
static constexpr auto vertexAttribFunc {
[](GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) -> GLuint {
@@ -23,6 +26,7 @@ struct gl_traits_longfloat : public gl_traits_base {
return 1;
}};
};
+
struct gl_traits_integer : public gl_traits_base {
static constexpr auto vertexAttribFunc {
[](GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) -> GLuint {
@@ -30,27 +34,35 @@ struct gl_traits_integer : public gl_traits_base {
return 1;
}};
};
+
template<> struct gl_traits<glm::f32> : public gl_traits_float {
static constexpr GLenum type {GL_FLOAT};
};
+
template<> struct gl_traits<glm::f64> : public gl_traits_longfloat {
static constexpr GLenum type {GL_DOUBLE};
};
+
template<> struct gl_traits<glm::int8> : public gl_traits_integer {
static constexpr GLenum type {GL_BYTE};
};
+
template<> struct gl_traits<glm::int16> : public gl_traits_integer {
static constexpr GLenum type {GL_SHORT};
};
+
template<> struct gl_traits<glm::int32> : public gl_traits_integer {
static constexpr GLenum type {GL_INT};
};
+
template<> struct gl_traits<glm::uint8> : public gl_traits_integer {
static constexpr GLenum type {GL_UNSIGNED_BYTE};
};
+
template<> struct gl_traits<glm::uint16> : public gl_traits_integer {
static constexpr GLenum type {GL_UNSIGNED_SHORT};
};
+
template<> struct gl_traits<glm::uint32> : public gl_traits_integer {
static constexpr GLenum type {GL_UNSIGNED_INT};
};
diff --git a/lib/jsonParse-persistence.cpp b/lib/jsonParse-persistence.cpp
index fe8bf8d..5c0011a 100644
--- a/lib/jsonParse-persistence.cpp
+++ b/lib/jsonParse-persistence.cpp
@@ -93,17 +93,20 @@ namespace Persistence {
{
strm.put(ch);
}
+
static inline void
wrh(std::ostream & strm, char ch)
{
using namespace std::literals;
strm << R"(\u)"sv << std::setw(4) << std::hex << static_cast<int>(ch) << std::setw(1);
}
+
static inline void
wre(std::ostream & strm, char e)
{
strm << '\\' << e;
}
+
template<char E>
static inline void
wre(std::ostream & strm, char)
diff --git a/lib/location.cpp b/lib/location.cpp
index 732dd6d..ff7cfa6 100644
--- a/lib/location.cpp
+++ b/lib/location.cpp
@@ -3,7 +3,7 @@
#include <glm/gtx/transform.hpp>
glm::mat4
-Location::getTransform() const
+Location::getRotationTransform() const
{
- return glm::translate(pos) * rotate_ypr(rot);
+ return rotate_ypr(rot);
}
diff --git a/lib/location.h b/lib/location.h
index 078f5d3..8570fc2 100644
--- a/lib/location.h
+++ b/lib/location.h
@@ -1,14 +1,16 @@
#pragma once
+#include "config/types.h"
#include <glm/mat4x4.hpp>
-#include <glm/vec3.hpp>
class Location {
public:
- explicit Location(glm::vec3 pos = {}, glm::vec3 rot = {}) : pos {pos}, rot {rot} { }
+#ifndef __cpp_aggregate_paren_init
+ explicit Location(GlobalPosition3D pos = {}, Rotation3D rot = {}) : pos {pos}, rot {rot} { }
+#endif
- glm::mat4 getTransform() const;
+ [[nodiscard]] glm::mat4 getRotationTransform() const;
- glm::vec3 pos;
- glm::vec3 rot;
+ GlobalPosition3D pos;
+ Rotation3D rot;
};
diff --git a/lib/maths.cpp b/lib/maths.cpp
index b8dbd34..5430ef6 100644
--- a/lib/maths.cpp
+++ b/lib/maths.cpp
@@ -6,7 +6,7 @@
#include <stdexcept>
glm::mat4
-flat_orientation(const glm::vec3 & diff)
+flat_orientation(const Direction3D & diff)
{
static const auto oneeighty {glm::rotate(pi, up)};
const auto flatdiff {glm::normalize(!!diff)};
@@ -16,17 +16,17 @@ flat_orientation(const glm::vec3 & diff)
}
// Helper to lookup into a matrix given an xy vector coordinate
-template<typename M>
+template<typename M, typename I>
inline auto &
-operator^(M & m, glm::ivec2 xy)
+operator^(M & m, glm::vec<2, I> xy)
{
return m[xy.x][xy.y];
}
// Create a matrix for the angle, given the targets into the matrix
-template<typename M>
+template<typename M, typename I>
inline auto
-rotation(typename M::value_type a, glm::ivec2 c1, glm::ivec2 s1, glm::ivec2 c2, glm::ivec2 ms2)
+rotation(typename M::value_type a, glm::vec<2, I> c1, glm::vec<2, I> s1, glm::vec<2, I> c2, glm::vec<2, I> ms2)
{
M m(1);
sincosf(a, m ^ s1, m ^ c1);
@@ -39,51 +39,51 @@ rotation(typename M::value_type a, glm::ivec2 c1, glm::ivec2 s1, glm::ivec2 c2,
glm::mat2
rotate_flat(float a)
{
- return rotation<glm::mat2>(a, {0, 0}, {0, 1}, {1, 1}, {1, 0});
+ return rotation<glm::mat2, glm::length_t>(a, {0, 0}, {0, 1}, {1, 1}, {1, 0});
}
// Create a yaw transformation matrix
glm::mat4
rotate_yaw(float a)
{
- return rotation<glm::mat4>(a, {0, 0}, {1, 0}, {1, 1}, {0, 1});
+ return rotation<glm::mat4, glm::length_t>(a, {0, 0}, {1, 0}, {1, 1}, {0, 1});
}
// Create a roll transformation matrix
glm::mat4
rotate_roll(float a)
{
- return rotation<glm::mat4>(a, {0, 0}, {2, 0}, {2, 2}, {0, 2});
+ return rotation<glm::mat4, glm::length_t>(a, {0, 0}, {2, 0}, {2, 2}, {0, 2});
}
// Create a pitch transformation matrix
glm::mat4
rotate_pitch(float a)
{
- return rotation<glm::mat4>(a, {1, 1}, {1, 2}, {2, 2}, {2, 1});
+ return rotation<glm::mat4, glm::length_t>(a, {1, 1}, {1, 2}, {2, 2}, {2, 1});
}
// Create a combined yaw, pitch, roll transformation matrix
glm::mat4
-rotate_ypr(glm::vec3 a)
+rotate_ypr(Rotation3D a)
{
return rotate_yaw(a.y) * rotate_pitch(a.x) * rotate_roll(a.z);
}
glm::mat4
-rotate_yp(glm::vec2 a)
+rotate_yp(Rotation2D a)
{
return rotate_yaw(a.y) * rotate_pitch(a.x);
}
float
-vector_yaw(const glm::vec3 & diff)
+vector_yaw(const Direction3D & diff)
{
return std::atan2(diff.x, diff.y);
}
float
-vector_pitch(const glm::vec3 & diff)
+vector_pitch(const Direction3D & diff)
{
return std::atan(diff.z);
}
@@ -106,7 +106,7 @@ normalize(float ang)
return ang;
}
-Arc::Arc(const glm::vec3 & centre3, const glm::vec3 & e0p, const glm::vec3 & e1p) :
+Arc::Arc(const Position3D & centre3, const Position3D & e0p, const Position3D & e1p) :
Arc([&]() -> Arc {
const auto diffa = e0p - centre3;
const auto diffb = e1p - centre3;
@@ -120,8 +120,8 @@ Arc::Arc(const glm::vec3 & centre3, const glm::vec3 & e0p, const glm::vec3 & e1p
{
}
-std::pair<glm::vec2, bool>
-find_arc_centre(glm::vec2 as, float entrys, glm::vec2 bs, float entrye)
+std::pair<Position2D, bool>
+find_arc_centre(Position2D as, float entrys, Position2D bs, float entrye)
{
if (as == bs) {
return {as, false};
@@ -129,8 +129,8 @@ find_arc_centre(glm::vec2 as, float entrys, glm::vec2 bs, float entrye)
return find_arc_centre(as, sincosf(entrys + half_pi), bs, sincosf(entrye - half_pi));
}
-std::pair<glm::vec2, bool>
-find_arc_centre(glm::vec2 as, glm::vec2 ad, glm::vec2 bs, glm::vec2 bd)
+std::pair<Position2D, bool>
+find_arc_centre(Position2D as, Position2D ad, Position2D bs, Position2D bd)
{
const auto det = bd.x * ad.y - bd.y * ad.x;
if (det != 0) { // near parallel line will yield noisy results
@@ -142,7 +142,7 @@ find_arc_centre(glm::vec2 as, glm::vec2 ad, glm::vec2 bs, glm::vec2 bd)
}
std::pair<float, float>
-find_arcs_radius(glm::vec2 start, float entrys, glm::vec2 end, float entrye)
+find_arcs_radius(Position2D start, float entrys, Position2D end, float entrye)
{
const auto getrad = [&](float leftOrRight) {
return find_arcs_radius(start, sincosf(entrys + leftOrRight), end, sincosf(entrye + leftOrRight));
@@ -151,7 +151,7 @@ find_arcs_radius(glm::vec2 start, float entrys, glm::vec2 end, float entrye)
}
float
-find_arcs_radius(glm::vec2 start, glm::vec2 ad, glm::vec2 end, glm::vec2 bd)
+find_arcs_radius(Position2D start, Position2D ad, Position2D end, Position2D bd)
{
// Short name functions for big forula
auto sqrt = [](float v) {
@@ -177,12 +177,14 @@ find_arcs_radius(glm::vec2 start, glm::vec2 ad, glm::vec2 end, glm::vec2 bd)
/ (2 * (sq(X) - 2 * X * Z + sq(Z) + sq(Y) - 2 * Y * W + sq(W) - 4));
}
-float operator"" _mph(const long double v)
+float
+operator"" _mph(const long double v)
{
return static_cast<float>(mph_to_ms(v));
}
-float operator"" _kph(const long double v)
+float
+operator"" _kph(const long double v)
{
return static_cast<float>(kph_to_ms(v));
}
diff --git a/lib/maths.h b/lib/maths.h
index b95b706..67b2a15 100644
--- a/lib/maths.h
+++ b/lib/maths.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config/types.h"
#include <cmath>
#include <glm/glm.hpp>
#include <glm/gtc/constants.hpp>
@@ -9,7 +10,7 @@
struct Arc : public std::pair<float, float> {
using std::pair<float, float>::pair;
- Arc(const glm::vec3 & centre3, const glm::vec3 & e0p, const glm::vec3 & e1p);
+ Arc(const Position3D & centre3, const Position3D & e0p, const Position3D & e1p);
float
operator[](unsigned int i) const
@@ -18,19 +19,19 @@ struct Arc : public std::pair<float, float> {
}
};
-constexpr const glm::vec3 origin {0, 0, 0};
-constexpr const glm::vec3 up {0, 0, 1};
-constexpr const glm::vec3 down {0, 0, -1};
-constexpr const glm::vec3 north {0, 1, 0};
-constexpr const glm::vec3 south {0, -1, 0};
-constexpr const glm::vec3 east {1, 0, 0};
-constexpr const glm::vec3 west {-1, 0, 0};
+constexpr const Position3D origin {0, 0, 0};
+constexpr const Position3D up {0, 0, 1};
+constexpr const Position3D down {0, 0, -1};
+constexpr const Position3D north {0, 1, 0};
+constexpr const Position3D south {0, -1, 0};
+constexpr const Position3D east {1, 0, 0};
+constexpr const Position3D west {-1, 0, 0};
constexpr auto half_pi {glm::half_pi<float>()};
constexpr auto quarter_pi {half_pi / 2};
constexpr auto pi {glm::pi<float>()};
constexpr auto two_pi {glm::two_pi<float>()};
-glm::mat4 flat_orientation(const glm::vec3 & diff);
+glm::mat4 flat_orientation(const Rotation3D & diff);
// C++ wrapper for C's sincosf, but with references, not pointers
inline auto
@@ -39,10 +40,10 @@ sincosf(float a, float & s, float & c)
return sincosf(a, &s, &c);
}
-inline glm::vec2
+inline Rotation2D
sincosf(float a)
{
- glm::vec2 sc;
+ Rotation2D sc;
sincosf(a, sc.x, sc.y);
return sc;
}
@@ -51,11 +52,11 @@ glm::mat2 rotate_flat(float);
glm::mat4 rotate_roll(float);
glm::mat4 rotate_yaw(float);
glm::mat4 rotate_pitch(float);
-glm::mat4 rotate_yp(glm::vec2);
-glm::mat4 rotate_ypr(glm::vec3);
+glm::mat4 rotate_yp(Rotation2D);
+glm::mat4 rotate_ypr(Rotation3D);
-float vector_yaw(const glm::vec3 & diff);
-float vector_pitch(const glm::vec3 & diff);
+float vector_yaw(const Direction3D & diff);
+float vector_pitch(const Direction3D & diff);
float round_frac(const float & v, const float & frac);
@@ -87,26 +88,26 @@ perspective_divide(glm::vec<4, T, Q> v)
return v / v.w;
}
-constexpr inline glm::vec2
-operator!(const glm::vec3 & v)
+constexpr inline Position2D
+operator!(const Position3D & v)
{
return {v.x, v.y};
}
-constexpr inline glm::vec3
-operator^(const glm::vec2 & v, float z)
+constexpr inline Position3D
+operator^(const Position2D & v, float z)
{
return {v.x, v.y, z};
}
constexpr inline glm::vec4
-operator^(const glm::vec3 & v, float w)
+operator^(const Position3D & v, float w)
{
return {v.x, v.y, v.z, w};
}
-constexpr inline glm::vec3
-operator!(const glm::vec2 & v)
+constexpr inline Position3D
+operator!(const Position2D & v)
{
return v ^ 0.F;
}
@@ -125,15 +126,15 @@ operator||(const glm::vec<L, T, Q> v1, const T v2)
return {v1, v2};
}
-inline glm::vec3
-operator%(const glm::vec3 & p, const glm::mat4 & mutation)
+inline Position3D
+operator%(const Position3D & p, const glm::mat4 & mutation)
{
const auto p2 = mutation * (p ^ 1);
return p2 / p2.w;
}
-inline glm::vec3
-operator%=(glm::vec3 & p, const glm::mat4 & mutation)
+inline Position3D
+operator%=(Position3D & p, const glm::mat4 & mutation)
{
return p = p % mutation;
}
@@ -146,10 +147,10 @@ arc_length(const Arc & arc)
float normalize(float ang);
-std::pair<glm::vec2, bool> find_arc_centre(glm::vec2 start, float entrys, glm::vec2 end, float entrye);
-std::pair<glm::vec2, bool> find_arc_centre(glm::vec2 start, glm::vec2 ad, glm::vec2 end, glm::vec2 bd);
-std::pair<float, float> find_arcs_radius(glm::vec2 start, float entrys, glm::vec2 end, float entrye);
-float find_arcs_radius(glm::vec2 start, glm::vec2 ad, glm::vec2 end, glm::vec2 bd);
+std::pair<Position2D, bool> find_arc_centre(Position2D start, float entrys, Position2D end, float entrye);
+std::pair<Position2D, bool> find_arc_centre(Position2D start, Position2D ad, Position2D end, Position2D bd);
+std::pair<float, float> find_arcs_radius(Position2D start, float entrys, Position2D end, float entrye);
+float find_arcs_radius(Position2D start, Position2D ad, Position2D end, Position2D bd);
template<typename T>
auto
diff --git a/lib/persistence.cpp b/lib/persistence.cpp
index e22d74d..38e2ac6 100644
--- a/lib/persistence.cpp
+++ b/lib/persistence.cpp
@@ -167,6 +167,7 @@ namespace Persistence {
{
throw std::logic_error("Default write op shouldn't ever get called");
}
+
/// LCOV_EXCL_STOP
ParseBase::ParseBase() : sharedObjectsInstance {std::make_shared<SharedObjects>()}
diff --git a/lib/persistence.h b/lib/persistence.h
index 5d71d4c..92f3052 100644
--- a/lib/persistence.h
+++ b/lib/persistence.h
@@ -153,6 +153,7 @@ namespace Persistence {
};
struct Persistable;
+
struct PersistenceStore {
using SelectionFactory = std::function<SelectionPtr()>;
PersistenceStore() = default;
@@ -163,6 +164,7 @@ namespace Persistence {
enum class NameAction { Push, HandleAndContinue, Ignore };
using NameActionSelection = std::pair<NameAction, SelectionPtr>;
+
template<typename Helper, typename T>
[[nodiscard]] inline bool
persistValue(const std::string_view key, T & value)
@@ -267,6 +269,7 @@ namespace Persistence {
template<glm::length_t L, typename T, glm::qualifier Q>
struct SelectionT<glm::vec<L, T, Q>> : public SelectionT<std::span<T>> {
SelectionT(glm::vec<L, T, Q> & v) : SelectionT<std::span<T>> {spn}, spn {&v[0], L} { }
+
std::span<T> spn;
};
@@ -316,6 +319,7 @@ namespace Persistence {
MapByMember(Map & m) : Persistence::SelectionT<Type> {s}, map {m} { }
using Persistence::SelectionT<Type>::SelectionT;
+
void
endObject(Persistence::Stack & stk) override
{
@@ -332,7 +336,9 @@ namespace Persistence {
template<typename Container, typename Type = typename Container::value_type>
struct Appender : public Persistence::SelectionT<Type> {
Appender(Container & c) : Persistence::SelectionT<Type> {s}, container {c} { }
+
using Persistence::SelectionT<Type>::SelectionT;
+
void
endObject(Persistence::Stack & stk) override
{
@@ -407,6 +413,7 @@ namespace Persistence {
{
return std::dynamic_pointer_cast<T>(Persistence::ParseBase::sharedObjects.lock()->at(k));
}
+
template<typename... T>
static auto
emplaceShared(T &&... v)
@@ -421,6 +428,7 @@ namespace Persistence {
inline static thread_local SharedObjectsWPtr sharedObjects;
SharedObjectsPtr sharedObjectsInstance;
};
+
// TODO Move these
using SeenSharedObjects = std::map<void *, std::string>;
inline SeenSharedObjects seenSharedObjects;
@@ -428,6 +436,7 @@ namespace Persistence {
template<typename Ptr> struct SelectionPtrBase : public SelectionV<Ptr> {
static constexpr auto shared = std::is_copy_assignable_v<Ptr>;
using T = typename Ptr::element_type;
+
struct SelectionObj : public SelectionV<Ptr> {
struct MakeObjectByTypeName : public SelectionV<Ptr> {
using SelectionV<Ptr>::SelectionV;
diff --git a/lib/ptr.h b/lib/ptr.h
index b7d15a1..fb959ab 100644
--- a/lib/ptr.h
+++ b/lib/ptr.h
@@ -55,6 +55,7 @@ public:
protected:
explicit wrapped_ptr(Obj * o) : obj {o} { }
+
Obj * obj;
};
diff --git a/lib/ray.cpp b/lib/ray.cpp
index c4e0d8c..9fb3648 100644
--- a/lib/ray.cpp
+++ b/lib/ray.cpp
@@ -2,13 +2,13 @@
#include <algorithm>
Ray
-Ray::fromPoints(glm::vec3 start, glm::vec3 p)
+Ray::fromPoints(Position3D start, Position3D p)
{
return {start, glm::normalize(p - start)};
}
float
-Ray::distanceToLine(const glm::vec3 & p1, const glm::vec3 & e1) const
+Ray::distanceToLine(const Position3D & p1, const Position3D & e1) const
{
// https://en.wikipedia.org/wiki/Skew_lines
const auto diff = p1 - e1;
@@ -25,10 +25,10 @@ Ray::distanceToLine(const glm::vec3 & p1, const glm::vec3 & e1) const
}
bool
-Ray::passesCloseToEdges(const std::span<const glm::vec3> positions, float distance) const
+Ray::passesCloseToEdges(const std::span<const Position3D> positions, float distance) const
{
return std::adjacent_find(positions.begin(), positions.end(),
- [this, distance](const glm::vec3 & a, const glm::vec3 & b) {
+ [this, distance](const Position3D & a, const Position3D & b) {
return distanceToLine(a, b) <= distance;
})
!= positions.end();
diff --git a/lib/ray.h b/lib/ray.h
index 9bf47af..bc70c74 100644
--- a/lib/ray.h
+++ b/lib/ray.h
@@ -1,17 +1,20 @@
#pragma once
+#include "config/types.h"
#include <glm/glm.hpp>
#include <span>
class Ray {
public:
- Ray(glm::vec3 start, glm::vec3 direction) : start {start}, direction {direction} { }
+#ifndef __cpp_aggregate_paren_init
+ Ray(Position3D start, Direction3D direction) : start {start}, direction {direction} { }
+#endif
- static Ray fromPoints(glm::vec3, glm::vec3);
+ static Ray fromPoints(Position3D, Position3D);
- glm::vec3 start;
- glm::vec3 direction;
+ Position3D start;
+ Direction3D direction;
- float distanceToLine(const glm::vec3 & a, const glm::vec3 & b) const;
- bool passesCloseToEdges(const std::span<const glm::vec3> positions, float distance) const;
+ [[nodiscard]] float distanceToLine(const Position3D & a, const Position3D & b) const;
+ [[nodiscard]] bool passesCloseToEdges(const std::span<const Position3D> positions, float distance) const;
};
diff --git a/lib/resource.h b/lib/resource.h
index 37dd657..9af3632 100644
--- a/lib/resource.h
+++ b/lib/resource.h
@@ -16,5 +16,6 @@ public:
Resource::setBasePath(RESDIR);
}
};
+
BOOST_GLOBAL_FIXTURE(SetResourcePath);
#endif
diff --git a/lib/saxParse-persistence.h b/lib/saxParse-persistence.h
index 6043b25..bd5db57 100644
--- a/lib/saxParse-persistence.h
+++ b/lib/saxParse-persistence.h
@@ -10,6 +10,7 @@ namespace Persistence {
private:
template<typename T> struct Root : public Persistable {
T t {};
+
bool
persist(PersistenceStore & store)
{
diff --git a/lib/stdTypeDefs.h b/lib/stdTypeDefs.h
index 317cdb3..beab630 100644
--- a/lib/stdTypeDefs.h
+++ b/lib/stdTypeDefs.h
@@ -6,18 +6,22 @@
template<typename T> struct AnyPtr {
// cppcheck-suppress noExplicitConstructor
AnyPtr(T * p) : ptr {p} { }
+
// cppcheck-suppress noExplicitConstructor
template<typename S> AnyPtr(const S & p) : ptr {p.get()} { }
+
auto
get() const
{
return ptr;
}
+
auto
operator->() const
{
return ptr;
}
+
auto &
operator*() const
{
diff --git a/lib/unicode.h b/lib/unicode.h
index f69c43c..bc491f3 100644
--- a/lib/unicode.h
+++ b/lib/unicode.h
@@ -50,6 +50,7 @@ struct utf8_string_view {
constexpr utf8_string_view(const Str & str) : begin_ {str.data()}, end_ {str.data() + str.length()}
{
}
+
// cppcheck-suppress noExplicitConstructor; NOLINTNEXTLINE(hicpp-explicit-conversions)
constexpr utf8_string_view(const char * const str) : utf8_string_view {std::string_view {str}} { }
@@ -70,6 +71,7 @@ struct utf8_string_view {
private:
const char *begin_, *end_;
};
+
template<> struct std::iterator_traits<utf8_string_view::iter> {
using difference_type = size_t;
using value_type = uint32_t;
diff --git a/lib/worker.h b/lib/worker.h
index 0d15ca2..95bb4ec 100644
--- a/lib/worker.h
+++ b/lib/worker.h
@@ -16,6 +16,7 @@ public:
class WorkItem {
protected:
WorkItem(Worker * worker) : worker {worker} { }
+
virtual ~WorkItem() = default;
NO_MOVE(WorkItem);
NO_COPY(WorkItem);
@@ -25,6 +26,7 @@ public:
{
worker->assist();
}
+
Worker * worker;
public:
@@ -57,6 +59,7 @@ public:
{
return instance.addWorkImpl(std::forward<Params>(params)...);
}
+
template<typename T> using WorkPtrT = std::shared_ptr<WorkItemT<T>>;
private:
diff --git a/res/brush47.xml b/res/brush47.xml
index 31518c8..dc33282 100644
--- a/res/brush47.xml
+++ b/res/brush47.xml
@@ -61,7 +61,7 @@
<textureFragment id="roofSideWithVents" path="rail/roofSideWithVents.png"/>
<textureFragment id="roofTopWithVents" path="rail/roofTopWithVents.png"/>
<textureFragment id="cabWindowFront" path="rail/cabWindowFront.png"/>
- <asset p.typeid="RailVehicleClass" id="brush-47" name="Brush 47" length="19.38" wheelBase="15.70" maxSpeed="42.4688">
+ <asset p.typeid="RailVehicleClass" id="brush-47" name="Brush 47" length="19380" wheelBase="15700" maxSpeed="42468.8">
<bodyMesh id="body" size="2.69,19.38,3.9">
<use type="cuboid" position="0,0,1.2" scale="2.69,19.38,0.3" colour="goldenrod">
<face id="bottom" colour="#2c3539"/>
diff --git a/test/perf-geoData.cpp b/test/perf-geoData.cpp
index 4fed632..4d4505e 100644
--- a/test/perf-geoData.cpp
+++ b/test/perf-geoData.cpp
@@ -8,17 +8,17 @@ namespace {
terrain_findPoint(benchmark::State & state)
{
for (auto _ : state) {
- benchmark::DoNotOptimize(tm.findPoint({315555, 495556}));
+ benchmark::DoNotOptimize(tm.findPoint({315555000, 495556000}));
}
}
void
terrain_walk(benchmark::State & state)
{
- const glm::vec2 point {310001, 490000};
+ const glm::vec2 point {310001000, 490000000};
const GeoData::PointFace start {point, tm.findPoint(point)};
for (auto _ : state) {
- tm.walk(start, {319999, 500000}, [](auto f) {
+ tm.walk(start, {319999000, 500000000}, [](auto f) {
benchmark::DoNotOptimize(f);
});
}
diff --git a/test/test-assetFactory.cpp b/test/test-assetFactory.cpp
index 145481e..c8183df 100644
--- a/test/test-assetFactory.cpp
+++ b/test/test-assetFactory.cpp
@@ -25,7 +25,7 @@ BOOST_GLOBAL_FIXTURE(TestMainWindow);
const std::filesystem::path TMP {"/tmp"};
-class FactoryFixture : public TestRenderOutputSize<glm::ivec2 {2048, 1024}>, public SceneProvider {
+class FactoryFixture : public TestRenderOutputSize<TextureAbsCoord {2048, 1024}>, public SceneProvider {
public:
FactoryFixture() : sceneRenderer {size, output} { }
@@ -64,7 +64,7 @@ public:
}
void
- render(float dist = 10.f)
+ render(float dist)
{
sceneRenderer.camera.setView({-dist, dist * 1.2f, dist * 1.2f}, south + east + down);
sceneRenderer.render(*this);
@@ -104,7 +104,7 @@ BOOST_AUTO_TEST_CASE(brush47xml, *boost::unit_test::timeout(5))
auto railVehicle = std::make_shared<RailVehicle>(brush47rvc);
objects.objects.push_back(brush47rvc);
- render();
+ render(10000);
}
BOOST_AUTO_TEST_CASE(foliage, *boost::unit_test::timeout(5))
@@ -116,13 +116,13 @@ BOOST_AUTO_TEST_CASE(foliage, *boost::unit_test::timeout(5))
auto tree_01_1_f = std::dynamic_pointer_cast<Foliage>(tree_01_1);
BOOST_REQUIRE(tree_01_1_f);
- auto plant1 = std::make_shared<Plant>(tree_01_1_f, Location {{-2, 2, 0}, {0, 0, 0}});
- auto plant2 = std::make_shared<Plant>(tree_01_1_f, Location {{3, -4, 0}, {0, 1, 0}});
- auto plant3 = std::make_shared<Plant>(tree_01_1_f, Location {{-2, -4, 0}, {0, 2, 0}});
- auto plant4 = std::make_shared<Plant>(tree_01_1_f, Location {{3, 2, 0}, {0, 3, 0}});
+ auto plant1 = std::make_shared<Plant>(tree_01_1_f, Location {{-2000, 2000, 0}, {0, 0, 0}});
+ auto plant2 = std::make_shared<Plant>(tree_01_1_f, Location {{3000, -4000, 0}, {0, 1, 0}});
+ auto plant3 = std::make_shared<Plant>(tree_01_1_f, Location {{-2000, -4000, 0}, {0, 2, 0}});
+ auto plant4 = std::make_shared<Plant>(tree_01_1_f, Location {{3000, 2000, 0}, {0, 3, 0}});
objects.objects.push_back(tree_01_1_f);
- render(5);
+ render(6000);
}
BOOST_AUTO_TEST_SUITE_END();
@@ -183,14 +183,15 @@ BOOST_AUTO_TEST_CASE(texturePacker_many, *boost::unit_test::timeout(5))
{
std::vector<TexturePacker::Image> images(256);
std::fill(images.begin(), images.end(), TexturePacker::Image {32, 32});
- const auto totalSize = std::accumulate(images.begin(), images.end(), 0U, [](auto t, const auto & i) {
+ const auto totalSize = std::accumulate(images.begin(), images.end(), 0, [](auto t, const auto & i) {
return t + TexturePacker::area(i);
});
TexturePacker tp {images};
BOOST_CHECK_EQUAL(TexturePacker::Size(32, 32), tp.minSize());
const auto result = tp.pack();
BOOST_CHECK_EQUAL(result.first.size(), images.size());
- BOOST_CHECK_GE(TexturePacker::area(result.second), TexturePacker::area(images.front()) * images.size());
+ BOOST_CHECK_GE(TexturePacker::area(result.second),
+ TexturePacker::area(images.front()) * static_cast<GLsizei>(images.size()));
BOOST_CHECK_EQUAL(totalSize, TexturePacker::area(result.second));
}
diff --git a/test/test-geoData.cpp b/test/test-geoData.cpp
index 447ab37..4e85f73 100644
--- a/test/test-geoData.cpp
+++ b/test/test-geoData.cpp
@@ -11,7 +11,7 @@ public:
TestTerrainMesh() : GeoData {GeoData::loadFromAsciiGrid(FIXTURESDIR "height/SD19.asc")} { }
};
-constexpr size_t ncols = 200, nrows = 200, xllcorner = 310000, yllcorner = 490000, cellsize = 50;
+constexpr size_t ncols = 200, nrows = 200, xllcorner = 310000000, yllcorner = 490000000, cellsize = 50000;
BOOST_FIXTURE_TEST_SUITE(ttm, TestTerrainMesh);
@@ -20,18 +20,22 @@ BOOST_AUTO_TEST_CASE(loadSuccess)
BOOST_CHECK_EQUAL(ncols * nrows, n_vertices());
BOOST_CHECK_EQUAL(2 * (ncols - 1) * (nrows - 1), n_faces());
const auto [lower, upper] = getExtents();
- BOOST_CHECK_EQUAL(lower, glm::vec3(310000, 490000, -2.6));
- BOOST_CHECK_EQUAL(upper, glm::vec3(319950, 499950, 571.6));
+ BOOST_CHECK_EQUAL(lower, GlobalPosition3D(310000000, 490000000, -2600));
+ BOOST_CHECK_EQUAL(upper, GlobalPosition3D(319950000, 499950000, 571600));
}
BOOST_AUTO_TEST_CASE(normalsAllPointUp)
{
- BOOST_CHECK(std::all_of(faces_begin(), faces_end(), [this](auto && vh) {
- return normal(vh).z > 0;
- }));
- BOOST_CHECK(std::all_of(vertices_begin(), vertices_end(), [this](auto && vh) {
- return normal(vh).z > 0;
- }));
+ BOOST_CHECK_EQUAL(std::count_if(faces_begin(), faces_end(),
+ [this](auto && vh) {
+ return normal(vh).z > 0;
+ }),
+ n_faces());
+ BOOST_CHECK_EQUAL(std::count_if(vertices_begin(), vertices_end(),
+ [this](auto && vh) {
+ return normal(vh).z > 0;
+ }),
+ n_vertices());
}
BOOST_AUTO_TEST_CASE(trianglesContainsPoints)
@@ -39,13 +43,13 @@ BOOST_AUTO_TEST_CASE(trianglesContainsPoints)
const auto face = face_handle(0);
BOOST_TEST_CONTEXT(GeoData::Triangle<2>(this, fv_range(face))) {
- BOOST_CHECK(triangleContainsPoint(glm::vec2 {xllcorner, yllcorner}, face));
- BOOST_CHECK(triangleContainsPoint(glm::vec2 {xllcorner + cellsize, yllcorner + cellsize}, face));
- BOOST_CHECK(triangleContainsPoint(glm::vec2 {xllcorner, yllcorner + cellsize}, face));
- BOOST_CHECK(triangleContainsPoint(glm::vec2 {xllcorner + 1, yllcorner + 1}, face));
- BOOST_CHECK(triangleContainsPoint(glm::vec2 {xllcorner + 1, yllcorner + 2}, face));
- BOOST_CHECK(!triangleContainsPoint(glm::vec2 {xllcorner + 3, yllcorner + 2}, face));
- BOOST_CHECK(!triangleContainsPoint(glm::vec2 {xllcorner + cellsize, yllcorner}, face));
+ BOOST_CHECK(triangleContainsPoint(GlobalPosition2D {xllcorner, yllcorner}, face));
+ BOOST_CHECK(triangleContainsPoint(GlobalPosition2D {xllcorner + cellsize, yllcorner + cellsize}, face));
+ BOOST_CHECK(triangleContainsPoint(GlobalPosition2D {xllcorner, yllcorner + cellsize}, face));
+ BOOST_CHECK(triangleContainsPoint(GlobalPosition2D {xllcorner + 1, yllcorner + 1}, face));
+ BOOST_CHECK(triangleContainsPoint(GlobalPosition2D {xllcorner + 1, yllcorner + 2}, face));
+ BOOST_CHECK(!triangleContainsPoint(GlobalPosition2D {xllcorner + 3, yllcorner + 2}, face));
+ BOOST_CHECK(!triangleContainsPoint(GlobalPosition2D {xllcorner + cellsize, yllcorner}, face));
}
}
@@ -55,7 +59,7 @@ static const TestTerrainMesh fixedTerrtain;
BOOST_AUTO_TEST_CASE(locatePointFace)
{
- const GeoData::PointFace pf {{310002, 490003}};
+ const GeoData::PointFace pf {{310002000, 490003000}};
BOOST_CHECK(!pf.isLocated());
BOOST_CHECK(pf.face(&fixedTerrtain).is_valid());
BOOST_CHECK_EQUAL(pf.face(&fixedTerrtain).idx(), 0);
@@ -63,19 +67,19 @@ BOOST_AUTO_TEST_CASE(locatePointFace)
BOOST_AUTO_TEST_CASE(preLocatePointFace)
{
- const GeoData::PointFace pf {{310002, 490003}, &fixedTerrtain};
+ const GeoData::PointFace pf {{310002000, 490003000}, &fixedTerrtain};
BOOST_CHECK(pf.isLocated());
BOOST_CHECK_EQUAL(pf.face(&fixedTerrtain).idx(), 0);
}
-using FindPointData = std::tuple<glm::vec2, int>;
+using FindPointData = std::tuple<GlobalPosition2D, int>;
// No boundary cases as these can produce different valid results depending on starting point
BOOST_DATA_TEST_CASE(findPointOnTerrain,
boost::unit_test::data::make<FindPointData>({
{{0, 0}, -1}, {{xllcorner, 0}, -1}, {{0, yllcorner}, -1}, {{xllcorner + 1, yllcorner + 2}, 0},
{{xllcorner + (cellsize * (nrows - 1)) - 2, yllcorner + (cellsize * (ncols - 1)) - 1}, 79200},
- {{315555, 495556}, 44400}, // perf test target
+ {{315555000, 495556000}, 44400}, // perf test target
})
* boost::unit_test::data::make<int>(
{0, 1, 2, 3, 4, 5, 6, 10, 100, 150, 200, 1000, 1234, 17439, 79201, 79200, 79199}),
@@ -84,38 +88,38 @@ BOOST_DATA_TEST_CASE(findPointOnTerrain,
BOOST_CHECK_EQUAL(fh, fixedTerrtain.findPoint(p, GeoData::FaceHandle(start)).idx());
}
-using FindPositionData = std::tuple<glm::vec2, float>;
+using FindPositionData = std::tuple<GlobalPosition2D, GlobalDistance>;
BOOST_DATA_TEST_CASE(findPositionAt,
boost::unit_test::data::make<FindPositionData>({
// corners
- {{310000, 490000}, 32.8F},
- {{310050, 490050}, 33.0F},
- {{310000, 490050}, 32.7F},
- {{310050, 490000}, 33.2F},
- {{310750, 490150}, 58.4F},
+ {{310000000, 490000000}, 32800},
+ {{310050000, 490050000}, 33000},
+ {{310000000, 490050000}, 32700},
+ {{310050000, 490000000}, 33200},
+ {{310750000, 490150000}, 58399},
// midpoints
- {{310025, 490025}, 32.9F},
- {{310025, 490050}, 32.85F},
- {{310000, 490025}, 32.75F},
+ {{310025000, 490025000}, 32900},
+ {{310025000, 490050000}, 32850},
+ {{310000000, 490025000}, 32750},
// other
- {{310751, 490152}, 58.326F},
+ {{310751000, 490152000}, 58326},
}),
p, h)
{
- BOOST_CHECK_CLOSE_VEC(fixedTerrtain.positionAt(p), p ^ h);
+ BOOST_CHECK_EQUAL(fixedTerrtain.positionAt(p), GlobalPosition3D(p, h));
}
-using FindRayIntersectData = std::tuple<glm::vec3, glm::vec3, glm::vec3>;
+using FindRayIntersectData = std::tuple<GlobalPosition3D, Direction3D, GlobalPosition3D>;
BOOST_DATA_TEST_CASE(findRayIntersect,
boost::unit_test::data::make<FindRayIntersectData>({
- {{310000, 490000, 50}, {1, 1, -2}, {310008.59, 490008.59, 32.834301}},
- {{310000, 490000, 50}, {1, 1, -1}, {310017.12, 490017.12, 32.868526}},
+ {{310000000, 490000000, 50000}, {1, 1, -2}, {310008585, 490008585, 32834}},
+ {{310000000, 490000000, 50000}, {1, 1, -1}, {310017136, 490017136, 32868}},
}),
p, d, i)
{
- BOOST_CHECK_CLOSE_VEC(fixedTerrtain.intersectRay({p, d}).value(), i);
+ BOOST_CHECK_EQUAL(fixedTerrtain.intersectRay({p, d}).value(), i);
}
BOOST_AUTO_TEST_CASE(boundaryWalk)
@@ -128,22 +132,22 @@ BOOST_AUTO_TEST_CASE(boundaryWalk)
BOOST_CHECK_EQUAL(count, 2 * (ncols + nrows - 2));
}
-using WalkTerrainData = std::tuple<glm::vec2, glm::vec2, std::vector<int>>;
+using WalkTerrainData = std::tuple<GlobalPosition2D, GlobalPosition2D, std::vector<int>>;
BOOST_DATA_TEST_CASE(walkTerrain,
boost::unit_test::data::make<WalkTerrainData>({
- {{310002, 490003}, {310002, 490003}, {0}},
- {{310003, 490002}, {310003, 490002}, {1}},
- {{310002, 490003}, {310003, 490002}, {0, 1}},
- {{310003, 490002}, {310002, 490003}, {1, 0}},
- {{310002, 490003}, {310202, 490003}, {0, 1, 2, 3, 4, 5, 6, 7, 8}},
- {{310202, 490003}, {310002, 490003}, {8, 7, 6, 5, 4, 3, 2, 1, 0}},
- {{310002, 490003}, {310002, 490203}, {0, 399, 398, 797, 796, 1195, 1194, 1593, 1592}},
- {{310002, 490003}, {309999, 489999}, {0}},
- {{309999, 489999}, {310002, 490003}, {0}},
- {{320002, 500003}, {319949, 499948}, {79201}},
- {{309999, 490003}, {310004, 489997}, {0, 1}},
- {{310004, 489997}, {309999, 490003}, {1, 0}},
+ {{310002000, 490003000}, {310002000, 490003000}, {0}},
+ {{310003000, 490002000}, {310003000, 490002000}, {1}},
+ {{310002000, 490003000}, {310003000, 490002000}, {0, 1}},
+ {{310003000, 490002000}, {310002000, 490003000}, {1, 0}},
+ {{310002000, 490003000}, {310202000, 490003000}, {0, 1, 2, 3, 4, 5, 6, 7, 8}},
+ {{310202000, 490003000}, {310002000, 490003000}, {8, 7, 6, 5, 4, 3, 2, 1, 0}},
+ {{310002000, 490003000}, {310002000, 490203000}, {0, 399, 398, 797, 796, 1195, 1194, 1593, 1592}},
+ {{310002000, 490003000}, {309999000, 489999000}, {0}},
+ {{309999000, 489999000}, {310002000, 490003000}, {0}},
+ {{320002000, 500003000}, {319949000, 499948000}, {79201}},
+ {{309999000, 490003000}, {310004000, 489997000}, {0, 1}},
+ {{310004000, 489997000}, {309999000, 490003000}, {1, 0}},
}),
from, to, visits)
{
@@ -156,10 +160,10 @@ BOOST_DATA_TEST_CASE(walkTerrain,
BOOST_DATA_TEST_CASE(walkTerrainSetsFromFace,
boost::unit_test::data::make<WalkTerrainData>({
- {{310002, 490003}, {310002, 490003}, {0}},
- {{310003, 490002}, {310003, 490002}, {1}},
- {{310002, 490003}, {310003, 490002}, {0, 1}},
- {{310003, 490002}, {310002, 490003}, {1, 0}},
+ {{310002000, 490003000}, {310002000, 490003000}, {0}},
+ {{310003000, 490002000}, {310003000, 490002000}, {1}},
+ {{310002000, 490003000}, {310003000, 490002000}, {0, 1}},
+ {{310003000, 490002000}, {310002000, 490003000}, {1, 0}},
}),
from, to, visits)
{
@@ -170,13 +174,13 @@ BOOST_DATA_TEST_CASE(walkTerrainSetsFromFace,
BOOST_DATA_TEST_CASE(walkTerrainUntil,
boost::unit_test::data::make<WalkTerrainData>({
- {{310002, 490003}, {310002, 490003}, {0}},
- {{310003, 490002}, {310003, 490002}, {1}},
- {{310002, 490003}, {310003, 490002}, {0, 1}},
- {{310003, 490002}, {310002, 490003}, {1, 0}},
- {{310002, 490003}, {310202, 490003}, {0, 1, 2, 3, 4}},
- {{310202, 490003}, {310002, 490003}, {8, 7, 6, 5, 4}},
- {{310002, 490003}, {310002, 490203}, {0, 399, 398, 797, 796}},
+ {{310002000, 490003000}, {310002000, 490003000}, {0}},
+ {{310003000, 490002000}, {310003000, 490002000}, {1}},
+ {{310002000, 490003000}, {310003000, 490002000}, {0, 1}},
+ {{310003000, 490002000}, {310002000, 490003000}, {1, 0}},
+ {{310002000, 490003000}, {310202000, 490003000}, {0, 1, 2, 3, 4}},
+ {{310202000, 490003000}, {310002000, 490003000}, {8, 7, 6, 5, 4}},
+ {{310002000, 490003000}, {310002000, 490203000}, {0, 399, 398, 797, 796}},
}),
from, to, visits)
{
diff --git a/test/test-glContextBhvr.cpp b/test/test-glContextBhvr.cpp
index 2f71aec..26b45d9 100644
--- a/test/test-glContextBhvr.cpp
+++ b/test/test-glContextBhvr.cpp
@@ -31,7 +31,7 @@ BOOST_AUTO_TEST_CASE(windowContextThingsBehaviour1)
const SDL_GLContextPtr context {window};
BOOST_REQUIRE(context);
BOOST_REQUIRE(!glCreateProgram);
- BOOST_REQUIRE_EQUAL(gladLoadGL(reinterpret_cast<GLADloadfunc>(SDL_GL_GetProcAddress)), 40006);
+ BOOST_REQUIRE_GT(gladLoadGL(reinterpret_cast<GLADloadfunc>(SDL_GL_GetProcAddress)), 0);
BOOST_REQUIRE(glCreateProgram);
CreateProgramTest();
} // Context destroyed
diff --git a/test/test-maths.cpp b/test/test-maths.cpp
index 2560319..9eae918 100644
--- a/test/test-maths.cpp
+++ b/test/test-maths.cpp
@@ -196,12 +196,12 @@ BOOST_DATA_TEST_CASE(straight1,
const TestLinkStraight l(v);
{
const auto p = l.positionAt(0, 0);
- BOOST_CHECK_EQUAL(p.pos, origin);
+ BOOST_CHECK_EQUAL(p.pos, GlobalPosition3D {origin});
BOOST_CHECK_EQUAL(p.rot, glm::vec3(0, angFor, 0));
}
{
const auto p = l.positionAt(0, 1);
- BOOST_CHECK_EQUAL(p.pos, v);
+ BOOST_CHECK_EQUAL(p.pos, GlobalPosition3D {v});
BOOST_CHECK_EQUAL(p.rot, glm::vec3(0, angBack, 0));
}
}
@@ -231,12 +231,12 @@ BOOST_DATA_TEST_CASE(curve1,
BOOST_CHECK_EQUAL(l.radius, 1.F);
{
const auto p = l.positionAt(0, 0);
- BOOST_CHECK_CLOSE_VEC(p.pos, origin);
+ BOOST_CHECK_CLOSE_VEC(RelativePosition3D {p.pos}, origin);
BOOST_CHECK_CLOSE_VEC(p.rot, glm::vec3(0, angFor, 0));
}
{
const auto p = l.positionAt(0, 1);
- BOOST_CHECK_CLOSE_VEC(p.pos, e1);
+ BOOST_CHECK_CLOSE_VEC(RelativePosition3D {p.pos}, e1);
BOOST_CHECK_CLOSE_VEC(p.rot, glm::vec3(0, angBack, 0));
}
}
@@ -247,13 +247,13 @@ BOOST_DATA_TEST_CASE(curve1,
{
const auto p = l.positionAt(0, 0);
const auto angForReversed = normalize(vector_yaw(origin - e1) * 2 - angFor);
- BOOST_CHECK_CLOSE_VEC(p.pos, e1);
+ BOOST_CHECK_CLOSE_VEC(RelativePosition3D {p.pos}, e1);
BOOST_CHECK_CLOSE_VEC(p.rot, glm::vec3(0, angForReversed, 0));
}
{
const auto p = l.positionAt(0, 1);
const auto angBackReversed = normalize(vector_yaw(e1 - origin) * 2 - angBack);
- BOOST_CHECK_CLOSE_VEC(p.pos, origin);
+ BOOST_CHECK_CLOSE_VEC(RelativePosition3D {p.pos}, origin);
BOOST_CHECK_CLOSE_VEC(p.rot, glm::vec3(0, angBackReversed, 0));
}
}
diff --git a/test/test-render.cpp b/test/test-render.cpp
index fb2a71b..f15e51e 100644
--- a/test/test-render.cpp
+++ b/test/test-render.cpp
@@ -26,7 +26,7 @@ class TestScene : public SceneProvider {
std::shared_ptr<RailVehicle> train1, train2;
Terrain terrain {[]() {
- auto gd = std::make_shared<GeoData>(GeoData::createFlat({0, 0}, {1000, 1000}, 1));
+ auto gd = std::make_shared<GeoData>(GeoData::createFlat({0, 0}, {1000000, 1000000}, 1));
return gd;
}()};
@@ -34,11 +34,11 @@ public:
TestScene()
{
train1 = std::make_shared<RailVehicle>(brush47rvc);
- train1->location.setPosition({52, 50, 2});
+ train1->location.setPosition({52000, 50000, 2000});
train1->bogies.front().setPosition(train1->bogies.front().position() + train1->location.position());
train1->bogies.back().setPosition(train1->bogies.back().position() + train1->location.position());
train2 = std::make_shared<RailVehicle>(brush47rvc);
- train2->location.setPosition({52, 30, 2});
+ train2->location.setPosition({52000, 30000, 2000});
train2->bogies.front().setPosition(train2->bogies.front().position() + train2->location.position());
train2->bogies.back().setPosition(train2->bogies.back().position() + train2->location.position());
}
@@ -87,7 +87,7 @@ BOOST_FIXTURE_TEST_SUITE(w, TestRenderOutput);
BOOST_AUTO_TEST_CASE(basic)
{
SceneRenderer ss {size, output};
- ss.camera.setView({-10, -10, 60}, glm::normalize(glm::vec3 {1, 1, -0.5F}));
+ ss.camera.setView({-10000, -10000, 60000}, glm::normalize(glm::vec3 {1, 1, -0.5F}));
const TestScene scene;
ss.render(scene);
Texture::save(outImage, "/tmp/basic.tga");
@@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(basic)
BOOST_AUTO_TEST_CASE(pointlight)
{
SceneRenderer ss {size, output};
- ss.camera.setView({-10, -10, 60}, glm::normalize(glm::vec3 {1, 1, -0.5F}));
+ ss.camera.setView({-10000, -10000, 60000}, glm::normalize(glm::vec3 {1, 1, -0.5F}));
class PointLightScene : public TestScene {
public:
@@ -110,9 +110,9 @@ BOOST_AUTO_TEST_CASE(pointlight)
void
lights(const SceneShader & shader) const override
{
- for (int x = 50; x < 100; x += 20) {
- for (int y = 50; y < 2000; y += 20) {
- shader.pointLight.add({x, y, 4}, {1.0, 1.0, 1.0}, 0.1F);
+ for (int x = 50000; x < 100000; x += 20000) {
+ for (int y = 50000; y < 2000000; y += 20000) {
+ shader.pointLight.add({x, y, 4000}, {1.0, 1.0, 1.0}, 0.1F);
}
}
}
@@ -126,7 +126,7 @@ BOOST_AUTO_TEST_CASE(pointlight)
BOOST_AUTO_TEST_CASE(spotlight)
{
SceneRenderer ss {size, output};
- ss.camera.setView({-10, -10, 60}, glm::normalize(glm::vec3 {1, 1, -0.5F}));
+ ss.camera.setView({-10000, -10000, 60000}, glm::normalize(glm::vec3 {1, 1, -0.5F}));
class PointLightScene : public TestScene {
public:
@@ -140,10 +140,10 @@ BOOST_AUTO_TEST_CASE(spotlight)
void
lights(const SceneShader & shader) const override
{
- shader.spotLight.add({50, 50, 15}, down, {1.0, 1.0, 1.0}, 0.01F, 1);
- shader.spotLight.add({51, 59.5, 1}, north, {1.0, 1.0, 1.0}, 0.001F, .5);
- shader.spotLight.add({53, 59.5, 1}, north, {1.0, 1.0, 1.0}, 0.001F, .5);
- shader.spotLight.add({60, 50, 3}, north + east, {1.0, 1.0, 1.0}, 0.0001F, .7F);
+ shader.spotLight.add({50000, 50000, 15000}, down, {1.0, 1.0, 1.0}, 0.01F, 1);
+ shader.spotLight.add({51000, 59500, 1000}, north, {1.0, 1.0, 1.0}, 0.001F, .5);
+ shader.spotLight.add({53000, 59500, 1000}, north, {1.0, 1.0, 1.0}, 0.001F, .5);
+ shader.spotLight.add({60000, 50000, 3000}, north + east, {1.0, 1.0, 1.0}, 0.0001F, .7F);
}
};
diff --git a/test/testRenderOutput.cpp b/test/testRenderOutput.cpp
index 464b0b3..9af4451 100644
--- a/test/testRenderOutput.cpp
+++ b/test/testRenderOutput.cpp
@@ -1,7 +1,7 @@
#include "testRenderOutput.h"
#include <stdexcept>
-TestRenderOutput::TestRenderOutput(glm::ivec2 s) : size {s}
+TestRenderOutput::TestRenderOutput(TextureAbsCoord s) : size {s}
{
glBindFramebuffer(GL_FRAMEBUFFER, output);
const auto configuregdata
diff --git a/test/testRenderOutput.h b/test/testRenderOutput.h
index 13c380f..056d029 100644
--- a/test/testRenderOutput.h
+++ b/test/testRenderOutput.h
@@ -1,24 +1,25 @@
#pragma once
+#include "config/types.h"
#include "glArrays.h"
#include <glm/vec2.hpp>
#include <special_members.h>
class TestRenderOutput {
public:
- TestRenderOutput(glm::ivec2 size = {640, 480});
+ explicit TestRenderOutput(TextureAbsCoord size = {640, 480});
virtual ~TestRenderOutput() = default;
NO_MOVE(TestRenderOutput);
NO_COPY(TestRenderOutput);
- const glm::ivec2 size;
+ const TextureAbsCoord size;
glFrameBuffer output;
glRenderBuffer depth;
glTexture outImage;
};
-template<glm::ivec2 Size> class TestRenderOutputSize : public TestRenderOutput {
+template<TextureAbsCoord Size> class TestRenderOutputSize : public TestRenderOutput {
public:
TestRenderOutputSize() : TestRenderOutput {Size} { }
};
diff --git a/test/testStructures.h b/test/testStructures.h
index 6966052..aaaf940 100644
--- a/test/testStructures.h
+++ b/test/testStructures.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config/types.h"
#include <persistence.h>
struct AbsObject : public Persistence::Persistable {
@@ -31,9 +32,9 @@ struct TestObject : public Persistence::Persistable {
float flt {};
std::string str {};
bool bl {};
- glm::vec3 pos {};
+ Position3D pos {};
std::vector<float> flts;
- std::vector<glm::vec3> poss;
+ std::vector<Position3D> poss;
std::vector<std::vector<std::vector<std::string>>> nest;
std::unique_ptr<TestObject> ptr;
std::unique_ptr<AbsObject> aptr;
diff --git a/thirdparty/openmesh/glmcompat.h b/thirdparty/openmesh/glmcompat.h
index 708b1a6..dc5a96e 100644
--- a/thirdparty/openmesh/glmcompat.h
+++ b/thirdparty/openmesh/glmcompat.h
@@ -1,6 +1,7 @@
#pragma once
#include <OpenMesh/Core/Mesh/Traits.hh>
+#include <OpenMesh/Core/Utils/vector_cast.hh>
#include <glm/geometric.hpp>
#include <glm/vec3.hpp>
@@ -21,6 +22,18 @@ namespace glm {
}
namespace OpenMesh {
+ template<typename dst_t, typename src_t, glm::length_t n, glm::qualifier Q>
+ struct vector_caster<glm::vec<n, dst_t, Q>, glm::vec<n, src_t, Q>> {
+ using source_type = glm::vec<n, src_t, Q>;
+ using return_type = glm::vec<n, dst_t, Q>;
+
+ inline static return_type
+ cast(const source_type & _src)
+ {
+ return return_type {_src};
+ }
+ };
+
template<glm::length_t L, typename T, glm::qualifier Q> struct vector_traits<glm::vec<L, T, Q>> {
using vector_type = glm::vec<L, T, Q>;
using value_type = T;
diff --git a/ui/builders/freeExtend.h b/ui/builders/freeExtend.h
index 55fe7ff..b276426 100644
--- a/ui/builders/freeExtend.h
+++ b/ui/builders/freeExtend.h
@@ -9,5 +9,5 @@ class BuilderFreeExtend : public EditNetwork::Builder {
void click(Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e, const Ray & ray) override;
void move(Network * network, const GeoData * geoData, const SDL_MouseMotionEvent & e, const Ray & ray) override;
- std::optional<glm::vec3> p1;
+ std::optional<Position3D> p1;
};
diff --git a/ui/builders/straight.cpp b/ui/builders/straight.cpp
index 4fa9585..9b262bb 100644
--- a/ui/builders/straight.cpp
+++ b/ui/builders/straight.cpp
@@ -47,7 +47,7 @@ BuilderStraight::click(Network * network, const GeoData * geoData, const SDL_Mou
}
void
-BuilderStraight::create(Network * network, glm::vec3 p1, glm::vec3 p2) const
+BuilderStraight::create(Network * network, Position3D p1, Position3D p2) const
{
network->addStraight(p1, p2);
}
diff --git a/ui/builders/straight.h b/ui/builders/straight.h
index 1cde2b0..cf99a1d 100644
--- a/ui/builders/straight.h
+++ b/ui/builders/straight.h
@@ -9,7 +9,7 @@ class BuilderStraight : public EditNetwork::Builder {
void click(Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e, const Ray & ray) override;
void move(Network * network, const GeoData * geoData, const SDL_MouseMotionEvent & e, const Ray & ray) override;
- void create(Network * network, glm::vec3 p1, glm::vec3 p2) const;
+ void create(Network * network, Position3D p1, Position3D p2) const;
- std::optional<glm::vec3> p1;
+ std::optional<Position3D> p1;
};
diff --git a/ui/editNetwork.h b/ui/editNetwork.h
index eb1677e..e1aaa61 100644
--- a/ui/editNetwork.h
+++ b/ui/editNetwork.h
@@ -21,7 +21,7 @@ public:
void render(const SceneShader &) const override;
void render(const UIShader & shader, const UIComponent::Position & pos) const override;
- using NetworkClickPos = std::variant<glm::vec3, Node::Ptr>;
+ using NetworkClickPos = std::variant<Position3D, Node::Ptr>;
class Builder {
public:
diff --git a/ui/font.cpp b/ui/font.cpp
index 108f905..ebd856d 100644
--- a/ui/font.cpp
+++ b/ui/font.cpp
@@ -14,6 +14,7 @@
#include <unicode.h>
#include <util.h>
#include <utility>
+
// IWYU pragma: no_forward_declare FT_LibraryRec_
std::string
diff --git a/ui/font.h b/ui/font.h
index 6c86e18..2f3337f 100644
--- a/ui/font.h
+++ b/ui/font.h
@@ -31,6 +31,7 @@ public:
glm::ivec2 bearing;
long advance;
};
+
struct FontTexture {
glTexture texture;
unsigned int used;
diff --git a/ui/gameMainSelector.cpp b/ui/gameMainSelector.cpp
index 081718d..a451ee1 100644
--- a/ui/gameMainSelector.cpp
+++ b/ui/gameMainSelector.cpp
@@ -8,14 +8,16 @@
#include <game/selectable.h>
#include <game/worldobject.h> // IWYU pragma: keep
#include <gfx/gl/camera.h>
+#include <math.h>
#include <optional>
#include <span>
#include <stream_support.h>
#include <typeinfo>
#include <vector>
-GameMainSelector::GameMainSelector(const Camera * c, glm::vec2 size) : UIComponent {{{}, size}}, camera {c} { }
-constexpr glm::vec2 TargetPos {5, 45};
+GameMainSelector::GameMainSelector(const Camera * c, ScreenAbsCoord size) : UIComponent {{{}, size}}, camera {c} { }
+
+constexpr ScreenAbsCoord TargetPos {5, 45};
void
GameMainSelector::render(const UIShader & shader, const Position & parentPos) const
@@ -40,7 +42,7 @@ bool
GameMainSelector::handleInput(const SDL_Event & e, const Position & parentPos)
{
const auto getRay = [this](const auto & e) {
- const auto mouse = glm::vec2 {e.x, e.y} / position.size;
+ const auto mouse = ScreenRelCoord {e.x, e.y} / position.size;
return camera->unProject(mouse);
};
if (target) {
@@ -71,8 +73,8 @@ GameMainSelector::handleInput(const SDL_Event & e, const Position & parentPos)
void
GameMainSelector::defaultClick(const Ray & ray)
{
- glm::vec2 baryPos {};
- float distance;
+ Position2D baryPos {};
+ float distance {};
if (const auto selected
= gameState->world.applyOne<Selectable>(&Selectable::intersectRay, ray, &baryPos, &distance);
diff --git a/ui/gameMainSelector.h b/ui/gameMainSelector.h
index 98cdf53..88db34b 100644
--- a/ui/gameMainSelector.h
+++ b/ui/gameMainSelector.h
@@ -1,6 +1,7 @@
#pragma once
#include "SDL_events.h"
+#include "config/types.h"
#include "special_members.h"
#include "uiComponent.h"
#include "worldOverlay.h"
@@ -26,7 +27,7 @@ public:
virtual void render(const SceneShader &) const;
};
- GameMainSelector(const Camera * c, glm::vec2 size);
+ GameMainSelector(const Camera * c, ScreenAbsCoord size);
void render(const UIShader & shader, const Position & pos) const override;
void render(const SceneShader & shader) const override;
diff --git a/ui/gameMainWindow.cpp b/ui/gameMainWindow.cpp
index 6981c54..d71c74a 100644
--- a/ui/gameMainWindow.cpp
+++ b/ui/gameMainWindow.cpp
@@ -31,8 +31,8 @@ public:
GameMainWindow::GameMainWindow(size_t w, size_t h) :
Window {w, h, "I Like Trains", SDL_WINDOW_OPENGL}, SceneRenderer {Window::size, 0}
{
- uiComponents.create<ManualCameraController>(glm::vec2 {315000, 495000});
- auto gms = uiComponents.create<GameMainSelector>(&camera, glm::vec2 {w, h});
+ uiComponents.create<ManualCameraController>(glm::vec2 {315'000'000, 495'000'000});
+ auto gms = uiComponents.create<GameMainSelector>(&camera, ScreenAbsCoord {w, h});
uiComponents.create<GameMainToolbar>(gms.get());
}
@@ -48,6 +48,7 @@ GameMainWindow::render() const
SceneRenderer::render(*this);
Window::render();
}
+
void
GameMainWindow::content(const SceneShader & shader) const
{
@@ -59,17 +60,20 @@ GameMainWindow::content(const SceneShader & shader) const
gameState->world.apply<Renderable>(&Renderable::render, shader);
uiComponents.apply<WorldOverlay>(&WorldOverlay::render, shader);
}
+
void
GameMainWindow::environment(const SceneShader & s, const SceneRenderer & r) const
{
// default for now
SceneProvider::environment(s, r);
}
+
void
GameMainWindow::lights(const SceneShader & shader) const
{
gameState->world.apply<Renderable>(&Renderable::lights, shader);
}
+
void
GameMainWindow::shadows(const ShadowMapper & shadowMapper) const
{
diff --git a/ui/iconButton.h b/ui/iconButton.h
index 6ac9317..0afe92d 100644
--- a/ui/iconButton.h
+++ b/ui/iconButton.h
@@ -10,6 +10,7 @@ class UIShader;
union SDL_Event;
static const constexpr glm::vec2 ICON_SIZE {32.F, 32.F};
+
class IconButton : public UIComponent {
public:
IconButton(const std::string & icon, glm::vec2 position, UIEvent click);
diff --git a/ui/manualCameraController.cpp b/ui/manualCameraController.cpp
index 8e52b0e..f6993a8 100644
--- a/ui/manualCameraController.cpp
+++ b/ui/manualCameraController.cpp
@@ -59,12 +59,12 @@ ManualCameraController::handleInput(const SDL_Event & e, const Position &)
pitch = std::clamp(pitch - 0.01F * static_cast<float>(e.motion.yrel), 0.1F, half_pi);
}
else {
- focus += rotate_flat(-direction) * glm::vec2 {-e.motion.xrel, e.motion.yrel};
+ focus += rotate_flat(-direction) * (Position2D {-e.motion.xrel, e.motion.yrel} * dist / 2.0F);
}
}
return true;
case SDL_MOUSEWHEEL:
- dist = std::clamp(dist - static_cast<float>(e.wheel.y) * 4.F, 5.F, 200.F);
+ dist = std::clamp(dist - static_cast<float>(e.wheel.y) * 400.F, 5.F, 200000.F);
break;
}
return false;
diff --git a/ui/manualCameraController.h b/ui/manualCameraController.h
index d15fa76..1efaee1 100644
--- a/ui/manualCameraController.h
+++ b/ui/manualCameraController.h
@@ -11,7 +11,7 @@ class Camera;
class ManualCameraController : public CameraController, public UIComponent {
public:
- explicit ManualCameraController(glm::vec2 f) : UIComponent {{}}, focus {f} { }
+ explicit ManualCameraController(Position2D f) : UIComponent {{}}, focus {f} { }
bool handleInput(const SDL_Event & e, const Position &) override;
void render(const UIShader &, const Position & parentPos) const override;
@@ -20,7 +20,7 @@ public:
private:
bool ctrl {false}, mrb {false};
- glm::vec2 focus;
+ Position2D focus;
float direction {quarter_pi};
- float dist {40}, pitch {quarter_pi};
+ float dist {4000}, pitch {quarter_pi};
};
diff --git a/ui/modeHelper.h b/ui/modeHelper.h
index 77707f2..d20f2db 100644
--- a/ui/modeHelper.h
+++ b/ui/modeHelper.h
@@ -4,6 +4,7 @@
union SDL_Event;
enum ModeSecondClick { Unset, Reset, NoAction };
+
template<typename Target, ModeSecondClick msc = ModeSecondClick::Unset> class Mode {
public:
explicit Mode(Target & t) : target {t} { }
diff --git a/ui/text.cpp b/ui/text.cpp
index d24c268..b776b90 100644
--- a/ui/text.cpp
+++ b/ui/text.cpp
@@ -12,6 +12,7 @@
#include <utility>
const std::filesystem::path font {"/usr/share/fonts/hack/Hack-Regular.ttf"};
+
Text::Text(std::string_view s, Position pos, glm::vec3 c) : UIComponent {pos}, colour {c}
{
for (const auto & textureQuads :
diff --git a/ui/text.h b/ui/text.h
index 9fe87d1..de2fe2e 100644
--- a/ui/text.h
+++ b/ui/text.h
@@ -25,6 +25,7 @@ private:
glVertexArray vao;
glBuffer vbo;
};
+
std::vector<Model> models;
glm::vec3 colour;
};
diff --git a/ui/uiComponent.cpp b/ui/uiComponent.cpp
index e480fbc..aa4838d 100644
--- a/ui/uiComponent.cpp
+++ b/ui/uiComponent.cpp
@@ -20,6 +20,7 @@ UIComponent::Position::operator&(const glm::vec2 & pos) const
{
return (pos.x >= origin.x && pos.y >= origin.y && pos.x < origin.x + size.x && pos.y < origin.y + size.y);
}
+
bool
UIComponent::Position::operator&(const SDL_MouseButtonEvent & pos) const
{
diff --git a/ui/uiComponent.h b/ui/uiComponent.h
index 75c2284..71d2659 100644
--- a/ui/uiComponent.h
+++ b/ui/uiComponent.h
@@ -18,6 +18,7 @@ public:
bool operator&(const SDL_MouseButtonEvent &) const;
bool operator&(const glm::vec2 &) const;
};
+
explicit UIComponent(Position);
virtual ~UIComponent() = default;
diff --git a/ui/uiComponentPlacer.cpp b/ui/uiComponentPlacer.cpp
index 368e772..5e645d8 100644
--- a/ui/uiComponentPlacer.cpp
+++ b/ui/uiComponentPlacer.cpp
@@ -16,6 +16,7 @@ UIComponentPlacer::next(glm::vec2 size)
max = std::max(max, size[1 - axis]);
return n;
}
+
glm::vec2
UIComponentPlacer::getLimit() const
{
diff --git a/ui/window.h b/ui/window.h
index 369228a..8f2b70b 100644
--- a/ui/window.h
+++ b/ui/window.h
@@ -31,11 +31,12 @@ public:
protected:
virtual void render() const;
+
struct GLInitHelper {
GLInitHelper();
};
- const glm::ivec2 size;
+ const ScreenAbsCoord size;
SDL_WindowPtr m_window;
SDL_GLContextPtr glContext;
GLInitHelper glInithelper;