4 #include <GLFW\glfw3.h>
7 #include <glm\gtc\matrix_transform.hpp>
8 #include <glm\gtc\type_ptr.hpp>
11 #include <unordered_set>
18 std::vector
<glm::vec3
> vertices
;
20 BrushPolygon(Plane p
) :
26 bool IntersectNgon(glm::vec3 orig
, glm::vec3 dir
,
30 if (polygon
.vertices
.size() < 3)
33 glm::vec3 N
= polygon
.plane
.normal
;
38 float NdotRayDir
= glm::dot(N
, dir
);
39 if (glm::abs(NdotRayDir
) < 1e-3)
43 *t
= -(glm::dot(N
, orig
) + polygon
.plane
.offset
) / NdotRayDir
;
44 //Check if triangle is behind the ray
45 if (*t
< 0) return false;
47 glm::vec3 P
= orig
+ ((*t
) * dir
);
49 glm::vec3 C
, edge
, vp
;
52 for (int i
= 0; i
< polygon
.vertices
.size(); i
++)
54 glm::vec3 v0
= polygon
.vertices
[i
];
55 glm::vec3 v1
= i
+ 1 == polygon
.vertices
.size() ? polygon
.vertices
[0] : polygon
.vertices
[i
+ 1];
59 C
= glm::cross(edge
, vp
);
60 if (glm::dot(N
, C
) < 0) {
69 bool IntersectTriangle(glm::vec3 orig
, glm::vec3 dir
,
70 glm::vec3 v0
, glm::vec3 v1
, glm::vec3 v2
, glm::vec3 norm
,
78 float NdotRayDir
= glm::dot(N
, dir
);
79 if (glm::abs(NdotRayDir
) < 1e-4)
82 float d
= glm::dot(N
, v0
);
85 *t
= -(glm::dot(N
, orig
) + d
) / NdotRayDir
;
86 //Check if triangle is behind the ray
87 if (*t
< 0) return false;
89 glm::vec3 P
= orig
+ ((*t
) * dir
);
91 glm::vec3 C
, edge
, vp
;
96 C
= glm::cross(edge
, vp
);
97 if (glm::dot(N
, C
) < 0) return false;
101 C
= glm::cross(edge
, vp
);
102 if (glm::dot(N
, C
) < 0) return false;
106 C
= glm::cross(edge
, vp
);
107 if (glm::dot(N
, C
) < 0) return false;
112 std::vector
<float> IntersectMesh(glm::vec3 orig
, glm::vec3 dir
, Mesh
* mesh
)
114 std::vector
<float> ret
;
115 for (int i
= 0; i
< mesh
->vertices
.size() / 18; i
++)
117 glm::vec3 v0
= glm::vec3(mesh
->vertices
[i
* 18 + 0], mesh
->vertices
[i
* 18 + 1], mesh
->vertices
[i
* 18 + 2]);
118 glm::vec3 n0
= glm::vec3(mesh
->vertices
[i
* 18 + 3], mesh
->vertices
[i
* 18 + 4], mesh
->vertices
[i
* 18 + 5]);
119 glm::vec3 v1
= glm::vec3(mesh
->vertices
[i
* 18 + 6], mesh
->vertices
[i
* 18 + 7], mesh
->vertices
[i
* 18 + 8]);
120 glm::vec3 n1
= glm::vec3(mesh
->vertices
[i
* 18 + 9], mesh
->vertices
[i
* 18 + 10], mesh
->vertices
[i
* 18 + 11]);
121 glm::vec3 v2
= glm::vec3(mesh
->vertices
[i
* 18 + 12], mesh
->vertices
[i
* 18 + 13], mesh
->vertices
[i
* 18 + 14]);
122 glm::vec3 n2
= glm::vec3(mesh
->vertices
[i
* 18 + 15], mesh
->vertices
[i
* 18 + 16], mesh
->vertices
[i
* 18 + 17]);
125 if (ray::IntersectTriangle(orig
, dir
, v0
, v1
, v2
, n0
, &dist
))
136 Mesh
* GeneratedMesh
;
138 std::vector
<BrushPolygon
> ngons
;
139 std::vector
<float> meshData
;
144 Polytope(std::vector
<Plane
> planes
, bool gen_gl_mesh
= true, bool dbg
= false)
146 std::vector
<glm::vec3
> intersecting
;
148 //Set up polygon structure
149 for (int i
= 0; i
< planes
.size(); i
++) {
150 this->ngons
.push_back(BrushPolygon(planes
[i
]));
153 // Do plane intersections
154 for (int i
= 0; i
< planes
.size(); i
++) {
155 for (int j
= 0; j
< planes
.size(); j
++) {
156 for (int k
= 0; k
< planes
.size(); k
++) {
157 if (i
== j
|| i
== k
|| j
== k
) continue; //Skip invalid checks
159 glm::vec3
p(0, 0, 0);
161 if (!Plane::FinalThreePlaneIntersection(planes
[i
], planes
[j
], planes
[k
], &p
)) { continue; };
164 //Check if point is outside object
165 for (int m
= 0; m
< planes
.size(); m
++)
167 if (Plane::EvalPointPolarity(planes
[m
], p
) < -0.01f
)
174 if (!valid
) continue;
176 intersecting
.push_back(p
);
179 this->ngons
[i
].vertices
.push_back(p
);
180 this->ngons
[j
].vertices
.push_back(p
);
181 this->ngons
[k
].vertices
.push_back(p
);
186 std::vector
<float> generatedMesh
;
188 float x
= this->ngons
[0].vertices
[0].x
;
189 float _x
= this->ngons
[0].vertices
[0].x
;
190 float y
= this->ngons
[0].vertices
[0].y
;
191 float _y
= this->ngons
[0].vertices
[0].y
;
192 float z
= this->ngons
[0].vertices
[0].z
;
193 float _z
= this->ngons
[0].vertices
[0].z
;
195 //Remove polygon vertex duplicates
196 for (int i
= 0; i
< this->ngons
.size(); i
++) {
198 std::vector
<glm::vec3
> newlist
;
200 //Cleanup and find bounds
202 for (int j
= 0; j
< this->ngons
[i
].vertices
.size(); j
++)
206 for (int k
= 0; k
< newlist
.size(); k
++)
208 if (glm::distance(newlist
[k
], this->ngons
[i
].vertices
[j
]) < 0.5f
) //Throw out dupe points (within half a unit)
216 newlist
.push_back(this->ngons
[i
].vertices
[j
]);
218 x
= this->ngons
[i
].vertices
[j
].x
> x
? this->ngons
[i
].vertices
[j
].x
: x
;
219 _x
= this->ngons
[i
].vertices
[j
].x
< _x
? this->ngons
[i
].vertices
[j
].x
: _x
;
221 y
= this->ngons
[i
].vertices
[j
].y
> y
? this->ngons
[i
].vertices
[j
].y
: y
;
222 _y
= this->ngons
[i
].vertices
[j
].y
< _y
? this->ngons
[i
].vertices
[j
].y
: _y
;
224 z
= this->ngons
[i
].vertices
[j
].z
> z
? this->ngons
[i
].vertices
[j
].z
: z
;
225 _z
= this->ngons
[i
].vertices
[j
].z
< _z
? this->ngons
[i
].vertices
[j
].z
: _z
;
228 this->ngons
[i
].vertices
= newlist
;
231 if (this->ngons
[i
].vertices
.size() < 3)
234 std::vector
<glm::vec3
> points
= Plane::OrderCoplanarClockWise(this->ngons
[i
].plane
, this->ngons
[i
].vertices
);
235 this->ngons
[i
].vertices
= points
;
236 for (int j
= 0; j
< points
.size() - 2; j
++) {
237 glm::vec3 a
= points
[0];
238 glm::vec3 b
= points
[j
+ 1];
239 glm::vec3 c
= points
[j
+ 2];
241 generatedMesh
.push_back(-a
.x
);
242 generatedMesh
.push_back(a
.z
);
243 generatedMesh
.push_back(a
.y
);
245 generatedMesh
.push_back(this->ngons
[i
].plane
.normal
.x
);
246 generatedMesh
.push_back(-this->ngons
[i
].plane
.normal
.z
);
247 generatedMesh
.push_back(-this->ngons
[i
].plane
.normal
.y
);
250 generatedMesh
.push_back(-b
.x
);
251 generatedMesh
.push_back(b
.z
);
252 generatedMesh
.push_back(b
.y
);
254 generatedMesh
.push_back(this->ngons
[i
].plane
.normal
.x
);
255 generatedMesh
.push_back(-this->ngons
[i
].plane
.normal
.z
);
256 generatedMesh
.push_back(-this->ngons
[i
].plane
.normal
.y
);
259 generatedMesh
.push_back(-c
.x
);
260 generatedMesh
.push_back(c
.z
);
261 generatedMesh
.push_back(c
.y
);
263 generatedMesh
.push_back(this->ngons
[i
].plane
.normal
.x
);
264 generatedMesh
.push_back(-this->ngons
[i
].plane
.normal
.z
);
265 generatedMesh
.push_back(-this->ngons
[i
].plane
.normal
.y
);
269 NWU
= glm::vec3(-_x
, z
, y
);
270 SEL
= glm::vec3(-x
, _z
, _y
);
272 this->meshData
= generatedMesh
;
276 Mesh
* m
= new Mesh(generatedMesh
, MeshMode::POS_XYZ_NORMAL_XYZ
);
277 this->GeneratedMesh
= m
;