2024-03-21 16:31:17 +01:00
|
|
|
<script context="module" lang="ts">
|
2024-03-20 01:40:42 +01:00
|
|
|
const color = new Color(0x202020);
|
|
|
|
color.convertLinearToSRGB();
|
|
|
|
|
|
|
|
const color2 = color.clone();
|
|
|
|
color2.convertSRGBToLinear();
|
|
|
|
|
|
|
|
const circleMaterial = new MeshBasicMaterial({
|
|
|
|
color,
|
|
|
|
toneMapped: false,
|
|
|
|
});
|
2024-03-21 16:31:17 +01:00
|
|
|
|
|
|
|
const lineCache = new Map<number, BufferGeometry>();
|
|
|
|
|
|
|
|
const curve = new CubicBezierCurve(
|
|
|
|
new Vector2(0, 0),
|
|
|
|
new Vector2(0, 0),
|
|
|
|
new Vector2(0, 0),
|
|
|
|
new Vector2(0, 0),
|
|
|
|
);
|
2024-03-20 01:40:42 +01:00
|
|
|
</script>
|
|
|
|
|
2024-03-06 14:01:07 +01:00
|
|
|
<script lang="ts">
|
2024-03-20 01:40:42 +01:00
|
|
|
import { T } from "@threlte/core";
|
2024-03-21 16:31:17 +01:00
|
|
|
import { MeshLineMaterial } from "@threlte/extras";
|
|
|
|
import { BufferGeometry, MeshBasicMaterial, Vector3 } from "three";
|
2024-03-20 01:40:42 +01:00
|
|
|
import { Color } from "three/src/math/Color.js";
|
2024-03-19 16:41:15 +01:00
|
|
|
import { CubicBezierCurve } from "three/src/extras/curves/CubicBezierCurve.js";
|
|
|
|
import { Vector2 } from "three/src/math/Vector2.js";
|
2024-04-10 23:50:41 +02:00
|
|
|
import { createEdgeGeometry } from "./createEdgeGeometry.js";
|
2024-03-06 14:01:07 +01:00
|
|
|
|
2024-03-11 19:37:58 +01:00
|
|
|
export let from: { x: number; y: number };
|
|
|
|
export let to: { x: number; y: number };
|
2024-03-06 14:01:07 +01:00
|
|
|
|
2024-03-20 17:39:52 +01:00
|
|
|
let samples = 5;
|
2024-03-19 16:41:15 +01:00
|
|
|
|
2024-03-21 16:31:17 +01:00
|
|
|
let geometry: BufferGeometry;
|
2024-03-06 14:01:07 +01:00
|
|
|
|
2024-03-21 16:31:17 +01:00
|
|
|
let lastId: number | null = null;
|
2024-03-06 14:01:07 +01:00
|
|
|
|
2024-03-21 16:31:17 +01:00
|
|
|
const primeA = 31;
|
|
|
|
const primeB = 37;
|
2024-03-06 14:01:07 +01:00
|
|
|
|
2024-03-21 16:31:17 +01:00
|
|
|
export const update = function () {
|
|
|
|
const new_x = to.x - from.x;
|
|
|
|
const new_y = to.y - from.y;
|
|
|
|
const curveId = new_x * primeA + new_y * primeB;
|
|
|
|
if (lastId === curveId) {
|
|
|
|
return;
|
2024-03-06 14:01:07 +01:00
|
|
|
}
|
2024-03-11 19:37:58 +01:00
|
|
|
|
2024-03-21 16:31:17 +01:00
|
|
|
const mid = new Vector2(new_x / 2, new_y / 2);
|
|
|
|
|
|
|
|
if (lineCache.has(curveId)) {
|
|
|
|
geometry = lineCache.get(curveId)!;
|
|
|
|
return;
|
|
|
|
}
|
2024-03-11 19:37:58 +01:00
|
|
|
|
2024-03-20 17:39:52 +01:00
|
|
|
const length = Math.floor(
|
2024-03-21 16:31:17 +01:00
|
|
|
Math.sqrt(Math.pow(new_x, 2) + Math.pow(new_y, 2)) / 4,
|
2024-03-20 17:39:52 +01:00
|
|
|
);
|
2024-03-21 16:31:17 +01:00
|
|
|
samples = Math.min(Math.max(10, length), 60);
|
2024-03-11 19:37:58 +01:00
|
|
|
|
2024-03-21 16:31:17 +01:00
|
|
|
curve.v0.set(0, 0);
|
|
|
|
curve.v1.set(mid.x, 0);
|
|
|
|
curve.v2.set(mid.x, new_y);
|
|
|
|
curve.v3.set(new_x, new_y);
|
2024-03-20 17:39:52 +01:00
|
|
|
|
2024-03-21 16:31:17 +01:00
|
|
|
const points = curve
|
|
|
|
.getPoints(samples)
|
|
|
|
.map((p) => new Vector3(p.x, 0, p.y))
|
|
|
|
.flat();
|
|
|
|
|
|
|
|
geometry = createEdgeGeometry(points);
|
|
|
|
lineCache.set(curveId, geometry);
|
2024-03-13 14:30:30 +01:00
|
|
|
};
|
2024-03-06 14:01:07 +01:00
|
|
|
|
2024-03-11 19:37:58 +01:00
|
|
|
$: if (from || to) {
|
2024-03-06 14:01:07 +01:00
|
|
|
update();
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
2024-03-06 19:44:37 +01:00
|
|
|
<T.Mesh
|
2024-03-11 19:37:58 +01:00
|
|
|
position.x={from.x}
|
|
|
|
position.z={from.y}
|
2024-03-06 19:44:37 +01:00
|
|
|
position.y={0.8}
|
|
|
|
rotation.x={-Math.PI / 2}
|
2024-03-20 01:40:42 +01:00
|
|
|
material={circleMaterial}
|
2024-03-06 19:44:37 +01:00
|
|
|
>
|
2024-03-14 16:28:38 +01:00
|
|
|
<T.CircleGeometry args={[0.3, 16]} />
|
2024-03-06 19:44:37 +01:00
|
|
|
</T.Mesh>
|
|
|
|
|
|
|
|
<T.Mesh
|
2024-03-11 19:37:58 +01:00
|
|
|
position.x={to.x}
|
|
|
|
position.z={to.y}
|
2024-03-06 19:44:37 +01:00
|
|
|
position.y={0.8}
|
|
|
|
rotation.x={-Math.PI / 2}
|
2024-03-20 01:40:42 +01:00
|
|
|
material={circleMaterial}
|
2024-03-06 19:44:37 +01:00
|
|
|
>
|
2024-03-14 16:28:38 +01:00
|
|
|
<T.CircleGeometry args={[0.3, 16]} />
|
2024-03-06 19:44:37 +01:00
|
|
|
</T.Mesh>
|
|
|
|
|
2024-03-21 16:31:17 +01:00
|
|
|
{#if geometry}
|
|
|
|
<T.Mesh position.x={from.x} position.z={from.y} position.y={0.1} {geometry}>
|
|
|
|
<MeshLineMaterial
|
|
|
|
width={4}
|
|
|
|
attenuate={false}
|
|
|
|
color={color2}
|
|
|
|
toneMapped={false}
|
|
|
|
/>
|
|
|
|
</T.Mesh>
|
|
|
|
{/if}
|