feat(assets): use single texture atlas instead of loading all images individually
This commit is contained in:
@@ -1,29 +1,44 @@
|
||||
import * as THREE from "three";
|
||||
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
||||
|
||||
const imageCache = new Map<string, HTMLImageElement>();
|
||||
type Rect = [number, number, number, number];
|
||||
|
||||
let atlasImage: HTMLImageElement | null = null;
|
||||
const modelCache = new Map<string, THREE.Group>();
|
||||
|
||||
const loaded = ref(0);
|
||||
const total = ref({{TOTAL}});
|
||||
const isReady = computed(() => loaded.value === total.value);
|
||||
|
||||
const createImage = (path: string) => {
|
||||
if (imageCache.has(path)) {
|
||||
return imageCache.get(path)!;
|
||||
}
|
||||
if (import.meta.client) {
|
||||
atlasImage = document.createElement('img');
|
||||
atlasImage.src = '/nds/atlas.webp';
|
||||
|
||||
const img = document.createElement('img');
|
||||
img.src = path;
|
||||
imageCache.set(path, img);
|
||||
|
||||
if (img.complete) {
|
||||
if (atlasImage.complete) {
|
||||
loaded.value += 1;
|
||||
} else {
|
||||
img.onload = () => { loaded.value += 1 };
|
||||
atlasImage.onload = () => {
|
||||
loaded.value += 1;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const drawAtlasImage = (
|
||||
ctx: CanvasRenderingContext2D,
|
||||
[sx, sy, sw, sh]: Rect,
|
||||
[dx, dy, dw, dh]: Rect,
|
||||
opts?: Partial<{ colored: boolean }>,
|
||||
): void => {
|
||||
if (!atlasImage) return;
|
||||
|
||||
if (opts?.colored) {
|
||||
const app = useAppStore();
|
||||
sh /= 16;
|
||||
sy += (app.color.row * 4 + app.color.col) * sh;
|
||||
dh = sh;
|
||||
}
|
||||
|
||||
return img;
|
||||
ctx.drawImage(atlasImage, sx, sy, sw, sh, dx, dy, dw, dh);
|
||||
};
|
||||
|
||||
const createModel = (path: string) => {
|
||||
@@ -54,7 +69,28 @@ const createModel = (path: string) => {
|
||||
return model;
|
||||
};
|
||||
|
||||
const assets = {{ASSETS}};
|
||||
export type AtlasImage = {
|
||||
draw: (
|
||||
ctx: CanvasRenderingContext2D,
|
||||
x: number,
|
||||
y: number,
|
||||
opts?: Partial<{ colored: boolean }>,
|
||||
) => void;
|
||||
rect: { x: number; y: number; width: number; height: number };
|
||||
};
|
||||
|
||||
type ImageTree = {
|
||||
[key: string]: AtlasImage | ImageTree;
|
||||
};
|
||||
|
||||
type ModelTree = {
|
||||
[key: string]: THREE.Group | ModelTree;
|
||||
};
|
||||
|
||||
const assets = {
|
||||
images: {{IMAGES}} as const satisfies ImageTree,
|
||||
models: {{MODELS}} as const satisfies ModelTree,
|
||||
};
|
||||
|
||||
export const useAssets = () => {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user