1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
// Copyright (C) 2008-2012 NVIDIA Corporation.
// Copyright (C) 2019 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef QSSG_RENDER_RAY_H
#define QSSG_RENDER_RAY_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtQuick3DUtils/private/qssgbounds3_p.h>
#include <QtQuick3DUtils/private/qssgplane_p.h>
#include <QtGui/QVector2D>
#include <QtGui/QVector3D>
#include <QtGui/QMatrix4x4>
#include <optional>
QT_BEGIN_NAMESPACE
class QSSGMeshBVHNode;
struct QSSGRenderMesh;
struct QSSGMeshBVHTriangle;
enum class QSSGRenderBasisPlanes
{
XY,
YZ,
XZ,
};
struct Q_AUTOTEST_EXPORT QSSGRenderRay
{
QVector3D origin;
QVector3D direction;
QSSGRenderRay() = default;
QSSGRenderRay(const QVector3D &inOrigin, const QVector3D &inDirection)
: origin(inOrigin), direction(inDirection)
{
}
// If we are parallel, then no intersection of course.
static std::optional<QVector3D> intersect(const QSSGPlane &inPlane, const QSSGRenderRay &ray);
// Perform an intersection aslo returning Barycentric Coordinates
static bool triangleIntersect(const QSSGRenderRay &ray,
const QVector3D &v0,
const QVector3D &v1,
const QVector3D &v2,
float &u,
float &v,
QVector3D &normal);
struct IntersectionResult
{
bool intersects = false;
float rayLengthSquared = 0.; // Length of the ray in world coordinates for the hit.
QVector2D relXY; // UV coords for further mouse picking against a offscreen-rendered object.
QVector3D scenePosition;
QVector3D localPosition;
QVector3D faceNormal;
IntersectionResult() = default;
inline constexpr IntersectionResult(float rl,
const QVector2D &relxy,
const QVector3D &scenePosition,
const QVector3D &localPosition,
const QVector3D &normal)
: intersects(true)
, rayLengthSquared(rl)
, relXY(relxy)
, scenePosition(scenePosition)
, localPosition(localPosition)
, faceNormal(normal)
{}
};
struct HitResult
{
float min;
float max;
const QSSGBounds3 *bounds;
inline bool intersects() const { return bounds && max >= std::max(min, 0.0f); }
};
struct RayData
{
enum class DirectionOp : quint8
{
Normal,
Swap,
Zero = 0x10
};
const QMatrix4x4 &globalTransform;
const QSSGRenderRay &ray;
// Cached data calculated from the global transform and the ray
const QVector3D origin;
const QVector3D directionInvers;
const QVector3D direction;
const DirectionOp dirOp[3];
};
static RayData createRayData(const QMatrix4x4 &globalTransform,
const QSSGRenderRay &ray);
static IntersectionResult createIntersectionResult(const RayData &data,
const HitResult &hit);
static HitResult intersectWithAABBv2(const RayData &data,
const QSSGBounds3 &bounds);
static void intersectWithBVH(const RayData &data,
const QSSGMeshBVHNode *bvh,
const QSSGRenderMesh *mesh,
QVector<IntersectionResult> &intersections,
int depth = 0);
static QVector<IntersectionResult> intersectWithBVHTriangles(const RayData &data,
const std::vector<QSSGMeshBVHTriangle> &bvhTriangles,
int triangleOffset,
int triangleCount);
std::optional<QVector2D> relative(const QMatrix4x4 &inGlobalTransform,
const QSSGBounds3 &inBounds,
QSSGRenderBasisPlanes inPlane) const;
std::optional<QVector2D> relativeXY(const QMatrix4x4 &inGlobalTransform, const QSSGBounds3 &inBounds) const
{
return relative(inGlobalTransform, inBounds, QSSGRenderBasisPlanes::XY);
}
};
QT_END_NAMESPACE
#endif
|