File: tst_picking.cpp

package info (click to toggle)
qt6-quick3d 6.10.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 143,588 kB
  • sloc: cpp: 395,989; ansic: 41,469; xml: 288; sh: 242; makefile: 32
file content (123 lines) | stat: -rw-r--r-- 4,090 bytes parent folder | download
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
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only

#include <QtTest>

#include <ssg/qssgrendercontextcore.h>

#include <QtQuick3DRuntimeRender/private/qssgrhicustommaterialsystem_p.h>
#include <QtQuick3DRuntimeRender/private/qssgdebugdrawsystem_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrendershadercodegenerator_p.h>

#include <QtQuick3DRuntimeRender/private/qssgrenderer_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrenderpickresult_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrendermodel_p.h>

class picking : public QObject
{
    Q_OBJECT

public:
    picking();
    ~picking() = default;

private Q_SLOTS:
    void initTestCase();
    void bench_picking1();
    void bench_picking1Miss();
    void bench_picking1in1k();
    void bench_picking1in1kMiss();

private:
    std::unique_ptr<QSSGRenderContextInterface> renderCtx;

    void benchImpl(int count, bool hit);
};

picking::picking()
    : renderCtx(std::make_unique<QSSGRenderContextInterface>(std::make_unique<QSSGBufferManager>()
                                                             , std::make_unique<QSSGRenderer>()
                                                             , nullptr
                                                             , nullptr
                                                             , nullptr
                                                             , nullptr
                                                             , std::make_unique<QSSGRhiContext>(QRhi::create(QRhi::Implementation::Null, nullptr))))
{
}

void picking::initTestCase()
{
    QSKIP("Test does not work with the RHI implementation at the moment");
}

void picking::bench_picking1()
{
    benchImpl(1, true);
}

void picking::bench_picking1Miss()
{
    benchImpl(1, false);
}

void picking::bench_picking1in1k()
{
    benchImpl(1000, true);
}

void picking::bench_picking1in1kMiss()
{
    benchImpl(1, false);
}

void picking::benchImpl(int count, bool hit)
{
    Q_ASSERT(count > 0 && count <= 1000);
    const auto &bufferManager = renderCtx->bufferManager();
    QVector2D viewportDim(400.0f, 400.0f);
    QSSGRenderLayer dummyLayer;
    QMatrix4x4 globalTransform;
    QMatrix4x4 viewProjection;

    QSSGRenderCamera dummyCamera(QSSGRenderCamera::Type::OrthographicCamera);
    dummyCamera.localTransform.translate(QVector3D(0.0f, 0.0f, 600.0f));
    static_cast<QSSGRenderNode &>(dummyCamera).markDirty(QSSGRenderNode::DirtyFlag::TransformDirty);
    QSSGRenderCamera::calculateProjectionInternal(dummyCamera, QRectF(QPointF(), QSizeF(viewportDim.x(), viewportDim.y())));
    dummyCamera.calculateViewProjectionMatrix(globalTransform, viewProjection);

    dummyLayer.renderedCameras = { &dummyCamera };

    static const auto setModelPosition = [](QSSGRenderModel &model, const QVector3D &pos) {
        model.localTransform.translate(pos);
        model.markDirty(QSSGRenderNode::DirtyFlag::TransformDirty);
    };

    QSSGRenderModel models[1000];

    const auto cubeMeshPath = QSSGRenderPath(QStringLiteral("#Cube"));

    for (int i = 0; i != count; ++i) {
        auto &model = models[i];
        model.meshPath = cubeMeshPath;
        model.setState(QSSGRenderModel::LocalState::Pickable);
        setModelPosition(model, { 0.0f + i, 0.0f + i, 0.0f + i });
        dummyLayer.addChild(model);
    }

    // Since we're using the same mesh for each model, we only need to call loadMesh() once.
    bufferManager->loadMesh(models[0]);

    QVarLengthArray<QSSGRenderPickResult, 20> res;
    QSSGRenderRay ray = hit ? QSSGRenderRay{ { 0.0f, 0.0f, -100.0f }, { 0.0f, 0.0f, 1.0f } } : QSSGRenderRay{ { 0.0f, 0.0f, -100.0f }, { 1.0f, 0.0f, 0.0f } };
    QBENCHMARK {
        res = QSSGRendererPrivate::syncPick(*renderCtx, dummyLayer, ray);
    }
    QVERIFY(!res.isEmpty());
    QVERIFY(res.first().m_hitObject != nullptr);
}

QTEST_APPLESS_MAIN(picking)

#include "tst_picking.moc"