From d543e422686a3ca51905c9f3c549c64639547e7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Tue, 2 Jan 2024 14:50:46 -0600 Subject: [PATCH] feat: gun limits --- public/test/11633.glb | Bin 18799804 -> 18799804 bytes scripts/buildAssets.ts | 2 +- src/app/tools/tankopedia/[id]/page.tsx | 93 +++++++++++++++++-------- src/core/blitz/extractModel.ts | 10 +-- src/core/streams/sc2.ts | 32 +++++++++ 5 files changed, 103 insertions(+), 34 deletions(-) diff --git a/public/test/11633.glb b/public/test/11633.glb index 379cca1bae95441a19365499366688293caa2a81..b408aa2ae9f8e68170b9bbe758081938e9ce707f 100644 GIT binary patch delta 1299 zcmWmAcU;VI0LJmx(9W8K3VT@6YS``^nF%Fv&+w3$+xbc2zVBXs%KPNFHi0DOqhTm8#v0{rm$}Dk(+n zm0PKfHka}=?ozhKT*}ZmNRjL^%||I!8!Gda7KaDPR8q1wOj@b6kfd;*c!O4F(8^$h zDv-k%3RHy&OkoCdSfCm#Q5`i<6SZIkYuLaRcCd#79N`3KxIl^8sDrw2g&XRjJ{rIs z4bcdV(F7i73Qu^!8$M_TU#Q@R=I}=V0?`635rkG~jW!5ITeL%agrEaL(Gi`{8C}p7 z-JnKy^gvI9p%;3i5Bj1X`eOhz2#5H3AO;}1g-F06=&%?|uoQ_{hUHj+B&(+D z12!TRX-LN=WMDJ4U@NvE6Wfu69oUIo*o{5di)`#e4))^!a&Zuca2R?VK^~6c81hko z<0!-loWv=dMiI{7EY9IPE}$3}aS4}k1y^wm*Kq?kaSOLmf;+g2dnmBA!f#Zd5`XX){}M}-vLuKY ziBu7hix`V2M5>CIh?t6)iI|I6h*T4?6say!L!_oiEfFgbYY`g}TM;`Edl3f_M-e9x PXAu`!VTn>HD=+vD#P)(H delta 1314 zcmYk&cUTN?9LMqJ>PnMT8ssP=Bkhw2A=}yOTK1-4%gnlL`B7HcvR61!GR`LZjEtO> zoxR8V_n$vr@8|n`{`}_V{Itr&p86V*pz*W}3e}xc~pQ0Dnf-ys0>edp$e*^ z8mhw^HBb|^P#Zp|17G;T9{~tN5Q3pbU4)<>LQx+L5Qc_mgvJO*6EsCLM4&lZpe0(N zHQJyp+ChW%=zxysgwE)KuIPsD=z*TlA`yL`>PF-=RzXk(M5t zk>smW#!tmGy)r&I$t^vzAm3kSR87YW%)~6rh7Kv1gSnW8`B;F3ScJt$#S#cC#WJKJ z9m}x-E3pczk%3IC!CI`tdThW(Y{F(_VGFim8@6Kyc48NHV-NOXAF{C@2XGL296}Bb z;|Ow*hoi{HF&xJUoP+_Va2jWD7Uyst7jO}mP=L$0f~&ZO>$riNFya<&;|}hk5chB& z5AYC0cmxw3;|ZSP8J?pUFYpqt@EULM7Vl7k_xOO1_=L~+g0J|7@A!eA_=Vs2gTM2P zD#aqmn8}#SC}k{UEM-c`Sjkw+*vQz**vZ(-l$I$Y;~-O3#!<#e##yGEjEjt`jGK(R UOnI3KG9EG&75PS$O7Sf3AO8!8CIA2c diff --git a/scripts/buildAssets.ts b/scripts/buildAssets.ts index 5f918f1a1..0a6d69627 100644 --- a/scripts/buildAssets.ts +++ b/scripts/buildAssets.ts @@ -533,7 +533,7 @@ if (allTargets || targets?.includes('tankModels')) { // if (id !== 1) continue; // t-34 // if (id !== 6753) continue; // type 71 // if (id !== 5137) continue; // tiger ii - if (id !== 11633) continue; // tiger ii + if (id !== 11633) continue; // forest witch // if (id !== 6225) continue; // fv215b console.log(`Building model ${id} @ ${nation}/${tankIndex}`); diff --git a/src/app/tools/tankopedia/[id]/page.tsx b/src/app/tools/tankopedia/[id]/page.tsx index 2db1e28d5..b3c865b6e 100644 --- a/src/app/tools/tankopedia/[id]/page.tsx +++ b/src/app/tools/tankopedia/[id]/page.tsx @@ -21,7 +21,7 @@ import { } from '@radix-ui/themes'; import { Canvas, ThreeEvent, useLoader } from '@react-three/fiber'; import { go } from 'fuzzysort'; -import { debounce } from 'lodash'; +import { clamp, debounce } from 'lodash'; import Link from 'next/link'; import { use, useEffect, useRef, useState } from 'react'; import { Color, Group, Mesh, Vector3 } from 'three'; @@ -67,9 +67,14 @@ export default function Page({ params }: { params: { id: string } }) { tank.turretOrigin[1], -tank.turretOrigin[2], ).applyAxisAngle(new Vector3(1, 0, 0), Math.PI / 2); - const gunOrigin = new Vector3(...turret.gunOrigin); - const [turretRotation, setTurretRotation] = useState(0); - const [hullRotation, setHullRotation] = useState(0); + const gunOrigin = new Vector3( + turret.gunOrigin[0], + turret.gunOrigin[1], + -turret.gunOrigin[2], + ).applyAxisAngle(new Vector3(1, 0, 0), Math.PI / 2); + const [turretYaw, setTurretYaw] = useState(0); + const [hullYaw, setHullYaw] = useState(0); + const [mantletPitch, setMantletPitch] = useState(0); const [orbitControlsEnabled, setOrbitControlsEnabled] = useState(true); const turretRotationInput = useRef(null); const hullRotationInput = useRef(null); @@ -93,14 +98,19 @@ export default function Page({ params }: { params: { id: string } }) { }, [versusTurret]); useEffect(() => { turretRotationInput.current!.value = `${Math.round( - turretRotation * (180 / Math.PI), + turretYaw * (180 / Math.PI), )}`; - }, [turretRotation]); + }, [turretYaw]); useEffect(() => { hullRotationInput.current!.value = `${Math.round( - hullRotation * (180 / Math.PI), + hullYaw * (180 / Math.PI), )}`; - }); + }, [hullYaw]); + useEffect(() => { + gunRotationInput.current!.value = `${Math.round( + mantletPitch * (180 / Math.PI), + )}`; + }, [mantletPitch]); return ( @@ -173,7 +183,7 @@ export default function Page({ params }: { params: { id: string } }) { {gltf.scene.children[0].children.map((child) => { const isHull = child.name === 'hull'; @@ -188,7 +198,7 @@ export default function Page({ params }: { params: { id: string } }) { if (isHull) { event.stopPropagation(); - draftTurretRotation = hullRotation; + draftTurretRotation = hullYaw; setOrbitControlsEnabled(false); window.addEventListener( @@ -214,7 +224,7 @@ export default function Page({ params }: { params: { id: string } }) { } function handlePointerUp(event: PointerEvent) { setOrbitControlsEnabled(true); - setHullRotation(normalizeAngle180(draftTurretRotation)); + setHullYaw(normalizeAngle180(draftTurretRotation)); window.removeEventListener( 'pointermove', @@ -246,9 +256,9 @@ export default function Page({ params }: { params: { id: string } }) { {gltf.scene.children[0].children.map((child) => { @@ -270,7 +280,7 @@ export default function Page({ params }: { params: { id: string } }) { if (isTurret) { event.stopPropagation(); - draftTurretRotation = turretRotation; + draftTurretRotation = turretYaw; setOrbitControlsEnabled(false); window.addEventListener( @@ -303,9 +313,7 @@ export default function Page({ params }: { params: { id: string } }) { } function handlePointerUp(event: PointerEvent) { setOrbitControlsEnabled(true); - setTurretRotation( - normalizeAngle180(draftTurretRotation), - ); + setTurretYaw(normalizeAngle180(draftTurretRotation)); window.removeEventListener( 'pointermove', @@ -335,11 +343,13 @@ export default function Page({ params }: { params: { id: string } }) { })} {gltf.scene.children[0].children.map((child) => { @@ -365,7 +375,7 @@ export default function Page({ params }: { params: { id: string } }) { ) { event.stopPropagation(); - draftMantletPitch = turretRotation; + draftMantletPitch = mantletPitch; setOrbitControlsEnabled(false); window.addEventListener( @@ -385,11 +395,22 @@ export default function Page({ params }: { params: { id: string } }) { (2 * Math.PI) / canvas.current!.width; const delta = -event.movementY * rotationSpeed; draftMantletPitch += delta; + draftMantletPitch = clamp( + draftMantletPitch, + -gun.pitch[1] * (Math.PI / 180), + -gun.pitch[0] * (Math.PI / 180), + ); if (mantletContainer.current) { mantletContainer.current.position + .set(0, 0, 0) + .sub(turretOrigin) .sub(gunOrigin) - .applyAxisAngle(new Vector3(1, 0, 0), delta) + .applyAxisAngle( + new Vector3(1, 0, 0), + draftMantletPitch, + ) + .add(turretOrigin) .add(gunOrigin); mantletContainer.current.rotation.x = draftMantletPitch; @@ -397,7 +418,7 @@ export default function Page({ params }: { params: { id: string } }) { } function handlePointerUp(event: PointerEvent) { setOrbitControlsEnabled(true); - setTurretRotation( + setMantletPitch( normalizeAngle180(draftMantletPitch), ); @@ -458,7 +479,7 @@ export default function Page({ params }: { params: { id: string } }) { Hull { - setHullRotation( + setHullYaw( normalizeAngle180( Number(hullRotationInput.current?.value) * (Math.PI / 180), @@ -485,7 +506,7 @@ export default function Page({ params }: { params: { id: string } }) { Turret { - setTurretRotation( + setTurretYaw( normalizeAngle180( Number(turretRotationInput.current?.value) * (Math.PI / 180), @@ -511,8 +532,24 @@ export default function Page({ params }: { params: { id: string } }) { > Gun { + setMantletPitch( + clamp( + normalizeAngle180( + Number(gunRotationInput.current?.value) * + (Math.PI / 180), + ), + -gun.pitch[1] * (Math.PI / 180), + -gun.pitch[0] * (Math.PI / 180), + ), + ); + }} + onKeyDown={(event) => { + if (event.key === 'Enter') { + gunRotationInput.current?.blur(); + } + }} ref={gunRotationInput} - value={0} style={{ textAlign: 'right' }} /> ° diff --git a/src/core/blitz/extractModel.ts b/src/core/blitz/extractModel.ts index 6931e4521..6320c0ef1 100644 --- a/src/core/blitz/extractModel.ts +++ b/src/core/blitz/extractModel.ts @@ -14,9 +14,9 @@ import { ScgStream, vertexAttributeVectorSizes } from '../streams/scg'; import { VertexAttribute } from '../streams/scpg'; import { readDVPLFile } from './readDVPLFile'; -BigInt.prototype.toJSON = function () { - return this.toString(); -}; +// BigInt.prototype.toJSON = function () { +// return this.toString(); +// }; const MAX_FLOAT32 = 2 ** 127 * (2 - 2 ** -23); @@ -175,11 +175,11 @@ export async function extractModel( case 'ActionComponent': case 'ParticleEffectComponent': case 'SlotComponent': + case 'MotionComponent': case 'TankElementComponent': + case 'SkeletonComponent': break; - // console.log(JSON.stringify(component, null, 2)); - case 'TransformComponent': { const translation = new Vector3(); const rotation = new Quaternion(); diff --git a/src/core/streams/sc2.ts b/src/core/streams/sc2.ts index 64b69d783..8567f6f21 100644 --- a/src/core/streams/sc2.ts +++ b/src/core/streams/sc2.ts @@ -232,6 +232,38 @@ export type Component = isDestructible: boolean; shouldCastShadow: boolean; shouldGenerateSilhouette: boolean; + } + | { + 'comp.typename': 'MotionComponent'; + 'motion.filepath': string; + 'motion.playbackRate': number; + 'simpleMotion.repeatsCount': number; + } + | { + 'comp.typename': 'SkeletonComponent'; + joints: Record< + string, // 0000, 0001, ... + { + 'joint.bbox.max': Vector3Tuple; + 'joint.bbox.min': Vector3Tuple; + 'joint.bindPose': [ + Vector4Tuple, + Vector4Tuple, + Vector4Tuple, + Vector4Tuple, + ]; + 'joint.invBindPose': [ + Vector4Tuple, + Vector4Tuple, + Vector4Tuple, + Vector4Tuple, + ]; + 'joint.name': string; + 'joint.parentIndex': number; + 'joint.uid': string; + } + >; + jointsCount: number; }; interface SceneComponents {