rayzee 7.31.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +164 -0
- package/dist/rayzee.es.js +6547 -4334
- package/dist/rayzee.umd.js +122 -73
- package/package.json +1 -1
- package/src/EngineDefaults.js +168 -13
- package/src/EngineIssues.js +6 -0
- package/src/PathTracerApp.js +128 -20
- package/src/Processor/ArchiveReader.js +538 -0
- package/src/Processor/AssetLoader.js +357 -22
- package/src/Processor/BVHBuilder.js +48 -32
- package/src/Processor/BVHRefitter.js +244 -99
- package/src/Processor/ChunkedRecords.js +302 -0
- package/src/Processor/EmissiveTriangleBuilder.js +48 -21
- package/src/Processor/GeometryExtractor.js +577 -92
- package/src/Processor/HostMemory.js +222 -0
- package/src/Processor/InstanceTable.js +548 -97
- package/src/Processor/PBRT/EqualAreaOctahedral.js +173 -0
- package/src/Processor/PBRT/LoopSubdivision.js +240 -0
- package/src/Processor/PBRT/PBRTCurves.js +249 -0
- package/src/Processor/PBRT/PBRTMath.js +28 -0
- package/src/Processor/PBRT/PBRTParser.js +187 -41
- package/src/Processor/PBRT/PBRTSceneBuilder.js +659 -34
- package/src/Processor/PBRT/PBRTTokenizer.js +205 -65
- package/src/Processor/PBRT/index.js +306 -45
- package/src/Processor/PackedRayBuffer.js +29 -18
- package/src/Processor/ParallelBVHBuilder.js +9 -8
- package/src/Processor/QueueManager.js +5 -3
- package/src/Processor/SceneProcessor.js +1063 -366
- package/src/Processor/TLASBuilder.js +546 -201
- package/src/Processor/TextureCreator.js +11 -9
- package/src/Processor/VRAMTracker.js +12 -3
- package/src/Processor/Workers/BVHRefitWorker.js +16 -11
- package/src/Processor/Workers/BVHWorker.js +12 -12
- package/src/Processor/Workers/TLASWorker.js +37 -0
- package/src/Stages/NormalDepth.js +6 -2
- package/src/Stages/PathTracer.js +5 -5
- package/src/Stages/PathTracerStage.js +163 -41
- package/src/TSL/BVHTraversal.js +208 -90
- package/src/TSL/Common.js +135 -2
- package/src/TSL/Displacement.js +21 -11
- package/src/TSL/EmissiveSampling.js +49 -25
- package/src/TSL/ExtendKernel.js +3 -2
- package/src/TSL/LightBVHSampling.js +7 -4
- package/src/TSL/LightsDirect.js +30 -29
- package/src/TSL/ShadeKernel.js +8 -6
- package/src/TSL/Struct.js +3 -0
- package/src/TSL/TextureSampling.js +24 -9
- package/src/TSL/patches.js +128 -3
- package/src/index.js +3 -0
- package/src/managers/AnimationManager.js +86 -76
- package/src/managers/CameraManager.js +11 -0
- package/src/managers/MaterialDataManager.js +29 -23
- package/src/managers/TransformManager.js +9 -192
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
* - bare words: WorldBegin, Shape, true, false (directives / bools)
|
|
10
10
|
* Comments run from '#' to end of line.
|
|
11
11
|
*
|
|
12
|
+
* Scans BYTES, not a string, and hands the parser one token at a time. Scene files
|
|
13
|
+
* reach 2.4 GB — far past both the 512 MB a JavaScript string can hold and what an
|
|
14
|
+
* array of a hundred million token objects would cost — so neither the source text
|
|
15
|
+
* nor the token stream is ever materialised whole.
|
|
16
|
+
*
|
|
12
17
|
* Pure JS, no Three.js — keeps it unit-testable in node.
|
|
13
18
|
*/
|
|
14
19
|
|
|
@@ -20,122 +25,257 @@ export const TokenType = {
|
|
|
20
25
|
RBRACKET: ']'
|
|
21
26
|
};
|
|
22
27
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
const
|
|
28
|
+
const TAB = 9, LF = 10, FF = 12, CR = 13, SPACE = 32;
|
|
29
|
+
const QUOTE = 34, HASH = 35, PLUS = 43, MINUS = 45, DOT = 46;
|
|
30
|
+
const ZERO = 48, NINE = 57, LBRACKET = 91, RBRACKET = 93;
|
|
31
|
+
const UPPER_E = 69, LOWER_E = 101;
|
|
32
|
+
|
|
33
|
+
const isSpace = b => b === SPACE || b === TAB || b === LF || b === CR || b === FF;
|
|
34
|
+
const isDigit = b => b >= ZERO && b <= NINE;
|
|
35
|
+
|
|
36
|
+
// Beyond 15 significant digits the scaled-integer shortcut loses the last bits, so
|
|
37
|
+
// those rare tokens go through Number() instead. 10^0..10^22 are the powers of ten a
|
|
38
|
+
// double holds exactly.
|
|
39
|
+
const MAX_EXACT_DIGITS = 15;
|
|
40
|
+
const MAX_EXACT_POW10 = 22;
|
|
41
|
+
const POW10 = ( () => {
|
|
42
|
+
|
|
43
|
+
const t = new Float64Array( MAX_EXACT_POW10 + 1 );
|
|
44
|
+
for ( let i = 0; i < t.length; i ++ ) t[ i ] = Math.pow( 10, i );
|
|
45
|
+
return t;
|
|
46
|
+
|
|
47
|
+
} )();
|
|
27
48
|
|
|
28
|
-
|
|
29
|
-
if ( c === '.' && isDigit( next ) ) return true;
|
|
30
|
-
if ( c === '-' || c === '+' ) {
|
|
49
|
+
const utf8 = new TextDecoder();
|
|
31
50
|
|
|
32
|
-
|
|
33
|
-
|
|
51
|
+
function decodeRange( bytes, start, end ) {
|
|
52
|
+
|
|
53
|
+
const len = end - start;
|
|
54
|
+
if ( len === 0 ) return '';
|
|
55
|
+
|
|
56
|
+
let ascii = true;
|
|
57
|
+
for ( let i = start; i < end; i ++ ) if ( bytes[ i ] > 127 ) {
|
|
58
|
+
|
|
59
|
+
ascii = false; break;
|
|
34
60
|
|
|
35
61
|
}
|
|
36
62
|
|
|
37
|
-
return
|
|
63
|
+
if ( ! ascii ) return utf8.decode( bytes.subarray( start, end ) );
|
|
38
64
|
|
|
39
|
-
|
|
65
|
+
let out = '';
|
|
66
|
+
for ( let i = start; i < end; i ++ ) out += String.fromCharCode( bytes[ i ] );
|
|
67
|
+
return out;
|
|
68
|
+
|
|
69
|
+
}
|
|
40
70
|
|
|
41
71
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
72
|
+
* Pull-based lexer over a byte buffer.
|
|
73
|
+
*
|
|
74
|
+
* `peek()` returns the next token without consuming it, `next()` consumes it, and both
|
|
75
|
+
* return null at end of input.
|
|
45
76
|
*/
|
|
46
|
-
export
|
|
77
|
+
export class TokenStream {
|
|
47
78
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
let i = 0;
|
|
79
|
+
/** @param {Uint8Array|string} source */
|
|
80
|
+
constructor( source ) {
|
|
51
81
|
|
|
52
|
-
|
|
82
|
+
this.bytes = typeof source === 'string' ? new TextEncoder().encode( source ) : source;
|
|
83
|
+
this.i = 0;
|
|
84
|
+
this.n = this.bytes.length;
|
|
85
|
+
this._ahead = null;
|
|
53
86
|
|
|
54
|
-
|
|
87
|
+
}
|
|
55
88
|
|
|
56
|
-
|
|
57
|
-
if ( isWhitespace( c ) ) {
|
|
89
|
+
peek() {
|
|
58
90
|
|
|
59
|
-
|
|
60
|
-
|
|
91
|
+
if ( this._ahead === null ) this._ahead = this._scan();
|
|
92
|
+
return this._ahead;
|
|
93
|
+
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
next() {
|
|
97
|
+
|
|
98
|
+
const t = this.peek();
|
|
99
|
+
this._ahead = null;
|
|
100
|
+
return t;
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
_scan() {
|
|
105
|
+
|
|
106
|
+
const b = this.bytes;
|
|
107
|
+
let i = this.i;
|
|
108
|
+
const n = this.n;
|
|
109
|
+
|
|
110
|
+
for ( ;; ) {
|
|
111
|
+
|
|
112
|
+
while ( i < n && isSpace( b[ i ] ) ) i ++;
|
|
113
|
+
if ( i < n && b[ i ] === HASH ) {
|
|
114
|
+
|
|
115
|
+
while ( i < n && b[ i ] !== LF ) i ++;
|
|
116
|
+
continue;
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
break;
|
|
61
121
|
|
|
62
122
|
}
|
|
63
123
|
|
|
64
|
-
|
|
65
|
-
if ( c === '#' ) {
|
|
124
|
+
if ( i >= n ) {
|
|
66
125
|
|
|
67
|
-
|
|
68
|
-
|
|
126
|
+
this.i = i;
|
|
127
|
+
return null;
|
|
69
128
|
|
|
70
129
|
}
|
|
71
130
|
|
|
72
|
-
|
|
73
|
-
if ( c === '[' ) {
|
|
131
|
+
const c = b[ i ];
|
|
74
132
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
133
|
+
if ( c === LBRACKET ) {
|
|
134
|
+
|
|
135
|
+
this.i = i + 1;
|
|
136
|
+
return { type: TokenType.LBRACKET };
|
|
78
137
|
|
|
79
138
|
}
|
|
80
139
|
|
|
81
|
-
if ( c ===
|
|
140
|
+
if ( c === RBRACKET ) {
|
|
82
141
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
continue;
|
|
142
|
+
this.i = i + 1;
|
|
143
|
+
return { type: TokenType.RBRACKET };
|
|
86
144
|
|
|
87
145
|
}
|
|
88
146
|
|
|
89
|
-
|
|
90
|
-
if ( c === '"' ) {
|
|
147
|
+
if ( c === QUOTE ) {
|
|
91
148
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
while ( i < n && src[ i ] !== '"' ) i ++;
|
|
149
|
+
const start = ++ i;
|
|
150
|
+
while ( i < n && b[ i ] !== QUOTE ) i ++;
|
|
95
151
|
if ( i >= n ) throw new Error( 'PBRT tokenizer: unterminated string literal' );
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
152
|
+
this.i = i + 1;
|
|
153
|
+
return { type: TokenType.STRING, value: decodeRange( b, start, i ) };
|
|
154
|
+
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if ( isDigit( c ) || ( c === DOT && isDigit( b[ i + 1 ] ) )
|
|
158
|
+
|| ( ( c === MINUS || c === PLUS ) && ( isDigit( b[ i + 1 ] ) || ( b[ i + 1 ] === DOT && isDigit( b[ i + 2 ] ) ) ) ) ) {
|
|
159
|
+
|
|
160
|
+
return this._scanNumber( i );
|
|
99
161
|
|
|
100
162
|
}
|
|
101
163
|
|
|
102
|
-
|
|
103
|
-
|
|
164
|
+
const start = i;
|
|
165
|
+
while ( i < n ) {
|
|
104
166
|
|
|
105
|
-
|
|
167
|
+
const ch = b[ i ];
|
|
168
|
+
if ( isSpace( ch ) || ch === QUOTE || ch === LBRACKET || ch === RBRACKET || ch === HASH ) break;
|
|
106
169
|
i ++;
|
|
107
|
-
while ( i < n ) {
|
|
108
170
|
|
|
109
|
-
|
|
110
|
-
if ( ( ch >= '0' && ch <= '9' ) || ch === '.' || ch === 'e' || ch === 'E' ||
|
|
111
|
-
ch === '-' || ch === '+' ) {
|
|
171
|
+
}
|
|
112
172
|
|
|
113
|
-
|
|
173
|
+
this.i = i;
|
|
174
|
+
return { type: TokenType.WORD, value: decodeRange( b, start, i ) };
|
|
114
175
|
|
|
115
|
-
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
_scanNumber( start ) {
|
|
179
|
+
|
|
180
|
+
const b = this.bytes;
|
|
181
|
+
const n = this.n;
|
|
182
|
+
let i = start;
|
|
183
|
+
|
|
184
|
+
let negative = false;
|
|
185
|
+
if ( b[ i ] === MINUS ) {
|
|
186
|
+
|
|
187
|
+
negative = true; i ++;
|
|
188
|
+
|
|
189
|
+
} else if ( b[ i ] === PLUS ) i ++;
|
|
190
|
+
|
|
191
|
+
let mantissa = 0;
|
|
192
|
+
let digits = 0;
|
|
193
|
+
let fracDigits = 0;
|
|
194
|
+
|
|
195
|
+
while ( i < n && isDigit( b[ i ] ) ) {
|
|
196
|
+
|
|
197
|
+
mantissa = mantissa * 10 + ( b[ i ] - ZERO );
|
|
198
|
+
digits ++; i ++;
|
|
199
|
+
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if ( i < n && b[ i ] === DOT ) {
|
|
203
|
+
|
|
204
|
+
i ++;
|
|
205
|
+
while ( i < n && isDigit( b[ i ] ) ) {
|
|
206
|
+
|
|
207
|
+
mantissa = mantissa * 10 + ( b[ i ] - ZERO );
|
|
208
|
+
digits ++; fracDigits ++; i ++;
|
|
116
209
|
|
|
117
210
|
}
|
|
118
211
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
let exponent = 0;
|
|
215
|
+
if ( i < n && ( b[ i ] === LOWER_E || b[ i ] === UPPER_E ) ) {
|
|
216
|
+
|
|
217
|
+
let j = i + 1;
|
|
218
|
+
let expNeg = false;
|
|
219
|
+
if ( j < n && ( b[ j ] === MINUS || b[ j ] === PLUS ) ) {
|
|
220
|
+
|
|
221
|
+
expNeg = b[ j ] === MINUS; j ++;
|
|
222
|
+
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if ( j < n && isDigit( b[ j ] ) ) {
|
|
226
|
+
|
|
227
|
+
let e = 0;
|
|
228
|
+
while ( j < n && isDigit( b[ j ] ) ) {
|
|
229
|
+
|
|
230
|
+
e = e * 10 + ( b[ j ] - ZERO ); j ++;
|
|
231
|
+
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
exponent = expNeg ? - e : e;
|
|
235
|
+
i = j;
|
|
236
|
+
|
|
237
|
+
}
|
|
124
238
|
|
|
125
239
|
}
|
|
126
240
|
|
|
127
|
-
|
|
128
|
-
|
|
241
|
+
this.i = i;
|
|
242
|
+
|
|
243
|
+
if ( digits === 0 ) throw new Error( `PBRT tokenizer: invalid number "${decodeRange( b, start, i )}"` );
|
|
244
|
+
|
|
245
|
+
const scale = exponent - fracDigits;
|
|
246
|
+
const exact = digits <= MAX_EXACT_DIGITS && scale >= - MAX_EXACT_POW10 && scale <= MAX_EXACT_POW10;
|
|
247
|
+
|
|
248
|
+
if ( ! exact ) {
|
|
129
249
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
tokens.push( { type: TokenType.WORD, value: src.slice( start, i ) } );
|
|
250
|
+
const value = Number( decodeRange( b, start, i ) );
|
|
251
|
+
if ( Number.isNaN( value ) ) throw new Error( `PBRT tokenizer: invalid number "${decodeRange( b, start, i )}"` );
|
|
252
|
+
return { type: TokenType.NUMBER, value };
|
|
134
253
|
|
|
135
254
|
}
|
|
136
255
|
|
|
256
|
+
// Scale by dividing rather than multiplying by a negative power: 10^-4 is not exact,
|
|
257
|
+
// and 654435761 * 1e-4 lands a bit below -65443.5761.
|
|
258
|
+
let value = scale === 0 ? mantissa
|
|
259
|
+
: scale > 0 ? mantissa * POW10[ scale ]
|
|
260
|
+
: mantissa / POW10[ - scale ];
|
|
261
|
+
if ( negative ) value = - value;
|
|
262
|
+
return { type: TokenType.NUMBER, value };
|
|
263
|
+
|
|
137
264
|
}
|
|
138
265
|
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Tokenize a whole pbrt source into an array.
|
|
270
|
+
* Convenience for tests and small files; the loader streams instead.
|
|
271
|
+
* @param {string|Uint8Array} src
|
|
272
|
+
* @returns {Array<{type: string, value?: string|number}>}
|
|
273
|
+
*/
|
|
274
|
+
export function tokenize( src ) {
|
|
275
|
+
|
|
276
|
+
const stream = new TokenStream( src );
|
|
277
|
+
const tokens = [];
|
|
278
|
+
for ( let t = stream.next(); t !== null; t = stream.next() ) tokens.push( t );
|
|
139
279
|
return tokens;
|
|
140
280
|
|
|
141
281
|
}
|