1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/// The CSS selector used to query the RayTrace Canvas 2D canvas element
/// from the DOM.
pub const RAYTRACE_CANVAS_SELECTOR: &str = "#raytrace-canvas";
/// The CSS selector for the RayTrace Canvas 2D loading overlay canvas.
pub const RAYTRACE_LOADING_CANVAS_SELECTOR: &str = "#raytrace-loading-canvas";
/// The CSS selector used to query the RayTrace WebGL canvas element.
pub const RAYTRACE_WEBGL_CANVAS_SELECTOR: &str = "#raytrace-webgl-canvas";
/// The CSS selector for the RayTrace WebGL loading overlay canvas.
pub const RAYTRACE_WEBGL_LOADING_CANVAS_SELECTOR: &str = "#raytrace-webgl-loading-canvas";
/// The CSS selector used to query the RayTrace WebGPU canvas element.
pub const RAYTRACE_WEBGPU_CANVAS_SELECTOR: &str = "#raytrace-webgpu-canvas";
/// The CSS selector for the RayTrace WebGPU loading overlay canvas.
pub const RAYTRACE_WEBGPU_LOADING_CANVAS_SELECTOR: &str = "#raytrace-webgpu-loading-canvas";
/// The stable error code recorded when
/// [`RayTraceRenderer::init`](euv_engine::RayTraceRenderer) rejects the
/// requested backend.
///
/// Distinct from [`RAYTRACE_ERROR_CODE_RENDER`] so the status banner can
/// tell "this browser cannot host the backend at all" apart from "the
/// backend was acquired and then failed mid-run".
pub const RAYTRACE_ERROR_CODE_INIT: &str = "RAYTRACE_INIT";
/// The stable error code recorded when
/// [`RayTraceRenderer::render`](euv_engine::RayTraceRenderer) rejects a
/// frame.
pub const RAYTRACE_ERROR_CODE_RENDER: &str = "RAYTRACE_RENDER";
/// The stable error code recorded when
/// [`RayTraceRenderer::resize`](euv_engine::RayTraceRenderer) rejects new
/// dimensions.
pub const RAYTRACE_ERROR_CODE_RESIZE: &str = "RAYTRACE_RESIZE";
/// The fallback detail text used when a rejected engine call carries a
/// `JsValue` that is not a string (a thrown object, a number, ...).
pub const RAYTRACE_ERROR_DETAIL_UNKNOWN: &str = "engine returned a non-string error";
/// The log prefix every RayTrace engine diagnostic is written with.
pub const RAYTRACE_LOG_PREFIX: &str = "[euv-engine][raytrace]";
/// The message written to the console when a backend finishes
/// initializing.
pub const RAYTRACE_LOG_BACKEND_READY: &str = "backend ready";
/// Minimum visible duration in milliseconds for a RayTrace tab's loading
/// overlay.
///
/// A backend can finish `init` well inside a single
/// `requestAnimationFrame` tick, and most browsers collapse a mount +
/// unmount that happens inside one tick into a single paint. The overlay
/// would then never be seen at all, so the `loaded` flag is flipped on a
/// timer instead of immediately, which guarantees the user sees the
/// "Initializing..." line for every tab.
pub const RAYTRACE_LOADING_MIN_MILLIS: i32 = 400;
/// Logical width of the RayTrace Canvas 2D tab's internal framebuffer at
/// render scale 1.0.
///
/// Every ladder step is a multiple of this pair, so the backing store
/// keeps the exact 4:3 ratio the `c_raytrace_canvas_fullscreen`
/// `object-fit: contain` letterbox contract expects.
pub const RAYTRACE_WIDTH: f64 = 320.0;
/// Logical height of the RayTrace Canvas 2D tab's internal framebuffer at
/// render scale 1.0.
pub const RAYTRACE_HEIGHT: f64 = 240.0;
/// The render-scale ladder for the Canvas 2D adaptive-resolution path.
///
/// The backing buffer is sized `320 * scale` by `240 * scale`, so every
/// step keeps a 4:3 frame: 1280x960, 960x720, 800x600, 640x480, 560x420,
/// 480x360, 400x300, 320x240, 240x180, 160x120, 120x90, 80x60. The loop
/// starts at index 7 (scale 1.0) so weak clients never start heavy, and
/// the controller only climbs toward 4.0 after sustained fast frames prove
/// the budget allows it.
pub const RAYTRACE_RENDER_SCALES: = ;
/// The index into [`RAYTRACE_RENDER_SCALES`] the Canvas 2D loop starts
/// at.
pub const RAYTRACE_RENDER_SCALE_START_INDEX: usize = 7;
/// Exponential-moving-average blend factor for the measured per-frame
/// render time that drives adaptive resolution.
pub const RAYTRACE_ADAPT_EMA_ALPHA: f64 = 0.1;
/// Measured render time in milliseconds above which the adaptive
/// controller steps the render scale down (115% of the 60 FPS budget).
pub const RAYTRACE_ADAPT_SLOW_FRAME_MILLIS: f64 = 16.67 * 1.15;
/// Measured render time in milliseconds below which the adaptive
/// controller steps the render scale up one rung (75% of the 60 FPS
/// budget).
pub const RAYTRACE_ADAPT_FAST_FRAME_MILLIS: f64 = 16.67 * 0.75;
/// Measured render time in milliseconds below which the adaptive
/// controller steps the render scale up two rungs at once (45% of the 60
/// FPS budget), skipping intermediate rungs when the headroom is obvious.
pub const RAYTRACE_ADAPT_VERY_FAST_FRAME_MILLIS: f64 = 16.67 * 0.45;
/// Number of consecutive slow frames required before stepping the render
/// scale down one notch.
pub const RAYTRACE_ADAPT_SLOW_FRAMES: u32 = 30;
/// Number of consecutive fast frames required before stepping the render
/// scale up (one notch, or two notches when the frame time also stayed
/// below [`RAYTRACE_ADAPT_VERY_FAST_FRAME_MILLIS`] for the same span).
pub const RAYTRACE_ADAPT_FAST_FRAMES: u32 = 45;
/// Supersampling grid resolution per axis used by every RayTrace tab.
///
/// `2` traces four rays per pixel, matching the 2x2 supersampling the
/// demo has always used and keeping the three backends on one sampling
/// grid. It sits inside the engine's accepted `1..=4` range, so
/// `RayTraceSettings::validate` accepts it unchanged.
pub const RAYTRACE_SAMPLES_PER_AXIS: u32 = 2;
/// The secondary bounce limit used by every RayTrace tab.
///
/// `4` matches the engine default and the bounce count the demo has
/// always advertised, and sits inside the engine's accepted `0..=16`
/// range.
pub const RAYTRACE_MAX_BOUNCES: u32 = 4;
/// The orbit yaw speed in radians per second for auto-rotation.
///
/// Mirrors the 3D game page's constant so the two orbit demos feel the
/// same when both are visible in the sidebar.
pub const RAYTRACE_AUTO_YAW_SPEED: f64 = 0.5;
/// The minimum angle in radians between the camera pitch and +/- pi/2.
///
/// Wider than a pure gimbal guard on purpose. The engine derives the
/// camera basis as `forward x up`, and a forward vector very close to
/// vertical makes that cross product collapse toward zero; past the
/// point where it reaches zero the engine rejects the frame outright as
/// a degenerate basis. An 0.12 rad floor keeps the cross product's
/// horizontal component at 0.12 or more, which is the smallest value that
/// both stays numerically far from the degenerate case and still lets the
/// user look nearly straight down at the scene.
pub const RAYTRACE_PITCH_CLAMP: f64 = 0.12;
/// The sensitivity multiplier applied to pointer drag deltas before they
/// are folded into orbit angles.
///
/// Matches the 3D game page's pointer handlers so the two demos feel
/// identical in drag responsiveness.
pub const RAYTRACE_DRAG_SENSITIVITY: f64 = 0.01;
/// The radius of the orbit sphere the camera sits on.
pub const RAYTRACE_CAMERA_DISTANCE: f64 = 8.0;
/// The x-coordinate of the orbit sphere's centre (the scene's look-at
/// target).
pub const RAYTRACE_CAMERA_LOOK_AT_X: f64 = 0.0;
/// The y-coordinate of the orbit sphere's centre (the scene's look-at
/// target).
pub const RAYTRACE_CAMERA_LOOK_AT_Y: f64 = 0.4;
/// The z-coordinate of the orbit sphere's centre (the scene's look-at
/// target).
pub const RAYTRACE_CAMERA_LOOK_AT_Z: f64 = 0.0;
/// The fixed viewer position the demo's specular lobes are evaluated
/// against.
///
/// The light set is built once and reused for the lifetime of the loop so
/// no frame allocates a light list, which means the shading eye is fixed
/// as well: the demo traces exactly what it packs, and the specular
/// highlight on the mirror sphere reads as a highlight for this viewer
/// rather than tracking the orbiting eye.
pub const RAYTRACE_SHADING_EYE_X: f64 = 0.0;
/// The y component of [`RAYTRACE_SHADING_EYE_X`]'s viewer position.
pub const RAYTRACE_SHADING_EYE_Y: f64 = 1.2;
/// The z component of [`RAYTRACE_SHADING_EYE_X`]'s viewer position.
pub const RAYTRACE_SHADING_EYE_Z: f64 = 4.2;
/// The JavaScript property name for the touch list `touches` on a
/// `TouchEvent`.
pub const RAYTRACE_EVENT_PROPERTY_TOUCHES: &str = "touches";
/// The JavaScript property name for the client X coordinate on a `Touch`
/// object.
pub const RAYTRACE_EVENT_PROPERTY_CLIENT_X: &str = "clientX";
/// The JavaScript property name for the client Y coordinate on a `Touch`
/// object.
pub const RAYTRACE_EVENT_PROPERTY_CLIENT_Y: &str = "clientY";
/// The JavaScript event name for the window resize event.
pub const RAYTRACE_EVENT_RESIZE: &str = "resize";
/// The JavaScript property name for the device pixel ratio on `Window`.
pub const RAYTRACE_EVENT_PROPERTY_DEVICE_PIXEL_RATIO: &str = "devicePixelRatio";
/// Delay in milliseconds before a loop's first `requestAnimationFrame`
/// callback is scheduled, allowing the canvas element to mount before the
/// first frame attempts to acquire a backend.
pub const RAYTRACE_LOOP_START_DELAY_MILLIS: i32 = 360;
/// Debounce window in milliseconds applied to window resize events before
/// they mark the GPU-backed loops' backing store dirty.
///
/// Mirrors `GAME_3D_RESIZE_DEBOUNCE_MILLIS`.
pub const RAYTRACE_RESIZE_DEBOUNCE_MILLIS: i32 = 100;