feat: models

This commit is contained in:
TrèsAbhi committed 2023-12-31 20:47:21 -06:00
1 parent 28dde23115
commit 8b10f2cc4a
7 files changed
+122 -76

No files matched your search

+1
View File
@@ -79,6 +79,7 @@
"SKLLD",
"Smri",
"Specularity",
"SSAO",
"startcase",
"statsfull",
"steamapps",
+2
View File
@@ -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",
Binary file not shown.
+3 -6
View File
@@ -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);
}
@@ -0,0 +1,22 @@
import { useThree } from '@react-three/fiber';
import { RefObject, useEffect } from 'react';
import { Box3, Group } from 'three';
interface TankAlignmentProps {
model: RefObject<Group>;
}
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;
}
+43 -68
View File
@@ -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<HTMLInputElement>(null);
const model = useRef<Group>(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 } }) {
</Tabs.Root>
<div style={{ height: '50vh', maxHeight: 576 }}>
<Canvas onPointerDown={(event) => event.preventDefault()}>
<Canvas
onPointerDown={(event) => event.preventDefault()}
camera={{ fov: 20, position: [4, 0, -16] }}
>
<TankAlignment model={model} />
<OrbitControls />
<ambientLight />
<directionalLight />
{/* I really like apartment, dawn, and sunset */}
<Environment preset="apartment" />
<mesh>
<torusKnotGeometry args={[undefined, undefined, 128, 16]} />
<meshStandardMaterial color="cyan" />
</mesh>
<group ref={model}>
<primitive object={gltf.scene} />
</group>
</Canvas>
</div>
@@ -236,23 +233,15 @@ export default function Page({ params }: { params: { id: string } }) {
<Flex gap="2" wrap="wrap">
<Flex>
{versusTank.turrets.map((id, index) => (
<Tooltip
content={
awaitedTurretDefinitions[id].name
}
>
{versusTank.turrets.map((turret, index) => (
<Tooltip content={turret.name}>
<ModuleButtons
key={id}
onClick={() =>
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 } }) {
))}
</Flex>
<Flex>
{versusTurret.guns.map((id, index) => (
<Tooltip
content={awaitedGunDefinitions[id].name}
>
{versusTurret.guns.map((gun, index) => (
<Tooltip content={gun.name}>
<ModuleButtons
key={id}
onClick={() =>
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 } }) {
<Theme radius="small">
<Flex gap="4">
<Flex gap="1">
{tank.turrets.map((turretId) => {
const thisTurret = awaitedTurretDefinitions[turretId];
{tank.turrets.map((thisTurret) => {
return (
<Tooltip content={thisTurret.name}>
<Button
@@ -400,9 +381,7 @@ export default function Page({ params }: { params: { id: string } }) {
</Flex>
<Flex gap="1">
{turret.guns.map((gunId, index) => {
const thisGun = awaitedGunDefinitions[gunId];
{turret.guns.map((thisGun, index) => {
return (
<Tooltip content={thisGun.name}>
<Button
@@ -446,15 +425,11 @@ export default function Page({ params }: { params: { id: string } }) {
<Flex gap="2" direction="column">
<Heading size="5">Shells</Heading>
{gun.shells.map((shellId) => {
const shell = awaitedShellDefinitions[shellId];
return (
<Text>
{shell.name} ({shell.type}): {shell.damage.armor}
</Text>
);
})}
{gun.shells.map((shell) => (
<Text>
{shell.name} ({shell.type}): {shell.damage.armor}
</Text>
))}
</Flex>
</Flex>
</PageWrapper>
+51 -2
View File
@@ -2054,6 +2054,17 @@
suspend-react "^0.1.3"
zustand "^3.7.1"
"@react-three/postprocessing@^2.15.11":
version "2.15.11"
resolved "https://registry.yarnpkg.com/@react-three/postprocessing/-/postprocessing-2.15.11.tgz#d07069eabe5da67c31f56ca7f4fbef71dcca817b"
integrity sha512-XQJxhk/hsbzUCLagd8V4pg28iy+UMkYeFFL7BOdlSM1TgAorNzMim+Wu5zI6fbAaGMpmwk7PCbOZN5YPgD0BRQ==
dependencies:
buffer "^6.0.3"
maath "^0.6.0"
n8ao "^1.6.6"
postprocessing "^6.32.1"
three-stdlib "^2.23.4"
"@resvg/[email protected]":
version "2.6.0"
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-android-arm-eabi/-/resvg-js-android-arm-eabi-2.6.0.tgz#fed7723ed5c5f7490762e025ad704bcbceee37b7"
@@ -3198,6 +3209,14 @@ core-util-is@~1.0.0:
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
cors@^2.8.5:
version "2.8.5"
resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
dependencies:
object-assign "^4"
vary "^1"
crc@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/crc/-/crc-4.3.2.tgz#49b7821cbf2cf61dfd079ed93863bbebd5469b9a"
@@ -4477,6 +4496,11 @@ lz4@^0.6.5:
nan "^2.13.2"
xxhashjs "^0.2.2"
maath@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/maath/-/maath-0.6.0.tgz#7841d0fb95bbb37d19b08b7c5458ef70190950d2"
integrity sha512-dSb2xQuP7vDnaYqfoKzlApeRcR2xtN8/f7WV/TMAkBC8552TwTLtOO0JTcSygkYMjNDPoo6V01jTw/aPi4JrMw==
maath@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/maath/-/maath-0.9.0.tgz#425a9600dfc5d0aecfa48029a2e3eea852531b06"
@@ -4723,6 +4747,14 @@ [email protected]:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
n8ao@^1.6.6:
version "1.7.3"
resolved "https://registry.yarnpkg.com/n8ao/-/n8ao-1.7.3.tgz#dada1ac33248b45d20db65acb2767de2d17da62d"
integrity sha512-4eq0ZW+hKCDaCmkXIl7qqui7L2YSQyINvXeqqnXYXrXQ56Zbc59FADhwj59q+4zyG93ccGrmIq97x3WmQ8GBbA==
dependencies:
cors "^2.8.5"
express "^4.18.2"
nan@^2.13.2:
version "2.18.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554"
@@ -4833,7 +4865,7 @@ npm-pick-manifest@^9.0.0:
npm-package-arg "^11.0.0"
semver "^7.3.5"
object-assign@^4.0.1, object-assign@^4.1.1:
object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
@@ -5072,6 +5104,11 @@ postcss@^8.4.27, postcss@^8.4.32:
picocolors "^1.0.0"
source-map-js "^1.0.2"
postprocessing@^6.32.1, postprocessing@^6.34.1:
version "6.34.1"
resolved "https://registry.yarnpkg.com/postprocessing/-/postprocessing-6.34.1.tgz#bdbff8def3301e861f0d45a39a188f3cafa7f252"
integrity sha512-xae6A2XNs61V3ohGHR+i9sQDvB4dWaoG/AICw0hg8sOYQWAYDlf+esWMRmO4hixMaYo3AJBJ9WAA7JF7OiGakw==
potpack@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/potpack/-/potpack-1.0.2.tgz#23b99e64eb74f5741ffe7656b5b5c4ddce8dfc14"
@@ -5794,6 +5831,18 @@ three-mesh-bvh@^0.6.7:
resolved "https://registry.yarnpkg.com/three-mesh-bvh/-/three-mesh-bvh-0.6.8.tgz#f27d18ca75bdc59316dff0f561af8fb316621a54"
integrity sha512-EGebF9DZx1S8+7OZYNNTT80GXJZVf+UYXD/HyTg/e2kR/ApofIFfUS4ZzIHNnUVIadpnLSzM4n96wX+l7GMbnQ==
three-stdlib@^2.23.4:
version "2.28.11"
resolved "https://registry.yarnpkg.com/three-stdlib/-/three-stdlib-2.28.11.tgz#3cfb15563a228598d0d608630711640b7b7b499c"
integrity sha512-2zo5+N2pe91Y88F+pTDTgQYNnV7pTixF93GQis2TS/fGeOf2Qlw0aKhJbzvSq7w8YkhpKL8f1v3L95JImxCltQ==
dependencies:
"@types/draco3d" "^1.4.0"
"@types/offscreencanvas" "^2019.6.4"
"@types/webxr" "^0.5.2"
draco3d "^1.4.1"
fflate "^0.6.9"
potpack "^1.0.1"
three-stdlib@^2.28.0:
version "2.28.7"
resolved "https://registry.yarnpkg.com/three-stdlib/-/three-stdlib-2.28.7.tgz#677ad2ce4d57375f7582e5fd62eadfd07ef6059a"
@@ -6097,7 +6146,7 @@ validate-npm-package-name@^5.0.0:
dependencies:
builtins "^5.0.0"
vary@~1.1.2:
vary@^1, vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==