Compare commits

..

No commits in common. "59d9311cc890b6d00a3be73491f6268d1b7b9422" and "af019d331851192eaddf0a90ed6bfe376a5b1ed0" have entirely different histories.

9 changed files with 64 additions and 418 deletions

View File

@ -28,10 +28,10 @@ struct Lines {
}
void render() const {
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
// glEnable(GL_LINE_SMOOTH);
// glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glBindVertexArray(lineVAO);
glLineWidth(1.0f);
glLineWidth(3.3f);
glDrawArrays(GL_LINES, 0, vertex_count);
glLineWidth(1.0f);
}

View File

@ -5,6 +5,7 @@
#ifndef ECSGAME_MESH_H
#define ECSGAME_MESH_H
#include <GLFW/glfw3.h>
#include <glad/glad.h>
#include <vector>

View File

@ -8,16 +8,13 @@
#include "../Components/Transform.h"
#include "../ECS.h"
#include <map>
using namespace ECS;
class CollisionSystem : public EntitySystem {
public:
CollisionSystem(Entity *collision_entity) : collision_entity(collision_entity) {}
// Initialize the kdtree
void build() {
std::vector<Triangle *> triangles;
std::vector<Point *> points;
// ObjMesh
@ -26,11 +23,7 @@ class CollisionSystem : public EntitySystem {
std::vector<unsigned int> indices = mesh->indices;
std::vector<float> vertices = mesh->vertices;
std::map<Vector, Point *> triangle_map;
// TODO: Iterate over vertices, add triangles by also iterating over indices
for (int i = 0; i < mesh->vertex_count; i += 3) {
// Build vertices from this triangle
float v0p0 = vertices[indices[i + 0] * 14 + 0];
float v0p1 = vertices[indices[i + 0] * 14 + 1];
float v0p2 = vertices[indices[i + 0] * 14 + 2];
@ -58,30 +51,12 @@ class CollisionSystem : public EntitySystem {
Vector v3(v3glm.x, v3glm.y, v3glm.z);
Triangle *triangle = new Triangle(v1, v2, v3);
triangles.emplace_back(triangle);
if (triangle_map.count(v1) == 0) {
triangle_map[v1] = new Point(v1, std::list<Triangle *>{triangle});
} else {
triangle_map[v1]->triangles.emplace_back(triangle);
}
if (triangle_map.count(v2) == 0) {
triangle_map[v2] = new Point(v2, std::list<Triangle *>{triangle});
} else {
triangle_map[v2]->triangles.emplace_back(triangle);
}
if (triangle_map.count(v3) == 0) {
triangle_map[v3] = new Point(v3, std::list<Triangle *>{triangle});
} else {
triangle_map[v3]->triangles.emplace_back(triangle);
}
points.emplace_back(new Point(v1, triangle));
points.emplace_back(new Point(v2, triangle));
points.emplace_back(new Point(v3, triangle));
}
// Convert to list
std::transform(
triangle_map.begin(), triangle_map.end(), back_inserter(points),
[](const std::map<Vector, Point *>::value_type &val) { return val.second; });
});
// LODObjMesh
@ -93,6 +68,8 @@ class CollisionSystem : public EntitySystem {
std::cout << "Start building kdtree with " << points.size() << " points" << std::endl;
kdtree = new KDTree(points);
std::cout << "Done" << std::endl;
std::cout << kdtree->to_string() << std::endl;
}
void tick(World *pWorld, float deltaTime) override {
@ -104,23 +81,16 @@ class CollisionSystem : public EntitySystem {
glm::vec3 direction_glm = mouse_look->get_look_direction();
Vector direction = Vector(direction_glm.x, direction_glm.y, direction_glm.z);
Ray ray(origin, direction);
Ray ray(origin, direction * 5.0);
Vector collision_position(0, 0, 0);
const Triangle *result = kdtree->intersect_ray(ray, collision_position);
Triangle *result = kdtree->intersect_ray(ray);
if (result) {
// Output to console
std::cout << "Triangle: " << result->p1[0] << ", " << result->p1[1] << ", "
<< result->p1[2] << " | " << result->p2[0] << ", " << result->p2[1]
<< ", " << result->p2[2] << " | " << result->p3[0] << ", "
<< result->p3[1] << ", " << result->p3[2] << std::endl;
// Ouput visually
glm::vec3 pos =
glm::vec3(collision_position[0], collision_position[1], collision_position[2]);
collision_entity->get<Transform>()->set_origin(pos);
std::cout << result->p1[0] << ", " << result->p1[1] << ", " << result->p1[2]
<< std::endl;
}
// TODO: Also output visually
});
}
@ -129,6 +99,4 @@ class CollisionSystem : public EntitySystem {
World *myWorld;
KDTree *kdtree;
Entity *collision_entity;
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 557 B

View File

@ -1,10 +0,0 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 500
Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

View File

@ -1,271 +0,0 @@
# Blender v2.83.5 OBJ File: ''
# www.blender.org
mtllib sphere.mtl
o Icosphere
v -0.000000 -0.200000 -0.000000
v 0.144721 -0.089444 0.105145
v -0.055278 -0.089444 0.170130
v -0.178885 -0.089443 -0.000000
v -0.055278 -0.089444 -0.170130
v 0.144721 -0.089444 -0.105145
v 0.055278 0.089444 0.170130
v -0.144721 0.089444 0.105145
v -0.144721 0.089444 -0.105145
v 0.055278 0.089444 -0.170130
v 0.178885 0.089443 -0.000000
v -0.000000 0.200000 -0.000000
v -0.032491 -0.170131 0.099999
v 0.085065 -0.170131 0.061802
v 0.052574 -0.105148 0.161802
v 0.170130 -0.105147 -0.000000
v 0.085065 -0.170131 -0.061802
v -0.105146 -0.170130 -0.000000
v -0.137638 -0.105147 0.099999
v -0.032491 -0.170131 -0.099999
v -0.137638 -0.105147 -0.099999
v 0.052574 -0.105148 -0.161802
v 0.190212 0.000000 0.061803
v 0.190212 0.000000 -0.061803
v -0.000000 0.000000 0.200000
v 0.117557 0.000000 0.161803
v -0.190212 0.000000 0.061803
v -0.117557 0.000000 0.161803
v -0.117557 0.000000 -0.161803
v -0.190212 0.000000 -0.061803
v 0.117557 0.000000 -0.161803
v -0.000000 0.000000 -0.200000
v 0.137638 0.105147 0.099999
v -0.052574 0.105148 0.161802
v -0.170130 0.105147 -0.000000
v -0.052574 0.105148 -0.161802
v 0.137638 0.105147 -0.099999
v 0.032491 0.170131 0.099999
v 0.105146 0.170130 -0.000000
v -0.085065 0.170131 0.061802
v -0.085065 0.170131 -0.061802
v 0.032491 0.170131 -0.099999
vt 0.818181 0.000000
vt 0.772726 0.078731
vt 0.863635 0.078731
vt 0.727272 0.157461
vt 0.681818 0.078731
vt 0.636363 0.157461
vt 0.090909 0.000000
vt 0.045454 0.078731
vt 0.136363 0.078731
vt 0.272727 0.000000
vt 0.227273 0.078731
vt 0.318182 0.078731
vt 0.454545 0.000000
vt 0.409090 0.078731
vt 0.500000 0.078731
vt 0.681818 0.236191
vt 0.909090 0.157461
vt 0.818181 0.157461
vt 0.863635 0.236191
vt 0.181818 0.157461
vt 0.090909 0.157461
vt 0.136363 0.236191
vt 0.363636 0.157461
vt 0.272727 0.157461
vt 0.318182 0.236191
vt 0.545454 0.157461
vt 0.454545 0.157461
vt 0.500000 0.236191
vt 0.772726 0.236191
vt 0.954545 0.236191
vt 0.227273 0.236191
vt 0.409090 0.236191
vt 0.590909 0.236191
vt 0.818181 0.314921
vt 0.727272 0.314921
vt 0.772726 0.393651
vt 1.000000 0.314921
vt 0.909091 0.314921
vt 0.954545 0.393651
vt 0.272727 0.314921
vt 0.181818 0.314921
vt 0.227273 0.393651
vt 0.454545 0.314921
vt 0.363636 0.314921
vt 0.409090 0.393651
vt 0.636363 0.314921
vt 0.545454 0.314921
vt 0.590909 0.393651
vt 0.500000 0.393651
vt 0.545454 0.472382
vt 0.318182 0.393651
vt 0.363636 0.472382
vt 0.136363 0.393651
vt 0.181818 0.472382
vt 0.090909 0.314921
vt 0.863635 0.393651
vt 0.909090 0.472382
vt 0.681818 0.393651
vt 0.727272 0.472382
vt 0.045454 0.236191
vt 0.000000 0.157461
vt 0.590909 0.078731
vt 0.636363 0.000000
vn 0.1024 -0.9435 0.3151
vn 0.7002 -0.6617 0.2680
vn -0.2680 -0.9435 0.1947
vn -0.2680 -0.9435 -0.1947
vn 0.1024 -0.9435 -0.3151
vn 0.9050 -0.3304 0.2680
vn 0.0247 -0.3304 0.9435
vn -0.8897 -0.3304 0.3151
vn -0.5746 -0.3304 -0.7488
vn 0.5346 -0.3304 -0.7779
vn 0.8026 -0.1256 0.5831
vn -0.3066 -0.1256 0.9435
vn -0.9921 -0.1256 0.0000
vn -0.3066 -0.1256 -0.9435
vn 0.8026 -0.1256 -0.5831
vn 0.4089 0.6617 0.6284
vn -0.4713 0.6617 0.5831
vn -0.7002 0.6617 -0.2680
vn 0.0385 0.6617 -0.7488
vn 0.7240 0.6617 -0.1947
vn 0.2680 0.9435 -0.1947
vn 0.4911 0.7947 -0.3568
vn 0.4089 0.6617 -0.6284
vn -0.1024 0.9435 -0.3151
vn -0.1876 0.7947 -0.5773
vn -0.4713 0.6617 -0.5831
vn -0.3313 0.9435 0.0000
vn -0.6071 0.7947 0.0000
vn -0.7002 0.6617 0.2680
vn -0.1024 0.9435 0.3151
vn -0.1876 0.7947 0.5773
vn 0.0385 0.6617 0.7488
vn 0.2680 0.9435 0.1947
vn 0.4911 0.7947 0.3568
vn 0.7240 0.6617 0.1947
vn 0.8897 0.3304 -0.3151
vn 0.7947 0.1876 -0.5773
vn 0.5746 0.3304 -0.7488
vn -0.0247 0.3304 -0.9435
vn -0.3035 0.1876 -0.9342
vn -0.5346 0.3304 -0.7779
vn -0.9050 0.3304 -0.2680
vn -0.9822 0.1876 0.0000
vn -0.9050 0.3304 0.2680
vn -0.5346 0.3304 0.7779
vn -0.3035 0.1876 0.9342
vn -0.0247 0.3304 0.9435
vn 0.5746 0.3304 0.7488
vn 0.7947 0.1876 0.5773
vn 0.8897 0.3304 0.3151
vn 0.3066 0.1256 -0.9435
vn 0.3035 -0.1876 -0.9342
vn 0.0247 -0.3304 -0.9435
vn -0.8026 0.1256 -0.5831
vn -0.7947 -0.1876 -0.5773
vn -0.8897 -0.3304 -0.3151
vn -0.8026 0.1256 0.5831
vn -0.7947 -0.1876 0.5773
vn -0.5746 -0.3304 0.7488
vn 0.3066 0.1256 0.9435
vn 0.3035 -0.1876 0.9342
vn 0.5346 -0.3304 0.7779
vn 0.9921 0.1256 0.0000
vn 0.9822 -0.1876 0.0000
vn 0.9050 -0.3304 -0.2680
vn 0.4713 -0.6617 -0.5831
vn 0.1876 -0.7947 -0.5773
vn -0.0385 -0.6617 -0.7488
vn -0.4089 -0.6617 -0.6284
vn -0.4911 -0.7947 -0.3568
vn -0.7240 -0.6617 -0.1947
vn -0.7240 -0.6617 0.1947
vn -0.4911 -0.7947 0.3568
vn -0.4089 -0.6617 0.6284
vn 0.7002 -0.6617 -0.2680
vn 0.6071 -0.7947 0.0000
vn 0.3313 -0.9435 0.0000
vn -0.0385 -0.6617 0.7488
vn 0.1876 -0.7947 0.5773
vn 0.4713 -0.6617 0.5831
usemtl None
s off
f 1/1/1 14/2/1 13/3/1
f 2/4/2 14/5/2 16/6/2
f 1/7/3 13/8/3 18/9/3
f 1/10/4 18/11/4 20/12/4
f 1/13/5 20/14/5 17/15/5
f 2/4/6 16/6/6 23/16/6
f 3/17/7 15/18/7 25/19/7
f 4/20/8 19/21/8 27/22/8
f 5/23/9 21/24/9 29/25/9
f 6/26/10 22/27/10 31/28/10
f 2/4/11 23/16/11 26/29/11
f 3/17/12 25/19/12 28/30/12
f 4/20/13 27/22/13 30/31/13
f 5/23/14 29/25/14 32/32/14
f 6/26/15 31/28/15 24/33/15
f 7/34/16 33/35/16 38/36/16
f 8/37/17 34/38/17 40/39/17
f 9/40/18 35/41/18 41/42/18
f 10/43/19 36/44/19 42/45/19
f 11/46/20 37/47/20 39/48/20
f 39/48/21 42/49/21 12/50/21
f 39/48/22 37/47/22 42/49/22
f 37/47/23 10/43/23 42/49/23
f 42/45/24 41/51/24 12/52/24
f 42/45/25 36/44/25 41/51/25
f 36/44/26 9/40/26 41/51/26
f 41/42/27 40/53/27 12/54/27
f 41/42/28 35/41/28 40/53/28
f 35/41/29 8/55/29 40/53/29
f 40/39/30 38/56/30 12/57/30
f 40/39/31 34/38/31 38/56/31
f 34/38/32 7/34/32 38/56/32
f 38/36/33 39/58/33 12/59/33
f 38/36/34 33/35/34 39/58/34
f 33/35/35 11/46/35 39/58/35
f 24/33/36 37/47/36 11/46/36
f 24/33/37 31/28/37 37/47/37
f 31/28/38 10/43/38 37/47/38
f 32/32/39 36/44/39 10/43/39
f 32/32/40 29/25/40 36/44/40
f 29/25/41 9/40/41 36/44/41
f 30/31/42 35/41/42 9/40/42
f 30/31/43 27/22/43 35/41/43
f 27/22/44 8/55/44 35/41/44
f 28/30/45 34/38/45 8/37/45
f 28/30/46 25/19/46 34/38/46
f 25/19/47 7/34/47 34/38/47
f 26/29/48 33/35/48 7/34/48
f 26/29/49 23/16/49 33/35/49
f 23/16/50 11/46/50 33/35/50
f 31/28/51 32/32/51 10/43/51
f 31/28/52 22/27/52 32/32/52
f 22/27/53 5/23/53 32/32/53
f 29/25/54 30/31/54 9/40/54
f 29/25/55 21/24/55 30/31/55
f 21/24/56 4/20/56 30/31/56
f 27/22/57 28/60/57 8/55/57
f 27/22/58 19/21/58 28/60/58
f 19/21/59 3/61/59 28/60/59
f 25/19/60 26/29/60 7/34/60
f 25/19/61 15/18/61 26/29/61
f 15/18/62 2/4/62 26/29/62
f 23/16/63 24/33/63 11/46/63
f 23/16/64 16/6/64 24/33/64
f 16/6/65 6/26/65 24/33/65
f 17/15/66 22/27/66 6/26/66
f 17/15/67 20/14/67 22/27/67
f 20/14/68 5/23/68 22/27/68
f 20/12/69 21/24/69 5/23/69
f 20/12/70 18/11/70 21/24/70
f 18/11/71 4/20/71 21/24/71
f 18/9/72 19/21/72 4/20/72
f 18/9/73 13/8/73 19/21/73
f 13/8/74 3/61/74 19/21/74
f 16/6/75 17/62/75 6/26/75
f 16/6/76 14/5/76 17/62/76
f 14/5/77 1/63/77 17/62/77
f 13/3/78 15/18/78 3/17/78
f 13/3/79 14/2/79 15/18/79
f 14/2/80 2/4/80 15/18/80

View File

@ -1,6 +1,5 @@
#pragma once
#include <list>
#include <vector>
// Forward declarations
@ -22,14 +21,6 @@ struct Vector {
return Vector(c[0] - other.c[0], c[1] - other.c[1], c[2] - other.c[2]);
}
bool operator<(const Vector &other) const {
if ((c[2] < other.c[2])) { return true; }
if ((c[2] == other.c[2]) && (c[1] < other.c[1])) { return true; }
if ((c[2] == other.c[2]) && (c[1] == other.c[1]) && (c[0] < other.c[0])) { return true; }
return false;
}
Vector operator*(float scalar) const {
return Vector(c[0] * scalar, c[1] * scalar, c[2] * scalar);
}
@ -45,22 +36,18 @@ struct Vector {
};
struct Point {
Point(Vector pos) : pos(pos) {}
Point(Vector pos, std::list<Triangle *> triangles) : pos(pos), triangles(triangles) {}
Point(Vector pos, Triangle *triangle) : pos(pos), triangle(triangle) {}
Vector pos;
std::list<Triangle *> triangles;
Triangle *triangle;
};
struct Triangle {
Triangle(Vector p1, Vector p2, Vector p3) : p1(p1), p2(p2), p3(p3) {}
std::vector<Point *> create_point_objects() {
return std::vector<Point *>{new Point(p1, std::list<Triangle *>{this}),
new Point(p2, std::list<Triangle *>{this}),
new Point(p3, std::list<Triangle *>{this})};
return std::vector<Point *>{new Point(p1, this), new Point(p2, this), new Point(p3, this)};
}
Vector p1;
@ -87,7 +74,7 @@ struct Ray {
Vector direction;
bool intersects_triangle(const Triangle *triangle, Vector &result, float &t) {
bool intersects_triangle(Triangle *triangle) {
// Ray-triangle-intersection with the MöllerTrumbore algorithm
// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
const float EPSILON = 0.0000001;
@ -116,9 +103,8 @@ struct Ray {
// At this stage we can compute t to find out where the intersection point is on the
// line.
t = f * edge2.dot(q);
float t = f * edge2.dot(q);
if (t > EPSILON) {
result = origin + direction * t;
return true;
} else {
// This means that there is a line intersection but not a ray intersection.

View File

@ -1,6 +1,5 @@
#include "geometry.h"
#include <algorithm>
#include <chrono>
#include <glm/glm.hpp>
#include <iostream>
#include <string>
@ -8,32 +7,11 @@
class KDTree {
public:
KDTree(std::vector<Point *> points) {
std::cout << "Starting to build tree with " << points.size() << " points took ";
auto start = std::chrono::high_resolution_clock::now();
root = build(points, 0);
auto end = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
<< " microseconds" << std::endl;
}
KDTree(std::vector<Point *> points) { root = build(points, 0); }
~KDTree() = default; // TODO: Delete all allocated Nodes
const Triangle *intersect_ray(const Ray ray, Vector &result) {
auto start = std::chrono::high_resolution_clock::now();
float nearest = 1000.0;
const Triangle *nearest_triangle = nullptr;
intersect_ray_recurse(nearest_triangle, result, ray, root, 1000.0, 0, nearest);
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Intersection took "
<< std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
<< " microseconds" << std::endl;
return nearest_triangle;
}
Triangle *intersect_ray(Ray ray) { return intersect_ray_recurse(ray, root, 1000.0, 0); }
std::string to_string() {
std::string str = "";
@ -107,49 +85,50 @@ class KDTree {
build(right_of_median, depth + 1));
}
void intersect_ray_recurse(const Triangle *&nearest_triangle, Vector &result, Ray ray,
Node *node, float max_distance, int depth, float &nearest) {
Triangle *intersect_ray_recurse(Ray ray, Node *node, float max_distance, int depth) {
// Exit condition: There was no collision
if (node == nullptr) { return; }
// Check for a collision here
for (const Triangle *triangle : node->point->triangles) {
Vector current_result(0, 0, 0);
float current_distance;
if (ray.intersects_triangle(triangle, current_result, current_distance)) {
if (current_distance < nearest) {
nearest = current_distance;
nearest_triangle = triangle;
result = current_result;
}
}
}
if (node == nullptr) { return nullptr; }
// Is the left or right child node closer to this point?
Node *near =
ray.origin[node->axis] > node->point->pos[node->axis] ? node->right : node->left;
Node *far = near == node->right ? node->left : node->right;
if (ray.direction[node->axis] == 0.0) {
intersect_ray_recurse(nearest_triangle, result, ray, near, max_distance, depth + 1,
nearest);
} else {
/* float t =
(node->point->pos[node->axis] - ray.origin[node->axis]) /
ray.direction[node->axis];
// Check for collisions in this order (stopping if an intersection is found):
// 1. In the nearer section
// 2. With the point in this current node
// 3. In the further section
if (t >= 0.0 && t < max_distance) {
intersect_ray_recurse(nearest_triangle, result, ray, near, t, depth + 1,
nearest); intersect_ray_recurse(nearest_triangle, result, Ray(ray.origin +
ray.direction * t, ray.direction), far, max_distance - t, depth + 1, nearest); } else
{ intersect_ray_recurse(nearest_triangle, result, ray, near, max_distance, depth + 1,
nearest);
} */
intersect_ray_recurse(nearest_triangle, result, ray, near, max_distance, depth + 1,
nearest);
intersect_ray_recurse(nearest_triangle, result, ray, far, max_distance, depth + 1,
nearest);
// If the axes are not parallel, our max_distance decreases, since we've already covered
// some area. `t` represents the distance from this node to the splitting plane.
float t = ray.direction[node->axis] != 0.0
? (node->point->pos[node->axis] - ray.origin[node->axis]) /
ray.direction[node->axis]
: max_distance;
Triangle *near_result = intersect_ray_recurse(ray, near, t, depth + 1);
// If the nearer segment had a collision, we're done! We're only interested in the closest
// collision.
if (near_result != nullptr) { return near_result; }
// No collision in the nearer side, so check for a collision directly here
if (ray.intersects_triangle(node->point->triangle)) {
// We do have a collision here, so we're done and can return this point!
return node->point->triangle;
}
// No collision here either. Does it make sense to also check the far node?
// Only if the axes are not parallel and if that area is not behind us
if (ray.direction[node->axis] != 0.0 && t >= 0.0) {
// It does make sense to check the far node.
// For this, calculate a new ray origin and continue towards that direction, but with
// the new origin (we can leave behind what we already checked)
return intersect_ray_recurse(Ray(ray.origin + ray.direction * t, ray.direction), far,
max_distance - t, depth + 1);
}
// If nothing worked, return a nullptr
return nullptr;
}
void to_string_recurse(std::string &str, Node *node, int depth) {

View File

@ -91,14 +91,7 @@ int main(int argc, char **argv) {
world->registerSystem(new SineAnimationSystem());
world->registerSystem(new InteractivePathSystem());
// Create collision indicator
Entity *collision_point = world->create();
collision_point->assign<Transform>();
collision_point->assign<ObjMesh>(ObjMesh("Resources/sphere.obj", ObjMesh::Settings()));
collision_point->assign<Texture>("Resources/red.png", Texture::Settings(true), false);
collision_point->assign<Material>(0.1, 0.9);
CollisionSystem *collision_system = new CollisionSystem(collision_point);
CollisionSystem *collision_system = new CollisionSystem();
world->registerSystem(collision_system);
RenderSystem *renderSystem = new RenderSystem();
@ -229,10 +222,10 @@ int main(int argc, char **argv) {
world->tick(delta);
renderSystem->render(world, defaultShader, shadowShader, debugShader, lineShader);
/* ring->get<Transform>()->rotate(delta * 100.0, glm::vec3(0.0, 1.0, 0.0));
sun->get<DirectionalLight>()->direction = glm::normalize(glm::vec3(
glm::rotate(glm::mat4(1), (float)elapsed_time * 0.5f, glm::vec3(0.0, 1.0, 0.0))
* glm::vec4(1.0, 1.0, 1.0, 0.0))); */
ring->get<Transform>()->rotate(delta * 100.0, glm::vec3(0.0, 1.0, 0.0));
sun->get<DirectionalLight>()->direction = glm::normalize(glm::vec3(
glm::rotate(glm::mat4(1), (float)elapsed_time * 0.5f, glm::vec3(0.0, 1.0, 0.0)) *
glm::vec4(1.0, 1.0, 1.0, 0.0)));
/* Swap front and back buffers */
glfwSwapBuffers(window);