diff --git a/.vscode/settings.json b/.vscode/settings.json index fed3f7c40..004e622e0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -79,6 +79,7 @@ "SKLLD", "Smri", "Specularity", + "SSAO", "startcase", "statsfull", "steamapps", diff --git a/package.json b/package.json index cf50b27cf..3b9378a4d 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@radix-ui/themes": "^2.0.1", "@react-three/drei": "^9.90.1", "@react-three/fiber": "^8.15.12", + "@react-three/postprocessing": "^2.15.11", "@resvg/resvg-js": "^2.4.1", "@vanilla-extract/css": "^1.13.0", "bepaint": "^0.1.0-beta.3", @@ -54,6 +55,7 @@ "markdown-escape": "^2.0.0", "next": "^14.0.3", "parse-dds": "^1.2.1", + "postprocessing": "^6.34.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-fuzzysort": "^1.0.1", diff --git a/public/test/5137.glb b/public/test/5137.glb new file mode 100644 index 000000000..f201c44c0 Binary files /dev/null and b/public/test/5137.glb differ diff --git a/scripts/buildAssets.ts b/scripts/buildAssets.ts index 32351d782..6372e1245 100644 --- a/scripts/buildAssets.ts +++ b/scripts/buildAssets.ts @@ -520,9 +520,9 @@ if (allTargets || targets?.includes('tankModels')) { // if (id !== 24609) continue; // concept 1b // if (id !== 4417) continue; // amx m4 mle // if (id !== 7297) continue; // 60tp - if (id !== 1) continue; // t-34 + // if (id !== 1) continue; // t-34 // if (id !== 6753) continue; // type 71 - // if (id !== 5137) continue; // tiger ii + if (id !== 5137) continue; // tiger ii // if (id !== 6225) continue; // fv215b console.log(`Building model ${id} @ ${nation}/${tankIndex}`); @@ -536,10 +536,7 @@ if (allTargets || targets?.includes('tankModels')) { baseColor, ); - writeFile( - `dist/assets/models/${id}.glb`, - await nodeIO.writeBinary(model), - ); + writeFile(`public/test/${id}.glb`, await nodeIO.writeBinary(model)); // await mkdir(`dist/assets/models/${id}`, { recursive: true }); // nodeIO.write(`dist/assets/models/${id}/index.gltf`, model); } diff --git a/src/app/tools/tankopedia/[id]/components/tankAlignment.ts b/src/app/tools/tankopedia/[id]/components/tankAlignment.ts new file mode 100644 index 000000000..3157d256b --- /dev/null +++ b/src/app/tools/tankopedia/[id]/components/tankAlignment.ts @@ -0,0 +1,22 @@ +import { useThree } from '@react-three/fiber'; +import { RefObject, useEffect } from 'react'; +import { Box3, Group } from 'three'; + +interface TankAlignmentProps { + model: RefObject; +} + +export function TankAlignment({ model }: TankAlignmentProps) { + const camera = useThree((state) => state.camera); + + useEffect(() => { + const box = new Box3().setFromObject(model.current!); + const diameter = Math.max(box.max.x - box.min.x, box.max.z - box.min.z); + const radius = diameter / 2; + + model.current?.position.set(0, -(box.min.y + box.max.y) / 2, 0); + // camera.position.set(radius * -0.25, radius * 0.1, radius * -1.5); + }, []); + + return null; +} diff --git a/src/app/tools/tankopedia/[id]/page.tsx b/src/app/tools/tankopedia/[id]/page.tsx index 68c0cab7b..68c295e33 100644 --- a/src/app/tools/tankopedia/[id]/page.tsx +++ b/src/app/tools/tankopedia/[id]/page.tsx @@ -5,6 +5,7 @@ import { CaretRightIcon, MagnifyingGlassIcon, } from '@radix-ui/react-icons'; + import { Button, Card, @@ -19,66 +20,59 @@ import { Theme, Tooltip, } from '@radix-ui/themes'; -import { OrbitControls } from '@react-three/drei'; -import { Canvas } from '@react-three/fiber'; +import { Environment, OrbitControls } from '@react-three/drei'; +import { Canvas, useLoader } from '@react-three/fiber'; import { go } from 'fuzzysort'; import { debounce } from 'lodash'; import Link from 'next/link'; import { use, useEffect, useRef, useState } from 'react'; +import { Group } from 'three'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; import { Flag } from '../../../../components/Flag'; import { ModuleButtons } from '../../../../components/ModuleButton'; import PageWrapper from '../../../../components/PageWrapper'; import { asset } from '../../../../core/blitzkrieg/asset'; -import { gunDefinitions } from '../../../../core/blitzkrieg/definitions/guns'; -import { shellDefinitions } from '../../../../core/blitzkrieg/definitions/shells'; -import { turretDefinitions } from '../../../../core/blitzkrieg/definitions/turrets'; import { TIER_ROMAN_NUMERALS, tankDefinitions, tankNamesDiacritics, } from '../../../../core/blitzkrieg/tankDefinitions'; import * as styles from '../page.css'; +import { TankAlignment } from './components/tankAlignment'; export default function Page({ params }: { params: { id: string } }) { const id = parseInt(params.id); const awaitedTankDefinitions = use(tankDefinitions); - const awaitedTurretDefinitions = use(turretDefinitions); - const awaitedGunDefinitions = use(gunDefinitions); - const awaitedShellDefinitions = use(shellDefinitions); const awaitedTankNamesDiacritics = use(tankNamesDiacritics); const tank = awaitedTankDefinitions[id]; - const [turret, setTurret] = useState( - awaitedTurretDefinitions[tank.turrets.at(-1)!], - ); - const [gun, setGun] = useState(awaitedGunDefinitions[turret.guns.at(-1)!]); + const [turret, setTurret] = useState(tank.turrets.at(-1)!); + const [gun, setGun] = useState(turret.guns.at(-1)!); const [crew, setCrew] = useState(100); const [mode, setMode] = useState('model'); const versusTankSearchInput = useRef(null); + const model = useRef(null); const [versusTankSearchResults, setVersusTankSearchResults] = useState< number[] >([]); const [versusTank, setVersusTank] = useState(tank); - const [versusTurret, setVersusTurret] = useState( - awaitedTurretDefinitions[versusTank.turrets.at(-1)!], - ); - const [versusGun, setVersusGun] = useState( - awaitedGunDefinitions[versusTurret.guns.at(-1)!], - ); + const [versusTurret, setVersusTurret] = useState(versusTank.turrets.at(-1)!); + const [versusGun, setVersusGun] = useState(versusTurret.guns.at(-1)!); const [versusTankTab, setVersusTankTab] = useState('search'); + const gltf = useLoader(GLTFLoader, '/test/5137.glb'); useEffect(() => { - if (!turret.guns.includes(gun.id)) { - setGun(awaitedGunDefinitions[turret.guns.at(-1)!]); + if (!turret.guns.some(({ id }) => gun.id === id)) { + setGun(turret.guns.at(-1)!); } }, [turret]); useEffect(() => { - if (!versusTank.turrets.includes(versusTurret.id)) { - setVersusTurret(awaitedTurretDefinitions[versusTank.turrets.at(-1)!]); + if (!versusTank.turrets.some(({ id }) => id === versusTurret.id)) { + setVersusTurret(versusTank.turrets.at(-1)!); } }, [versusTank]); useEffect(() => { - if (!versusTurret.guns.includes(versusGun.id)) { - setVersusGun(awaitedGunDefinitions[versusTurret.guns.at(-1)!]); + if (!versusTurret.guns.some(({ id }) => id === versusGun.id)) { + setVersusGun(versusTurret.guns.at(-1)!); } }, [versusTurret]); @@ -113,16 +107,19 @@ export default function Page({ params }: { params: { id: string } }) {
- event.preventDefault()}> + event.preventDefault()} + camera={{ fov: 20, position: [4, 0, -16] }} + > + - - + {/* I really like apartment, dawn, and sunset */} + - - - - + + +
@@ -236,23 +233,15 @@ export default function Page({ params }: { params: { id: string } }) { - {versusTank.turrets.map((id, index) => ( - + {versusTank.turrets.map((turret, index) => ( + - setVersusTurret( - awaitedTurretDefinitions[id], - ) + setVersusTurret(turret) } selected={versusTurret.id === id} - tier={ - awaitedTurretDefinitions[id].tier - } + tier={turret.tier} type="turret" style={{ margin: -0.5, @@ -276,19 +265,13 @@ export default function Page({ params }: { params: { id: string } }) { ))} - {versusTurret.guns.map((id, index) => ( - + {versusTurret.guns.map((gun, index) => ( + - setVersusGun( - awaitedGunDefinitions[id], - ) - } + onClick={() => setVersusGun(gun)} selected={versusGun.id === id} - tier={awaitedGunDefinitions[id].tier} + tier={gun.tier} type="gun" style={{ margin: -0.5, @@ -376,9 +359,7 @@ export default function Page({ params }: { params: { id: string } }) { - {tank.turrets.map((turretId) => { - const thisTurret = awaitedTurretDefinitions[turretId]; - + {tank.turrets.map((thisTurret) => { return (