OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
geometry_port.hpp
1#pragma once
2#include <ossia/detail/config.hpp>
3
4#include <ossia/detail/small_vector.hpp>
5#include <ossia/detail/variant.hpp>
6
7#include <cstdint>
8#include <memory>
9#include <string>
10#include <string_view>
11
12namespace ossia
13{
14
15// clang-format off
16// Semantic identification for geometry attributes.
17// Custom attributes use attribute_semantic::custom + a string name.
18enum class attribute_semantic : uint16_t
19{
20 // Core geometry
21 position = 0, // vec3. Object-space position.
22 normal = 1, // vec3. Surface normal.
23 tangent = 2, // vec4. xyz=tangent, w=handedness (±1). [glTF TANGENT]
24 bitangent = 3, // vec3. cross(N, T.xyz) * T.w.
25
26 // Basic materials
27 texcoord0 = 100, // vec2/3. Primary UV. [glTF TEXCOORD_0]
28 texcoord1 = texcoord0 + 1, // vec2. Secondary UV (lightmaps). [glTF TEXCOORD_1]
29 texcoord2 = texcoord0 + 2, // vec2. Secondary UV. [glTF TEXCOORD_2]
30 texcoord3 = texcoord0 + 3, // vec2. Secondary UV. [glTF TEXCOORD_3]
31 texcoord4 = texcoord0 + 4, // vec2. Secondary UV. [glTF TEXCOORD_4]
32 texcoord5 = texcoord0 + 5, // vec2. Secondary UV.
33 texcoord6 = texcoord0 + 6, // vec2. Secondary UV.
34 texcoord7 = texcoord0 + 7, // vec2. Secondary UV.
35
36 color0 = 200, // vec4. Vertex color RGBA. [glTF COLOR_0]
37 color1 = color0 + 1, // vec4. Secondary vertex color. [glTF COLOR_1]
38 color2 = color0 + 2, // vec4. Secondary vertex color.
39 color3 = color0 + 3, // vec4. Secondary vertex color.
40
41 // Skinning / skeletal animation
42 joints0 = 300, // uvec4. Bone indices, set 0. [glTF JOINTS_0]
43 joints1 = joints0 + 1, // uvec4. Bone indices, set 1. [glTF JOINTS_1]
44
45 weights0 = 400, // vec4. Bone weights, set 0. [glTF WEIGHTS_0]
46 weights1 = weights0 + 1, // vec4. Bone weights, set 1. [glTF WEIGHTS_1]
47
48 // Morph targets / blend shapes
49 morph_position = 500, // vec3. Position delta for morph target.
50 morph_normal = morph_position + 1, // vec3. Normal delta for morph target.
51 morph_tangent = morph_position + 2, // vec3. Tangent delta (no w). [glTF morph TANGENT]
52 morph_texcoord = morph_position + 3, // vec2. UV delta for morph target.
53 morph_color = morph_position + 4, // vec3/4. Color delta for morph target.
54
55 // Transform / instancing
56 rotation = 600, // vec4. Quaternion (x,y,z,w).
57 rotation_extra = morph_position + 1, // vec4. Post-orient rotation.
58 scale = morph_position + 2, // vec3. Non-uniform scale.
59 uniform_scale = morph_position + 3, // float. Uniform scale.
60 up = morph_position + 4, // vec3. Up vector for LookAt.
61 pivot = morph_position + 5, // vec3. Local pivot point.
62 transform_matrix = morph_position + 6, // mat4. Full transform, overrides TRS. (note: remember that mat4 takes 4 lanes of attributes)
63 translation = morph_position + 7, // vec3. Additional translation offset.
64
65 // Particle dynamics
66 velocity = 1000, // vec3. Velocity in units/sec.
67 acceleration = velocity + 1, // vec3. Current acceleration.
68 force = velocity + 2, // vec3. Accumulated force this frame.
69 mass = velocity + 3, // float.
70 age = velocity + 4, // float. Time since birth, seconds.
71 lifetime = velocity + 5, // float. Max age before death.
72 birth_time = velocity + 6, // float. Absolute time of birth.
73 particle_id = velocity + 7, // int. Stable unique ID.
74 drag = velocity + 8, // float. Per-particle drag coefficient.
75 angular_velocity = velocity + 9, // vec3. Rotation speed rad/sec.
76 previous_position = velocity + 10, // vec3. For Verlet / motion blur.
77 rest_position = velocity + 11, // vec3. Undeformed position.
78 target_position = velocity + 12, // vec3. Goal position for constraints.
79 previous_velocity = velocity + 13, // vec3. Velocity at previous frame.
80 state = velocity + 14, // int. alive/dying/dead/collided enum.
81 collision_count = velocity + 15, // int. Number of collisions.
82 collision_normal = velocity + 16, // vec3. Normal at last collision.
83 sleep = velocity + 17, // int. Dormant flag (skip simulation).
84
85 // Rendering hints
86 sprite_size = 1100, // vec2. Billboard width/height.
87 sprite_rotation = sprite_size + 1, // float. Billboard screen-space rotation.
88 sprite_facing = sprite_size + 2, // vec3. Custom billboard facing direction.
89 sprite_index = sprite_size + 3, // int/float. Sub-image index for sprite sheets.
90 width = sprite_size + 4, // float. Curve/ribbon thickness.
91 opacity = sprite_size + 5, // float. Separate from color alpha.
92 emissive = sprite_size + 6, // vec3. Self-illumination color.
93 emissive_strength = sprite_size + 7, // float. Emissive intensity multiplier.
94
95 // Material / PBR
96 roughness = 1200, // float. PBR roughness [0-1].
97 metallic = roughness + 1, // float. PBR metalness [0-1].
98 ambient_occlusion = roughness + 2, // float. Baked AO [0-1].
99 specular = roughness + 3, // float. Specular factor.
100 subsurface = roughness + 4, // float. SSS intensity.
101 clearcoat = roughness + 5, // float. Clearcoat factor.
102 clearcoat_roughness = roughness + 6, // float. Clearcoat roughness.
103 anisotropy = roughness + 7, // float. Anisotropic reflection.
104 anisotropy_direction = roughness + 8, // vec3. Anisotropy tangent direction.
105 ior = roughness + 9, // float. Index of refraction.
106 transmission = roughness + 10, // float. Transmission factor (glass-like).
107 thickness = roughness + 11, // float. Volume thickness for transmission.
108 material_id = roughness + 22, // int. Index into material array.
109
110 // Gaussian splatting
111 sh_dc = 1300, // vec3. SH degree-0 (DC) color.
112 sh_coeffs = sh_dc + 1, // float[N]. SH coefficients for higher degrees.
113 covariance_3d = sh_dc + 2, // vec6 or mat3. 3D covariance (6 unique floats).
114 sh_degree = sh_dc + 3, // int. Active SH degree for this splat (0-3).
115
116 // Volumetric / field data
117 density = 1400, // float. Scalar density.
118 temperature = density + 1, // float.
119 fuel = density + 2, // float.
120 pressure = density + 3, // float.
121 divergence = density + 4, // float.
122 sdf_distance = density + 5, // float. Signed distance field value.
123 voxel_color = density + 6, // vec4. Per-voxel RGBA.
124
125 // Topology / connectivity
126 name = 1600, // string. Piece/group identifier.
127 piece_id = name + 1, // int. Numeric piece/group index.
128 line_id = name + 2, // int. Which line strip this point belongs to.
129 prim_id = name + 3, // int. Source primitive index.
130 point_id = name + 4, // int. Stable point ID (distinct from array index).
131 group_mask = name + 5, // int. Bitfield for group membership.
132 instance_id = name + 6, // int. Which instance this element belongs to.
133
134 // UI
135 selection = 1700, // float. Soft selection weight [0-1].
136
137 // User / general purpose
138 fx0 = 2000, // float. General-purpose effect control.
139 fx1 = fx0 + 1, // float. General-purpose effect control.
140 fx2 = fx0 + 2, // float. General-purpose effect control.
141 fx3 = fx0 + 3, // float. General-purpose effect control.
142 fx4 = fx0 + 4, // float. General-purpose effect control.
143 fx5 = fx0 + 5, // float. General-purpose effect control.
144 fx6 = fx0 + 6, // float. General-purpose effect control.
145 fx7 = fx0 + 7, // float. General-purpose effect control.
146
147 // Custom (string name lookup)
148 custom = 0xFFFF
149};
150
151// Returns a display name for well-known semantics, empty for custom.
152OSSIA_EXPORT std::string_view semantic_to_name(attribute_semantic s) noexcept;
153
154// Returns the semantic for a well-known name, or custom if not recognized.
155OSSIA_EXPORT attribute_semantic name_to_semantic(std::string_view name) noexcept;
156
157struct geometry
158{
159 struct cpu_buffer
160 {
161 std::shared_ptr<void> raw_data;
162 int64_t byte_size{};
163 };
164
165 struct gpu_buffer
166 {
167 void* handle{}; // Can be casted to e.g. a QRhiBuffer
168 int64_t byte_size{};
169 };
170
171 struct buffer
172 {
173 ossia::variant<cpu_buffer, gpu_buffer> data;
174 bool dirty{};
175 int64_t active_element_count{-1}; // -1 = use full buffer; else first N elements valid
176 };
177
178 struct binding
179 {
180 uint32_t byte_stride{};
181 enum
182 {
183 per_vertex,
184 per_instance
185 } classification{};
186 int step_rate{};
187 };
188
189 struct attribute
190 {
191 int binding = 0;
192 int location = 0;
193
194 enum
195 {
196 float4,
197 float3,
198 float2,
199 float1,
200 unormbyte4,
201 unormbyte2,
202 unormbyte1,
203 uint4,
204 uint3,
205 uint2,
206 uint1,
207 sint4,
208 sint3,
209 sint2,
210 sint1,
211 half4,
212 half3,
213 half2,
214 half1,
215 ushort4,
216 ushort3,
217 ushort2,
218 ushort1,
219 sshort4,
220 sshort3,
221 sshort2,
222 sshort1,
223 } format
224 = float4;
225
226 uint32_t byte_offset = 0;
227
228 // Semantic identification for this attribute.
229 // For well-known semantics, name is empty (derivable from the enum).
230 // For custom semantics, name holds the user-defined attribute name.
231 attribute_semantic semantic = attribute_semantic::custom;
232 std::string name;
233 };
234
235 struct input
236 {
237 int buffer{};
238 int64_t byte_offset{};
239 };
240
241 ossia::small_vector<buffer, 2> buffers;
242 ossia::small_vector<binding, 2> bindings;
243 ossia::small_vector<attribute, 2> attributes;
244 ossia::small_vector<input, 2> input;
245
246 int vertices{}, indices{}, instances{1};
247 enum
248 {
249 triangles,
250 triangle_strip,
251 triangle_fan,
252 lines,
253 line_strip,
254 points
255 } topology;
256 enum
257 {
258 none,
259 front,
260 back
261 } cull_mode;
262 enum
263 {
264 counter_clockwise,
265 clockwise
266 } front_face;
267
268 struct
269 {
270 int buffer{-1};
271 int64_t byte_offset{};
272 enum
273 {
274 uint16,
275 uint32
276 } format{};
277 } index;
278
279 // Axis-aligned bounding box. All zeros = not computed.
280 struct
281 {
282 float min[3]{};
283 float max[3]{};
284 } bounds;
285
286 // Optional GPU buffer holding a uint32 element count for indirect dispatch/draw.
287 // When set, renderers can use drawIndirect/dispatchIndirect.
288 gpu_buffer indirect_count;
289
290 // Auxiliary structured buffers that travel with the geometry.
291 // These are NOT per-vertex attributes; they are opaque buffers with
292 // application-defined internal layouts (e.g. particle bookkeeping structs,
293 // indirect dispatch/draw args, index lists).
294 // The buffer data lives in the `buffers` array; this struct references it.
295 // Consumers match by name against their shader storage declarations.
296 struct auxiliary_buffer
297 {
298 std::string name; // Shader-visible name for matching (e.g. "particle_aux")
299 int buffer{-1}; // Index into the buffers array
300 int64_t byte_offset{}; // Offset within the buffer
301 int64_t byte_size{}; // Size of the auxiliary data region
302 };
303 ossia::small_vector<auxiliary_buffer, 1> auxiliary;
304
305 // Find an auxiliary buffer by name. Returns nullptr if not found.
306 const auxiliary_buffer* find_auxiliary(std::string_view name) const noexcept
307 {
308 for(auto& a : auxiliary)
309 if(a.name == name)
310 return &a;
311 return nullptr;
312 }
313
314 // Find an attribute by semantic enum. Returns nullptr if not found.
315 const attribute* find(attribute_semantic sem) const noexcept
316 {
317 for(auto& a : attributes)
318 if(a.semantic == sem)
319 return &a;
320 return nullptr;
321 }
322
323 // Find a custom attribute by name. Returns nullptr if not found.
324 const attribute* find(std::string_view attr_name) const noexcept
325 {
326 for(auto& a : attributes)
327 if(a.semantic == attribute_semantic::custom && a.name == attr_name)
328 return &a;
329 return nullptr;
330 }
331
332 // Returns the display name for an attribute (semantic name or custom name).
333 static std::string_view display_name(const attribute& a) noexcept
334 {
335 if(a.semantic != attribute_semantic::custom)
336 return semantic_to_name(a.semantic);
337 return a.name;
338 }
339};
340
341struct mesh_list
342{
343 std::vector<geometry> meshes;
344 int64_t dirty_index{};
345};
346using mesh_list_ptr = std::shared_ptr<mesh_list>;
347struct transform3d
348{
349 float matrix[16]{
350 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.,
351 };
352};
353
354struct geometry_filter
355{
356 int64_t node_id{}; // which node is responsible for initalizing the UBO
357 int64_t filter_id{}; // unique index for this filter instance
371 std::string shader;
372 int64_t dirty_index{};
373};
374
375struct geometry_filter_list
376{
377 std::vector<geometry_filter> filters;
378 int64_t dirty_index{};
379};
380using geometry_filter_list_ptr = std::shared_ptr<geometry_filter_list>;
381
382struct geometry_spec
383{
384 mesh_list_ptr meshes;
385 geometry_filter_list_ptr filters;
386
387 operator bool() const noexcept { return meshes && filters; }
388 bool operator==(const geometry_spec&) const noexcept = default;
389 bool operator<(const geometry_spec& rhs) const noexcept
390 {
391 return (meshes < rhs.meshes) || (meshes == rhs.meshes && filters < rhs.filters);
392 }
393};
394
395struct OSSIA_EXPORT geometry_port
396{
397 static const constexpr int which = 4;
398 enum dirt_flags
399 {
400 dirty_transform = 0x1,
401 dirty_meshes = 0x2
402 };
403
404 void clear();
405
406 geometry_spec geometry;
407 transform3d transform;
408 uint8_t flags{};
409};
410
411struct geometry_delay_line
412{
413 std::vector<geometry_spec> geometries;
414};
415
416}
Definition git_info.h:7
OSSIA_INLINE constexpr auto min(const T a, const U b) noexcept -> typename std::conditional<(sizeof(T) > sizeof(U)), T, U >::type
min function tailored for values
Definition math.hpp:125
OSSIA_INLINE constexpr auto max(const T a, const U b) noexcept -> typename std::conditional<(sizeof(T) > sizeof(U)), T, U >::type
max function tailored for values
Definition math.hpp:96