diff --git a/src/accelerators/bbox.c b/src/accelerators/bbox.c deleted file mode 100644 index eac1200a..00000000 --- a/src/accelerators/bbox.c +++ /dev/null @@ -1,99 +0,0 @@ -// -// bbox.c -// C-ray -// -// Created by Valtteri Koskivuori on 28/04/2017. -// Copyright © 2015-2020 Valtteri Koskivuori. All rights reserved. -// - -#include "../includes.h" -#include "bbox.h" - -#include "../datatypes/vertexbuffer.h" -#include "../datatypes/poly.h" -#include "../utils/assert.h" - -/** - Get the longest axis of an axis-aligned bounding box - - @param bbox Bounding box to compute longest axis for - @return Longest axis as an enum - */ -enum bboxAxis getLongestAxis(const struct boundingBox *bbox) { - float x = fabsf(bbox->start.x - bbox->end.x); - float y = fabsf(bbox->start.y - bbox->end.y); - float z = fabsf(bbox->start.z - bbox->end.z); - - return x > y && x > z ? X : y > z ? Y : Z; -} - -/// Compute the surface area of a given bounding box -/// @param box Bounding box to compute surface area for -float findSurfaceArea(const struct boundingBox *box) { - float width = box->end.x - box->start.x; - float height = box->end.y - box->start.y; - float length = box->end.z - box->start.z; - return 2 * (length * width) + 2 * (length * height) + 2 * (width * height); -} - -/** - Compute the bounding box for a given array of polygons - - @param polys Indices to polygons to compute bounding box for - @param count Amount of polygons indices given - @return Axis-aligned bounding box - */ -struct boundingBox *computeBoundingBox(const int *polys, const int count) { - ASSERT(polys); - ASSERT(count > 0); - struct boundingBox *bbox = calloc(1, sizeof(*bbox)); - struct vector minPoint = vecWithPos(FLT_MAX, FLT_MAX, FLT_MAX); - struct vector maxPoint = vecWithPos(-FLT_MAX, -FLT_MAX, -FLT_MAX); - - for (int i = 0; i < count; ++i) { - for (int j = 0; j < 3; ++j) { - minPoint = vecMin(minPoint, vertexArray[polygonArray[polys[i]].vertexIndex[j]]); - maxPoint = vecMax(maxPoint, vertexArray[polygonArray[polys[i]].vertexIndex[j]]); - } - } - struct vector center = vecWithPos(0.5f * (minPoint.x + maxPoint.x), 0.5f * (minPoint.y + maxPoint.y), 0.5f * (minPoint.z + maxPoint.z)); - float maxDistance = 0.0f; - for (int i = 0; i < count; ++i) { - for (int j = 0; j < 3; ++j) { - struct vector fromCenter = vecSub(vertexArray[polygonArray[polys[i]].vertexIndex[j]], center); - maxDistance = max(maxDistance, pow(vecLength(fromCenter), 2)); - } - } - bbox->start = minPoint; - bbox->end = maxPoint; - bbox->midPoint = center; - bbox->surfaceArea = findSurfaceArea(bbox); - return bbox; -} - -bool rayIntersectsWithAABB(const struct boundingBox *box, const struct lightRay *ray) { - //If a mesh has no polygons, it won't have a root bbox either. - if (!box) return false; - - struct vector dirfrac = vecWithPos(1.0f / ray->direction.x, 1.0f / ray->direction.y, 1.0f / ray->direction.z); - - float t1 = (box->start.x - ray->start.x)*dirfrac.x; - float t2 = (box-> end.x - ray->start.x)*dirfrac.x; - float t3 = (box->start.y - ray->start.y)*dirfrac.y; - float t4 = (box-> end.y - ray->start.y)*dirfrac.y; - float t5 = (box->start.z - ray->start.z)*dirfrac.z; - float t6 = (box-> end.z - ray->start.z)*dirfrac.z; - - float tmin = max(max(min(t1, t2), min(t3, t4)), min(t5, t6)); - float tmax = min(min(max(t1, t2), max(t3, t4)), max(t5, t6)); - - // if tmax < 0, ray is intersecting AABB, but the whole AABB is behind us - if (tmax < 0) { - return false; - } - // if tmin > tmax, ray doesn't intersect AABB - if (tmin > tmax) { - return false; - } - return true; -} diff --git a/src/accelerators/bbox.h b/src/accelerators/bbox.h deleted file mode 100644 index 3f638bf8..00000000 --- a/src/accelerators/bbox.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// bbox.h -// C-ray -// -// Created by Valtteri Koskivuori on 28/04/2017. -// Copyright © 2015-2020 Valtteri Koskivuori. All rights reserved. -// - -#pragma once - -#include "../datatypes/vector.h" -#include "../datatypes/lightRay.h" - -/// Current bbox split axis -enum bboxAxis { - X, - Y, - Z -}; - -/// Bounding box for a given set of primitives -struct boundingBox { - struct vector start, end, midPoint; - float surfaceArea; -}; - -/// Computes a bounding box for a given array of polygons -/// @param polys Array of polygons to process -/// @param count Amount of polygons given -struct boundingBox *computeBoundingBox(const int *polys, const int count); - -/// Compute the longest axis of a given bounding box -/// @param bbox Bounding box to process -enum bboxAxis getLongestAxis(const struct boundingBox *bbox); - -/// Checks for an intersection between a given ray and bounding box -/// @param box Bounding box to check intersection against -/// @param ray Ray to intersect -bool rayIntersectsWithAABB(const struct boundingBox *box, const struct lightRay *ray); diff --git a/src/accelerators/bvh.c b/src/accelerators/bvh.c index 52f8bd2d..1c361def 100644 --- a/src/accelerators/bvh.c +++ b/src/accelerators/bvh.c @@ -14,6 +14,7 @@ #include "../datatypes/vertexbuffer.h" #include "../datatypes/poly.h" #include "../datatypes/vector.h" +#include "../datatypes/bbox.h" #include "../datatypes/lightRay.h" #include "../datatypes/mesh.h" @@ -31,20 +32,14 @@ #define TRAVERSAL_COST 1.5f // Ratio (cost of traversing a node / cost of intersecting a primitive) #define BIN_COUNT 32 // Number of bins to use to approximate the SAH -// TODO: Move this to its own file if need be -// NOTE: The existing `boundingBox` type is too big -typedef struct bBox { - vector min, max; -} bBox; - // Bin used to approximate the SAH. typedef struct Bin { - bBox bbox; + struct boundingBox bbox; unsigned count; float cost; } Bin; -static inline void storeBBoxInNode(struct bvhNode *node, const bBox *bbox) { +static inline void storeBBoxInNode(struct bvhNode *node, const struct boundingBox *bbox) { node->bounds[0] = bbox->min.x; node->bounds[1] = bbox->max.x; node->bounds[2] = bbox->min.y; @@ -53,7 +48,7 @@ static inline void storeBBoxInNode(struct bvhNode *node, const bBox *bbox) { node->bounds[5] = bbox->max.z; } -static inline void loadBBoxFromNode(bBox *bbox, const struct bvhNode *node) { +static inline void loadBBoxFromNode(struct boundingBox *bbox, const struct bvhNode *node) { bbox->min.x = node->bounds[0]; bbox->max.x = node->bounds[1]; bbox->min.y = node->bounds[2]; @@ -62,25 +57,10 @@ static inline void loadBBoxFromNode(bBox *bbox, const struct bvhNode *node) { bbox->max.z = node->bounds[5]; } -static const bBox emptyBBox = { - .min = { FLT_MAX, FLT_MAX, FLT_MAX }, - .max = { -FLT_MAX, -FLT_MAX, -FLT_MAX } -}; - -static inline float halfArea(const bBox *bbox) { - vector extent = vecSub(bbox->max, bbox->min); - return extent.x * (extent.y + extent.z) + extent.y * extent.z; -} - -static inline void extendBBox(bBox *dst, const bBox *src) { - dst->min = vecMin(dst->min, src->min); - dst->max = vecMax(dst->max, src->max); -} - static inline float nodeArea(const struct bvhNode *node) { - bBox bbox; + struct boundingBox bbox; loadBBoxFromNode(&bbox, node); - return halfArea(&bbox); + return bboxHalfArea(&bbox); } static inline void makeLeaf(struct bvhNode* node, unsigned begin, unsigned primCount) { @@ -137,7 +117,7 @@ static inline unsigned partitionPrimitiveIndices( static void buildBvhRecursive( unsigned nodeId, struct bvh *bvh, - const bBox *bboxes, + const struct boundingBox *bboxes, const vector *centers, unsigned begin, unsigned end, unsigned depth) @@ -172,13 +152,13 @@ static void buildBvhRecursive( // Sweep from the right to the left to compute the partial SAH cost. // Recall that the SAH is the sum of two parts: SA(left) * N(left) + SA(right) * N(right). // This loop computes SA(right) * N(right) alone. - bBox curBBox = emptyBBox; + struct boundingBox curBBox = emptyBBox; unsigned curCount = 0; for (unsigned i = BIN_COUNT; i > 1; --i) { Bin *bin = &bins[axis][i - 1]; curCount += bin->count; extendBBox(&curBBox, &bin->bbox); - bin->cost = curCount * halfArea(&curBBox); + bin->cost = curCount * bboxHalfArea(&curBBox); } // Sweep from the left to the right to compute the full cost and find the minimum. @@ -188,7 +168,7 @@ static void buildBvhRecursive( Bin *bin = &bins[axis][i]; curCount += bin->count; extendBBox(&curBBox, &bin->bbox); - float cost = curCount * halfArea(&curBBox) + bins[axis][i + 1].cost; + float cost = curCount * bboxHalfArea(&curBBox) + bins[axis][i + 1].cost; if (cost < minCost[axis]) { minBin[axis] = i + 1; minCost[axis] = cost; @@ -228,8 +208,8 @@ static void buildBvhRecursive( bvh->nodeCount += 2; // Compute the bounding box of the children - bBox leftBBox = emptyBBox; - bBox rightBBox = emptyBBox; + struct boundingBox leftBBox = emptyBBox; + struct boundingBox rightBBox = emptyBBox; for (unsigned i = 0; i < minBin[minAxis]; ++i) extendBBox(&leftBBox, &bins[minAxis][i].bbox); for (unsigned i = minBin[minAxis]; i < BIN_COUNT; ++i) @@ -246,21 +226,21 @@ static void buildBvhRecursive( } } -struct bvh *buildBvh(int *polys, unsigned count) { +// Builds a BVH using the provided callback to obtain bounding boxes and centers for each primitive +static inline struct bvh *buildBvhGeneric( + void* userData, + void (*getBBoxAndCenter)(void *, unsigned, struct boundingBox *, vector *), + unsigned count) +{ vector *centers = malloc(sizeof(vector) * count); - bBox *bboxes = malloc(sizeof(bBox) * count); + struct boundingBox *bboxes = malloc(sizeof(struct boundingBox) * count); int *primIndices = malloc(sizeof(int) * count); - bBox rootBBox = emptyBBox; + struct boundingBox rootBBox = emptyBBox; // Precompute bboxes and centers for (unsigned i = 0; i < count; ++i) { - vector v0 = vertexArray[polygonArray[polys[i]].vertexIndex[0]]; - vector v1 = vertexArray[polygonArray[polys[i]].vertexIndex[1]]; - vector v2 = vertexArray[polygonArray[polys[i]].vertexIndex[2]]; - centers[i] = getMidPoint(v0, v1, v2); - bboxes[i].min = vecMin(v0, vecMin(v1, v2)); - bboxes[i].max = vecMax(v0, vecMax(v1, v2)); + getBBoxAndCenter(userData, i, &bboxes[i], ¢ers[i]); primIndices[i] = i; rootBBox.min = vecMin(rootBBox.min, bboxes[i].min); rootBBox.max = vecMax(rootBBox.max, bboxes[i].max); @@ -279,51 +259,38 @@ struct bvh *buildBvh(int *polys, unsigned count) { // Shrink array of nodes (since some leaves may contain more than 1 primitive) bvh->nodes = realloc(bvh->nodes, sizeof(struct bvhNode) * bvh->nodeCount); - for (unsigned i = 0; i < count; ++i) - primIndices[i] = polys[primIndices[i]]; free(centers); free(bboxes); return bvh; } -vector centerFromBBox(struct bBox box) { - return (vector){ - box.min.x + (0.5f * (box.max.x - box.min.x)), - box.min.y + (0.5f * (box.max.y - box.min.y)), - box.min.z + (0.5f * (box.max.z - box.min.z)) - }; +static void getPolyBBoxAndCenter(void* userData, unsigned i, struct boundingBox *bbox, vector *center) { + int* polys = userData; + vector v0 = vertexArray[polygonArray[polys[i]].vertexIndex[0]]; + vector v1 = vertexArray[polygonArray[polys[i]].vertexIndex[1]]; + vector v2 = vertexArray[polygonArray[polys[i]].vertexIndex[2]]; + *center = getMidPoint(v0, v1, v2); + bbox->min = vecMin(v0, vecMin(v1, v2)); + bbox->max = vecMax(v0, vecMax(v1, v2)); } -struct bvh *topLevelBvh(struct mesh *meshes, unsigned meshCount) { - vector *centers = malloc(sizeof(vector) * meshCount); - bBox *bboxes = malloc(sizeof(bBox) * meshCount); - int *primIndices = malloc(sizeof(int) * meshCount); - - bBox rootBBox = emptyBBox; - - //Gather up the bboxes and centres - for (unsigned i = 0; i < meshCount; ++i) { - loadBBoxFromNode(&bboxes[i], &meshes[i].bvh->nodes[0]); - centers[i] = centerFromBBox(bboxes[i]); - rootBBox.min = vecMin(rootBBox.min, bboxes[i].min); - rootBBox.max = vecMax(rootBBox.max, bboxes[i].max); - primIndices[i] = i; - } - - unsigned maxNodes = 2 * meshCount - 1; - struct bvh *bvh = malloc(sizeof(struct bvh)); - bvh->nodeCount = 1; - bvh->nodes = malloc(sizeof(struct bvhNode) * maxNodes); - bvh->primIndices = primIndices; - storeBBoxInNode(&bvh->nodes[0], &rootBBox); - - buildBvhRecursive(0, bvh, bboxes, centers, 0, meshCount, 0); - bvh->nodes = realloc(bvh->nodes, sizeof(struct bvhNode) * bvh->nodeCount); - free(centers); - free(bboxes); +struct bvh *buildBvh(int *polys, unsigned count) { + struct bvh *bvh = buildBvhGeneric(polys, getPolyBBoxAndCenter, count); + for (unsigned i = 0; i < count; ++i) + bvh->primIndices[i] = polys[bvh->primIndices[i]]; return bvh; } +static void getMeshBBoxAndCenter(void* userData, unsigned i, struct boundingBox *bbox, vector *center) { + struct mesh *meshes = userData; + loadBBoxFromNode(bbox, &meshes[i].bvh->nodes[0]); + *center = bboxCenter(bbox); +} + +struct bvh *buildTopLevelBvh(struct mesh *meshes, unsigned meshCount) { + return buildBvhGeneric(meshes, getMeshBBoxAndCenter, meshCount); +} + static inline bool rayIntersectsWithBvhLeaf(const struct bvh *bvh, const struct bvhNode *leaf, const struct lightRay *ray, struct hitRecord *isect) { bool found = false; for (int i = 0; i < leaf->primCount; ++i) { diff --git a/src/accelerators/bvh.h b/src/accelerators/bvh.h index ee3764a9..98c9a01c 100644 --- a/src/accelerators/bvh.h +++ b/src/accelerators/bvh.h @@ -32,7 +32,7 @@ struct bvh { /// @param count Amount of polygons given struct bvh *buildBvh(int *polygons, unsigned count); -struct bvh *topLevelBvh(struct mesh *meshes, unsigned meshCount); +struct bvh *buildTopLevelBvh(struct mesh *meshes, unsigned meshCount); /// Intersects a ray with the given BVH bool rayIntersectsWithBvh(const struct bvh *bvh, const struct lightRay *ray, struct hitRecord *isect); diff --git a/src/accelerators/kdtree.c b/src/accelerators/kdtree.c deleted file mode 100644 index 0b4b4b50..00000000 --- a/src/accelerators/kdtree.c +++ /dev/null @@ -1,212 +0,0 @@ -// -// kdtree.c -// C-ray -// -// Created by Valtteri Koskivuori on 28/04/2017. -// Copyright © 2015-2020 Valtteri Koskivuori. All rights reserved. -// - -#include "../includes.h" -#include "kdtree.h" -#include "bbox.h" - -#include "../renderer/pathtrace.h" -#include "../datatypes/vertexbuffer.h" -#include "../datatypes/poly.h" - -//Tree funcs - -/* - Nodes are built per-object - Start at root node that contains all tris, and a bounding box for the mesh - At each level, split on a different axis in order X,Y,Z,X,Y,Z OR by longest axis - For each level: - 1. Find the midpoint of all tris in the node (calculated in a bounding box already) - 2. Find the longest axis of the bounding box for that node - 3. For each tri in the node, check if for the current axis, it is less than or greater than the overall midpoint - If less, push to left child - if greater, push to right child - */ - -struct Array { - int *array; - size_t used; - size_t size; -}; - -void initArray(struct Array *a, size_t initialSize) { - a->array = malloc(initialSize * sizeof(*a->array)); - a->used = 0; - a->size = initialSize; -} - -void insertArray(struct Array *a, int element) { - // a->used is the number of used entries, because a->array[a->used++] updates a->used only *after* the array has been accessed. - // Therefore a->used can go up to a->size - if (a->used == a->size) { - a->size *= 2; - a->array = realloc(a->array, a->size * sizeof(a->array)); - } - a->array[a->used++] = element; -} - -void freeArray(struct Array *a) { - free(a->array); - a->array = NULL; - a->used = a->size = 0; -} - -struct kdTreeNode *getNewNode() { - struct kdTreeNode *node = calloc(1, sizeof(*node)); - node->bbox = NULL; - node->left = NULL; - node->right = NULL; - node->polygons = NULL; - node->polyCount = 0; - return node; -} - -struct kdTreeNode *buildTree(int *polygons, const int count) { - struct kdTreeNode *node = getNewNode(); - node->polygons = polygons; - node->polyCount = count; - - if (count == 0) - return node; - if (count == 1) { - node->bbox = computeBoundingBox(&node->polygons[0], 1); - node->left = NULL; - node->right = NULL; - return node; - } - - node->bbox = computeBoundingBox(node->polygons, node->polyCount); - float currentSAHCost = (float)node->polyCount * node->bbox->surfaceArea; - - struct vector midPoint = node->bbox->midPoint; - - struct Array leftPolys; - initArray(&leftPolys, 5); - struct Array rightPolys; - initArray(&rightPolys, 5); - - enum bboxAxis axis = getLongestAxis(node->bbox); - - for (int i = 0; i < node->polyCount; ++i) { - struct vector polyMidPoint = getMidPoint(vertexArray[polygonArray[node->polygons[i]].vertexIndex[0]], - vertexArray[polygonArray[node->polygons[i]].vertexIndex[1]], - vertexArray[polygonArray[node->polygons[i]].vertexIndex[2]]); - - if (((axis == X) && (midPoint.x >= polyMidPoint.x)) || - ((axis == Y) && (midPoint.y >= polyMidPoint.y)) || - ((axis == Z) && (midPoint.z >= polyMidPoint.z))) { - insertArray(&rightPolys, node->polygons[i]); - } else { - insertArray(&leftPolys, node->polygons[i]); - } - } - - bool rightFreed = false; - bool leftFreed = false; - if (leftPolys.used == 0 && rightPolys.used > 0) { - freeArray(&leftPolys); - leftPolys = rightPolys; - leftFreed = true; - } - if (rightPolys.used == 0 && leftPolys.used > 0) { - freeArray(&rightPolys); - rightPolys = leftPolys; - rightFreed = true; - } - - struct boundingBox *leftBBox = computeBoundingBox(leftPolys.array, (int)leftPolys.used); - struct boundingBox *rightBBox = computeBoundingBox(rightPolys.array, (int)rightPolys.used); - - float leftSAHCost = leftPolys.used * leftBBox->surfaceArea; - float rightSAHCost = rightPolys.used * rightBBox->surfaceArea; - - free(leftBBox); - free(rightBBox); - - if ((leftSAHCost + rightSAHCost) > currentSAHCost) { - //Stop here - node->left = NULL; - node->right = NULL; - if (leftPolys.used > 0 && !leftFreed) freeArray(&leftPolys); - if (rightPolys.used > 0 && !rightFreed) freeArray(&rightPolys); - } else { - //Keep going - node->left = buildTree(leftPolys.array, (int)leftPolys.used); - node->right = buildTree(rightPolys.array, (int)rightPolys.used); - } - - return node; -} - -//Recurse through tree and count orphan nodes with no polygons -int checkTree(const struct kdTreeNode *node) { - int orphans = 0; - if (node) { - if (node->polyCount == 0) { - orphans += 1; - } - if (node->left) { - orphans += checkTree(node->left); - } - if (node->right) { - orphans += checkTree(node->right); - } - } - return orphans; -} - -int countNodes(const struct kdTreeNode *node) { - int nodes = 0; - if (node) { - if (node->left) { - nodes += countNodes(node->left); - } - if (node->right) { - nodes += countNodes(node->right); - } - nodes += 1; - } - return nodes; -} - -bool rayIntersectsWithNode(const struct kdTreeNode *node, const struct lightRay *ray, struct hitRecord *isect) { - if (!node) return false; - if (!rayIntersectsWithAABB(node->bbox, ray)) return false; - if (node->left || node->right) { - //Recurse down both sides - bool hitLeft = rayIntersectsWithNode(node->left, ray, isect); - bool hitRight = rayIntersectsWithNode(node->right, ray, isect); - return hitLeft || hitRight; - } else { - bool hasHit = false; - //This is a leaf, so check all polys - for (int i = 0; i < node->polyCount; ++i) { - struct poly p = polygonArray[node->polygons[i]]; - if (rayIntersectsWithPolygon(ray, &p, &isect->distance, &isect->surfaceNormal, &isect->uv)) { - hasHit = true; - isect->type = hitTypePolygon; - isect->polyIndex = p.polyIndex; - } - } - if (hasHit) { // Return only after checking every polygon to make sure we got the closest one. - isect->didIntersect = true; - return true; - } - } - return false; -} - -void destroyTree(struct kdTreeNode *node) { - if (node) { - destroyTree(node->left); - destroyTree(node->right); - free(node->bbox); - free(node->polygons); - free(node); - } -} diff --git a/src/accelerators/kdtree.h b/src/accelerators/kdtree.h deleted file mode 100644 index e987c723..00000000 --- a/src/accelerators/kdtree.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// kdtree.h -// C-ray -// -// Created by Valtteri Koskivuori on 28/04/2017. -// Copyright © 2015-2020 Valtteri Koskivuori. All rights reserved. -// - -#pragma once - -struct lightRay; -struct hitRecord; - -struct kdTreeNode { - struct boundingBox *bbox;//Bounding box - struct kdTreeNode *left; //Pointer to left child - struct kdTreeNode *right;//Pointer to right child - int *polygons; //indices to polygons within the bounding box - int polyCount; //Amount of polygons -}; - -/// Builds a KD-tree for a given array of polygons and returns a pointer to the root node -/// @param polygons Array of polygons to process -/// @param count Amount of polygons given -/// @param depth Current depth for recursive calls -struct kdTreeNode *buildTree(int *polygons, const int count); - -/// Traverses a given KD-tree to find an intersection between a ray and a polygon in that tree. Hopefully really fast. -/// @param node Root node to start traversing from -/// @param ray Ray to check intersection against -/// @param isect Intersection information is saved to this struct -bool rayIntersectsWithNode(const struct kdTreeNode *node, const struct lightRay *ray, struct hitRecord *isect); - -/// Count total nodes in a given tree -/// @param node root node of a tree to evaluate -int countNodes(const struct kdTreeNode *node); - -/// Check the health of a given tree -/// @param node root node of a tree to evaluate -int checkTree(const struct kdTreeNode *node); - -/// Free a given tree -/// @param node Root node of a tree to free -void destroyTree(struct kdTreeNode *node); diff --git a/src/datatypes/bbox.h b/src/datatypes/bbox.h new file mode 100644 index 00000000..0ac7f5da --- /dev/null +++ b/src/datatypes/bbox.h @@ -0,0 +1,36 @@ +// +// bbox.h +// C-ray +// +// Created by Valtteri Koskivuori on 28/04/2017. +// Copyright © 2015-2020 Valtteri Koskivuori. All rights reserved. +// + +#pragma once + +#include +#include "../datatypes/vector.h" + +/// Bounding box for a given set of primitives +struct boundingBox { + struct vector min, max; +}; + +static const struct boundingBox emptyBBox = { + .min = { FLT_MAX, FLT_MAX, FLT_MAX }, + .max = { -FLT_MAX, -FLT_MAX, -FLT_MAX } +}; + +static inline float bboxHalfArea(const struct boundingBox *bbox) { + vector extent = vecSub(bbox->max, bbox->min); + return extent.x * (extent.y + extent.z) + extent.y * extent.z; +} + +static inline void extendBBox(struct boundingBox *dst, const struct boundingBox *src) { + dst->min = vecMin(dst->min, src->min); + dst->max = vecMax(dst->max, src->max); +} + +static inline vector bboxCenter(const struct boundingBox* bbox) { + return vecScale(vecAdd(bbox->max, bbox->min), 0.5f); +} diff --git a/src/datatypes/mesh.c b/src/datatypes/mesh.c index 3d83a7a6..169a47d6 100644 --- a/src/datatypes/mesh.c +++ b/src/datatypes/mesh.c @@ -9,7 +9,6 @@ #include "../includes.h" #include "mesh.h" -#include "../accelerators/kdtree.h" #include "../accelerators/bvh.h" #include "vertexbuffer.h" #include "transforms.h" @@ -65,11 +64,7 @@ void destroyMesh(struct mesh *mesh) { if (mesh->transformCount > 0) { free(mesh->transforms); } -#ifdef OLD_KD_TREE - destroyTree(mesh->tree); -#else destroyBvh(mesh->bvh); -#endif if (mesh->materials) { for (int i = 0; i < mesh->materialCount; ++i) { destroyMaterial(&mesh->materials[i]); diff --git a/src/datatypes/mesh.h b/src/datatypes/mesh.h index 9111229a..d3d682ba 100644 --- a/src/datatypes/mesh.h +++ b/src/datatypes/mesh.h @@ -42,13 +42,8 @@ struct mesh { int materialCount; struct material *materials; -#ifdef OLD_KD_TREE - //Root node of the kd-tree for this mesh - struct kdTreeNode *tree; -#else struct bvh *bvh; -#endif - + char *name; }; diff --git a/src/datatypes/scene.c b/src/datatypes/scene.c index f5c907cb..1fbe6ebe 100644 --- a/src/datatypes/scene.c +++ b/src/datatypes/scene.c @@ -18,7 +18,6 @@ #include "image/hdr.h" #include "camera.h" #include "vertexbuffer.h" -#include "../accelerators/kdtree.h" #include "../accelerators/bvh.h" #include "tile.h" #include "mesh.h" @@ -40,11 +39,7 @@ void transformMeshes(struct world *scene) { //TODO: Parallelize this task void computeAccels(struct mesh *meshes, int meshCount) { -#ifdef OLD_KD_TREE - logr(info, "Computing KD-trees: "); -#else logr(info, "Computing BVHs: "); -#endif struct timeval timer = {0}; startTimer(&timer); for (int i = 0; i < meshCount; ++i) { @@ -52,11 +47,7 @@ void computeAccels(struct mesh *meshes, int meshCount) { for (int j = 0; j < meshes[i].polyCount; ++j) { indices[j] = meshes[i].firstPolyIndex + j; } -#ifdef OLD_KD_TREE - meshes[i].tree = buildTree(indices, meshes[i].polyCount); -#else meshes[i].bvh = buildBvh(indices, meshes[i].polyCount); -#endif } printSmartTime(getMs(timer)); printf("\n"); @@ -66,7 +57,7 @@ void computeTopLevelBvh(struct world *scene) { logr(info, "Computing top-level BVH: "); struct timeval timer = {0}; startTimer(&timer); - scene->topLevel = topLevelBvh(scene->meshes, scene->meshCount); + scene->topLevel = buildTopLevelBvh(scene->meshes, scene->meshCount); printSmartTime(getMs(timer)); printf("\n"); } diff --git a/src/renderer/pathtrace.c b/src/renderer/pathtrace.c index 2f53b7a9..83cd3aa3 100644 --- a/src/renderer/pathtrace.c +++ b/src/renderer/pathtrace.c @@ -11,8 +11,6 @@ #include "../datatypes/scene.h" #include "../datatypes/camera.h" -#include "../accelerators/bbox.h" -#include "../accelerators/kdtree.h" #include "../accelerators/bvh.h" #include "../datatypes/image/texture.h" #include "../datatypes/image/hdr.h" diff --git a/src/utils/loaders/sceneloader.c b/src/utils/loaders/sceneloader.c index 03819416..a9348dfc 100644 --- a/src/utils/loaders/sceneloader.c +++ b/src/utils/loaders/sceneloader.c @@ -30,7 +30,6 @@ #include "../platform/capabilities.h" #include "../../datatypes/image/imagefile.h" #include "../../renderer/renderer.h" -#include "../../accelerators/kdtree.h" #include "../converter.h" #include "textureloader.h" #include "objloader.h"