mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
dispose models on unload
This commit is contained in:
1 parent
4f42a31f53
commit
100c7391fb
3 files changed
+90
-23
No files matched your search
@@ -1,23 +1,19 @@
|
|||||||
import { asset } from '@blitzkit/core';
|
import { asset } from "@blitzkit/core";
|
||||||
import { type ObjectMap, useLoader } from '@react-three/fiber';
|
import { useLoader } from "@react-three/fiber";
|
||||||
import { type GLTF, GLTFLoader } from 'three-stdlib';
|
import { GLTFLoader } from "three-stdlib";
|
||||||
|
import { useDispose } from "./useDispose";
|
||||||
const cache: Record<
|
|
||||||
number,
|
|
||||||
{ gltf: GLTF & ObjectMap; hasDynamicArmor: boolean }
|
|
||||||
> = {};
|
|
||||||
|
|
||||||
export function useArmor(id: number) {
|
export function useArmor(id: number) {
|
||||||
const gltf = useLoader(GLTFLoader, asset(`3d/tanks/armor/${id}.glb`));
|
const path = asset(`3d/tanks/armor/${id}.glb`);
|
||||||
|
const gltf = useLoader(GLTFLoader, path);
|
||||||
|
|
||||||
if (!cache[id]) {
|
useDispose(gltf, path);
|
||||||
cache[id] = {
|
|
||||||
gltf,
|
return {
|
||||||
hasDynamicArmor: Object.values(gltf.nodes).some(
|
gltf,
|
||||||
(node) =>
|
hasDynamicArmor: Object.values(gltf.nodes).some(
|
||||||
node.name.includes('state_00') || node.name.includes('state_01'),
|
(node) =>
|
||||||
),
|
node.name.includes("state_00") || node.name.includes("state_01"),
|
||||||
};
|
),
|
||||||
}
|
};
|
||||||
return cache[id];
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import { useLoader } from "@react-three/fiber";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { Cache } from "three";
|
||||||
|
import { GLTFLoader } from "three-stdlib";
|
||||||
|
|
||||||
|
export function useDispose(gltf: any, path: string) {
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
const disposedGeometries = new Set<string>();
|
||||||
|
const disposedMaterials = new Set<string>();
|
||||||
|
const disposedTextures = new Set<string>();
|
||||||
|
|
||||||
|
gltf.scene.traverse((obj: any) => {
|
||||||
|
if (obj.geometry) {
|
||||||
|
const geometry = obj.geometry;
|
||||||
|
|
||||||
|
if (!disposedGeometries.has(geometry.uuid)) {
|
||||||
|
disposedGeometries.add(geometry.uuid);
|
||||||
|
geometry.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.material) {
|
||||||
|
const materials = Array.isArray(obj.material)
|
||||||
|
? obj.material
|
||||||
|
: [obj.material];
|
||||||
|
|
||||||
|
for (const material of materials) {
|
||||||
|
if (!disposedMaterials.has(material.uuid)) {
|
||||||
|
disposedMaterials.add(material.uuid);
|
||||||
|
|
||||||
|
for (const key in material) {
|
||||||
|
const value = material[key];
|
||||||
|
|
||||||
|
if (
|
||||||
|
value &&
|
||||||
|
value.isTexture &&
|
||||||
|
!disposedTextures.has(value.uuid)
|
||||||
|
) {
|
||||||
|
disposedTextures.add(value.uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key in material) {
|
||||||
|
const value = material[key];
|
||||||
|
|
||||||
|
if (value && value.isTexture) {
|
||||||
|
value.source.data.close();
|
||||||
|
value.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
material.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.skeleton) {
|
||||||
|
obj.skeleton.dispose?.();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
useLoader.clear(GLTFLoader, path);
|
||||||
|
Cache.remove(path);
|
||||||
|
};
|
||||||
|
}, [gltf, path]);
|
||||||
|
}
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
import { asset } from "@blitzkit/core";
|
import { asset } from "@blitzkit/core";
|
||||||
import { type ObjectMap, useLoader } from "@react-three/fiber";
|
import { useLoader } from "@react-three/fiber";
|
||||||
import { Mesh, MeshStandardMaterial } from "three";
|
import { Mesh, MeshStandardMaterial } from "three";
|
||||||
import { type GLTF, GLTFLoader } from "three-stdlib";
|
import { GLTFLoader } from "three-stdlib";
|
||||||
|
import { useDispose } from "./useDispose";
|
||||||
|
|
||||||
export function useModel(id: number) {
|
export function useModel(id: number) {
|
||||||
const gltf = useLoader(GLTFLoader, asset(`3d/tanks/models/${id}.glb`));
|
const path = asset(`3d/tanks/models/${id}.glb`);
|
||||||
|
const gltf = useLoader(GLTFLoader, path);
|
||||||
|
|
||||||
|
useDispose(gltf, path);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
gltf,
|
gltf,
|
||||||
@@ -12,7 +16,7 @@ export function useModel(id: number) {
|
|||||||
(node) =>
|
(node) =>
|
||||||
node instanceof Mesh &&
|
node instanceof Mesh &&
|
||||||
node.material instanceof MeshStandardMaterial &&
|
node.material instanceof MeshStandardMaterial &&
|
||||||
node.material.roughnessMap !== null
|
node.material.roughnessMap !== null,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user