This commit is contained in:
MihailRis
2024-05-06 17:35:05 +03:00
parent b3a1cad0e1
commit 3c6089225f
16 changed files with 633 additions and 638 deletions
+83 -83
View File
@@ -6,113 +6,113 @@
class Frustum
{
public:
Frustum() {};
Frustum() {};
void update(glm::mat4 projview);
bool IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const;
void update(glm::mat4 projview);
bool IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const;
private:
enum Planes
{
Left = 0,
Right,
Bottom,
Top,
Near,
Far,
Count,
Combinations = Count * (Count - 1) / 2
};
enum Planes
{
Left = 0,
Right,
Bottom,
Top,
Near,
Far,
Count,
Combinations = Count * (Count - 1) / 2
};
template<Planes i, Planes j>
struct ij2k
{
enum { k = i * (9 - i) / 2 + j - 1 };
};
template<Planes i, Planes j>
struct ij2k
{
enum { k = i * (9 - i) / 2 + j - 1 };
};
template<Planes a, Planes b, Planes c>
glm::vec3 intersection(const glm::vec3* crosses) const;
template<Planes a, Planes b, Planes c>
glm::vec3 intersection(const glm::vec3* crosses) const;
glm::vec4 m_planes[Count];
glm::vec3 m_points[8];
glm::vec4 m_planes[Count];
glm::vec3 m_points[8];
};
inline void Frustum::update(glm::mat4 m)
{
m = glm::transpose(m);
m_planes[Left] = m[3] + m[0];
m_planes[Right] = m[3] - m[0];
m_planes[Bottom] = m[3] + m[1];
m_planes[Top] = m[3] - m[1];
m_planes[Near] = m[3] + m[2];
m_planes[Far] = m[3] - m[2];
m = glm::transpose(m);
m_planes[Left] = m[3] + m[0];
m_planes[Right] = m[3] - m[0];
m_planes[Bottom] = m[3] + m[1];
m_planes[Top] = m[3] - m[1];
m_planes[Near] = m[3] + m[2];
m_planes[Far] = m[3] - m[2];
glm::vec3 crosses[Combinations] = {
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Right])),
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Bottom])),
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Top])),
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Near])),
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Far])),
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Bottom])),
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Top])),
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Near])),
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Far])),
glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Top])),
glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Near])),
glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Far])),
glm::cross(glm::vec3(m_planes[Top]), glm::vec3(m_planes[Near])),
glm::cross(glm::vec3(m_planes[Top]), glm::vec3(m_planes[Far])),
glm::cross(glm::vec3(m_planes[Near]), glm::vec3(m_planes[Far]))
};
glm::vec3 crosses[Combinations] = {
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Right])),
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Bottom])),
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Top])),
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Near])),
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Far])),
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Bottom])),
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Top])),
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Near])),
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Far])),
glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Top])),
glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Near])),
glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Far])),
glm::cross(glm::vec3(m_planes[Top]), glm::vec3(m_planes[Near])),
glm::cross(glm::vec3(m_planes[Top]), glm::vec3(m_planes[Far])),
glm::cross(glm::vec3(m_planes[Near]), glm::vec3(m_planes[Far]))
};
m_points[0] = intersection<Left, Bottom, Near>(crosses);
m_points[1] = intersection<Left, Top, Near>(crosses);
m_points[2] = intersection<Right, Bottom, Near>(crosses);
m_points[3] = intersection<Right, Top, Near>(crosses);
m_points[4] = intersection<Left, Bottom, Far>(crosses);
m_points[5] = intersection<Left, Top, Far>(crosses);
m_points[6] = intersection<Right, Bottom, Far>(crosses);
m_points[7] = intersection<Right, Top, Far>(crosses);
m_points[0] = intersection<Left, Bottom, Near>(crosses);
m_points[1] = intersection<Left, Top, Near>(crosses);
m_points[2] = intersection<Right, Bottom, Near>(crosses);
m_points[3] = intersection<Right, Top, Near>(crosses);
m_points[4] = intersection<Left, Bottom, Far>(crosses);
m_points[5] = intersection<Left, Top, Far>(crosses);
m_points[6] = intersection<Right, Bottom, Far>(crosses);
m_points[7] = intersection<Right, Top, Far>(crosses);
}
inline bool Frustum::IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const
{
// check box outside/inside of frustum
for (int i = 0; i < Count; i++)
{
if ((glm::dot(m_planes[i], glm::vec4(minp.x, minp.y, minp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(maxp.x, minp.y, minp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(minp.x, maxp.y, minp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(maxp.x, maxp.y, minp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(minp.x, minp.y, maxp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(maxp.x, minp.y, maxp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(minp.x, maxp.y, maxp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(maxp.x, maxp.y, maxp.z, 1.0f)) < 0.0))
{
return false;
}
}
// check box outside/inside of frustum
for (int i = 0; i < Count; i++)
{
if ((glm::dot(m_planes[i], glm::vec4(minp.x, minp.y, minp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(maxp.x, minp.y, minp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(minp.x, maxp.y, minp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(maxp.x, maxp.y, minp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(minp.x, minp.y, maxp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(maxp.x, minp.y, maxp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(minp.x, maxp.y, maxp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(maxp.x, maxp.y, maxp.z, 1.0f)) < 0.0))
{
return false;
}
}
// check frustum outside/inside box
int out;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].x > maxp.x) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].x < minp.x) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].y > maxp.y) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].y < minp.y) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].z > maxp.z) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].z < minp.z) ? 1 : 0); if (out == 8) return false;
// check frustum outside/inside box
int out;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].x > maxp.x) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].x < minp.x) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].y > maxp.y) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].y < minp.y) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].z > maxp.z) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].z < minp.z) ? 1 : 0); if (out == 8) return false;
return true;
return true;
}
template<Frustum::Planes a, Frustum::Planes b, Frustum::Planes c>
inline glm::vec3 Frustum::intersection(const glm::vec3* crosses) const
{
float D = glm::dot(glm::vec3(m_planes[a]), crosses[ij2k<b, c>::k]);
glm::vec3 res = glm::mat3(crosses[ij2k<b, c>::k], -crosses[ij2k<a, c>::k], crosses[ij2k<a, b>::k]) *
glm::vec3(m_planes[a].w, m_planes[b].w, m_planes[c].w);
return res * (-1.0f / D);
float D = glm::dot(glm::vec3(m_planes[a]), crosses[ij2k<b, c>::k]);
glm::vec3 res = glm::mat3(crosses[ij2k<b, c>::k], -crosses[ij2k<a, c>::k], crosses[ij2k<a, b>::k]) *
glm::vec3(m_planes[a].w, m_planes[b].w, m_planes[c].w);
return res * (-1.0f / D);
}
#endif // MATHS_FRUSTUM_CULLING_HPP_
+7 -7
View File
@@ -2,15 +2,15 @@
#define MATHS_UVREGION_HPP_
struct UVRegion {
float u1;
float v1;
float u2;
float v2;
float u1;
float v1;
float u2;
float v2;
UVRegion(float u1, float v1, float u2, float v2)
: u1(u1), v1(v1), u2(u2), v2(v2){}
UVRegion(float u1, float v1, float u2, float v2)
: u1(u1), v1(v1), u2(u2), v2(v2){}
UVRegion() : u1(0.0f), v1(0.0f), u2(1.0f), v2(1.0f){}
UVRegion() : u1(0.0f), v1(0.0f), u2(1.0f), v2(1.0f){}
};
#endif // MATHS_UVREGION_HPP_
+1 -1
View File
@@ -5,7 +5,7 @@
// Axis Aligned Bounding Box
struct AABB {
glm::vec3 a {0.0f};
glm::vec3 a {0.0f};
glm::vec3 b {1.0f};
/* Get AABB point with minimal x,y,z */
+194 -194
View File
@@ -10,249 +10,249 @@ Ray::Ray(const rayvec3& origin, const rayvec3& dir) : origin(origin), dir(dir) {
//make faces from AABB
AABBFaces::AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox){
rayvec3 pbMin = parentBox.min(), // every face is min-point and opposite corner point
pbMax = parentBox.max(),
pbRealPos = parentBoxPos + pbMin;
rayvec2 yzMax = rayvec2(parentBoxPos.y + pbMax.y, parentBoxPos.z + pbMax.z ),
xzMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.z + pbMax.z ),
xyMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.y + pbMax.y );
faces[0] = { parentBoxPos + rayvec3(pbMax.x, pbMin.y, pbMin.z), yzMax };
rayvec3 pbMin = parentBox.min(), // every face is min-point and opposite corner point
pbMax = parentBox.max(),
pbRealPos = parentBoxPos + pbMin;
rayvec2 yzMax = rayvec2(parentBoxPos.y + pbMax.y, parentBoxPos.z + pbMax.z ),
xzMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.z + pbMax.z ),
xyMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.y + pbMax.y );
faces[0] = { parentBoxPos + rayvec3(pbMax.x, pbMin.y, pbMin.z), yzMax };
faces[1] = {pbRealPos, yzMax};
faces[1] = {pbRealPos, yzMax};
faces[2] = { parentBoxPos + rayvec3(pbMin.x, pbMax.y, pbMin.z), xzMax };
faces[2] = { parentBoxPos + rayvec3(pbMin.x, pbMax.y, pbMin.z), xzMax };
faces[3] = {pbRealPos, xzMax};
faces[3] = {pbRealPos, xzMax};
faces[4] = { parentBoxPos + rayvec3(pbMin.x, pbMin.y, pbMax.z), xyMax };
faces[4] = { parentBoxPos + rayvec3(pbMin.x, pbMin.y, pbMax.z), xyMax };
faces[5] = {pbRealPos, xyMax};
faces[5] = {pbRealPos, xyMax};
}
RayRelation Ray::intersectYZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //y and z global coords of opposite corner
glm::ivec3& normal_ret,
scalar_t& distance_ret //sinonym of rayCoef
){
if (fabs(glm::dot(dir, X_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel;
}
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //y and z global coords of opposite corner
glm::ivec3& normal_ret,
scalar_t& distance_ret //sinonym of rayCoef
){
if (fabs(glm::dot(dir, X_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.x - origin.x) / (dir.x);// equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = {faceMin.x,
rayCoef*dir.y + origin.y,
rayCoef*dir.z + origin.z};
scalar_t rayCoef = (faceMin.x - origin.x) / (dir.x);// equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = {faceMin.x,
rayCoef*dir.y + origin.y,
rayCoef*dir.z + origin.z};
if (intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]){
distance_ret = rayCoef; // believe that dir normalized
if (dir.x > 0) normal_ret = -X_AXIS;
else normal_ret = X_AXIS;
return RayRelation::Intersect;
}
return RayRelation::None;
if (intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]){
distance_ret = rayCoef; // believe that dir normalized
if (dir.x > 0) normal_ret = -X_AXIS;
else normal_ret = X_AXIS;
return RayRelation::Intersect;
}
return RayRelation::None;
}
RayRelation Ray::intersectXZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //x and z global coords of opposite corner
glm::ivec3& normal_ret,
scalar_t& distance_ret
){
if (fabs(glm::dot(dir, Y_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel;
}
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //x and z global coords of opposite corner
glm::ivec3& normal_ret,
scalar_t& distance_ret
){
if (fabs(glm::dot(dir, Y_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.y - origin.y) / (dir.y);// equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef *dir.x + origin.x,
faceMin.y,
rayCoef*dir.z + origin.z};
scalar_t rayCoef = (faceMin.y - origin.y) / (dir.y);// equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef *dir.x + origin.x,
faceMin.y,
rayCoef*dir.z + origin.z};
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1] ){
distance_ret = rayCoef; // believe that dir normalized
if (dir.y > 0) normal_ret = -Y_AXIS;
else normal_ret = Y_AXIS;
return RayRelation::Intersect;
}
return RayRelation::None;
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1] ){
distance_ret = rayCoef; // believe that dir normalized
if (dir.y > 0) normal_ret = -Y_AXIS;
else normal_ret = Y_AXIS;
return RayRelation::Intersect;
}
return RayRelation::None;
}
RayRelation Ray::intersectXYFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //x and y global coords of opposite corner
glm::ivec3& normal_ret,
scalar_t& distance_ret
){
if (fabs(glm::dot(dir, Z_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.z - origin.z) / (dir.z); // equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef *dir.x + origin.x,
rayCoef*dir.y + origin.y,
faceMin.z};
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[1] ){
distance_ret = rayCoef; // believe that dir normalized
if (dir.z > 0) normal_ret = -Z_AXIS;
else normal_ret = Z_AXIS;
return RayRelation::Intersect;
}
return RayRelation::None;
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //x and y global coords of opposite corner
glm::ivec3& normal_ret,
scalar_t& distance_ret
){
if (fabs(glm::dot(dir, Z_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.z - origin.z) / (dir.z); // equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef *dir.x + origin.x,
rayCoef*dir.y + origin.y,
faceMin.z};
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[1] ){
distance_ret = rayCoef; // believe that dir normalized
if (dir.z > 0) normal_ret = -Z_AXIS;
else normal_ret = Z_AXIS;
return RayRelation::Intersect;
}
return RayRelation::None;
}
RayRelation Ray::isIntersectsYZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner
){
if (fabs(glm::dot(dir, X_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel;
}
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner
){
if (fabs(glm::dot(dir, X_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.x - origin.x) / (dir.x);
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { faceMin.x,
rayCoef * dir.y + origin.y,
rayCoef * dir.z + origin.z };
scalar_t rayCoef = (faceMin.x - origin.x) / (dir.x);
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { faceMin.x,
rayCoef * dir.y + origin.y,
rayCoef * dir.z + origin.z };
if (intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]) {
return RayRelation::Intersect;
}
return RayRelation::None;
if (intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]) {
return RayRelation::Intersect;
}
return RayRelation::None;
}
RayRelation Ray::isIntersectsXZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner
) {
if (fabs(glm::dot(dir, Y_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel;
}
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner
) {
if (fabs(glm::dot(dir, Y_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.y - origin.y) / (dir.y);
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef * dir.x + origin.x,
faceMin.y,
rayCoef * dir.z + origin.z };
scalar_t rayCoef = (faceMin.y - origin.y) / (dir.y);
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef * dir.x + origin.x,
faceMin.y,
rayCoef * dir.z + origin.z };
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]) {
return RayRelation::Intersect;
}
return RayRelation::None;
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]) {
return RayRelation::Intersect;
}
return RayRelation::None;
}
RayRelation Ray::isIntersectsXYFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner
) {
if (fabs(glm::dot(dir, Z_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel;
}
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner
) {
if (fabs(glm::dot(dir, Z_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.z - origin.z) / (dir.z);
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef * dir.x + origin.x,
rayCoef * dir.y + origin.y,
faceMin.z };
scalar_t rayCoef = (faceMin.z - origin.z) / (dir.z);
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef * dir.x + origin.x,
rayCoef * dir.y + origin.y,
faceMin.z };
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[1]) {
return RayRelation::Intersect;
}
return RayRelation::None;
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[1]) {
return RayRelation::Intersect;
}
return RayRelation::None;
}
RayRelation Ray::intersectAABB(
const rayvec3& boxPos,
const AABB& box,
float maxDist,
const AABB& box,
float maxDist,
glm::ivec3& normal_ret,
scalar_t& distance_ret){
const AABBFaces& boxFaces = AABBFaces(boxPos, box);
return intersectAABBFaces(boxFaces, maxDist, normal_ret, distance_ret);
scalar_t& distance_ret){
const AABBFaces& boxFaces = AABBFaces(boxPos, box);
return intersectAABBFaces(boxFaces, maxDist, normal_ret, distance_ret);
}
RayRelation Ray::intersectAABBFaces(
const AABBFaces& boxFaces,
float maxDist,
float maxDist,
glm::ivec3& normal_ret,
scalar_t& distance_ret){
scalar_t& distance_ret){
scalar_t faceDist;
distance_ret = maxDist;
glm::ivec3 bufNormal;
//unsigned char intersectedCount = 0; //this code is very uncomfortable, DONT LEARN IT!
bool isIntersect = false;
scalar_t faceDist;
distance_ret = maxDist;
glm::ivec3 bufNormal;
//unsigned char intersectedCount = 0; //this code is very uncomfortable, DONT LEARN IT!
bool isIntersect = false;
if (intersectYZFace(
boxFaces.faces[0].first, boxFaces.faces[0].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret){
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectYZFace(
boxFaces.faces[0].first, boxFaces.faces[0].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret){
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectYZFace(
boxFaces.faces[1].first, boxFaces.faces[1].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectYZFace(
boxFaces.faces[1].first, boxFaces.faces[1].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXZFace(
boxFaces.faces[2].first, boxFaces.faces[2].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXZFace(
boxFaces.faces[2].first, boxFaces.faces[2].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXZFace(
boxFaces.faces[3].first, boxFaces.faces[3].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXZFace(
boxFaces.faces[3].first, boxFaces.faces[3].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXYFace(
boxFaces.faces[4].first, boxFaces.faces[4].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXYFace(
boxFaces.faces[4].first, boxFaces.faces[4].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXYFace(
boxFaces.faces[5].first, boxFaces.faces[5].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (isIntersect) return RayRelation::Intersect;
return RayRelation::None;
if (intersectXYFace(
boxFaces.faces[5].first, boxFaces.faces[5].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (isIntersect) return RayRelation::Intersect;
return RayRelation::None;
}
+43 -43
View File
@@ -17,61 +17,61 @@ enum class RayRelation {
};
class AABBFaces {
static const unsigned char AABBFACES_COUNT = 6;
static const unsigned char AABBFACES_COUNT = 6;
public:
std::array<std::pair<rayvec3, rayvec2>, AABBFACES_COUNT> faces; // every face is min-point and opposite corner point
std::array<std::pair<rayvec3, rayvec2>, AABBFACES_COUNT> faces; // every face is min-point and opposite corner point
AABBFaces(){};
AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox);
AABBFaces(){};
AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox);
};
class Ray {
public:
rayvec3 origin;
rayvec3 dir;
rayvec3 origin;
rayvec3 dir;
Ray(const rayvec3& rayOrigin,
const rayvec3& rayDir);
Ray(const rayvec3& rayOrigin,
const rayvec3& rayDir);
RayRelation isIntersectsYZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner);
RayRelation isIntersectsXZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner);
RayRelation isIntersectsXYFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner);
RayRelation isIntersectsYZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner);
RayRelation isIntersectsXZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner);
RayRelation isIntersectsXYFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner);
///returns normal and distance
RayRelation intersectYZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectXZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectXYFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectYZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectXZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectXYFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectAABB(
const rayvec3& boxPos,
const AABB& box,
float maxDist,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectAABB(
const rayvec3& boxPos,
const AABB& box,
float maxDist,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectAABBFaces( // calculates only normal and distance
const AABBFaces& boxFaces,
float maxDist,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectAABBFaces( // calculates only normal and distance
const AABBFaces& boxFaces,
float maxDist,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
};
#endif // SRC_VOXNATHS_HPP_
+16 -16
View File
@@ -4,48 +4,48 @@
#include "../typedefs.hpp"
inline int floordiv(int a, int b) {
if (a < 0 && a % b) {
return (a / b) - 1;
}
return a / b;
if (a < 0 && a % b) {
return (a / b) - 1;
}
return a / b;
}
inline int ceildiv(int a, int b) {
if (a > 0 && a % b) {
return a / b + 1;
}
return a / b;
if (a > 0 && a % b) {
return a / b + 1;
}
return a / b;
}
inline int max(int a, int b) {
return (a > b) ? a : b;
return (a > b) ? a : b;
}
inline int min(int a, int b) {
return (a < b) ? a : b;
return (a < b) ? a : b;
}
inline int64_t max(int64_t a, int64_t b) {
return (a > b) ? a : b;
return (a > b) ? a : b;
}
inline int64_t min(int64_t a, int64_t b) {
return (a < b) ? a : b;
return (a < b) ? a : b;
}
static unsigned int g_seed;
inline void fast_srand(int seed) {
g_seed = seed;
g_seed = seed;
}
inline int fast_rand(void) {
g_seed = (214013 * g_seed + 2531011);
return (g_seed >> 16) & 0x7FFF;
g_seed = (214013 * g_seed + 2531011);
return (g_seed >> 16) & 0x7FFF;
}
inline light_t light_pack(ubyte r, ubyte g, ubyte b, ubyte s) {
return r | (g << 4) | (b << 8) | (s << 12);
return r | (g << 4) | (b << 8) | (s << 12);
}
#endif // VOXNATHS_HPP_