Add tooling setup with biome, justfile, and check pipeline
This commit is contained in:
parent
a3bbc258be
commit
03679622a3
14 changed files with 524 additions and 393 deletions
24
biome.json
Normal file
24
biome.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.4.6/schema.json",
|
||||
"root": true,
|
||||
"vcs": {
|
||||
"enabled": true,
|
||||
"clientKind": "git",
|
||||
"useIgnoreFile": true
|
||||
},
|
||||
"formatter": {
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 4
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true
|
||||
},
|
||||
"assist": {
|
||||
"enabled": true,
|
||||
"actions": {
|
||||
"source": {
|
||||
"organizeImports": "on"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
bun.lock
32
bun.lock
|
|
@ -9,13 +9,33 @@
|
|||
"three": "^0.173.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.4.6",
|
||||
"@types/bun": "^1.3.10",
|
||||
"@types/three": "^0.173.0",
|
||||
"typescript": "^5.8.2",
|
||||
"vite": "^6.2.1",
|
||||
"typescript": "^5.9.3",
|
||||
"vite": "^6.4.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@biomejs/biome": ["@biomejs/biome@2.4.6", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.6", "@biomejs/cli-darwin-x64": "2.4.6", "@biomejs/cli-linux-arm64": "2.4.6", "@biomejs/cli-linux-arm64-musl": "2.4.6", "@biomejs/cli-linux-x64": "2.4.6", "@biomejs/cli-linux-x64-musl": "2.4.6", "@biomejs/cli-win32-arm64": "2.4.6", "@biomejs/cli-win32-x64": "2.4.6" }, "bin": { "biome": "bin/biome" } }, "sha512-QnHe81PMslpy3mnpL8DnO2M4S4ZnYPkjlGCLWBZT/3R9M6b5daArWMMtEfP52/n174RKnwRIf3oT8+wc9ihSfQ=="],
|
||||
|
||||
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-NW18GSyxr+8sJIqgoGwVp5Zqm4SALH4b4gftIA0n62PTuBs6G2tHlwNAOj0Vq0KKSs7Sf88VjjmHh0O36EnzrQ=="],
|
||||
|
||||
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-4uiE/9tuI7cnjtY9b07RgS7gGyYOAfIAGeVJWEfeCnAarOAS7qVmuRyX6d7JTKw28/mt+rUzMasYeZ+0R/U1Mw=="],
|
||||
|
||||
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-kMLaI7OF5GN1Q8Doymjro1P8rVEoy7BKQALNz6fiR8IC1WKduoNyteBtJlHT7ASIL0Cx2jR6VUOBIbcB1B8pew=="],
|
||||
|
||||
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-F/JdB7eN22txiTqHM5KhIVt0jVkzZwVYrdTR1O3Y4auBOQcXxHK4dxULf4z43QyZI5tsnQJrRBHZy7wwtL+B3A=="],
|
||||
|
||||
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.6", "", { "os": "linux", "cpu": "x64" }, "sha512-oHXmUFEoH8Lql1xfc3QkFLiC1hGR7qedv5eKNlC185or+o4/4HiaU7vYODAH3peRCfsuLr1g6v2fK9dFFOYdyw=="],
|
||||
|
||||
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.6", "", { "os": "linux", "cpu": "x64" }, "sha512-C9s98IPDu7DYarjlZNuzJKTjVHN03RUnmHV5htvqsx6vEUXCDSJ59DNwjKVD5XYoSS4N+BYhq3RTBAL8X6svEg=="],
|
||||
|
||||
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-xzThn87Pf3YrOGTEODFGONmqXpTwUNxovQb72iaUOdcw8sBSY3+3WD8Hm9IhMYLnPi0n32s3L3NWU6+eSjfqFg=="],
|
||||
|
||||
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.6", "", { "os": "win32", "cpu": "x64" }, "sha512-7++XhnsPlr1HDbor5amovPjOH6vsrFOCdp93iKXhFn6bcMUI6soodj3WWKfgEO6JosKU1W5n3uky3WW9RlRjTg=="],
|
||||
|
||||
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
|
||||
|
||||
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
|
||||
|
|
@ -120,8 +140,12 @@
|
|||
|
||||
"@tweenjs/tween.js": ["@tweenjs/tween.js@23.1.3", "", {}, "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA=="],
|
||||
|
||||
"@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="],
|
||||
|
||||
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||
|
||||
"@types/node": ["@types/node@25.3.5", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA=="],
|
||||
|
||||
"@types/stats.js": ["@types/stats.js@0.17.4", "", {}, "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA=="],
|
||||
|
||||
"@types/three": ["@types/three@0.173.0", "", { "dependencies": { "@tweenjs/tween.js": "~23.1.3", "@types/stats.js": "*", "@types/webxr": "*", "@webgpu/types": "*", "fflate": "~0.8.2", "meshoptimizer": "~0.18.1" } }, "sha512-KtNjfI/CRB6JVKIVeZM1R3GYDX2wkoV2itNcQu2j4d7qkhjGOuB+s2oF6jl9mztycDLGMtrAnJQYxInC8Bb20A=="],
|
||||
|
|
@ -130,6 +154,8 @@
|
|||
|
||||
"@webgpu/types": ["@webgpu/types@0.1.69", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="],
|
||||
|
||||
"bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="],
|
||||
|
||||
"esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
|
||||
|
||||
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||
|
|
@ -160,6 +186,8 @@
|
|||
|
||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||
|
||||
"undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
|
||||
|
||||
"vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
13
justfile
Normal file
13
justfile
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
default:
|
||||
@just --list
|
||||
|
||||
lint:
|
||||
bun run lint
|
||||
|
||||
typecheck:
|
||||
bun run typecheck
|
||||
|
||||
test:
|
||||
bun run test
|
||||
|
||||
check: lint typecheck test
|
||||
|
|
@ -8,6 +8,8 @@
|
|||
"three": "^0.173.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.4.6",
|
||||
"@types/bun": "^1.3.10",
|
||||
"@types/three": "^0.173.0",
|
||||
"typescript": "^5.9.3",
|
||||
"vite": "^6.4.1"
|
||||
|
|
@ -15,7 +17,11 @@
|
|||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"lint": "bunx biome check --write .",
|
||||
"typecheck": "bunx tsc --noEmit",
|
||||
"test": "bun test",
|
||||
"check": "bun run lint && bun run typecheck && bun run test"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
|
|
|
|||
159
src/Renderer.ts
159
src/Renderer.ts
|
|
@ -1,7 +1,7 @@
|
|||
import * as THREE from 'three';
|
||||
import {SceneCollection} from "./App";
|
||||
import type { WebGLRenderTarget } from "three";
|
||||
import * as THREE from "three";
|
||||
import type { SceneCollection } from "./App";
|
||||
import Config from "./Config";
|
||||
import {WebGLRenderTarget} from "three";
|
||||
|
||||
interface Resources {
|
||||
worldRenderTarget: THREE.WebGLRenderTarget;
|
||||
|
|
@ -17,7 +17,7 @@ export default class Renderer {
|
|||
public resources!: Resources;
|
||||
|
||||
constructor(public canvas: HTMLCanvasElement) {
|
||||
this.renderer = new THREE.WebGLRenderer({canvas})
|
||||
this.renderer = new THREE.WebGLRenderer({ canvas });
|
||||
|
||||
this.initResources();
|
||||
}
|
||||
|
|
@ -26,79 +26,112 @@ export default class Renderer {
|
|||
const antTextureSize = Math.round(Math.sqrt(2 ** Config.antsCount));
|
||||
|
||||
this.resources = {
|
||||
worldRenderTarget: new THREE.WebGLRenderTarget(Config.worldSize, Config.worldSize, {
|
||||
worldRenderTarget: new THREE.WebGLRenderTarget(
|
||||
Config.worldSize,
|
||||
Config.worldSize,
|
||||
{
|
||||
format: THREE.RGBAFormat,
|
||||
type: THREE.FloatType,
|
||||
depthBuffer: false,
|
||||
magFilter: THREE.LinearFilter,
|
||||
minFilter: THREE.LinearFilter,
|
||||
}),
|
||||
worldRenderTargetCopy: new THREE.WebGLRenderTarget(Config.worldSize, Config.worldSize, {
|
||||
},
|
||||
),
|
||||
worldRenderTargetCopy: new THREE.WebGLRenderTarget(
|
||||
Config.worldSize,
|
||||
Config.worldSize,
|
||||
{
|
||||
format: THREE.RGBAFormat,
|
||||
type: THREE.FloatType,
|
||||
depthBuffer: false,
|
||||
magFilter: THREE.NearestFilter,
|
||||
minFilter: THREE.NearestFilter,
|
||||
}),
|
||||
worldBlurredRenderTarget: new THREE.WebGLRenderTarget(Config.worldSize, Config.worldSize, {
|
||||
},
|
||||
),
|
||||
worldBlurredRenderTarget: new THREE.WebGLRenderTarget(
|
||||
Config.worldSize,
|
||||
Config.worldSize,
|
||||
{
|
||||
format: THREE.RGBAFormat,
|
||||
type: THREE.FloatType,
|
||||
depthBuffer: false,
|
||||
magFilter: THREE.NearestFilter,
|
||||
minFilter: THREE.NearestFilter,
|
||||
}),
|
||||
antsDataRenderTarget0: new THREE.WebGLRenderTarget(antTextureSize, antTextureSize, {
|
||||
},
|
||||
),
|
||||
antsDataRenderTarget0: new THREE.WebGLRenderTarget(
|
||||
antTextureSize,
|
||||
antTextureSize,
|
||||
{
|
||||
format: THREE.RGBAFormat,
|
||||
type: THREE.FloatType,
|
||||
depthBuffer: false,
|
||||
magFilter: THREE.NearestFilter,
|
||||
minFilter: THREE.NearestFilter,
|
||||
}),
|
||||
antsDataRenderTarget1: new THREE.WebGLRenderTarget(antTextureSize, antTextureSize, {
|
||||
},
|
||||
),
|
||||
antsDataRenderTarget1: new THREE.WebGLRenderTarget(
|
||||
antTextureSize,
|
||||
antTextureSize,
|
||||
{
|
||||
format: THREE.RGBAFormat,
|
||||
type: THREE.FloatType,
|
||||
depthBuffer: false,
|
||||
magFilter: THREE.NearestFilter,
|
||||
minFilter: THREE.NearestFilter,
|
||||
}),
|
||||
antsDiscreteRenderTarget: new THREE.WebGLRenderTarget(Config.worldSize, Config.worldSize, {
|
||||
},
|
||||
),
|
||||
antsDiscreteRenderTarget: new THREE.WebGLRenderTarget(
|
||||
Config.worldSize,
|
||||
Config.worldSize,
|
||||
{
|
||||
format: THREE.RGBAFormat,
|
||||
type: THREE.UnsignedByteType,
|
||||
depthBuffer: false,
|
||||
magFilter: THREE.NearestFilter,
|
||||
minFilter: THREE.NearestFilter,
|
||||
})
|
||||
},
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
public renderSimulation(scenes: SceneCollection) {
|
||||
const [antsComputeSource, antsComputeTarget] = scenes.ants.getRenderTargets();
|
||||
const [antsComputeSource, antsComputeTarget] =
|
||||
scenes.ants.getRenderTargets();
|
||||
|
||||
this.setViewportFromRT(this.resources.worldBlurredRenderTarget);
|
||||
this.renderer.setRenderTarget(this.resources.worldBlurredRenderTarget);
|
||||
scenes.worldBlur.material.uniforms.tWorld.value = this.resources.worldRenderTarget.texture;
|
||||
scenes.worldBlur.material.uniforms.tWorld.value =
|
||||
this.resources.worldRenderTarget.texture;
|
||||
this.renderer.render(scenes.worldBlur, scenes.worldBlur.camera);
|
||||
|
||||
this.setViewportFromRT(antsComputeTarget);
|
||||
this.renderer.setRenderTarget(antsComputeTarget);
|
||||
scenes.ants.material.uniforms.tLastState.value = antsComputeSource.texture;
|
||||
scenes.ants.material.uniforms.tWorld.value = this.resources.worldBlurredRenderTarget.texture;
|
||||
scenes.ants.material.uniforms.tLastState.value =
|
||||
antsComputeSource.texture;
|
||||
scenes.ants.material.uniforms.tWorld.value =
|
||||
this.resources.worldBlurredRenderTarget.texture;
|
||||
this.renderer.render(scenes.ants, scenes.ants.camera);
|
||||
|
||||
this.setViewportFromRT(this.resources.antsDiscreteRenderTarget);
|
||||
this.renderer.setRenderTarget(this.resources.antsDiscreteRenderTarget);
|
||||
scenes.discretize.material.uniforms.tDataCurrent.value = antsComputeTarget.texture;
|
||||
scenes.discretize.material.uniforms.tDataLast.value = antsComputeSource.texture;
|
||||
scenes.discretize.material.uniforms.tDataCurrent.value =
|
||||
antsComputeTarget.texture;
|
||||
scenes.discretize.material.uniforms.tDataLast.value =
|
||||
antsComputeSource.texture;
|
||||
this.renderer.render(scenes.discretize, scenes.discretize.camera);
|
||||
|
||||
this.setViewportFromRT(this.resources.worldRenderTarget);
|
||||
this.renderer.setRenderTarget(this.resources.worldRenderTarget);
|
||||
scenes.world.material.uniforms.tLastState.value = this.resources.worldBlurredRenderTarget.texture;
|
||||
scenes.world.material.uniforms.tDiscreteAnts.value = this.resources.antsDiscreteRenderTarget.texture;
|
||||
scenes.world.material.uniforms.tLastState.value =
|
||||
this.resources.worldBlurredRenderTarget.texture;
|
||||
scenes.world.material.uniforms.tDiscreteAnts.value =
|
||||
this.resources.antsDiscreteRenderTarget.texture;
|
||||
this.renderer.render(scenes.world, scenes.world.camera);
|
||||
|
||||
scenes.screen.material.uniforms.tData.value = antsComputeTarget.texture;
|
||||
scenes.screen.groundMaterial.uniforms.map.value = this.resources.worldRenderTargetCopy.texture;
|
||||
scenes.screen.groundMaterial.uniforms.map.value =
|
||||
this.resources.worldRenderTargetCopy.texture;
|
||||
}
|
||||
|
||||
private setViewportFromRT(rt: WebGLRenderTarget) {
|
||||
|
|
@ -108,14 +141,24 @@ export default class Renderer {
|
|||
public renderToScreen(scenes: SceneCollection) {
|
||||
this.setViewportFromRT(this.resources.worldRenderTargetCopy);
|
||||
this.renderer.setRenderTarget(this.resources.worldRenderTargetCopy);
|
||||
scenes.draw.material.uniforms.tWorld.value = this.resources.worldRenderTarget.texture;
|
||||
scenes.draw.material.uniforms.pointerPosition.value = scenes.screen.pointerPosition;
|
||||
scenes.draw.material.uniforms.tWorld.value =
|
||||
this.resources.worldRenderTarget.texture;
|
||||
scenes.draw.material.uniforms.pointerPosition.value =
|
||||
scenes.screen.pointerPosition;
|
||||
scenes.draw.material.uniforms.drawMode.value = scenes.screen.drawMode;
|
||||
scenes.draw.material.uniforms.brushRadius.value = Config.brushRadius;
|
||||
this.renderer.render(scenes.draw, scenes.draw.camera);
|
||||
this.renderer.copyFramebufferToTexture(this.resources.worldRenderTarget.texture, new THREE.Vector2());
|
||||
this.renderer.copyFramebufferToTexture(
|
||||
this.resources.worldRenderTarget.texture,
|
||||
new THREE.Vector2(),
|
||||
);
|
||||
|
||||
this.renderer.setViewport(0, 0, scenes.screen.renderWidth, scenes.screen.renderHeight);
|
||||
this.renderer.setViewport(
|
||||
0,
|
||||
0,
|
||||
scenes.screen.renderWidth,
|
||||
scenes.screen.renderHeight,
|
||||
);
|
||||
this.renderer.setRenderTarget(null);
|
||||
this.renderer.render(scenes.screen, scenes.screen.camera);
|
||||
}
|
||||
|
|
@ -128,41 +171,73 @@ export default class Renderer {
|
|||
public getCommonMaterialDefines(): Record<string, string> {
|
||||
return {
|
||||
WORLD_SIZE: Renderer.convertNumberToFloatString(Config.worldSize),
|
||||
SCENT_THRESHOLD: Renderer.convertNumberToFloatString(Config.scentThreshold),
|
||||
SCENT_FADE_OUT_FACTOR: Renderer.convertNumberToFloatString(Config.scentFadeOutFactor),
|
||||
SCENT_BLUR_RADIUS: Renderer.convertNumberToFloatString(Config.scentBlurRadius),
|
||||
SCENT_MAX_STORAGE: Renderer.convertNumberToFloatString(Config.scentMaxStorage),
|
||||
SCENT_PER_MARKER: Renderer.convertNumberToFloatString(Config.scentPerMarker),
|
||||
SCENT_MAX_PER_CELL: Renderer.convertNumberToFloatString(Config.scentMaxPerCell),
|
||||
SCENT_THRESHOLD: Renderer.convertNumberToFloatString(
|
||||
Config.scentThreshold,
|
||||
),
|
||||
SCENT_FADE_OUT_FACTOR: Renderer.convertNumberToFloatString(
|
||||
Config.scentFadeOutFactor,
|
||||
),
|
||||
SCENT_BLUR_RADIUS: Renderer.convertNumberToFloatString(
|
||||
Config.scentBlurRadius,
|
||||
),
|
||||
SCENT_MAX_STORAGE: Renderer.convertNumberToFloatString(
|
||||
Config.scentMaxStorage,
|
||||
),
|
||||
SCENT_PER_MARKER: Renderer.convertNumberToFloatString(
|
||||
Config.scentPerMarker,
|
||||
),
|
||||
SCENT_MAX_PER_CELL: Renderer.convertNumberToFloatString(
|
||||
Config.scentMaxPerCell,
|
||||
),
|
||||
ANT_SPEED: Renderer.convertNumberToFloatString(Config.antSpeed),
|
||||
ANT_ROTATION_ANGLE: Renderer.convertNumberToFloatString(Config.antRotationAngle)
|
||||
ANT_ROTATION_ANGLE: Renderer.convertNumberToFloatString(
|
||||
Config.antRotationAngle,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
public reset(scenes: SceneCollection) {
|
||||
const antTextureSize = Math.round(Math.sqrt(2 ** Config.antsCount));
|
||||
|
||||
this.resources.worldRenderTarget.setSize(Config.worldSize, Config.worldSize)
|
||||
this.resources.worldRenderTarget.setSize(
|
||||
Config.worldSize,
|
||||
Config.worldSize,
|
||||
);
|
||||
this.renderer.setRenderTarget(this.resources.worldRenderTarget);
|
||||
this.renderer.clear();
|
||||
|
||||
this.resources.worldRenderTargetCopy.setSize(Config.worldSize, Config.worldSize)
|
||||
this.resources.worldRenderTargetCopy.setSize(
|
||||
Config.worldSize,
|
||||
Config.worldSize,
|
||||
);
|
||||
this.renderer.setRenderTarget(this.resources.worldRenderTargetCopy);
|
||||
this.renderer.clear();
|
||||
|
||||
this.resources.worldBlurredRenderTarget.setSize(Config.worldSize, Config.worldSize)
|
||||
this.resources.worldBlurredRenderTarget.setSize(
|
||||
Config.worldSize,
|
||||
Config.worldSize,
|
||||
);
|
||||
this.renderer.setRenderTarget(this.resources.worldBlurredRenderTarget);
|
||||
this.renderer.clear();
|
||||
|
||||
this.resources.antsDataRenderTarget0.setSize(antTextureSize, antTextureSize)
|
||||
this.resources.antsDataRenderTarget0.setSize(
|
||||
antTextureSize,
|
||||
antTextureSize,
|
||||
);
|
||||
this.renderer.setRenderTarget(this.resources.antsDataRenderTarget0);
|
||||
this.renderer.clear();
|
||||
|
||||
this.resources.antsDataRenderTarget1.setSize(antTextureSize, antTextureSize)
|
||||
this.resources.antsDataRenderTarget1.setSize(
|
||||
antTextureSize,
|
||||
antTextureSize,
|
||||
);
|
||||
this.renderer.setRenderTarget(this.resources.antsDataRenderTarget1);
|
||||
this.renderer.clear();
|
||||
|
||||
this.resources.antsDiscreteRenderTarget.setSize(Config.worldSize, Config.worldSize)
|
||||
this.resources.antsDiscreteRenderTarget.setSize(
|
||||
Config.worldSize,
|
||||
Config.worldSize,
|
||||
);
|
||||
this.renderer.setRenderTarget(this.resources.antsDiscreteRenderTarget);
|
||||
this.renderer.clear();
|
||||
|
||||
|
|
|
|||
7
src/__tests__/placeholder.test.ts
Normal file
7
src/__tests__/placeholder.test.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { describe, expect, test } from "bun:test";
|
||||
|
||||
describe("placeholder", () => {
|
||||
test("passes", () => {
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
});
|
||||
4
src/global.d.ts
vendored
4
src/global.d.ts
vendored
|
|
@ -1,8 +1,8 @@
|
|||
declare module '*.vert' {
|
||||
declare module "*.vert" {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
declare module '*.frag' {
|
||||
declare module "*.frag" {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
import * as THREE from 'three';
|
||||
import {WebGLRenderTarget} from 'three';
|
||||
import Renderer from "../Renderer";
|
||||
import AbstractScene from "./AbstractScene";
|
||||
import type { WebGLRenderTarget } from "three";
|
||||
import * as THREE from "three";
|
||||
import type Renderer from "../Renderer";
|
||||
import fragmentShader from "../shaders/antsCompute.frag";
|
||||
import vertexShader from "../shaders/antsCompute.vert";
|
||||
import FullScreenTriangleGeometry from "../utils/FullScreenTriangleGeometry";
|
||||
import fragmentShader from '../shaders/antsCompute.frag';
|
||||
import vertexShader from '../shaders/antsCompute.vert';
|
||||
import AbstractScene from "./AbstractScene";
|
||||
|
||||
export default class AntsComputeScene extends AbstractScene {
|
||||
public camera: THREE.OrthographicCamera = new THREE.OrthographicCamera();
|
||||
|
|
@ -17,14 +17,14 @@ export default class AntsComputeScene extends AbstractScene {
|
|||
const geometry = new FullScreenTriangleGeometry();
|
||||
const material = new THREE.RawShaderMaterial({
|
||||
uniforms: {
|
||||
uTime: {value: 0},
|
||||
tLastState: {value: null},
|
||||
tWorld: {value: null},
|
||||
uTime: { value: 0 },
|
||||
tLastState: { value: null },
|
||||
tWorld: { value: null },
|
||||
},
|
||||
vertexShader,
|
||||
fragmentShader,
|
||||
defines: this.renderer.getCommonMaterialDefines(),
|
||||
glslVersion: THREE.GLSL3
|
||||
glslVersion: THREE.GLSL3,
|
||||
});
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
this.add(mesh);
|
||||
|
|
@ -33,7 +33,7 @@ export default class AntsComputeScene extends AbstractScene {
|
|||
|
||||
this.renderTargets = [
|
||||
this.renderer.resources.antsDataRenderTarget0,
|
||||
this.renderer.resources.antsDataRenderTarget1
|
||||
this.renderer.resources.antsDataRenderTarget1,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -48,9 +48,7 @@ export default class AntsComputeScene extends AbstractScene {
|
|||
this.material.needsUpdate = true;
|
||||
}
|
||||
|
||||
public resize(width: number, height: number) {
|
||||
|
||||
}
|
||||
public resize(width: number, height: number) {}
|
||||
|
||||
public update() {
|
||||
this.material.uniforms.uTime.value = performance.now();
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import * as THREE from 'three';
|
||||
import Renderer from "../Renderer";
|
||||
import AbstractScene from "./AbstractScene";
|
||||
import * as THREE from "three";
|
||||
import type Renderer from "../Renderer";
|
||||
import fragmentShader from "../shaders/draw.frag";
|
||||
import vertexShader from "../shaders/draw.vert";
|
||||
import FullScreenTriangleGeometry from "../utils/FullScreenTriangleGeometry";
|
||||
import fragmentShader from '../shaders/draw.frag';
|
||||
import vertexShader from '../shaders/draw.vert';
|
||||
import AbstractScene from "./AbstractScene";
|
||||
|
||||
export default class DrawScene extends AbstractScene {
|
||||
public readonly camera: THREE.OrthographicCamera = new THREE.OrthographicCamera();
|
||||
public readonly camera: THREE.OrthographicCamera =
|
||||
new THREE.OrthographicCamera();
|
||||
public readonly material: THREE.RawShaderMaterial;
|
||||
|
||||
constructor(renderer: Renderer) {
|
||||
|
|
@ -15,15 +16,15 @@ export default class DrawScene extends AbstractScene {
|
|||
const geometry = new FullScreenTriangleGeometry();
|
||||
const material = new THREE.RawShaderMaterial({
|
||||
uniforms: {
|
||||
tWorld: {value: null},
|
||||
pointerPosition: {value: new THREE.Vector2()},
|
||||
drawMode: {value: 0},
|
||||
brushRadius: {value: 0},
|
||||
tWorld: { value: null },
|
||||
pointerPosition: { value: new THREE.Vector2() },
|
||||
drawMode: { value: 0 },
|
||||
brushRadius: { value: 0 },
|
||||
},
|
||||
vertexShader,
|
||||
fragmentShader,
|
||||
defines: this.renderer.getCommonMaterialDefines(),
|
||||
glslVersion: THREE.GLSL3
|
||||
glslVersion: THREE.GLSL3,
|
||||
});
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
this.add(mesh);
|
||||
|
|
@ -36,11 +37,7 @@ export default class DrawScene extends AbstractScene {
|
|||
this.material.needsUpdate = true;
|
||||
}
|
||||
|
||||
public resize(width: number, height: number) {
|
||||
public resize(width: number, height: number) {}
|
||||
|
||||
}
|
||||
|
||||
public update() {
|
||||
|
||||
}
|
||||
public update() {}
|
||||
}
|
||||
|
|
@ -1,12 +1,13 @@
|
|||
import * as THREE from 'three';
|
||||
import Renderer from "../Renderer";
|
||||
import AbstractScene from "./AbstractScene";
|
||||
import * as THREE from "three";
|
||||
import type Renderer from "../Renderer";
|
||||
import fragmentShader from "../shaders/worldBlur.frag";
|
||||
import vertexShader from "../shaders/worldBlur.vert";
|
||||
import FullScreenTriangleGeometry from "../utils/FullScreenTriangleGeometry";
|
||||
import fragmentShader from '../shaders/worldBlur.frag';
|
||||
import vertexShader from '../shaders/worldBlur.vert';
|
||||
import AbstractScene from "./AbstractScene";
|
||||
|
||||
export default class WorldBlurScene extends AbstractScene {
|
||||
public readonly camera: THREE.OrthographicCamera = new THREE.OrthographicCamera();
|
||||
public readonly camera: THREE.OrthographicCamera =
|
||||
new THREE.OrthographicCamera();
|
||||
public readonly material: THREE.RawShaderMaterial;
|
||||
|
||||
constructor(renderer: Renderer) {
|
||||
|
|
@ -15,12 +16,12 @@ export default class WorldBlurScene extends AbstractScene {
|
|||
const geometry = new FullScreenTriangleGeometry();
|
||||
const material = new THREE.RawShaderMaterial({
|
||||
uniforms: {
|
||||
tWorld: {value: null},
|
||||
tWorld: { value: null },
|
||||
},
|
||||
vertexShader,
|
||||
fragmentShader,
|
||||
defines: this.renderer.getCommonMaterialDefines(),
|
||||
glslVersion: THREE.GLSL3
|
||||
glslVersion: THREE.GLSL3,
|
||||
});
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
this.add(mesh);
|
||||
|
|
@ -33,11 +34,7 @@ export default class WorldBlurScene extends AbstractScene {
|
|||
this.material.needsUpdate = true;
|
||||
}
|
||||
|
||||
public resize(width: number, height: number) {
|
||||
public resize(width: number, height: number) {}
|
||||
|
||||
}
|
||||
|
||||
public update() {
|
||||
|
||||
}
|
||||
public update() {}
|
||||
}
|
||||
|
|
@ -1,12 +1,13 @@
|
|||
import * as THREE from 'three';
|
||||
import Renderer from "../Renderer";
|
||||
import AbstractScene from "./AbstractScene";
|
||||
import * as THREE from "three";
|
||||
import type Renderer from "../Renderer";
|
||||
import fragmentShader from "../shaders/world.frag";
|
||||
import vertexShader from "../shaders/world.vert";
|
||||
import FullScreenTriangleGeometry from "../utils/FullScreenTriangleGeometry";
|
||||
import fragmentShader from '../shaders/world.frag';
|
||||
import vertexShader from '../shaders/world.vert';
|
||||
import AbstractScene from "./AbstractScene";
|
||||
|
||||
export default class WorldComputeScene extends AbstractScene {
|
||||
public readonly camera: THREE.OrthographicCamera = new THREE.OrthographicCamera();
|
||||
public readonly camera: THREE.OrthographicCamera =
|
||||
new THREE.OrthographicCamera();
|
||||
public readonly material: THREE.RawShaderMaterial;
|
||||
|
||||
constructor(renderer: Renderer) {
|
||||
|
|
@ -15,13 +16,13 @@ export default class WorldComputeScene extends AbstractScene {
|
|||
const geometry = new FullScreenTriangleGeometry();
|
||||
const material = new THREE.RawShaderMaterial({
|
||||
uniforms: {
|
||||
tLastState: {value: null},
|
||||
tDiscreteAnts: {value: null}
|
||||
tLastState: { value: null },
|
||||
tDiscreteAnts: { value: null },
|
||||
},
|
||||
vertexShader,
|
||||
fragmentShader,
|
||||
defines: this.renderer.getCommonMaterialDefines(),
|
||||
glslVersion: THREE.GLSL3
|
||||
glslVersion: THREE.GLSL3,
|
||||
});
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
this.add(mesh);
|
||||
|
|
@ -34,11 +35,7 @@ export default class WorldComputeScene extends AbstractScene {
|
|||
this.material.needsUpdate = true;
|
||||
}
|
||||
|
||||
public resize(width: number, height: number) {
|
||||
public resize(width: number, height: number) {}
|
||||
|
||||
}
|
||||
|
||||
public update() {
|
||||
|
||||
}
|
||||
public update() {}
|
||||
}
|
||||
|
|
@ -1,28 +1,17 @@
|
|||
import * as THREE from "three";
|
||||
|
||||
const positionBuffer = new Float32Array([
|
||||
-1, 3, 0,
|
||||
-1, -1, 0,
|
||||
3, -1, 0,
|
||||
]);
|
||||
const positionBuffer = new Float32Array([-1, 3, 0, -1, -1, 0, 3, -1, 0]);
|
||||
|
||||
const uvBuffer = new Float32Array([
|
||||
0, 2,
|
||||
0, 0,
|
||||
2, 0
|
||||
]);
|
||||
const uvBuffer = new Float32Array([0, 2, 0, 0, 2, 0]);
|
||||
|
||||
export default class FullScreenTriangleGeometry extends THREE.BufferGeometry {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.setAttribute(
|
||||
'position',
|
||||
new THREE.BufferAttribute(positionBuffer, 3)
|
||||
);
|
||||
this.setAttribute(
|
||||
'uv',
|
||||
new THREE.BufferAttribute(uvBuffer, 2)
|
||||
"position",
|
||||
new THREE.BufferAttribute(positionBuffer, 3),
|
||||
);
|
||||
this.setAttribute("uv", new THREE.BufferAttribute(uvBuffer, 2));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue