9#include <foundation/PxBounds3.h>
10#include <foundation/PxVec3.h>
11#include <geometry/PxConvexMesh.h>
12#include <geometry/PxTriangleMesh.h>
13#include <geometry/PxHeightField.h>
15#include <QQuick3DGeometry>
25 boxGeometry->setStride(32);
27 boxGeometry->setBounds(-halfExtents, halfExtents);
29 const float x = halfExtents.
x();
30 const float y = halfExtents.
y();
31 const float z = halfExtents.
z();
62 sphereGeometry->clear();
67 sphereGeometry->setStride(32);
69 sphereGeometry->setBounds(
QVector3D(-radius, -radius, -radius),
74 const int circleSegments = 24;
75 constexpr double TAU = 2 *
M_PI;
76 const float step = float(TAU / circleSegments);
78 for (
float theta = 0; theta < TAU; theta += step) {
79 const float x = radius *
qCos(theta);
80 const float y = radius *
qSin(theta);
86 for (
int i = 0;
i < circlePoints.
count(); ++
i) {
87 const auto refPoint1 = circlePoints[
i];
89 if (index2 == circlePoints.
count())
91 const auto refPoint2 = circlePoints[index2];
92 const auto vertex1 =
QVector3D(0.0f, refPoint1.x(), refPoint1.y());
93 const auto vertex2 =
QVector3D(0.0f, refPoint2.x(), refPoint2.y());
98 for (
int i = 0;
i < circlePoints.
count(); ++
i) {
99 const auto refPoint1 = circlePoints[
i];
101 if (index2 == circlePoints.
count())
103 const auto refPoint2 = circlePoints[index2];
104 const auto vertex1 =
QVector3D(refPoint1.x(), 0.0f, refPoint1.y());
105 const auto vertex2 =
QVector3D(refPoint2.x(), 0.0f, refPoint2.y());
110 for (
int i = 0;
i < circlePoints.
count(); ++
i) {
111 const auto refPoint1 = circlePoints[
i];
113 if (index2 == circlePoints.
count())
115 const auto refPoint2 = circlePoints[index2];
116 const auto vertex1 =
QVector3D(refPoint1.x(), refPoint1.y(), 0.0f);
117 const auto vertex2 =
QVector3D(refPoint2.x(), refPoint2.y(), 0.0f);
122 return sphereGeometry;
126 const float halfHeight)
129 capsuleGeometry->clear();
134 capsuleGeometry->setStride(32);
136 capsuleGeometry->setBounds(
QVector3D(-(halfHeight + radius), -radius, -radius),
137 QVector3D(halfHeight + radius, radius, radius));
143 const int circleSegments = 32;
144 constexpr double TAU = 2 *
M_PI;
147 const float step = float(TAU / circleSegments);
149 for (
float theta = 0; theta < TAU; theta += step) {
150 const float x = radius *
qCos(theta);
151 const float y = radius *
qSin(theta);
158 for (
int i = 0;
i < circlePoints.
count(); ++
i) {
159 const auto refPoint1 = circlePoints[
i];
161 if (index2 == circlePoints.
count())
163 const auto refPoint2 = circlePoints[index2];
164 const auto vertex1 =
QVector3D(halfHeight, refPoint1.x(), refPoint1.y());
165 const auto vertex2 =
QVector3D(halfHeight, refPoint2.x(), refPoint2.y());
167 builder.
addLine(vertex1, vertex2, normal);
171 for (
int i = 0;
i < circlePoints.
count(); ++
i) {
172 const auto refPoint1 = circlePoints[
i];
174 if (index2 == circlePoints.
count())
176 const auto refPoint2 = circlePoints[index2];
177 const auto vertex1 =
QVector3D(-halfHeight, refPoint1.x(), refPoint1.y());
178 const auto vertex2 =
QVector3D(-halfHeight, refPoint2.x(), refPoint2.y());
180 builder.
addLine(vertex1, vertex2, normal);
185 const auto vertex1 =
QVector3D(halfHeight, 0, radius);
186 const auto vertex2 =
QVector3D(-halfHeight, 0, radius);
188 builder.
addLine(vertex1, vertex2, normal);
193 const auto vertex1 =
QVector3D(halfHeight, 0, -radius);
194 const auto vertex2 =
QVector3D(-halfHeight, 0, -radius);
196 builder.
addLine(vertex1, vertex2, normal);
201 const auto vertex1 =
QVector3D(halfHeight, -radius, 0);
202 const auto vertex2 =
QVector3D(-halfHeight, -radius, 0);
204 builder.
addLine(vertex1, vertex2, normal);
209 const auto vertex1 =
QVector3D(halfHeight, radius, 0);
210 const auto vertex2 =
QVector3D(-halfHeight, radius, 0);
212 builder.
addLine(vertex1, vertex2, normal);
219 const int half = circlePoints.
count() / 2;
220 for (
int i = 0;
i < half + 1; ++
i)
223 for (
int i = half;
i <= circlePoints.
count(); ++
i) {
225 if (
i >= circlePoints.
count())
232 for (
int i = 0;
i < topIndexes.
count(); ++
i) {
233 const auto refPoint1 = circlePoints[topIndexes[
i]];
235 if (index2 == topIndexes.count())
237 const auto refPoint2 = circlePoints[topIndexes[index2]];
238 const auto vertex1 =
QVector3D(refPoint1.y() + halfHeight, refPoint1.x(), 0.0f);
239 const auto vertex2 =
QVector3D(refPoint2.y() + halfHeight, refPoint2.x(), 0.0f);
241 builder.
addLine(vertex1, vertex2, normal);
245 for (
int i = 0;
i < bottomIndexes.
count(); ++
i) {
246 const auto refPoint1 = circlePoints[bottomIndexes[
i]];
248 if (index2 == bottomIndexes.count())
250 const auto refPoint2 = circlePoints[bottomIndexes[index2]];
251 const auto vertex1 =
QVector3D(refPoint1.y() - halfHeight, refPoint1.x(), 0.0f);
252 const auto vertex2 =
QVector3D(refPoint2.y() - halfHeight, refPoint2.x(), 0.0f);
254 builder.
addLine(vertex1, vertex2, normal);
258 for (
int i = 0;
i < topIndexes.
count(); ++
i) {
259 const auto refPoint1 = circlePoints[topIndexes[
i]];
261 if (index2 == topIndexes.count())
263 const auto refPoint2 = circlePoints[topIndexes[index2]];
264 const auto vertex1 =
QVector3D(refPoint1.y() + halfHeight, 0.0f, refPoint1.x());
265 const auto vertex2 =
QVector3D(refPoint2.y() + halfHeight, 0.0f, refPoint2.x());
267 builder.
addLine(vertex1, vertex2, normal);
271 for (
int i = 0;
i < bottomIndexes.
count(); ++
i) {
272 const auto refPoint1 = circlePoints[bottomIndexes[
i]];
274 if (index2 == bottomIndexes.count())
276 const auto refPoint2 = circlePoints[bottomIndexes[index2]];
277 const auto vertex1 =
QVector3D(refPoint1.y() - halfHeight, 0.0f, refPoint1.x());
278 const auto vertex2 =
QVector3D(refPoint2.y() - halfHeight, 0.0f, refPoint2.x());
280 builder.
addLine(vertex1, vertex2, normal);
284 return capsuleGeometry;
290 planeGeometry->clear();
295 planeGeometry->setStride(32);
301 planeGeometry->setBounds({ -
s, -
s, -
h }, {
s,
s,
h });
305 builder.
addLine({ -
s, -
s, 0 }, { 0, 0, 0 });
308 builder.
addLine({
s, -
s, 0 }, { 0, 0, 0 });
311 builder.
addLine({
s,
s, 0 }, { 0, 0, 0 });
314 builder.
addLine({ -
s,
s, 0 }, { 0, 0, 0 });
317 return planeGeometry;
321 float heightScale,
float rowScale,
324 if (!heightField || heightField->getNbRows() < 2 || heightField->getNbColumns() < 2)
333 geometry->setStride(32);
338 const int numRows = heightField->getNbRows();
339 const int numCols = heightField->getNbColumns();
341 const float sizeX = rowScale * (numRows - 1);
342 const float sizeZ = columnScale * (numCols - 1);
344 const float heightF = heightScale;
346 float minHeight = 0.f;
347 float maxHeight = 0.f;
350 const float height = heightField->getSample(
row, col).height * heightF;
356 for (
int row = 0;
row < numRows;
row++) {
357 for (
int col = 0; col < numCols; col++) {
358 if (
row < numRows - 1)
360 if (col < numCols - 1)
381 geometry->setStride(32);
386 const physx::PxU32 nbPolys = convexMesh->getNbPolygons();
387 const physx::PxU8 *polygons = convexMesh->getIndexBuffer();
388 const physx::PxVec3 *verts = convexMesh->getVertices();
389 const physx::PxU32 nbVerts = convexMesh->getNbVertices();
391 physx::PxHullPolygon
data;
392 for (physx::PxU32
i = 0;
i < nbPolys;
i++) {
393 convexMesh->getPolygonData(
i,
data);
396 const physx::PxU32 nbTris = physx::PxU32(
data.mNbVerts - 2);
397 const physx::PxU8 vref0 = polygons[
data.mIndexBase + 0];
400 for (physx::PxU32
j = 0;
j < nbTris;
j++) {
401 const physx::PxU32 vref1 = polygons[
data.mIndexBase + 0 +
j + 1];
402 const physx::PxU32 vref2 = polygons[
data.mIndexBase + 0 +
j + 2];
416 auto bounds = convexMesh->getLocalBounds();
436 geometry->setStride(32);
441 const physx::PxU32 triangleCount = triangleMesh->getNbTriangles();
442 const physx::PxU32 has16BitIndices =
443 triangleMesh->getTriangleMeshFlags() & physx::PxTriangleMeshFlag::e16_BIT_INDICES;
444 const void *indexBuffer = triangleMesh->getTriangles();
445 const physx::PxVec3 *vertexBuffer = triangleMesh->getVertices();
446 const physx::PxU32 *intIndices =
reinterpret_cast<const physx::PxU32 *
>(indexBuffer);
447 const physx::PxU16 *shortIndices =
reinterpret_cast<const physx::PxU16 *
>(indexBuffer);
448 for (physx::PxU32
i = 0;
i < triangleCount; ++
i) {
449 physx::PxVec3 triVert[3];
451 if (has16BitIndices) {
452 triVert[0] = vertexBuffer[*shortIndices++];
453 triVert[1] = vertexBuffer[*shortIndices++];
454 triVert[2] = vertexBuffer[*shortIndices++];
456 triVert[0] = vertexBuffer[*intIndices++];
457 triVert[1] = vertexBuffer[*intIndices++];
458 triVert[2] = vertexBuffer[*intIndices++];
470 auto bounds = triangleMesh->getLocalBounds();
void addLine(const QVector3D &start, const QVector3D &end, const QVector3D &normal=QVector3D(0, 0, 1))
QByteArray generateVertexArray()
qsizetype count() const noexcept
void append(parameter_type t)
\qmltype Geometry \inherits Object3D \inqmlmodule QtQuick3D \instantiates QQuick3DGeometry
The QVector2D class represents a vector or vertex in 2D space.
The QVector3D class represents a vector or vertex in 3D space.
constexpr float y() const noexcept
Returns the y coordinate of this point.
constexpr float x() const noexcept
Returns the x coordinate of this point.
constexpr float z() const noexcept
Returns the z coordinate of this point.
QQuick3DGeometry * generateConvexMeshGeometry(physx::PxConvexMesh *convexMesh)
QQuick3DGeometry * generateSphereGeometry(const float radius)
QQuick3DGeometry * generateHeightFieldGeometry(physx::PxHeightField *heightField, float heightScale, float rowScale, float columnScale)
QQuick3DGeometry * generatePlaneGeometry()
QQuick3DGeometry * generateBoxGeometry(const QVector3D &halfExtents)
QQuick3DGeometry * generateCapsuleGeometry(const float radius, const float halfHeight)
QQuick3DGeometry * generateTriangleMeshGeometry(physx::PxTriangleMesh *triangleMesh)
Q_ALWAYS_INLINE QVector3D toQtType(const physx::PxVec3 &vec)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei GLsizei height
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat GLfloat GLfloat h
GLenum GLenum GLsizei void * row