Files
tyra-linux/engine/src/physics/ray.cpp
T
2022-08-14 17:37:55 -03:00

103 lines
2.5 KiB
C++

/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022-2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Wellinator Carvalho <wellcoj@gmail.com>
*/
#include "physics/ray.hpp"
#include <tamtypes.h>
#include <math.h>
#include <algorithm>
#include <sstream>
#include <iomanip>
namespace Tyra {
Ray::Ray() {}
Ray::Ray(const Vec4& t_origin, const Vec4& t_direction) {
origin.set(t_origin);
direction.set(t_direction);
}
Ray::~Ray() {}
Vec4 Ray::at(const float& t) const { return (direction * t) + origin; }
float Ray::distanceToPoint(const Vec4& point) const {
return origin.distanceTo(point);
}
bool Ray::intersectBox(const Vec4& minCorner, const Vec4& maxCorner,
float* outputDistance) const {
Vec4 _min = (minCorner - this->origin) / this->invDir();
Vec4 _max = (minCorner - this->origin) / this->invDir();
float tmin =
std::max(std::max(std::min(_min.x, _max.x), std::min(_min.y, _max.y)),
std::min(_min.z, _max.z));
float tmax =
std::min(std::min(std::max(_min.x, _max.x), std::max(_min.y, _max.y)),
std::max(_min.z, _max.z));
// if tmax < 0, ray (line) is intersecting AABB, but whole AABB is behing us
if (tmax < 0) {
if (outputDistance != nullptr) {
*outputDistance = -1.0f;
}
return false;
}
// if tmin > tmax, ray doesn't intersect AABB
if (tmin > tmax) {
if (outputDistance != nullptr) {
*outputDistance = -1.0f;
}
return false;
}
if (tmin < 0) {
if (outputDistance != nullptr) {
*outputDistance = tmax;
}
return true;
}
if (outputDistance != nullptr) {
*outputDistance = tmin;
}
return true;
}
Vec4 Ray::invDir() const {
return Vec4(1 / this->direction.x, 1 / this->direction.y,
1 / this->direction.z, 1);
}
void Ray::print() const {
auto text = getPrint(nullptr);
printf("%s\n", text.c_str());
}
void Ray::print(const char* name) const {
auto text = getPrint(name);
printf("%s\n", text.c_str());
}
std::string Ray::getPrint(const char* name) const {
std::stringstream res;
if (name) {
res << name << "(";
} else {
res << "Ray(";
}
res << std::fixed << std::setprecision(4);
res << origin.getPrint("origin") << ", " << direction.getPrint("direction")
<< ")";
return res.str();
}
} // Namespace Tyra