Working on BVH

main
Brett 2022-10-18 00:44:49 -04:00
parent 03d0740003
commit 36b250a66b
37 changed files with 1922 additions and 131 deletions

View File

@ -39,7 +39,7 @@
{
"directoryIndex" : 0,
"id" : "Step_2::@6890427a1f51a3e7e1df",
"jsonFile" : "target-Step_2-Debug-b27f884bab06827a0b8a.json",
"jsonFile" : "target-Step_2-Debug-c817dd65f416e821189b.json",
"name" : "Step_2",
"projectIndex" : 0
}

View File

@ -26,7 +26,7 @@
"objects" :
[
{
"jsonFile" : "codemodel-v2-c89fcd438d6ff892e367.json",
"jsonFile" : "codemodel-v2-cd07775fdd2e364d3d72.json",
"kind" : "codemodel",
"version" :
{
@ -86,7 +86,7 @@
},
"codemodel-v2" :
{
"jsonFile" : "codemodel-v2-c89fcd438d6ff892e367.json",
"jsonFile" : "codemodel-v2-cd07775fdd2e364d3d72.json",
"kind" : "codemodel",
"version" :
{

View File

@ -71,7 +71,9 @@
2,
3,
4,
5
5,
6,
7
]
}
],
@ -109,12 +111,20 @@
2,
3,
4,
5
5,
6,
7
]
}
],
"sources" :
[
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "src/globals.cpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
@ -127,6 +137,12 @@
"path" : "src/main.cpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "src/math/colliders.cpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,

Binary file not shown.

View File

@ -1,40 +1,15 @@
# ninja log v5
0 915 1666044004009674564 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
1 1080 1666041865974063754 CMakeFiles/Step_2.dir/src/util/parser.cpp.o dc1044c577ff67b5
1 919 1666044004017674800 CMakeFiles/Step_2.dir/src/raytracing.cpp.o cfda37b51895cd7e
919 981 1666044004077676562 Step_2 513d6b5f7b82bcb
1 831 1666044003929672214 CMakeFiles/Step_2.dir/src/world.cpp.o abef135c83fe5bb1
0 934 1666041865830059555 CMakeFiles/Step_2.dir/src/image/image.cpp.o 13adbb05fcabbeec
1 746 1666046081093003733 CMakeFiles/Step_2.dir/src/util/models.cpp.o 637cb95d94c45aa5
1 927 1666046081273009106 CMakeFiles/Step_2.dir/src/world.cpp.o abef135c83fe5bb1
1 942 1666046081289009585 CMakeFiles/Step_2.dir/src/raytracing.cpp.o cfda37b51895cd7e
1 1031 1666046081377012214 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
1031 1114 1666046081457014603 Step_2 7fa048d28deec3eb
0 928 1666046122330234924 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
928 993 1666046122394236835 Step_2 7fa048d28deec3eb
0 932 1666046219013119982 CMakeFiles/Step_2.dir/src/world.cpp.o abef135c83fe5bb1
0 1023 1666046219105122725 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
1023 1092 1666046219173124755 Step_2 7fa048d28deec3eb
1 999 1666046241685796261 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
999 1062 1666046241749798170 Step_2 7fa048d28deec3eb
0 1002 1666046252390115513 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
1002 1073 1666046252462117662 Step_2 7fa048d28deec3eb
0 791 1666047936840238827 CMakeFiles/Step_2.dir/src/world.cpp.o abef135c83fe5bb1
0 927 1666047936976242871 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
927 992 1666047937040244774 Step_2 7fa048d28deec3eb
0 903 1666047991325858795 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
903 964 1666047991389860698 Step_2 7fa048d28deec3eb
1 914 1666048033211104116 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
914 978 1666048033275106019 Step_2 7fa048d28deec3eb
1 894 1666048070228204690 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
894 955 1666048070288206475 Step_2 7fa048d28deec3eb
1 918 1666048117581612568 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
918 981 1666048117645614472 Step_2 7fa048d28deec3eb
0 833 1666048278626400562 CMakeFiles/Step_2.dir/src/world.cpp.o abef135c83fe5bb1
833 897 1666048278686402346 Step_2 7fa048d28deec3eb
1 886 1666048336304115348 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
886 947 1666048336364117131 Step_2 7fa048d28deec3eb
1 921 1666048358240767530 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
921 990 1666048358312769670 Step_2 7fa048d28deec3eb
0 823 1666048503185076728 CMakeFiles/Step_2.dir/src/world.cpp.o abef135c83fe5bb1
823 887 1666048503249078633 Step_2 7fa048d28deec3eb
1 1043 1666064132960672809 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
1 754 1666063960682945134 CMakeFiles/Step_2.dir/src/math/colliders.cpp.o a8a5f894b3fe853c
1 943 1666053389345551413 CMakeFiles/Step_2.dir/src/util/parser.cpp.o dc1044c577ff67b5
1 848 1666063960778948360 CMakeFiles/Step_2.dir/src/raytracing.cpp.o cfda37b51895cd7e
1043 1115 1666064133032675183 Step_2 a444ddadd61997d2
1 923 1666063960854950913 CMakeFiles/Step_2.dir/src/util/models.cpp.o 637cb95d94c45aa5
0 10 1666063876984117759 CMakeFiles/Step_2.dir/src/globals.cpp.o 9579c877d4b65af0
1 869 1666064119040213917 CMakeFiles/Step_2.dir/src/world.cpp.o abef135c83fe5bb1
0 883 1666053389289549931 CMakeFiles/Step_2.dir/src/image/image.cpp.o 13adbb05fcabbeec
0 891 1666065564826630786 CMakeFiles/Step_2.dir/src/util/models.cpp.o 637cb95d94c45aa5
0 823 1666065649113302898 CMakeFiles/Step_2.dir/src/raytracing.cpp.o cfda37b51895cd7e
0 851 1666065649141303787 CMakeFiles/Step_2.dir/src/world.cpp.o abef135c83fe5bb1
0 1014 1666065649305308983 CMakeFiles/Step_2.dir/src/main.cpp.o 2fb1ddffcef25127
1014 1084 1666065649373311137 Step_2 a444ddadd61997d2

Binary file not shown.

View File

@ -1,3 +1,3 @@
Start testing: Oct 17 19:15 EDT
Start testing: Oct 18 00:00 EDT
----------------------------------------------------------
End testing: Oct 17 19:15 EDT
End testing: Oct 18 00:00 EDT

View File

@ -49,6 +49,13 @@ cmake_ninja_workdir = /home/brett/Documents/Brock/CS$ 3P93/Project/Step$ 2/cmake
build cmake_object_order_depends_target_Step_2: phony || CMakeFiles/Step_2.dir
build CMakeFiles/Step_2.dir/src/globals.cpp.o: CXX_COMPILER__Step_2_Debug /home/brett/Documents/Brock/CS$ 3P93/Project/Step$ 2/src/globals.cpp || cmake_object_order_depends_target_Step_2
DEP_FILE = CMakeFiles/Step_2.dir/src/globals.cpp.o.d
FLAGS = -g -std=gnu++20
INCLUDES = -I"/home/brett/Documents/Brock/CS 3P93/Project/Step 2/include"
OBJECT_DIR = CMakeFiles/Step_2.dir
OBJECT_FILE_DIR = CMakeFiles/Step_2.dir/src
build CMakeFiles/Step_2.dir/src/image/image.cpp.o: CXX_COMPILER__Step_2_Debug /home/brett/Documents/Brock/CS$ 3P93/Project/Step$ 2/src/image/image.cpp || cmake_object_order_depends_target_Step_2
DEP_FILE = CMakeFiles/Step_2.dir/src/image/image.cpp.o.d
FLAGS = -g -std=gnu++20
@ -63,6 +70,13 @@ build CMakeFiles/Step_2.dir/src/main.cpp.o: CXX_COMPILER__Step_2_Debug /home/bre
OBJECT_DIR = CMakeFiles/Step_2.dir
OBJECT_FILE_DIR = CMakeFiles/Step_2.dir/src
build CMakeFiles/Step_2.dir/src/math/colliders.cpp.o: CXX_COMPILER__Step_2_Debug /home/brett/Documents/Brock/CS$ 3P93/Project/Step$ 2/src/math/colliders.cpp || cmake_object_order_depends_target_Step_2
DEP_FILE = CMakeFiles/Step_2.dir/src/math/colliders.cpp.o.d
FLAGS = -g -std=gnu++20
INCLUDES = -I"/home/brett/Documents/Brock/CS 3P93/Project/Step 2/include"
OBJECT_DIR = CMakeFiles/Step_2.dir
OBJECT_FILE_DIR = CMakeFiles/Step_2.dir/src/math
build CMakeFiles/Step_2.dir/src/raytracing.cpp.o: CXX_COMPILER__Step_2_Debug /home/brett/Documents/Brock/CS$ 3P93/Project/Step$ 2/src/raytracing.cpp || cmake_object_order_depends_target_Step_2
DEP_FILE = CMakeFiles/Step_2.dir/src/raytracing.cpp.o.d
FLAGS = -g -std=gnu++20
@ -99,7 +113,7 @@ build CMakeFiles/Step_2.dir/src/world.cpp.o: CXX_COMPILER__Step_2_Debug /home/br
#############################################
# Link the executable Step_2
build Step_2: CXX_EXECUTABLE_LINKER__Step_2_Debug CMakeFiles/Step_2.dir/src/image/image.cpp.o CMakeFiles/Step_2.dir/src/main.cpp.o CMakeFiles/Step_2.dir/src/raytracing.cpp.o CMakeFiles/Step_2.dir/src/util/models.cpp.o CMakeFiles/Step_2.dir/src/util/parser.cpp.o CMakeFiles/Step_2.dir/src/world.cpp.o
build Step_2: CXX_EXECUTABLE_LINKER__Step_2_Debug CMakeFiles/Step_2.dir/src/globals.cpp.o CMakeFiles/Step_2.dir/src/image/image.cpp.o CMakeFiles/Step_2.dir/src/main.cpp.o CMakeFiles/Step_2.dir/src/math/colliders.cpp.o CMakeFiles/Step_2.dir/src/raytracing.cpp.o CMakeFiles/Step_2.dir/src/util/models.cpp.o CMakeFiles/Step_2.dir/src/util/parser.cpp.o CMakeFiles/Step_2.dir/src/world.cpp.o
FLAGS = -g
OBJECT_DIR = CMakeFiles/Step_2.dir
POST_BUILD = :

View File

@ -0,0 +1,47 @@
# Blender 3.3.1
# www.blender.org
mtllib cube.mtl
o Cube
v -250.000000 -250.000000 250.000000
v -250.000000 250.000000 250.000000
v -250.000000 -250.000000 -250.000000
v -250.000000 250.000000 -250.000000
v 250.000000 -250.000000 250.000000
v 250.000000 250.000000 250.000000
v 250.000000 -250.000000 -250.000000
v 250.000000 250.000000 -250.000000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn -0.0000 1.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vt 0.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 1.000000 1.000000
s 0
f 3/6/1 2/2/1 1/1/1
f 7/14/2 4/8/2 3/4/2
f 5/9/3 8/16/3 7/14/3
f 1/1/4 6/12/4 5/10/4
f 1/1/5 7/15/5 3/5/5
f 6/13/6 4/8/6 8/16/6
f 3/6/1 4/7/1 2/2/1
f 7/14/2 8/16/2 4/8/2
f 5/9/3 6/11/3 8/16/3
f 1/1/4 2/2/4 6/12/4
f 1/1/5 5/10/5 7/15/5
f 6/13/6 2/3/6 4/8/6

View File

@ -0,0 +1,47 @@
# Blender 3.3.1
# www.blender.org
mtllib cubeflipped.mtl
o Cube
v -250.000000 -250.000000 250.000000
v -250.000000 250.000000 250.000000
v -250.000000 -250.000000 -250.000000
v -250.000000 250.000000 -250.000000
v 250.000000 -250.000000 250.000000
v 250.000000 250.000000 250.000000
v 250.000000 -250.000000 -250.000000
v 250.000000 250.000000 -250.000000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 1.000000 1.000000
s 0
f 3/6/1 1/1/1 2/2/1
f 7/14/2 3/4/2 4/8/2
f 5/9/3 7/14/3 8/16/3
f 1/1/4 5/10/4 6/12/4
f 1/1/5 3/5/5 7/15/5
f 6/13/6 8/16/6 4/8/6
f 3/6/1 2/2/1 4/7/1
f 7/14/2 4/8/2 8/16/2
f 5/9/3 8/16/3 6/11/3
f 1/1/4 6/12/4 2/2/4
f 1/1/5 7/15/5 5/10/5
f 6/13/6 4/8/6 2/3/6

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View File

@ -39,7 +39,7 @@
{
"directoryIndex" : 0,
"id" : "Step_2::@6890427a1f51a3e7e1df",
"jsonFile" : "target-Step_2-Release-1f9724322786b4b63326.json",
"jsonFile" : "target-Step_2-Release-447fa4d814ec7f408004.json",
"name" : "Step_2",
"projectIndex" : 0
}

View File

@ -26,7 +26,7 @@
"objects" :
[
{
"jsonFile" : "codemodel-v2-01890b5125a9a100c3e5.json",
"jsonFile" : "codemodel-v2-7b5e10a772884891e931.json",
"kind" : "codemodel",
"version" :
{
@ -86,7 +86,7 @@
},
"codemodel-v2" :
{
"jsonFile" : "codemodel-v2-01890b5125a9a100c3e5.json",
"jsonFile" : "codemodel-v2-7b5e10a772884891e931.json",
"kind" : "codemodel",
"version" :
{

View File

@ -71,7 +71,9 @@
2,
3,
4,
5
5,
6,
7
]
}
],
@ -109,12 +111,20 @@
2,
3,
4,
5
5,
6,
7
]
}
],
"sources" :
[
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "src/globals.cpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
@ -127,6 +137,12 @@
"path" : "src/main.cpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "src/math/colliders.cpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,

View File

@ -49,6 +49,13 @@ cmake_ninja_workdir = /home/brett/Documents/Brock/CS$ 3P93/Project/Step$ 2/cmake
build cmake_object_order_depends_target_Step_2: phony || CMakeFiles/Step_2.dir
build CMakeFiles/Step_2.dir/src/globals.cpp.o: CXX_COMPILER__Step_2_Release /home/brett/Documents/Brock/CS$ 3P93/Project/Step$ 2/src/globals.cpp || cmake_object_order_depends_target_Step_2
DEP_FILE = CMakeFiles/Step_2.dir/src/globals.cpp.o.d
FLAGS = -O3 -DNDEBUG -std=gnu++20
INCLUDES = -I"/home/brett/Documents/Brock/CS 3P93/Project/Step 2/include"
OBJECT_DIR = CMakeFiles/Step_2.dir
OBJECT_FILE_DIR = CMakeFiles/Step_2.dir/src
build CMakeFiles/Step_2.dir/src/image/image.cpp.o: CXX_COMPILER__Step_2_Release /home/brett/Documents/Brock/CS$ 3P93/Project/Step$ 2/src/image/image.cpp || cmake_object_order_depends_target_Step_2
DEP_FILE = CMakeFiles/Step_2.dir/src/image/image.cpp.o.d
FLAGS = -O3 -DNDEBUG -std=gnu++20
@ -63,6 +70,13 @@ build CMakeFiles/Step_2.dir/src/main.cpp.o: CXX_COMPILER__Step_2_Release /home/b
OBJECT_DIR = CMakeFiles/Step_2.dir
OBJECT_FILE_DIR = CMakeFiles/Step_2.dir/src
build CMakeFiles/Step_2.dir/src/math/colliders.cpp.o: CXX_COMPILER__Step_2_Release /home/brett/Documents/Brock/CS$ 3P93/Project/Step$ 2/src/math/colliders.cpp || cmake_object_order_depends_target_Step_2
DEP_FILE = CMakeFiles/Step_2.dir/src/math/colliders.cpp.o.d
FLAGS = -O3 -DNDEBUG -std=gnu++20
INCLUDES = -I"/home/brett/Documents/Brock/CS 3P93/Project/Step 2/include"
OBJECT_DIR = CMakeFiles/Step_2.dir
OBJECT_FILE_DIR = CMakeFiles/Step_2.dir/src/math
build CMakeFiles/Step_2.dir/src/raytracing.cpp.o: CXX_COMPILER__Step_2_Release /home/brett/Documents/Brock/CS$ 3P93/Project/Step$ 2/src/raytracing.cpp || cmake_object_order_depends_target_Step_2
DEP_FILE = CMakeFiles/Step_2.dir/src/raytracing.cpp.o.d
FLAGS = -O3 -DNDEBUG -std=gnu++20
@ -99,7 +113,7 @@ build CMakeFiles/Step_2.dir/src/world.cpp.o: CXX_COMPILER__Step_2_Release /home/
#############################################
# Link the executable Step_2
build Step_2: CXX_EXECUTABLE_LINKER__Step_2_Release CMakeFiles/Step_2.dir/src/image/image.cpp.o CMakeFiles/Step_2.dir/src/main.cpp.o CMakeFiles/Step_2.dir/src/raytracing.cpp.o CMakeFiles/Step_2.dir/src/util/models.cpp.o CMakeFiles/Step_2.dir/src/util/parser.cpp.o CMakeFiles/Step_2.dir/src/world.cpp.o
build Step_2: CXX_EXECUTABLE_LINKER__Step_2_Release CMakeFiles/Step_2.dir/src/globals.cpp.o CMakeFiles/Step_2.dir/src/image/image.cpp.o CMakeFiles/Step_2.dir/src/main.cpp.o CMakeFiles/Step_2.dir/src/math/colliders.cpp.o CMakeFiles/Step_2.dir/src/raytracing.cpp.o CMakeFiles/Step_2.dir/src/util/models.cpp.o CMakeFiles/Step_2.dir/src/util/parser.cpp.o CMakeFiles/Step_2.dir/src/world.cpp.o
FLAGS = -O3 -DNDEBUG
OBJECT_DIR = CMakeFiles/Step_2.dir
POST_BUILD = :

13
Step 2/include/globals.h Normal file
View File

@ -0,0 +1,13 @@
/*
* Created by Brett Terpstra 6920201 on 17/10/22.
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*/
#ifndef STEP_2_GLOBALS_H
#define STEP_2_GLOBALS_H
namespace Raytracing {
}
#endif //STEP_2_GLOBALS_H

52
Step 2/include/math/bvh.h Normal file
View File

@ -0,0 +1,52 @@
/*
* 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 <util/std.h>
#include <types.h>
// A currently pure header implementation of a BVH. TODO: make source file.
// this is also for testing and might not make it into the step 2.
namespace Raytracing {
class BVHNode {
private:
void* obj;
AABB aabb;
BVHNode* left;
BVHNode* right;
public:
BVHNode(void* obj, AABB aabb, BVHNode* left, BVHNode* right): obj(obj), aabb(std::move(aabb)), left(left), right(right) {}
~BVHNode() {
delete(left);
delete(right);
}
};
class BVHTree {
private:
BVHNode* root = nullptr;
public:
explicit BVHTree(const std::vector<Object*>& objectsInWorld) {
// create a volume for the entire world.
AABB world;
for (const auto& obj : objectsInWorld)
if (!obj->getAABB().isEmpty())
world.expand(obj->getAABB());
// world sized bvh node isn't associated with a specific object
// only leafs should be non-null, and we might need to change it to a vector.
root = new BVHNode(nullptr, world, nullptr, nullptr);
}
~BVHTree(){
delete(root);
}
};
}
#endif //STEP_2_BVH_H

View File

@ -0,0 +1,99 @@
/*
* Created by Brett Terpstra 6920201 on 17/10/22.
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*/
#ifndef STEP_2_COLLIDERS_H
#define STEP_2_COLLIDERS_H
#include <math/vectors.h>
namespace Raytracing {
// 3D Axis Aligned Bounding Box
class AABB {
protected:
vec4 min;
vec4 max;
bool empty = false;
public:
AABB() {
empty = true;
};
AABB(PRECISION_TYPE minX, PRECISION_TYPE minY, PRECISION_TYPE minZ, PRECISION_TYPE maxX, PRECISION_TYPE maxY, PRECISION_TYPE maxZ):
min{minX, minY, minZ}, max{maxX, maxY, maxZ} {
}
AABB(const vec4& min, const vec4& max): min(min), max(max) {}
// creates an AABB extending of size centered on x, y, z
AABB(PRECISION_TYPE x, PRECISION_TYPE y, PRECISION_TYPE z, PRECISION_TYPE size):
min{x - size, y - size, z - size}, max{x + size, y + size, z + size} {
}
// translates the AABB to position x,y,z for world collision detection
[[nodiscard]] AABB translate(PRECISION_TYPE x, PRECISION_TYPE y, PRECISION_TYPE z) const {
vec4 pos = {x, y, z};
return {min + pos, max + pos};
}
// returns an expanded version of this AABB is the other AABB is larger then this AABB
[[nodiscard]] AABB expand(const AABB& other) const {
PRECISION_TYPE minX = std::min(min.x(), other.min.x());
PRECISION_TYPE minY = std::min(min.y(), other.min.y());
PRECISION_TYPE minZ = std::min(min.z(), other.min.z());
PRECISION_TYPE maxX = std::max(max.x(), other.max.x());
PRECISION_TYPE maxY = std::max(max.y(), other.max.y());
PRECISION_TYPE maxZ = std::max(max.z(), other.max.z());
return {minX, minY, minZ, maxX, maxY, maxZ};
}
[[nodiscard]] inline bool intersects(PRECISION_TYPE minX, PRECISION_TYPE minY, PRECISION_TYPE minZ, PRECISION_TYPE maxX, PRECISION_TYPE maxY,
PRECISION_TYPE maxZ) const {
return min.x() < maxX && max.x() > minX && min.y() < maxY && max.y() > minY && min.z() < maxZ && max.z() > minZ;
}
[[nodiscard]] inline bool intersects(const vec4& minV, const vec4& maxV) const {
return intersects(minV.x(), minV.y(), minV.z(), maxV.x(), maxV.y(), maxV.z());
}
[[nodiscard]] inline bool intersects(const AABB& other) const {
return intersects(other.min, other.max);
}
[[nodiscard]] inline bool isInside(PRECISION_TYPE x, PRECISION_TYPE y, PRECISION_TYPE z) const {
return x > min.x() && x < max.x() && y > min.y() && y < max.y() && z > min.z() && z < max.z();
}
[[nodiscard]] inline bool intersectsWithYZ(PRECISION_TYPE y, PRECISION_TYPE z) const {
return y >= min.y() && y <= max.y() && z >= min.z() && z <= max.z();
}
[[nodiscard]] inline bool intersectsWithXZ(PRECISION_TYPE x, PRECISION_TYPE z) const {
return x >= min.x() && x <= max.x() && z >= min.z() && z <= max.z();
}
[[nodiscard]] inline bool intersectsWithXY(PRECISION_TYPE x, PRECISION_TYPE y) const {
return x >= min.x() && x <= max.x() && y >= min.y() && y <= max.y();
}
[[nodiscard]] inline vec4 getCenter() const {
return {min.x() + (max.x() - min.x()) * 0.5, min.y() + (max.y() - min.y()) * 0.5, min.z() + (max.z() - min.z()) * 0.5};
}
[[nodiscard]] PRECISION_TYPE longestDistanceFromCenter() const;
// 0 - x
// 1 - y
// 2 - z
[[nodiscard]] int longestAxis() const;
[[nodiscard]] PRECISION_TYPE longestAxisLength() const;
[[nodiscard]] std::vector<AABB> splitByLongestAxis() const;
[[nodiscard]] PRECISION_TYPE avgDistanceFromCenter() const;
[[nodiscard]] inline bool isEmpty() const {return empty;}
};
}
#endif //STEP_2_COLLIDERS_H

69
Step 2/include/types.h Normal file
View File

@ -0,0 +1,69 @@
/*
* Created by Brett Terpstra 6920201 on 18/10/22.
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*/
#ifndef STEP_2_TYPES_H
#define STEP_2_TYPES_H
#include <math/vectors.h>
#include <math/colliders.h>
// there were some files which needed access to these types
// but including them from world.h would've resulted in circular includes,
// so I moved them here.
namespace Raytracing {
struct HitData {
// all the other values only matter if this is true
bool hit{false};
// the hit point on the object
vec4 hitPoint{};
// the normal of that hit point
vec4 normal{};
// the length of the vector from its origin in its direction.
PRECISION_TYPE length{0};
};
struct ScatterResults {
// returns true to recast the ray with the provided ray
bool scattered;
// the new ray to be cast if scattered
Ray newRay;
// the color of the material
vec4 attenuationColor;
};
class Material {
private:
// most materials will need an albedo
vec4 baseColor;
public:
explicit Material(const vec4& baseColor): baseColor(baseColor) {}
// returns true if the ray was scattered along with the scattered ray, otherwise will return false with empty ray.
// the returned vec4 is the attenuation color
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const = 0;
[[nodiscard]] vec4 getBaseColor() const { return baseColor; }
};
class Object {
protected:
vec4 position;
Material* material;
AABB aabb;
public:
explicit Object(Material* material, const vec4& position): material(material), position(position) {};
// return true if the ray intersects with this object, only between min and max
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const = 0;
[[nodiscard]] Material* getMaterial() const { return material; }
[[nodiscard]] vec4 getPosition() const {return position;}
[[nodiscard]] AABB getAABB() const {return aabb;}
virtual ~Object() = default;
};
}
#endif //STEP_2_TYPES_H

View File

@ -8,35 +8,96 @@
#include <util/std.h>
#include <math/vectors.h>
#include <math/colliders.h>
namespace Raytracing {
struct Triangle {
vec4 vertex1, vertex2, vertex3;
bool hasNormals = false;
vec4 normal1, normal2, normal3;
vec4 uv1, uv2, uv3;
public:
vec4 vertex1, vertex2, vertex3;
bool hasNormals = false;
vec4 normal1, normal2, normal3;
vec4 uv1, uv2, uv3;
AABB aabb;
Triangle(const vec4& v1, const vec4& v2, const vec4& v3): vertex1(v1), vertex2(v2), vertex3(v3) {}
Triangle(const vec4& v1, const vec4& v2, const vec4& v3): vertex1(v1), vertex2(v2), vertex3(v3) {}
Triangle(const vec4& v1, const vec4& v2, const vec4& v3,
const vec4& n1, const vec4& n2, const vec4& n3): vertex1(v1), vertex2(v2), vertex3(v3),
hasNormals(true), normal1(n1), normal2(n2), normal3(n3) {}
Triangle(const vec4& v1, const vec4& v2, const vec4& v3,
const vec4& n1, const vec4& n2, const vec4& n3): vertex1(v1), vertex2(v2), vertex3(v3),
hasNormals(true), normal1(n1), normal2(n2), normal3(n3) {}
Triangle(const vec4& v1, const vec4& v2, const vec4& v3,
const vec4& uv1, const vec4& uv2, const vec4& uv3,
const vec4& n1, const vec4& n2, const vec4& n3): vertex1(v1), vertex2(v2), vertex3(v3),
uv1(uv1), uv2(uv2), uv3(uv3),
hasNormals(true), normal1(n1), normal2(n2), normal3(n3) {}
[[nodiscard]] vec4 findClosestNormal(const vec4& point) const {
// no need to sqrt as exact distance doesn't matter
auto n1Dist = (point - normal1).lengthSquared();
auto n2Dist = (point - normal2).lengthSquared();
auto n3Dist = (point - normal3).lengthSquared();
return (n1Dist < n2Dist && n1Dist < n3Dist) ? normal1 : (n2Dist < n3Dist ? normal2 : normal3);
}
};
struct face {
int v1, v2, v3;
int uv1, uv2, uv3;
int n1, n2, n3;
};
struct ModelData {
// storing all this data is memory inefficient
// since normals and vertices are only vec3s
// and uvs are vec2s
// TODO: create lower order vector classes
std::vector<vec4> vertices;
std::vector<vec4> uvs;
std::vector<vec4> normals;
std::vector<int> indices;
public:
// storing all this data is memory inefficient
// since normals and vertices are only vec3s
// and uvs are vec2s
// TODO: create lower order vector classes
std::vector<vec4> vertices;
std::vector<vec4> uvs;
std::vector<vec4> normals;
std::vector<face> faces;
AABB aabb;
std::vector<Triangle> toTriangles() {
std::vector<Triangle> toTriangles() {
std::vector<Triangle> triangles;
}
PRECISION_TYPE minX = INFINITY, minY = INFINITY, minZ = INFINITY, maxX = -INFINITY, maxY = -INFINITY, maxZ = -INFINITY;
for (face f: faces) {
Triangle t {vertices[f.v1], vertices[f.v2], vertices[f.v3],
uvs[f.uv1], uvs[f.uv2], uvs[f.uv3],
normals[f.n1], normals[f.n2], normals[f.n3]};
PRECISION_TYPE tMinX = INFINITY, tMinY = INFINITY, tMinZ = INFINITY, tMaxX = -INFINITY, tMaxY = -INFINITY, tMaxZ = -INFINITY;
// find the min and max of all the triangles
tMinX = std::min(t.vertex1.x(), std::min(t.vertex2.x(), std::min(t.vertex3.x(), tMinX)));
tMinY = std::min(t.vertex1.y(), std::min(t.vertex2.y(), std::min(t.vertex3.y(), tMinY)));
tMinZ = std::min(t.vertex1.z(), std::min(t.vertex2.z(), std::min(t.vertex3.z(), tMinZ)));
tMaxX = std::max(t.vertex1.x(), std::max(t.vertex2.x(), std::max(t.vertex3.x(), tMaxX)));
tMaxY = std::max(t.vertex1.y(), std::max(t.vertex2.y(), std::max(t.vertex3.y(), tMaxY)));
tMaxZ = std::max(t.vertex1.z(), std::max(t.vertex2.z(), std::max(t.vertex3.z(), tMaxZ)));
// create a AABB for model local BVH
t.aabb = {tMinX, tMinY, tMinZ, tMaxX, tMaxY, tMaxZ};
// and of course for a model AABB,
minX = std::min(tMinX, minX);
minY = std::min(tMinY, minY);
minZ = std::min(tMinZ, minZ);
maxX = std::max(tMaxX, maxX);
maxY = std::max(tMaxY, maxY);
maxZ = std::max(tMaxZ, maxZ);
triangles.push_back(t);
}
// to generate a AABB
aabb = {minX, minY, minZ, maxX, maxY, maxZ};
return triangles;
}
};
class ModelLoader {

View File

@ -79,6 +79,19 @@ namespace Raytracing {
});
return str.str();
}
// taken from https://stackoverflow.com/questions/14265581/parse-split-a-string-in-c-using-string-delimiter-standard-c
// extended to return a vector
static inline std::vector<std::string> split(std::string s, const std::string& delim){
size_t pos = 0;
std::vector<std::string> tokens;
while ((pos = s.find(delim)) != std::string::npos) {
auto token = s.substr(0, pos);
tokens.push_back(token);
s.erase(0, pos + delim.length());
}
tokens.push_back(s);
return tokens;
}
// taken from https://stackoverflow.com/questions/216823/how-to-trim-an-stdstring
// would've preferred to use boost lib but instructions said to avoid external libs
// trim from start (in place)

View File

@ -9,78 +9,42 @@
#include <util/std.h>
#include <math/vectors.h>
#include <util/models.h>
#include <math/bvh.h>
#include <types.h>
#include <utility>
namespace Raytracing {
struct HitData {
// all the other values only matter if this is true
bool hit{false};
// the hit point on the object
vec4 hitPoint{};
// the normal of that hit point
vec4 normal{};
// the length of the vector from its origin in its direction.
PRECISION_TYPE length{0};
};
struct ScatterResults {
// returns true to recast the ray with the provided ray
bool scattered;
// the new ray to be cast if scattered
Ray newRay;
// the color of the material
vec4 attenuationColor;
};
class Material {
private:
// most materials will need an albedo
vec4 baseColor;
public:
explicit Material(const vec4& baseColor): baseColor(baseColor) {}
// returns true if the ray was scattered along with the scattered ray, otherwise will return false with empty ray.
// the returned vec4 is the attenuation color
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const = 0;
[[nodiscard]] vec4 getBaseColor() const { return baseColor; }
};
class Object {
private:
Material* material;
public:
explicit Object(Material* material): material(material) {};
// return true if the ray intersects with this object, only between min and max
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const = 0;
Material* getMaterial() { return material; }
virtual ~Object() = default;
};
class SphereObject : public Object {
private:
vec4 position;
PRECISION_TYPE radius;
public:
SphereObject(const vec4& position, PRECISION_TYPE radius, Material* material): position(position), radius(radius), Object(material) {}
SphereObject(const vec4& position, PRECISION_TYPE radius, Material* material): radius(radius), Object(material, position) {}
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const;
};
class TriangleObject : public Object {
private:
vec4 position;
Triangle theTriangle;
public:
TriangleObject(const vec4& position, Triangle theTriangle, Material* material): Object(material), position(position),
TriangleObject(const vec4& position, Triangle theTriangle, Material* material): Object(material, position),
theTriangle(std::move(theTriangle)) {}
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const;
};
class ModelObject : public Object {
private:
std::vector<Triangle> triangles;
public:
ModelObject(const vec4& position, ModelData data, Material* material): Object(material, position) {
triangles = data.toTriangles();
this->aabb = data.aabb;
}
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const;
};
class DiffuseMaterial : public Material {
private:
public:

8
Step 2/src/globals.cpp Normal file
View File

@ -0,0 +1,8 @@
/*
* Created by Brett Terpstra 6920201 on 17/10/22.
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*/
// Yes, globals are bad.
namespace Raytracing {
}

View File

@ -46,11 +46,14 @@ int main(int argc, char** args) {
Raytracing::Image image(445, 256);
Raytracing::Camera camera(140, image);
camera.setPosition({0, 0, 0});
camera.setPosition({0, 0, 1});
//camera.lookAt(Raytracing::vec4(0,1,0), Raytracing::vec4(0, 0, -1), Raytracing::vec4(0, 1, 0));
Raytracing::World world;
Raytracing::OBJLoader loader;
Raytracing::ModelData testData = loader.loadModel("spider.obj");
world.addMaterial("greenDiffuse", new Raytracing::DiffuseMaterial{Raytracing::vec4{0, 1.0, 0, 1}});
world.addMaterial("redDiffuse", new Raytracing::DiffuseMaterial{Raytracing::vec4{1.0, 0, 0, 1}});
world.addMaterial("blueDiffuse", new Raytracing::DiffuseMaterial{Raytracing::vec4{0, 0, 1.0, 1}});
@ -59,11 +62,12 @@ int main(int argc, char** args) {
world.addMaterial("redMetal", new Raytracing::BrushedMetalMaterial{Raytracing::vec4{1.0, 0.4, 0.4, 1}, 0.6f});
world.addMaterial("blueMetal", new Raytracing::MetalMaterial{Raytracing::vec4{0.4, 0.4, 1.0, 1}});
world.add(new Raytracing::SphereObject(Raytracing::vec4(0,0,-1,0), 0.5, world.getMaterial("redDiffuse")));
world.add(new Raytracing::SphereObject(Raytracing::vec4(-1,0,-1,0), 0.5, world.getMaterial("blueMetal")));
world.add(new Raytracing::SphereObject(Raytracing::vec4(1,0,-1,0), 0.5, world.getMaterial("redMetal")));
world.add(new Raytracing::SphereObject(Raytracing::vec4(0,-100.5,-1,0), 100, world.getMaterial("greenDiffuse")));
world.add(new Raytracing::TriangleObject(Raytracing::vec4(0,0.1,-0.5f,0), {{-0.5, -0.5, 0.0}, {0.5, -0.5, 0.0}, {0.0, 0.5, 0.0}}, world.getMaterial("greenDiffuse")));
//world.add(new Raytracing::SphereObject(Raytracing::vec4(0,0,-1,0), 0.5, world.getMaterial("redDiffuse")));
//world.add(new Raytracing::SphereObject(Raytracing::vec4(-1,0,-1,0), 0.5, world.getMaterial("blueMetal")));
//world.add(new Raytracing::SphereObject(Raytracing::vec4(1,0,-1,0), 0.5, world.getMaterial("redMetal")));
//world.add(new Raytracing::SphereObject(Raytracing::vec4(0,-100.5,-1,0), 100, world.getMaterial("greenDiffuse")));
//world.add(new Raytracing::TriangleObject(Raytracing::vec4(0,0.1,-0.5f,0), {{-0.5, -0.5, 0.0}, {0.5, -0.5, 0.0}, {0.0, 0.5, 0}}, world.getMaterial("greenDiffuse")));
world.add(new Raytracing::ModelObject({0, 0, -1}, testData, world.getMaterial("redDiffuse")));
Raytracing::Raycaster raycaster {camera, image, world, parser};

View File

@ -0,0 +1,64 @@
/*
* Created by Brett Terpstra 6920201 on 17/10/22.
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*/
#include <math/colliders.h>
namespace Raytracing {
PRECISION_TYPE AABB::longestDistanceFromCenter() const {
vec4 center = getCenter();
PRECISION_TYPE maxX = std::abs(max.x() - center.x());
PRECISION_TYPE minX = std::abs(min.x() - center.x());
PRECISION_TYPE maxY = std::abs(max.y() - center.y());
PRECISION_TYPE minY = std::abs(min.y() - center.y());
PRECISION_TYPE maxZ = std::abs(max.z() - center.z());
PRECISION_TYPE minZ = std::abs(min.z() - center.z());
return std::max(maxX, std::max(minX, std::max(maxY, std::max(minY, std::max(maxZ, minZ)))));
}
PRECISION_TYPE AABB::avgDistanceFromCenter() const {
vec4 center = getCenter();
PRECISION_TYPE maxX = std::abs(max.x() - center.x());
PRECISION_TYPE minX = std::abs(min.x() - center.x());
PRECISION_TYPE maxY = std::abs(max.y() - center.y());
PRECISION_TYPE minY = std::abs(min.y() - center.y());
PRECISION_TYPE maxZ = std::abs(max.z() - center.z());
PRECISION_TYPE minZ = std::abs(min.z() - center.z());
maxX *= maxX;
minX *= minX;
maxY *= maxY;
minY *= minY;
maxZ *= maxZ;
minZ *= minZ;
return std::sqrt(maxX + minX + maxY + minY + maxZ + minZ);
}
int AABB::longestAxis() const {
PRECISION_TYPE X = std::abs(max.x() - min.x());
PRECISION_TYPE Y = std::abs(max.y() - min.y());
PRECISION_TYPE Z = std::abs(max.z() - min.z());
return X > Y && X > Z ? 0 : Y > Z ? 1 : 2;
}
PRECISION_TYPE AABB::longestAxisLength() const {
PRECISION_TYPE X = std::abs(max.x() - min.x());
PRECISION_TYPE Y = std::abs(max.y() - min.y());
PRECISION_TYPE Z = std::abs(max.z() - min.z());
return X > Y && X > Z ? X : Y > Z ? Y : Z;
}
std::vector<AABB> AABB::splitByLongestAxis() const {
PRECISION_TYPE X = std::abs(max.x() - min.x());
PRECISION_TYPE Y = std::abs(max.y() - min.y());
PRECISION_TYPE Z = std::abs(max.z() - min.z());
if (X > Y && X > Z) {
PRECISION_TYPE x2 = X/2.0;
} else if (Y > Z) {
} else {
}
}
}

View File

@ -59,6 +59,7 @@ namespace Raytracing {
// if the material scatters the ray, ie casts a new one,
if (scatterResults.scattered) // attenuate the recursive raycast by the material's color
return scatterResults.attenuationColor * raycast(scatterResults.newRay, depth + 1);
tlog << "Not scattered? " << object->getMaterial();
return {0,0,0};
}

View File

@ -3,8 +3,62 @@
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*/
#include <util/models.h>
#include <fstream>
#include <ios>
Raytracing::ModelData Raytracing::OBJLoader::loadModel(std::string file) {
std::ifstream modelFile;
return Raytracing::ModelData();
modelFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
modelFile.open(file);
std::stringstream modelSource;
// read the entire file into a string
modelSource << modelFile.rdbuf();
modelFile.close();
std::string modelUnprocessedSource = modelSource.str();
auto lines = String::split(modelUnprocessedSource, "\n");
ilog << "Loading of model file " << file << " complete! Now processing " << lines.size() << " lines.\n";
ModelData data;
for (const auto& line : lines){
auto spaces = String::split(line, " ");
if (line.starts_with("v ")) { // vertex
data.vertices.emplace_back(std::stof(spaces[1]), std::stof(spaces[2]), std::stof(spaces[3]));
} else if (line.starts_with("vt ")){ // uv
data.uvs.emplace_back(std::stof(spaces[1]), std::stof(spaces[2]), 0);
} else if (line.starts_with("vn ")){ // normal
data.normals.emplace_back(std::stof(spaces[1]), std::stof(spaces[2]), std::stof(spaces[3]));
} else if (line.starts_with("f ")){ // face
// we've reached the faces, we'll need to process them later.
auto t1 = String::split(spaces[1], "/");
auto t2 = String::split(spaces[2], "/");
auto t3 = String::split(spaces[3], "/");
face f {};
// obj files are 1 indexed,
// but arrays are 0 indexed,
// must be transformed.
f.v1 = std::stoi(t1[0])-1;
f.v2 = std::stoi(t2[0])-1;
f.v3 = std::stoi(t3[0])-1;
f.uv1 = std::stoi(t1[1])-1;
f.uv2 = std::stoi(t2[1])-1;
f.uv3 = std::stoi(t3[1])-1;
f.n1 = std::stoi(t1[2])-1;
f.n2 = std::stoi(t2[2])-1;
f.n3 = std::stoi(t3[2])-1;
data.faces.push_back(f);
}
}
ilog << "Completed extracting vertex data from model file " << file << "!\n";
return data;
}

View File

@ -96,8 +96,9 @@ namespace Raytracing {
return {shouldReflect, Ray{hitData.hitPoint, newRay + Raycaster::randomUnitVector() * fuzzyness}, getBaseColor()};
}
HitData TriangleObject::checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const {
static HitData checkIfTriangleGotHit(Triangle theTriangle, vec4 position, const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) {
// MöllerTrumbore intersection algorithm
// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
vec4 edge1, edge2, h, s, q;
PRECISION_TYPE a, f, u, v;
edge1 = (theTriangle.vertex2 + position) - (theTriangle.vertex1 + position);
@ -127,7 +128,8 @@ namespace Raytracing {
// ray intersects
vec4 rayIntersectionPoint = ray.along(t);
vec4 normal;
if (theTriangle.hasNormals) // TODO: deal with n2 and n3
// normal = theTriangle.findClosestNormal(rayIntersectionPoint - position);
if (theTriangle.hasNormals) // returning the closest normal is extra computation when n1 would likely be fine.
normal = theTriangle.normal1;
else {
// standard points to normal algorithm but using already computed edges
@ -138,4 +140,18 @@ namespace Raytracing {
}
return {false, vec4(), vec4(), 0};
}
HitData TriangleObject::checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const {
return checkIfTriangleGotHit(theTriangle, position, ray, min, max);
}
HitData ModelObject::checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const {
auto hResult = HitData{false, vec4(), vec4(), max};
for (const Triangle& t : triangles) {
auto cResult = checkIfTriangleGotHit(t, position, ray, min, hResult.length);
if (cResult.hit)
hResult = cResult;
}
return hResult;
}
}