1 | // Copyright (C) 2021 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include <QtQuick3DRuntimeRender/private/qssgrenderparticles_p.h> |
5 | #include <cmath> |
6 | |
7 | QT_BEGIN_NAMESPACE |
8 | |
9 | static int divisibleBy(int a, int b) |
10 | { |
11 | return (a % b) ? a + b - (a % b) : a; |
12 | } |
13 | static int ceilDivide(int a, int b) |
14 | { |
15 | int x = a / b; |
16 | int y = (a % b) ? 1 : 0; |
17 | return x + y; |
18 | } |
19 | |
20 | void QSSGParticleBuffer::resize(int particleCount, int particleSize) |
21 | { |
22 | if (particleCount == 0) { |
23 | m_particlesPerSlice = 0; |
24 | m_particleCount = 0; |
25 | m_sliceStride = 0; |
26 | m_size = QSize(); |
27 | m_particleBuffer.resize(size: 0); |
28 | return; |
29 | } |
30 | int vec4PerParticle = ceilDivide(a: particleSize, b: 16); |
31 | int vec4s = particleCount * vec4PerParticle; |
32 | int width = divisibleBy(a: std::sqrt(x: vec4s), b: vec4PerParticle); |
33 | int height = ceilDivide(a: vec4s, b: width); |
34 | m_particlesPerSlice = width / vec4PerParticle; |
35 | m_particleCount = particleCount; |
36 | width = divisibleBy(a: width, b: 4); |
37 | height = divisibleBy(a: height, b: 4); |
38 | m_sliceStride = width * 16; |
39 | m_size = QSize(width, height); |
40 | m_particleBuffer.resize(size: m_sliceStride * height); |
41 | } |
42 | |
43 | void QSSGParticleBuffer::resizeLine(int particleCount, int segmentCount) |
44 | { |
45 | m_segments = segmentCount; |
46 | resize(particleCount: particleCount * segmentCount, particleSize: sizeof(QSSGLineParticle)); |
47 | } |
48 | |
49 | void QSSGParticleBuffer::setBounds(const QSSGBounds3& bounds) |
50 | { |
51 | m_bounds = bounds; |
52 | m_serial++; |
53 | } |
54 | |
55 | char *QSSGParticleBuffer::pointer() |
56 | { |
57 | return m_particleBuffer.data(); |
58 | } |
59 | |
60 | const char *QSSGParticleBuffer::pointer() const |
61 | { |
62 | return m_particleBuffer.constData(); |
63 | } |
64 | |
65 | int QSSGParticleBuffer::particlesPerSlice() const |
66 | { |
67 | return m_particlesPerSlice; |
68 | } |
69 | |
70 | int QSSGParticleBuffer::sliceStride() const |
71 | { |
72 | return m_sliceStride; |
73 | } |
74 | |
75 | int QSSGParticleBuffer::particleCount() const |
76 | { |
77 | return m_particleCount; |
78 | } |
79 | |
80 | QSize QSSGParticleBuffer::size() const |
81 | { |
82 | return m_size; |
83 | } |
84 | |
85 | int QSSGParticleBuffer::sliceCount() const |
86 | { |
87 | return m_size.height(); |
88 | } |
89 | |
90 | QByteArray QSSGParticleBuffer::data() const |
91 | { |
92 | return m_particleBuffer; |
93 | } |
94 | |
95 | int QSSGParticleBuffer::bufferSize() const |
96 | { |
97 | return m_particleBuffer.size(); |
98 | } |
99 | |
100 | int QSSGParticleBuffer::serial() const |
101 | { |
102 | return m_serial; |
103 | } |
104 | |
105 | int QSSGParticleBuffer::segments() const |
106 | { |
107 | return m_segments; |
108 | } |
109 | |
110 | QSSGBounds3 QSSGParticleBuffer::bounds() const |
111 | { |
112 | return m_bounds; |
113 | } |
114 | |
115 | QSSGRenderParticles::QSSGRenderParticles() |
116 | : QSSGRenderNode(QSSGRenderGraphObject::Type::Particles) |
117 | { |
118 | |
119 | } |
120 | |
121 | QT_END_NAMESPACE |
122 | |