From c16ccc4b4cb73f4bb70061b6c3d300f833e9948a Mon Sep 17 00:00:00 2001 From: tresabhi <43380238+tresabhi@users.noreply.github.com> Date: Fri, 12 Jun 2026 19:45:37 -0500 Subject: [PATCH] proper grouping --- packages/game/Models/MonoGltf.cs | 11 +++- .../components/TankopediaSandbox/index.tsx | 55 +++++++------------ .../src/hooks/useTankChassisModel.ts | 25 +++++++++ .../website-ue/src/hooks/useTankHullModel.ts | 7 +++ packages/website-ue/src/hooks/useTankModel.ts | 27 +++++++++ 5 files changed, 87 insertions(+), 38 deletions(-) create mode 100644 packages/website-ue/src/hooks/useTankChassisModel.ts create mode 100644 packages/website-ue/src/hooks/useTankHullModel.ts create mode 100644 packages/website-ue/src/hooks/useTankModel.ts diff --git a/packages/game/Models/MonoGltf.cs b/packages/game/Models/MonoGltf.cs index db0966c14..b2afac2f7 100644 --- a/packages/game/Models/MonoGltf.cs +++ b/packages/game/Models/MonoGltf.cs @@ -11,6 +11,7 @@ using CUE4Parse.UE4.Assets.Exports.SkeletalMesh; using CUE4Parse.UE4.Assets.Exports.StaticMesh; using CUE4Parse.UE4.Objects.Core.Math; using CUE4Parse.UE4.Objects.Meshes; +using Org.BouncyCastle.Crypto.Engines; using SharpGLTF.Geometry; using SharpGLTF.Geometry.VertexTypes; using SharpGLTF.Materials; @@ -56,10 +57,13 @@ public class MonoGltf var lod0 = convertedStaticMesh.LODs.Find(lod => !lod.SkipLod)!; + var i = 0; foreach (var section in lod0.Sections!.Value) { var configured = ParseSection(section, materialMap, lod0, lod0.Verts!); - scene.AddRigidMesh(configured, group); + var node = group.CreateNode($"{i++}"); + + scene.AddRigidMesh(configured, node); } } else if (mesh is USkeletalMesh skeletalMesh) @@ -68,10 +72,13 @@ public class MonoGltf var lod0 = convertedSkeletalMesh.LODs.Find(lod => !lod.SkipLod)!; + var i = 0; foreach (var section in lod0.Sections!.Value) { var configured = ParseSection(section, materialMap, lod0, lod0.Verts!); - scene.AddRigidMesh(configured, group); + var node = group.CreateNode($"{i++}"); + + scene.AddRigidMesh(configured, node); } } else diff --git a/packages/website-ue/src/components/TankopediaSandbox/index.tsx b/packages/website-ue/src/components/TankopediaSandbox/index.tsx index ef757a8c2..1384cbbce 100644 --- a/packages/website-ue/src/components/TankopediaSandbox/index.tsx +++ b/packages/website-ue/src/components/TankopediaSandbox/index.tsx @@ -3,10 +3,11 @@ import { type StageParameters, } from "@protos/blitz_static_tank_upgrade_single_stage"; import { OrbitControls } from "@react-three/drei"; -import { Canvas, useLoader } from "@react-three/fiber"; -import { Mesh, MeshStandardMaterial } from "three"; -import { GLTFLoader } from "three-stdlib"; +import { Canvas } from "@react-three/fiber"; import { useProtagonist } from "../../hooks/useProtagonist"; +import { useTankChassisModel } from "../../hooks/useTankChassisModel"; +import { useTankHullModel } from "../../hooks/useTankHullModel"; +import { useTankModel } from "../../hooks/useTankModel"; import styles from "./index.module.css"; interface TankopediaSandboxProps { @@ -40,50 +41,26 @@ function Content({ parameters }: TankopediaSandboxProps) { ({ tank_part }) => tank_part === VisualChanges_TankPart.TANK_PART_GUN, )!.name; - const hull = useLoader(GLTFLoader, `/models/tanks/${tank.id}/hull.glb`); - const chassis = useLoader(GLTFLoader, `/models/tanks/${tank.id}/chassis.glb`); + const collision = false; - console.log(chassis); - - const turret = useLoader( - GLTFLoader, - `/models/tanks/${tank.id}/${selectedTurret}.glb`, - ); - const gun = useLoader( - GLTFLoader, - `/models/tanks/${tank.id}/${selectedGun}.glb`, - ); - - const gltfs = [turret, gun, hull, chassis]; - - for (const gltf of gltfs) { - gltf.scene.traverse((child) => { - if ( - child instanceof Mesh && - child.material instanceof MeshStandardMaterial - ) { - // TODO: remove this hack and fix the gltf - child.material.vertexColors = false; - } - - child.castShadow = true; - child.receiveShadow = true; - }); - } + const hull = useTankHullModel(); + const chassis = useTankChassisModel(); + const turret = useTankModel(`/models/tanks/${tank.id}/${selectedTurret}.glb`); + const gun = useTankModel(`/models/tanks/${tank.id}/${selectedGun}.glb`); return ( <> - - + + - + - + + diff --git a/packages/website-ue/src/hooks/useTankChassisModel.ts b/packages/website-ue/src/hooks/useTankChassisModel.ts new file mode 100644 index 000000000..62f66c08a --- /dev/null +++ b/packages/website-ue/src/hooks/useTankChassisModel.ts @@ -0,0 +1,25 @@ +import { Tankopedia } from "../stores/tankopedia"; +import { useProtagonist } from "./useProtagonist"; +import { useTankModel } from "./useTankModel"; + +export function useTankChassisModel() { + const tank = useProtagonist(); + const scene = useTankModel(`/models/tanks/${tank.id}/chassis.glb`); + const isChassisDamaged = Tankopedia.use( + (state) => state.protagonist.status.chassis_damaged, + ); + + // for (const child of scene.children) { + // if (child.name.endsWith("TrackCrashed")) { + // child.visible = isChassisDamaged; + // } + + // if (child.name.startsWith("Track")) { + // child.visible = !isChassisDamaged; + // } + // } + + console.log(scene); + + return scene; +} diff --git a/packages/website-ue/src/hooks/useTankHullModel.ts b/packages/website-ue/src/hooks/useTankHullModel.ts new file mode 100644 index 000000000..474b9893f --- /dev/null +++ b/packages/website-ue/src/hooks/useTankHullModel.ts @@ -0,0 +1,7 @@ +import { useProtagonist } from "./useProtagonist"; +import { useTankModel } from "./useTankModel"; + +export function useTankHullModel() { + const tank = useProtagonist(); + return useTankModel(`/models/tanks/${tank.id}/hull.glb`); +} diff --git a/packages/website-ue/src/hooks/useTankModel.ts b/packages/website-ue/src/hooks/useTankModel.ts new file mode 100644 index 000000000..3f9ac701a --- /dev/null +++ b/packages/website-ue/src/hooks/useTankModel.ts @@ -0,0 +1,27 @@ +import { useLoader } from "@react-three/fiber"; +import { Mesh, MeshStandardMaterial } from "three"; +import { GLTFLoader } from "three-stdlib"; + +export function useTankModel(url: string) { + const collision = false; + const gltf = useLoader(GLTFLoader, url); + + gltf.scene.traverse((child) => { + if ( + child instanceof Mesh && + child.material instanceof MeshStandardMaterial + ) { + // TODO: remove this hack and fix the gltf + child.material.vertexColors = false; + } + + child.castShadow = true; + child.receiveShadow = true; + }); + + for (const child of gltf.scene.children) { + child.visible = (child.name === "CollisionMesh") === collision; + } + + return gltf.scene; +}