Compare commits
No commits in common. "1649af99434d0088ce71e39259cb4afd987ca4b1" and "27dcc00e680a0019931a5e113714d43752dbb462" have entirely different histories.
1649af9943
...
27dcc00e68
@ -13,26 +13,22 @@ struct ObjMesh : public Mesh {
|
|||||||
Settings() = default;
|
Settings() = default;
|
||||||
|
|
||||||
Settings(float minDistanceForRender, float maxDistanceForRender, float diffuse,
|
Settings(float minDistanceForRender, float maxDistanceForRender, float diffuse,
|
||||||
float specular, bool colliding)
|
float specular)
|
||||||
: minDistanceForRender(minDistanceForRender),
|
: minDistanceForRender(minDistanceForRender),
|
||||||
maxDistanceForRender(maxDistanceForRender), colliding(colliding) {}
|
maxDistanceForRender(maxDistanceForRender) {}
|
||||||
|
|
||||||
float minDistanceForRender = 0.0;
|
float minDistanceForRender = 0.0;
|
||||||
float maxDistanceForRender = 1000.0;
|
float maxDistanceForRender = 1000.0;
|
||||||
bool colliding = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit ObjMesh(const std::string &path, const Settings &settings)
|
explicit ObjMesh(const std::string &path, const Settings &settings)
|
||||||
: Mesh(getVerticesFromFile(path), getIndicesFromFile(path)),
|
: Mesh(getVerticesFromFile(path), getIndicesFromFile(path)),
|
||||||
minDistance(settings.minDistanceForRender), maxDistance(settings.maxDistanceForRender),
|
minDistance(settings.minDistanceForRender), maxDistance(settings.maxDistanceForRender) {}
|
||||||
colliding(settings.colliding) {}
|
|
||||||
|
|
||||||
float minDistance;
|
float minDistance;
|
||||||
|
|
||||||
float maxDistance;
|
float maxDistance;
|
||||||
|
|
||||||
bool colliding;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::vector<float> getVerticesFromFile(const std::string &path) {
|
static std::vector<float> getVerticesFromFile(const std::string &path) {
|
||||||
objl::Loader loader;
|
objl::Loader loader;
|
||||||
|
@ -23,16 +23,12 @@ class CollisionSystem : public EntitySystem {
|
|||||||
// ObjMesh
|
// ObjMesh
|
||||||
myWorld->each<ObjMesh, Transform>(
|
myWorld->each<ObjMesh, Transform>(
|
||||||
[&](Entity *ent, ComponentHandle<ObjMesh> mesh, ComponentHandle<Transform> transform) {
|
[&](Entity *ent, ComponentHandle<ObjMesh> mesh, ComponentHandle<Transform> transform) {
|
||||||
// If this mesh shouldn't collide, skip it
|
|
||||||
if (!mesh->colliding) { return; }
|
|
||||||
|
|
||||||
std::vector<unsigned int> indices = mesh->indices;
|
std::vector<unsigned int> indices = mesh->indices;
|
||||||
std::vector<float> vertices = mesh->vertices;
|
std::vector<float> vertices = mesh->vertices;
|
||||||
|
|
||||||
std::map<Vector, Point *> triangle_map;
|
std::map<Vector, Point *> triangle_map;
|
||||||
|
|
||||||
// We iterate over the index array and add the resulting triangles to a hash map of
|
// TODO: Iterate over vertices, add triangles by also iterating over indices
|
||||||
// vertices. That way, each vertex holds a list of all triangles it is involved in.
|
|
||||||
for (int i = 0; i < mesh->vertex_count; i += 3) {
|
for (int i = 0; i < mesh->vertex_count; i += 3) {
|
||||||
// Build vertices from this triangle
|
// Build vertices from this triangle
|
||||||
float v0p0 = vertices[indices[i + 0] * 14 + 0];
|
float v0p0 = vertices[indices[i + 0] * 14 + 0];
|
||||||
@ -94,7 +90,9 @@ class CollisionSystem : public EntitySystem {
|
|||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
|
std::cout << "Start building kdtree with " << points.size() << " points" << std::endl;
|
||||||
kdtree = new KDTree(points);
|
kdtree = new KDTree(points);
|
||||||
|
std::cout << "Done" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tick(World *pWorld, float deltaTime) override {
|
void tick(World *pWorld, float deltaTime) override {
|
||||||
|
@ -22,7 +22,6 @@ struct Vector {
|
|||||||
return Vector(c[0] - other.c[0], c[1] - other.c[1], c[2] - other.c[2]);
|
return Vector(c[0] - other.c[0], c[1] - other.c[1], c[2] - other.c[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arbitrary but functional definition of '<', primarily for use in an std::map.
|
|
||||||
bool operator<(const Vector &other) const {
|
bool operator<(const Vector &other) const {
|
||||||
if ((c[2] < other.c[2])) { return true; }
|
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])) { return true; }
|
||||||
@ -31,7 +30,6 @@ struct Vector {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Component-wise multiplication with a scalar
|
|
||||||
Vector operator*(float scalar) const {
|
Vector operator*(float scalar) const {
|
||||||
return Vector(c[0] * scalar, c[1] * scalar, c[2] * scalar);
|
return Vector(c[0] * scalar, c[1] * scalar, c[2] * scalar);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "geometry.h"
|
#include "geometry.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@ -11,7 +9,7 @@
|
|||||||
class KDTree {
|
class KDTree {
|
||||||
public:
|
public:
|
||||||
KDTree(std::vector<Point *> points) {
|
KDTree(std::vector<Point *> points) {
|
||||||
std::cout << "Building tree with " << points.size() << " points took ";
|
std::cout << "Starting to build tree with " << points.size() << " points took ";
|
||||||
auto start = std::chrono::high_resolution_clock::now();
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
root = build(points, 0);
|
root = build(points, 0);
|
||||||
auto end = std::chrono::high_resolution_clock::now();
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
@ -111,17 +109,13 @@ class KDTree {
|
|||||||
|
|
||||||
void intersect_ray_recurse(const Triangle *&nearest_triangle, Vector &result, Ray ray,
|
void intersect_ray_recurse(const Triangle *&nearest_triangle, Vector &result, Ray ray,
|
||||||
Node *node, int depth, float &nearest) {
|
Node *node, int depth, float &nearest) {
|
||||||
// Exit condition: This node was iterated towards, but does not exist
|
// Exit condition: There was no collision
|
||||||
if (node == nullptr) { return; }
|
if (node == nullptr) { return; }
|
||||||
|
|
||||||
// Check for a collision here
|
// Check for a collision here
|
||||||
// Iterate over all Triangles which this Point is involved in
|
|
||||||
for (const Triangle *triangle : node->point->triangles) {
|
for (const Triangle *triangle : node->point->triangles) {
|
||||||
Vector current_result(0, 0, 0);
|
Vector current_result(0, 0, 0);
|
||||||
float current_distance;
|
float current_distance;
|
||||||
|
|
||||||
// If we have a collision, and it is closer to the ray origin than the closest previous
|
|
||||||
// collision, remember it
|
|
||||||
if (ray.intersects_triangle(triangle, current_result, current_distance)) {
|
if (ray.intersects_triangle(triangle, current_result, current_distance)) {
|
||||||
if (current_distance < nearest) {
|
if (current_distance < nearest) {
|
||||||
nearest = current_distance;
|
nearest = current_distance;
|
||||||
@ -131,16 +125,14 @@ class KDTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is the ray origin within the left or right child node bounding box?
|
// Is the left or right child node closer to this point?
|
||||||
Node *near =
|
Node *near =
|
||||||
ray.origin[node->axis] > node->point->pos[node->axis] ? node->right : node->left;
|
ray.origin[node->axis] > node->point->pos[node->axis] ? node->right : node->left;
|
||||||
Node *far = near == node->right ? node->left : node->right;
|
Node *far = near == node->right ? node->left : node->right;
|
||||||
|
|
||||||
if (ray.direction[node->axis] == 0.0) {
|
if (ray.direction[node->axis] == 0.0) {
|
||||||
// The ray is parallel to the splitting axis, so we only need to check within this box.
|
|
||||||
intersect_ray_recurse(nearest_triangle, result, ray, near, depth + 1, nearest);
|
intersect_ray_recurse(nearest_triangle, result, ray, near, depth + 1, nearest);
|
||||||
} else {
|
} else {
|
||||||
// Calculate the distance from the ray origin to the splitting axis
|
|
||||||
float t =
|
float t =
|
||||||
(node->point->pos[node->axis] - ray.origin[node->axis]) / ray.direction[node->axis];
|
(node->point->pos[node->axis] - ray.origin[node->axis]) / ray.direction[node->axis];
|
||||||
|
|
||||||
|
19
main.cpp
19
main.cpp
@ -94,11 +94,7 @@ int main(int argc, char **argv) {
|
|||||||
// Create collision indicator
|
// Create collision indicator
|
||||||
Entity *collision_point = world->create();
|
Entity *collision_point = world->create();
|
||||||
collision_point->assign<Transform>();
|
collision_point->assign<Transform>();
|
||||||
|
collision_point->assign<ObjMesh>(ObjMesh("Resources/sphere.obj", ObjMesh::Settings()));
|
||||||
ObjMesh::Settings cp_obj_settings = ObjMesh::Settings();
|
|
||||||
cp_obj_settings.colliding = false;
|
|
||||||
collision_point->assign<ObjMesh>(ObjMesh("Resources/sphere.obj", cp_obj_settings));
|
|
||||||
|
|
||||||
collision_point->assign<Texture>("Resources/red.png", Texture::Settings(true), false);
|
collision_point->assign<Texture>("Resources/red.png", Texture::Settings(true), false);
|
||||||
collision_point->assign<Material>(0.1, 0.9);
|
collision_point->assign<Material>(0.1, 0.9);
|
||||||
|
|
||||||
@ -132,8 +128,8 @@ int main(int argc, char **argv) {
|
|||||||
Entity *monkey = world->create();
|
Entity *monkey = world->create();
|
||||||
monkey->assign<Transform>();
|
monkey->assign<Transform>();
|
||||||
monkey->assign<LODObjMesh>(std::vector<ObjMesh>{
|
monkey->assign<LODObjMesh>(std::vector<ObjMesh>{
|
||||||
ObjMesh("Resources/Monkey.obj", ObjMesh::Settings(0.0, 8.0, 0.4, 0.6, false)),
|
ObjMesh("Resources/Monkey.obj", ObjMesh::Settings(0.0, 8.0, 0.4, 0.6)),
|
||||||
ObjMesh("Resources/MonkeySimple.obj", ObjMesh::Settings(8.0, 100.0, 0.4, 0.6, false))});
|
ObjMesh("Resources/MonkeySimple.obj", ObjMesh::Settings(8.0, 100.0, 0.4, 0.6))});
|
||||||
monkey->assign<Texture>("Resources/Marble010_2K_Color.jpg", Texture::Settings(true), false);
|
monkey->assign<Texture>("Resources/Marble010_2K_Color.jpg", Texture::Settings(true), false);
|
||||||
monkey->get<Texture>()->addNormalmap("Resources/Marble010_2K_Normal.jpg",
|
monkey->get<Texture>()->addNormalmap("Resources/Marble010_2K_Normal.jpg",
|
||||||
Texture::Settings(true));
|
Texture::Settings(true));
|
||||||
@ -208,11 +204,11 @@ int main(int argc, char **argv) {
|
|||||||
Entity *sun = world->create();
|
Entity *sun = world->create();
|
||||||
sun->assign<DirectionalLight>(glm::normalize(glm::vec3(1.0, 1.0, 1.0)));
|
sun->assign<DirectionalLight>(glm::normalize(glm::vec3(1.0, 1.0, 1.0)));
|
||||||
|
|
||||||
|
Entity *kdtree_vis = world->create();
|
||||||
|
|
||||||
// We're done loading geometry -> build the collision structure
|
// We're done loading geometry -> build the collision structure
|
||||||
collision_system->build();
|
collision_system->build();
|
||||||
|
|
||||||
// Save the visualized kdtree as another entity
|
|
||||||
Entity *kdtree_vis = world->create();
|
|
||||||
kdtree_vis->assign<Lines>(collision_system->kdtree->get_lines());
|
kdtree_vis->assign<Lines>(collision_system->kdtree->get_lines());
|
||||||
|
|
||||||
Shader defaultShader("Shaders/default-vertex.vs", "Shaders/default-fragment.fs");
|
Shader defaultShader("Shaders/default-vertex.vs", "Shaders/default-fragment.fs");
|
||||||
@ -233,16 +229,15 @@ int main(int argc, char **argv) {
|
|||||||
world->tick(delta);
|
world->tick(delta);
|
||||||
renderSystem->render(world, defaultShader, shadowShader, debugShader, lineShader);
|
renderSystem->render(world, defaultShader, shadowShader, debugShader, lineShader);
|
||||||
|
|
||||||
// Animations
|
|
||||||
/* ring->get<Transform>()->rotate(delta * 100.0, glm::vec3(0.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(
|
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::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))); */
|
* glm::vec4(1.0, 1.0, 1.0, 0.0))); */
|
||||||
|
|
||||||
// Swap front and back buffers
|
/* Swap front and back buffers */
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
|
|
||||||
// Poll for and process events
|
/* Poll for and process events */
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user