13 std::array<
int, 2> { 0, 1 }, std::array<
int, 2> { 1, 2 }, std::array<
int, 2> { 2, 3 }, std::array<
int, 2> { 3, 0 },
14 std::array<
int, 2> { 4, 5 }, std::array<
int, 2> { 5, 6 }, std::array<
int, 2> { 6, 7 }, std::array<
int, 2> { 7, 4 },
15 std::array<
int, 2> { 0, 4 }, std::array<
int, 2> { 1, 5 }, std::array<
int, 2> { 2, 6 }, std::array<
int, 2> { 3, 7 },
39 constexpr QColor colorBox = QColorConstants::Yellow;
50 float shortestAxisSq = (box[0] - box[1]).lengthSquared();
51 shortestAxisSq =
std::min(shortestAxisSq, (box[0] - box[4]).lengthSquared());
52 shortestAxisSq =
std::min(shortestAxisSq, (box[0] - box[3]).lengthSquared());
53 const float axisLength = qSqrt(shortestAxisSq) * 0.5f;
55 auto drawAxisLine = [&](
const QVector3D &from,
const QVector3D &to,
const QColor &axisColor) {
56 const QVector3D dir = (to - from).normalized();
57 const QVector3D mid = from + dir * axisLength;
58 debugDrawSystem->drawLine(from, mid, axisColor);
59 debugDrawSystem->drawLine(mid, to, colorBox);
65 drawAxisLine(box[0], box[1], QColorConstants::Red);
66 debugDrawSystem->drawLine(box[1], box[2], colorBox);
67 drawAxisLine(box[0], box[3], QColorConstants::Green);
68 debugDrawSystem->drawLine(box[2], box[3], colorBox);
71 drawAxisLine(box[0], box[4], QColorConstants::Blue);
72 debugDrawSystem->drawLine(box[1], box[5], colorBox);
73 debugDrawSystem->drawLine(box[2], box[6], colorBox);
74 debugDrawSystem->drawLine(box[3], box[7], colorBox);
77 debugDrawSystem->drawLine(box[4], box[5], colorBox);
78 debugDrawSystem->drawLine(box[5], box[6], colorBox);
79 debugDrawSystem->drawLine(box[6], box[7], colorBox);
80 debugDrawSystem->drawLine(box[7], box[4], colorBox);
82 debugDrawSystem->setEnabled(
true);
153 const QSSGBoxPoints &castingBox,
154 QSSGDebugDrawSystem *debugDrawSystem,
158 QList<Vertex> vertices;
159 vertices.reserve(castingBox.size());
160 for (
const auto &p : castingBox) {
163 vertices.push_back(point);
166 for (
auto line : BOX_LINE_INDICES) {
167 vertices[line[0]].addNeighbor(line[1]);
168 vertices[line[1]].addNeighbor(line[0]);
171 QList<QVector2D> planePoints;
172 QList<QPair<quint8, quint8>> lines;
173 QList<
bool> intersecting;
174 QList<quint8> newVertexIndices;
175 QList<Vertex> verticesPrev;
177 for (
const auto &plane : planes) {
178 const QVector3D center = plane[0];
179 const QVector3D normal = plane[1];
180 newVertexIndices.clear();
181 verticesPrev = vertices;
182 for (
int vertIndexI = 0, vertEnd = vertices.length(); vertIndexI < vertEnd; ++vertIndexI) {
183 Vertex vertex = vertices[vertIndexI];
188 if (QVector3D::dotProduct(vertex.position - center, normal) >= 0) {
194 vertices[vertIndexI].active =
false;
195 for (
int neighborIndex : vertex.neighbors) {
196 if (neighborIndex == -1)
198 vertices[neighborIndex].removeNeighbor(vertIndexI);
201 for (
int neighborIndex : vertex.neighbors) {
202 if (neighborIndex == -1)
205 const quint32 idx0 = vertIndexI;
206 const quint32 idx1 = neighborIndex;
209 if (QVector3D::dotProduct(vertices[idx1].position - center, normal) < 0)
212 QVector3D planePoint = center;
213 QVector3D planeNormal = normal;
214 QVector3D linePoint = vertices[idx0].position;
215 QVector3D lineDirection = vertices[idx0].position - vertices[idx1].position;
216 QSSGPlane plane(planePoint, planeNormal);
217 QSSGRenderRay ray(linePoint, lineDirection);
219 if (
auto intersect = QSSGRenderRay::intersect(plane, ray); intersect.has_value()) {
220 int addedIdx = vertices.length();
221 Q_ASSERT(addedIdx <= 255);
223 p.position = intersect.value();
225 vertices[idx1].addNeighbor(addedIdx);
226 vertices.push_back(p);
227 newVertexIndices.push_back(addedIdx);
232 if (newVertexIndices.isEmpty())
236 QMatrix4x4 transform;
239 const QVector3D forward = normal;
240 const QVector3D right = QVector3D(-forward.y(), forward.x(), 0);
241 const QVector3D up = QVector3D::crossProduct(forward, right);
242 transform.setRow(0, QVector4D(right, 0.0f));
243 transform.setRow(1, QVector4D(up, 0.0f));
244 transform.setRow(2, QVector4D(forward, 0.0f));
245 transform.setRow(3, QVector4D(0.0f, 0.0f, 0.0f, 1.0f));
248 planePoints.reserve(newVertexIndices.length());
249 for (
auto &p0 : newVertexIndices) {
250 QVector3D p = transform.map(vertices[p0].position);
251 planePoints.push_back(QVector2D(p.x(), p.y()));
257 lines.reserve((planePoints.length() * planePoints.length()) / 4);
258 for (
int i = 0, length = planePoints.length(); i < length; ++i) {
259 for (
int j = i + 1; j < length; ++j) {
260 lines.push_back({ i, j });
265 intersecting.clear();
266 intersecting.resize(lines.length(),
false);
267 for (
int i = 0, length = lines.length(); i < length; ++i) {
268 QPair<quint8, quint8> lineI = lines[i];
269 QVector2D a = planePoints[lineI.first];
270 QVector2D b = planePoints[lineI.second];
271 for (
int j = i + 1; j < length; ++j) {
272 QPair<quint8, quint8> lineJ = lines[j];
275 if (lineJ.first == lineI.first || lineJ.first == lineI.second || lineJ.second == lineI.first
276 || lineJ.second == lineI.second)
279 QVector2D c = planePoints[lineJ.first];
280 QVector2D d = planePoints[lineJ.second];
281 if (lineLineIntersection(a, b, c, d)) {
282 intersecting[i] =
true;
283 intersecting[j] =
true;
288 for (
int i = 0, length = lines.length(); i < length; ++i) {
289 if (intersecting[i]) {
293 QPair<quint8, quint8> lineI = lines[i];
294 int a = newVertexIndices[lineI.first];
295 int b = newVertexIndices[lineI.second];
296 vertices[a].addNeighbor(b);
297 vertices[b].addNeighbor(a);
301 for (
const Vertex &point : vertices) {
302 if (point.active && (point.borked || !point.allNeighbors())) {
303 vertices = verticesPrev;
309 QList<QVector3D> result;
310 result.reserve(vertices.length());
311 for (
const Vertex &vertex : vertices) {
313 result.push_back(vertex.position);
316 if (debugDrawSystem) {
317 debugDrawSystem->setEnabled(
true);
318 for (
int i = 0; i < vertices.length(); i++) {
319 Vertex point = vertices[i];
323 QVector3D position = vertices[i].position;
324 debugDrawSystem->drawLine(position, vertices[point.neighbors[0]].position, color);
325 debugDrawSystem->drawLine(position, vertices[point.neighbors[1]].position, color);
326 debugDrawSystem->drawLine(position, vertices[point.neighbors[2]].position, color);
359 const float minX = boxBounds.minimum.x();
360 const float minY = boxBounds.minimum.y();
361 const float minZ = boxBounds.minimum.z();
362 const float maxX = boxBounds.maximum.x();
363 const float maxY = boxBounds.maximum.y();
364 const float maxZ = boxBounds.maximum.z();
366 QSSGBoxPoints points;
367 points[0] = QVector3D(minX, minY, minZ);
368 points[1] = QVector3D(maxX, minY, minZ);
369 points[2] = QVector3D(maxX, maxY, minZ);
370 points[3] = QVector3D(minX, maxY, minZ);
371 points[4] = QVector3D(minX, minY, maxZ);
372 points[5] = QVector3D(maxX, minY, maxZ);
373 points[6] = QVector3D(maxX, maxY, maxZ);
374 points[7] = QVector3D(minX, maxY, maxZ);
378 static constexpr std::array<
int, 4> LEFT = { 0, 3, 7, 4 };
379 static constexpr std::array<
int, 4> TOP = { 3, 2, 6, 7 };
380 static constexpr std::array<
int, 4> BOTTOM = { 4, 5, 1, 0 };
381 static constexpr std::array<
int, 4> RIGHT = { 2, 1, 5, 6 };
382 static constexpr std::array<
std::array<
int, 4>, 4> faceIndices = { LEFT, TOP, BOTTOM, RIGHT };
384 QList<std::array<QVector3D, 2>> faces;
385 faces.resize(faceIndices.size());
386 for (
int i = 0; i <
int(faceIndices.size()); ++i) {
387 std::array<
int, 4> face = faceIndices[i];
388 QVector3D center = points[face[0]];
389 QVector3D b = points[face[1]] - points[face[0]];
390 QVector3D a = points[face[2]] - points[face[0]];
391 QVector3D n = -QVector3D::crossProduct(a, b).normalized();
392 faces[i] = { center, n };
395 return sliceBoxByPlanes(faces, box,
nullptr, QColorConstants::Black);