/* * 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 #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; }; struct BVHNode { public: struct BVHHitData { BVHNode* ptr{}; AABBHitData data{}; bool hit = false; }; std::vector objs; AABB aabb; BVHNode* left; BVHNode* right; int index; int hit = 0; BVHNode(std::vector objs, AABB aabb, BVHNode* left, BVHNode* right): objs(std::move(objs)), aabb(std::move(aabb)), left(left), right(right) { index = count++; } BVHHitData firstHitRayIntersectTraversal(const Ray& r, PRECISION_TYPE min, PRECISION_TYPE max); ~BVHNode() { delete (left); delete (right); } }; class BVHTree { private: BVHNode* root = nullptr; // splits the objs in the vector based on the provided AABBs static BVHPartitionedSpace partition(const std::pair& aabbs, const std::vector& objs); static bool vectorEquals(const BVHPartitionedSpace& oldSpace, const BVHPartitionedSpace& newSpace); BVHNode* addObjectsRecur(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); } }; } #endif //STEP_2_BVH_H