Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qssgrenderer_closest_point_p.h
Go to the documentation of this file.
1// Copyright (C) 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3// Qt-Security score:significant reason:default
4
5
6#ifndef QSSG_RENDERER_CLOSEST_POINT_P_H
7#define QSSG_RENDERER_CLOSEST_POINT_P_H
8
9#include <QVector3D>
10
11#include <cstdlib>
12
13QT_BEGIN_NAMESPACE
14
15namespace {
16
17// Closest point on triangle ABC to point p, using metric defined by template class
18// This code is based on: https://github.com/RenderKit/embree/blob/master/tutorials/common/math/closest_point.h
19
20template<class Dot>
21static QVector3D closestPointOnTriangle(const QVector3D &p,
22 const QVector3D &a,
23 const QVector3D &b,
24 const QVector3D &c,
25 const Dot &dot,
26 float &u, float &v, float &w)
27{
28 const QVector3D ab = b - a;
29 const QVector3D ac = c - a;
30 const QVector3D ap = p - a;
31
32 // Vertex region A
33 const float d1 = dot(ab, ap);
34 const float d2 = dot(ac, ap);
35 if (d1 <= 0.f && d2 <= 0.f) {
36 u = 1.0f; v = 0.0f; w = 0.0f;
37 return a;
38 }
39
40 // Vertex region B
41 const QVector3D bp = p - b;
42 const float d3 = dot(ab, bp);
43 const float d4 = dot(ac, bp);
44 if (d3 >= 0.f && d4 <= d3) {
45 u = 0.0f; v = 1.0f; w = 0.0f;
46 return b;
47 }
48
49 // Edge AB
50 const float vc = d1 * d4 - d3 * d2;
51 if (vc <= 0.f && d1 >= 0.f && d3 <= 0.f) {
52 const float v_edge = d1 / (d1 - d3);
53 u = 1.0f - v_edge; v = v_edge; w = 0.0f;
54 return a + v_edge * ab;
55 }
56
57 // Vertex region C
58 const QVector3D cp = p - c;
59 const float d5 = dot(ab, cp);
60 const float d6 = dot(ac, cp);
61 if (d6 >= 0.f && d5 <= d6) {
62 u = 0.0f; v = 0.0f; w = 1.0f;
63 return c;
64 }
65
66 // Edge AC
67 const float vb = d5 * d2 - d1 * d6;
68 if (vb <= 0.f && d2 >= 0.f && d6 <= 0.f) {
69 const float w_edge = d2 / (d2 - d6);
70 u = 1.0f - w_edge; v = 0.0f; w = w_edge;
71 return a + w_edge * ac;
72 }
73
74 // Edge BC
75 const float va = d3 * d6 - d5 * d4;
76 if (va <= 0.f && (d4 - d3) >= 0.f && (d5 - d6) >= 0.f) {
77 const QVector3D bc = c - b;
78 const float w_edge = (d4 - d3) / ((d4 - d3) + (d5 - d6));
79 u = 0.0f; v = 1.0f - w_edge; w = w_edge;
80 return b + w_edge * bc;
81 }
82
83 // Inside face region
84 const float denom = va + vb + vc;
85
86 // Check for degenerate case
87 if (std::abs(denom) < 1e-20f) {
88 // Degenerate triangle in metric space: fall back to closest among vertices
89 const float da = dot(ap, ap);
90 const float db = dot(bp, bp);
91 const float dc = dot(cp, cp);
92 if (da <= db && da <= dc) {
93 u = 1.0f; v = 0.0f; w = 0.0f;
94 return a;
95 }
96 if (db <= dc) {
97 u = 0.0f; v = 1.0f; w = 0.0f;
98 return b;
99 }
100 u = 0.0f; v = 0.0f; w = 1.0f;
101 return c;
102 }
103
104 const float invDenom = 1.0f / denom;
105 u = va * invDenom;
106 v = vb * invDenom;
107 w = vc * invDenom;
108 return a + v * ab + w * ac;
109}
110
111} // namespace (anonymous)
112
113QT_END_NAMESPACE
114
115#endif // QSSG_RENDERER_CLOSEST_POINT_P_H
friend class QSSGRenderContextInterface
static QVector3D closestPointOnTriangle(const QVector3D &p, const QVector3D &a, const QVector3D &b, const QVector3D &c, const Dot &dot, float &u, float &v, float &w)
static void cleanupResourcesImpl(const QSSGRenderContextInterface &rci, const Container &resources)
static void getPickableRecursive(const QSSGRenderNode &node, RenderableList &renderables, bool pickEverything=false)
static void dfs(const QSSGRenderNode &node, RenderableList &renderables)
static QByteArray rendererLogPrefix()
static QSSGCullFaceMode mirroredCullMode(QSSGCullFaceMode cullMode)
static QSSGCullFaceMode cullModeForSubset(const QSSGRenderModel &model, int subset)