152 lines
3.9 KiB
C++
152 lines
3.9 KiB
C++
|
#include "Frustum.hpp"
|
||
|
#include <cmath>
|
||
|
namespace Slic3r {
|
||
|
|
||
|
void Frustum::Plane::set_abcd(float a, float b, float c, float d)
|
||
|
{
|
||
|
m_abcd[0] = a;
|
||
|
m_abcd[1] = b;
|
||
|
m_abcd[2] = c;
|
||
|
m_abcd[3] = d;
|
||
|
}
|
||
|
|
||
|
const Vec4f& Frustum::Plane::get_abcd() const
|
||
|
{
|
||
|
return m_abcd;
|
||
|
}
|
||
|
|
||
|
void Frustum::Plane::normailze()
|
||
|
{
|
||
|
float mag;
|
||
|
mag = sqrt(m_abcd[0] * m_abcd[0] + m_abcd[1] * m_abcd[1] + m_abcd[2] * m_abcd[2]);
|
||
|
m_abcd[0] = m_abcd[0] / mag;
|
||
|
m_abcd[1] = m_abcd[1] / mag;
|
||
|
m_abcd[2] = m_abcd[2] / mag;
|
||
|
m_abcd[3] = m_abcd[3] / mag;
|
||
|
}
|
||
|
|
||
|
float Frustum::Plane::distance(const Vec3f& pt) const
|
||
|
{
|
||
|
float result = 0.0f;
|
||
|
for (int i = 0; i < 3; ++i) {
|
||
|
result += pt[i] * m_abcd[i];
|
||
|
}
|
||
|
|
||
|
result += m_abcd[3];
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
Frustum::Plane::PlaneIntersects Frustum::Plane::intersects(const BoundingBoxf3 &box) const
|
||
|
{
|
||
|
// see https://cgvr.cs.uni-bremen.de/teaching/cg_literatur/lighthouse3d_view_frustum_culling/index.html
|
||
|
|
||
|
Vec3d positive_v = box.min;
|
||
|
if (m_abcd[0] > 0.f)
|
||
|
positive_v[0] = box.max.x();
|
||
|
if (m_abcd[1] > 0.f)
|
||
|
positive_v[1] = box.max.y();
|
||
|
if (m_abcd[2] > 0.f)
|
||
|
positive_v[2] = box.max.z();
|
||
|
|
||
|
float dis_positive = distance(positive_v.cast<float>());
|
||
|
if (dis_positive < 0.f)
|
||
|
{
|
||
|
return Frustum::Plane::PlaneIntersects::Intersects_Back;
|
||
|
}
|
||
|
|
||
|
Vec3d negitive_v = box.max;
|
||
|
if (m_abcd[0] > 0.f)
|
||
|
negitive_v[0] = box.min.x();
|
||
|
if (m_abcd[1] > 0.f)
|
||
|
negitive_v[1] = box.min.y();
|
||
|
if (m_abcd[2] > 0.f)
|
||
|
negitive_v[2] = box.min.z();
|
||
|
|
||
|
float dis_negitive = distance(negitive_v.cast<float>());
|
||
|
|
||
|
if (dis_negitive < 0.f)
|
||
|
{
|
||
|
return Frustum::Plane::PlaneIntersects::Intersects_Cross;
|
||
|
}
|
||
|
|
||
|
return Frustum::Plane::PlaneIntersects::Intersects_Front;
|
||
|
}
|
||
|
Frustum::Plane::PlaneIntersects Frustum::Plane::intersects(const Vec3f &p0) const
|
||
|
{
|
||
|
float d = distance(p0);
|
||
|
if (d == 0) {
|
||
|
return Plane::Intersects_Tangent;
|
||
|
}
|
||
|
return (d > 0.0f) ? Plane::Intersects_Front : Plane::Intersects_Back;
|
||
|
}
|
||
|
Frustum::Plane::PlaneIntersects Frustum::Plane::intersects(const Vec3f &p0, const Vec3f &p1) const
|
||
|
{
|
||
|
Plane::PlaneIntersects state0 = intersects(p0);
|
||
|
Plane::PlaneIntersects state1 = intersects(p1);
|
||
|
if (state0 == state1) {
|
||
|
return state0;
|
||
|
}
|
||
|
if (state0 == Plane::Intersects_Tangent || state1 == Plane::Intersects_Tangent) {
|
||
|
return Plane::Intersects_Tangent;
|
||
|
}
|
||
|
|
||
|
return Plane::Intersects_Cross;
|
||
|
}
|
||
|
Frustum::Plane::PlaneIntersects Frustum::Plane::intersects(const Vec3f &p0, const Vec3f &p1, const Vec3f &p2) const
|
||
|
{
|
||
|
Plane::PlaneIntersects state0 = intersects(p0, p1);
|
||
|
Plane::PlaneIntersects state1 = intersects(p0, p2);
|
||
|
Plane::PlaneIntersects state2 = intersects(p1, p2);
|
||
|
|
||
|
if (state0 == state1 && state0 == state2) {
|
||
|
return state0; }
|
||
|
|
||
|
if (state0 == Plane::Intersects_Cross || state1 == Plane::Intersects_Cross || state2 == Plane::Intersects_Cross) {
|
||
|
return Plane::Intersects_Cross;
|
||
|
}
|
||
|
|
||
|
return Plane::Intersects_Tangent;
|
||
|
}
|
||
|
|
||
|
bool Frustum::intersects(const BoundingBoxf3 &box) const
|
||
|
{
|
||
|
for (auto& plane : planes) {
|
||
|
const auto rt = plane.intersects(box);
|
||
|
if (Frustum::Plane::Intersects_Back == rt) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool Frustum::intersects(const Vec3f &p0) const {
|
||
|
for (auto &plane : planes) {
|
||
|
if (plane.intersects(p0) == Plane::Intersects_Back) { return false; }
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool Frustum::intersects(const Vec3f &p0, const Vec3f &p1) const
|
||
|
{
|
||
|
for (auto &plane : planes) {
|
||
|
if (plane.intersects(p0, p1) == Plane::Intersects_Back) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool Frustum::intersects(const Vec3f &p0, const Vec3f &p1, const Vec3f &p2) const
|
||
|
{
|
||
|
for (auto &plane : planes) {
|
||
|
if (plane.intersects(p0, p1, p2) == Plane::Intersects_Back) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
} // namespace Slic3r
|