Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Johannes Braun
glare
Commits
4257c19c
Commit
4257c19c
authored
Aug 18, 2017
by
Johannes Braun
Browse files
Played around a wee bit.
parent
2fa06238
Changes
11
Hide whitespace changes
Inline
Side-by-side
src/executables/just_testing/dat/some_tree.cpp
0 → 100644
View file @
4257c19c
#include
"some_tree.h"
\ No newline at end of file
src/executables/just_testing/dat/some_tree.h
0 → 100644
View file @
4257c19c
#ifndef INCLUDE_SOME_TREE_H
#define INCLUDE_SOME_TREE_H
#include
<functional>
#include
<memory>
#include
<vector>
#include
<core/numeric/geometry.h>
template
<
typename
T
>
struct
some_locality_tree
{
using
converter
=
std
::
function
<
math
::
Bounds
(
const
T
&
src
)
>
;
enum
class
node_type
:
uint32_t
{
eRoot
=
0
,
eLeaf
,
eInner
};
struct
node
{
int32_t
parent
=
-
1
;
node_type
type
;
int32_t
left
;
int32_t
right
;
int32_t
data_index
;
int32_t
bounds_index
;
uint32_t
cost
;
};
some_locality_tree
(
converter
bounds_from_data
)
:
m_converter
(
bounds_from_data
),
m_depth
(
0
)
{
}
void
put
(
const
T
&
data
)
{
auto
index
=
m_data_storage
.
size
();
m_data_storage
.
push_back
(
data
);
if
(
m_node_storage
.
empty
())
{
node
n
;
n
.
type
=
node_type
::
eRoot
;
n
.
data_index
=
0
;
n
.
cost
=
0
;
m_node_storage
.
emplace_back
();
n
.
bounds_index
=
m_bounds_storage
.
size
();
m_bounds_storage
.
push_back
(
m_converter
(
data
));
m_depth
=
1
;
return
;
}
// when adding a node... check if inside the whole bb
const
auto
bounds
=
m_converter
(
data
);
m_bounds_storage
.
push_back
(
bounds
);
auto
current_id
=
0
;
unsigned
depth
=
0
;
while
(
m_node_storage
[
current_id
].
type
!=
node_type
::
eLeaf
&&
m_node_storage
.
size
()
>
1
)
{
// decide which child is being overlapped the most
auto
cv_l
=
m_converter
(
get_bounds_from_dyn
(
m_node_storage
[
m_node_storage
[
current_id
].
left
]));
auto
cv_r
=
m_converter
(
get_bounds_from_dyn
(
m_node_storage
[
m_node_storage
[
current_id
].
right
]));
auto
cost_l
=
m_node_storage
[
m_node_storage
[
current_id
].
left
].
cost
;
auto
cost_r
=
m_node_storage
[
m_node_storage
[
current_id
].
right
].
cost
;
auto
l
=
cv_l
.
overlap
(
bounds
);
auto
r
=
cv_r
.
overlap
(
bounds
);
bool
pred
=
(
l
!=
0
&&
r
!=
0
)
?
(
l
/
float
(
cost_l
)
>
r
/
float
(
cost_r
))
:
((
l
==
0
&&
r
!=
0
)
?
false
:
((
l
!=
0
&&
r
==
0
)
?
true
:
(
cost_l
<
cost_r
)));
if
(
pred
)
{
++
(
m_node_storage
[
m_node_storage
[
current_id
].
left
].
cost
);
current_id
=
m_node_storage
[
current_id
].
left
;
}
else
{
++
(
m_node_storage
[
m_node_storage
[
current_id
].
right
].
cost
);
current_id
=
m_node_storage
[
current_id
].
right
;
}
++
depth
;
}
if
(
depth
>=
m_depth
)
m_depth
=
depth
+
1
;
//copy old node!
node
old_node
=
m_node_storage
[
current_id
];
auto
old_parent
=
old_node
.
parent
;
old_node
.
parent
=
current_id
;
old_node
.
type
=
node_type
::
eLeaf
;
node
new_node
;
new_node
.
type
=
node_type
::
eLeaf
;
new_node
.
data_index
=
index
;
new_node
.
parent
=
current_id
;
new_node
.
bounds_index
=
m_bounds_storage
.
size
()
-
1
;
// now being at a leaf node.
// create a parent, attach the leaf to it.
auto
old_bounds
=
m_converter
(
get_from
(
old_node
));
int
sizing
=
0
;
auto
center_old
=
old_bounds
.
center
();
auto
center_new
=
bounds
.
center
();
for
(
auto
i
=
0
;
i
<
3
;
++
i
)
{
if
(
center_old
[
i
]
<
center_new
[
i
])
++
sizing
;
}
auto
node_id_left
=
m_node_storage
.
size
()
+
(
sizing
>=
2
?
0
:
1
);
auto
node_id_right
=
m_node_storage
.
size
()
+
(
sizing
>=
2
?
1
:
0
);
m_node_storage
.
push_back
(
sizing
>=
2
?
old_node
:
new_node
);
m_node_storage
.
push_back
(
sizing
>=
2
?
new_node
:
old_node
);
node
new_parent
;
new_parent
.
parent
=
old_parent
;
new_parent
.
left
=
node_id_left
;
new_parent
.
right
=
node_id_right
;
new_parent
.
type
=
old_parent
==
-
1
?
node_type
::
eRoot
:
node_type
::
eInner
;
old_bounds
.
expand
(
bounds
);
math
::
Bounds
new_bounds
=
old_bounds
;
new_parent
.
bounds_index
=
m_bounds_storage
.
size
();
m_bounds_storage
.
push_back
(
new_bounds
);
if
(
new_parent
.
type
!=
node_type
::
eRoot
)
{
auto
c_id
=
new_parent
.
parent
;
while
(
true
)
{
auto
&&
data
=
get_bounds_from_dyn
(
m_node_storage
[
c_id
]);
data
.
expand
(
old_bounds
);
if
(
m_node_storage
[
c_id
].
type
==
node_type
::
eRoot
)
break
;
c_id
=
m_node_storage
[
c_id
].
parent
;
}
}
m_node_storage
[
current_id
]
=
new_parent
;
}
const
T
&
get_from
(
const
node
&
n
)
{
return
m_data_storage
[
n
.
data_index
];
}
unsigned
depth
()
const
{
return
m_depth
;
}
private:
math
::
Bounds
&
get_bounds_from_dyn
(
const
node
&
n
)
{
return
m_bounds_storage
[
n
.
bounds_index
];
}
unsigned
m_depth
;
converter
m_converter
;
std
::
vector
<
node
>
m_node_storage
;
std
::
vector
<
math
::
Bounds
>
m_bounds_storage
;
std
::
vector
<
T
>
m_data_storage
;
};
#endif // !INCLUDE_SOME_TREE_H
src/executables/just_testing/main.cpp
View file @
4257c19c
#include
<any>
#include
<vector>
#include
<algorithm>
std
::
vector
<
std
::
any
>
anystuff
;
constexpr
int
bla
()
{
return
4
;
}
#include
<array>
#include
<random>
#include
<util/log.h>
#include
<core/time.h>
#include
"dat/some_tree.h"
int
main
()
{
anystuff
.
push_back
(
std
::
make_any
<
int
>
(
10
));
some_locality_tree
<
math
::
Bounds
>
loctree
([](
const
auto
&
x
)
{
return
x
;
});
const
static
auto
rnd_bounds
=
[]()
{
std
::
random_device
dev
;
std
::
mt19937
gen
(
dev
());
std
::
uniform_real_distribution
<
float
>
dst
(
-
100.
f
,
100.
f
);
auto
v1
=
glm
::
vec4
(
dst
(
gen
),
dst
(
gen
),
dst
(
gen
),
1
);
auto
v2
=
glm
::
vec4
(
dst
(
gen
),
dst
(
gen
),
dst
(
gen
),
1
);
return
math
::
Bounds
{
glm
::
min
(
v1
,
v2
),
glm
::
max
(
v1
,
v2
)
};
};
constexpr
auto
x
=
4000
;
std
::
array
<
math
::
Bounds
,
x
>
bounds
;
std
::
vector
<
math
::
Bounds
>
test
;
for
(
auto
i
=
0
;
i
<
x
;
++
i
)
{
bounds
[
i
]
=
rnd_bounds
();
}
glare
::
core
::
ClockNS
clocky
;
clocky
.
restart
();
//test.reserve(10000);
for
(
int
i
=
0
;
i
<
x
;
++
i
)
{
test
.
insert
(
test
.
begin
(),
bounds
[
i
]);
}
Log_Info
<<
"Took "
<<
clocky
.
time
();
for
(
auto
&&
b
:
bounds
)
loctree
.
put
(
b
);
Log_Info
<<
sizeof
(
int
*
);
bool
b
=
true
;
system
(
"pause"
);
}
\ No newline at end of file
src/libraries/core/base/framebuffer.h
View file @
4257c19c
...
...
@@ -22,10 +22,9 @@ namespace glare::core
class
Framebuffer
{
public:
static
constexpr
bool
is_multisampled
=
texture_color_type
::
is_multisampled
;
// The type of texture used for color attachments
using
texture_color_type
=
TTextureBase
<
gl
::
TextureFormat
::
eRGBA
,
gl
::
TextureInternalFormat
::
eRGBA32Float
,
gl
::
Type
::
eFloat
>
;
static
constexpr
bool
is_multisampled
=
texture_color_type
::
is_multisampled
;
// The type of texture used for the depth attachment
using
texture_depth_type
=
TTextureBase
<
gl
::
TextureFormat
::
eDepthComponent
,
gl
::
TextureInternalFormat
::
eDepthComponent32Float
,
gl
::
Type
::
eFloat
>
;
...
...
src/libraries/core/numeric/geometry.cpp
View file @
4257c19c
...
...
@@ -171,12 +171,24 @@ namespace math
float
Bounds
::
overlap
(
const
math
::
Bounds
&
other
)
const
{
const
auto
calc_overlap
=
[
this
,
&
other
](
int
axis
)
{
return
glm
::
max
(
0.
f
,
glm
::
min
(
max
[
axis
],
other
.
max
[
axis
])
-
glm
::
max
(
min
[
axis
],
other
.
min
[
axis
]));
};
return
calc_overlap
(
0
)
*
calc_overlap
(
1
)
*
calc_overlap
(
2
);
}
bool
Bounds
::
contains
(
glm
::
vec4
point
)
const
{
return
point
.
x
>=
min
.
x
&&
point
.
y
>=
min
.
y
&&
point
.
z
>=
min
.
z
&&
point
.
x
<=
max
.
x
&&
point
.
y
<=
max
.
y
&&
point
.
z
<=
max
.
z
;
}
bool
Bounds
::
contains
(
const
math
::
Bounds
&
other
)
const
{
return
contains
(
other
.
min
)
&&
contains
(
other
.
max
);
}
unsigned
Bounds
::
largestAxis
()
const
{
const
float
max
=
glm
::
compMax
(
size
());
...
...
src/libraries/core/numeric/geometry.h
View file @
4257c19c
...
...
@@ -99,6 +99,8 @@ namespace math
Bounds
()
=
default
;
bool
contains
(
glm
::
vec4
point
)
const
;
bool
contains
(
const
math
::
Bounds
&
other
)
const
;
float
overlap
(
const
math
::
Bounds
&
other
)
const
;
unsigned
largestAxis
()
const
;
bool
splittable
()
const
;
glm
::
vec4
size
()
const
;
...
...
src/libraries/raytrace/intersect.cpp
View file @
4257c19c
...
...
@@ -39,4 +39,176 @@ namespace glare::raytrace
return
false
;
}
bool
intersect
::
intersects
(
const
Ray
&
ray
,
const
math
::
Bounds
&
bounds
,
float
max_t
)
{
const
glm
::
vec3
dirfrac
=
1.0
f
/
glm
::
vec3
(
ray
.
direction
.
xyz
);
//intersections with box planes parallel to x, y, z axis
const
float
t1
=
(
bounds
.
min
.
x
-
ray
.
origin
.
x
)
*
dirfrac
.
x
;
const
float
t3
=
(
bounds
.
min
.
y
-
ray
.
origin
.
y
)
*
dirfrac
.
y
;
const
float
t5
=
(
bounds
.
min
.
z
-
ray
.
origin
.
z
)
*
dirfrac
.
z
;
const
float
t2
=
(
bounds
.
max
.
x
-
ray
.
origin
.
x
)
*
dirfrac
.
x
;
const
float
t4
=
(
bounds
.
max
.
y
-
ray
.
origin
.
y
)
*
dirfrac
.
y
;
const
float
t6
=
(
bounds
.
max
.
z
-
ray
.
origin
.
z
)
*
dirfrac
.
z
;
const
float
tmin
=
glm
::
max
(
glm
::
max
(
glm
::
min
(
t1
,
t2
),
glm
::
min
(
t3
,
t4
)),
glm
::
min
(
t5
,
t6
));
const
float
tmax
=
glm
::
min
(
glm
::
min
(
glm
::
max
(
t1
,
t2
),
glm
::
max
(
t3
,
t4
)),
glm
::
max
(
t5
,
t6
));
return
tmax
>=
0
&&
tmin
<=
tmax
&&
tmin
<=
max_t
;
}
bool
intersect
::
intersects
(
const
Ray
&
ray
,
const
math
::
Triangle
&
triangle
,
float
&
t
,
float
&
u
,
float
&
v
)
{
const
float
epsilon
=
std
::
numeric_limits
<
float
>::
epsilon
();
const
glm
::
vec3
v1
=
triangle
.
a
.
xyz
;
const
glm
::
vec3
v2
=
triangle
.
b
.
xyz
;
const
glm
::
vec3
v3
=
triangle
.
c
.
xyz
;
//Find vectors for two edges sharing V1
glm
::
vec3
e1
=
v2
-
v1
;
glm
::
vec3
e2
=
v3
-
v1
;
//Begin calculating determinant - also used to calculate u parameter
glm
::
vec3
P
=
glm
::
cross
(
glm
::
vec3
(
ray
.
direction
.
xyz
),
e2
);
//if determinant is near zero, ray lies in plane of triangle
float
det
=
glm
::
dot
(
e1
,
P
);
//NOT CULLING
if
(
det
>
-
epsilon
&&
det
<
epsilon
)
return
false
;
float
inv_det
=
1.
f
/
det
;
//calculate distance from V1 to ray origin
glm
::
vec3
T
=
ray
.
origin
.
xyz
-
v1
;
//Calculate u parameter and test bound
u
=
glm
::
dot
(
T
,
P
)
*
inv_det
;
//The intersection lies outside of the triangle
if
(
u
<
0.
f
||
u
>
1.
f
)
return
false
;
//Prepare to test v parameter
glm
::
vec3
Q
=
cross
(
T
,
e1
);
//Calculate V parameter and test bound
v
=
glm
::
dot
(
glm
::
vec3
(
ray
.
direction
.
xyz
),
Q
)
*
inv_det
;
//The intersection lies outside of the triangle
if
(
v
<
0.
f
||
u
+
v
>
1.
f
)
return
false
;
t
=
glm
::
dot
(
e2
,
Q
)
*
inv_det
;
if
(
t
>
epsilon
)
{
//ray intersection
return
true
;
}
// No hit, no win
return
false
;
}
bool
intersect
::
intersects
(
const
math
::
Bounds
&
bounds
,
const
math
::
Triangle
&
c_triangle
)
{
return
intersects
(
c_triangle
,
bounds
);
}
bool
intersect
::
intersects
(
const
math
::
Triangle
&
c_triangle
,
const
math
::
Bounds
&
bounds
)
{
// SAT: Separating Axis Theorem
// Two convex polyhedra A and B are disjoint, if they can be separated along either an axis parallel to a normal of a face of either A or B,
// or along an Axis formed from the cross product of an edge from A widh an edge from B.
// ------------------------------------------------------------------------------------------------------------------------------------------
// 1) Project triangle points on x, y and z min and max plane normals. Quit if disjoint.
// 2) Project AABB points on triangle normal. Quit if disjoint.
// ------------------------------------------------------------------------------------------------------------------------------------------
// Projection procedure: Calculate vector cp from plane center (eg x max = bounds.max-vec3(0, half[y], half[z])) to triangle point.
// Then check dot(cp, plane_normal) < 0.
math
::
Triangle
triangle
=
c_triangle
;
const
glm
::
vec3
bounds_halfsize
=
bounds
.
size
().
xyz
*
0.5
f
;
sortTriangleLongestAxis
(
triangle
);
// --------------------------------------- NEEDED ----------------------------------------------------
float
sidedness_max
;
float
sidedness_min
;
int
i
;
// ---------------------------------------------------------------------------------------------------
// --------------------------------------- X AXIS ----------------------------------------------------
// Check separating min and max planes on x-plane
glm
::
vec3
plane_max
=
bounds
.
max
.
xyz
-
glm
::
vec3
(
0
,
bounds_halfsize
[
1
],
bounds_halfsize
[
2
]);
glm
::
vec3
plane_min
=
bounds
.
min
.
xyz
+
glm
::
vec3
(
0
,
bounds_halfsize
[
1
],
bounds_halfsize
[
2
]);
bool
separate_min
=
true
;
bool
separate_max
=
true
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
sidedness_max
=
glm
::
dot
(
triangle
[
i
].
xyz
-
plane_max
,
glm
::
vec3
(
1
,
0
,
0
));
sidedness_min
=
glm
::
dot
(
triangle
[
i
].
xyz
-
plane_min
,
glm
::
vec3
(
-
1
,
0
,
0
));
//separate is true, if all sidedness values are >1.
separate_max
&=
sidedness_max
>
0
;
separate_min
&=
sidedness_min
>
0
;
}
if
(
separate_min
||
separate_max
)
return
false
;
// ---------------------------------------------------------------------------------------------------
// --------------------------------------- Y AXIS ----------------------------------------------------
// Check separating min and max planes on y-plane
plane_max
=
bounds
.
max
.
xyz
-
glm
::
vec3
(
bounds_halfsize
[
0
],
0
,
bounds_halfsize
[
2
]);
plane_min
=
bounds
.
min
.
xyz
+
glm
::
vec3
(
bounds_halfsize
[
0
],
0
,
bounds_halfsize
[
2
]);
separate_min
=
true
;
separate_max
=
true
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
sidedness_max
=
glm
::
dot
(
triangle
[
i
].
xyz
-
plane_max
,
glm
::
vec3
(
0
,
1
,
0
));
sidedness_min
=
glm
::
dot
(
triangle
[
i
].
xyz
-
plane_min
,
glm
::
vec3
(
0
,
-
1
,
0
));
//separate is true, if all sidedness values are >1.
separate_max
&=
sidedness_max
>
0
;
separate_min
&=
sidedness_min
>
0
;
}
if
(
separate_min
||
separate_max
)
return
false
;
// ---------------------------------------------------------------------------------------------------
// --------------------------------------- Z AXIS ----------------------------------------------------
// Check separating min and max planes on z-plane
plane_max
=
bounds
.
max
.
xyz
-
glm
::
vec3
(
bounds_halfsize
[
0
],
bounds_halfsize
[
1
],
0
);
plane_min
=
bounds
.
min
.
xyz
+
glm
::
vec3
(
bounds_halfsize
[
0
],
bounds_halfsize
[
1
],
0
);
separate_min
=
true
;
separate_max
=
true
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
sidedness_max
=
glm
::
dot
(
triangle
[
i
].
xyz
-
plane_max
,
glm
::
vec3
(
0
,
0
,
1
));
sidedness_min
=
glm
::
dot
(
triangle
[
i
].
xyz
-
plane_min
,
glm
::
vec3
(
0
,
0
,
-
1
));
//separate is true, if all sidedness values are >1.
separate_max
&=
sidedness_max
>
0
;
separate_min
&=
sidedness_min
>
0
;
}
if
(
separate_min
||
separate_max
)
return
false
;
// ---------------------------------------------------------------------------------------------------
// -------------------------------------- TRIANGLE ---------------------------------------------------
// Check separating from triangle
const
glm
::
vec3
normal
=
triangle
.
normal
().
xyz
;
separate_min
=
true
;
separate_max
=
true
;
for
(
int
sign
:
{
-
1
,
1
})
{
for
(
i
=
-
1
;
i
<
3
;
i
++
)
{
glm
::
vec3
corner
=
bounds
[(
sign
+
1
)
/
2
].
xyz
;
if
(
i
>=
0
)
{
corner
[
i
]
+=
2
*
sign
*
bounds_halfsize
[
i
];
}
sidedness_min
=
glm
::
dot
(
corner
-
triangle
.
a
.
xyz
,
normal
);
separate_min
&=
sidedness_min
<
0
;
separate_max
&=
sidedness_min
>
0
;
}
}
if
(
separate_min
||
separate_max
)
return
false
;
// ---------------------------------------------------------------------------------------------------
return
true
;
}
}
\ No newline at end of file
src/libraries/raytrace/intersect.h
View file @
4257c19c
...
...
@@ -9,28 +9,14 @@
namespace
glare
::
raytrace
{
/**
* Class containing all intersection tests between objects as template functions.
*/
class
intersect
{
public:
/**
* @brief Template function for intersecting an object from type One to one from type Other.
* @tparam One One intersection candidate type.
* @tparam Other The other intersection candidate type.
*/
template
<
typename
One
,
typename
Other
>
static
bool
intersects
(
const
One
&
one
,
const
Other
&
other
)
{
return
false
;
}
template
<
>
static
bool
intersect
::
intersects
<
math
::
Bounds
,
math
::
Triangle
>
(
const
math
::
Bounds
&
bounds
,
const
math
::
Triangle
&
c_triangle
);
template
<
>
static
bool
intersect
::
intersects
<
math
::
Triangle
,
math
::
Bounds
>
(
const
math
::
Triangle
&
c_triangle
,
const
math
::
Bounds
&
bounds
);
static
bool
intersects
(
const
math
::
Bounds
&
bounds
,
const
math
::
Triangle
&
c_triangle
);
static
bool
intersects
(
const
math
::
Triangle
&
c_triangle
,
const
math
::
Bounds
&
bounds
);
static
bool
intersects
(
const
Ray
&
ray
,
const
math
::
Bounds
&
bounds
,
float
max_t
);
static
bool
intersects
(
const
Ray
&
ray
,
const
math
::
Triangle
&
triangle
,
float
&
t
,
float
&
u
,
float
&
v
);
...
...
@@ -49,181 +35,6 @@ namespace glare::raytrace
if
(
b
[
axis
]
<
c
[
axis
])
std
::
swap
(
b
,
c
);
if
(
a
[
axis
]
<
b
[
axis
])
std
::
swap
(
a
,
b
);
}
inline
bool
intersect
::
intersects
(
const
Ray
&
ray
,
const
math
::
Bounds
&
bounds
,
float
max_t
)
{
const
glm
::
vec3
dirfrac
=
1.0
f
/
glm
::
vec3
(
ray
.
direction
.
xyz
);
//intersections with box planes parallel to x, y, z axis
const
float
t1
=
(
bounds
.
min
.
x
-
ray
.
origin
.
x
)
*
dirfrac
.
x
;
const
float
t3
=
(
bounds
.
min
.
y
-
ray
.
origin
.
y
)
*
dirfrac
.
y
;
const
float
t5
=
(
bounds
.
min
.
z
-
ray
.
origin
.
z
)
*
dirfrac
.
z
;
const
float
t2
=
(
bounds
.
max
.
x
-
ray
.
origin
.
x
)
*
dirfrac
.
x
;
const
float
t4
=
(
bounds
.
max
.
y
-
ray
.
origin
.
y
)
*
dirfrac
.
y
;
const
float
t6
=
(
bounds
.
max
.
z
-
ray
.
origin
.
z
)
*
dirfrac
.
z
;
const
float
tmin
=
glm
::
max
(
glm
::
max
(
glm
::
min
(
t1
,
t2
),
glm
::
min
(
t3
,
t4
)),
glm
::
min
(
t5
,
t6
));
const
float
tmax
=
glm
::
min
(
glm
::
min
(
glm
::
max
(
t1
,
t2
),
glm
::
max
(
t3
,
t4
)),
glm
::
max
(
t5
,
t6
));
return
tmax
>=
0
&&
tmin
<=
tmax
&&
tmin
<=
max_t
;
}
inline
bool
intersect
::
intersects
(
const
Ray
&
ray
,
const
math
::
Triangle
&
triangle
,
float
&
t
,
float
&
u
,
float
&
v
)
{
const
float
epsilon
=
std
::
numeric_limits
<
float
>::
epsilon
();
const
glm
::
vec3
v1
=
triangle
.
a
.
xyz
;
const
glm
::
vec3
v2
=
triangle
.
b
.
xyz
;
const
glm
::
vec3
v3
=
triangle
.
c
.
xyz
;
//Find vectors for two edges sharing V1
glm
::
vec3
e1
=
v2
-
v1
;
glm
::
vec3
e2
=
v3
-
v1
;
//Begin calculating determinant - also used to calculate u parameter
glm
::
vec3
P
=
glm
::
cross
(
glm
::
vec3
(
ray
.
direction
.
xyz
),
e2
);
//if determinant is near zero, ray lies in plane of triangle
float
det
=
glm
::
dot
(
e1
,
P
);
//NOT CULLING
if
(
det
>
-
epsilon
&&
det
<
epsilon
)
return
false
;
float
inv_det
=
1.
f
/
det
;
//calculate distance from V1 to ray origin
glm
::
vec3
T
=
ray
.
origin
.
xyz
-
v1
;
//Calculate u parameter and test bound
u
=
glm
::
dot
(
T
,
P
)
*
inv_det
;
//The intersection lies outside of the triangle
if
(
u
<
0.
f
||
u
>
1.
f
)
return
false
;
//Prepare to test v parameter
glm
::
vec3
Q
=
cross
(
T
,
e1
);
//Calculate V parameter and test bound
v
=
glm
::
dot
(
glm
::
vec3
(
ray
.
direction
.
xyz
),
Q
)
*
inv_det
;
//The intersection lies outside of the triangle
if
(
v
<
0.
f
||
u
+
v
>
1.
f
)
return
false
;
t
=
glm
::
dot
(
e2
,
Q
)
*
inv_det
;
if
(
t
>
epsilon
)
{
//ray intersection
return
true
;
}
// No hit, no win
return
false
;
}
template
<
>
inline
bool
intersect
::
intersects
<
math
::
Bounds
,
math
::
Triangle
>
(
const
math
::
Bounds
&
bounds
,
const
math
::
Triangle
&
c_triangle
)
{
return
intersects
(
c_triangle
,
bounds
);
}
template
<
>
inline
bool
intersect
::
intersects
<
math
::
Triangle
,
math
::
Bounds
>
(
const
math
::
Triangle
&
c_triangle
,
const
math
::
Bounds
&
bounds
)
{
// SAT: Separating Axis Theorem
// Two convex polyhedra A and B are disjoint, if they can be separated along either an axis parallel to a normal of a face of either A or B,
// or along an Axis formed from the cross product of an edge from A widh an edge from B.
// ------------------------------------------------------------------------------------------------------------------------------------------
// 1) Project triangle points on x, y and z min and max plane normals. Quit if disjoint.
// 2) Project AABB points on triangle normal. Quit if disjoint.
// ------------------------------------------------------------------------------------------------------------------------------------------
// Projection procedure: Calculate vector cp from plane center (eg x max = bounds.max-vec3(0, half[y], half[z])) to triangle point.
// Then check dot(cp, plane_normal) < 0.
math
::
Triangle
triangle
=
c_triangle
;
const
glm
::
vec3
bounds_halfsize
=
bounds
.
size
().
xyz
*
0.5
f
;
sortTriangleLongestAxis
(
triangle
);
// --------------------------------------- NEEDED ----------------------------------------------------
float
sidedness_max
;
float
sidedness_min
;