chore: setup linting
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
<script lang="ts">
|
||||
import localStore from "$lib/helpers/localStore";
|
||||
import { T, useTask } from "@threlte/core";
|
||||
import { OrbitControls } from "@threlte/extras";
|
||||
import { onMount } from "svelte";
|
||||
import { Vector3 } from "three";
|
||||
import type { PerspectiveCamera, Vector3Tuple } from "three";
|
||||
import type { OrbitControls as OrbitControlsType } from "three/examples/jsm/controls/OrbitControls.js";
|
||||
import localStore from '$lib/helpers/localStore';
|
||||
import { T, useTask } from '@threlte/core';
|
||||
import { OrbitControls } from '@threlte/extras';
|
||||
import { onMount } from 'svelte';
|
||||
import { Vector3 } from 'three';
|
||||
import type { PerspectiveCamera, Vector3Tuple } from 'three';
|
||||
import type { OrbitControls as OrbitControlsType } from 'three/examples/jsm/controls/OrbitControls.js';
|
||||
|
||||
let camera = $state<PerspectiveCamera>();
|
||||
let controls = $state<OrbitControlsType>();
|
||||
@@ -20,9 +20,9 @@
|
||||
const cameraTransform = localStore<{
|
||||
camera: Vector3Tuple;
|
||||
target: Vector3Tuple;
|
||||
}>("nodes.camera.transform", {
|
||||
}>('nodes.camera.transform', {
|
||||
camera: [10, 10, 10],
|
||||
target: [0, 0, 0],
|
||||
target: [0, 0, 0]
|
||||
});
|
||||
|
||||
function saveCameraState() {
|
||||
@@ -33,7 +33,7 @@
|
||||
if (tPos.some((v) => isNaN(v)) || cPos.some((v) => isNaN(v))) return;
|
||||
$cameraTransform = {
|
||||
camera: cPos,
|
||||
target: tPos,
|
||||
target: tPos
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,13 +54,13 @@
|
||||
|
||||
$effect(() => {
|
||||
if (
|
||||
center &&
|
||||
controls &&
|
||||
centerCamera &&
|
||||
(center.x !== controls.target.x ||
|
||||
center.y !== controls.target.y ||
|
||||
center.z !== controls.target.z) &&
|
||||
!isRunning
|
||||
center
|
||||
&& controls
|
||||
&& centerCamera
|
||||
&& (center.x !== controls.target.x
|
||||
|| center.y !== controls.target.y
|
||||
|| center.z !== controls.target.z)
|
||||
&& !isRunning
|
||||
) {
|
||||
isRunning = true;
|
||||
task.start();
|
||||
|
||||
@@ -1,23 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { T, useTask, useThrelte } from "@threlte/core";
|
||||
import { colors } from '$lib/graph-interface/graph/colors.svelte';
|
||||
import { T, useTask, useThrelte } from '@threlte/core';
|
||||
import { Grid, MeshLineGeometry, MeshLineMaterial, Text } from '@threlte/extras';
|
||||
import {
|
||||
Grid,
|
||||
MeshLineGeometry,
|
||||
MeshLineMaterial,
|
||||
Text,
|
||||
} from "@threlte/extras";
|
||||
import {
|
||||
type Group,
|
||||
type BufferGeometry,
|
||||
Vector3,
|
||||
type Vector3Tuple,
|
||||
Box3,
|
||||
type BufferGeometry,
|
||||
type Group,
|
||||
Mesh,
|
||||
MeshBasicMaterial,
|
||||
} from "three";
|
||||
import { appSettings } from "../settings/app-settings.svelte";
|
||||
import Camera from "./Camera.svelte";
|
||||
import { colors } from "$lib/graph-interface/graph/colors.svelte";
|
||||
Vector3,
|
||||
type Vector3Tuple
|
||||
} from 'three';
|
||||
import { appSettings } from '../settings/app-settings.svelte';
|
||||
import Camera from './Camera.svelte';
|
||||
|
||||
const { renderStage, invalidate: _invalidate } = useThrelte();
|
||||
|
||||
@@ -32,7 +27,7 @@
|
||||
lines,
|
||||
centerCamera,
|
||||
fps = $bindable(),
|
||||
scene = $bindable(),
|
||||
scene = $bindable()
|
||||
}: Props = $props();
|
||||
|
||||
let geometries = $state.raw<BufferGeometry[]>([]);
|
||||
@@ -43,13 +38,13 @@
|
||||
fps.push(1 / delta);
|
||||
fps = fps.slice(-100);
|
||||
},
|
||||
{ stage: renderStage, autoInvalidate: false },
|
||||
{ stage: renderStage, autoInvalidate: false }
|
||||
);
|
||||
|
||||
export const invalidate = function () {
|
||||
export const invalidate = function() {
|
||||
if (scene) {
|
||||
const geos: BufferGeometry[] = [];
|
||||
scene.traverse(function (child) {
|
||||
scene.traverse(function(child) {
|
||||
if (isMesh(child)) {
|
||||
geos.push(child.geometry);
|
||||
}
|
||||
@@ -67,17 +62,29 @@
|
||||
_invalidate();
|
||||
};
|
||||
|
||||
function isMesh(child: Mesh | any): child is Mesh {
|
||||
return child.isObject3D && "material" in child;
|
||||
function isMesh(child: unknown): child is Mesh {
|
||||
return (
|
||||
child !== null
|
||||
&& typeof child === 'object'
|
||||
&& 'isObject3D' in child
|
||||
&& child.isObject3D === true
|
||||
&& 'material' in child
|
||||
);
|
||||
}
|
||||
|
||||
function isMatCapMaterial(material: any): material is MeshBasicMaterial {
|
||||
return material.isMaterial && "matcap" in material;
|
||||
function isMatCapMaterial(material: unknown): material is MeshBasicMaterial {
|
||||
return (
|
||||
material !== null
|
||||
&& typeof material === 'object'
|
||||
&& 'isMaterial' in material
|
||||
&& material.isMaterial === true
|
||||
&& 'matcap' in material
|
||||
);
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
const wireframe = appSettings.value.debug.wireframe;
|
||||
scene.traverse(function (child) {
|
||||
scene.traverse(function(child) {
|
||||
if (isMesh(child) && isMatCapMaterial(child.material) && child.visible) {
|
||||
child.material.wireframe = wireframe;
|
||||
}
|
||||
@@ -89,7 +96,7 @@
|
||||
return [
|
||||
geo.attributes.position.array[i],
|
||||
geo.attributes.position.array[i + 1],
|
||||
geo.attributes.position.array[i + 2],
|
||||
geo.attributes.position.array[i + 2]
|
||||
] as Vector3Tuple;
|
||||
}
|
||||
</script>
|
||||
@@ -98,12 +105,12 @@
|
||||
|
||||
{#if appSettings.value.showGrid}
|
||||
<Grid
|
||||
cellColor={colors["outline"]}
|
||||
cellColor={colors['outline']}
|
||||
cellThickness={0.7}
|
||||
infiniteGrid
|
||||
sectionThickness={0.7}
|
||||
sectionDistance={2}
|
||||
sectionColor={colors["outline"]}
|
||||
sectionColor={colors['outline']}
|
||||
fadeDistance={50}
|
||||
fadeStrength={10}
|
||||
fadeOrigin={new Vector3(0, 0, 0)}
|
||||
@@ -112,9 +119,9 @@
|
||||
|
||||
<T.Group>
|
||||
{#if geometries}
|
||||
{#each geometries as geo}
|
||||
{#each geometries as geo (geo.id)}
|
||||
{#if appSettings.value.debug.showIndices}
|
||||
{#each geo.attributes.position.array as _, i}
|
||||
{#each geo.attributes.position.array, i (i)}
|
||||
{#if i % 3 === 0}
|
||||
<Text fontSize={0.25} position={getPosition(geo, i)} />
|
||||
{/if}
|
||||
@@ -134,7 +141,7 @@
|
||||
</T.Group>
|
||||
|
||||
{#if appSettings.value.debug.showStemLines && lines}
|
||||
{#each lines as line}
|
||||
{#each lines as line (line[0].x + '-' + line[0].y + '-' + '' + line[0].z)}
|
||||
<T.Mesh>
|
||||
<MeshLineGeometry points={line} />
|
||||
<MeshLineMaterial width={0.1} color="red" depthTest={false} />
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { Canvas } from "@threlte/core";
|
||||
import Scene from "./Scene.svelte";
|
||||
import { Vector3 } from "three";
|
||||
import { decodeFloat, splitNestedArray } from "@nodarium/utils";
|
||||
import type { PerformanceStore } from "@nodarium/utils";
|
||||
import { appSettings } from "$lib/settings/app-settings.svelte";
|
||||
import SmallPerformanceViewer from "$lib/performance/SmallPerformanceViewer.svelte";
|
||||
import { MeshMatcapMaterial, TextureLoader, type Group } from "three";
|
||||
import {
|
||||
createGeometryPool,
|
||||
createInstancedGeometryPool,
|
||||
} from "./geometryPool";
|
||||
import SmallPerformanceViewer from '$lib/performance/SmallPerformanceViewer.svelte';
|
||||
import { appSettings } from '$lib/settings/app-settings.svelte';
|
||||
import { decodeFloat, splitNestedArray } from '@nodarium/utils';
|
||||
import type { PerformanceStore } from '@nodarium/utils';
|
||||
import { Canvas } from '@threlte/core';
|
||||
import { Vector3 } from 'three';
|
||||
import { type Group, MeshMatcapMaterial, TextureLoader } from 'three';
|
||||
import { createGeometryPool, createInstancedGeometryPool } from './geometryPool';
|
||||
import Scene from './Scene.svelte';
|
||||
|
||||
const loader = new TextureLoader();
|
||||
const matcap = loader.load("/matcap_green.jpg");
|
||||
matcap.colorSpace = "srgb";
|
||||
const matcap = loader.load('/matcap_green.jpg');
|
||||
matcap.colorSpace = 'srgb';
|
||||
const material = new MeshMatcapMaterial({
|
||||
color: 0xffffff,
|
||||
matcap,
|
||||
matcap
|
||||
});
|
||||
|
||||
let sceneComponent = $state<ReturnType<typeof Scene>>();
|
||||
@@ -34,7 +31,7 @@
|
||||
|
||||
return {
|
||||
totalFaces: meshes.totalFaces + faces.totalFaces,
|
||||
totalVertices: meshes.totalVertices + faces.totalVertices,
|
||||
totalVertices: meshes.totalVertices + faces.totalVertices
|
||||
};
|
||||
}
|
||||
|
||||
@@ -64,12 +61,12 @@
|
||||
}
|
||||
|
||||
export const update = function update(result: Int32Array) {
|
||||
perf.addPoint("split-result");
|
||||
perf.addPoint('split-result');
|
||||
const inputs = splitNestedArray(result);
|
||||
perf.endPoint();
|
||||
|
||||
if (appSettings.value.debug.showStemLines) {
|
||||
perf.addPoint("create-lines");
|
||||
perf.addPoint('create-lines');
|
||||
lines = inputs
|
||||
.map((input) => {
|
||||
if (input[0] === 0) {
|
||||
@@ -80,13 +77,13 @@
|
||||
perf.endPoint();
|
||||
}
|
||||
|
||||
perf.addPoint("update-geometries");
|
||||
perf.addPoint('update-geometries');
|
||||
|
||||
const { totalVertices, totalFaces } = updateGeometries(inputs, scene);
|
||||
perf.endPoint();
|
||||
|
||||
perf.addPoint("total-vertices", totalVertices);
|
||||
perf.addPoint("total-faces", totalFaces);
|
||||
perf.addPoint('total-vertices', totalVertices);
|
||||
perf.addPoint('total-faces', totalFaces);
|
||||
sceneComponent?.invalidate();
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { fastHashArrayBuffer } from "@nodarium/utils";
|
||||
import { fastHashArrayBuffer } from '@nodarium/utils';
|
||||
import {
|
||||
BufferAttribute,
|
||||
BufferGeometry,
|
||||
@@ -7,14 +7,14 @@ import {
|
||||
InstancedMesh,
|
||||
Material,
|
||||
Matrix4,
|
||||
Mesh,
|
||||
} from "three";
|
||||
Mesh
|
||||
} from 'three';
|
||||
|
||||
function fastArrayHash(arr: Int32Array) {
|
||||
const sampleDistance = Math.max(Math.floor(arr.length / 1000), 1);
|
||||
const sampleCount = Math.floor(arr.length / sampleDistance);
|
||||
|
||||
let hash = new Int32Array(sampleCount);
|
||||
const hash = new Int32Array(sampleCount);
|
||||
|
||||
for (let i = 0; i < sampleCount; i++) {
|
||||
const index = i * sampleDistance;
|
||||
@@ -28,18 +28,18 @@ export function createGeometryPool(parentScene: Group, material: Material) {
|
||||
const scene = new Group();
|
||||
parentScene.add(scene);
|
||||
|
||||
let meshes: Mesh[] = [];
|
||||
const meshes: Mesh[] = [];
|
||||
|
||||
let totalVertices = 0;
|
||||
let totalFaces = 0;
|
||||
|
||||
function updateSingleGeometry(
|
||||
data: Int32Array,
|
||||
existingMesh: Mesh | null = null,
|
||||
existingMesh: Mesh | null = null
|
||||
) {
|
||||
let hash = fastArrayHash(data);
|
||||
const hash = fastArrayHash(data);
|
||||
|
||||
let geometry = existingMesh ? existingMesh.geometry : new BufferGeometry();
|
||||
const geometry = existingMesh ? existingMesh.geometry : new BufferGeometry();
|
||||
if (existingMesh) {
|
||||
existingMesh.visible = true;
|
||||
}
|
||||
@@ -65,8 +65,8 @@ export function createGeometryPool(parentScene: Group, material: Material) {
|
||||
const vertices = new Float32Array(data.buffer, index * 4, vertexCount * 3);
|
||||
index = index + vertexCount * 3;
|
||||
|
||||
let posAttribute = geometry.getAttribute(
|
||||
"position",
|
||||
const posAttribute = geometry.getAttribute(
|
||||
'position'
|
||||
) as BufferAttribute | null;
|
||||
|
||||
if (posAttribute && posAttribute.count === vertexCount) {
|
||||
@@ -74,8 +74,8 @@ export function createGeometryPool(parentScene: Group, material: Material) {
|
||||
posAttribute.needsUpdate = true;
|
||||
} else {
|
||||
geometry.setAttribute(
|
||||
"position",
|
||||
new Float32BufferAttribute(vertices, 3),
|
||||
'position',
|
||||
new Float32BufferAttribute(vertices, 3)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -83,27 +83,27 @@ export function createGeometryPool(parentScene: Group, material: Material) {
|
||||
index = index + vertexCount * 3;
|
||||
|
||||
if (
|
||||
geometry.userData?.faceCount !== faceCount ||
|
||||
geometry.userData?.vertexCount !== vertexCount
|
||||
geometry.userData?.faceCount !== faceCount
|
||||
|| geometry.userData?.vertexCount !== vertexCount
|
||||
) {
|
||||
// Add data to geometry
|
||||
geometry.setIndex([...indices]);
|
||||
}
|
||||
|
||||
const normalsAttribute = geometry.getAttribute(
|
||||
"normal",
|
||||
'normal'
|
||||
) as BufferAttribute | null;
|
||||
if (normalsAttribute && normalsAttribute.count === vertexCount) {
|
||||
normalsAttribute.set(normals, 0);
|
||||
normalsAttribute.needsUpdate = true;
|
||||
} else {
|
||||
geometry.setAttribute("normal", new Float32BufferAttribute(normals, 3));
|
||||
geometry.setAttribute('normal', new Float32BufferAttribute(normals, 3));
|
||||
}
|
||||
|
||||
geometry.userData = {
|
||||
vertexCount,
|
||||
faceCount,
|
||||
hash,
|
||||
hash
|
||||
};
|
||||
|
||||
if (!existingMesh) {
|
||||
@@ -119,7 +119,7 @@ export function createGeometryPool(parentScene: Group, material: Material) {
|
||||
totalFaces = 0;
|
||||
for (let i = 0; i < Math.max(newData.length, meshes.length); i++) {
|
||||
const existingMesh = meshes[i];
|
||||
let input = newData[i];
|
||||
const input = newData[i];
|
||||
if (input) {
|
||||
updateSingleGeometry(input, existingMesh || null);
|
||||
} else if (existingMesh) {
|
||||
@@ -127,13 +127,13 @@ export function createGeometryPool(parentScene: Group, material: Material) {
|
||||
}
|
||||
}
|
||||
return { totalVertices, totalFaces };
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function createInstancedGeometryPool(
|
||||
parentScene: Group,
|
||||
material: Material,
|
||||
material: Material
|
||||
) {
|
||||
const scene = new Group();
|
||||
parentScene.add(scene);
|
||||
@@ -144,11 +144,11 @@ export function createInstancedGeometryPool(
|
||||
|
||||
function updateSingleInstance(
|
||||
data: Int32Array,
|
||||
existingInstance: InstancedMesh | null = null,
|
||||
existingInstance: InstancedMesh | null = null
|
||||
) {
|
||||
let hash = fastArrayHash(data);
|
||||
const hash = fastArrayHash(data);
|
||||
|
||||
let geometry = existingInstance
|
||||
const geometry = existingInstance
|
||||
? existingInstance.geometry
|
||||
: new BufferGeometry();
|
||||
|
||||
@@ -169,8 +169,8 @@ export function createInstancedGeometryPool(
|
||||
const indices = data.subarray(index, indicesEnd);
|
||||
index = indicesEnd;
|
||||
if (
|
||||
geometry.userData?.faceCount !== faceCount ||
|
||||
geometry.userData?.vertexCount !== vertexCount
|
||||
geometry.userData?.faceCount !== faceCount
|
||||
|| geometry.userData?.vertexCount !== vertexCount
|
||||
) {
|
||||
// Add data to geometry
|
||||
geometry.setIndex([...indices]);
|
||||
@@ -179,34 +179,34 @@ export function createInstancedGeometryPool(
|
||||
// Vertices
|
||||
const vertices = new Float32Array(data.buffer, index * 4, vertexCount * 3);
|
||||
index = index + vertexCount * 3;
|
||||
let posAttribute = geometry.getAttribute(
|
||||
"position",
|
||||
const posAttribute = geometry.getAttribute(
|
||||
'position'
|
||||
) as BufferAttribute | null;
|
||||
if (posAttribute && posAttribute.count === vertexCount) {
|
||||
posAttribute.set(vertices, 0);
|
||||
posAttribute.needsUpdate = true;
|
||||
} else {
|
||||
geometry.setAttribute(
|
||||
"position",
|
||||
new Float32BufferAttribute(vertices, 3),
|
||||
'position',
|
||||
new Float32BufferAttribute(vertices, 3)
|
||||
);
|
||||
}
|
||||
|
||||
const normals = new Float32Array(data.buffer, index * 4, vertexCount * 3);
|
||||
index = index + vertexCount * 3;
|
||||
const normalsAttribute = geometry.getAttribute(
|
||||
"normal",
|
||||
'normal'
|
||||
) as BufferAttribute | null;
|
||||
if (normalsAttribute && normalsAttribute.count === vertexCount) {
|
||||
normalsAttribute.set(normals, 0);
|
||||
normalsAttribute.needsUpdate = true;
|
||||
} else {
|
||||
geometry.setAttribute("normal", new Float32BufferAttribute(normals, 3));
|
||||
geometry.setAttribute('normal', new Float32BufferAttribute(normals, 3));
|
||||
}
|
||||
|
||||
if (
|
||||
existingInstance &&
|
||||
instanceCount > existingInstance.geometry.userData.count
|
||||
existingInstance
|
||||
&& instanceCount > existingInstance.geometry.userData.count
|
||||
) {
|
||||
scene.remove(existingInstance);
|
||||
instances.splice(instances.indexOf(existingInstance), 1);
|
||||
@@ -226,12 +226,12 @@ export function createInstancedGeometryPool(
|
||||
const matrices = new Float32Array(
|
||||
data.buffer,
|
||||
index * 4,
|
||||
instanceCount * 16,
|
||||
instanceCount * 16
|
||||
);
|
||||
|
||||
for (let i = 0; i < instanceCount; i++) {
|
||||
const matrix = new Matrix4().fromArray(
|
||||
matrices.subarray(i * 16, i * 16 + 16),
|
||||
matrices.subarray(i * 16, i * 16 + 16)
|
||||
);
|
||||
existingInstance.setMatrixAt(i, matrix);
|
||||
}
|
||||
@@ -241,9 +241,9 @@ export function createInstancedGeometryPool(
|
||||
faceCount,
|
||||
count: Math.max(
|
||||
instanceCount,
|
||||
existingInstance.geometry.userData.count || 0,
|
||||
existingInstance.geometry.userData.count || 0
|
||||
),
|
||||
hash,
|
||||
hash
|
||||
};
|
||||
|
||||
existingInstance.instanceMatrix.needsUpdate = true;
|
||||
@@ -255,7 +255,7 @@ export function createInstancedGeometryPool(
|
||||
totalFaces = 0;
|
||||
for (let i = 0; i < Math.max(newData.length, instances.length); i++) {
|
||||
const existingMesh = instances[i];
|
||||
let input = newData[i];
|
||||
const input = newData[i];
|
||||
if (input) {
|
||||
updateSingleInstance(input, existingMesh || null);
|
||||
} else if (existingMesh) {
|
||||
@@ -263,6 +263,6 @@ export function createInstancedGeometryPool(
|
||||
}
|
||||
}
|
||||
return { totalVertices, totalFaces };
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user