diff --git a/src/runtimerender/graphobjects/qssgrendercamera.cpp b/src/runtimerender/graphobjects/qssgrendercamera.cpp index 79fba09d2a55afdaddd0a38e4c1bb7555b528db5..41eb77115eb4c99877ff0f317bacfc5336b23552 100644 --- a/src/runtimerender/graphobjects/qssgrendercamera.cpp +++ b/src/runtimerender/graphobjects/qssgrendercamera.cpp @@ -242,7 +242,7 @@ QVector3D QSSGRenderCamera::unprojectToPosition(const QVector3D &inGlobalPos, co QVector3D theObjGlobalPos = inGlobalPos; float theDistance = -1.0f * QVector3D::dotProduct(theObjGlobalPos, theCameraDir); QSSGPlane theCameraPlane(theCameraDir, theDistance); - return inRay.intersect(theCameraPlane); + return QSSGRenderRay::intersect(theCameraPlane, inRay); } float QSSGRenderCamera::verticalFov(float aspectRatio) const diff --git a/src/runtimerender/qssgrenderray.cpp b/src/runtimerender/qssgrenderray.cpp index 0cd07408ed11ed60a38ac9e2641dfe885df219df..cb99418d890bfed1f9a622143055957afafcad98 100644 --- a/src/runtimerender/qssgrenderray.cpp +++ b/src/runtimerender/qssgrenderray.cpp @@ -37,18 +37,20 @@ QT_BEGIN_NAMESPACE // http://www.siggraph.org/education/materials/HyperGraph/raytrace/rayplane_intersection.htm -QSSGOption<QVector3D> QSSGRenderRay::intersect(const QSSGPlane &inPlane) const +QSSGOption<QVector3D> QSSGRenderRay::intersect(const QSSGPlane &inPlane, const QSSGRenderRay &ray) { - float Vd = QVector3D::dotProduct(inPlane.n, direction); + float Vd = QVector3D::dotProduct(inPlane.n, ray.direction); if (std::abs(Vd) < .0001f) return QSSGEmpty(); - float V0 = -1.0f * (QVector3D::dotProduct(inPlane.n, origin) + inPlane.d); + float V0 = -1.0f * (QVector3D::dotProduct(inPlane.n, ray.origin) + inPlane.d); float t = V0 / Vd; - return origin + (direction * t); + return ray.origin + (ray.direction * t); } -QSSGRenderRay::IntersectionResult QSSGRenderRay::intersectWithAABB(const QMatrix4x4 &inGlobalTransform, const QSSGBounds3 &inBounds, - bool inForceIntersect) const +QSSGRenderRay::IntersectionResult QSSGRenderRay::intersectWithAABB(const QMatrix4x4 &inGlobalTransform, + const QSSGBounds3 &inBounds, + const QSSGRenderRay &ray, + bool inForceIntersect) { // Intersect the origin with the AABB described by bounds. @@ -63,11 +65,11 @@ QSSGRenderRay::IntersectionResult QSSGRenderRay::intersectWithAABB(const QMatrix // Transform pick origin and direction into the subset's space. QMatrix4x4 theOriginTransform = inGlobalTransform.inverted(); - QVector3D theTransformedOrigin = mat44::transform(theOriginTransform, origin); + QVector3D theTransformedOrigin = mat44::transform(theOriginTransform, ray.origin); float *outOriginTransformPtr(theOriginTransform.data()); outOriginTransformPtr[12] = outOriginTransformPtr[13] = outOriginTransformPtr[14] = 0.0f; - QVector3D theTransformedDirection = mat44::rotate(theOriginTransform, direction); + QVector3D theTransformedDirection = mat44::rotate(theOriginTransform, ray.direction); static const float KD_FLT_MAX = 3.40282346638528860e+38; static const float kEpsilon = 1e-5f; @@ -107,7 +109,7 @@ QSSGRenderRay::IntersectionResult QSSGRenderRay::intersectWithAABB(const QMatrix QVector3D scaledDir = theTransformedDirection * theMinWinner; QVector3D newPosInLocal = theTransformedOrigin + scaledDir; QVector3D newPosInGlobal = mat44::transform(inGlobalTransform, newPosInLocal); - QVector3D cameraToLocal = origin - newPosInGlobal; + QVector3D cameraToLocal = ray.origin - newPosInGlobal; float rayLengthSquared = vec3::magnitudeSquared(cameraToLocal); @@ -154,8 +156,8 @@ QSSGOption<QVector2D> QSSGRenderRay::relative(const QMatrix4x4 &inGlobalTransfor ? QVector3D::dotProduct(theDirection, inBounds.maximum) : QVector3D::dotProduct(theDirection, inBounds.minimum)); - QSSGRenderRay relativeRay(theTransformedOrigin, theTransformedDirection); - QSSGOption<QVector3D> localIsect = relativeRay.intersect(thePlane); + const QSSGRenderRay relativeRay(theTransformedOrigin, theTransformedDirection); + QSSGOption<QVector3D> localIsect = QSSGRenderRay::intersect(thePlane, relativeRay); if (localIsect.hasValue()) { float xRange = QVector3D::dotProduct(theRight, inBounds.maximum) - QVector3D::dotProduct(theRight, inBounds.minimum); float yRange = QVector3D::dotProduct(theUp, inBounds.maximum) - QVector3D::dotProduct(theUp, inBounds.minimum); diff --git a/src/runtimerender/qssgrenderray_p.h b/src/runtimerender/qssgrenderray_p.h index 3b8ebd13001bc977b099935cb54ab9a55ac2531f..6f915e1e25debfceceb92bdcb2f20ca05f91df9e 100644 --- a/src/runtimerender/qssgrenderray_p.h +++ b/src/runtimerender/qssgrenderray_p.h @@ -68,7 +68,7 @@ struct QSSGRenderRay { } // If we are parallel, then no intersection of course. - QSSGOption<QVector3D> intersect(const QSSGPlane &inPlane) const; + static QSSGOption<QVector3D> intersect(const QSSGPlane &inPlane, const QSSGRenderRay &ray); struct IntersectionResult { @@ -85,8 +85,10 @@ struct QSSGRenderRay {} }; - IntersectionResult intersectWithAABB(const QMatrix4x4 &inGlobalTransform, const QSSGBounds3 &inBounds, - bool inForceIntersect = false) const; + static IntersectionResult intersectWithAABB(const QMatrix4x4 &inGlobalTransform, + const QSSGBounds3 &inBounds, + const QSSGRenderRay &ray, + bool inForceIntersect = false); QSSGOption<QVector2D> relative(const QMatrix4x4 &inGlobalTransform, const QSSGBounds3 &inBounds, diff --git a/src/runtimerender/rendererimpl/qssgrendererimpl.cpp b/src/runtimerender/rendererimpl/qssgrendererimpl.cpp index bee98d9c5e478db9cbe51ab91e7569615db46219..24c3ec447eed11c2978e684e873ef383371fdc2d 100644 --- a/src/runtimerender/rendererimpl/qssgrendererimpl.cpp +++ b/src/runtimerender/rendererimpl/qssgrendererimpl.cpp @@ -888,14 +888,14 @@ void QSSGRendererImpl::intersectRayWithSubsetRenderable(const QSSGRef<QSSGBuffer if (modelBounds.isEmpty()) return; - QSSGRenderRay::IntersectionResult intersectionResult = inRay.intersectWithAABB(globalTransform, modelBounds); + QSSGRenderRay::IntersectionResult intersectionResult = QSSGRenderRay::intersectWithAABB(globalTransform, modelBounds, inRay); // If we don't intersect with the model at all, then there's no need to go furher down! if (!intersectionResult.intersects) return; for (const auto &subMesh : subMeshes) { - intersectionResult = inRay.intersectWithAABB(globalTransform, subMesh.bounds); + intersectionResult = QSSGRenderRay::intersectWithAABB(globalTransform, subMesh.bounds, inRay); if (intersectionResult.intersects) break; } @@ -914,7 +914,7 @@ void QSSGRendererImpl::intersectRayWithSubsetRenderable(const QSSGRenderRay &inR QSSGRenderableObject &inRenderableObject, TPickResultArray &outIntersectionResultList) { - QSSGRenderRay::IntersectionResult intersectionResult = inRay.intersectWithAABB(inRenderableObject.globalTransform, inRenderableObject.bounds); + QSSGRenderRay::IntersectionResult intersectionResult = QSSGRenderRay::intersectWithAABB(inRenderableObject.globalTransform, inRenderableObject.bounds, inRay); if (!intersectionResult.intersects) return;