lots of changes

This commit is contained in:
2025-07-01 20:38:31 +02:00
parent c3475ec41d
commit 41eecfa2c2
29 changed files with 35194 additions and 33659 deletions
+6 -6
View File
@@ -1,7 +1,7 @@
target_sources(MeshShadingDemo
PUBLIC
FlyCam.h
FlyCam.cpp
PathFollowCam.h
PathFollowCam.cpp
target_sources(MeshShadingDemo
PUBLIC
FlyCam.h
FlyCam.cpp
PathFollowCam.h
PathFollowCam.cpp
)
+20 -20
View File
@@ -1,21 +1,21 @@
#include "FlyCam.h"
FlyCam::FlyCam(PScene scene)
: Actor(scene)
{
attachComponent<Component::Camera>();
attachComponent<Component::KeyboardInput>();
}
FlyCam::~FlyCam()
{}
Component::Camera& FlyCam::getCamera()
{
return accessComponent<Component::Camera>();
}
Component::KeyboardInput& FlyCam::getKeyboardInput()
{
return accessComponent<Component::KeyboardInput>();
#include "FlyCam.h"
FlyCam::FlyCam(PScene scene)
: Actor(scene)
{
attachComponent<Component::Camera>();
attachComponent<Component::KeyboardInput>();
}
FlyCam::~FlyCam()
{}
Component::Camera& FlyCam::getCamera()
{
return accessComponent<Component::Camera>();
}
Component::KeyboardInput& FlyCam::getKeyboardInput()
{
return accessComponent<Component::KeyboardInput>();
}
+16 -16
View File
@@ -1,17 +1,17 @@
#pragma once
#include "Define.h"
#include <MinimalEngine.h>
#include <Actor/Actor.h>
#include <Component/KeyboardInput.h>
#include <Component/Camera.h>
class FlyCam : public Actor
{
public:
FlyCam(PScene scene);
virtual ~FlyCam();
Component::KeyboardInput& getKeyboardInput();
Component::Camera& getCamera();
private:
};
#pragma once
#include "Define.h"
#include <MinimalEngine.h>
#include <Actor/Actor.h>
#include <Component/KeyboardInput.h>
#include <Component/Camera.h>
class FlyCam : public Actor
{
public:
FlyCam(PScene scene);
virtual ~FlyCam();
Component::KeyboardInput& getKeyboardInput();
Component::Camera& getCamera();
private:
};
DEFINE_REF(FlyCam)
+22 -22
View File
@@ -1,22 +1,22 @@
#include "PathFollowCam.h"
PathFollowCam::PathFollowCam(PScene scene)
: Actor(scene)
{
attachComponent<Component::Camera>();
attachComponent<PathFollow>();
}
PathFollowCam::~PathFollowCam()
{}
PathFollow& PathFollowCam::getPathFollow()
{
return accessComponent<PathFollow>();
}
Component::Camera& PathFollowCam::getCamera()
{
return accessComponent<Component::Camera>();
}
#include "PathFollowCam.h"
PathFollowCam::PathFollowCam(PScene scene)
: Actor(scene)
{
attachComponent<Component::Camera>();
attachComponent<PathFollow>();
}
PathFollowCam::~PathFollowCam()
{}
PathFollow& PathFollowCam::getPathFollow()
{
return accessComponent<PathFollow>();
}
Component::Camera& PathFollowCam::getCamera()
{
return accessComponent<Component::Camera>();
}
+16 -16
View File
@@ -1,17 +1,17 @@
#pragma once
#include "Define.h"
#include <MinimalEngine.h>
#include <Actor/Actor.h>
#include <Component/PathFollow.h>
#include <Component/Camera.h>
class PathFollowCam : public Actor
{
public:
PathFollowCam(PScene scene);
virtual ~PathFollowCam();
PathFollow& getPathFollow();
Component::Camera& getCamera();
private:
};
#pragma once
#include "Define.h"
#include <MinimalEngine.h>
#include <Actor/Actor.h>
#include <Component/PathFollow.h>
#include <Component/Camera.h>
class PathFollowCam : public Actor
{
public:
PathFollowCam(PScene scene);
virtual ~PathFollowCam();
PathFollow& getPathFollow();
Component::Camera& getCamera();
private:
};
DEFINE_REF(PathFollowCam)
+9 -9
View File
@@ -1,9 +1,9 @@
target_sources(MeshShadingDemo
PUBLIC
Define.h
MeshShadingDemoGame.h
MeshShadingDemoGame.cpp)
add_subdirectory(Actor/)
add_subdirectory(Component/)
add_subdirectory(System/)
target_sources(MeshShadingDemo
PUBLIC
Define.h
MeshShadingDemoGame.h
MeshShadingDemoGame.cpp)
add_subdirectory(Actor/)
add_subdirectory(Component/)
add_subdirectory(System/)
+3 -3
View File
@@ -1,4 +1,4 @@
target_sources(MeshShadingDemo
PRIVATE
Path.h
target_sources(MeshShadingDemo
PRIVATE
Path.h
PathFollow.h)
+187 -187
View File
@@ -1,188 +1,188 @@
#pragma once
#include <Define.h>
#include <MinimalEngine.h>
#include <Containers/Array.h>
#include <Math/Vector.h>
#include <Graphics/DebugVertex.h>
struct Path
{
static constexpr float ARC_LENGTH_TABLE_DISTANCE = 0.05f;
static constexpr float LAST_POS_EPSILON = 0.015f;
Path(Array<Vector> points)
: points(std::move(points))
{
createDebugVertices();
updateArcLengthTable();
}
// How sharply the curve bends at the interpolated points, between 0 and 1.
float tension = 0.5f;
// The points of the Catmull-Rom curve
Array<Vector> points = Array<Vector>();
// Offset How many points should be skipped when checking arc length table to find distance (optimization)
int pointOffset = 0;
// Whether to start from the first point once the last point has been reached.
bool looping = false;
// Arc Length table, stores for each arc (between two consecutive points)
// a list of chord length distances. The chord length entries are stored with a distance
// of ARC_LENGTH_TABLE_DISTANCE and contain the arc length approximated by cummulative chord lengths.
// E.g. if ARC_LENGTH_TABLE_DISTANCE = 0.2f, then the first entry in the first vector is
// the chord length (=direct distance) between t=0 and t=0.2,
// the second one the distance between t=0 and t=0.4, and so on
Array<Array<float>> arcLengthTable = Array<Array<float>>();
bool showSplineCurve = false;
bool showControlPoints = false;
bool showArcLengthTableSamplePoints = false;
int debugSplineCurveVerticesCount = 0;
int debugArcLengthTableSampleVerticesCount = 0;
private:
Array<DebugVertex> verticesSplineCurve;
Array<DebugVertex> verticesArcLengthTableSample;
public:
// Needs to be called the first time.
// Creates vertices used for rendering the debug lines and control points
void createDebugVertices()
{
updateDebugControlPoints();
updateDebugSplineCurveVertices(Array<Vector>());
updateDebugArcLengthTableSample(Array<Vector>());
}
void updateDebugControlPoints()
{
Array<DebugVertex> verticesControlPoints = Array<DebugVertex>();
for (uint32_t i = 0; i < points.size(); i++)
{
DebugVertex v = DebugVertex{
.position = points[i],
.color = Vector(1, 0, 0),
};
verticesControlPoints.add(v);
}
}
void updateDebugSplineCurveVertices(const Array<Vector>& newSplineCurvePoints)
{
for (uint32_t i = 1; i < newSplineCurvePoints.size(); i++) // First one can be skipped, as it's always the last one from previous call
{
DebugVertex v = DebugVertex{
.position = newSplineCurvePoints[i],
.color = Vector(0, 0, 1),
};
verticesSplineCurve.add(v);
}
debugSplineCurveVerticesCount = verticesSplineCurve.size();
}
void updateDebugArcLengthTableSample(const Array<Vector>& newArcLengthTablePositions)
{
for (uint32_t i = 1; i < newArcLengthTablePositions.size(); i++) // First one can be skipped, as it's always the last one from previous call
{
DebugVertex v = DebugVertex{
.position = newArcLengthTablePositions[i],
.color = Vector(0, 1, 0),
};
verticesArcLengthTableSample.add(v);
}
debugArcLengthTableSampleVerticesCount = verticesArcLengthTableSample.size();
}
void updateArcLengthTable()
{
assert(points.size() > 3);
Array<Vector> debugPoints = Array<Vector>(); //only used for debug visualization
// don't recalculate existing entries
int startIndex = arcLengthTable.size();
float previousDistance = 0.0f;
if (arcLengthTable.size() > 0)
{
Array<float> pChoordLength = arcLengthTable[arcLengthTable.size() - 1];
previousDistance = pChoordLength[pChoordLength.size() - 1];
}
int stepsPerP = 1.0f / Path::ARC_LENGTH_TABLE_DISTANCE;
// If path is looping, we need to check all points
int p0IndexBorder = looping ? points.size() : points.size() - 3;
// First distance is p1 to p2 (since p0 is skipped), but we check loop by p0
for (int p0Index = startIndex; p0Index < p0IndexBorder; p0Index++)
{
Array<float> choordLengths = Array<float>();
Vector pA = catmullrom(0,
points[(p0Index) % points.size()],
points[(p0Index + 1) % points.size()],
points[(p0Index + 2) % points.size()],
points[(p0Index + 3) % points.size()],
tension);
debugPoints.add(pA);
// First distance is always same as last distance from previous step/point
choordLengths.add(previousDistance);
for (int step = 1; step < (stepsPerP + 1); step++)
{
Vector pB = catmullrom(step * Path::ARC_LENGTH_TABLE_DISTANCE,
points[(p0Index) % points.size()],
points[(p0Index + 1) % points.size()],
points[(p0Index + 2) % points.size()],
points[(p0Index + 3) % points.size()],
tension);
debugPoints.add(pB);
previousDistance += glm::distance(pA, pB);
choordLengths.add(previousDistance);
pA = pB;
}
Array<float>& arr = arcLengthTable.add();
arr = std::move(choordLengths);
}
updateDebugArcLengthTableSample(debugPoints);
updateDebugSplineCurveVertices(debugPoints);
}
void appendPoints(const Array<Vector>& toBeAppendedPoints, Vector pointPositionOffset)
{
size_t originalSize = points.size();
points.resize(originalSize + toBeAppendedPoints.size());
for (size_t i = 0; i < toBeAppendedPoints.size(); i++)
{
points[originalSize + i] = toBeAppendedPoints[i] + pointPositionOffset;
}
updateDebugControlPoints();
}
float getPathLength() const
{
if (arcLengthTable.size() == 0 || arcLengthTable.back().size() == 0)
return 0.f;
return arcLengthTable.back().back();
}
// Returns float P(t) between p1 and p2
static float catmullrom(float t, float p0, float p1, float p2, float p3, float tension)
{
// TODO: The tension variable doesn't fully influence this function.
// If it's something else than 0.5, This would need to be rewritten, as the matrix would be a bit different then
return tension * (
(2 * p1) +
(-p0 + p2) * t +
(2 * p0 - 5 * p1 + 4 * p2 - p3) * t * t +
(-p0 + 3 * p1 - 3 * p2 + p3) * t * t * t
);
}
// Returns point P(t) between p1 and p2
static Vector catmullrom(float t, Vector p0, Vector p1, Vector p2, Vector p3, float tension)
{
return Vector(
catmullrom(t, p0.x, p1.x, p2.x, p3.x, tension),
catmullrom(t, p0.y, p1.y, p2.y, p3.y, tension),
catmullrom(t, p0.z, p1.z, p2.z, p3.z, tension)
);
}
#pragma once
#include <Define.h>
#include <MinimalEngine.h>
#include <Containers/Array.h>
#include <Math/Vector.h>
#include <Graphics/DebugVertex.h>
struct Path
{
static constexpr float ARC_LENGTH_TABLE_DISTANCE = 0.05f;
static constexpr float LAST_POS_EPSILON = 0.015f;
Path(Array<Vector> points)
: points(std::move(points))
{
createDebugVertices();
updateArcLengthTable();
}
// How sharply the curve bends at the interpolated points, between 0 and 1.
float tension = 0.5f;
// The points of the Catmull-Rom curve
Array<Vector> points = Array<Vector>();
// Offset How many points should be skipped when checking arc length table to find distance (optimization)
int pointOffset = 0;
// Whether to start from the first point once the last point has been reached.
bool looping = false;
// Arc Length table, stores for each arc (between two consecutive points)
// a list of chord length distances. The chord length entries are stored with a distance
// of ARC_LENGTH_TABLE_DISTANCE and contain the arc length approximated by cummulative chord lengths.
// E.g. if ARC_LENGTH_TABLE_DISTANCE = 0.2f, then the first entry in the first vector is
// the chord length (=direct distance) between t=0 and t=0.2,
// the second one the distance between t=0 and t=0.4, and so on
Array<Array<float>> arcLengthTable = Array<Array<float>>();
bool showSplineCurve = false;
bool showControlPoints = false;
bool showArcLengthTableSamplePoints = false;
int debugSplineCurveVerticesCount = 0;
int debugArcLengthTableSampleVerticesCount = 0;
private:
Array<DebugVertex> verticesSplineCurve;
Array<DebugVertex> verticesArcLengthTableSample;
public:
// Needs to be called the first time.
// Creates vertices used for rendering the debug lines and control points
void createDebugVertices()
{
updateDebugControlPoints();
updateDebugSplineCurveVertices(Array<Vector>());
updateDebugArcLengthTableSample(Array<Vector>());
}
void updateDebugControlPoints()
{
Array<DebugVertex> verticesControlPoints = Array<DebugVertex>();
for (uint32_t i = 0; i < points.size(); i++)
{
DebugVertex v = DebugVertex{
.position = points[i],
.color = Vector(1, 0, 0),
};
verticesControlPoints.add(v);
}
}
void updateDebugSplineCurveVertices(const Array<Vector>& newSplineCurvePoints)
{
for (uint32_t i = 1; i < newSplineCurvePoints.size(); i++) // First one can be skipped, as it's always the last one from previous call
{
DebugVertex v = DebugVertex{
.position = newSplineCurvePoints[i],
.color = Vector(0, 0, 1),
};
verticesSplineCurve.add(v);
}
debugSplineCurveVerticesCount = verticesSplineCurve.size();
}
void updateDebugArcLengthTableSample(const Array<Vector>& newArcLengthTablePositions)
{
for (uint32_t i = 1; i < newArcLengthTablePositions.size(); i++) // First one can be skipped, as it's always the last one from previous call
{
DebugVertex v = DebugVertex{
.position = newArcLengthTablePositions[i],
.color = Vector(0, 1, 0),
};
verticesArcLengthTableSample.add(v);
}
debugArcLengthTableSampleVerticesCount = verticesArcLengthTableSample.size();
}
void updateArcLengthTable()
{
assert(points.size() > 3);
Array<Vector> debugPoints = Array<Vector>(); //only used for debug visualization
// don't recalculate existing entries
int startIndex = arcLengthTable.size();
float previousDistance = 0.0f;
if (arcLengthTable.size() > 0)
{
Array<float> pChoordLength = arcLengthTable[arcLengthTable.size() - 1];
previousDistance = pChoordLength[pChoordLength.size() - 1];
}
int stepsPerP = 1.0f / Path::ARC_LENGTH_TABLE_DISTANCE;
// If path is looping, we need to check all points
int p0IndexBorder = looping ? points.size() : points.size() - 3;
// First distance is p1 to p2 (since p0 is skipped), but we check loop by p0
for (int p0Index = startIndex; p0Index < p0IndexBorder; p0Index++)
{
Array<float> choordLengths = Array<float>();
Vector pA = catmullrom(0,
points[(p0Index) % points.size()],
points[(p0Index + 1) % points.size()],
points[(p0Index + 2) % points.size()],
points[(p0Index + 3) % points.size()],
tension);
debugPoints.add(pA);
// First distance is always same as last distance from previous step/point
choordLengths.add(previousDistance);
for (int step = 1; step < (stepsPerP + 1); step++)
{
Vector pB = catmullrom(step * Path::ARC_LENGTH_TABLE_DISTANCE,
points[(p0Index) % points.size()],
points[(p0Index + 1) % points.size()],
points[(p0Index + 2) % points.size()],
points[(p0Index + 3) % points.size()],
tension);
debugPoints.add(pB);
previousDistance += glm::distance(pA, pB);
choordLengths.add(previousDistance);
pA = pB;
}
Array<float>& arr = arcLengthTable.add();
arr = std::move(choordLengths);
}
updateDebugArcLengthTableSample(debugPoints);
updateDebugSplineCurveVertices(debugPoints);
}
void appendPoints(const Array<Vector>& toBeAppendedPoints, Vector pointPositionOffset)
{
size_t originalSize = points.size();
points.resize(originalSize + toBeAppendedPoints.size());
for (size_t i = 0; i < toBeAppendedPoints.size(); i++)
{
points[originalSize + i] = toBeAppendedPoints[i] + pointPositionOffset;
}
updateDebugControlPoints();
}
float getPathLength() const
{
if (arcLengthTable.size() == 0 || arcLengthTable.back().size() == 0)
return 0.f;
return arcLengthTable.back().back();
}
// Returns float P(t) between p1 and p2
static float catmullrom(float t, float p0, float p1, float p2, float p3, float tension)
{
// TODO: The tension variable doesn't fully influence this function.
// If it's something else than 0.5, This would need to be rewritten, as the matrix would be a bit different then
return tension * (
(2 * p1) +
(-p0 + p2) * t +
(2 * p0 - 5 * p1 + 4 * p2 - p3) * t * t +
(-p0 + 3 * p1 - 3 * p2 + p3) * t * t * t
);
}
// Returns point P(t) between p1 and p2
static Vector catmullrom(float t, Vector p0, Vector p1, Vector p2, Vector p3, float tension)
{
return Vector(
catmullrom(t, p0.x, p1.x, p2.x, p3.x, tension),
catmullrom(t, p0.y, p1.y, p2.y, p3.y, tension),
catmullrom(t, p0.z, p1.z, p2.z, p3.z, tension)
);
}
};
+26 -26
View File
@@ -1,27 +1,27 @@
#pragma once
#include "Define.h"
#include <Math/Vector.h>
#include <Actor/Actor.h>
struct PathFollow
{
enum class SpeedControl {
Linear,
EaseInEaseOut
};
PEntity path;
// How many seconds since start of path, used to calculate new position in path
float time = 0.0f;
// How much distance per passed second will be traversed along the path
float traversalSpeed = 1.0f;
// The desired speed control function (choose Linear to simply use the traversal speed)
SpeedControl speedControl = SpeedControl::Linear;
// Distance travelled through the path
float distance = 0.0f;
// The entity's Transform will always get this offset applied
Vector pathOffset = Seele::Vector(0);
Vector lastPos = Vector(0);
#pragma once
#include "Define.h"
#include <Math/Vector.h>
#include <Actor/Actor.h>
struct PathFollow
{
enum class SpeedControl {
Linear,
EaseInEaseOut
};
PEntity path;
// How many seconds since start of path, used to calculate new position in path
float time = 0.0f;
// How much distance per passed second will be traversed along the path
float traversalSpeed = 1.0f;
// The desired speed control function (choose Linear to simply use the traversal speed)
SpeedControl speedControl = SpeedControl::Linear;
// Distance travelled through the path
float distance = 0.0f;
// The entity's Transform will always get this offset applied
Vector pathOffset = Seele::Vector(0);
Vector lastPos = Vector(0);
};
+13 -13
View File
@@ -1,14 +1,14 @@
#pragma once
#include <MinimalEngine.h>
using namespace Seele;
#ifdef WIN32
#ifdef BUILD_DLL
#define MESHSHADINGDEMO_API __declspec(dllexport)
#else
#define MESHSHADINGDEMO_API __declspec(dllimport)
#endif
#else
#define MESHSHADINGDEMO_API
#pragma once
#include <MinimalEngine.h>
using namespace Seele;
#ifdef WIN32
#ifdef BUILD_DLL
#define MESHSHADINGDEMO_API __declspec(dllexport)
#else
#define MESHSHADINGDEMO_API __declspec(dllimport)
#endif
#else
#define MESHSHADINGDEMO_API
#endif
+217 -217
View File
@@ -1,218 +1,218 @@
#include "MeshShadingDemoGame.h"
#include "Actor/FlyCam.h"
#include "Asset/AssetRegistry.h"
#include "Component/Transform.h"
#include "Component/TerrainTile.h"
#include "System/FlyCamSystem.h"
#include "Component/Path.h"
#include "Component/WaterTile.h"
#include "System/SplineCamSystem.h"
#include "Graphics/StaticMeshVertexData.h"
MeshShadingDemoGame::MeshShadingDemoGame()
{
}
MeshShadingDemoGame::~MeshShadingDemoGame()
{
}
void MeshShadingDemoGame::setupScene(PScene scene, PSystemGraph graph)
{
flyCam = new FlyCam(scene);
flyCam->attachComponent<Component::PointLight>(Vector(1, 1, 1), 1.0f, 2.0f);
flyCam->getCamera().mainCamera = true;
followCam = new PathFollowCam(scene);
//followCam->getCamera().mainCamera = true;
/* {
Array<Vector> lightPoints = {
Vector(13.542, 3.12369, -12.3293),
Vector(20.6668, 3.04548, -20.9486),
Vector(11.5522, 3.09676, -45.9563),
Vector(10.392, 3.0536, -63.238),
Vector(14.8289, 3.01454, -72.0112),
Vector(16.9386, 3.06158, -80.7447),
Vector(17.6772, 3.05903, -89.3406),
Vector(17.4801, 3.03598, -97.9897),
Vector(17.1882, 3.04928, -106.596),
Vector(16.8547, 3.05735, -116.065),
Vector(16.6074, 3.05262, -123.884),
Vector(16.331, 3.03858, -132.499),
Vector(16.0015, 3.07391, -141.126),
Vector(26.1148, 3.05149, -141.591),
Vector(26.4517, 3.06293, -132.945),
Vector(26.7491, 3.06205, -124.321),
Vector(27.0371, 3.11222, -115.731),
Vector(28.7401, 3.063, -98.5291),
Vector(29.0123, 3.09289, -89.8635),
Vector(28.5112, 3.07688, -81.2221),
Vector(26.8285, 3.12346, -72.5381),
Vector(23.7577, 3.07845, -63.8065),
Vector(18.4836, 3.07243, -54.9846),
Vector(11.5667, 3.0757, -46.1511),
Vector(44.4868, 3.169, -11.858),
Vector(50.5335, 3.15588, -21.1511),
Vector(54.2709, 3.18958, -30.2516),
Vector(55.6934, 3.22225, -39.0652),
Vector(55.8267, 3.16783, -47.748),
Vector(55.0125, 3.20429, -56.3455),
Vector(54.0781, 3.20927, -64.9114),
Vector(53.1076, 3.17979, -74.2689),
Vector(52.2437, 3.21515, -82.0613),
Vector(51.3169, 3.19196, -90.6292),
Vector(50.3008, 3.20521, -99.2916),
Vector(60.4217, 3.17473, -100.424),
Vector(61.3612, 3.21026, -91.855),
Vector(62.2923, 3.1473, -83.2846),
Vector(63.2343, 3.18438, -74.7077),
Vector(66.1857, 3.23896, -57.6697),
Vector(67.1304, 3.19608, -49.0803),
Vector(67.2474, 3.17215, -40.4073),
Vector(66.2297, 3.20527, -31.6281),
Vector(63.8036, 3.21531, -22.7063),
Vector(59.241, 3.19388, -13.5084),
Vector(53.0474, 3.21296, -4.20644),
Vector(4.588, 3.085, 4.934),
Vector(7.953, 3.121, -3.686),
Vector(13.556, 3.187, -20.951),
Vector(28.248, 3.119, -12.431),
Vector(21.286, 3.132, -3.812),
Vector(16.584, 3.1152, 4.822),
Vector(14.232, 3.151, 13.474),
Vector(13.178, 3.144, 22.079),
Vector(13.074, 3.176, 30.716),
Vector(13.053, 3.136, 39.339),
Vector(13.062, 3.163, 48.746),
Vector(13.067, 3.097, 56.555),
Vector(13.051, 3.109, 65.204),
Vector(13.073, 3.107, 73.822),
Vector(2.997, 3.1082, 73.903),
Vector(2.951, 3.127, 65.324),
Vector(2.939, 3.117, 56.713),
Vector(2.939, 3.100, 48.078),
Vector(1.819, 3.048, 30.881),
Vector(1.812, 3.076, 22.211),
Vector(2.647, 3.154, 13.573),
};
Path p = Path({
Vector(-16.9676, 5.7499, -77.5539),
Vector(-3.95049, 3.51678, -60.7428),
Vector(0.954792, 3.47537, -55.1175),
Vector(16.9581, 3.26171, -34.3647),
Vector(25.8841, 3.0817, -24.1843),
Vector(42.8916, 2.71463, -7.55981),
Vector(58.1216, 2.88532, -15.9938),
Vector(67.3108, 3.40471, -48.757),
Vector(73.9232, 3.10779, -144.263),
Vector(81.7667, 3.32603, -172.821),
});
for (auto p : lightPoints)
{
lights.add(new PointLightActor(scene, p, Vector(251 / 255.f, 207 / 255.f, 107 / 255.f), 2));
}
path = new Entity(scene);
path->attachComponent<Path>(p);
chapel = new StaticMeshActor(scene, AssetRegistry::findMesh("Whitechapel", "Whitechapel"));
followCam->getPathFollow().path = path;
}*/
/*
{
Path p = Path({
Vector(-28.8013, 9.58383, -84.0442),
Vector(-27.5597, 9.09855, -57.1531),
Vector(-27.2196, 8.99756, -14.1793),
Vector(-27.5354, 8.11755, 26.1741),
Vector(-28.6125, 7.32383, 67.1864),
Vector(-5.20891, 7.62963, 87.9103),
Vector(18.1879, 8.19607, 113.661),
Vector(18.8014, 5.01105, 149.623),
Vector(18.6341, 4.84045, 183.52),
Vector(21.6458, 4.17056, 190.23),
});
path = new Entity(scene);
path->attachComponent<Path>(p);
for (uint32 y = 0; y < 2; y++)
{
for (uint32 x = 0; x < 2; x++)
{
suburbs.add(new StaticMeshActor(scene, AssetRegistry::findMesh("suburbs", "city-suburbs")));
suburbs.back()->getTransform().setPosition(Vector(x * 143, 0, y * 193));
}
}
followCam->getPathFollow().path = path;
}*/
{
Path p = Path({
Vector(33.3414, 36.8653, 28.819),
Vector(69.6004, 42.7509, 109.65),
Vector(82.0893, 43.8156, 127.942),
Vector(106.724, 42.0612, 154.561),
Vector(168.118, 39.9358, 220.453),
Vector(219.94, 42.453, 273.038),
Vector(244.23, 44.1136, 289.115),
Vector(253.318, 44.4212, 303.567),
Vector(256.505, 44.6277, 324.343),
Vector(282.637, 45.0222, 371.102),
Vector(299.247, 45.3911, 375.493),
Vector(393.234, 37.4515, 364.943),
});
//path = new Entity(scene);
//path->attachComponent<Path>(p);
//followCam->getPathFollow().path = path;
//minecraft = new StaticMeshActor(scene, AssetRegistry::findMesh("minecraft", "minecraft-medieval-city"));
//minecraft->getTransform().setScale(Vector(0.01, 0.01, 0.01));
}
{
Path p = Path({
Vector(89.3805, 153.648, 270.467),
Vector(131.966, 119.247, 116.347),
Vector(72.9846, 95.5085, 18.481),
Vector(23.1404, 96.2972, 31.0632),
Vector(-12.3954, 100.118, -10.2085),
Vector(-11.1341, 104.619, -79.1077),
Vector(-7.61656, 112.695, -102.459),
});
//path = new Entity(scene);
//path->attachComponent<Path>(p);
//followCam->getPathFollow().path = path;
//volvo = new StaticMeshActor(scene, AssetRegistry::findMesh("Volvo", "Volvo"));
}
test = new StaticMeshActor(scene, AssetRegistry::findMesh("rttest", "rttest"));
//test->getTransform().setScale(Vector(0.01, 0.01, 0.01));
/*for (int32 y = -40; y < 40; ++y)
{
for (int32 x = -40; x < 40; ++x)
{
scene->attachComponent<Component::WaterTile>(scene->createEntity(), Component::WaterTile{
.location = IVector2(x, y),
.height = 0,
});
}
}*/
center = new PointLightActor(scene, Vector(0, 0, 0), 10, Vector(1, 1, 1), 10);
xAxis = new PointLightActor(scene, Vector(10, 0, 0), 10, Vector(1, 0, 0), 10);
yAxis = new PointLightActor(scene, Vector(0, 10, 0), 10, Vector(0, 1, 0), 10);
zAxis = new PointLightActor(scene, Vector(0, 0, 10), 10, Vector(0, 0, 1), 10);
light = new DirectionalLightActor(scene, Vector(1, 1, 1), 1, Vector(0.4, -0.4, 0));
graph->addSystem(new FlyCamSystem(scene));
graph->addSystem(new SplineCamSystem(scene));
}
Game* createInstance()
{
return new MeshShadingDemoGame();
}
void destroyInstance(Game* game)
{
delete game;
#include "MeshShadingDemoGame.h"
#include "Actor/FlyCam.h"
#include "Asset/AssetRegistry.h"
#include "Component/Transform.h"
#include "Component/TerrainTile.h"
#include "System/FlyCamSystem.h"
#include "Component/Path.h"
#include "Component/WaterTile.h"
#include "System/SplineCamSystem.h"
#include "Graphics/StaticMeshVertexData.h"
MeshShadingDemoGame::MeshShadingDemoGame()
{
}
MeshShadingDemoGame::~MeshShadingDemoGame()
{
}
void MeshShadingDemoGame::setupScene(PScene scene, PSystemGraph graph)
{
flyCam = new FlyCam(scene);
flyCam->attachComponent<Component::PointLight>(Vector(1, 1, 1), 1.0f, 2.0f);
flyCam->getCamera().mainCamera = true;
followCam = new PathFollowCam(scene);
//followCam->getCamera().mainCamera = true;
/* {
Array<Vector> lightPoints = {
Vector(13.542, 3.12369, -12.3293),
Vector(20.6668, 3.04548, -20.9486),
Vector(11.5522, 3.09676, -45.9563),
Vector(10.392, 3.0536, -63.238),
Vector(14.8289, 3.01454, -72.0112),
Vector(16.9386, 3.06158, -80.7447),
Vector(17.6772, 3.05903, -89.3406),
Vector(17.4801, 3.03598, -97.9897),
Vector(17.1882, 3.04928, -106.596),
Vector(16.8547, 3.05735, -116.065),
Vector(16.6074, 3.05262, -123.884),
Vector(16.331, 3.03858, -132.499),
Vector(16.0015, 3.07391, -141.126),
Vector(26.1148, 3.05149, -141.591),
Vector(26.4517, 3.06293, -132.945),
Vector(26.7491, 3.06205, -124.321),
Vector(27.0371, 3.11222, -115.731),
Vector(28.7401, 3.063, -98.5291),
Vector(29.0123, 3.09289, -89.8635),
Vector(28.5112, 3.07688, -81.2221),
Vector(26.8285, 3.12346, -72.5381),
Vector(23.7577, 3.07845, -63.8065),
Vector(18.4836, 3.07243, -54.9846),
Vector(11.5667, 3.0757, -46.1511),
Vector(44.4868, 3.169, -11.858),
Vector(50.5335, 3.15588, -21.1511),
Vector(54.2709, 3.18958, -30.2516),
Vector(55.6934, 3.22225, -39.0652),
Vector(55.8267, 3.16783, -47.748),
Vector(55.0125, 3.20429, -56.3455),
Vector(54.0781, 3.20927, -64.9114),
Vector(53.1076, 3.17979, -74.2689),
Vector(52.2437, 3.21515, -82.0613),
Vector(51.3169, 3.19196, -90.6292),
Vector(50.3008, 3.20521, -99.2916),
Vector(60.4217, 3.17473, -100.424),
Vector(61.3612, 3.21026, -91.855),
Vector(62.2923, 3.1473, -83.2846),
Vector(63.2343, 3.18438, -74.7077),
Vector(66.1857, 3.23896, -57.6697),
Vector(67.1304, 3.19608, -49.0803),
Vector(67.2474, 3.17215, -40.4073),
Vector(66.2297, 3.20527, -31.6281),
Vector(63.8036, 3.21531, -22.7063),
Vector(59.241, 3.19388, -13.5084),
Vector(53.0474, 3.21296, -4.20644),
Vector(4.588, 3.085, 4.934),
Vector(7.953, 3.121, -3.686),
Vector(13.556, 3.187, -20.951),
Vector(28.248, 3.119, -12.431),
Vector(21.286, 3.132, -3.812),
Vector(16.584, 3.1152, 4.822),
Vector(14.232, 3.151, 13.474),
Vector(13.178, 3.144, 22.079),
Vector(13.074, 3.176, 30.716),
Vector(13.053, 3.136, 39.339),
Vector(13.062, 3.163, 48.746),
Vector(13.067, 3.097, 56.555),
Vector(13.051, 3.109, 65.204),
Vector(13.073, 3.107, 73.822),
Vector(2.997, 3.1082, 73.903),
Vector(2.951, 3.127, 65.324),
Vector(2.939, 3.117, 56.713),
Vector(2.939, 3.100, 48.078),
Vector(1.819, 3.048, 30.881),
Vector(1.812, 3.076, 22.211),
Vector(2.647, 3.154, 13.573),
};
Path p = Path({
Vector(-16.9676, 5.7499, -77.5539),
Vector(-3.95049, 3.51678, -60.7428),
Vector(0.954792, 3.47537, -55.1175),
Vector(16.9581, 3.26171, -34.3647),
Vector(25.8841, 3.0817, -24.1843),
Vector(42.8916, 2.71463, -7.55981),
Vector(58.1216, 2.88532, -15.9938),
Vector(67.3108, 3.40471, -48.757),
Vector(73.9232, 3.10779, -144.263),
Vector(81.7667, 3.32603, -172.821),
});
for (auto p : lightPoints)
{
lights.add(new PointLightActor(scene, p, Vector(251 / 255.f, 207 / 255.f, 107 / 255.f), 2));
}
path = new Entity(scene);
path->attachComponent<Path>(p);
chapel = new StaticMeshActor(scene, AssetRegistry::findMesh("Whitechapel", "Whitechapel"));
followCam->getPathFollow().path = path;
}*/
/*
{
Path p = Path({
Vector(-28.8013, 9.58383, -84.0442),
Vector(-27.5597, 9.09855, -57.1531),
Vector(-27.2196, 8.99756, -14.1793),
Vector(-27.5354, 8.11755, 26.1741),
Vector(-28.6125, 7.32383, 67.1864),
Vector(-5.20891, 7.62963, 87.9103),
Vector(18.1879, 8.19607, 113.661),
Vector(18.8014, 5.01105, 149.623),
Vector(18.6341, 4.84045, 183.52),
Vector(21.6458, 4.17056, 190.23),
});
path = new Entity(scene);
path->attachComponent<Path>(p);
for (uint32 y = 0; y < 2; y++)
{
for (uint32 x = 0; x < 2; x++)
{
suburbs.add(new StaticMeshActor(scene, AssetRegistry::findMesh("suburbs", "city-suburbs")));
suburbs.back()->getTransform().setPosition(Vector(x * 143, 0, y * 193));
}
}
followCam->getPathFollow().path = path;
}*/
{
Path p = Path({
Vector(33.3414, 36.8653, 28.819),
Vector(69.6004, 42.7509, 109.65),
Vector(82.0893, 43.8156, 127.942),
Vector(106.724, 42.0612, 154.561),
Vector(168.118, 39.9358, 220.453),
Vector(219.94, 42.453, 273.038),
Vector(244.23, 44.1136, 289.115),
Vector(253.318, 44.4212, 303.567),
Vector(256.505, 44.6277, 324.343),
Vector(282.637, 45.0222, 371.102),
Vector(299.247, 45.3911, 375.493),
Vector(393.234, 37.4515, 364.943),
});
//path = new Entity(scene);
//path->attachComponent<Path>(p);
//followCam->getPathFollow().path = path;
//minecraft = new StaticMeshActor(scene, AssetRegistry::findMesh("minecraft", "minecraft-medieval-city"));
//minecraft->getTransform().setScale(Vector(0.01, 0.01, 0.01));
}
{
Path p = Path({
Vector(89.3805, 153.648, 270.467),
Vector(131.966, 119.247, 116.347),
Vector(72.9846, 95.5085, 18.481),
Vector(23.1404, 96.2972, 31.0632),
Vector(-12.3954, 100.118, -10.2085),
Vector(-11.1341, 104.619, -79.1077),
Vector(-7.61656, 112.695, -102.459),
});
//path = new Entity(scene);
//path->attachComponent<Path>(p);
//followCam->getPathFollow().path = path;
//volvo = new StaticMeshActor(scene, AssetRegistry::findMesh("Volvo", "Volvo"));
}
test = new StaticMeshActor(scene, AssetRegistry::findMesh("rttest", "rttest"));
//test->getTransform().setScale(Vector(0.01, 0.01, 0.01));
/*for (int32 y = -40; y < 40; ++y)
{
for (int32 x = -40; x < 40; ++x)
{
scene->attachComponent<Component::WaterTile>(scene->createEntity(), Component::WaterTile{
.location = IVector2(x, y),
.height = 0,
});
}
}*/
center = new PointLightActor(scene, Vector(0, 0, 0), 10, Vector(1, 1, 1), 10);
xAxis = new PointLightActor(scene, Vector(10, 0, 0), 10, Vector(1, 0, 0), 10);
yAxis = new PointLightActor(scene, Vector(0, 10, 0), 10, Vector(0, 1, 0), 10);
zAxis = new PointLightActor(scene, Vector(0, 0, 10), 10, Vector(0, 0, 1), 10);
light = new DirectionalLightActor(scene, Vector(1, 1, 1), 1, Vector(0.4, -0.4, 0));
graph->addSystem(new FlyCamSystem(scene));
graph->addSystem(new SplineCamSystem(scene));
}
Game* createInstance()
{
return new MeshShadingDemoGame();
}
void destroyInstance(Game* game)
{
delete game;
}
+33 -33
View File
@@ -1,34 +1,34 @@
#pragma once
#include "Actor/FlyCam.h"
#include "Actor/PathFollowCam.h"
#include "Define.h"
#include <Actor/StaticMeshActor.h>
#include <Actor/DirectionalLightActor.h>
#include <Actor/PointLightActor.h>
#include <Game.h>
class MESHSHADINGDEMO_API MeshShadingDemoGame : public Game {
public:
MeshShadingDemoGame();
virtual ~MeshShadingDemoGame();
virtual void setupScene(PScene scene, PSystemGraph graph) override;
private:
Array<OPointLightActor> lights;
OStaticMeshActor chapel;
OStaticMeshActor test;
OStaticMeshActor minecraft;
OStaticMeshActor volvo;
Array<OStaticMeshActor> suburbs;
OEntity path;
OFlyCam flyCam;
OPathFollowCam followCam;
ODirectionalLightActor light;
OPointLightActor center;
OPointLightActor xAxis;
OPointLightActor yAxis;
OPointLightActor zAxis;
};
extern "C" MESHSHADINGDEMO_API Game* createInstance();
#pragma once
#include "Actor/FlyCam.h"
#include "Actor/PathFollowCam.h"
#include "Define.h"
#include <Actor/StaticMeshActor.h>
#include <Actor/DirectionalLightActor.h>
#include <Actor/PointLightActor.h>
#include <Game.h>
class MESHSHADINGDEMO_API MeshShadingDemoGame : public Game {
public:
MeshShadingDemoGame();
virtual ~MeshShadingDemoGame();
virtual void setupScene(PScene scene, PSystemGraph graph) override;
private:
Array<OPointLightActor> lights;
OStaticMeshActor chapel;
OStaticMeshActor test;
OStaticMeshActor minecraft;
OStaticMeshActor volvo;
Array<OStaticMeshActor> suburbs;
OEntity path;
OFlyCam flyCam;
OPathFollowCam followCam;
ODirectionalLightActor light;
OPointLightActor center;
OPointLightActor xAxis;
OPointLightActor yAxis;
OPointLightActor zAxis;
};
extern "C" MESHSHADINGDEMO_API Game* createInstance();
extern "C" MESHSHADINGDEMO_API void destroyInstance(Game* game);
+5 -5
View File
@@ -1,6 +1,6 @@
target_sources(MeshShadingDemo
PUBLIC
FlyCamSystem.h
FlyCamSystem.cpp
SplineCamSystem.h
target_sources(MeshShadingDemo
PUBLIC
FlyCamSystem.h
FlyCamSystem.cpp
SplineCamSystem.h
SplineCamSystem.cpp)
+53 -53
View File
@@ -1,54 +1,54 @@
#include "FlyCamSystem.h"
FlyCamSystem::FlyCamSystem(PScene scene)
: System::ComponentSystem<Component::KeyboardInput, Component::Camera, Component::Transform, Component::PointLight>(scene) {}
FlyCamSystem::~FlyCamSystem() {}
void FlyCamSystem::update(Component::KeyboardInput& input, Component::Camera& camera, Component::Transform& transform, Component::PointLight& light) {
float cameraMove = static_cast<float>(deltaTime) * 4;
if(input.keys[KeyCode::KEY_LEFT_SHIFT])
{
cameraMove *= 10;
}
Vector forward = transform.getForward();
Vector side = transform.getRight();
Vector moveVector = Vector();
if (input.keys[KeyCode::KEY_J])
{
std::cout << transform.getPosition() << std::endl;
}
if(input.keys[KeyCode::KEY_W])
{
moveVector += forward * cameraMove;
}
if(input.keys[KeyCode::KEY_S])
{
moveVector += forward * -cameraMove;
}
if(input.keys[KeyCode::KEY_A])
{
moveVector += side * -cameraMove;
}
if(input.keys[KeyCode::KEY_D])
{
moveVector += side * cameraMove;
}
if(input.keys[KeyCode::KEY_E])
{
moveVector += Vector(0, cameraMove, 0);
}
if(input.keys[KeyCode::KEY_Q])
{
moveVector += Vector(0, -cameraMove, 0);
}
transform.translate(moveVector);
if(input.mouse2)
{
transform.setRotation(glm::rotate(transform.getRotation(), input.deltaX / 500, Vector(0, 1, 0)));
transform.setRotation(glm::rotate(transform.getRotation(), input.deltaY / 500, transform.getRight()));
}
light.attenuation += input.scrollY * 0.1;
#include "FlyCamSystem.h"
FlyCamSystem::FlyCamSystem(PScene scene)
: System::ComponentSystem<Component::KeyboardInput, Component::Camera, Component::Transform, Component::PointLight>(scene) {}
FlyCamSystem::~FlyCamSystem() {}
void FlyCamSystem::update(Component::KeyboardInput& input, Component::Camera& camera, Component::Transform& transform, Component::PointLight& light) {
float cameraMove = static_cast<float>(deltaTime) * 4;
if(input.keys[KeyCode::KEY_LEFT_SHIFT])
{
cameraMove *= 10;
}
Vector forward = transform.getForward();
Vector side = transform.getRight();
Vector moveVector = Vector();
if (input.keys[KeyCode::KEY_J])
{
std::cout << transform.getPosition() << std::endl;
}
if(input.keys[KeyCode::KEY_W])
{
moveVector += forward * cameraMove;
}
if(input.keys[KeyCode::KEY_S])
{
moveVector += forward * -cameraMove;
}
if(input.keys[KeyCode::KEY_A])
{
moveVector += side * -cameraMove;
}
if(input.keys[KeyCode::KEY_D])
{
moveVector += side * cameraMove;
}
if(input.keys[KeyCode::KEY_E])
{
moveVector += Vector(0, cameraMove, 0);
}
if(input.keys[KeyCode::KEY_Q])
{
moveVector += Vector(0, -cameraMove, 0);
}
transform.translate(moveVector);
if(input.mouse2)
{
transform.setRotation(glm::rotate(transform.getRotation(), input.deltaX / 500, Vector(0, 1, 0)));
transform.setRotation(glm::rotate(transform.getRotation(), input.deltaY / 500, transform.getRight()));
}
light.attenuation += input.scrollY * 0.1;
}
+22 -22
View File
@@ -1,23 +1,23 @@
#pragma once
#include "Define.h"
#include <MinimalEngine.h>
#include <Scene/Scene.h>
#include <System/ComponentSystem.h>
#include <Component/Camera.h>
#include <Component/KeyboardInput.h>
class FlyCamSystem : public System::ComponentSystem<
Component::KeyboardInput,
Component::Camera,
Component::Transform,
Component::PointLight>
{
public:
FlyCamSystem(PScene scene);
virtual ~FlyCamSystem();
virtual void update(Seele::Component::KeyboardInput& input, Seele::Component::Camera& camera, Seele::Component::Transform& transform, Seele::Component::PointLight& pointLight) override;
private:
float lastMouseX;
float lastMouseY;
};
#pragma once
#include "Define.h"
#include <MinimalEngine.h>
#include <Scene/Scene.h>
#include <System/ComponentSystem.h>
#include <Component/Camera.h>
#include <Component/KeyboardInput.h>
class FlyCamSystem : public System::ComponentSystem<
Component::KeyboardInput,
Component::Camera,
Component::Transform,
Component::PointLight>
{
public:
FlyCamSystem(PScene scene);
virtual ~FlyCamSystem();
virtual void update(Seele::Component::KeyboardInput& input, Seele::Component::Camera& camera, Seele::Component::Transform& transform, Seele::Component::PointLight& pointLight) override;
private:
float lastMouseX;
float lastMouseY;
};
DEFINE_REF(FlyCamSystem)
+141 -141
View File
@@ -1,141 +1,141 @@
#include "SplineCamSystem.h"
SplineCamSystem::SplineCamSystem(PScene scene)
: System::ComponentSystem<Component::Camera, Component::Transform, PathFollow>(scene)
{}
SplineCamSystem::~SplineCamSystem()
{}
void SplineCamSystem::update(Component::Camera& cam, Component::Transform& transform, PathFollow& follow)
{
if (follow.path == nullptr)
return;
Path& path = follow.path->accessComponent<Path>();
//for (size_t i = 0; i < path.points.size() - 1; ++i)
//{
// addDebugVertex(DebugVertex{
// .position = path.points[i],
// .color = Vector(0, 1, 0)
// });
// addDebugVertex(DebugVertex{
// .position = path.points[i + 1],
// .color = Vector(0, 1, 0)
// });
//}
updateFollowDistance(follow, path.getPathLength());
std::tuple<int, float> pt = findP0AndTForDistance(path, follow.distance);
auto [p0Index, t] = pt;
if (p0Index < 0 || (path.points.size() <= p0Index + 3 && !path.looping))
// Not enough points to interpolate...
return;
Vector p0 = path.points[p0Index];
Vector p1 = path.points[(p0Index + 1) % path.points.size()];
Vector p2 = path.points[(p0Index + 2) % path.points.size()];
Vector p3 = path.points[(p0Index + 3) % path.points.size()];
Vector oldPos = transform.getPosition() - follow.pathOffset;
Vector newPos = path.catmullrom(t, p0, p1, p2, p3, path.tension);
transform.setPosition(newPos + follow.pathOffset);
if ((oldPos - follow.lastPos).length() > Path::LAST_POS_EPSILON)
{
follow.lastPos = oldPos;
}
Vector tangentVector = glm::normalize(follow.lastPos - newPos);
Quaternion newRot = glm::quatLookAt(tangentVector, Vector(0.0f, 1.0f, 0.0f));
transform.setRotation(newRot);
}
std::tuple<int, float> SplineCamSystem::findP0AndTForDistance(const Path& path, float distance)
{
if (path.arcLengthTable.size() == 0)
return std::tuple<int, float>(-1, 0.0f);
int p0 = -1;
float t = 0.0f;
int pIndexToCheck = 1;//path.pointOffset + 1;
//if (path.looping)
//{
// // If looping, subtract loop distance until we are in the final "lap"
// float lapDistance = path.arcLengthTable[path.arcLengthTable.size() - 1][path.arcLengthTable[path.arcLengthTable.size() - 1].size() - 1];
// while (distance >= lapDistance)
// {
// distance -= lapDistance;
// }
//
// // If we are in a new loop, the path.pointOffset might not be valid anymore
// if (path.arcLengthTable[path.pointOffset][0] > distance)
// {
// pIndexToCheck = 1;
// }
//}
float lapDistance = path.arcLengthTable[path.arcLengthTable.size() - 1][path.arcLengthTable[path.arcLengthTable.size() - 1].size() - 1];
if (distance >= lapDistance)
{
getGlobals().running = false;
}
while (pIndexToCheck < path.arcLengthTable.size()
&& path.arcLengthTable[pIndexToCheck][0] < distance)
{
pIndexToCheck++;
}
p0 = pIndexToCheck - 1;
int arcTableIndex = 1;
float additionalT = 0.0f;
// TODO this could be improved e.g. by using binary search
while (arcTableIndex < path.arcLengthTable[p0].size()
&& path.arcLengthTable[p0][arcTableIndex] < distance)
{
arcTableIndex++;
}
arcTableIndex--;
// Interpolate between arc length table entries to find additionalT
if (arcTableIndex + 1 < path.arcLengthTable[p0].size())
{
float distanceA = path.arcLengthTable[p0][arcTableIndex];
float distanceB = path.arcLengthTable[p0][arcTableIndex + 1];
float abDistance = distanceB - distanceA;
float requiredDistanceAfterA = distance - distanceA;
additionalT = Path::ARC_LENGTH_TABLE_DISTANCE * (requiredDistanceAfterA / abDistance);
}
t = (arcTableIndex * Path::ARC_LENGTH_TABLE_DISTANCE) + additionalT;
assert(p0 < path.points.size());
assert(t >= 0.0f && t <= 1.0f);
return std::tuple<int, float>(p0, t);
}
void SplineCamSystem::updateFollowDistance(PathFollow& follow, float pathLength)
{
follow.time = follow.time + deltaTime;
switch (follow.speedControl)
{
case PathFollow::SpeedControl::Linear:
// We increase distance instead of setting it based on overall time, because Linear SpeedControl allows for traversalSpeed change
follow.distance += (deltaTime * follow.traversalSpeed);
break;
case PathFollow::SpeedControl::EaseInEaseOut:
{
float timeNeededForPath = pathLength / follow.traversalSpeed;
float t = follow.time / timeNeededForPath;
int laps = (int)t;
t = t - laps;
float s = (glm::sin(t * glm::pi<float>() - glm::pi<float>() / 2.f) + 1) / 2.f;
follow.distance = ((laps + s) * pathLength);
break;
}
default:
assert(false && "Unknown SpeedControl");
}
}
#include "SplineCamSystem.h"
SplineCamSystem::SplineCamSystem(PScene scene)
: System::ComponentSystem<Component::Camera, Component::Transform, PathFollow>(scene)
{}
SplineCamSystem::~SplineCamSystem()
{}
void SplineCamSystem::update(Component::Camera& cam, Component::Transform& transform, PathFollow& follow)
{
if (follow.path == nullptr)
return;
Path& path = follow.path->accessComponent<Path>();
//for (size_t i = 0; i < path.points.size() - 1; ++i)
//{
// addDebugVertex(DebugVertex{
// .position = path.points[i],
// .color = Vector(0, 1, 0)
// });
// addDebugVertex(DebugVertex{
// .position = path.points[i + 1],
// .color = Vector(0, 1, 0)
// });
//}
updateFollowDistance(follow, path.getPathLength());
std::tuple<int, float> pt = findP0AndTForDistance(path, follow.distance);
auto [p0Index, t] = pt;
if (p0Index < 0 || (path.points.size() <= p0Index + 3 && !path.looping))
// Not enough points to interpolate...
return;
Vector p0 = path.points[p0Index];
Vector p1 = path.points[(p0Index + 1) % path.points.size()];
Vector p2 = path.points[(p0Index + 2) % path.points.size()];
Vector p3 = path.points[(p0Index + 3) % path.points.size()];
Vector oldPos = transform.getPosition() - follow.pathOffset;
Vector newPos = path.catmullrom(t, p0, p1, p2, p3, path.tension);
transform.setPosition(newPos + follow.pathOffset);
if ((oldPos - follow.lastPos).length() > Path::LAST_POS_EPSILON)
{
follow.lastPos = oldPos;
}
Vector tangentVector = glm::normalize(follow.lastPos - newPos);
Quaternion newRot = glm::quatLookAt(tangentVector, Vector(0.0f, 1.0f, 0.0f));
transform.setRotation(newRot);
}
std::tuple<int, float> SplineCamSystem::findP0AndTForDistance(const Path& path, float distance)
{
if (path.arcLengthTable.size() == 0)
return std::tuple<int, float>(-1, 0.0f);
int p0 = -1;
float t = 0.0f;
int pIndexToCheck = 1;//path.pointOffset + 1;
//if (path.looping)
//{
// // If looping, subtract loop distance until we are in the final "lap"
// float lapDistance = path.arcLengthTable[path.arcLengthTable.size() - 1][path.arcLengthTable[path.arcLengthTable.size() - 1].size() - 1];
// while (distance >= lapDistance)
// {
// distance -= lapDistance;
// }
//
// // If we are in a new loop, the path.pointOffset might not be valid anymore
// if (path.arcLengthTable[path.pointOffset][0] > distance)
// {
// pIndexToCheck = 1;
// }
//}
float lapDistance = path.arcLengthTable[path.arcLengthTable.size() - 1][path.arcLengthTable[path.arcLengthTable.size() - 1].size() - 1];
if (distance >= lapDistance)
{
getGlobals().running = false;
}
while (pIndexToCheck < path.arcLengthTable.size()
&& path.arcLengthTable[pIndexToCheck][0] < distance)
{
pIndexToCheck++;
}
p0 = pIndexToCheck - 1;
int arcTableIndex = 1;
float additionalT = 0.0f;
// TODO this could be improved e.g. by using binary search
while (arcTableIndex < path.arcLengthTable[p0].size()
&& path.arcLengthTable[p0][arcTableIndex] < distance)
{
arcTableIndex++;
}
arcTableIndex--;
// Interpolate between arc length table entries to find additionalT
if (arcTableIndex + 1 < path.arcLengthTable[p0].size())
{
float distanceA = path.arcLengthTable[p0][arcTableIndex];
float distanceB = path.arcLengthTable[p0][arcTableIndex + 1];
float abDistance = distanceB - distanceA;
float requiredDistanceAfterA = distance - distanceA;
additionalT = Path::ARC_LENGTH_TABLE_DISTANCE * (requiredDistanceAfterA / abDistance);
}
t = (arcTableIndex * Path::ARC_LENGTH_TABLE_DISTANCE) + additionalT;
assert(p0 < path.points.size());
assert(t >= 0.0f && t <= 1.0f);
return std::tuple<int, float>(p0, t);
}
void SplineCamSystem::updateFollowDistance(PathFollow& follow, float pathLength)
{
follow.time = follow.time + deltaTime;
switch (follow.speedControl)
{
case PathFollow::SpeedControl::Linear:
// We increase distance instead of setting it based on overall time, because Linear SpeedControl allows for traversalSpeed change
follow.distance += (deltaTime * follow.traversalSpeed);
break;
case PathFollow::SpeedControl::EaseInEaseOut:
{
float timeNeededForPath = pathLength / follow.traversalSpeed;
float t = follow.time / timeNeededForPath;
int laps = (int)t;
t = t - laps;
float s = (glm::sin(t * glm::pi<float>() - glm::pi<float>() / 2.f) + 1) / 2.f;
follow.distance = ((laps + s) * pathLength);
break;
}
default:
assert(false && "Unknown SpeedControl");
}
}
+22 -22
View File
@@ -1,23 +1,23 @@
#pragma once
#include "Define.h"
#include <MinimalEngine.h>
#include <Scene/Scene.h>
#include <System/ComponentSystem.h>
#include <Component/Camera.h>
#include <Component/Path.h>
#include <Component/PathFollow.h>
class SplineCamSystem : public System::ComponentSystem<
Component::Camera,
Component::Transform,
PathFollow>
{
public:
SplineCamSystem(PScene scene);
virtual ~SplineCamSystem();
virtual void update(Component::Camera& camera, Component::Transform& transform, PathFollow& follow);
private:
std::tuple<int, float> findP0AndTForDistance(const Path& path, float distance);
void updateFollowDistance(PathFollow& follow, float pathLength);
};
#pragma once
#include "Define.h"
#include <MinimalEngine.h>
#include <Scene/Scene.h>
#include <System/ComponentSystem.h>
#include <Component/Camera.h>
#include <Component/Path.h>
#include <Component/PathFollow.h>
class SplineCamSystem : public System::ComponentSystem<
Component::Camera,
Component::Transform,
PathFollow>
{
public:
SplineCamSystem(PScene scene);
virtual ~SplineCamSystem();
virtual void update(Component::Camera& camera, Component::Transform& transform, PathFollow& follow);
private:
std::tuple<int, float> findP0AndTForDistance(const Path& path, float distance);
void updateFollowDistance(PathFollow& follow, float pathLength);
};
DEFINE_REF(SplineCamSystem)