COSC-3P93-Project/Step 3/include/engine/world.h

182 lines
6.5 KiB
C
Raw Normal View History

2022-10-20 11:30:15 -04:00
/*
* Created by Brett Terpstra 6920201 on 16/10/22.
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*/
#ifndef STEP_2_WORLD_H
#define STEP_2_WORLD_H
#include "engine/util/std.h"
#include "engine/math/vectors.h"
#include "engine/util/models.h"
#include "engine/math/bvh.h"
#include "types.h"
#include <config.h>
2022-12-03 11:54:34 -05:00
#ifdef COMPILE_GUI
2022-12-03 11:54:34 -05:00
#include "graphics/gl/shader.h"
#include "graphics/debug_gui.h"
2022-12-03 11:54:34 -05:00
#endif
2022-10-20 11:30:15 -04:00
#include <utility>
2022-10-20 11:30:15 -04:00
namespace Raytracing {
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
class SphereObject : public Object {
private:
PRECISION_TYPE radius;
public:
SphereObject(const Vec4& position, PRECISION_TYPE radius, Material* material): radius(radius), Object(material, position) {}
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const;
};
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
class ModelObject : public Object {
private:
std::vector<std::shared_ptr<Triangle>> triangles;
std::unique_ptr<TriangleBVHTree> triangleBVH;
2022-10-20 11:30:15 -04:00
public:
ModelObject(const Vec4& position, ModelData& data, Material* material): Object(material, position) {
2022-10-20 11:30:15 -04:00
// since all of this occurs before the main ray tracing algorithm it's fine to do sequentially
2022-12-03 11:54:34 -05:00
TriangulatedModel model{data};
this->triangles = model.triangles;
this->aabb = std::move(model.aabb);
std::vector<TriangleBVHObject> triangulatedObjects;
2022-12-03 11:54:34 -05:00
for (const auto& tri: triangles) {
TriangleBVHObject triangleObject;
triangleObject.tri = tri;
triangleObject.aabb = tri->aabb;
triangleObject.position = position;
triangulatedObjects.push_back(triangleObject);
}
triangleBVH = std::make_unique<TriangleBVHTree>(triangulatedObjects);
2022-12-03 11:54:34 -05:00
#ifdef COMPILE_GUI
vao = new VAO(triangles);
#endif
2022-10-20 11:30:15 -04:00
}
2022-12-03 11:54:34 -05:00
[[nodiscard]] virtual DebugBVHData getBVHTree() { return {triangleBVH.get(), false}; }
[[nodiscard]] virtual std::vector<std::shared_ptr<Triangle>> getTriangles() { return triangles; }
2022-10-20 11:30:15 -04:00
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const;
};
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
class DiffuseMaterial : public Material {
private:
public:
explicit DiffuseMaterial(const Vec4& scatterColor): Material(scatterColor) {}
2022-12-03 11:54:34 -05:00
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
2022-10-20 11:30:15 -04:00
};
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
class MetalMaterial : public Material {
protected:
static inline Vec4 reflect(const Vec4& incomingVector, const Vec4& normal) {
return incomingVector - 2 * Vec4::dot(incomingVector, normal) * normal;
}
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
public:
explicit MetalMaterial(const Vec4& metalColor): Material(metalColor) {}
2022-12-03 11:54:34 -05:00
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
2022-10-20 11:30:15 -04:00
};
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
class BrushedMetalMaterial : public MetalMaterial {
private:
PRECISION_TYPE fuzzyness;
public:
explicit BrushedMetalMaterial(const Vec4& metalColor, PRECISION_TYPE fuzzyness): MetalMaterial(metalColor), fuzzyness(fuzzyness) {}
2022-12-03 11:54:34 -05:00
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
};
2022-11-22 00:26:23 -05:00
class LightMaterial : public Material {
public:
explicit LightMaterial(const Vec4& lightColor): Material(lightColor) {}
2022-12-03 11:54:34 -05:00
2022-11-22 00:26:23 -05:00
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
2022-12-03 11:54:34 -05:00
2022-11-22 00:26:23 -05:00
[[nodiscard]] virtual Vec4 emission(PRECISION_TYPE u, PRECISION_TYPE v, const Vec4& hitPoint) const override;
};
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
class TexturedMaterial : public Material {
protected:
int width{}, height{}, channels{};
unsigned char* data;
2022-10-20 11:30:15 -04:00
public:
explicit TexturedMaterial(const std::string& file);
2022-12-03 11:54:34 -05:00
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
2022-12-03 11:54:34 -05:00
2022-11-22 00:26:23 -05:00
[[nodiscard]] Vec4 getColor(PRECISION_TYPE u, PRECISION_TYPE v) const;
~TexturedMaterial();
2022-10-20 11:30:15 -04:00
};
2022-11-16 17:34:17 -05:00
struct WorldConfig {
bool useBVH = true;
bool padding[7]{};
2022-11-23 11:55:40 -05:00
#ifdef COMPILE_GUI
Shader& worldShader;
explicit WorldConfig(Shader& shader): worldShader(shader) {}
2022-12-03 11:54:34 -05:00
2022-11-23 11:55:40 -05:00
#endif
2022-11-16 17:34:17 -05:00
};
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
class World {
private:
// store all the objects in the world,
std::vector<Object*> objects;
std::unique_ptr<BVHTree> bvhObjects;
2022-10-20 11:30:15 -04:00
std::unordered_map<std::string, Material*> materials;
2022-11-16 17:34:17 -05:00
WorldConfig m_config;
2022-10-20 11:30:15 -04:00
public:
2022-11-16 17:34:17 -05:00
explicit World(WorldConfig config): m_config(config) {};
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
World(const World& world) = delete;
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
World(const World&& world) = delete;
2022-12-03 11:54:34 -05:00
// Called by the raytracer class after all objects have been added to the world
// this allows us to generate a statically unchanging BVH for easy rendering
2022-10-20 11:30:15 -04:00
void generateBVH();
2022-12-03 11:54:34 -05:00
#ifdef COMPILE_GUI
// currently disabled. TODO: BVH renderer class
void drawBVH(Shader& worldShader) {}
#endif
inline void add(Object* object) {
2022-12-03 11:54:34 -05:00
objects.push_back(object);
2022-11-23 11:55:40 -05:00
#ifdef COMPILE_GUI
2022-12-03 11:54:34 -05:00
if (object->getBVHTree().bvhTree != nullptr && !object->getBVHTree().isRegular)
new DebugBVH{(TriangleBVHTree*) object->getBVHTree().bvhTree, m_config.worldShader};
2022-11-23 11:55:40 -05:00
#endif
2022-12-03 11:54:34 -05:00
}
inline void add(const std::string& materialName, Material* mat) { materials.insert({materialName, mat}); }
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
inline Material* getMaterial(const std::string& materialName) { return materials.at(materialName); }
2022-12-03 11:54:34 -05:00
2022-11-15 16:23:37 -05:00
[[nodiscard]] inline BVHTree* getBVH() { return bvhObjects.get(); }
2022-12-03 11:54:34 -05:00
[[nodiscard]] inline std::vector<Object*> getObjectsInWorld() { return objects; }
2022-10-20 11:30:15 -04:00
[[nodiscard]] virtual std::pair<HitData, Object*> checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const;
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
~World();
2022-12-03 11:54:34 -05:00
2022-10-20 11:30:15 -04:00
};
}
#endif //STEP_2_WORLD_H