/* * Created by Brett Terpstra 6920201 on 17/10/22. * Copyright (c) 2022 Brett Terpstra. All Rights Reserved. */ #ifndef STEP_2_BVH_H #define STEP_2_BVH_H #include "engine/util/std.h" #include "engine/types.h" #include "engine/util/models.h" #include #ifdef COMPILE_GUI #include #include #endif #include namespace Raytracing { #ifdef COMPILE_GUI extern std::shared_ptr aabbVAO; extern int count; extern int selected; #endif struct BVHObject { Object* ptr = nullptr; AABB aabb; }; struct BVHPartitionedSpace { std::vector left; std::vector right; }; inline bool operator==(const BVHPartitionedSpace& left, const BVHPartitionedSpace& right) { if (left.left.size() != right.left.size() || left.right.size() != right.right.size()) return false; for (int i = 0; i < left.left.size(); i++) { if (left.left[i].aabb != right.left[i].aabb) return false; } for (int i = 0; i < left.right.size(); i++) { if (left.right[i].aabb != right.right[i].aabb) return false; } return true; } struct BVHNode { public: struct BVHHitData { BVHNode* ptr{}; AABBHitData data{}; bool hit = false; }; std::vector objs; AABB aabb; BVHNode* left; BVHNode* right; BVHNode(std::vector objs, AABB aabb, BVHNode* left, BVHNode* right): objs(std::move(objs)), aabb(std::move(aabb)), left(left), right(right) {} BVHHitData firstHitRayIntersectTraversal(const Ray& r, PRECISION_TYPE min, PRECISION_TYPE max); ~BVHNode() { delete (left); delete (right); } }; class BVHTree { private: BVHNode* root = nullptr; static BVHPartitionedSpace partition(const std::pair& aabbs, const std::vector& objs); BVHNode* addObjectsRecursively(const std::vector& objects, const BVHPartitionedSpace& prevSpace); public: std::vector noAABBObjects; explicit BVHTree(const std::vector& objectsInWorld) { addObjects(objectsInWorld); #ifdef COMPILE_GUI auto aabbVertexData = Shapes::cubeVertexBuilder{}; if (aabbVAO == nullptr) aabbVAO = std::make_shared(aabbVertexData.cubeVerticesRaw, aabbVertexData.cubeUVs); #endif } void addObjects(const std::vector& objects); std::vector rayFirstHitIntersect(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max); std::vector rayAnyHitIntersect(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max); ~BVHTree() { delete (root); } }; struct TriangleBVHObject { Triangle* ptr = nullptr; AABB aabb; }; struct TriangleBVHPartitionedSpace { std::vector left; std::vector right; }; struct TriangleBVHNode { struct BVHHitData { TriangleBVHNode* ptr{}; AABBHitData data{}; bool hit = false; }; std::vector objs; AABB aabb; TriangleBVHNode* left; TriangleBVHNode* right; TriangleBVHNode(std::vector objs, AABB aabb, TriangleBVHNode* left, TriangleBVHNode* right) : objs(std::move(objs)), aabb(std::move(aabb)), left(left), right(right) {} ~TriangleBVHNode() { delete (left); delete (right); } }; } #endif //STEP_2_BVH_H