1// Copyright (C) 2017 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#include "pointsvisitor_p.h"
5#include <Qt3DCore/qentity.h>
6#include <Qt3DRender/qgeometryrenderer.h>
7#include <Qt3DRender/private/managers_p.h>
8#include <Qt3DRender/private/nodemanagers_p.h>
9#include <Qt3DRender/private/buffermanager_p.h>
10#include <Qt3DRender/private/geometryrenderer_p.h>
11#include <Qt3DRender/private/geometryrenderermanager_p.h>
12#include <Qt3DRender/private/geometry_p.h>
13#include <Qt3DRender/private/attribute_p.h>
14#include <Qt3DRender/private/buffer_p.h>
15#include <Qt3DRender/private/trianglesvisitor_p.h>
16#include <Qt3DRender/private/visitorutils_p.h>
17
18QT_BEGIN_NAMESPACE
19
20namespace Qt3DRender {
21
22namespace Render {
23
24namespace {
25
26// indices, vertices are already offset
27template<typename Index, typename Vertex>
28void traverseCoordinatesIndexed(Index *indices,
29 Vertex *vertices,
30 const BufferInfo &indexInfo,
31 const BufferInfo &vertexInfo,
32 PointsVisitor *visitor)
33{
34 uint i = 0;
35 const uint verticesStride = vertexInfo.byteStride / sizeof(Vertex);
36 const uint maxVerticesDataSize = qMin(a: vertexInfo.dataSize, b: 3U);
37
38 uint ndx;
39 Vector3D abc;
40 while (i < indexInfo.count) {
41 ndx = indices[i];
42 const uint idx = ndx * verticesStride;
43 for (uint j = 0; j < maxVerticesDataSize; ++j) {
44 abc[j] = vertices[idx + j];
45 }
46 visitor->visit(ndx, c: abc);
47 ++i;
48 }
49}
50
51// vertices are already offset
52template<typename Vertex>
53void traverseCoordinates(Vertex *vertices,
54 const BufferInfo &vertexInfo,
55 PointsVisitor *visitor)
56{
57 const uint verticesStride = vertexInfo.byteStride / sizeof(Vertex);
58 const uint maxVerticesDataSize = qMin(a: vertexInfo.dataSize, b: 3U);
59
60 uint ndx = 0;
61 Vector3D abc;
62 while (ndx < vertexInfo.count) {
63 const uint idx = ndx * verticesStride;
64 for (uint j = 0; j < maxVerticesDataSize; ++j)
65 abc[j] = vertices[idx + j];
66 visitor->visit(ndx, c: abc);
67 ++ndx;
68 }
69}
70
71template<typename Index, typename Visitor>
72struct IndexedVertexExecutor
73{
74 template<typename Vertex>
75 void operator ()(const BufferInfo &vertexInfo, Vertex * vertices)
76 {
77 traverseCoordinatesIndexed(m_indices, vertices, m_indexBufferInfo, vertexInfo, m_visitor);
78 }
79
80 BufferInfo m_indexBufferInfo;
81 Index *m_indices;
82 Qt3DRender::QGeometryRenderer::PrimitiveType m_primitiveType;
83 Visitor* m_visitor;
84};
85
86template<typename Visitor>
87struct IndexExecutor
88{
89 template<typename Index>
90 void operator ()( const BufferInfo &indexInfo, Index *indices)
91 {
92 IndexedVertexExecutor<Index, Visitor> exec;
93 exec.m_primitiveType = m_primitiveType;
94 exec.m_indices = indices;
95 exec.m_indexBufferInfo = indexInfo;
96 exec.m_visitor = m_visitor;
97 Qt3DRender::Render::Visitor::processBuffer(m_vertexBufferInfo, exec);
98 }
99
100 BufferInfo m_vertexBufferInfo;
101 Qt3DRender::QGeometryRenderer::PrimitiveType m_primitiveType;
102 Visitor* m_visitor;
103};
104
105template<typename Visitor>
106struct VertexExecutor
107{
108 template<typename Vertex>
109 void operator ()(const BufferInfo &vertexInfo, Vertex *vertices)
110 {
111 switch (m_primitiveType) {
112 case Qt3DRender::QGeometryRenderer::Points:
113 traverseCoordinates(vertices, vertexInfo, m_visitor);
114 return;
115 default:
116 Q_UNREACHABLE_RETURN();
117 }
118 }
119
120 Qt3DRender::QGeometryRenderer::PrimitiveType m_primitiveType;
121 Visitor* m_visitor;
122};
123
124} // anonymous
125
126
127PointsVisitor::~PointsVisitor()
128{
129
130}
131
132void PointsVisitor::apply(const Qt3DCore::QEntity *entity)
133{
134 GeometryRenderer *renderer = m_manager->geometryRendererManager()->lookupResource(id: entity->id());
135 apply(renderer, id: entity->id());
136}
137
138void PointsVisitor::apply(const GeometryRenderer *renderer, const Qt3DCore::QNodeId id)
139{
140 m_nodeId = id;
141 if (renderer && renderer->instanceCount() == 1) {
142 Visitor::visitPrimitives<GeometryRenderer, VertexExecutor<PointsVisitor>,
143 IndexExecutor<PointsVisitor>, PointsVisitor>(manager: m_manager, renderer, visitor: this);
144 }
145}
146
147void PointsVisitor::apply(const PickingProxy *proxy, const Qt3DCore::QNodeId id)
148{
149 m_nodeId = id;
150 if (proxy && proxy->instanceCount() == 1) {
151 Visitor::visitPrimitives<PickingProxy, VertexExecutor<PointsVisitor>,
152 IndexExecutor<PointsVisitor>, PointsVisitor>(manager: m_manager, renderer: proxy, visitor: this);
153 }
154}
155
156} // namespace Render
157
158} // namespace Qt3DRender
159
160QT_END_NAMESPACE
161

source code of qt3d/src/render/backend/pointsvisitor.cpp