init
This commit is contained in:
commit
444f800536
122 changed files with 17137 additions and 0 deletions
199
shared/UtilsMath.h
Normal file
199
shared/UtilsMath.h
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
#pragma once
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using glm::mat4;
|
||||
using glm::vec2;
|
||||
using glm::vec3;
|
||||
using glm::vec4;
|
||||
|
||||
namespace Math
|
||||
{
|
||||
static constexpr float PI = 3.14159265359f;
|
||||
static constexpr float TWOPI = 6.28318530718f;
|
||||
} // namespace Math
|
||||
|
||||
inline vec2 clampLength(const vec2& v, float maxLength)
|
||||
{
|
||||
const float l = length(v);
|
||||
|
||||
return (l > maxLength) ? normalize(v) * maxLength : v;
|
||||
}
|
||||
|
||||
struct BoundingBox {
|
||||
vec3 min_;
|
||||
vec3 max_;
|
||||
BoundingBox() = default;
|
||||
BoundingBox(const vec3& min, const vec3& max)
|
||||
: min_(glm::min(min, max))
|
||||
, max_(glm::max(min, max))
|
||||
{
|
||||
}
|
||||
BoundingBox(const vec3* points, size_t numPoints)
|
||||
{
|
||||
vec3 vmin(std::numeric_limits<float>::max());
|
||||
vec3 vmax(std::numeric_limits<float>::lowest());
|
||||
|
||||
for (size_t i = 0; i != numPoints; i++) {
|
||||
vmin = glm::min(vmin, points[i]);
|
||||
vmax = glm::max(vmax, points[i]);
|
||||
}
|
||||
min_ = vmin;
|
||||
max_ = vmax;
|
||||
}
|
||||
vec3 getSize() const { return vec3(max_[0] - min_[0], max_[1] - min_[1], max_[2] - min_[2]); }
|
||||
vec3 getCenter() const { return 0.5f * vec3(max_[0] + min_[0], max_[1] + min_[1], max_[2] + min_[2]); }
|
||||
void transform(const glm::mat4& t)
|
||||
{
|
||||
vec3 corners[] = {
|
||||
vec3(min_.x, min_.y, min_.z), vec3(min_.x, max_.y, min_.z), vec3(min_.x, min_.y, max_.z), vec3(min_.x, max_.y, max_.z),
|
||||
vec3(max_.x, min_.y, min_.z), vec3(max_.x, max_.y, min_.z), vec3(max_.x, min_.y, max_.z), vec3(max_.x, max_.y, max_.z),
|
||||
};
|
||||
for (auto& v : corners)
|
||||
v = vec3(t * vec4(v, 1.0f));
|
||||
*this = BoundingBox(corners, 8);
|
||||
}
|
||||
BoundingBox getTransformed(const glm::mat4& t) const
|
||||
{
|
||||
BoundingBox b = *this;
|
||||
b.transform(t);
|
||||
return b;
|
||||
}
|
||||
void combinePoint(const vec3& p)
|
||||
{
|
||||
min_ = glm::min(min_, p);
|
||||
max_ = glm::max(max_, p);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> T clamp(T v, T a, T b)
|
||||
{
|
||||
if (v < a)
|
||||
return a;
|
||||
if (v > b)
|
||||
return b;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline float random01()
|
||||
{
|
||||
return (float)rand() / (float)RAND_MAX;
|
||||
}
|
||||
|
||||
inline float randomFloat(float min, float max)
|
||||
{
|
||||
return min + (max - min) * random01();
|
||||
}
|
||||
|
||||
inline vec3 randomVec(const vec3& min, const vec3& max)
|
||||
{
|
||||
return vec3(randomFloat(min.x, max.x), randomFloat(min.y, max.y), randomFloat(min.z, max.z));
|
||||
}
|
||||
|
||||
inline vec3 randVec()
|
||||
{
|
||||
return randomVec(vec3(-5, -5, -5), vec3(5, 5, 5));
|
||||
}
|
||||
|
||||
inline void getFrustumPlanes(mat4 viewProj, vec4* planes)
|
||||
{
|
||||
viewProj = glm::transpose(viewProj);
|
||||
planes[0] = vec4(viewProj[3] + viewProj[0]); // left
|
||||
planes[1] = vec4(viewProj[3] - viewProj[0]); // right
|
||||
planes[2] = vec4(viewProj[3] + viewProj[1]); // bottom
|
||||
planes[3] = vec4(viewProj[3] - viewProj[1]); // top
|
||||
planes[4] = vec4(viewProj[3] + viewProj[2]); // near
|
||||
planes[5] = vec4(viewProj[3] - viewProj[2]); // far
|
||||
}
|
||||
|
||||
inline void getFrustumCorners(mat4 viewProj, vec4* points)
|
||||
{
|
||||
const vec4 corners[] = { vec4(-1, -1, -1, 1), vec4(1, -1, -1, 1), vec4(1, 1, -1, 1), vec4(-1, 1, -1, 1),
|
||||
vec4(-1, -1, 1, 1), vec4(1, -1, 1, 1), vec4(1, 1, 1, 1), vec4(-1, 1, 1, 1) };
|
||||
|
||||
const glm::mat4 invViewProj = glm::inverse(viewProj);
|
||||
|
||||
for (int i = 0; i != 8; i++) {
|
||||
const vec4 q = invViewProj * corners[i];
|
||||
points[i] = q / q.w;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool isBoxInFrustum(glm::vec4* frustumPlanes, glm::vec4* frustumCorners, const BoundingBox& box)
|
||||
{
|
||||
using glm::dot;
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int r = 0;
|
||||
r += (dot(frustumPlanes[i], vec4(box.min_.x, box.min_.y, box.min_.z, 1.0f)) < 0.0) ? 1 : 0;
|
||||
r += (dot(frustumPlanes[i], vec4(box.max_.x, box.min_.y, box.min_.z, 1.0f)) < 0.0) ? 1 : 0;
|
||||
r += (dot(frustumPlanes[i], vec4(box.min_.x, box.max_.y, box.min_.z, 1.0f)) < 0.0) ? 1 : 0;
|
||||
r += (dot(frustumPlanes[i], vec4(box.max_.x, box.max_.y, box.min_.z, 1.0f)) < 0.0) ? 1 : 0;
|
||||
r += (dot(frustumPlanes[i], vec4(box.min_.x, box.min_.y, box.max_.z, 1.0f)) < 0.0) ? 1 : 0;
|
||||
r += (dot(frustumPlanes[i], vec4(box.max_.x, box.min_.y, box.max_.z, 1.0f)) < 0.0) ? 1 : 0;
|
||||
r += (dot(frustumPlanes[i], vec4(box.min_.x, box.max_.y, box.max_.z, 1.0f)) < 0.0) ? 1 : 0;
|
||||
r += (dot(frustumPlanes[i], vec4(box.max_.x, box.max_.y, box.max_.z, 1.0f)) < 0.0) ? 1 : 0;
|
||||
if (r == 8)
|
||||
return false;
|
||||
}
|
||||
|
||||
// check frustum outside/inside box
|
||||
int r = 0;
|
||||
r = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
r += ((frustumCorners[i].x > box.max_.x) ? 1 : 0);
|
||||
if (r == 8)
|
||||
return false;
|
||||
r = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
r += ((frustumCorners[i].x < box.min_.x) ? 1 : 0);
|
||||
if (r == 8)
|
||||
return false;
|
||||
r = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
r += ((frustumCorners[i].y > box.max_.y) ? 1 : 0);
|
||||
if (r == 8)
|
||||
return false;
|
||||
r = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
r += ((frustumCorners[i].y < box.min_.y) ? 1 : 0);
|
||||
if (r == 8)
|
||||
return false;
|
||||
r = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
r += ((frustumCorners[i].z > box.max_.z) ? 1 : 0);
|
||||
if (r == 8)
|
||||
return false;
|
||||
r = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
r += ((frustumCorners[i].z < box.min_.z) ? 1 : 0);
|
||||
if (r == 8)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline BoundingBox combineBoxes(const std::vector<BoundingBox>& boxes)
|
||||
{
|
||||
std::vector<vec3> allPoints;
|
||||
allPoints.reserve(boxes.size() * 8);
|
||||
|
||||
for (const auto& b : boxes) {
|
||||
allPoints.emplace_back(b.min_.x, b.min_.y, b.min_.z);
|
||||
allPoints.emplace_back(b.min_.x, b.min_.y, b.max_.z);
|
||||
allPoints.emplace_back(b.min_.x, b.max_.y, b.min_.z);
|
||||
allPoints.emplace_back(b.min_.x, b.max_.y, b.max_.z);
|
||||
|
||||
allPoints.emplace_back(b.max_.x, b.min_.y, b.min_.z);
|
||||
allPoints.emplace_back(b.max_.x, b.min_.y, b.max_.z);
|
||||
allPoints.emplace_back(b.max_.x, b.max_.y, b.min_.z);
|
||||
allPoints.emplace_back(b.max_.x, b.max_.y, b.max_.z);
|
||||
}
|
||||
|
||||
return BoundingBox(allPoints.data(), allPoints.size());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue