Add SAB-backed rotor transforms and smooth camera controls
Amp-Thread-ID: https://ampcode.com/threads/T-01a01ff8-b91f-724f-8952-f07c6b5042fd Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
This commit is contained in:
@@ -496,6 +496,7 @@ canvas {
|
||||
height: 100%;
|
||||
display: block;
|
||||
object-fit: contain;
|
||||
touch-action: none;
|
||||
}
|
||||
.output {
|
||||
position: absolute;
|
||||
|
||||
@@ -61,8 +61,8 @@ log("Pointer movement mutates nodePositions; no worker message is sent.");
|
||||
|
||||
const move = (event) => {
|
||||
const bounds = canvas.getBoundingClientRect();
|
||||
mesh.position[0] = ((event.clientX - bounds.left) / bounds.width - 0.5) * 1.4;
|
||||
mesh.position[1] = (0.5 - (event.clientY - bounds.top) / bounds.height) * 1.2;
|
||||
mesh.position.x = ((event.clientX - bounds.left) / bounds.width - 0.5) * 1.4;
|
||||
mesh.position.y = (0.5 - (event.clientY - bounds.top) / bounds.height) * 1.2;
|
||||
};
|
||||
canvas.addEventListener("pointermove", move);
|
||||
|
||||
@@ -270,13 +270,35 @@ log("HDR → exposure → color grading → FXAA → canvas");
|
||||
|
||||
return { scene, mesh, exposure, grade, fxaa, dispose: () => scene.dispose() };`;
|
||||
|
||||
const importing = `import { ArcRotateCamera, Picking, Scene, importGltf } from "@yawn/handles";
|
||||
const importing = `import { AmbientLight, ArcRotateCamera, PointLight, Picking, Scene, importGltf } from "@yawn/handles";
|
||||
|
||||
const scene = new Scene(canvas, { hdr: true, arenaBytes: 384 * 1024 * 1024 });
|
||||
await scene.ready;
|
||||
scene.array("sceneAccent").row(0).set([1, 1, 1, 1]);
|
||||
log("Importing /models/sponza.glb in the importer worker…");
|
||||
const meshes = await importGltf(scene, "/models/sponza.glb");
|
||||
|
||||
// Add a warm ambient/key/fill setup without changing the authored transforms.
|
||||
const lights = [
|
||||
new AmbientLight(scene, {
|
||||
color: [1, 0.93, 0.82],
|
||||
intensity: 0.18,
|
||||
}),
|
||||
new PointLight(scene, {
|
||||
position: [-10, 14, -4],
|
||||
color: [1, 0.72, 0.5],
|
||||
intensity: 2,
|
||||
range: 28,
|
||||
}),
|
||||
new PointLight(scene, {
|
||||
position: [9, 10, 6],
|
||||
color: [1, 0.9, 0.75],
|
||||
intensity: 1.5,
|
||||
range: 24,
|
||||
}),
|
||||
];
|
||||
await Promise.all(lights.map((light) => light.ready));
|
||||
|
||||
const target = [0, 8, 0];
|
||||
const camera = new ArcRotateCamera(scene, {
|
||||
targetPosition: target,
|
||||
@@ -305,6 +327,7 @@ await pick();
|
||||
return {
|
||||
scene,
|
||||
meshes,
|
||||
lights,
|
||||
camera,
|
||||
picking,
|
||||
async dispose() {
|
||||
|
||||
@@ -72,7 +72,7 @@ follow.stop();
|
||||
follow.start();
|
||||
```
|
||||
|
||||
The input and follow loops never post camera updates to core: they mutate the position, quaternion, camera, and derived matrix rows directly in shared memory.
|
||||
The input and follow loops never post camera updates to core: they mutate the position, rotor, camera, and derived matrix rows directly in shared memory.
|
||||
|
||||
<Playground example="cameras" />
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ The shared importer worker fetches and parses glTF/GLB, then the response hydrat
|
||||
import { importGltf } from "@yawn/handles";
|
||||
|
||||
const meshes = await importGltf(scene, "/models/sponza.glb");
|
||||
meshes[0].position[1] = 0.5;
|
||||
meshes[0].position.y = 0.5;
|
||||
```
|
||||
|
||||
The importer handles triangle primitives, external/data buffers, standard vertex attributes, indices, node transforms, and metallic-roughness values. Application-specific extensions remain application policy.
|
||||
@@ -34,7 +34,7 @@ If row allocations relocated since `Picking` was created, refresh its shared des
|
||||
await picking.refresh();
|
||||
```
|
||||
|
||||
The playground below imports the repository's full LFS-backed `sponza.glb` in the importer worker, preserves its authored transforms, places an arc camera in its coordinate system, and sends a real ray to the BVH worker. Click the preview to pick again.
|
||||
The playground below imports the repository's full LFS-backed `sponza.glb` in the importer worker, preserves its authored transforms, adds neutral warm lighting, places an arc camera in its coordinate system, and sends a real ray to the BVH worker. Click the preview to pick again.
|
||||
|
||||
<Playground example="importing" />
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ const point = new PointLight(scene, {
|
||||
});
|
||||
|
||||
const sun = new DirectionalLight(scene, {
|
||||
quaternion: [0.2, 0, 0, 0.98],
|
||||
rotor: [0.2, 0, 0, 0.98],
|
||||
color: [1, 0.95, 0.8],
|
||||
intensity: 3,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Scene and shared data
|
||||
|
||||
Think of every handle as an array index, not an object mirrored into core. `Node.position`, `Node.quaternion`, and `Node.scale` are views into separate flat SOA arrays.
|
||||
Think of every handle as an array index, not an object mirrored into core. `Node.position`, `Node.rotor`, and `Node.scale` are component views into separate flat SOA arrays.
|
||||
|
||||
## Direct transform movement
|
||||
|
||||
@@ -11,12 +11,12 @@ const pivot = new Node(scene, { position: [0, 1, 0] });
|
||||
await pivot.ready;
|
||||
|
||||
canvas.addEventListener("pointermove", (event) => {
|
||||
pivot.position[0] += event.movementX * 0.002;
|
||||
pivot.position[1] -= event.movementY * 0.002;
|
||||
pivot.position.x += event.movementX * 0.002;
|
||||
pivot.position.y -= event.movementY * 0.002;
|
||||
});
|
||||
```
|
||||
|
||||
The pointer handler sends no messages. The typed-array view points directly into the arena shared with the render worker. The camera helpers use this same pattern; see [Cameras and controls](/guide/cameras).
|
||||
The pointer handler sends no messages. Each component property reads or writes its lane in the arena shared with the render worker. Replace complete transforms with `setPosition([x, y, z])`, `setRotor([x, y, z, w])`, and `setScale([x, y, z])`. `translate(...)`, `rotate(...)`, and `rotateX/Y/Z(...)` are convenience methods over those same SAB lanes. The camera helpers use this same pattern; see [Cameras and controls](/guide/cameras).
|
||||
|
||||
<Playground example="sab" />
|
||||
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ const mesh = new Mesh(scene, {
|
||||
});
|
||||
await mesh.ready;
|
||||
|
||||
mesh.position[0] = 0.25; // direct SAB mutation
|
||||
mesh.position.x = 0.25; // direct SAB mutation
|
||||
```
|
||||
|
||||
`Scene` installs one HDR clustered-forward loadout. Adding compute, custom shaders, textures, or post effects rebuilds that same loadout; changing values already present in shared rows does not send a message.
|
||||
|
||||
Reference in New Issue
Block a user