import * as THREE from 'three';
export const WARMUP = { framesBeforeReady: 480 };
export const PARAMS = {
a: { value: 0.95, min: 0.1, max: 2, step: 0.01, label: "a", folder: "Dynamics" },
b: { value: 0.7, min: 0.1, max: 2, step: 0.01, label: "b", folder: "Dynamics" },
c: { value: 0.6, min: 0.1, max: 2, step: 0.01, label: "c", folder: "Dynamics" },
d: { value: 3.5, min: 0.1, max: 5, step: 0.01, label: "d", folder: "Dynamics" },
e: { value: 0.25, min: 0.0, max: 2, step: 0.01, label: "e", folder: "Dynamics" },
f: { value: 0.1, min: 0.0, max: 2, step: 0.01, label: "f", folder: "Dynamics" },
dt: { value: 0.01, min: 0.001, max: 0.05, step: 0.001, label: "Step", folder: "Dynamics" },
trail: { value: 12000, min: 1000, max: 60000, step: 500, label: "Trail Length", folder: "Appearance" },
hue: { value: 200, min: 0, max: 360, step: 1, label: "Hue", folder: "Appearance" },
};
export const SHARE = { bookmarked: ["a","b","c","d","e","f","dt","trail","hue"] };
export function sceneSetup(THREE, scene, camera, renderer, params, seed) {
scene.background = new THREE.Color(0x07080a);
camera.position.set(0, 0, 5);
const positions = new Float32Array(params.trail * 3);
const geo = new THREE.BufferGeometry();
geo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geo.setDrawRange(0, 0);
const mat = new THREE.LineBasicMaterial({ color: new THREE.Color().setHSL(params.hue / 360, 0.7, 0.55) });
const line = new THREE.Line(geo, mat);
scene.add(line);
return {
p: { x: 0.1, y: 0, z: 0 },
positions, geo, mat, line, count: 0,
};
}
export function sceneAnimate(THREE, scene, camera, state, params, time, delta) {
state.mat.color.setHSL(params.hue / 360, 0.7, 0.55);
const { a, b, c, d, e, f, dt } = params;
const trail = params.trail | 0;
for (let i = 0; i < 8; i++) {
const { x, y, z } = state.p;
const dx = (z - b) * x - d * y;
const dy = d * x + (z - b) * y;
const dz = c + a * z - (z * z * z) / 3 - (x * x + y * y) * (1 + e * z) + f * z * x * x * x;
state.p.x += dx * dt;
state.p.y += dy * dt;
state.p.z += dz * dt;
const idx = (state.count % trail) * 3;
state.positions[idx] = state.p.x;
state.positions[idx + 1] = state.p.y;
state.positions[idx + 2] = state.p.z;
state.count++;
}
state.geo.attributes.position.needsUpdate = true;
state.geo.setDrawRange(0, Math.min(state.count, trail));
}