skip to content
==> src/scene.c <==
1/* The scene format's layout, validation and settable words (pathtrace-core lib.rs). */
2#include "pathtrace/scene.h"
3
4const size_t pt_settable[PT_SETTABLE_COUNT] = {PT_H_WIDTH, PT_H_HEIGHT, PT_H_SPP,
5                                               PT_H_PASSES, PT_H_DEPTH, PT_H_SEED};
6
7pt_layout pt_layout_of(const uint32_t *sc) {
8    pt_layout l;
9    uint32_t nmat = sc[PT_H_NMAT];
10    l.nquad = sc[PT_H_NQUAD];
11    l.nsph = sc[PT_H_NSPH];
12    l.ntri = sc[PT_H_NTRI];
13    l.mat = PT_HEADER_WORDS;
14    l.quad = l.mat + PT_MAT_WORDS * (size_t)nmat;
15    l.sph = l.quad + PT_QUAD_WORDS * (size_t)l.nquad;
16    l.tri = l.sph + PT_SPH_WORDS * (size_t)l.nsph;
17    l.light = sc[PT_H_LIGHT];
18    return l;
19}
20
21uint32_t pt_validate(const uint32_t *sc, size_t len) { return pt_validate_in(sc, len, PT_MAX_TILES); }
22
23uint32_t pt_validate_in(const uint32_t *sc, size_t len, uint32_t max_tiles) {
24    if (len < PT_HEADER_WORDS) return 1;
25    if (sc[PT_H_MAGIC] != PT_MAGIC_SCENE || sc[PT_H_VERSION] != PT_VERSION) return 2;
26    size_t words = sc[PT_H_WORDS];
27    if (words > len || words > PT_SCENE_MAX_WORDS) return 3;
28    uint32_t w = sc[PT_H_WIDTH], h = sc[PT_H_HEIGHT];
29    if (w == 0 || h == 0 || w % PT_TILE_W != 0 || h % PT_TILE_H != 0 ||
30        (uint64_t)(w / PT_TILE_W) * (h / PT_TILE_H) > max_tiles)
31        return 4;
32    if (sc[PT_H_SPP] < 1 || sc[PT_H_SPP] > 1024 || sc[PT_H_PASSES] < 1 || sc[PT_H_PASSES] > 4096 ||
33        sc[PT_H_DEPTH] < 1 || sc[PT_H_DEPTH] > 16)
34        return 5;
35    uint32_t nmat = sc[PT_H_NMAT], nquad = sc[PT_H_NQUAD], nsph = sc[PT_H_NSPH], ntri = sc[PT_H_NTRI];
36    if (nmat == 0 || nmat > 64 || nquad > 64 || nsph > 64 || ntri > 64) return 6;
37    pt_layout l = pt_layout_of(sc);
38    if (l.tri + PT_TRI_WORDS * (size_t)ntri != words) return 7;
39    for (size_t i = 0; i < nmat; i++)
40        if (sc[l.mat + PT_MAT_WORDS * i] > PT_EMIT) return 8;
41    for (size_t i = 0; i < nquad; i++)
42        if (sc[l.quad + PT_QUAD_WORDS * i + 15] >= nmat) return 9;
43    for (size_t i = 0; i < nsph; i++)
44        if (sc[l.sph + PT_SPH_WORDS * i + 5] >= nmat) return 9;
45    for (size_t i = 0; i < ntri; i++)
46        if (sc[l.tri + PT_TRI_WORDS * i + 12] >= nmat) return 9;
47    if (sc[PT_H_LIGHT] != PT_NO_LIGHT && sc[PT_H_LIGHT] >= nquad) return 10;
48    return 0;
49}
50
51bool pt_set_param(uint32_t *sc, size_t len, uint32_t arg) {
52    size_t word = arg >> 24;
53    uint32_t value = arg & 0x00ffffffu;
54    bool settable = false;
55    for (int i = 0; i < PT_SETTABLE_COUNT; i++) settable |= pt_settable[i] == word;
56    if (!settable || word >= len) return false;
57    sc[word] = value;
58    return true;
59}