1// Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QT3DRENDER_QAXISALIGNEDBOUNDINGBOX_P_H
5#define QT3DRENDER_QAXISALIGNEDBOUNDINGBOX_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of other Qt classes. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <vector>
19#include <QMatrix4x4>
20#include <QVector3D>
21
22#include <Qt3DRender/private/qt3drender_global_p.h>
23
24QT_BEGIN_NAMESPACE
25
26class QDebug;
27
28namespace Qt3DRender {
29
30class QAxisAlignedBoundingBox
31{
32public:
33 inline QAxisAlignedBoundingBox()
34 : m_center()
35 , m_radii()
36 {}
37
38 inline explicit QAxisAlignedBoundingBox(const std::vector<QVector3D> &points)
39 : m_center()
40 , m_radii()
41 {
42 update(points);
43 }
44
45 void clear()
46 {
47 m_center = QVector3D();
48 m_radii = QVector3D();
49 }
50
51 bool isNull() const { return m_center.isNull() && m_radii.isNull(); }
52
53 void Q_3DRENDERSHARED_PRIVATE_EXPORT update(const std::vector<QVector3D> &points);
54
55 inline QVector3D center() const { return m_center; }
56 inline QVector3D radii() const { return m_radii; }
57
58 inline QVector3D minPoint() const { return m_center - m_radii; }
59 inline QVector3D maxPoint() const { return m_center + m_radii; }
60
61 inline float xExtent() const { return 2.0f * m_radii.x(); }
62 inline float yExtent() const { return 2.0f * m_radii.y(); }
63 inline float zExtent() const { return 2.0f * m_radii.z(); }
64
65 inline float maxExtent() const { return qMax( a: xExtent(), b: qMax( a: yExtent(), b: zExtent() ) ); }
66 inline float minExtent() const { return qMin( a: xExtent(), b: qMin( a: yExtent(), b: zExtent() ) ); }
67
68 inline bool contains( const QVector3D& pt ) const
69 {
70 QVector3D minP(minPoint()), maxP(maxPoint());
71 if ((pt.x() < minP.x()) || (pt.x() > maxP.x()) ||
72 (pt.y() < minP.y()) || (pt.y() > maxP.y()) ||
73 (pt.z() < minP.z()) || (pt.z() > maxP.z()) )
74 {
75 return false;
76 }
77 return true;
78 }
79
80 inline void expandToContain(const QVector3D &pt)
81 {
82 update(points: std::vector<QVector3D> { pt });
83 }
84
85 inline void expandToContain(const QAxisAlignedBoundingBox &other)
86 {
87 update(points: std::vector<QVector3D> { other.minPoint(), other.maxPoint() });
88 }
89
90 inline QAxisAlignedBoundingBox transformBy(const QMatrix4x4 &mat) const
91 {
92 QAxisAlignedBoundingBox r;
93 r.m_center = mat.map(point: m_center);
94 r.m_radii = mat.map(point: m_radii);
95 return r;
96 }
97
98 inline QAxisAlignedBoundingBox &transform(const QMatrix4x4 &mat)
99 {
100 m_center = mat.map(point: m_center);
101 m_radii = mat.map(point: m_radii);
102 return *this;
103 }
104
105private:
106 QVector3D m_center;
107 QVector3D m_radii;
108
109 friend bool intersects(const QAxisAlignedBoundingBox &a,
110 const QAxisAlignedBoundingBox &b);
111};
112
113QDebug operator<<(QDebug dbg, const QAxisAlignedBoundingBox &c);
114
115inline bool intersects(const QAxisAlignedBoundingBox &a,
116 const QAxisAlignedBoundingBox &b)
117{
118 // Test y axis last as this is often the least discriminatory in OpenGL applications
119 // where worlds tend to be mostly in the xz-plane
120 if (qAbs(t: a.m_center[0] - b.m_center[0]) > a.m_radii[0] + b.m_radii[0])
121 return false;
122 if (qAbs(t: a.m_center[2] - b.m_center[2]) > a.m_radii[2] + b.m_radii[2])
123 return false;
124 if (qAbs(t: a.m_center[1] - b.m_center[1]) > a.m_radii[1] + b.m_radii[1])
125 return false;
126 return true;
127}
128
129} // namespace Qt3DRender
130
131QT_END_NAMESPACE
132
133#endif // QT3DRENDER_QAXISALIGNEDBOUNDINGBOX_P_H
134

source code of qt3d/src/render/io/qaxisalignedboundingbox_p.h