aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/geometry_update/tilegeometry.cpp
blob: a7574c78f93e2dd9b04e225d1d4d9a09381a1372 (plain)
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only

#include "tilegeometry.h"
#include <QtGui/QVector3D>
#include <array>

struct QObjMesh
{
    std::vector<unsigned int> indices;
    std::vector<QVector3D> vertices;
    std::vector<QVector2D> uvs;
};

QObjMesh calcUVs(const QObjMesh &obj)
{
    QObjMesh result = obj;
    QVector3D min = QVector3D(123456789.f, 123456789.f, 123456789.f);
    QVector3D max = QVector3D(-123456789.f, -123456789.f, -123456789.f);

    for (const auto &v : obj.vertices) {
        min.setX(qMin(v.x(), min.x()));
        min.setY(qMin(v.y(), min.y()));
        min.setZ(qMin(v.z(), min.z()));
        max.setX(qMax(v.x(), max.x()));
        max.setY(qMax(v.y(), max.y()));
        max.setZ(qMax(v.z(), max.z()));
    }

    QVector3D len = (max - min);

    for (const auto &v : obj.vertices) {
        QVector3D vmin = (v - min);
        result.uvs.push_back(QVector2D(vmin.x() / len.x(), vmin.z() / len.z()));
    }

    return result;
}

QObjMesh getHoleMesh()
{
    QObjMesh mesh;
    mesh.vertices = {
        QVector3D(-50, 0, 50),   QVector3D(-50, 0, 25),   QVector3D(-21, 0, 21),   QVector3D(-25, 0, 50),
        QVector3D(-25, 0, 50),   QVector3D(-21, 0, 21),   QVector3D(0, 0, 30),     QVector3D(0, 0, 50),
        QVector3D(0, 0, 50),     QVector3D(0, 0, 30),     QVector3D(21, 0, 21),    QVector3D(25, 0, 50),
        QVector3D(25, 0, 50),    QVector3D(21, 0, 21),    QVector3D(50, 0, 25),    QVector3D(50, 0, 50),
        QVector3D(-50, 0, 25),   QVector3D(-50, 0, 0),    QVector3D(-30, 0, 0),    QVector3D(-21, 0, 21),
        QVector3D(21, 0, 21),    QVector3D(30, 0, 0),     QVector3D(50, 0, 0),     QVector3D(50, 0, 25),
        QVector3D(-50, 0, 0),    QVector3D(-50, 0, -25),  QVector3D(-21, 0, -21),  QVector3D(-30, 0, 0),
        QVector3D(30, 0, 0),     QVector3D(21, 0, -21),   QVector3D(50, 0, -25),   QVector3D(50, 0, 0),
        QVector3D(-50, 0, -25),  QVector3D(-50, 0, -50),  QVector3D(-25, 0, -50),  QVector3D(-21, 0, -21),
        QVector3D(-21, 0, -21),  QVector3D(-25, 0, -50),  QVector3D(0, 0, -50),    QVector3D(0, 0, -30),
        QVector3D(0, 0, -30),    QVector3D(0, 0, -50),    QVector3D(25, 0, -50),   QVector3D(21, 0, -21),
        QVector3D(21, 0, -21),   QVector3D(25, 0, -50),   QVector3D(50, 0, -50),   QVector3D(50, 0, -25),
        QVector3D(-50, 10, 50),  QVector3D(-25, 10, 50),  QVector3D(-21, 10, 21),  QVector3D(-50, 10, 25),
        QVector3D(-25, 10, 50),  QVector3D(0, 10, 50),    QVector3D(0, 10, 30),    QVector3D(-21, 10, 21),
        QVector3D(0, 10, 50),    QVector3D(25, 10, 50),   QVector3D(21, 10, 21),   QVector3D(0, 10, 30),
        QVector3D(25, 10, 50),   QVector3D(50, 10, 50),   QVector3D(50, 10, 25),   QVector3D(21, 10, 21),
        QVector3D(-50, 10, 25),  QVector3D(-21, 10, 21),  QVector3D(-30, 10, 0),   QVector3D(-50, 10, 0),
        QVector3D(21, 10, 21),   QVector3D(50, 10, 25),   QVector3D(50, 10, 0),    QVector3D(30, 10, 0),
        QVector3D(-50, 10, 0),   QVector3D(-30, 10, 0),   QVector3D(-21, 10, -21), QVector3D(-50, 10, -25),
        QVector3D(30, 10, 0),    QVector3D(50, 10, 0),    QVector3D(50, 10, -25),  QVector3D(21, 10, -21),
        QVector3D(-50, 10, -25), QVector3D(-21, 10, -21), QVector3D(-25, 10, -50), QVector3D(-50, 10, -50),
        QVector3D(-21, 10, -21), QVector3D(0, 10, -30),   QVector3D(0, 10, -50),   QVector3D(-25, 10, -50),
        QVector3D(0, 10, -30),   QVector3D(21, 10, -21),  QVector3D(25, 10, -50),  QVector3D(0, 10, -50),
        QVector3D(21, 10, -21),  QVector3D(50, 10, -25),  QVector3D(50, 10, -50),  QVector3D(25, 10, -50),
        QVector3D(30, 0, 0),     QVector3D(21, 0, 21),    QVector3D(21, 10, 21),   QVector3D(30, 10, 0),
        QVector3D(21, 0, 21),    QVector3D(0, 0, 30),     QVector3D(0, 10, 30),    QVector3D(21, 10, 21),
        QVector3D(0, 0, -30),    QVector3D(21, 0, -21),   QVector3D(21, 10, -21),  QVector3D(0, 10, -30),
        QVector3D(-30, 0, 0),    QVector3D(-21, 0, -21),  QVector3D(-21, 10, -21), QVector3D(-30, 10, 0),
        QVector3D(0, 0, 30),     QVector3D(-21, 0, 21),   QVector3D(-21, 10, 21),  QVector3D(0, 10, 30),
        QVector3D(-21, 0, 21),   QVector3D(-30, 0, 0),    QVector3D(-30, 10, 0),   QVector3D(-21, 10, 21),
        QVector3D(-21, 0, -21),  QVector3D(0, 0, -30),    QVector3D(0, 10, -30),   QVector3D(-21, 10, -21),
        QVector3D(21, 0, -21),   QVector3D(30, 0, 0),     QVector3D(30, 10, 0),    QVector3D(21, 10, -21)
    };

    mesh.indices = { 0,   1,   3,   1,   2,   3,   4,   5,   7,   5,   6,   7,   8,   9,   11,  9,   10,  11,  12,  13,
                     15,  13,  14,  15,  16,  17,  19,  17,  18,  19,  20,  21,  23,  21,  22,  23,  24,  25,  27,  25,
                     26,  27,  28,  29,  31,  29,  30,  31,  32,  33,  35,  33,  34,  35,  36,  37,  39,  37,  38,  39,
                     40,  41,  43,  41,  42,  43,  44,  45,  47,  45,  46,  47,  48,  49,  51,  49,  50,  51,  52,  53,
                     55,  53,  54,  55,  56,  57,  59,  57,  58,  59,  60,  61,  63,  61,  62,  63,  64,  65,  67,  65,
                     66,  67,  68,  69,  71,  69,  70,  71,  72,  73,  75,  73,  74,  75,  76,  77,  79,  77,  78,  79,
                     80,  81,  83,  81,  82,  83,  84,  85,  87,  85,  86,  87,  88,  89,  91,  89,  90,  91,  92,  93,
                     95,  93,  94,  95,  96,  97,  99,  97,  98,  99,  100, 101, 103, 101, 102, 103, 104, 105, 107, 105,
                     106, 107, 108, 109, 111, 109, 110, 111, 112, 113, 115, 113, 114, 115, 116, 117, 119, 117, 118, 119,
                     120, 121, 123, 121, 122, 123, 124, 125, 127, 125, 126, 127 };

    return mesh;
}

QObjMesh getFloorMesh()
{
    QObjMesh mesh;
    mesh.vertices = {
        QVector3D(-50, 0, 50),   QVector3D(-50, 0, 25),   QVector3D(-25, 0, 25),   QVector3D(-25, 0, 50),
        QVector3D(-25, 0, 50),   QVector3D(-25, 0, 25),   QVector3D(0, 0, 25),     QVector3D(0, 0, 50),
        QVector3D(0, 0, 50),     QVector3D(0, 0, 25),     QVector3D(25, 0, 25),    QVector3D(25, 0, 50),
        QVector3D(25, 0, 50),    QVector3D(25, 0, 25),    QVector3D(50, 0, 25),    QVector3D(50, 0, 50),
        QVector3D(-50, 0, 25),   QVector3D(-50, 0, 0),    QVector3D(-25, 0, 0),    QVector3D(-25, 0, 25),
        QVector3D(-25, 0, 25),   QVector3D(-25, 0, 0),    QVector3D(0, 0, 0),      QVector3D(0, 0, 25),
        QVector3D(0, 0, 25),     QVector3D(0, 0, 0),      QVector3D(25, 0, 0),     QVector3D(25, 0, 25),
        QVector3D(25, 0, 25),    QVector3D(25, 0, 0),     QVector3D(50, 0, 0),     QVector3D(50, 0, 25),
        QVector3D(-50, 0, 0),    QVector3D(-50, 0, -25),  QVector3D(-25, 0, -25),  QVector3D(-25, 0, 0),
        QVector3D(-25, 0, 0),    QVector3D(-25, 0, -25),  QVector3D(0, 0, -25),    QVector3D(0, 0, 0),
        QVector3D(0, 0, 0),      QVector3D(0, 0, -25),    QVector3D(25, 0, -25),   QVector3D(25, 0, 0),
        QVector3D(25, 0, 0),     QVector3D(25, 0, -25),   QVector3D(50, 0, -25),   QVector3D(50, 0, 0),
        QVector3D(-50, 0, -25),  QVector3D(-50, 0, -50),  QVector3D(-25, 0, -50),  QVector3D(-25, 0, -25),
        QVector3D(-25, 0, -25),  QVector3D(-25, 0, -50),  QVector3D(0, 0, -50),    QVector3D(0, 0, -25),
        QVector3D(0, 0, -25),    QVector3D(0, 0, -50),    QVector3D(25, 0, -50),   QVector3D(25, 0, -25),
        QVector3D(25, 0, -25),   QVector3D(25, 0, -50),   QVector3D(50, 0, -50),   QVector3D(50, 0, -25),
        QVector3D(-50, 10, 50),  QVector3D(-25, 10, 50),  QVector3D(-25, 10, 25),  QVector3D(-50, 10, 25),
        QVector3D(-25, 10, 50),  QVector3D(0, 10, 50),    QVector3D(0, 10, 25),    QVector3D(-25, 10, 25),
        QVector3D(0, 10, 50),    QVector3D(25, 10, 50),   QVector3D(25, 10, 25),   QVector3D(0, 10, 25),
        QVector3D(25, 10, 50),   QVector3D(50, 10, 50),   QVector3D(50, 10, 25),   QVector3D(25, 10, 25),
        QVector3D(-50, 10, 25),  QVector3D(-25, 10, 25),  QVector3D(-25, 10, 0),   QVector3D(-50, 10, 0),
        QVector3D(-25, 10, 25),  QVector3D(0, 10, 25),    QVector3D(0, 10, 0),     QVector3D(-25, 10, 0),
        QVector3D(0, 10, 25),    QVector3D(25, 10, 25),   QVector3D(25, 10, 0),    QVector3D(0, 10, 0),
        QVector3D(25, 10, 25),   QVector3D(50, 10, 25),   QVector3D(50, 10, 0),    QVector3D(25, 10, 0),
        QVector3D(-50, 10, 0),   QVector3D(-25, 10, 0),   QVector3D(-25, 10, -25), QVector3D(-50, 10, -25),
        QVector3D(-25, 10, 0),   QVector3D(0, 10, 0),     QVector3D(0, 10, -25),   QVector3D(-25, 10, -25),
        QVector3D(0, 10, 0),     QVector3D(25, 10, 0),    QVector3D(25, 10, -25),  QVector3D(0, 10, -25),
        QVector3D(25, 10, 0),    QVector3D(50, 10, 0),    QVector3D(50, 10, -25),  QVector3D(25, 10, -25),
        QVector3D(-50, 10, -25), QVector3D(-25, 10, -25), QVector3D(-25, 10, -50), QVector3D(-50, 10, -50),
        QVector3D(-25, 10, -25), QVector3D(0, 10, -25),   QVector3D(0, 10, -50),   QVector3D(-25, 10, -50),
        QVector3D(0, 10, -25),   QVector3D(25, 10, -25),  QVector3D(25, 10, -50),  QVector3D(0, 10, -50),
        QVector3D(25, 10, -25),  QVector3D(50, 10, -25),  QVector3D(50, 10, -50),  QVector3D(25, 10, -50)
    };

    mesh.indices = { 0,   1,   3,   1,   2,   3,   4,   5,   7,   5,   6,   7,   8,   9,   11,  9,   10,  11,  12,  13,
                     15,  13,  14,  15,  16,  17,  19,  17,  18,  19,  20,  21,  23,  21,  22,  23,  24,  25,  27,  25,
                     26,  27,  28,  29,  31,  29,  30,  31,  32,  33,  35,  33,  34,  35,  36,  37,  39,  37,  38,  39,
                     40,  41,  43,  41,  42,  43,  44,  45,  47,  45,  46,  47,  48,  49,  51,  49,  50,  51,  52,  53,
                     55,  53,  54,  55,  56,  57,  59,  57,  58,  59,  60,  61,  63,  61,  62,  63,  64,  65,  67,  65,
                     66,  67,  68,  69,  71,  69,  70,  71,  72,  73,  75,  73,  74,  75,  76,  77,  79,  77,  78,  79,
                     80,  81,  83,  81,  82,  83,  84,  85,  87,  85,  86,  87,  88,  89,  91,  89,  90,  91,  92,  93,
                     95,  93,  94,  95,  96,  97,  99,  97,  98,  99,  100, 101, 103, 101, 102, 103, 104, 105, 107, 105,
                     106, 107, 108, 109, 111, 109, 110, 111, 112, 113, 115, 113, 114, 115, 116, 117, 119, 117, 118, 119,
                     120, 121, 123, 121, 122, 123, 124, 125, 127, 125, 126, 127 };

    return mesh;
}

void TileGeometry::createFloor()
{
    auto mesh = calcUVs(m_hasHole ? getHoleMesh() : getFloorMesh());

    // pos + uv
    constexpr int kStride = sizeof(QVector3D) + sizeof(QVector2D);
    QByteArray vertexData(mesh.vertices.size() * kStride, Qt::Initialization::Uninitialized);

    for (size_t i = 0; i < mesh.vertices.size(); i++) {
        QVector3D *vertex = reinterpret_cast<QVector3D *>(vertexData.data() + (kStride * i));
        QVector2D *uv = reinterpret_cast<QVector2D *>(vertexData.data() + (kStride * i) + sizeof(QVector3D));
        *vertex = mesh.vertices[i];
        *uv = mesh.uvs[i];
    }

    QByteArray indexBuffer(mesh.indices.size() * sizeof(unsigned int), Qt::Initialization::Uninitialized);
    memcpy(indexBuffer.data(), mesh.indices.data(), mesh.indices.size() * sizeof(unsigned int));

    clear();
    setVertexData(vertexData);
    setStride(kStride);
    setBounds(QVector3D(-50.0f, -50.0f, -50.0f), QVector3D(+50.0f, +50.0f, +50.0f));
    setPrimitiveType(QQuick3DGeometry::PrimitiveType::Triangles);
    addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0, QQuick3DGeometry::Attribute::F32Type);
    addAttribute(QQuick3DGeometry::Attribute::TexCoordSemantic, sizeof(QVector3D), QQuick3DGeometry::Attribute::F32Type);
    addAttribute(QQuick3DGeometry::Attribute::IndexSemantic, 0, QQuick3DGeometry::Attribute::U32Type);
    setIndexData(indexBuffer);
    update();
}

TileGeometry::TileGeometry()
{
    createFloor();
}

void TileGeometry::setHasHole(bool v)
{
    if (m_hasHole == v)
        return;
    m_hasHole = v;
    createFloor();
    emit hasHoleChanged(v);
}

bool TileGeometry::hasHole()
{
    return m_hasHole;
}