From 8cb15d488db3656b1651c79d477d4b69d71affa2 Mon Sep 17 00:00:00 2001
From: tresabhi <43380238+tresabhi@users.noreply.github.com>
Date: Sun, 18 Oct 2026 00:10:24 -0500
Subject: [PATCH] code split
---
packages/website/src/components/TankModel.tsx | 98 +------------------
packages/website/src/hooks/useBatched.tsx | 89 +++++++++++++++++
2 files changed, 94 insertions(+), 93 deletions(-)
create mode 100644 packages/website/src/hooks/useBatched.tsx
diff --git a/packages/website/src/components/TankModel.tsx b/packages/website/src/components/TankModel.tsx
index e362ccc55..8c15f33b6 100644
--- a/packages/website/src/components/TankModel.tsx
+++ b/packages/website/src/components/TankModel.tsx
@@ -4,20 +4,14 @@ import {
type ObjectMap,
type ThreeEvent,
} from "@react-three/fiber";
-import { useRef, type ComponentProps } from "react";
+import { useRef } from "react";
import type { Texture } from "three";
-import {
- BatchedMesh,
- Group,
- Mesh,
- MeshStandardMaterial,
- Object3D,
- Vector2,
-} from "three";
+import { Group, Mesh, MeshStandardMaterial, Vector2 } from "three";
import { applyPitchYawLimits } from "../core/blitz/applyPitchYawLimits";
import { hasEquipment } from "../core/blitzkit/hasEquipment";
import { modelTransformEvent } from "../core/blitzkit/modelTransform";
import { controlsEnabledEvent } from "../core/controlsEnabled";
+import { useBatched } from "../hooks/useBatched";
import { useModel } from "../hooks/useModel";
import { useTankModelDefinition } from "../hooks/useTankModelDefinition";
import { useTankTransform } from "../hooks/useTankTransform";
@@ -26,86 +20,6 @@ import { Tankopedia } from "../stores/tankopedia";
import { TankopediaDisplay } from "../stores/tankopediaPersistent/constants";
import { ModelTankWrapper } from "./Armor/components/ModelTankWrapper";
-interface BatchedProps extends ComponentProps<"group"> {
- slicer: (node: Object3D) => boolean;
- mutator?: (mesh: Mesh) => void;
-}
-
-function useBatched(map: ObjectMap, shadows = false) {
- return function Batched({ slicer, mutator, ...props }: BatchedProps) {
- const groups = new Map<
- MeshStandardMaterial,
- { clonedMaterial: MeshStandardMaterial; meshes: Mesh[] }
- >();
-
- for (const node of Object.values(map.nodes)) {
- if (!slicer(node)) continue;
-
- node.traverse((object) => {
- if (!(object instanceof Mesh)) return;
-
- const originalMaterial = object.material;
-
- if (!(originalMaterial instanceof MeshStandardMaterial)) return;
-
- let group = groups.get(originalMaterial);
-
- if (!group) {
- group = {
- clonedMaterial: originalMaterial.clone(),
- meshes: [],
- };
- groups.set(originalMaterial, group);
- }
-
- group.meshes.push(object);
- });
- }
-
- const wrapper = new Group();
-
- for (const { clonedMaterial: material, meshes } of groups.values()) {
- let vertices = 0;
- let indices = 0;
-
- for (const mesh of meshes) {
- vertices += mesh.geometry.attributes.position.count;
- indices += mesh.geometry.index!.count;
- }
-
- const batched = new BatchedMesh(
- meshes.length,
- vertices,
- indices,
- material,
- );
-
- for (const mesh of meshes) {
- const geometryId = batched.addGeometry(mesh.geometry);
- const instanceId = batched.addInstance(geometryId);
-
- mesh.updateWorldMatrix(true, false);
- batched.setMatrixAt(instanceId, mesh.matrixWorld);
-
- if (shadows) {
- batched.castShadow = true;
- batched.receiveShadow = true;
- }
-
- mutator?.(mesh);
- }
-
- wrapper.add(batched);
- }
-
- return (
-
-
-
- );
- };
-}
-
interface SectionProps {
map: ObjectMap;
}
@@ -354,15 +268,13 @@ function Gun({ map }: SectionProps) {
export function TankModel() {
const protagonist = Duel.use((draft) => draft.protagonist);
+
const track = Duel.use((state) => state.protagonist.track);
const turret = Duel.use((state) => state.protagonist.turret);
- const canvas = useThree((state) => state.gl.domElement);
+
const hullContainer = useRef(null);
const turretContainer = useRef(null!);
const gunContainer = useRef(null!);
- const tankModelDefinition = useTankModelDefinition();
- const turretModelDefinition =
- tankModelDefinition.turrets[protagonist.turret.id];
const { gltf } = useModel(protagonist.tank.id);
diff --git a/packages/website/src/hooks/useBatched.tsx b/packages/website/src/hooks/useBatched.tsx
new file mode 100644
index 000000000..f1110700f
--- /dev/null
+++ b/packages/website/src/hooks/useBatched.tsx
@@ -0,0 +1,89 @@
+import type { ObjectMap } from "@react-three/fiber";
+import type { ComponentProps } from "react";
+import {
+ BatchedMesh,
+ Group,
+ Mesh,
+ MeshStandardMaterial,
+ type Object3D,
+} from "three";
+
+interface BatchedProps extends ComponentProps<"group"> {
+ slicer: (node: Object3D) => boolean;
+ mutator?: (mesh: Mesh) => void;
+}
+
+export function useBatched(map: ObjectMap, shadows = false) {
+ return function Batched({ slicer, mutator, ...props }: BatchedProps) {
+ const groups = new Map<
+ MeshStandardMaterial,
+ { clonedMaterial: MeshStandardMaterial; meshes: Mesh[] }
+ >();
+
+ for (const node of Object.values(map.nodes)) {
+ if (!slicer(node)) continue;
+
+ node.traverse((object) => {
+ if (!(object instanceof Mesh)) return;
+
+ const originalMaterial = object.material;
+
+ if (!(originalMaterial instanceof MeshStandardMaterial)) return;
+
+ let group = groups.get(originalMaterial);
+
+ if (!group) {
+ group = {
+ clonedMaterial: originalMaterial.clone(),
+ meshes: [],
+ };
+ groups.set(originalMaterial, group);
+ }
+
+ group.meshes.push(object);
+ });
+ }
+
+ const wrapper = new Group();
+
+ for (const { clonedMaterial: material, meshes } of groups.values()) {
+ let vertices = 0;
+ let indices = 0;
+
+ for (const mesh of meshes) {
+ vertices += mesh.geometry.attributes.position.count;
+ indices += mesh.geometry.index!.count;
+ }
+
+ const batched = new BatchedMesh(
+ meshes.length,
+ vertices,
+ indices,
+ material,
+ );
+
+ for (const mesh of meshes) {
+ const geometryId = batched.addGeometry(mesh.geometry);
+ const instanceId = batched.addInstance(geometryId);
+
+ mesh.updateWorldMatrix(true, false);
+ batched.setMatrixAt(instanceId, mesh.matrixWorld);
+
+ if (shadows) {
+ batched.castShadow = true;
+ batched.receiveShadow = true;
+ }
+
+ mutator?.(mesh);
+ }
+
+ wrapper.add(batched);
+ }
+
+ return (
+
+
+
+ );
+ };
+}