21 #define DEFAULT_ORIGIN chag::make_vector(0.0f, 0.0f, 0.0f) 22 #define DEFAULT_HALFVECTOR chag::make_vector(1.0f, 1.0f, 1.0f) 26 origin = DEFAULT_ORIGIN;
27 halfVector = DEFAULT_HALFVECTOR;
28 setupAABB(DEFAULT_ORIGIN, DEFAULT_HALFVECTOR);
36 : origin(origin), halfVector(halfVector)
40 setupAABB(origin, halfVector);
43 Octree::Octree(chag::float3 origin, chag::float3 halfVector,
int depth)
44 : origin(origin), halfVector(halfVector), depth(depth)
47 setupAABB(origin, halfVector);
51 for (
int i = 0; i < 8; i++) {
56 void Octree::setupAABB(chag::float3 origin, chag::float3 halfVector) {
57 chag::float3 p1 = origin + halfVector;
58 chag::float3 p2 = origin - halfVector;
60 aabb.maxV = combineTwoPointsByComparator(p1,p2, [](
float point1,
float point2)
62 return point1 > point2;
64 aabb.minV = combineTwoPointsByComparator(p1,p2, [](
float point1,
float point2)
66 return point1 < point2;
70 chag::float3 Octree::combineTwoPointsByComparator(
71 chag::float3 p1, chag::float3 p2,
72 std::function<
bool (
float ,
float)> comparator)
74 chag::float3 maxPoint;
76 maxPoint.x = comparator(p1.x, p2.x) ? p1.x : p2.x;
77 maxPoint.y = comparator(p1.y, p2.y) ? p1.y : p2.y;
78 maxPoint.z = comparator(p1.z, p2.z) ? p1.z : p2.z;
88 void Octree::insertAll(std::vector<Triangle *> &triangles) {
89 for (
unsigned int i = 0; i < triangles.size(); i++) {
90 insertTriangle(triangles[i]);
94 void Octree::insertTriangle(
Triangle *t) {
97 for (
int i = 0; i < 8; i++) {
98 octs.insert(getOctantContainingPoint(boundingBox->points[i]));
101 if(octs.size() > 1 || depth == MAX_DEPTH) {
108 for (std::set<int>::iterator it = octs.begin(); it != octs.end(); it++) {
109 children[*it]->insertTriangle(t);
114 void Octree::createChildren() {
115 for (
int i = 0; i < 8; ++i) {
116 chag::float3 newOrigin = origin;
117 newOrigin.x += halfVector.x * (i & 4 ? .5f : -.5f);
118 newOrigin.y += halfVector.y * (i & 2 ? .5f : -.5f);
119 newOrigin.z += halfVector.z * (i & 1 ? .5f : -.5f);
120 children[i] =
new Octree(newOrigin, halfVector * .5f, depth + 1);
125 return *children != NULL;
130 for (
int i = 0; i < 8; i++) {
131 octs->push_back(children[i]);
137 int Octree::getOctantContainingPoint(
const chag::float3 &point) {
139 if (point.x >= origin.x) oct |= 4;
140 if (point.y >= origin.y) oct |= 2;
141 if (point.z >= origin.z) oct |= 1;
145 int Octree::getTriangleCount() {
154 int c = getTriangleCount();
157 for (
int i = 0; i < 8; i++) {
168 for (
int i = 0; i < 8; i++) {
176 bool testSlab(
float rayO,
float rayD,
float minV,
float maxV,
float *tNear,
float *tFar) {
178 if (rayD < 0.0001f) {
179 return rayO <= maxV && rayO >= minV;
183 float t1 = (minV - rayO) * rayD;
184 float t2 = (maxV - rayO) * rayD;
197 if (*tNear < *tFar) {
210 bool Octree::rayCastIntersectsAABB(chag::float3 rayOrigin, chag::float3 rayVector) {
211 chag::float3 maxCorner = chag::make_vector(origin.x + halfVector.x, origin.y + halfVector.y, origin.z + halfVector.z);
212 chag::float3 minCorner = chag::make_vector(origin.x - halfVector.x, origin.y - halfVector.y, origin.z - halfVector.z);
214 float tNear = -FLT_MAX, tFar = FLT_MAX;
216 return testSlab(rayOrigin.x, rayVector.x, minCorner.x, maxCorner.x, &tNear, &tFar)
217 || (testSlab(rayOrigin.y, rayVector.y, minCorner.y, maxCorner.y, &tNear, &tFar))
218 || (testSlab(rayOrigin.z, rayVector.z, minCorner.z, maxCorner.z, &tNear, &tFar));
223 if (!rayCastIntersectsAABB(rayOrigin, rayVector)) {
227 putTrianglesToList(triangleList);
229 for (
int i = 0; i < 8; i++) {
235 void Octree::putTrianglesToList(std::vector<Triangle *> *triangleList) {
236 for (
unsigned int i = 0; i < ts.size(); i++) {
237 triangleList->push_back(ts[i]);
int getTriangleCountRecursively()
std::vector< Triangle * > * getTriangles()
void getTrianglesInsersectedByRayCast(chag::float3 rayOrigin, chag::float3 rayVector, std::vector< Triangle * > *triangleList)
void getChildren(std::vector< Octree * > *octs)
int getNumberOfSubTrees()