diff --git a/src/app/tools/tankopedia/[id]/components/Lighting.tsx b/src/app/tools/tankopedia/[id]/components/Lighting.tsx index a78d6708e..27a0d7d4b 100644 --- a/src/app/tools/tankopedia/[id]/components/Lighting.tsx +++ b/src/app/tools/tankopedia/[id]/components/Lighting.tsx @@ -1,15 +1,24 @@ -export function Lighting() { +import { useModel } from '../../../../../hooks/useModel'; +import { Duel } from '../page'; + +interface LightingProps { + duel: Duel; +} + +export function Lighting({ duel }: LightingProps) { + const { hasPbr } = useModel(duel.protagonist.tank.id); + return ( <> diff --git a/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx b/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx index a246bfbee..6f8b5fd7c 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx @@ -162,7 +162,7 @@ export function TankSandbox({ duel }: TankSandboxProps) { > - + (({ duel }) => { }); const armorGltf = useArmor(duel.protagonist.tank.id); - const modelGltf = useModel(duel.protagonist.tank.id); + const { gltf: modelGltf } = useModel(duel.protagonist.tank.id); const armorNodes = Object.values(armorGltf.nodes); const modelNodes = Object.values(modelGltf.nodes); diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/SpacedArmorDepth.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/SpacedArmorDepth.tsx index aec7a74b2..9f7d2903a 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/SpacedArmorDepth.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/SpacedArmorDepth.tsx @@ -120,7 +120,7 @@ export const SpacedArmorDepth = memo(({ duel }) => { }); const armorGltf = useArmor(duel.protagonist.tank.id); - const modelGltf = useModel(duel.protagonist.tank.id); + const { gltf: modelGltf } = useModel(duel.protagonist.tank.id); const armorNodes = Object.values(armorGltf.nodes); const modelNodes = Object.values(modelGltf.nodes); diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx index 01ffcd21d..2ec51a609 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx @@ -122,7 +122,7 @@ export const TankModel = memo(({ duel: { protagonist } }: TankModelProps) => { tankModelDefinition.turrets[protagonist.turret.id]; const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id]; - const gltf = useModel(protagonist.tank.id); + const { gltf } = useModel(protagonist.tank.id); const nodes = Object.values(gltf.nodes); return ( diff --git a/src/hooks/useArmor.ts b/src/hooks/useArmor.ts index ee4152582..420e6089e 100644 --- a/src/hooks/useArmor.ts +++ b/src/hooks/useArmor.ts @@ -1,7 +1,11 @@ -import { useLoader } from '@react-three/fiber'; -import { GLTFLoader } from 'three-stdlib'; +import { ObjectMap, useLoader } from '@react-three/fiber'; +import { GLTF, GLTFLoader } from 'three-stdlib'; import { asset } from '../core/blitzkrieg/asset'; +const cache: Record = {}; + export function useArmor(id: number) { - return useLoader(GLTFLoader, asset(`3d/tanks/armor/${id}.glb`)); + const gltf = useLoader(GLTFLoader, asset(`3d/tanks/armor/${id}.glb`)); + if (!cache[id]) cache[id] = gltf; + return cache[id]; } diff --git a/src/hooks/useModel.ts b/src/hooks/useModel.ts index 11b856fef..df2433686 100644 --- a/src/hooks/useModel.ts +++ b/src/hooks/useModel.ts @@ -1,7 +1,28 @@ -import { useLoader } from '@react-three/fiber'; -import { GLTFLoader } from 'three-stdlib'; +import { ObjectMap, useLoader } from '@react-three/fiber'; +import { Mesh, MeshStandardMaterial } from 'three'; +import { GLTF, GLTFLoader } from 'three-stdlib'; import { asset } from '../core/blitzkrieg/asset'; +const cache: Record< + number, + { + gltf: GLTF & ObjectMap; + hasPbr: boolean; + } +> = {}; + export function useModel(id: number) { - return useLoader(GLTFLoader, asset(`3d/tanks/models/${id}.glb`)); + const gltf = useLoader(GLTFLoader, asset(`3d/tanks/models/${id}.glb`)); + if (!cache[id]) { + cache[id] = { + gltf, + hasPbr: Object.values(gltf.nodes).some( + (node) => + node instanceof Mesh && + node.material instanceof MeshStandardMaterial && + node.material.roughnessMap !== null, + ), + }; + } + return cache[id]; }