1.3.64
 
Loading...
Searching...
No Matches
RayTracingTypes.cpp
Go to the documentation of this file.
1
16#include "RayTracingTypes.h"
17#include "global.h"
18#include <algorithm>
19#include <climits>
20
21namespace helios {
22
24#ifndef NDEBUG
25
26 // ========== UUID / Position Validation ==========
27
28 if (primitive_UUIDs.size() != primitive_count) {
29 helios_runtime_error("RayTracingGeometry validation failed: primitive_UUIDs.size()=" + std::to_string(primitive_UUIDs.size()) + " != primitive_count=" + std::to_string(primitive_count));
30 }
31
32 // UUID lookup table validation
33 // NOTE: primitive_positions now includes bbox UUIDs (safe due to bbox_UUID_base = max_UUID + 1)
34 if (!primitive_UUIDs.empty()) {
35 uint max_uuid = *std::max_element(primitive_UUIDs.begin(), primitive_UUIDs.end());
36
37 // Include bbox UUIDs in expected size if present
38 if (bbox_count > 0) {
39 uint bbox_max_uuid = bbox_UUID_base + bbox_count - 1;
40 if (bbox_max_uuid > max_uuid) {
41 max_uuid = bbox_max_uuid;
42 }
43 }
44
45 size_t expected_size = max_uuid + 1;
46
47 if (primitive_positions.size() != expected_size) {
48 helios_runtime_error("RayTracingGeometry validation failed: primitive_positions.size()=" + std::to_string(primitive_positions.size()) + " != max_UUID+1=" + std::to_string(expected_size) + " (max_UUID=" + std::to_string(max_uuid) +
49 ")");
50 }
51
52 // Validate UUID→position mapping consistency
53 for (size_t pos = 0; pos < primitive_UUIDs.size(); pos++) {
54 uint UUID = primitive_UUIDs[pos];
55
56 if (UUID >= primitive_positions.size()) {
57 helios_runtime_error("RayTracingGeometry validation failed: primitive_UUIDs[" + std::to_string(pos) + "]=" + std::to_string(UUID) + " >= primitive_positions.size()=" + std::to_string(primitive_positions.size()));
58 }
59
60 uint mapped_pos = primitive_positions[UUID];
61 if (mapped_pos == UINT_MAX) {
62 helios_runtime_error("RayTracingGeometry validation failed: primitive_positions[" + std::to_string(UUID) + "] == UINT_MAX (should map to position " + std::to_string(pos) + ")");
63 }
64
65 if (mapped_pos != pos) {
66 helios_runtime_error("RayTracingGeometry validation failed: primitive_positions[" + std::to_string(UUID) + "]=" + std::to_string(mapped_pos) + " but UUID is at position " + std::to_string(pos) +
67 " (bidirectional mapping inconsistent)");
68 }
69 }
70 }
71
72 // ========== Per-Primitive Buffer Sizing ==========
73
74 // Calculate expected buffer size including bboxes
75 size_t expected_types_size = primitive_count + bbox_count;
76
77 // transform_matrices can be larger than primitive_count*16 if bboxes are present
78 if (transform_matrices.size() != expected_types_size * 16) {
79 helios_runtime_error("RayTracingGeometry validation failed: transform_matrices.size()=" + std::to_string(transform_matrices.size()) + " != (primitive_count+bbox_count)*16=" + std::to_string(expected_types_size * 16));
80 }
81
82 // primitive_types can be larger than primitive_count if bboxes are present
83 if (primitive_types.size() != expected_types_size) {
84 helios_runtime_error("RayTracingGeometry validation failed: primitive_types.size()=" + std::to_string(primitive_types.size()) + " != primitive_count+bbox_count=" + std::to_string(expected_types_size));
85 }
86
87 // object_subdivisions can be larger than primitive_count if bboxes are present
88 if (object_subdivisions.size() != expected_types_size) {
89 helios_runtime_error("RayTracingGeometry validation failed: object_subdivisions.size()=" + std::to_string(object_subdivisions.size()) + " != primitive_count+bbox_count=" + std::to_string(expected_types_size));
90 }
91
92 // twosided_flags can be larger than primitive_count if bboxes are present
93 if (twosided_flags.size() != expected_types_size) {
94 helios_runtime_error("RayTracingGeometry validation failed: twosided_flags.size()=" + std::to_string(twosided_flags.size()) + " != primitive_count+bbox_count=" + std::to_string(expected_types_size));
95 }
96
97 // solid_fractions can be larger than primitive_count if bboxes are present
98 if (solid_fractions.size() != expected_types_size) {
99 helios_runtime_error("RayTracingGeometry validation failed: solid_fractions.size()=" + std::to_string(solid_fractions.size()) + " != primitive_count+bbox_count=" + std::to_string(expected_types_size));
100 }
101
102 // ========== Object ID Validation ==========
103
104 // object_IDs can be larger than primitive_count if bboxes are present
105 if (object_IDs.size() != expected_types_size) {
106 helios_runtime_error("RayTracingGeometry validation failed: object_IDs.size()=" + std::to_string(object_IDs.size()) + " != primitive_count+bbox_count=" + std::to_string(expected_types_size));
107 }
108
109 // primitive_IDs must include bbox entries when periodic boundaries are enabled
110 size_t expected_primitive_IDs_size = primitive_count + bbox_count;
111 if (primitive_IDs.size() != expected_primitive_IDs_size) {
112 helios_runtime_error("RayTracingGeometry validation failed: primitive_IDs.size()=" + std::to_string(primitive_IDs.size()) + " != primitive_count+bbox_count=" + std::to_string(expected_primitive_IDs_size) +
113 " (COMMON BUG: Did you size by Nobjects instead of Nprimitives?)");
114 }
115
116 // ========== Per-Type Buffer Sizing ==========
117
118 if (patches.UUIDs.size() != patch_count) {
119 helios_runtime_error("RayTracingGeometry validation failed: patches.UUIDs.size()=" + std::to_string(patches.UUIDs.size()) + " != patch_count=" + std::to_string(patch_count));
120 }
121
122 if (patches.vertices.size() != patch_count * 4) {
123 helios_runtime_error("RayTracingGeometry validation failed: patches.vertices.size()=" + std::to_string(patches.vertices.size()) + " != patch_count*4=" + std::to_string(patch_count * 4));
124 }
125
126 if (triangles.UUIDs.size() != triangle_count) {
127 helios_runtime_error("RayTracingGeometry validation failed: triangles.UUIDs.size()=" + std::to_string(triangles.UUIDs.size()) + " != triangle_count=" + std::to_string(triangle_count));
128 }
129
130 if (triangles.vertices.size() != triangle_count * 3) {
131 helios_runtime_error("RayTracingGeometry validation failed: triangles.vertices.size()=" + std::to_string(triangles.vertices.size()) + " != triangle_count*3=" + std::to_string(triangle_count * 3));
132 }
133
134 if (tiles.UUIDs.size() != tile_count) {
135 helios_runtime_error("RayTracingGeometry validation failed: tiles.UUIDs.size()=" + std::to_string(tiles.UUIDs.size()) + " != tile_count=" + std::to_string(tile_count));
136 }
137
138 if (tiles.vertices.size() != tile_count * 4) {
139 helios_runtime_error("RayTracingGeometry validation failed: tiles.vertices.size()=" + std::to_string(tiles.vertices.size()) + " != tile_count*4=" + std::to_string(tile_count * 4));
140 }
141
142 if (voxels.UUIDs.size() != voxel_count) {
143 helios_runtime_error("RayTracingGeometry validation failed: voxels.UUIDs.size()=" + std::to_string(voxels.UUIDs.size()) + " != voxel_count=" + std::to_string(voxel_count));
144 }
145
146 if (voxels.vertices.size() != voxel_count * 8) {
147 helios_runtime_error("RayTracingGeometry validation failed: voxels.vertices.size()=" + std::to_string(voxels.vertices.size()) + " != voxel_count*8=" + std::to_string(voxel_count * 8));
148 }
149
150 if (bboxes.UUIDs.size() != bbox_count) {
151 helios_runtime_error("RayTracingGeometry validation failed: bboxes.UUIDs.size()=" + std::to_string(bboxes.UUIDs.size()) + " != bbox_count=" + std::to_string(bbox_count));
152 }
153
154 if (bboxes.vertices.size() != bbox_count * 4) {
155 helios_runtime_error("RayTracingGeometry validation failed: bboxes.vertices.size()=" + std::to_string(bboxes.vertices.size()) + " != bbox_count*4=" + std::to_string(bbox_count * 4));
156 }
157
158 if (disk_UUIDs.size() != disk_count) {
159 helios_runtime_error("RayTracingGeometry validation failed: disk_UUIDs.size()=" + std::to_string(disk_UUIDs.size()) + " != disk_count=" + std::to_string(disk_count));
160 }
161
162 if (disk_centers.size() != disk_count) {
163 helios_runtime_error("RayTracingGeometry validation failed: disk_centers.size()=" + std::to_string(disk_centers.size()) + " != disk_count=" + std::to_string(disk_count));
164 }
165
166 if (disk_radii.size() != disk_count) {
167 helios_runtime_error("RayTracingGeometry validation failed: disk_radii.size()=" + std::to_string(disk_radii.size()) + " != disk_count=" + std::to_string(disk_count));
168 }
169
170 if (disk_normals.size() != disk_count) {
171 helios_runtime_error("RayTracingGeometry validation failed: disk_normals.size()=" + std::to_string(disk_normals.size()) + " != disk_count=" + std::to_string(disk_count));
172 }
173
174 // ========== Subdivision Validation ==========
175
176 for (size_t i = 0; i < object_subdivisions.size(); i++) {
178 if (subdiv.x < 1 || subdiv.y < 1) {
179 helios_runtime_error("RayTracingGeometry validation failed: object_subdivisions[" + std::to_string(i) + "] = (" + std::to_string(subdiv.x) + "," + std::to_string(subdiv.y) + ") has zero or negative subdivision count");
180 }
181 }
182
183 // Heuristic check: warn if many primitives have subdivisions > (1,1)
184 // This often indicates subdivision inheritance bug (subpatches should be (1,1))
185 size_t subdivision_anomalies = 0;
186 for (size_t i = 0; i < object_subdivisions.size(); i++) {
187 if (object_subdivisions[i].x > 1 || object_subdivisions[i].y > 1) {
188 subdivision_anomalies++;
189 }
190 }
191
192 if (subdivision_anomalies > primitive_count / 2) {
193 std::cerr << "WARNING [RayTracingGeometry]: " << subdivision_anomalies << " / " << primitive_count << " primitives have subdivisions > (1,1). "
194 << "Check for subdivision inheritance bug - subpatches should have (1,1), "
195 << "only parent geometry should have actual subdivision counts.\n";
196 }
197
198#endif // NDEBUG
199 }
200
201} // namespace helios