new performance overlay

This commit is contained in:
azykov@mail.ru
2026-06-13 17:25:13 +03:00
parent a61b5f0105
commit 936db7ee0f
11 changed files with 260 additions and 64 deletions
+238
View File
@@ -75,6 +75,9 @@ importers:
nipplejs: nipplejs:
specifier: ^1.0.4 specifier: ^1.0.4
version: 1.0.4 version: 1.0.4
r3f-perf:
specifier: ^7.2.3
version: 7.2.3(@react-three/fiber@9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0))(@types/react@19.2.15)(@types/three@0.184.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0)(use-sync-external-store@1.6.0(react@19.2.6))
react: react:
specifier: ^19.2.6 specifier: ^19.2.6
version: 19.2.6 version: 19.2.6
@@ -583,6 +586,39 @@ packages:
'@pinojs/redact@0.4.0': '@pinojs/redact@0.4.0':
resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==}
'@radix-ui/react-icons@1.3.2':
resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==}
peerDependencies:
react: ^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc
'@react-spring/animated@9.7.5':
resolution: {integrity: sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
'@react-spring/core@9.7.5':
resolution: {integrity: sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
'@react-spring/rafz@9.7.5':
resolution: {integrity: sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw==}
'@react-spring/shared@9.7.5':
resolution: {integrity: sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
'@react-spring/three@9.7.5':
resolution: {integrity: sha512-RxIsCoQfUqOS3POmhVHa1wdWS0wyHAUway73uRLp3GAL5U2iYVNdnzQsep6M2NZ994BlW8TcKuMtQHUqOsy6WA==}
peerDependencies:
'@react-three/fiber': '>=6.0'
react: ^16.8.0 || ^17.0.0 || ^18.0.0
three: '>=0.126'
'@react-spring/types@9.7.5':
resolution: {integrity: sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g==}
'@react-three/drei@10.7.7': '@react-three/drei@10.7.7':
resolution: {integrity: sha512-ff+J5iloR0k4tC++QtD/j9u3w5fzfgFAWDtAGQah9pF2B1YgOq/5JxqY0/aVoQG5r3xSZz0cv5tk2YuBob4xEQ==} resolution: {integrity: sha512-ff+J5iloR0k4tC++QtD/j9u3w5fzfgFAWDtAGQah9pF2B1YgOq/5JxqY0/aVoQG5r3xSZz0cv5tk2YuBob4xEQ==}
peerDependencies: peerDependencies:
@@ -594,6 +630,17 @@ packages:
react-dom: react-dom:
optional: true optional: true
'@react-three/drei@9.122.0':
resolution: {integrity: sha512-SEO/F/rBCTjlLez7WAlpys+iGe9hty4rNgjZvgkQeXFSiwqD4Hbk/wNHMAbdd8vprO2Aj81mihv4dF5bC7D0CA==}
peerDependencies:
'@react-three/fiber': ^8
react: ^18
react-dom: ^18
three: '>=0.137'
peerDependenciesMeta:
react-dom:
optional: true
'@react-three/fiber@9.6.1': '@react-three/fiber@9.6.1':
resolution: {integrity: sha512-zF0rsKcVYpcJwbFEnv2HkHX9cvOEgsfQo/X8lwmR2dn13S4qEQJXir9fxf5js2LQFoXqxOY7MDkOkYx2uZ4gSg==} resolution: {integrity: sha512-zF0rsKcVYpcJwbFEnv2HkHX9cvOEgsfQo/X8lwmR2dn13S4qEQJXir9fxf5js2LQFoXqxOY7MDkOkYx2uZ4gSg==}
peerDependencies: peerDependencies:
@@ -724,6 +771,11 @@ packages:
'@rolldown/pluginutils@1.0.1': '@rolldown/pluginutils@1.0.1':
resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
'@stitches/react@1.2.8':
resolution: {integrity: sha512-9g9dWI4gsSVe8bNLlb+lMkBYsnIKCZTmvqvDG+Avnn69XfmHZKiaMrx7cgTaddq7aTPPmXiTsbFcUy0xgI4+wA==}
peerDependencies:
react: '>= 16.3.0'
'@tabler/icons-react@3.44.0': '@tabler/icons-react@3.44.0':
resolution: {integrity: sha512-8+rvzBbVm/1Z3sG3x7GUNAaxIKxwgz8xaMhRs23nrCnMTKRFAhEC+82zAIFeAA0seXdrAGX5HFCkaLpGK2rVHg==} resolution: {integrity: sha512-8+rvzBbVm/1Z3sG3x7GUNAaxIKxwgz8xaMhRs23nrCnMTKRFAhEC+82zAIFeAA0seXdrAGX5HFCkaLpGK2rVHg==}
peerDependencies: peerDependencies:
@@ -845,6 +897,14 @@ packages:
peerDependencies: peerDependencies:
react: '>= 16.8.0' react: '>= 16.8.0'
'@utsubo/events@0.1.7':
resolution: {integrity: sha512-WB/GEj/0h27Bz8rJ0+CBtNz5mLT79ne1OjB7PUM4n0qLBqEDwm6yBzZC3j6tasHjlBPJDYZiBVIA1glaMlgZ5g==}
peerDependencies:
react: '>=16.8.0'
peerDependenciesMeta:
react:
optional: true
'@vitejs/plugin-react@6.0.2': '@vitejs/plugin-react@6.0.2':
resolution: {integrity: sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==} resolution: {integrity: sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
@@ -927,6 +987,11 @@ packages:
buffer@6.0.3: buffer@6.0.3:
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
camera-controls@2.10.1:
resolution: {integrity: sha512-KnaKdcvkBJ1Irbrzl8XD6WtZltkRjp869Jx8c0ujs9K+9WD+1D7ryBsCiVqJYUqt6i/HR5FxT7RLASieUD+Q5w==}
peerDependencies:
three: '>=0.126.1'
camera-controls@3.1.2: camera-controls@3.1.2:
resolution: {integrity: sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA==} resolution: {integrity: sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA==}
engines: {node: '>=22.0.0', npm: '>=10.5.1'} engines: {node: '>=22.0.0', npm: '>=10.5.1'}
@@ -1069,6 +1134,9 @@ packages:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
eventemitter3@4.0.7:
resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
fast-decode-uri-component@1.0.1: fast-decode-uri-component@1.0.1:
resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==}
@@ -1350,6 +1418,10 @@ packages:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'} engines: {node: '>=10'}
loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
lru-cache@10.4.3: lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
@@ -1419,6 +1491,10 @@ packages:
nwsapi@2.2.23: nwsapi@2.2.23:
resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==} resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==}
object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
on-exit-leak-free@2.1.2: on-exit-leak-free@2.1.2:
resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
@@ -1483,6 +1559,9 @@ packages:
promise-worker-transferable@1.0.4: promise-worker-transferable@1.0.4:
resolution: {integrity: sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==} resolution: {integrity: sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==}
prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
punycode@2.3.1: punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'} engines: {node: '>=6'}
@@ -1490,11 +1569,35 @@ packages:
quick-format-unescaped@4.0.4: quick-format-unescaped@4.0.4:
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
r3f-perf@7.2.3:
resolution: {integrity: sha512-4+P/N/bnO9D8nzdm3suL/NjPZK/HHdjwpvajhi8j7eB41i2ECN6lX9RXiKSpHzpsDi2ui1tBj6q7/sz5opoqXw==}
peerDependencies:
'@react-three/fiber': '>=8.0'
dom: '*'
react: '>=18.0'
react-dom: '>=18.0'
three: '>=0.133'
peerDependenciesMeta:
'@react-three/fiber':
optional: true
dom:
optional: true
react-dom:
optional: true
react-composer@5.0.3:
resolution: {integrity: sha512-1uWd07EME6XZvMfapwZmc7NgCZqDemcvicRi3wMJzXsQLvZ3L7fTHVyPy1bZdnWXM4iPjYuNE+uJ41MLKeTtnA==}
peerDependencies:
react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
react-dom@19.2.6: react-dom@19.2.6:
resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==}
peerDependencies: peerDependencies:
react: ^19.2.6 react: ^19.2.6
react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
react-router-dom@7.16.0: react-router-dom@7.16.0:
resolution: {integrity: sha512-kMUAbimWB5FVbF4Bce4bJsiKJWLIUHq/mEG8+CFDnCSgltptBiG5nguducmsJeGKytlCvQud9Qhzpn49iduTlA==} resolution: {integrity: sha512-kMUAbimWB5FVbF4Bce4bJsiKJWLIUHq/mEG8+CFDnCSgltptBiG5nguducmsJeGKytlCvQud9Qhzpn49iduTlA==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
@@ -1637,6 +1740,12 @@ packages:
resolution: {integrity: sha512-e2zZ96wSChazBsbENf/Pcm/4swHt2cEKQ92rhUjkL9GCKiTDJIaTBenjE/m9DXi0QBmTMDkFDdOomUy20A1tDQ==} resolution: {integrity: sha512-e2zZ96wSChazBsbENf/Pcm/4swHt2cEKQ92rhUjkL9GCKiTDJIaTBenjE/m9DXi0QBmTMDkFDdOomUy20A1tDQ==}
engines: {node: '>=20'} engines: {node: '>=20'}
three-mesh-bvh@0.7.8:
resolution: {integrity: sha512-BGEZTOIC14U0XIRw3tO4jY7IjP7n7v24nv9JXS1CyeVRWOCkcOMhRnmENUjuV39gktAw4Ofhr0OvIAiTspQrrw==}
deprecated: Deprecated due to three.js version incompatibility. Please use v0.8.0, instead.
peerDependencies:
three: '>= 0.151.0'
three-mesh-bvh@0.8.3: three-mesh-bvh@0.8.3:
resolution: {integrity: sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==} resolution: {integrity: sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==}
peerDependencies: peerDependencies:
@@ -2292,6 +2401,43 @@ snapshots:
'@pinojs/redact@0.4.0': {} '@pinojs/redact@0.4.0': {}
'@radix-ui/react-icons@1.3.2(react@19.2.6)':
dependencies:
react: 19.2.6
'@react-spring/animated@9.7.5(react@19.2.6)':
dependencies:
'@react-spring/shared': 9.7.5(react@19.2.6)
'@react-spring/types': 9.7.5
react: 19.2.6
'@react-spring/core@9.7.5(react@19.2.6)':
dependencies:
'@react-spring/animated': 9.7.5(react@19.2.6)
'@react-spring/shared': 9.7.5(react@19.2.6)
'@react-spring/types': 9.7.5
react: 19.2.6
'@react-spring/rafz@9.7.5': {}
'@react-spring/shared@9.7.5(react@19.2.6)':
dependencies:
'@react-spring/rafz': 9.7.5
'@react-spring/types': 9.7.5
react: 19.2.6
'@react-spring/three@9.7.5(@react-three/fiber@9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0))(react@19.2.6)(three@0.184.0)':
dependencies:
'@react-spring/animated': 9.7.5(react@19.2.6)
'@react-spring/core': 9.7.5(react@19.2.6)
'@react-spring/shared': 9.7.5(react@19.2.6)
'@react-spring/types': 9.7.5
'@react-three/fiber': 9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0)
react: 19.2.6
three: 0.184.0
'@react-spring/types@9.7.5': {}
'@react-three/drei@10.7.7(@react-three/fiber@9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0))(@types/react@19.2.15)(@types/three@0.184.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0)': '@react-three/drei@10.7.7(@react-three/fiber@9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0))(@types/react@19.2.15)(@types/three@0.184.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0)':
dependencies: dependencies:
'@babel/runtime': 7.29.7 '@babel/runtime': 7.29.7
@@ -2325,6 +2471,41 @@ snapshots:
- '@types/three' - '@types/three'
- immer - immer
'@react-three/drei@9.122.0(@react-three/fiber@9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0))(@types/react@19.2.15)(@types/three@0.184.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0)(use-sync-external-store@1.6.0(react@19.2.6))':
dependencies:
'@babel/runtime': 7.29.7
'@mediapipe/tasks-vision': 0.10.17
'@monogrid/gainmap-js': 3.4.0(three@0.184.0)
'@react-spring/three': 9.7.5(@react-three/fiber@9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0))(react@19.2.6)(three@0.184.0)
'@react-three/fiber': 9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0)
'@use-gesture/react': 10.3.1(react@19.2.6)
camera-controls: 2.10.1(three@0.184.0)
cross-env: 7.0.3
detect-gpu: 5.0.70
glsl-noise: 0.0.0
hls.js: 1.6.16
maath: 0.10.8(@types/three@0.184.1)(three@0.184.0)
meshline: 3.3.1(three@0.184.0)
react: 19.2.6
react-composer: 5.0.3(react@19.2.6)
stats-gl: 2.4.2(@types/three@0.184.1)(three@0.184.0)
stats.js: 0.17.0
suspend-react: 0.1.3(react@19.2.6)
three: 0.184.0
three-mesh-bvh: 0.7.8(three@0.184.0)
three-stdlib: 2.36.1(three@0.184.0)
troika-three-text: 0.52.4(three@0.184.0)
tunnel-rat: 0.1.2(@types/react@19.2.15)(react@19.2.6)
utility-types: 3.11.0
zustand: 5.0.14(@types/react@19.2.15)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6))
optionalDependencies:
react-dom: 19.2.6(react@19.2.6)
transitivePeerDependencies:
- '@types/react'
- '@types/three'
- immer
- use-sync-external-store
'@react-three/fiber@9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0)': '@react-three/fiber@9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0)':
dependencies: dependencies:
'@babel/runtime': 7.29.7 '@babel/runtime': 7.29.7
@@ -2405,6 +2586,10 @@ snapshots:
'@rolldown/pluginutils@1.0.1': {} '@rolldown/pluginutils@1.0.1': {}
'@stitches/react@1.2.8(react@19.2.6)':
dependencies:
react: 19.2.6
'@tabler/icons-react@3.44.0(react@19.2.6)': '@tabler/icons-react@3.44.0(react@19.2.6)':
dependencies: dependencies:
'@tabler/icons': 3.44.0 '@tabler/icons': 3.44.0
@@ -2556,6 +2741,12 @@ snapshots:
'@use-gesture/core': 10.3.1 '@use-gesture/core': 10.3.1
react: 19.2.6 react: 19.2.6
'@utsubo/events@0.1.7(react@19.2.6)':
dependencies:
eventemitter3: 4.0.7
optionalDependencies:
react: 19.2.6
'@vitejs/plugin-react@6.0.2(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(sass@1.100.0)(tsx@4.22.4))': '@vitejs/plugin-react@6.0.2(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(sass@1.100.0)(tsx@4.22.4))':
dependencies: dependencies:
'@rolldown/pluginutils': 1.0.1 '@rolldown/pluginutils': 1.0.1
@@ -2632,6 +2823,10 @@ snapshots:
base64-js: 1.5.1 base64-js: 1.5.1
ieee754: 1.2.1 ieee754: 1.2.1
camera-controls@2.10.1(three@0.184.0):
dependencies:
three: 0.184.0
camera-controls@3.1.2(three@0.184.0): camera-controls@3.1.2(three@0.184.0):
dependencies: dependencies:
three: 0.184.0 three: 0.184.0
@@ -2802,6 +2997,8 @@ snapshots:
esutils@2.0.3: {} esutils@2.0.3: {}
eventemitter3@4.0.7: {}
fast-decode-uri-component@1.0.1: {} fast-decode-uri-component@1.0.1: {}
fast-deep-equal@3.1.3: {} fast-deep-equal@3.1.3: {}
@@ -3070,6 +3267,10 @@ snapshots:
dependencies: dependencies:
p-locate: 5.0.0 p-locate: 5.0.0
loose-envify@1.4.0:
dependencies:
js-tokens: 4.0.0
lru-cache@10.4.3: {} lru-cache@10.4.3: {}
lru-cache@5.1.1: lru-cache@5.1.1:
@@ -3120,6 +3321,8 @@ snapshots:
nwsapi@2.2.23: {} nwsapi@2.2.23: {}
object-assign@4.1.1: {}
on-exit-leak-free@2.1.2: {} on-exit-leak-free@2.1.2: {}
optionator@0.9.4: optionator@0.9.4:
@@ -3190,15 +3393,46 @@ snapshots:
is-promise: 2.2.2 is-promise: 2.2.2
lie: 3.3.0 lie: 3.3.0
prop-types@15.8.1:
dependencies:
loose-envify: 1.4.0
object-assign: 4.1.1
react-is: 16.13.1
punycode@2.3.1: {} punycode@2.3.1: {}
quick-format-unescaped@4.0.4: {} quick-format-unescaped@4.0.4: {}
r3f-perf@7.2.3(@react-three/fiber@9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0))(@types/react@19.2.15)(@types/three@0.184.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0)(use-sync-external-store@1.6.0(react@19.2.6)):
dependencies:
'@radix-ui/react-icons': 1.3.2(react@19.2.6)
'@react-three/drei': 9.122.0(@react-three/fiber@9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0))(@types/react@19.2.15)(@types/three@0.184.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0)(use-sync-external-store@1.6.0(react@19.2.6))
'@stitches/react': 1.2.8(react@19.2.6)
'@utsubo/events': 0.1.7(react@19.2.6)
react: 19.2.6
three: 0.184.0
zustand: 4.5.7(@types/react@19.2.15)(react@19.2.6)
optionalDependencies:
'@react-three/fiber': 9.6.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(three@0.184.0)
react-dom: 19.2.6(react@19.2.6)
transitivePeerDependencies:
- '@types/react'
- '@types/three'
- immer
- use-sync-external-store
react-composer@5.0.3(react@19.2.6):
dependencies:
prop-types: 15.8.1
react: 19.2.6
react-dom@19.2.6(react@19.2.6): react-dom@19.2.6(react@19.2.6):
dependencies: dependencies:
react: 19.2.6 react: 19.2.6
scheduler: 0.27.0 scheduler: 0.27.0
react-is@16.13.1: {}
react-router-dom@7.16.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): react-router-dom@7.16.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
dependencies: dependencies:
react: 19.2.6 react: 19.2.6
@@ -3319,6 +3553,10 @@ snapshots:
dependencies: dependencies:
real-require: 1.0.0 real-require: 1.0.0
three-mesh-bvh@0.7.8(three@0.184.0):
dependencies:
three: 0.184.0
three-mesh-bvh@0.8.3(three@0.184.0): three-mesh-bvh@0.8.3(three@0.184.0):
dependencies: dependencies:
three: 0.184.0 three: 0.184.0
+1
View File
@@ -19,6 +19,7 @@
"mobx-react-lite": "^4.1.1", "mobx-react-lite": "^4.1.1",
"mobx-utils": "^6.1.1", "mobx-utils": "^6.1.1",
"nipplejs": "^1.0.4", "nipplejs": "^1.0.4",
"r3f-perf": "^7.2.3",
"react": "^19.2.6", "react": "^19.2.6",
"react-dom": "^19.2.6", "react-dom": "^19.2.6",
"react-router-dom": "^7.16.0", "react-router-dom": "^7.16.0",
+2 -3
View File
@@ -1,6 +1,5 @@
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { SceneView } from "./SceneView"; import { SceneView } from "./SceneView";
import { DebugLabelsView } from "./DebugLabelsView";
import { state } from "../state"; import { state } from "../state";
import { useFrame } from "@react-three/fiber"; import { useFrame } from "@react-three/fiber";
import { Suspense } from "react"; import { Suspense } from "react";
@@ -18,8 +17,8 @@ export const GameView = observer(function () {
return (<> return (<>
<Suspense> <Suspense>
<Physics paused={game.isPaused} debug> <Physics paused={game.isPaused} debug={game.debugOverlay}>
<SceneView scene={game.scene} /> <SceneView scene={game.scene} debugOverlay={game.debugOverlay} />
</Physics> </Physics>
</Suspense> </Suspense>
</>); </>);
-2
View File
@@ -1,5 +1,4 @@
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { RenderInfoView } from "./RenderInfoView";
import { MenuView } from "./MenuView"; import { MenuView } from "./MenuView";
import { state } from "../state"; import { state } from "../state";
import { Panel } from "./Panel"; import { Panel } from "./Panel";
@@ -23,6 +22,5 @@ export const LeftPanel = observer(function () {
<div className="gap" /> <div className="gap" />
{/* <button onClick={handleLoadWorld}>Load</button> */} {/* <button onClick={handleLoadWorld}>Load</button> */}
<button onClick={handleLoadMockWorld}>Load mock world</button> <button onClick={handleLoadMockWorld}>Load mock world</button>
<div className="debug"><RenderInfoView /></div>
</Panel>; </Panel>;
}); });
@@ -1,30 +0,0 @@
import { useEffect, useRef } from "react";
import { observer } from "mobx-react-lite";
import { state } from "../state";
import { chartRef } from "./chartRef";
export const RenderInfoView = observer(function () {
const info = state.renderInfo;
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const el = containerRef.current;
if (!el)
return;
el.appendChild(chartRef.current);
return () => { el.removeChild(chartRef.current); };
}, []);
return <>
<div className="chart" ref={containerRef} />
{info != null && (
<div className="metrics">
<span>draw: {info.calls}</span>
<span>tri: {info.triangles}</span>
<span>shaders: {info.shaders}</span>
<span>geometries: {info.geometries}</span>
<span>textures: {info.textures}</span>
</div>
)}
</>;
});
+1 -1
View File
@@ -59,7 +59,7 @@ export const SceneEditorView = observer(function () {
infiniteGrid infiniteGrid
/> />
<Physics colliders={false} paused={true}> <Physics colliders={false} paused={true}>
<SceneView scene={state.worldEditor.scene} editMode /> <SceneView scene={state.worldEditor.scene} editMode debugOverlay />
</Physics> </Physics>
</Suspense> </Suspense>
</>); </>);
+2 -1
View File
@@ -7,6 +7,7 @@ import { DebugLabelsView } from "./DebugLabelsView";
type SceneViewProps = { type SceneViewProps = {
scene: RuntimeScene, scene: RuntimeScene,
editMode?: boolean; editMode?: boolean;
debugOverlay?: boolean;
} }
export const SceneView = observer(function (props: SceneViewProps) { export const SceneView = observer(function (props: SceneViewProps) {
@@ -20,6 +21,6 @@ export const SceneView = observer(function (props: SceneViewProps) {
: <ObjectEditorView key={obj.id} object={obj} isPlayer={props.scene.playerObjectId === obj.id} /> : <ObjectEditorView key={obj.id} object={obj} isPlayer={props.scene.playerObjectId === obj.id} />
)) ))
} }
<DebugLabelsView scene={props.scene} /> {props.debugOverlay && <DebugLabelsView scene={props.scene} />}
</>); </>);
}); });
+15 -6
View File
@@ -1,17 +1,27 @@
import { Perf } from 'r3f-perf'
import { Canvas } from '@react-three/fiber'; import { Canvas } from '@react-three/fiber';
import { KeyboardControls, Stats } from '@react-three/drei'; import { KeyboardControls } from '@react-three/drei';
import { chartRef } from './chartRef';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { state } from '../state'; import { state } from '../state';
import { GameView } from './GameView'; import { GameView } from './GameView';
import { SceneEditorView } from './SceneEditorView'; import { SceneEditorView } from './SceneEditorView';
import { JoystickView } from './JoystickView'; import { JoystickView } from './JoystickView';
import type { RefObject } from 'react'; import { useEffect } from 'react';
import { runInAction } from 'mobx';
import { IconPlayerPlayFilled, IconPlayerPauseFilled, IconPlayerStopFilled, IconPlayerSkipForwardFilled } from '@tabler/icons-react'; import { IconPlayerPlayFilled, IconPlayerPauseFilled, IconPlayerStopFilled, IconPlayerSkipForwardFilled } from '@tabler/icons-react';
import { RenderInfoUpdater } from './renderInfo';
export const ThreeView = observer(function () { export const ThreeView = observer(function () {
const isGame = !!state.game; const isGame = !!state.game;
useEffect(() => {
const onKeyDown = (e: KeyboardEvent) => {
if (e.code === 'Backquote' && state.game) {
runInAction(() => { state.game!.debugOverlay = !state.game!.debugOverlay; });
}
};
window.addEventListener('keydown', onKeyDown);
return () => window.removeEventListener('keydown', onKeyDown);
}, []);
return ( return (
<KeyboardControls map={[ <KeyboardControls map={[
{ name: 'forward', keys: ['ArrowUp', 'w', 'W'] }, { name: 'forward', keys: ['ArrowUp', 'w', 'W'] },
@@ -25,8 +35,7 @@ export const ThreeView = observer(function () {
// camera={state.world.character.camera} // camera={state.world.character.camera}
onPointerMissed={() => state.worldEditor.resetSelection()} onPointerMissed={() => state.worldEditor.resetSelection()}
> >
<Stats parent={chartRef as RefObject<HTMLElement>} /> <Perf position="bottom-right" />
<RenderInfoUpdater />
{isGame ? <GameView /> : <SceneEditorView />} {isGame ? <GameView /> : <SceneEditorView />}
</Canvas> </Canvas>
{isGame && <JoystickView />} {isGame && <JoystickView />}
-1
View File
@@ -1 +0,0 @@
export const chartRef = { current: document.createElement('span') };
-20
View File
@@ -1,20 +0,0 @@
import { useFrame, useThree } from "@react-three/fiber";
import { state } from "../state";
import { action } from "mobx";
export function RenderInfoUpdater() {
const { gl } = useThree();
useFrame(action(() => {
const { calls, triangles } = gl.info.render;
const shaders = gl.info.programs?.length ?? 0;
const { geometries, textures } = gl.info.memory;
state.setRenderInfo({
calls,
triangles,
shaders,
geometries,
textures,
});
}));
return null;
}
+1
View File
@@ -10,6 +10,7 @@ export class GameState {
private readonly world: WorldState; private readonly world: WorldState;
public isPaused: boolean = false; public isPaused: boolean = false;
public debugOverlay: boolean = false;
public time: number = 0; public time: number = 0;
public isFirstTick: boolean; public isFirstTick: boolean;
public scene: RuntimeGameScene; public scene: RuntimeGameScene;