4 #include <GLFW\glfw3.h>
7 #include <glm\gtc\matrix_transform.hpp>
8 #include <glm\gtc\type_ptr.hpp>
21 //Plane defined by three points
22 Plane(glm::vec3 P
, glm::vec3 Q
, glm::vec3 R
) {
23 glm::vec3 n
= glm::cross(P
- Q
, P
- R
); //Calculate normal
24 //float d = ((P.x * n.x + P.y * n.y + P.z * n.z) / glm::length(n)); //Calculate distance
26 float d
= glm::dot(glm::normalize(n
), P
);
29 this->normal
= glm::normalize(n
);
34 Plane(glm::vec3 normal
, float offset
) {
35 this->offset
= offset
;
36 this->normal
= normal
;
39 //Standard constructor (generic floor plane)
42 this->normal
= glm::vec3(0, 0, 1);
48 static bool ThreePlaneIntersection(Plane p1
, Plane p2
, Plane p3
, glm::vec3
* p
) {
49 float det
= glm::dot(glm::cross(p1
.normal
, p2
.normal
), p3
.normal
);
51 float epsilon
= 1e-5f
; //Epsilon value for floating point error
53 if (det
< epsilon
&& det
> -epsilon
) { return false; };
55 *p
= (-(p1
.offset
* glm::cross(p2
.normal
, p3
.normal
)) -
56 (p2
.offset
* glm::cross(p3
.normal
, p1
.normal
)) -
57 (p3
.offset
* glm::cross(p1
.normal
, p2
.normal
))) / det
;
61 static bool FinalThreePlaneIntersection(Plane p1
, Plane p2
, Plane p3
, glm::vec3
* p
) {
62 float det
= glm::dot(glm::cross(p1
.normal
, p2
.normal
), p3
.normal
);
63 float epsilon
= 1e-5f
; //Epsilon value for floating point error
65 if (det
< epsilon
&& det
> -epsilon
) { return false; };
67 *p
= -(-p1
.offset
* glm::cross(p2
.normal
, p3
.normal
)
68 - p2
.offset
* glm::cross(p3
.normal
, p1
.normal
)
69 - p3
.offset
* glm::cross(p1
.normal
, p2
.normal
))
70 / glm::dot(p1
.normal
, glm::cross(p2
.normal
, p3
.normal
));
76 p = (-adist(Cross(bnorm, cnorm))
77 -bdist(Cross(cnorm, anorm))
78 -cdist(Cross(anorm, bnorm)))
79 / Dot(anorm, Cross(bnorm, cnorm))
85 static bool GetTripleIntersection(Plane p1
, Plane p2
, Plane p3
, glm::vec3
* p
) {
86 float determinant
= glm::determinant(glm::mat3
{ p1
.normal
.x
, p2
.normal
.x
, p3
.normal
.x
,
87 p1
.normal
.y
, p2
.normal
.y
, p3
.normal
.y
,
88 p1
.normal
.z
, p2
.normal
.z
, p3
.normal
.z
});
90 float epsilon
= 1e-5f
; //Check within small epsilon to prevent infinite values
91 if (determinant
< epsilon
&& determinant
> -epsilon
) return false;
93 glm::vec3 point
= (glm::cross(p2
.normal
, p3
.normal
) * -p1
.offset
+
94 glm::cross(p3
.normal
, p1
.normal
) * -p2
.offset
+
95 glm::cross(p1
.normal
, p2
.normal
) * -p3
.offset
) / determinant
;
110 //Detects which side of the plane the point is on (-): negative, (~0): coplanar, (+): positive
111 static float EvalPointPolarity(Plane plane
, glm::vec3 p1
) {
112 return glm::dot(p1
, plane
.normal
) - //Evaluate dot & plane normal
113 glm::dot(plane
.normal
* plane
.offset
, plane
.normal
); //Compare to known point & plane normal (closest point to 0,0,0 is normal*offset)
116 //Determines clockwise-ness of point B in relation to point A with respect to center point C
117 static float CompareClockWiseNess(Plane plane
, glm::vec3 C
, glm::vec3 A
, glm::vec3 B
) {
118 return glm::dot(plane
.normal
, glm::cross(A
- C
, B
- C
));
121 static std::vector
<glm::vec3
> OrderCoplanarClockWise(Plane plane
, std::vector
<glm::vec3
> Points
) {
122 //Find center point (avarage distribution of points)
123 glm::vec3
center(0, 0, 0);
124 for (int i
= 0; i
< Points
.size(); i
++) {
127 center
/= Points
.size();
129 glm::vec3 ref
= Points
[0] - center
;
131 std::vector
<glm::vec4
> angledVecs
;
134 for (int i
= 0; i
< Points
.size(); i
++) {
135 glm::vec3 diff
= Points
[i
] - center
;
136 float ang
= atan2(glm::length(glm::cross(diff
, ref
)), glm::dot(diff
, ref
));
138 float sign
= glm::dot(glm::cross(diff
, ref
), plane
.normal
) < 0 ? -1.0f
: 1.0f
;
141 angledVecs
.push_back(glm::vec4(Points
[i
].x
, Points
[i
].y
, Points
[i
].z
, ang
));
146 bool modified
= false;
148 for (int i
= 0; i
< Points
.size() - 1; i
++)
150 int s0
= i
; int s1
= i
+ 1;
152 glm::vec4 a
= angledVecs
[s0
]; glm::vec4 b
= angledVecs
[s1
];
156 angledVecs
[s0
] = b
; angledVecs
[s1
] = a
;
160 if (!modified
) break;
163 for (int i
= 0; i
< Points
.size(); i
++)
165 Points
[i
] = glm::vec3(angledVecs
[i
].x
, angledVecs
[i
].y
, angledVecs
[i
].z
);
171 static void InPlaceOrderCoplanarClockWise(Plane plane
, std::vector
<glm::vec3
>* Points
){
172 if (Points
->size() == 0) return;
174 //Find center point (avarage distribution of points)
175 glm::vec3
center(0, 0, 0);
176 for (int i
= 0; i
< Points
->size(); i
++) {
177 center
+= (*Points
)[i
];
179 center
/= Points
->size();
181 glm::vec3 ref
= (*Points
)[0] - center
;
183 std::vector
<glm::vec4
> angledVecs
;
185 for (int i
= 0; i
< Points
->size(); i
++) {
186 glm::vec3 diff
= (*Points
)[i
] - center
;
187 float ang
= atan2(glm::length(glm::cross(diff
, ref
)), glm::dot(diff
, ref
));
189 float sign
= glm::dot(glm::cross(diff
, ref
), plane
.normal
) < 0 ? -1.0f
: 1.0f
;
192 angledVecs
.push_back(glm::vec4((*Points
)[i
].x
, (*Points
)[i
].y
, (*Points
)[i
].z
, ang
));
196 bool modified
= false;
198 for (int i
= 0; i
< Points
->size() - 1; i
++){
199 int s0
= i
; int s1
= i
+ 1;
201 glm::vec4 a
= angledVecs
[s0
]; glm::vec4 b
= angledVecs
[s1
];
204 angledVecs
[s0
] = b
; angledVecs
[s1
] = a
;
208 if (!modified
) break;
211 for (int i
= 0; i
< Points
->size(); i
++){
212 (*Points
)[i
] = glm::vec3(angledVecs
[i
].x
, angledVecs
[i
].y
, angledVecs
[i
].z
);