import { a as Mesh, c as SkinnedMesh, d as Vector2$1, f as Vector3$1, i as MathUtils, l as Uniform, n as Color, o as REVISION, r as InstancedMesh, s as ShaderMaterial, t as BackSide, u as UniformsUtils } from "../_chunks/libs/three.mjs";
import * as React from "react";
import { MarchingCubes as MarchingCubes$1 } from "three/examples/jsm/objects/MarchingCubes";
import { applyProps, createPortal, extend, useFrame, useThree } from "@react-three/fiber";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import { toCreasedNormals } from "three/examples/jsm/utils/BufferGeometryUtils";
import * as THREE from "three";
import { Object3D, Vector2, Vector3 } from "three";
import { Line2 } from "three/examples/jsm/lines/Line2.js";
import { LineGeometry } from "three/examples/jsm/lines/LineGeometry.js";
import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";

//#region src/experimental/Geometry/MarchingCubes/MarchingCubes.tsx
const globalContext = /* @__PURE__ */ React.createContext(null);
/**
* An abstraction for three's [MarchingCubes](https://threejs.org/examples/#webgl_marchingcubes).
*
* @example Basic usage
* ```jsx
* <MarchingCubes resolution={50} maxPolyCount={20000} enableUvs={false} enableColors={true}>
*   <MarchingCube strength={0.5} subtract={12} color={new Color('#f0f')} position={[0.5, 0.5, 0.5]} />
*   <MarchingPlane planeType="y" strength={0.5} subtract={12} />
* </MarchingCubes>
* ```
*/
const MarchingCubes = /* @__PURE__ */ React.forwardRef(({ resolution = 28, maxPolyCount = 1e4, enableUvs = false, enableColors = false, children, ...props }, ref) => {
	const marchingCubesRef = React.useRef(null);
	React.useImperativeHandle(ref, () => marchingCubesRef.current, []);
	const marchingCubes = React.useMemo(() => new MarchingCubes$1(resolution, null, enableUvs, enableColors, maxPolyCount), [
		resolution,
		maxPolyCount,
		enableUvs,
		enableColors
	]);
	const api = React.useMemo(() => ({ getParent: () => marchingCubesRef }), []);
	useFrame(() => {
		marchingCubes.update();
		marchingCubes.reset();
	}, -1);
	return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("primitive", {
		object: marchingCubes,
		ref: marchingCubesRef,
		...props,
		children: /* @__PURE__ */ jsx(globalContext.Provider, {
			value: api,
			children
		})
	}) });
});
const MarchingCube = /* @__PURE__ */ React.forwardRef(({ strength = .5, subtract = 12, color, ...props }, ref) => {
	const { getParent } = React.useContext(globalContext);
	const parentRef = React.useMemo(() => getParent(), [getParent]);
	const cubeRef = React.useRef(null);
	React.useImperativeHandle(ref, () => cubeRef.current, []);
	const vec = new Vector3$1();
	useFrame((state) => {
		if (!parentRef.current || !cubeRef.current) return;
		cubeRef.current.getWorldPosition(vec);
		parentRef.current.addBall(.5 + vec.x * .5, .5 + vec.y * .5, .5 + vec.z * .5, strength, subtract, color);
	});
	return /* @__PURE__ */ jsx("group", {
		ref: cubeRef,
		...props
	});
});
const MarchingPlane = /* @__PURE__ */ React.forwardRef(({ planeType: _planeType = "x", strength = .5, subtract = 12, ...props }, ref) => {
	const { getParent } = React.useContext(globalContext);
	const parentRef = React.useMemo(() => getParent(), [getParent]);
	const wallRef = React.useRef(null);
	React.useImperativeHandle(ref, () => wallRef.current, []);
	const planeType = React.useMemo(() => _planeType === "x" ? "addPlaneX" : _planeType === "y" ? "addPlaneY" : "addPlaneZ", [_planeType]);
	useFrame(() => {
		if (!parentRef.current || !wallRef.current) return;
		parentRef.current[planeType](strength, subtract);
	});
	return /* @__PURE__ */ jsx("group", {
		ref: wallRef,
		...props
	});
});

//#endregion
//#region src/legacy/Materials/shaderMaterial/shaderMaterial.tsx
/**
* Creates a ShaderMaterial class with uniforms as setter/getters and constructor args.
* Includes a unique `key` property for hot-reload support.
*
* @param uniforms - Default uniform values
* @param vertexShader - GLSL vertex shader
* @param fragmentShader - GLSL fragment shader
* @param onInit - Optional callback after material creation
*
* @example
* ```jsx
* const MyMaterial = shaderMaterial(
*   { time: 0, color: new THREE.Color(0.2, 0, 0.1) },
*   vertexShader,
*   fragmentShader
* )
* extend({ MyMaterial })
* <mesh><myMaterial key={MyMaterial.key} time={1} /></mesh>
* ```
*/
function shaderMaterial(uniforms, vertexShader, fragmentShader, onInit) {
	return class extends ShaderMaterial {
		static key = MathUtils.generateUUID();
		constructor(parameters) {
			super({
				vertexShader,
				fragmentShader,
				...parameters
			});
			for (const key in uniforms) {
				this.uniforms[key] = new Uniform(uniforms[key]);
				Object.defineProperty(this, key, {
					get() {
						return this.uniforms[key].value;
					},
					set(value) {
						this.uniforms[key].value = value;
					}
				});
			}
			this.uniforms = UniformsUtils.clone(this.uniforms);
			onInit?.(this);
		}
	};
}

//#endregion
//#region src/utils/constants.ts
const getVersion = () => parseInt(REVISION.replace(/\D+/g, ""));
const version = /* @__PURE__ */ getVersion();

//#endregion
//#region src/experimental/Effects/Outlines/Outlines.tsx
const OutlinesMaterial = /* @__PURE__ */ shaderMaterial({
	screenspace: false,
	color: /* @__PURE__ */ new Color("black"),
	opacity: 1,
	thickness: .05,
	size: /* @__PURE__ */ new Vector2$1()
}, `#include <common>
   #include <morphtarget_pars_vertex>
   #include <skinning_pars_vertex>
   #include <clipping_planes_pars_vertex>
   uniform float thickness;
   uniform bool screenspace;
   uniform vec2 size;
   void main() {
     #if defined (USE_SKINNING)
	     #include <beginnormal_vertex>
       #include <morphnormal_vertex>
       #include <skinbase_vertex>
       #include <skinnormal_vertex>
       #include <defaultnormal_vertex>
     #endif
     #include <begin_vertex>
	   #include <morphtarget_vertex>
	   #include <skinning_vertex>
     #include <project_vertex>
     #include <clipping_planes_vertex>
     vec4 tNormal = vec4(normal, 0.0);
     vec4 tPosition = vec4(transformed, 1.0);
     #ifdef USE_INSTANCING
       tNormal = instanceMatrix * tNormal;
       tPosition = instanceMatrix * tPosition;
     #endif
     if (screenspace) {
       vec3 newPosition = tPosition.xyz + tNormal.xyz * thickness;
       gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0); 
     } else {
       vec4 clipPosition = projectionMatrix * modelViewMatrix * tPosition;
       vec4 clipNormal = projectionMatrix * modelViewMatrix * tNormal;
       vec2 offset = normalize(clipNormal.xy) * thickness / size * clipPosition.w * 2.0;
       clipPosition.xy += offset;
       gl_Position = clipPosition;
     }
   }`, `uniform vec3 color;
   uniform float opacity;
   #include <clipping_planes_pars_fragment>
   void main(){
     #include <clipping_planes_fragment>
     gl_FragColor = vec4(color, opacity);
     #include <tonemapping_fragment>
     #include <${version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
   }`);
/**
* An ornamental component that extracts the geometry from its parent and displays an
* [inverted-hull outline](https://bnpr.gitbook.io/bnpr/outline/inverse-hull-method).
* Supported parents are `<mesh>`, `<skinnedMesh>` and `<instancedMesh>`.
*
* @example Basic usage
* ```jsx
* <mesh>
*   <boxGeometry />
*   <meshBasicMaterial />
*   <Outlines thickness={0.05} color="hotpink" />
* </mesh>
* ```
*/
function Outlines({ color = "black", opacity = 1, transparent = false, screenspace = false, toneMapped = true, polygonOffset = false, polygonOffsetFactor = 0, renderOrder = 0, thickness = .05, angle = Math.PI, clippingPlanes, ...props }) {
	const ref = React.useRef(null);
	const [material] = React.useState(() => new OutlinesMaterial({ side: BackSide }));
	const { gl } = useThree();
	const contextSize = gl.getDrawingBufferSize(new Vector2$1());
	React.useMemo(() => extend({ OutlinesMaterial }), []);
	const oldAngle = React.useRef(0);
	const oldGeometry = React.useRef(null);
	React.useLayoutEffect(() => {
		const group = ref.current;
		if (!group) return;
		const parent = group.parent;
		if (parent && parent.geometry) {
			if (oldAngle.current !== angle || oldGeometry.current !== parent.geometry) {
				oldAngle.current = angle;
				oldGeometry.current = parent.geometry;
				let mesh = group.children?.[0];
				if (mesh) {
					if (angle) mesh.geometry.dispose();
					group.remove(mesh);
				}
				if (parent.skeleton) {
					mesh = new SkinnedMesh();
					mesh.material = material;
					mesh.bind(parent.skeleton, parent.bindMatrix);
					group.add(mesh);
				} else if (parent.isInstancedMesh) {
					mesh = new InstancedMesh(parent.geometry, material, parent.count);
					mesh.instanceMatrix = parent.instanceMatrix;
					group.add(mesh);
				} else {
					mesh = new Mesh();
					mesh.material = material;
					group.add(mesh);
				}
				mesh.geometry = angle ? toCreasedNormals(parent.geometry, angle) : parent.geometry;
				mesh.morphTargetInfluences = parent.morphTargetInfluences;
				mesh.morphTargetDictionary = parent.morphTargetDictionary;
			}
		}
	});
	React.useLayoutEffect(() => {
		const group = ref.current;
		if (!group) return;
		const mesh = group.children[0];
		if (mesh) {
			mesh.renderOrder = renderOrder;
			const parent = group.parent;
			applyProps(mesh, {
				morphTargetInfluences: parent.morphTargetInfluences,
				morphTargetDictionary: parent.morphTargetDictionary
			});
			applyProps(mesh.material, {
				transparent,
				thickness,
				color,
				opacity,
				size: contextSize,
				screenspace,
				toneMapped,
				polygonOffset,
				polygonOffsetFactor,
				clippingPlanes,
				clipping: clippingPlanes && clippingPlanes.length > 0
			});
		}
	});
	React.useEffect(() => {
		return () => {
			const group = ref.current;
			if (!group) return;
			const mesh = group.children[0];
			if (mesh) {
				if (angle) mesh.geometry.dispose();
				group.remove(mesh);
			}
		};
	}, []);
	return /* @__PURE__ */ jsx("group", {
		ref,
		...props
	});
}

//#endregion
//#region src/legacy/Effects/Trail/Trail.tsx
const defaults = {
	width: .2,
	length: 1,
	decay: 1,
	local: false,
	stride: 0,
	interval: 1
};
const shiftLeft = (collection, steps = 1) => {
	const lastX = collection[collection.length - 3];
	const lastY = collection[collection.length - 2];
	const lastZ = collection[collection.length - 1];
	collection.set(collection.subarray(steps));
	const fillStart = collection.length - steps;
	for (let i = fillStart; i < collection.length; i += 3) {
		collection[i] = lastX;
		collection[i + 1] = lastY;
		collection[i + 2] = lastZ;
	}
	return collection;
};
function useTrail(target, settings, pointCount) {
	const { local, decay, interval, stride } = {
		...defaults,
		...settings
	};
	const points = React.useRef(null);
	const [worldPosition] = React.useState(() => new Vector3());
	React.useLayoutEffect(() => {
		if (target) {
			const pos = target.position;
			points.current = Float32Array.from({ length: pointCount * 3 }, (_, i) => pos.getComponent(i % 3));
		}
	}, [pointCount, target]);
	const prevPosition = React.useRef(new Vector3());
	const frameCount = React.useRef(0);
	useFrame(() => {
		if (!target) return;
		if (!points.current) return;
		if (frameCount.current === 0) {
			let newPosition;
			if (local) newPosition = target.position;
			else {
				target.getWorldPosition(worldPosition);
				newPosition = worldPosition;
			}
			const steps = 1 * decay;
			for (let i = 0; i < steps; i++) {
				if (newPosition.distanceTo(prevPosition.current) < stride) continue;
				shiftLeft(points.current, 3);
				points.current.set(newPosition.toArray(), points.current.length - 3);
			}
			prevPosition.current.copy(newPosition);
		}
		frameCount.current++;
		frameCount.current = frameCount.current % interval;
	});
	return points;
}
/**
* A declarative trail effect using Line2.
* WebGL version using LineMaterial.
*/
const Trail = /* @__PURE__ */ React.forwardRef((props, forwardRef) => {
	const { children } = props;
	const { width, length, decay, local, stride, interval } = {
		...defaults,
		...props
	};
	const { color = "hotpink", attenuation, target } = props;
	const size = useThree((s) => s.size);
	const scene = useThree((s) => s.scene);
	const ref = React.useRef(null);
	const [anchor, setAnchor] = React.useState(null);
	const pointCount = length * 10;
	const points = useTrail(anchor, {
		decay,
		local,
		stride,
		interval
	}, pointCount);
	React.useEffect(() => {
		const t = target?.current || ref.current.children.find((o) => o instanceof Object3D);
		if (t) setAnchor(t);
	}, [points, target]);
	const line = React.useMemo(() => new Line2(), []);
	const geo = React.useMemo(() => {
		const geometry = new LineGeometry();
		const initialPositions = new Float32Array(pointCount * 3).fill(0);
		const initialColors = new Float32Array(pointCount * 3).fill(1);
		geometry.setPositions(initialPositions);
		geometry.setColors(initialColors);
		return geometry;
	}, [pointCount]);
	const [resolution] = React.useState(() => new Vector2(size.width, size.height));
	const colorsRef = React.useRef(new Float32Array(pointCount * 3));
	const baseColor = React.useMemo(() => new THREE.Color(color), [color]);
	const mat = React.useMemo(() => new LineMaterial({
		color: 16777215,
		linewidth: width,
		vertexColors: true,
		resolution: new Vector2(size.width, size.height),
		transparent: true,
		alphaToCoverage: true
	}), [width, size]);
	React.useEffect(() => {
		resolution.set(size.width, size.height);
		mat.resolution.set(size.width, size.height);
	}, [
		size,
		mat,
		resolution
	]);
	useFrame(() => {
		if (!points.current) return;
		const count = points.current.length / 3;
		const colors = colorsRef.current;
		for (let i = 0; i < count; i++) {
			const t = i / (count - 1);
			const alpha = attenuation ? attenuation(t) : t;
			colors[i * 3 + 0] = baseColor.r * alpha;
			colors[i * 3 + 1] = baseColor.g * alpha;
			colors[i * 3 + 2] = baseColor.b * alpha;
		}
		geo.setPositions(points.current);
		geo.setColors(colors);
		line.computeLineDistances();
	});
	React.useLayoutEffect(() => {
		line.geometry = geo;
		line.material = mat;
	}, [
		line,
		geo,
		mat
	]);
	return /* @__PURE__ */ jsxs("group", { children: [createPortal(/* @__PURE__ */ jsx("primitive", {
		object: line,
		ref: forwardRef
	}), scene), /* @__PURE__ */ jsx("group", {
		ref,
		children
	})] });
});

//#endregion
export { MarchingCube, MarchingCubes, MarchingPlane, Outlines, Trail, useTrail };