@bloopjs/toodle 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mod.js +124 -18
- package/dist/mod.js.map +4 -4
- package/dist/textures/AssetManager.d.ts.map +1 -1
- package/dist/textures/util.d.ts +9 -0
- package/dist/textures/util.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/textures/AssetManager.ts +50 -29
- package/src/textures/util.ts +140 -0
package/dist/mod.js
CHANGED
|
@@ -19926,6 +19926,105 @@ async function textureToBitmap(device, texture, width, height) {
|
|
|
19926
19926
|
readBuffer.unmap();
|
|
19927
19927
|
return bitmap;
|
|
19928
19928
|
}
|
|
19929
|
+
async function packBitmapsToAtlasCPU(images, textureSize) {
|
|
19930
|
+
const cpuTextureAtlases = [];
|
|
19931
|
+
const packed = [];
|
|
19932
|
+
const spaces = [
|
|
19933
|
+
{ x: 0, y: 0, width: textureSize, height: textureSize }
|
|
19934
|
+
];
|
|
19935
|
+
let atlasRegionMap = new Map;
|
|
19936
|
+
for (const [id, { bitmap }] of images) {
|
|
19937
|
+
let bestSpace = -1;
|
|
19938
|
+
let bestScore = Number.POSITIVE_INFINITY;
|
|
19939
|
+
for (let i3 = 0;i3 < spaces.length; i3++) {
|
|
19940
|
+
const space2 = spaces[i3];
|
|
19941
|
+
if (bitmap.width <= space2.width && bitmap.height <= space2.height) {
|
|
19942
|
+
const score = Math.abs(space2.width * space2.height - bitmap.width * bitmap.height);
|
|
19943
|
+
if (score < bestScore) {
|
|
19944
|
+
bestScore = score;
|
|
19945
|
+
bestSpace = i3;
|
|
19946
|
+
}
|
|
19947
|
+
}
|
|
19948
|
+
}
|
|
19949
|
+
if (bestSpace === -1) {
|
|
19950
|
+
const tex2 = createAtlasBitmapFromPacked(packed, textureSize);
|
|
19951
|
+
cpuTextureAtlases.push({
|
|
19952
|
+
texture: tex2,
|
|
19953
|
+
textureRegions: atlasRegionMap,
|
|
19954
|
+
width: tex2.width,
|
|
19955
|
+
height: tex2.height
|
|
19956
|
+
});
|
|
19957
|
+
atlasRegionMap = new Map;
|
|
19958
|
+
packed.length = 0;
|
|
19959
|
+
spaces.length = 0;
|
|
19960
|
+
spaces.push({
|
|
19961
|
+
x: 0,
|
|
19962
|
+
y: 0,
|
|
19963
|
+
width: textureSize,
|
|
19964
|
+
height: textureSize
|
|
19965
|
+
});
|
|
19966
|
+
bestSpace = 0;
|
|
19967
|
+
}
|
|
19968
|
+
const space = spaces[bestSpace];
|
|
19969
|
+
packed.push({
|
|
19970
|
+
texture: bitmap,
|
|
19971
|
+
x: space.x,
|
|
19972
|
+
y: space.y,
|
|
19973
|
+
width: bitmap.width,
|
|
19974
|
+
height: bitmap.height
|
|
19975
|
+
});
|
|
19976
|
+
spaces.splice(bestSpace, 1);
|
|
19977
|
+
if (space.width - bitmap.width > 0) {
|
|
19978
|
+
spaces.push({
|
|
19979
|
+
x: space.x + bitmap.width,
|
|
19980
|
+
y: space.y,
|
|
19981
|
+
width: space.width - bitmap.width,
|
|
19982
|
+
height: bitmap.height
|
|
19983
|
+
});
|
|
19984
|
+
}
|
|
19985
|
+
if (space.height - bitmap.height > 0) {
|
|
19986
|
+
spaces.push({
|
|
19987
|
+
x: space.x,
|
|
19988
|
+
y: space.y + bitmap.height,
|
|
19989
|
+
width: space.width,
|
|
19990
|
+
height: space.height - bitmap.height
|
|
19991
|
+
});
|
|
19992
|
+
}
|
|
19993
|
+
const uvScale = {
|
|
19994
|
+
width: bitmap.width / textureSize,
|
|
19995
|
+
height: bitmap.height / textureSize
|
|
19996
|
+
};
|
|
19997
|
+
atlasRegionMap.set(id, {
|
|
19998
|
+
uvOffset: {
|
|
19999
|
+
x: space.x / textureSize,
|
|
20000
|
+
y: space.y / textureSize
|
|
20001
|
+
},
|
|
20002
|
+
uvScale,
|
|
20003
|
+
uvScaleCropped: uvScale,
|
|
20004
|
+
cropOffset: { x: 0, y: 0 },
|
|
20005
|
+
originalSize: { width: bitmap.width, height: bitmap.height }
|
|
20006
|
+
});
|
|
20007
|
+
}
|
|
20008
|
+
const tex = createAtlasBitmapFromPacked(packed, textureSize);
|
|
20009
|
+
cpuTextureAtlases.push({
|
|
20010
|
+
texture: tex,
|
|
20011
|
+
textureRegions: atlasRegionMap,
|
|
20012
|
+
width: tex.width,
|
|
20013
|
+
height: tex.height
|
|
20014
|
+
});
|
|
20015
|
+
return cpuTextureAtlases;
|
|
20016
|
+
}
|
|
20017
|
+
function createAtlasBitmapFromPacked(packed, atlasSize) {
|
|
20018
|
+
const canvas = new OffscreenCanvas(atlasSize, atlasSize);
|
|
20019
|
+
const ctx = canvas.getContext("2d");
|
|
20020
|
+
if (!ctx) {
|
|
20021
|
+
throw new Error("Failed to get 2d context from OffscreenCanvas");
|
|
20022
|
+
}
|
|
20023
|
+
for (const texture of packed) {
|
|
20024
|
+
ctx.drawImage(texture.texture, texture.x, texture.y);
|
|
20025
|
+
}
|
|
20026
|
+
return canvas.transferToImageBitmap();
|
|
20027
|
+
}
|
|
19929
20028
|
|
|
19930
20029
|
// src/textures/AssetManager.ts
|
|
19931
20030
|
class AssetManager {
|
|
@@ -20115,24 +20214,31 @@ class AssetManager {
|
|
|
20115
20214
|
return texture;
|
|
20116
20215
|
}
|
|
20117
20216
|
async#registerBundleFromTextures(bundleId, opts) {
|
|
20118
|
-
if (this.#backend.type
|
|
20119
|
-
|
|
20120
|
-
|
|
20121
|
-
|
|
20122
|
-
|
|
20123
|
-
|
|
20124
|
-
|
|
20125
|
-
|
|
20126
|
-
|
|
20127
|
-
|
|
20128
|
-
|
|
20129
|
-
|
|
20130
|
-
|
|
20217
|
+
if (this.#backend.type === "webgpu") {
|
|
20218
|
+
const device = this.#backend.device;
|
|
20219
|
+
const images = new Map;
|
|
20220
|
+
await Promise.all(Object.entries(opts.textures).map(async ([id, url]) => {
|
|
20221
|
+
const bitmap = await getBitmapFromUrl(url);
|
|
20222
|
+
let textureWrapper = this.#wrapBitmapToTexture(bitmap, id);
|
|
20223
|
+
if (opts.cropTransparentPixels && this.#cropComputeShader) {
|
|
20224
|
+
textureWrapper = await this.#cropComputeShader.processTexture(textureWrapper);
|
|
20225
|
+
}
|
|
20226
|
+
images.set(id, textureWrapper);
|
|
20227
|
+
}));
|
|
20228
|
+
const atlases = await packBitmapsToAtlas(images, this.#backend.limits.textureSize, device);
|
|
20229
|
+
this.bundles.registerDynamicBundle(bundleId, atlases);
|
|
20230
|
+
} else {
|
|
20231
|
+
if (opts.cropTransparentPixels) {
|
|
20232
|
+
console.warn("cropTransparentPixels is not supported on WebGL2 backend and will be ignored.");
|
|
20131
20233
|
}
|
|
20132
|
-
images
|
|
20133
|
-
|
|
20134
|
-
|
|
20135
|
-
|
|
20234
|
+
const images = new Map;
|
|
20235
|
+
await Promise.all(Object.entries(opts.textures).map(async ([id, url]) => {
|
|
20236
|
+
const bitmap = await getBitmapFromUrl(url);
|
|
20237
|
+
images.set(id, { bitmap, id });
|
|
20238
|
+
}));
|
|
20239
|
+
const atlases = await packBitmapsToAtlasCPU(images, this.#backend.limits.textureSize);
|
|
20240
|
+
this.bundles.registerDynamicBundle(bundleId, atlases);
|
|
20241
|
+
}
|
|
20136
20242
|
}
|
|
20137
20243
|
async#registerBundleFromAtlases(bundleId, opts) {
|
|
20138
20244
|
await this.bundles.registerAtlasBundle(bundleId, opts);
|
|
@@ -20798,5 +20904,5 @@ export {
|
|
|
20798
20904
|
AssetManager
|
|
20799
20905
|
};
|
|
20800
20906
|
|
|
20801
|
-
//# debugId=
|
|
20907
|
+
//# debugId=6E0EAD9B5EBDC37664756E2164756E21
|
|
20802
20908
|
//# sourceMappingURL=mod.js.map
|