OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
frustrum.cpp
Go to the documentation of this file.
1#include "frustrum.h"
2
3using namespace Tempest;
4
5void Frustrum::make(const Matrix4x4& m, int32_t w, int32_t h) {
6 width = uint32_t(w);
7 height = uint32_t(h);
8 mat = m;
9
10 float clip[16] = {}, t=0;
11 std::copy(m.data(), m.data()+16, clip );
12
13 f[0][0] = clip[ 3] - clip[ 0];
14 f[0][1] = clip[ 7] - clip[ 4];
15 f[0][2] = clip[11] - clip[ 8];
16 f[0][3] = clip[15] - clip[12];
17
18 t = std::sqrt(f[0][0]*f[0][0] + f[0][1]*f[0][1] + f[0][2]*f[0][2]);
19 if(t==0)
20 return clear();
21
22 f[0][0] /= t;
23 f[0][1] /= t;
24 f[0][2] /= t;
25 f[0][3] /= t;
26
27 f[1][0] = clip[ 3] + clip[ 0];
28 f[1][1] = clip[ 7] + clip[ 4];
29 f[1][2] = clip[11] + clip[ 8];
30 f[1][3] = clip[15] + clip[12];
31
32 t = std::sqrt(f[1][0]*f[1][0] + f[1][1]*f[1][1] + f[1][2]*f[1][2]);
33 if(t==0)
34 return clear();
35
36 f[1][0] /= t;
37 f[1][1] /= t;
38 f[1][2] /= t;
39 f[1][3] /= t;
40
41 f[2][0] = clip[ 3] + clip[ 1];
42 f[2][1] = clip[ 7] + clip[ 5];
43 f[2][2] = clip[11] + clip[ 9];
44 f[2][3] = clip[15] + clip[13];
45
46 t = std::sqrt(f[2][0]*f[2][0] + f[2][1]*f[2][1] + f[2][2]*f[2][2]);
47 if(t==0)
48 return clear();
49
50 f[2][0] /= t;
51 f[2][1] /= t;
52 f[2][2] /= t;
53 f[2][3] /= t;
54
55 f[3][0] = clip[ 3] - clip[ 1];
56 f[3][1] = clip[ 7] - clip[ 5];
57 f[3][2] = clip[11] - clip[ 9];
58 f[3][3] = clip[15] - clip[13];
59
60 t = std::sqrt(f[3][0]*f[3][0] + f[3][1]*f[3][1] + f[3][2]*f[3][2]);
61 if(t==0)
62 return clear();
63
64 f[3][0] /= t;
65 f[3][1] /= t;
66 f[3][2] /= t;
67 f[3][3] /= t;
68
69 f[4][0] = clip[ 3] - clip[ 2];
70 f[4][1] = clip[ 7] - clip[ 6];
71 f[4][2] = clip[11] - clip[10];
72 f[4][3] = clip[15] - clip[14];
73
74 t = std::sqrt(f[4][0]*f[4][0] + f[4][1]*f[4][1] + f[4][2]*f[4][2]);
75 if(t==0)
76 return clear();
77
78 f[4][0] /= t;
79 f[4][1] /= t;
80 f[4][2] /= t;
81 f[4][3] /= t;
82
83 f[5][0] = clip[ 3] + clip[ 2];
84 f[5][1] = clip[ 7] + clip[ 6];
85 f[5][2] = clip[11] + clip[10];
86 f[5][3] = clip[15] + clip[14];
87
88 t = std::sqrt(f[5][0]*f[5][0] + f[5][1]*f[5][1] + f[5][2]*f[5][2]);
89 if(t==0)
90 return clear();
91
92 f[5][0] /= t;
93 f[5][1] /= t;
94 f[5][2] /= t;
95 f[5][3] /= t;
96 }
97
99 mat = Matrix4x4();
100 std::memset(f,0,sizeof(f));
101 f[0][3] = -std::numeric_limits<float>::infinity();
102 }
103
104bool Frustrum::testPoint(float x, float y, float z) const {
105 return testPoint(x,y,z,0);
106 }
107
108bool Frustrum::testPoint(float x, float y, float z, float R) const {
109 // if(std::isnan(R))
110 // return false;
111
112 for(size_t i=0; i<6; i++) {
113 if(f[i][0]*x+f[i][1]*y+f[i][2]*z+f[i][3]<=-R)
114 return false;
115 }
116 return true;
117 }
118
119bool Frustrum::testPoint(const Tempest::Vec3& p, float R) const {
120 return testPoint(p.x,p.y,p.z,R);
121 }
122
123bool Frustrum::testPoint(const Vec3& p, float R, float& dist) const {
124 for(size_t i=0; i<5; i++) {
125 if(f[i][0]*p.x+f[i][1]*p.y+f[i][2]*p.z+f[i][3]<=-R)
126 return false;
127 }
128
129 dist = f[5][0]*p.x+f[5][1]*p.y+f[5][2]*p.z+f[5][3];
130 if(dist<-R)
131 return false;
132
133 return true;
134 }
135
136Frustrum::Ret Frustrum::testBbox(const Tempest::Vec3& min, const Tempest::Vec3& max) const {
137 auto ret = Ret::T_Full;
138 for(int i=0; i<6; i++) {
139 float dmax =
140 std::max(min.x * f[i][0], max.x * f[i][0])
141 + std::max(min.y * f[i][1], max.y * f[i][1])
142 + std::max(min.z * f[i][2], max.z * f[i][2])
143 + f[i][3];
144 float dmin =
145 std::min(min.x * f[i][0], max.x * f[i][0])
146 + std::min(min.y * f[i][1], max.y * f[i][1])
147 + std::min(min.z * f[i][2], max.z * f[i][2])
148 + f[i][3];
149 if(dmax<0)
150 return Ret::T_Invisible;
151 if(dmin<0)
152 ret = Ret::T_Partial;
153 }
154 return ret;
155 }
float f[6][4]
Definition frustrum.h:22
uint32_t width
Definition frustrum.h:24
uint32_t height
Definition frustrum.h:25
bool testPoint(float x, float y, float z) const
Definition frustrum.cpp:104
@ T_Invisible
Definition frustrum.h:16
@ T_Partial
Definition frustrum.h:17
void clear()
Definition frustrum.cpp:98
void make(const Tempest::Matrix4x4 &m, int32_t w, int32_t h)
Definition frustrum.cpp:5
Tempest::Matrix4x4 mat
Definition frustrum.h:23
Ret testBbox(const Tempest::Vec3 &min, const Tempest::Vec3 &max) const
Definition frustrum.cpp:136
static T clip(T v, T low, T hi)
Definition wave.cpp:14