20 auto boxGeometry =
new QQuick3DGeometry();
22 boxGeometry->addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0,
23 QQuick3DGeometry::Attribute::ComponentType::F32Type);
24 boxGeometry->addAttribute(QQuick3DGeometry::Attribute::NormalSemantic, 16,
25 QQuick3DGeometry::Attribute::ComponentType::F32Type);
26 boxGeometry->setStride(32);
27 boxGeometry->setPrimitiveType(QQuick3DGeometry::PrimitiveType::Lines);
28 boxGeometry->setBounds(-halfExtents, halfExtents);
30 const float x = halfExtents.x();
31 const float y = halfExtents.y();
32 const float z = halfExtents.z();
34 QCollisionDebugMeshBuilder builder;
36 builder.addLine(QVector3D(-x, -y, z), QVector3D(-x, y, z));
37 builder.addLine(QVector3D(-x, y, z), QVector3D(x, y, z));
38 builder.addLine(QVector3D(x, y, z), QVector3D(x, -y, z));
39 builder.addLine(QVector3D(x, -y, z), QVector3D(-x, -y, z));
42 builder.addLine(QVector3D(-x, -y, -z), QVector3D(-x, y, -z));
43 builder.addLine(QVector3D(-x, y, -z), QVector3D(x, y, -z));
44 builder.addLine(QVector3D(x, y, -z), QVector3D(x, -y, -z));
45 builder.addLine(QVector3D(x, -y, -z), QVector3D(-x, -y, -z));
48 builder.addLine(QVector3D(x, -y, z), QVector3D(x, -y, -z));
49 builder.addLine(QVector3D(-x, -y, -z), QVector3D(-x, -y, z));
52 builder.addLine(QVector3D(x, y, z), QVector3D(x, y, -z));
53 builder.addLine(QVector3D(-x, y, -z), QVector3D(-x, y, z));
55 boxGeometry->setVertexData(builder.generateVertexArray());
62 auto sphereGeometry =
new QQuick3DGeometry();
63 sphereGeometry->clear();
64 sphereGeometry->addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0,
65 QQuick3DGeometry::Attribute::ComponentType::F32Type);
66 sphereGeometry->addAttribute(QQuick3DGeometry::Attribute::NormalSemantic, 16,
67 QQuick3DGeometry::Attribute::ComponentType::F32Type);
68 sphereGeometry->setStride(32);
69 sphereGeometry->setPrimitiveType(QQuick3DGeometry::PrimitiveType::Lines);
70 sphereGeometry->setBounds(QVector3D(-radius, -radius, -radius),
71 QVector3D(radius, radius, radius));
75 const int circleSegments = 24;
76 constexpr double TAU = 2 * M_PI;
77 const float step =
float(TAU / circleSegments);
78 QVector<QVector2D> circlePoints;
79 for (
float theta = 0; theta < TAU; theta += step) {
80 const float x = radius * qCos(theta);
81 const float y = radius * qSin(theta);
82 circlePoints.append(QVector2D(x, y));
85 QCollisionDebugMeshBuilder builder;
87 for (
int i = 0; i < circlePoints.count(); ++i) {
88 const auto refPoint1 = circlePoints[i];
90 if (index2 == circlePoints.count())
92 const auto refPoint2 = circlePoints[index2];
93 const auto vertex1 =
QVector3D(0.0f, refPoint1.x(), refPoint1.y());
94 const auto vertex2 =
QVector3D(0.0f, refPoint2.x(), refPoint2.y());
95 builder.addLine(vertex1, vertex2, QVector3D(1, 0, 0));
99 for (
int i = 0; i < circlePoints.count(); ++i) {
100 const auto refPoint1 = circlePoints[i];
102 if (index2 == circlePoints.count())
104 const auto refPoint2 = circlePoints[index2];
105 const auto vertex1 =
QVector3D(refPoint1.x(), 0.0f, refPoint1.y());
106 const auto vertex2 =
QVector3D(refPoint2.x(), 0.0f, refPoint2.y());
107 builder.addLine(vertex1, vertex2, QVector3D(0, 1, 0));
111 for (
int i = 0; i < circlePoints.count(); ++i) {
112 const auto refPoint1 = circlePoints[i];
114 if (index2 == circlePoints.count())
116 const auto refPoint2 = circlePoints[index2];
117 const auto vertex1 =
QVector3D(refPoint1.x(), refPoint1.y(), 0.0f);
118 const auto vertex2 =
QVector3D(refPoint2.x(), refPoint2.y(), 0.0f);
119 builder.addLine(vertex1, vertex2, QVector3D(0, 0, 1));
121 sphereGeometry->setVertexData(builder.generateVertexArray());
123 return sphereGeometry;
127 const float halfHeight)
129 auto capsuleGeometry =
new QQuick3DGeometry();
130 capsuleGeometry->clear();
131 capsuleGeometry->addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0,
132 QQuick3DGeometry::Attribute::ComponentType::F32Type);
133 capsuleGeometry->addAttribute(QQuick3DGeometry::Attribute::NormalSemantic, 16,
134 QQuick3DGeometry::Attribute::ComponentType::F32Type);
135 capsuleGeometry->setStride(32);
136 capsuleGeometry->setPrimitiveType(QQuick3DGeometry::PrimitiveType::Lines);
137 capsuleGeometry->setBounds(QVector3D(-(halfHeight + radius), -radius, -radius),
138 QVector3D(halfHeight + radius, radius, radius));
144 const int circleSegments = 32;
145 constexpr double TAU = 2 * M_PI;
147 Q_ASSERT(circleSegments % 4 == 0);
148 const float step =
float(TAU / circleSegments);
149 QVector<QVector2D> circlePoints;
150 for (
float theta = 0; theta < TAU; theta += step) {
151 const float x = radius * qCos(theta);
152 const float y = radius * qSin(theta);
153 circlePoints.append(QVector2D(x, y));
156 QCollisionDebugMeshBuilder builder;
159 for (
int i = 0; i < circlePoints.count(); ++i) {
160 const auto refPoint1 = circlePoints[i];
162 if (index2 == circlePoints.count())
164 const auto refPoint2 = circlePoints[index2];
165 const auto vertex1 =
QVector3D(halfHeight, refPoint1.x(), refPoint1.y());
166 const auto vertex2 =
QVector3D(halfHeight, refPoint2.x(), refPoint2.y());
167 const auto normal = QVector3D(1, 0, 0);
168 builder.addLine(vertex1, vertex2, normal);
172 for (
int i = 0; i < circlePoints.count(); ++i) {
173 const auto refPoint1 = circlePoints[i];
175 if (index2 == circlePoints.count())
177 const auto refPoint2 = circlePoints[index2];
178 const auto vertex1 =
QVector3D(-halfHeight, refPoint1.x(), refPoint1.y());
179 const auto vertex2 =
QVector3D(-halfHeight, refPoint2.x(), refPoint2.y());
180 const auto normal = QVector3D(1, 0, 0);
181 builder.addLine(vertex1, vertex2, normal);
186 const auto vertex1 = QVector3D(halfHeight, 0, radius);
187 const auto vertex2 = QVector3D(-halfHeight, 0, radius);
188 const auto normal = QVector3D(0, 0, 1);
189 builder.addLine(vertex1, vertex2, normal);
194 const auto vertex1 = QVector3D(halfHeight, 0, -radius);
195 const auto vertex2 = QVector3D(-halfHeight, 0, -radius);
196 const auto normal = QVector3D(0, 0, -1);
197 builder.addLine(vertex1, vertex2, normal);
202 const auto vertex1 = QVector3D(halfHeight, -radius, 0);
203 const auto vertex2 = QVector3D(-halfHeight, -radius, 0);
204 const auto normal = QVector3D(0, -1, 0);
205 builder.addLine(vertex1, vertex2, normal);
210 const auto vertex1 = QVector3D(halfHeight, radius, 0);
211 const auto vertex2 = QVector3D(-halfHeight, radius, 0);
212 const auto normal = QVector3D(0, 1, 0);
213 builder.addLine(vertex1, vertex2, normal);
217 QVector<
int> topIndexes;
218 QVector<
int> bottomIndexes;
220 const int half = circlePoints.count() / 2;
221 for (
int i = 0; i < half + 1; ++i)
222 topIndexes.append(i);
224 for (
int i = half; i <= circlePoints.count(); ++i) {
226 if (i >= circlePoints.count())
227 index = index - circlePoints.count();
228 bottomIndexes.append(index);
233 for (
int i = 0; i < topIndexes.count(); ++i) {
234 const auto refPoint1 = circlePoints[topIndexes[i]];
236 if (index2 == topIndexes.count())
238 const auto refPoint2 = circlePoints[topIndexes[index2]];
239 const auto vertex1 =
QVector3D(refPoint1.y() + halfHeight, refPoint1.x(), 0.0f);
240 const auto vertex2 =
QVector3D(refPoint2.y() + halfHeight, refPoint2.x(), 0.0f);
241 const auto normal = QVector3D(0, 0, 1);
242 builder.addLine(vertex1, vertex2, normal);
246 for (
int i = 0; i < bottomIndexes.count(); ++i) {
247 const auto refPoint1 = circlePoints[bottomIndexes[i]];
249 if (index2 == bottomIndexes.count())
251 const auto refPoint2 = circlePoints[bottomIndexes[index2]];
252 const auto vertex1 =
QVector3D(refPoint1.y() - halfHeight, refPoint1.x(), 0.0f);
253 const auto vertex2 =
QVector3D(refPoint2.y() - halfHeight, refPoint2.x(), 0.0f);
254 const auto normal = QVector3D(0, 0, 1);
255 builder.addLine(vertex1, vertex2, normal);
259 for (
int i = 0; i < topIndexes.count(); ++i) {
260 const auto refPoint1 = circlePoints[topIndexes[i]];
262 if (index2 == topIndexes.count())
264 const auto refPoint2 = circlePoints[topIndexes[index2]];
265 const auto vertex1 =
QVector3D(refPoint1.y() + halfHeight, 0.0f, refPoint1.x());
266 const auto vertex2 =
QVector3D(refPoint2.y() + halfHeight, 0.0f, refPoint2.x());
267 const auto normal = QVector3D(0, 1, 0);
268 builder.addLine(vertex1, vertex2, normal);
272 for (
int i = 0; i < bottomIndexes.count(); ++i) {
273 const auto refPoint1 = circlePoints[bottomIndexes[i]];
275 if (index2 == bottomIndexes.count())
277 const auto refPoint2 = circlePoints[bottomIndexes[index2]];
278 const auto vertex1 =
QVector3D(refPoint1.y() - halfHeight, 0.0f, refPoint1.x());
279 const auto vertex2 =
QVector3D(refPoint2.y() - halfHeight, 0.0f, refPoint2.x());
280 const auto normal = QVector3D(0, 1, 0);
281 builder.addLine(vertex1, vertex2, normal);
284 capsuleGeometry->setVertexData(builder.generateVertexArray());
285 return capsuleGeometry;
290 auto planeGeometry =
new QQuick3DGeometry();
291 planeGeometry->clear();
292 planeGeometry->addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0,
293 QQuick3DGeometry::Attribute::ComponentType::F32Type);
294 planeGeometry->addAttribute(QQuick3DGeometry::Attribute::NormalSemantic, 16,
295 QQuick3DGeometry::Attribute::ComponentType::F32Type);
296 planeGeometry->setStride(32);
297 planeGeometry->setPrimitiveType(QQuick3DGeometry::PrimitiveType::Lines);
302 planeGeometry->setBounds({ -s, -s, -h }, { s, s, h });
303 QCollisionDebugMeshBuilder builder;
305 builder.addLine({ -s, -s, 0 }, { s, -s, 0 });
306 builder.addLine({ -s, -s, 0 }, { 0, 0, 0 });
308 builder.addLine({ s, -s, 0 }, { s, s, 0 });
309 builder.addLine({ s, -s, 0 }, { 0, 0, 0 });
311 builder.addLine({ s, s, 0 }, { -s, s, 0 });
312 builder.addLine({ s, s, 0 }, { 0, 0, 0 });
314 builder.addLine({ -s, s, 0 }, { -s, -s, 0 });
315 builder.addLine({ -s, s, 0 }, { 0, 0, 0 });
317 planeGeometry->setVertexData(builder.generateVertexArray());
318 return planeGeometry;
322 float heightScale,
float rowScale,
325 if (!heightField || heightField->getNbRows() < 2 || heightField->getNbColumns() < 2)
328 auto geometry =
new QQuick3DGeometry();
330 geometry->addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0,
331 QQuick3DGeometry::Attribute::ComponentType::F32Type);
332 geometry->addAttribute(QQuick3DGeometry::Attribute::NormalSemantic, 16,
333 QQuick3DGeometry::Attribute::ComponentType::F32Type);
334 geometry->setStride(32);
335 geometry->setPrimitiveType(QQuick3DGeometry::PrimitiveType::Lines);
337 QCollisionDebugMeshBuilder builder;
339 const int numRows = heightField->getNbRows();
340 const int numCols = heightField->getNbColumns();
342 const float sizeX = rowScale * (numRows - 1);
343 const float sizeZ = columnScale * (numCols - 1);
345 const float heightF = heightScale;
347 float minHeight = 0.f;
348 float maxHeight = 0.f;
350 auto sample = [&](
int row,
int col) ->
QVector3D {
351 const float height = heightField->getSample(row, col).height * heightF;
352 maxHeight = qMax(maxHeight, height);
353 minHeight = qMin(minHeight, height);
354 return QVector3D(row * rowScale, height, col * columnScale);
357 for (
int row = 0; row < numRows; row++) {
358 for (
int col = 0; col < numCols; col++) {
359 if (row < numRows - 1)
360 builder.addLine(sample(row, col), sample(row + 1, col));
361 if (col < numCols - 1)
362 builder.addLine(sample(row, col), sample(row, col + 1));
366 geometry->setBounds(QVector3D(0, minHeight, 0), QVector3D(sizeX, maxHeight, sizeZ));
367 geometry->setVertexData(builder.generateVertexArray());
376 auto geometry =
new QQuick3DGeometry();
378 geometry->addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0,
379 QQuick3DGeometry::Attribute::ComponentType::F32Type);
380 geometry->addAttribute(QQuick3DGeometry::Attribute::NormalSemantic, 16,
381 QQuick3DGeometry::Attribute::ComponentType::F32Type);
382 geometry->setStride(32);
383 geometry->setPrimitiveType(QQuick3DGeometry::PrimitiveType::Lines);
385 QCollisionDebugMeshBuilder builder;
387 const physx::PxU32 nbPolys = convexMesh->getNbPolygons();
388 const physx::PxU8 *polygons = convexMesh->getIndexBuffer();
389 const physx::PxVec3 *verts = convexMesh->getVertices();
390 const physx::PxU32 nbVerts = convexMesh->getNbVertices();
392 physx::PxHullPolygon data;
393 for (physx::PxU32 i = 0; i < nbPolys; i++) {
394 convexMesh->getPolygonData(i, data);
396 Q_ASSERT(data.mNbVerts > 2);
397 const physx::PxU32 nbTris = physx::PxU32(data.mNbVerts - 2);
398 const physx::PxU8 vref0 = polygons[data.mIndexBase + 0];
399 Q_ASSERT(vref0 < nbVerts);
401 for (physx::PxU32 j = 0; j < nbTris; j++) {
402 const physx::PxU32 vref1 = polygons[data.mIndexBase + 0 + j + 1];
403 const physx::PxU32 vref2 = polygons[data.mIndexBase + 0 + j + 2];
404 Q_ASSERT(vref1 < nbVerts);
405 Q_ASSERT(vref2 < nbVerts);
407 const QVector3D p0 = QPhysicsUtils::toQtType(verts[vref0]);
408 const QVector3D p1 = QPhysicsUtils::toQtType(verts[vref1]);
409 const QVector3D p2 = QPhysicsUtils::toQtType(verts[vref2]);
411 builder.addLine(p0, p1);
412 builder.addLine(p1, p2);
413 builder.addLine(p2, p0);
417 auto bounds = convexMesh->getLocalBounds();
419 geometry->setBounds(QPhysicsUtils::toQtType(bounds.minimum),
420 QPhysicsUtils::toQtType(bounds.maximum));
421 geometry->setVertexData(builder.generateVertexArray());
431 auto geometry =
new QQuick3DGeometry();
433 geometry->addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0,
434 QQuick3DGeometry::Attribute::ComponentType::F32Type);
435 geometry->addAttribute(QQuick3DGeometry::Attribute::NormalSemantic, 16,
436 QQuick3DGeometry::Attribute::ComponentType::F32Type);
437 geometry->setStride(32);
438 geometry->setPrimitiveType(QQuick3DGeometry::PrimitiveType::Lines);
440 QCollisionDebugMeshBuilder builder;
442 const physx::PxU32 triangleCount = triangleMesh->getNbTriangles();
443 const physx::PxU32 has16BitIndices =
444 triangleMesh->getTriangleMeshFlags() & physx::PxTriangleMeshFlag::e16_BIT_INDICES;
445 const void *indexBuffer = triangleMesh->getTriangles();
446 const physx::PxVec3 *vertexBuffer = triangleMesh->getVertices();
447 const physx::PxU32 *intIndices =
reinterpret_cast<
const physx::PxU32 *>(indexBuffer);
448 const physx::PxU16 *shortIndices =
reinterpret_cast<
const physx::PxU16 *>(indexBuffer);
449 for (physx::PxU32 i = 0; i < triangleCount; ++i) {
450 physx::PxVec3 triVert[3];
452 if (has16BitIndices) {
453 triVert[0] = vertexBuffer[*shortIndices++];
454 triVert[1] = vertexBuffer[*shortIndices++];
455 triVert[2] = vertexBuffer[*shortIndices++];
457 triVert[0] = vertexBuffer[*intIndices++];
458 triVert[1] = vertexBuffer[*intIndices++];
459 triVert[2] = vertexBuffer[*intIndices++];
462 const QVector3D p0 = QPhysicsUtils::toQtType(triVert[0]);
463 const QVector3D p1 = QPhysicsUtils::toQtType(triVert[1]);
464 const QVector3D p2 = QPhysicsUtils::toQtType(triVert[2]);
466 builder.addLine(p0, p1);
467 builder.addLine(p1, p2);
468 builder.addLine(p2, p0);
471 auto bounds = triangleMesh->getLocalBounds();
473 geometry->setBounds(QPhysicsUtils::toQtType(bounds.minimum),
474 QPhysicsUtils::toQtType(bounds.maximum));
475 geometry->setVertexData(builder.generateVertexArray());