@@ -16,11 +16,53 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
1616#include < vsg/nodes/IntersectionProxy.h>
1717#include < vsg/nodes/StateGroup.h>
1818#include < vsg/nodes/VertexDraw.h>
19+ #include < vsg/nodes/VertexIndexDraw.h>
1920#include < vsg/utils/Intersector.h>
2021#include < vsg/utils/LineSegmentIntersector.h>
2122
2223using namespace vsg ;
2324
25+ namespace
26+ {
27+ struct GetIndicesVisitor : public ConstVisitor
28+ {
29+ ref_ptr<const ubyteArray> ubyte_indices;
30+ ref_ptr<const ushortArray> ushort_indices;
31+ ref_ptr<const uintArray> uint_indices;
32+
33+ void apply (const BufferInfo& bufferInfo) override
34+ {
35+ bufferInfo.data ->accept (*this );
36+ }
37+
38+ void apply (const ubyteArray& array) override
39+ {
40+ ubyte_indices = &array;
41+ ushort_indices = nullptr ;
42+ uint_indices = nullptr ;
43+ }
44+ void apply (const ushortArray& array) override
45+ {
46+ ubyte_indices = nullptr ;
47+ ushort_indices = &array;
48+ uint_indices = nullptr ;
49+ }
50+ void apply (const uintArray& array) override
51+ {
52+ ubyte_indices = nullptr ;
53+ ushort_indices = nullptr ;
54+ uint_indices = &array;
55+ }
56+
57+ uint32_t operator [](size_t index)
58+ {
59+ if (ubyte_indices) return ubyte_indices->at (index);
60+ if (ushort_indices) return ushort_indices->at (index);
61+ return uint_indices->at (index);
62+ }
63+ };
64+ }
65+
2466IntersectionProxy::IntersectionProxy (Node* in_original) :
2567 Inherit(),
2668 original(in_original),
@@ -73,7 +115,38 @@ void vsg::IntersectionProxy::rebuild(vsg::ArrayState& arrayState)
73115 for (uint32_t i = vertexDraw->firstVertex ; (i + 2 ) < endVertex; i += 3 )
74116 {
75117 triangles.emplace_back (Triangle{vertices->at (i), vertices->at (i + 1 ), vertices->at (i + 2 )});
76- metadata.emplace_back (TriangleMetadata{i, instanceIndex});
118+ metadata.emplace_back (TriangleMetadata{i, i + 1 , i + 2 , instanceIndex});
119+ }
120+ }
121+ }
122+ }
123+ else if (auto * vertexIndexDraw = ::cast<VertexIndexDraw>(original))
124+ {
125+ arrayState.apply (*vertexIndexDraw);
126+
127+ uint32_t lastIndex = vertexIndexDraw->instanceCount > 1 ? (vertexIndexDraw->firstInstance + vertexIndexDraw->instanceCount ) : vertexIndexDraw->firstInstance + 1 ;
128+ uint32_t endIndex = vertexIndexDraw->firstIndex + ((vertexIndexDraw->indexCount + 2 ) / 3 ) * 3 ;
129+
130+ triangles.reserve (vertexIndexDraw->instanceCount * vertexIndexDraw->indexCount / 3 );
131+ metadata.reserve (triangles.size ());
132+
133+ if (!vertexIndexDraw->indices || !vertexIndexDraw->indices ->data )
134+ {
135+ warn (" Attempting to build IntersectionProxy for VertexIndexDraw with no indices." );
136+ return ;
137+ }
138+
139+ GetIndicesVisitor indices;
140+ vertexIndexDraw->indices ->accept (indices);
141+
142+ for (uint32_t instanceIndex = vertexIndexDraw->firstInstance ; instanceIndex < lastIndex; ++instanceIndex)
143+ {
144+ if (auto vertices = arrayState.vertexArray (instanceIndex))
145+ {
146+ for (uint32_t i = vertexIndexDraw->firstIndex ; i < endIndex; i += 3 )
147+ {
148+ triangles.emplace_back (Triangle{vertices->at (indices[i]), vertices->at (indices[i + 1 ]), vertices->at (indices[i + 2 ])});
149+ metadata.emplace_back (TriangleMetadata{indices[i], indices[i + 1 ], indices[i + 2 ], instanceIndex});
77150 }
78151 }
79152 }
@@ -227,7 +300,7 @@ void vsg::IntersectionProxy::intersect(LineSegmentIntersector& lineSegmentInters
227300
228301 dvec3 intersection = dvec3 (triangle.vertex0 ) * double (r0) + dvec3 (triangle.vertex1 ) * double (r1) + dvec3 (triangle.vertex2 ) * double (r2);
229302 const auto & metadata = leafMetadata[index].tris [i];
230- lineSegmentIntersector.add (intersection, double (t * inverseLength), {{metadata.index , r0}, {metadata.index + 1 , r1}, {metadata.index + 2 , r2}}, metadata.instance );
303+ lineSegmentIntersector.add (intersection, double (t * inverseLength), {{metadata.index0 , r0}, {metadata.index1 + 1 , r1}, {metadata.index2 + 2 , r2}}, metadata.instance );
231304 }
232305 };
233306
0 commit comments