diff options
author | Antti Määttä <antti.maatta@qt.io> | 2016-10-25 10:12:58 +0300 |
---|---|---|
committer | Antti Määttä <antti.maatta@qt.io> | 2017-01-24 16:22:20 +0000 |
commit | fc142f59a364c47818356fc6bf13471fec49ea99 (patch) | |
tree | 7738d2ae3494ea3034fe04014e35d014a4c817b6 | |
parent | 1ce5d53260ae1acc792b693a7af2288bbe3cb85a (diff) | |
download | qt3d-fc142f59a364c47818356fc6bf13471fec49ea99.tar.gz |
Retrieve uvw parameters when picking
The uvw can be used to interpolate coordinates on the intersection point.
Change-Id: I725ef572a78ad7766000270622f3ac85edd11071
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r-- | src/render/backend/triangleboundingvolume.cpp | 17 | ||||
-rw-r--r-- | src/render/backend/triangleboundingvolume_p.h | 2 | ||||
-rw-r--r-- | src/render/frontend/sphere.cpp | 3 | ||||
-rw-r--r-- | src/render/frontend/sphere_p.h | 2 | ||||
-rw-r--r-- | src/render/jobs/pickboundingvolumeutils.cpp | 1 | ||||
-rw-r--r-- | src/render/raycasting/qabstractcollisionqueryservice.cpp | 6 | ||||
-rw-r--r-- | src/render/raycasting/qabstractcollisionqueryservice_p.h | 3 | ||||
-rw-r--r-- | src/render/raycasting/qboundingvolume_p.h | 3 | ||||
-rw-r--r-- | src/render/raycasting/qcollisionqueryresult.cpp | 5 | ||||
-rw-r--r-- | src/render/raycasting/qcollisionqueryresult_p.h | 7 | ||||
-rw-r--r-- | src/render/raycasting/qraycastingservice.cpp | 8 |
11 files changed, 36 insertions, 21 deletions
diff --git a/src/render/backend/triangleboundingvolume.cpp b/src/render/backend/triangleboundingvolume.cpp index deef28a44..773bdd309 100644 --- a/src/render/backend/triangleboundingvolume.cpp +++ b/src/render/backend/triangleboundingvolume.cpp @@ -112,15 +112,18 @@ Qt3DCore::QNodeId TriangleBoundingVolume::id() const return m_id; } -bool TriangleBoundingVolume::intersects(const QRay3D &ray, QVector3D *q) const +bool TriangleBoundingVolume::intersects(const QRay3D &ray, QVector3D *q, QVector3D *uvw) const { float t = 0.0f; - QVector3D uvw; - const bool intersected = intersectsSegmentTriangle(ray, m_c, m_b, m_a, uvw, t); - - if (intersected && q != nullptr) - *q = ray.point(t * ray.distance()); - + QVector3D uvwr; + const float intersected = intersectsSegmentTriangle(ray, m_c, m_b, m_a, uvwr, t); + + if (intersected) { + if (q != nullptr) + *q = ray.point(t); + if (uvw != nullptr) + *uvw = uvwr; + } return intersected; } diff --git a/src/render/backend/triangleboundingvolume_p.h b/src/render/backend/triangleboundingvolume_p.h index cc394041b..7ee4e5384 100644 --- a/src/render/backend/triangleboundingvolume_p.h +++ b/src/render/backend/triangleboundingvolume_p.h @@ -78,7 +78,7 @@ public: const QVector3D &c); Qt3DCore::QNodeId id() const Q_DECL_FINAL; - bool intersects(const QRay3D &ray, QVector3D *q) const Q_DECL_FINAL; + bool intersects(const QRay3D &ray, QVector3D *q, QVector3D *uvw) const Q_DECL_FINAL; Type type() const Q_DECL_FINAL; QVector3D a() const; diff --git a/src/render/frontend/sphere.cpp b/src/render/frontend/sphere.cpp index 60e414c2e..6684d94cb 100644 --- a/src/render/frontend/sphere.cpp +++ b/src/render/frontend/sphere.cpp @@ -223,8 +223,9 @@ Qt3DCore::QNodeId Sphere::id() const return m_id; } -bool Sphere::intersects(const QRay3D &ray, QVector3D *q) const +bool Sphere::intersects(const QRay3D &ray, QVector3D *q, QVector3D *uvw) const { + Q_UNUSED(uvw); return intersectRaySphere(ray, *this, q); } diff --git a/src/render/frontend/sphere_p.h b/src/render/frontend/sphere_p.h index a30a12741..d5487386c 100644 --- a/src/render/frontend/sphere_p.h +++ b/src/render/frontend/sphere_p.h @@ -106,7 +106,7 @@ public: } Qt3DCore::QNodeId id() const Q_DECL_FINAL; - bool intersects(const QRay3D &ray, QVector3D *q) const Q_DECL_FINAL; + bool intersects(const QRay3D &ray, QVector3D *q, QVector3D *uvw = nullptr) const Q_DECL_FINAL; Type type() const Q_DECL_FINAL; static Sphere fromPoints(const QVector<QVector3D> &points); diff --git a/src/render/jobs/pickboundingvolumeutils.cpp b/src/render/jobs/pickboundingvolumeutils.cpp index d0618866b..230667b7b 100644 --- a/src/render/jobs/pickboundingvolumeutils.cpp +++ b/src/render/jobs/pickboundingvolumeutils.cpp @@ -172,6 +172,7 @@ bool CollisionVisitor::intersectsSegmentTriangle(uint andx, const QVector3D &a, queryResult.m_vertexIndex[0] = andx; queryResult.m_vertexIndex[1] = bndx; queryResult.m_vertexIndex[2] = cndx; + queryResult.m_uvw = uvw; queryResult.m_intersection = m_ray.point(t * m_ray.distance()); queryResult.m_distance = m_ray.projectedDistance(queryResult.m_intersection); hits.push_back(queryResult); diff --git a/src/render/raycasting/qabstractcollisionqueryservice.cpp b/src/render/raycasting/qabstractcollisionqueryservice.cpp index 4c59b6aab..32878ebd0 100644 --- a/src/render/raycasting/qabstractcollisionqueryservice.cpp +++ b/src/render/raycasting/qabstractcollisionqueryservice.cpp @@ -60,9 +60,11 @@ void QAbstractCollisionQueryService::setResultHandle(QCollisionQueryResult &resu result.d_func()->setHandle(handle); } -void QAbstractCollisionQueryService::addEntityHit(QCollisionQueryResult &result, Qt3DCore::QNodeId entity, const QVector3D& intersection, float distance) +void QAbstractCollisionQueryService::addEntityHit(QCollisionQueryResult &result, Qt3DCore::QNodeId entity, + const QVector3D& intersection, float distance, + const QVector3D& uvw) { - result.d_func()->addEntityHit(entity, intersection, distance); + result.d_func()->addEntityHit(entity, intersection, distance, uvw); } } // Qt3DRender diff --git a/src/render/raycasting/qabstractcollisionqueryservice_p.h b/src/render/raycasting/qabstractcollisionqueryservice_p.h index d26eacb98..f6f3bf334 100644 --- a/src/render/raycasting/qabstractcollisionqueryservice_p.h +++ b/src/render/raycasting/qabstractcollisionqueryservice_p.h @@ -95,7 +95,8 @@ protected: QAbstractCollisionQueryService(QAbstractCollisionQueryServicePrivate &dd); void setResultHandle(QCollisionQueryResult &result, const QQueryHandle &handle); - void addEntityHit(QCollisionQueryResult &result, Qt3DCore::QNodeId entity, const QVector3D &intersection, float distance); + void addEntityHit(QCollisionQueryResult &result, Qt3DCore::QNodeId entity, const QVector3D &intersection, + float distance, const QVector3D &uvw); private: Q_DECLARE_PRIVATE(QAbstractCollisionQueryService) diff --git a/src/render/raycasting/qboundingvolume_p.h b/src/render/raycasting/qboundingvolume_p.h index a69530246..0e5f6e45d 100644 --- a/src/render/raycasting/qboundingvolume_p.h +++ b/src/render/raycasting/qboundingvolume_p.h @@ -70,7 +70,8 @@ public: }; virtual Qt3DCore::QNodeId id() const = 0; - virtual bool intersects(const QRay3D &ray, QVector3D *q = nullptr) const = 0; + virtual bool intersects(const QRay3D &ray, QVector3D *q = nullptr, + QVector3D *uvw = nullptr) const = 0; virtual Type type() const = 0; }; diff --git a/src/render/raycasting/qcollisionqueryresult.cpp b/src/render/raycasting/qcollisionqueryresult.cpp index e4a6afa69..ad150d9a2 100644 --- a/src/render/raycasting/qcollisionqueryresult.cpp +++ b/src/render/raycasting/qcollisionqueryresult.cpp @@ -55,9 +55,10 @@ QCollisionQueryResultPrivate::QCollisionQueryResultPrivate(const QCollisionQuery { } -void QCollisionQueryResultPrivate::addEntityHit(Qt3DCore::QNodeId entity, const QVector3D& intersection, float distance) +void QCollisionQueryResultPrivate::addEntityHit(Qt3DCore::QNodeId entity, const QVector3D& intersection, + float distance, const QVector3D& uvw) { - m_hits.append(QCollisionQueryResult::Hit(entity, intersection, distance)); + m_hits.append(QCollisionQueryResult::Hit(entity, intersection, distance, uvw)); } void QCollisionQueryResultPrivate::setHandle(const QQueryHandle &handle) diff --git a/src/render/raycasting/qcollisionqueryresult_p.h b/src/render/raycasting/qcollisionqueryresult_p.h index 81bca98b6..fe96bfe48 100644 --- a/src/render/raycasting/qcollisionqueryresult_p.h +++ b/src/render/raycasting/qcollisionqueryresult_p.h @@ -69,12 +69,14 @@ class QT3DRENDERSHARED_EXPORT QCollisionQueryResult public: struct Hit { Hit() : m_distance(-1.f), m_triangleIndex(0) { m_vertexIndex[0] = m_vertexIndex[1] = m_vertexIndex[2] = 0; } - Hit(Qt3DCore::QNodeId entity, const QVector3D &intersection, float distance) : m_entityId(entity), m_intersection(intersection), m_distance(distance) { } + Hit(Qt3DCore::QNodeId entity, const QVector3D &intersection, float distance, const QVector3D &uvw) + : m_entityId(entity), m_intersection(intersection), m_distance(distance), m_uvw(uvw) { } Qt3DCore::QNodeId m_entityId; QVector3D m_intersection; float m_distance; uint m_triangleIndex; uint m_vertexIndex[3]; + QVector3D m_uvw; }; QCollisionQueryResult(); @@ -122,7 +124,8 @@ public: explicit QCollisionQueryResultPrivate(const QCollisionQueryResultPrivate ©); void setHandle(const QQueryHandle &handle); - void addEntityHit(Qt3DCore::QNodeId entity, const QVector3D& intersection, float distance); + void addEntityHit(Qt3DCore::QNodeId entity, const QVector3D& intersection, float distance, + const QVector3D& uvw); QQueryHandle m_handle; QVector<QCollisionQueryResult::Hit> m_hits; diff --git a/src/render/raycasting/qraycastingservice.cpp b/src/render/raycasting/qraycastingservice.cpp index 6dfb1c57a..9f3a52380 100644 --- a/src/render/raycasting/qraycastingservice.cpp +++ b/src/render/raycasting/qraycastingservice.cpp @@ -67,6 +67,7 @@ struct Hit float distance; Qt3DCore::QNodeId id; QVector3D intersection; + QVector3D uvw; }; bool compareHitsDistance(const Hit &a, const Hit &b) @@ -77,7 +78,7 @@ bool compareHitsDistance(const Hit &a, const Hit &b) Hit volumeRayIntersection(const QBoundingVolume *volume, const QRay3D &ray) { Hit hit; - if ((hit.intersects = volume->intersects(ray, &hit.intersection))) { + if ((hit.intersects = volume->intersects(ray, &hit.intersection, &hit.uvw))) { hit.distance = ray.projectedDistance(hit.intersection); hit.id = volume->id(); } @@ -133,12 +134,12 @@ QCollisionQueryResult QRayCastingServicePrivate::collides(const QRay3D &ray, QBo if (mode == QAbstractCollisionQueryService::FirstHit) { Hit firstHit = QtConcurrent::blockingMappedReduced<Hit>(volumes, gathererFunctor, reduceToFirstHit); if (firstHit.intersects) - q->addEntityHit(result, firstHit.id, firstHit.intersection, firstHit.distance); + q->addEntityHit(result, firstHit.id, firstHit.intersection, firstHit.distance, firstHit.uvw); } else { QVector<Hit> hits = QtConcurrent::blockingMappedReduced<QVector<Hit> >(volumes, gathererFunctor, reduceToAllHits); std::sort(hits.begin(), hits.end(), compareHitsDistance); for (const Hit &hit : qAsConst(hits)) - q->addEntityHit(result, hit.id, hit.intersection, hit.distance); + q->addEntityHit(result, hit.id, hit.intersection, hit.distance, hit.uvw); } return result; @@ -153,6 +154,7 @@ QCollisionQueryResult::Hit QRayCastingServicePrivate::collides(const QRay3D &ray result.m_distance = hit.distance; result.m_entityId = hit.id; result.m_intersection = hit.intersection; + result.m_uvw = hit.uvw; } return result; } |