-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from goksuguvendiren/bounding_box
Bounding box
- Loading branch information
Showing
21 changed files
with
1,455,572 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
// | ||
// Created by Göksu Güvendiren on 24/03/2017. | ||
// | ||
|
||
#include "HitInfo.h" | ||
#include "BoundingVolume.h" | ||
#include "Shape.h" | ||
#include "Box.h" | ||
#include "glm/glm.hpp" | ||
#include "Triangle.h" | ||
|
||
BoundingVolume::BoundingVolume(const std::vector<Shape*>& shapes, Axis axis) | ||
{ | ||
left = nullptr; | ||
right = nullptr; | ||
shape = nullptr; | ||
|
||
assert(shapes.size() > 0); | ||
|
||
if (shapes.size() == 1){ | ||
shape = shapes[0]; | ||
box = Box(shapes[0]->Min(), shapes[0]->Max()); | ||
|
||
return; | ||
} | ||
|
||
std::vector<Shape*> leftshapes; leftshapes.reserve(shapes.size() / 2 + 1); | ||
std::vector<Shape*> rightshapes; rightshapes.reserve(shapes.size() / 2 + 1); | ||
|
||
Axis nextAxis; | ||
glm::vec3 middle; | ||
|
||
std::vector<Shape*>::const_iterator beginning; | ||
std::vector<Shape*>::const_iterator middling; | ||
std::vector<Shape*>::const_iterator ending; | ||
|
||
auto sortedShapes = shapes; | ||
|
||
assert(axis == Axis::X || axis == Axis::Y || axis == Axis::Z); | ||
|
||
switch(axis){ | ||
case Axis::X : | ||
std::sort(sortedShapes.begin(), sortedShapes.end(), [](auto& sh1, auto& sh2){ | ||
return sh1->Middle().x < sh2->Middle().x; | ||
}); | ||
|
||
nextAxis = Axis::Y; | ||
break; | ||
|
||
case Axis::Y : | ||
std::sort(sortedShapes.begin(), sortedShapes.end(), [](auto& sh1, auto& sh2){ | ||
return sh1->Middle().y < sh2->Middle().y; | ||
}); | ||
|
||
nextAxis = Axis::Z; | ||
break; | ||
|
||
case Axis::Z : | ||
std::sort(sortedShapes.begin(), sortedShapes.end(), [](auto& sh1, auto& sh2){ | ||
return sh1->Middle().z < sh2->Middle().z; | ||
}); | ||
|
||
nextAxis = Axis::X; | ||
break; | ||
} | ||
|
||
beginning = sortedShapes.begin(); | ||
middling = sortedShapes.begin() + (sortedShapes.size() / 2); | ||
ending = sortedShapes.end(); | ||
|
||
leftshapes = std::vector<Shape*>(beginning, middling); | ||
rightshapes = std::vector<Shape*>(middling, ending); | ||
|
||
assert(shapes.size() == (leftshapes.size() + rightshapes.size())); | ||
|
||
left = new BoundingVolume(leftshapes, nextAxis); | ||
right = new BoundingVolume(rightshapes, nextAxis); | ||
|
||
box.Min(glm::min(left->box.Min(), right->box.Min())); | ||
box.Max(glm::max(left->box.Max(), right->box.Max())); | ||
} | ||
|
||
auto to_ptrs(const std::vector<Triangle> &triangles) | ||
{ | ||
std::vector<Shape*> shapes(triangles.size()); | ||
|
||
for(int i = 0; i < triangles.size(); i++){ | ||
const Shape* s = triangles.data() + i; | ||
shapes[i] = const_cast<Shape*>(s); | ||
} | ||
|
||
return shapes; | ||
} | ||
|
||
BoundingVolume::BoundingVolume(const std::vector<Triangle> &triangles, Axis axis) : | ||
BoundingVolume(to_ptrs(triangles), axis) | ||
{} | ||
|
||
boost::optional<HitInfo> BoundingVolume::Hit(const Ray &ray) const | ||
{ | ||
if (!box.Hit(ray)) return boost::none; | ||
if (!left && !right) return shape->Hit(ray); | ||
|
||
boost::optional<HitInfo> leftHitInfo = left->Hit(ray); | ||
boost::optional<HitInfo> rightHitInfo = right->Hit(ray); | ||
|
||
if (!leftHitInfo && !rightHitInfo) return boost::none; | ||
|
||
HitInfo ultimate; | ||
|
||
if (leftHitInfo) { | ||
ultimate = *leftHitInfo; | ||
} | ||
if (rightHitInfo){ | ||
if (rightHitInfo->Parameter() < ultimate.Parameter()) | ||
ultimate = *rightHitInfo; | ||
} | ||
|
||
return ultimate; | ||
} | ||
|
||
|
||
//bool BoundingVolume::FastHit (const Ray& ray) const | ||
//{ | ||
// if (!box.Hit(ray)) return false; | ||
// if (!left && !right) return shape->FastHit(ray); | ||
// | ||
// boost::optional<HitInfo> leftHitInfo = left->Hit(ray); | ||
// boost::optional<HitInfo> rightHitInfo = right->Hit(ray); | ||
// | ||
// if (!leftHitInfo && !rightHitInfo) return false; | ||
// | ||
// HitInfo ultimate; | ||
// | ||
// if (leftHitInfo) { | ||
// ultimate = *leftHitInfo; | ||
// } | ||
// if (rightHitInfo){ | ||
// if (rightHitInfo->Parameter() < ultimate.Parameter()) | ||
// ultimate = *rightHitInfo; | ||
// } | ||
// | ||
// return ultimate; | ||
//} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// Created by Göksu Güvendiren on 24/03/2017. | ||
// | ||
|
||
#pragma once | ||
#include <vector> | ||
#include "glm/vec3.hpp" | ||
#include "boost/optional.hpp" | ||
#include "Box.h" | ||
|
||
class Shape; | ||
class Triangle; | ||
class Ray; | ||
class HitInfo; | ||
|
||
enum class Axis | ||
{ | ||
X, | ||
Y, | ||
Z | ||
}; | ||
|
||
class BoundingVolume | ||
{ | ||
Box box; | ||
BoundingVolume* left; | ||
BoundingVolume* right; | ||
|
||
Shape* shape; | ||
|
||
public: | ||
BoundingVolume() : left(nullptr), right(nullptr), shape(nullptr) {}; | ||
const Box& BBox() const { return box; } | ||
BoundingVolume(const std::vector<Shape*>& shapes, Axis axis); | ||
BoundingVolume(const std::vector<Triangle>& triangles, Axis axis); | ||
|
||
boost::optional<HitInfo> Hit (const Ray& ray) const; | ||
bool FastHit (const Ray& ray) const; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// | ||
// Created by Göksu Güvendiren on 18/03/2017. | ||
// | ||
|
||
#include "Box.h" | ||
#include "Shape.h" | ||
#include "Ray.h" | ||
|
||
bool Box::Hit(const Ray &ray) const | ||
{ | ||
auto mins = (minValues - ray.Origin()) * ray.InvDirection(); | ||
auto maxs = (maxValues - ray.Origin()) * ray.InvDirection(); | ||
|
||
float tx1 = mins.x; | ||
float tx2 = maxs.x; | ||
|
||
float tmin = std::min(tx1, tx2); | ||
float tmax = std::max(tx1, tx2); | ||
|
||
float ty1 = mins.y; | ||
float ty2 = maxs.y; | ||
|
||
tmin = std::max(tmin, std::min(ty1, ty2)); | ||
tmax = std::min(tmax, std::max(ty1, ty2)); | ||
|
||
float tz1 = mins.z; | ||
float tz2 = maxs.z; | ||
|
||
tmin = std::max(tmin, std::min(tz1, tz2)); | ||
tmax = std::min(tmax, std::max(tz1, tz2)); | ||
|
||
return tmax >= std::max(0.f, tmin); | ||
} | ||
|
||
void Box::Compare(const glm::vec3 &val) | ||
{ | ||
minValues = glm::min(minValues, val); | ||
maxValues = glm::max(maxValues, val); | ||
} | ||
|
||
Box::Box() | ||
{} | ||
|
||
Box::Box(glm::vec3 minval, glm::vec3 maxval) | ||
{ | ||
minValues = minval; | ||
maxValues = maxval; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// | ||
// Created by Göksu Güvendiren on 18/03/2017. | ||
// | ||
|
||
#pragma once | ||
|
||
#include <boost/optional.hpp> | ||
#include "glm/vec3.hpp" | ||
|
||
class HitInfo; | ||
class Ray; | ||
|
||
class Box | ||
{ | ||
glm::vec3 minValues; | ||
glm::vec3 maxValues; | ||
|
||
public: | ||
Box(); | ||
Box(glm::vec3 minval, glm::vec3 maxval); | ||
|
||
// boost::optional<HitInfo> Hit(const Ray &ray) const; | ||
bool Hit(const Ray &ray) const; | ||
|
||
void Min(glm::vec3 val) { minValues = val; } | ||
void Max(glm::vec3 val) { maxValues = val; } | ||
|
||
const glm::vec3& Min() const { return minValues; } | ||
const glm::vec3& Max() const { return maxValues; } | ||
const glm::vec3 Middle() const { return (minValues + maxValues) / 2.0f; } | ||
|
||
void Compare(const glm::vec3& val); | ||
|
||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.