minerender 2.1.0-alpha.132 → 2.1.0-alpha.134
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/browser/esm/Materials.mjs +3 -2
- package/dist/browser/esm/Materials.mjs.map +1 -1
- package/dist/browser/esm/assets/Fonts.mjs +31 -4
- package/dist/browser/esm/assets/Fonts.mjs.map +1 -1
- package/dist/browser/esm/assets/_fonts/Unihex.mjs +166 -0
- package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -0
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs +12 -1
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
- package/dist/browser/esm/assets/source/parser/AssetParsers.mjs +1 -0
- package/dist/browser/esm/assets/source/parser/AssetParsers.mjs.map +1 -1
- package/dist/browser/esm/cache/Caching.mjs +2 -0
- package/dist/browser/esm/cache/Caching.mjs.map +1 -1
- package/dist/browser/esm/env/browser/section.worker.mjs +5 -3
- package/dist/browser/esm/env/browser/section.worker.mjs.map +1 -1
- package/dist/browser/esm/gui/GuiText.mjs +4 -3
- package/dist/browser/esm/gui/GuiText.mjs.map +1 -1
- package/dist/browser/esm/index.browser.d.mts +25 -4
- package/dist/browser/esm/model/scene/ModelObject.mjs +4 -0
- package/dist/browser/esm/model/scene/ModelObject.mjs.map +1 -1
- package/dist/browser/esm/world/SectionGeometry.mjs +5 -3
- package/dist/browser/esm/world/SectionGeometry.mjs.map +1 -1
- package/dist/browser/esm/world/SectionMesh.mjs +4 -0
- package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
- package/dist/browser/esm/world/SectionModels.mjs +2 -2
- package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
- package/dist/browser/index.d.ts +25 -4
- package/dist/browser/index.js +263 -38
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +306 -38
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +25 -4
- package/dist/node/index.d.ts +25 -4
- package/dist/node/index.js +267 -38
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +267 -38
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/cache/Caching.ts"],"sourcesContent":["import { AsyncLoadingCache, Caches, Loader, LoadingCache, SimpleCache } from \"@inventivetalent/loading-cache\";\nimport { BoxGeometryKey, CacheKey, serializeBoxGeometryKey, serializeImageKey, TextureKey } from \"./CacheKey\";\nimport { Time } from \"@inventivetalent/time\";\nimport { ImageInfo, ImageLoader } from \"../image/ImageLoader\";\nimport { BoxGeometry, Material, Mesh, PixelFormat, RGBAFormat, Texture } from \"three\";\nimport { Materials } from \"../Materials\";\nimport { CompatImage } from \"../canvas/CanvasCompat\";\nimport { Model, TextureAsset } from \"../model/Model\";\nimport { WrappedImage } from \"../WrappedImage\";\nimport { TextureAtlas } from \"../texture/TextureAtlas\";\nimport { ExtractableImageData } from \"../ExtractableImageData\";\nimport { MinecraftTextureMeta } from \"../MinecraftTextureMeta\";\nimport type { EntityModelFile } from \"../entity/EntityModel\";\nimport type { EntityAnimationFile } from \"../entity/EntityAnimation\";\nimport type { BlockEntityIndex } from \"../assets/BlockEntities\";\nimport type { ListAsset } from \"../ListAsset\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport type { AssetKey } from \"../assets/AssetKey\";\nimport type { BitmapFont } from \"../assets/Fonts\";\nimport type { BannerPattern } from \"../assets/BannerPatterns\";\nimport type { Biome } from \"../assets/Biomes\";\n\n/** Shared in-memory caches for loaded assets and render resources. Persistent stores are managed separately. */\nexport class Caching {\n\n private static _generation = 0;\n\n /** Changes when shared assets are cleared, so derived caches can discard their old values. */\n public static get generation(): number { return this._generation; }\n\n static readonly rawImageCache: AsyncLoadingCache<CacheKey, ImageInfo> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(5))\n .buildAsync<CacheKey, ImageInfo>();\n static readonly imageDataCache: AsyncLoadingCache<CacheKey, ImageData> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(10))\n .buildAsync<CacheKey, ImageData>();\n static readonly canvasImageDataCache: AsyncLoadingCache<CacheKey, ExtractableImageData> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(10))\n .buildAsync<CacheKey, ExtractableImageData>();\n static readonly wrappedImageCache: AsyncLoadingCache<CacheKey, WrappedImage> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(10))\n .buildAsync<CacheKey, WrappedImage>();\n\n static readonly boxGeometryCache: SimpleCache<CacheKey, BoxGeometry> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(20))\n .build<CacheKey, BoxGeometry>();\n\n static readonly textureCache: SimpleCache<CacheKey, Texture> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .build<CacheKey, Texture>();\n\n static readonly materialCache: SimpleCache<CacheKey, Material> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .build<CacheKey, Material>();\n\n static readonly boxMeshCache: SimpleCache<CacheKey, Mesh> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .build<CacheKey, Mesh>();\n\n static readonly textureAssetCache: AsyncLoadingCache<CacheKey, TextureAsset> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, TextureAsset>();\n static readonly textureMetaCache: AsyncLoadingCache<CacheKey, MinecraftTextureMeta> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, MinecraftTextureMeta>();\n\n static readonly rawModelCache: AsyncLoadingCache<CacheKey, Model> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, Model>();\n static readonly mergedModelCache: AsyncLoadingCache<CacheKey, Model> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, Model>();\n static readonly modelTextureAtlasCache: AsyncLoadingCache<CacheKey, TextureAtlas> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, TextureAtlas>();\n\n static readonly blockStateCache: AsyncLoadingCache<CacheKey, BlockState> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, BlockState>();\n\n static readonly listAssetCache: AsyncLoadingCache<CacheKey, ListAsset> = Caching.createAssetCache<ListAsset>();\n\n static readonly blockTintCache: AsyncLoadingCache<CacheKey, number> = Caching.createAssetCache<number>();\n\n static readonly entityModelCache: AsyncLoadingCache<CacheKey, EntityModelFile> = Caching.createAssetCache<EntityModelFile>();\n\n static readonly entityTextureCache: AsyncLoadingCache<CacheKey, AssetKey> = Caching.createAssetCache<AssetKey>();\n\n static readonly entityAnimationCache: AsyncLoadingCache<CacheKey, EntityAnimationFile> = Caching.createAssetCache<EntityAnimationFile>();\n static readonly blockEntityIndexCache: AsyncLoadingCache<CacheKey, BlockEntityIndex> = Caching.createAssetCache<BlockEntityIndex>();\n static readonly fontCache: AsyncLoadingCache<CacheKey, BitmapFont> = Caching.createAssetCache<BitmapFont>();\n static readonly bannerPatternCache: AsyncLoadingCache<CacheKey, BannerPattern> = Caching.createAssetCache<BannerPattern>();\n static readonly mineRenderDataCache: AsyncLoadingCache<CacheKey, unknown> = Caching.createAssetCache<unknown>();\n static readonly usernameUuidCache: AsyncLoadingCache<CacheKey, string> = Caches.builder()\n .expireAfterWrite(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, string>();\n static readonly biomeCache: AsyncLoadingCache<CacheKey, Biome> = Caching.createAssetCache<Biome>();\n\n private static createAssetCache<T>(): AsyncLoadingCache<CacheKey, T> {\n return Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, T>();\n }\n\n\n /** Every cache above, so clear()/end() can never fall out of sync with the field list again. */\n private static get all(): { invalidateAll(): void; end(): void }[] {\n return [\n this.rawImageCache,\n this.imageDataCache,\n this.canvasImageDataCache,\n this.wrappedImageCache,\n this.boxGeometryCache,\n this.textureCache,\n this.materialCache,\n this.boxMeshCache,\n this.textureAssetCache,\n this.textureMetaCache,\n this.rawModelCache,\n this.mergedModelCache,\n this.modelTextureAtlasCache,\n this.blockStateCache,\n this.listAssetCache,\n this.blockTintCache,\n this.entityModelCache,\n this.entityTextureCache,\n this.entityAnimationCache,\n this.blockEntityIndexCache,\n this.fontCache,\n this.bannerPatternCache,\n this.mineRenderDataCache,\n this.usernameUuidCache,\n this.biomeCache\n ];\n }\n\n /** Invalidates in-memory entries so later lookups reload them. Persisted entries are retained. */\n public static clear() {\n this._generation++;\n for (const cache of this.all) {\n cache.invalidateAll();\n }\n }\n\n /**\n * Clears every cache and stops its expiry timer.\n *\n * Expiry timers are unref'd in Node, so idle processes can exit without this cleanup.\n * Use {@link shutdown} to also stop requests and the shared Ticker.\n */\n public static end() {\n this._generation++;\n for (const cache of this.all) {\n cache.invalidateAll();\n cache.end();\n }\n }\n\n public static get cacheSizes() {\n return {\n //TODO\n }\n }\n\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/cache/Caching.ts"],"sourcesContent":["import { AsyncLoadingCache, Caches, Loader, LoadingCache, SimpleCache } from \"@inventivetalent/loading-cache\";\nimport { BoxGeometryKey, CacheKey, serializeBoxGeometryKey, serializeImageKey, TextureKey } from \"./CacheKey\";\nimport { Time } from \"@inventivetalent/time\";\nimport { ImageInfo, ImageLoader } from \"../image/ImageLoader\";\nimport { BoxGeometry, Material, Mesh, PixelFormat, RGBAFormat, Texture } from \"three\";\nimport { Materials } from \"../Materials\";\nimport { CompatImage } from \"../canvas/CanvasCompat\";\nimport { Model, TextureAsset } from \"../model/Model\";\nimport { WrappedImage } from \"../WrappedImage\";\nimport { TextureAtlas } from \"../texture/TextureAtlas\";\nimport { ExtractableImageData } from \"../ExtractableImageData\";\nimport { MinecraftTextureMeta } from \"../MinecraftTextureMeta\";\nimport type { EntityModelFile } from \"../entity/EntityModel\";\nimport type { EntityAnimationFile } from \"../entity/EntityAnimation\";\nimport type { BlockEntityIndex } from \"../assets/BlockEntities\";\nimport type { ListAsset } from \"../ListAsset\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport type { AssetKey } from \"../assets/AssetKey\";\nimport type { UnihexFile } from \"../assets/_fonts/Unihex\";\nimport type { BitmapFont } from \"../assets/Fonts\";\nimport type { BannerPattern } from \"../assets/BannerPatterns\";\nimport type { Biome } from \"../assets/Biomes\";\n\n/** Shared in-memory caches for loaded assets and render resources. Persistent stores are managed separately. */\nexport class Caching {\n\n private static _generation = 0;\n\n /** Changes when shared assets are cleared, so derived caches can discard their old values. */\n public static get generation(): number { return this._generation; }\n\n static readonly rawImageCache: AsyncLoadingCache<CacheKey, ImageInfo> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(5))\n .buildAsync<CacheKey, ImageInfo>();\n static readonly imageDataCache: AsyncLoadingCache<CacheKey, ImageData> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(10))\n .buildAsync<CacheKey, ImageData>();\n static readonly canvasImageDataCache: AsyncLoadingCache<CacheKey, ExtractableImageData> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(10))\n .buildAsync<CacheKey, ExtractableImageData>();\n static readonly wrappedImageCache: AsyncLoadingCache<CacheKey, WrappedImage> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(10))\n .buildAsync<CacheKey, WrappedImage>();\n\n static readonly boxGeometryCache: SimpleCache<CacheKey, BoxGeometry> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(20))\n .build<CacheKey, BoxGeometry>();\n\n static readonly textureCache: SimpleCache<CacheKey, Texture> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .build<CacheKey, Texture>();\n\n static readonly materialCache: SimpleCache<CacheKey, Material> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .build<CacheKey, Material>();\n\n static readonly boxMeshCache: SimpleCache<CacheKey, Mesh> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .build<CacheKey, Mesh>();\n\n static readonly textureAssetCache: AsyncLoadingCache<CacheKey, TextureAsset> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, TextureAsset>();\n static readonly textureMetaCache: AsyncLoadingCache<CacheKey, MinecraftTextureMeta> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, MinecraftTextureMeta>();\n\n static readonly rawModelCache: AsyncLoadingCache<CacheKey, Model> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, Model>();\n static readonly mergedModelCache: AsyncLoadingCache<CacheKey, Model> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, Model>();\n static readonly modelTextureAtlasCache: AsyncLoadingCache<CacheKey, TextureAtlas> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, TextureAtlas>();\n\n static readonly blockStateCache: AsyncLoadingCache<CacheKey, BlockState> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, BlockState>();\n\n static readonly listAssetCache: AsyncLoadingCache<CacheKey, ListAsset> = Caching.createAssetCache<ListAsset>();\n\n static readonly blockTintCache: AsyncLoadingCache<CacheKey, number> = Caching.createAssetCache<number>();\n\n static readonly entityModelCache: AsyncLoadingCache<CacheKey, EntityModelFile> = Caching.createAssetCache<EntityModelFile>();\n\n static readonly entityTextureCache: AsyncLoadingCache<CacheKey, AssetKey> = Caching.createAssetCache<AssetKey>();\n\n static readonly entityAnimationCache: AsyncLoadingCache<CacheKey, EntityAnimationFile> = Caching.createAssetCache<EntityAnimationFile>();\n static readonly blockEntityIndexCache: AsyncLoadingCache<CacheKey, BlockEntityIndex> = Caching.createAssetCache<BlockEntityIndex>();\n static readonly unihexCache: AsyncLoadingCache<CacheKey, UnihexFile> = Caching.createAssetCache<UnihexFile>();\n static readonly fontCache: AsyncLoadingCache<CacheKey, BitmapFont> = Caching.createAssetCache<BitmapFont>();\n static readonly bannerPatternCache: AsyncLoadingCache<CacheKey, BannerPattern> = Caching.createAssetCache<BannerPattern>();\n static readonly mineRenderDataCache: AsyncLoadingCache<CacheKey, unknown> = Caching.createAssetCache<unknown>();\n static readonly usernameUuidCache: AsyncLoadingCache<CacheKey, string> = Caches.builder()\n .expireAfterWrite(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, string>();\n static readonly biomeCache: AsyncLoadingCache<CacheKey, Biome> = Caching.createAssetCache<Biome>();\n\n private static createAssetCache<T>(): AsyncLoadingCache<CacheKey, T> {\n return Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, T>();\n }\n\n\n /** Every cache above, so clear()/end() can never fall out of sync with the field list again. */\n private static get all(): { invalidateAll(): void; end(): void }[] {\n return [\n this.rawImageCache,\n this.imageDataCache,\n this.canvasImageDataCache,\n this.wrappedImageCache,\n this.boxGeometryCache,\n this.textureCache,\n this.materialCache,\n this.boxMeshCache,\n this.textureAssetCache,\n this.textureMetaCache,\n this.rawModelCache,\n this.mergedModelCache,\n this.modelTextureAtlasCache,\n this.blockStateCache,\n this.listAssetCache,\n this.blockTintCache,\n this.entityModelCache,\n this.entityTextureCache,\n this.entityAnimationCache,\n this.blockEntityIndexCache,\n this.fontCache,\n this.unihexCache,\n this.bannerPatternCache,\n this.mineRenderDataCache,\n this.usernameUuidCache,\n this.biomeCache\n ];\n }\n\n /** Invalidates in-memory entries so later lookups reload them. Persisted entries are retained. */\n public static clear() {\n this._generation++;\n for (const cache of this.all) {\n cache.invalidateAll();\n }\n }\n\n /**\n * Clears every cache and stops its expiry timer.\n *\n * Expiry timers are unref'd in Node, so idle processes can exit without this cleanup.\n * Use {@link shutdown} to also stop requests and the shared Ticker.\n */\n public static end() {\n this._generation++;\n for (const cache of this.all) {\n cache.invalidateAll();\n cache.end();\n }\n }\n\n public static get cacheSizes() {\n return {\n //TODO\n }\n }\n\n}\n"],"mappings":"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","names":[]}
|
|
@@ -196,7 +196,7 @@ function buildSectionGeometry(input) {
|
|
|
196
196
|
const cornerBrightness2 = ambientOcclusion ? new Float32Array(4) : void 0;
|
|
197
197
|
for (const template of templateData) {
|
|
198
198
|
const { quads } = template;
|
|
199
|
-
if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 || template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 || template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads || template.biomeTint && template.biomeTint.length !== quads) {
|
|
199
|
+
if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 || template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 || template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads || template.shade && template.shade.length !== quads * 4 || template.biomeTint && template.biomeTint.length !== quads) {
|
|
200
200
|
throw new RangeError("Section template arrays do not match its quad count");
|
|
201
201
|
}
|
|
202
202
|
}
|
|
@@ -287,6 +287,7 @@ function buildSectionGeometry(input) {
|
|
|
287
287
|
}
|
|
288
288
|
const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);
|
|
289
289
|
const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);
|
|
290
|
+
const shade = new Float32Array(faces * 4).fill(1);
|
|
290
291
|
const outputIndices = new Uint32Array(faces * 6);
|
|
291
292
|
const blockIndices = new Uint16Array(faces);
|
|
292
293
|
let vertex = 0, indexOffset = 0;
|
|
@@ -316,6 +317,7 @@ function buildSectionGeometry(input) {
|
|
|
316
317
|
normals[vertex * 3] = template.normals[source * 3];
|
|
317
318
|
normals[vertex * 3 + 1] = template.normals[source * 3 + 1];
|
|
318
319
|
normals[vertex * 3 + 2] = template.normals[source * 3 + 2];
|
|
320
|
+
shade[vertex] = template.shade?.[source] ?? 1;
|
|
319
321
|
uvs[vertex * 2] = mapU(template.uvs[source * 2]);
|
|
320
322
|
uvs[vertex * 2 + 1] = mapV(template.uvs[source * 2 + 1]);
|
|
321
323
|
uvBounds[vertex * 4] = mapU(template.uvBounds[source * 4]);
|
|
@@ -368,11 +370,11 @@ function buildSectionGeometry(input) {
|
|
|
368
370
|
indexOffset += 6;
|
|
369
371
|
}
|
|
370
372
|
}
|
|
371
|
-
return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };
|
|
373
|
+
return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, shade, indices: outputIndices, blockIndices };
|
|
372
374
|
});
|
|
373
375
|
}
|
|
374
376
|
function sectionGeometryTransferables(pages) {
|
|
375
|
-
return pages.flatMap((page) => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.indices.buffer, page.blockIndices.buffer]);
|
|
377
|
+
return pages.flatMap((page) => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.shade.buffer, page.indices.buffer, page.blockIndices.buffer]);
|
|
376
378
|
}
|
|
377
379
|
|
|
378
380
|
// src/env/browser/section.worker.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/model/fluid/FluidQuads.ts","../../../../../src/world/_light/AmbientOcclusion.ts","../../../../../src/world/_light/FaceLight.ts","../../../../../src/world/SectionGeometry.ts","../../../../../src/env/browser/section.worker.ts"],"sourcesContent":["import type { DoubleArray, TripleArray } from \"../Model\";\n\nexport type FluidKind = \"water\" | \"lava\";\n\n/** Reads the fluid kind from bits 4 and 5 of a section cell byte. */\nexport function fluidKindOf(byte: number): FluidKind | undefined {\n const kind = byte & 48;\n return kind === 16 ? \"water\" : kind === 32 ? \"lava\" : undefined;\n}\n\n/** A neighboring cell's fluid level and full-cube occlusion state. */\nexport interface FluidSample {\n fluid?: FluidKind;\n level?: number;\n solid?: boolean;\n}\n\n/** Reads cells at integer block offsets relative to the fluid being rendered, with `(0, 0, 0)` as the center. */\nexport type FluidSampler = (x: number, y: number, z: number) => FluidSample;\n\nconst HORIZONTAL = [[0, -1], [0, 1], [-1, 0], [1, 0]] as const;\nconst EPSILON = 0.001;\n\nfunction ownHeight(sample: FluidSample): number {\n const level = sample.level ?? 0;\n return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;\n}\n\n/** Fluid faces as quads centered on the block, four vertices each, in emission order. */\nexport interface FluidQuads {\n positions: number[];\n normals: number[];\n uvs: number[];\n sprites: number[];\n}\n\n/** Builds centered fluid quads with sprite 0 (still) or 1 (flowing). */\nexport function buildFluidQuads(kind: FluidKind, sample: FluidSampler): FluidQuads {\n const positions: number[] = [], normals: number[] = [], uvs: number[] = [], sprites: number[] = [];\n const self = sample(0, 0, 0);\n const height = (x: number, z: number): number => {\n const state = sample(x, 0, z);\n if (state.fluid !== kind) return state.solid ? -1 : 0;\n return sample(x, 1, z).fluid === kind ? 1 : ownHeight(state);\n };\n const selfHeight = height(0, 0);\n const corner = (x: number, z: number): number => {\n if (selfHeight >= 1) return 1;\n const adjacent = [height(x, 0), height(0, z)];\n if (adjacent.some(value => value >= 1)) return 1;\n const values = [selfHeight, ...adjacent];\n if (adjacent.some(value => value > 0)) {\n const diagonal = height(x, z);\n if (diagonal >= 1) return 1;\n values.push(diagonal);\n }\n let sum = 0, weights = 0;\n for (const value of values) {\n if (value < 0) continue;\n const weight = value >= 0.8 ? 10 : 1;\n sum += value * weight;\n weights += weight;\n }\n return sum / weights;\n };\n const heights = [corner(-1, -1), corner(-1, 1), corner(1, 1), corner(1, -1)];\n const above = sample(0, 1, 0), below = sample(0, -1, 0);\n const renderTop = above.fluid !== kind && !(above.solid && Math.min(...heights) >= 1);\n const renderBottom = below.fluid !== kind && !below.solid;\n const bottom = renderBottom ? EPSILON : 0;\n const face = (vertices: TripleArray[], uv: DoubleArray[], normal: TripleArray, material: number) => {\n sprites.push(material);\n for (let i = 0; i < 4; i++) {\n positions.push(...vertices[i].map(value => value * 16 - 8));\n normals.push(...normal);\n uvs.push(uv[i][0], 1 - uv[i][1]);\n }\n };\n\n if (renderTop) {\n for (let i = 0; i < heights.length; i++) heights[i] -= EPSILON;\n let flowX = 0, flowZ = 0;\n for (const [x, z] of HORIZONTAL) {\n const neighbor = sample(x, 0, z);\n if (neighbor.fluid && neighbor.fluid !== kind) continue;\n let difference = 0;\n if (neighbor.fluid === kind) {\n difference = ownHeight(self) - ownHeight(neighbor);\n } else if (!neighbor.solid) {\n const lower = sample(x, -1, z);\n if (lower.fluid === kind) difference = ownHeight(self) - (ownHeight(lower) - 8 / 9);\n }\n flowX += x * difference;\n flowZ += z * difference;\n }\n const flowing = flowX !== 0 || flowZ !== 0;\n let uv: DoubleArray[] = [[0, 0], [0, 1], [1, 1], [1, 0]];\n if (flowing) {\n const angle = Math.atan2(flowZ, flowX) - Math.PI / 2;\n const s = Math.sin(angle) / 4, c = Math.cos(angle) / 4;\n uv = [[0.5 - c - s, 0.5 - c + s], [0.5 - c + s, 0.5 + c + s],\n [0.5 + c + s, 0.5 + c - s], [0.5 + c - s, 0.5 - c - s]];\n }\n face([[0, heights[0], 0], [0, heights[1], 1], [1, heights[2], 1], [1, heights[3], 0]], uv, [0, 1, 0], flowing ? 1 : 0);\n }\n if (renderBottom) {\n face([[0, bottom, 0], [1, bottom, 0], [1, bottom, 1], [0, bottom, 1]],\n [[0, 0], [1, 0], [1, 1], [0, 1]], [0, -1, 0], 0);\n }\n const sides = [\n { x: 0, z: -1, corners: [0, 3], edge: [[0, EPSILON], [1, EPSILON]] },\n { x: 0, z: 1, corners: [2, 1], edge: [[1, 1 - EPSILON], [0, 1 - EPSILON]] },\n { x: -1, z: 0, corners: [1, 0], edge: [[EPSILON, 1], [EPSILON, 0]] },\n { x: 1, z: 0, corners: [3, 2], edge: [[1 - EPSILON, 0], [1 - EPSILON, 1]] }\n ];\n for (const { x, z, corners, edge } of sides) {\n const neighbor = sample(x, 0, z);\n if (neighbor.fluid === kind || neighbor.solid) continue;\n const [h0, h1] = corners.map(index => heights[index]);\n const [[x0, z0], [x1, z1]] = edge;\n face([[x0, h0, z0], [x1, h1, z1], [x1, bottom, z1], [x0, bottom, z0]],\n [[0, (1 - h0) / 2], [0.5, (1 - h1) / 2], [0.5, 0.5], [0, 0.5]], [x, 0, z], 1);\n }\n return { positions, normals, uvs, sprites };\n}\n","const AXIS_STRIDES = [1, 9, 3] as const;\n\n/** Reads the edge and corner blockers around one cell in an 18×18×18 section neighborhood. */\nexport function sectionAmbientOcclusionMask(cells: Uint8Array, center: number): number {\n let mask = 0;\n for (let y = -1; y <= 1; y++) for (let z = -1; z <= 1; z++) for (let x = -1; x <= 1; x++) {\n if (Math.abs(x) + Math.abs(y) + Math.abs(z) < 2) continue;\n if (cells[center + y * 324 + z * 18 + x]) mask |= 1 << ((y + 1) * 9 + (z + 1) * 3 + x + 1);\n }\n return mask;\n}\n\nfunction cornerBrightness(mask: number, center: number, u: number, v: number): number {\n const sideU = (mask >>> (center + u)) & 1;\n const sideV = (mask >>> (center + v)) & 1;\n const corner = sideU && sideV ? 1 : (mask >>> (center + u + v)) & 1;\n return 1 - (sideU + sideV + corner) * 0.2;\n}\n\n/** Writes four linear AO factors for a boundary quad; inset or non-axis-aligned quads remain unchanged. */\nexport function quadAmbientOcclusion(positions: ArrayLike<number>, normals: ArrayLike<number>, quad: number,\n mask: number, output: Float32Array): void {\n output.fill(1);\n if (!mask) return;\n const start = quad * 12;\n let axis = 0;\n if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;\n if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;\n const uAxis = (axis + 1) % 3, vAxis = (axis + 2) % 3;\n if (Math.abs(Math.abs(normals[start + axis]) - 1) > 1e-6 ||\n Math.abs(normals[start + uAxis]) > 1e-6 || Math.abs(normals[start + vAxis]) > 1e-6) return;\n const sign = normals[start + axis] > 0 ? 1 : -1;\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = start + vertex * 3;\n if (Math.abs(positions[offset + axis] - sign * 8) > 0.0016 ||\n Math.abs(positions[offset + uAxis]) > 8.0016 || Math.abs(positions[offset + vAxis]) > 8.0016) return;\n }\n const center = 13 + sign * AXIS_STRIDES[axis];\n const u = AXIS_STRIDES[uAxis], v = AXIS_STRIDES[vAxis];\n const lowLow = cornerBrightness(mask, center, -u, -v);\n const highLow = cornerBrightness(mask, center, u, -v);\n const lowHigh = cornerBrightness(mask, center, -u, v);\n const highHigh = cornerBrightness(mask, center, u, v);\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = start + vertex * 3;\n const a = Math.max(0, Math.min(1, (positions[offset + uAxis] + 8) / 16));\n const b = Math.max(0, Math.min(1, (positions[offset + vAxis] + 8) / 16));\n output[vertex] = (lowLow * (1 - a) + highLow * a) * (1 - b) + (lowHigh * (1 - a) + highHigh * a) * b;\n }\n}\n","/** Converts a saved light level to linear brightness; unknown samples retain preview brightness. */\nexport function lightBrightness(level: number, ambient = 0): number {\n if (level === 255) return 1;\n const curve = level / (60 - 3 * level);\n return curve + ambient * (1 - curve);\n}\n\n/** Selects the adjacent light sample for a boundary quad, or the center sample for an inset quad. */\nexport function quadLightIndex(positions: ArrayLike<number>, normals: ArrayLike<number>, quad: number): number {\n const start = quad * 12;\n let axis = 0;\n if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;\n if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;\n const positive = normals[start + axis] > 0;\n const boundary = positive ? 8 : -8;\n for (let vertex = 0; vertex < 4; vertex++) {\n if (Math.abs(positions[start + vertex * 3 + axis] - boundary) > 0.0016) return 0;\n }\n return axis * 2 + (positive ? 1 : 2);\n}\n\n/** Fluids sample the brighter of their own cell and the cell above, or below for bottom faces. */\nexport function fluidLightLevel(center: number, neighbor: number): number {\n return Math.max(center === 255 ? 15 : center, neighbor === 255 ? 15 : neighbor);\n}\n\n/** Offsets for center and face samples in an 18×18×18 section neighborhood. */\nexport const LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18] as const;\n","import { buildFluidQuads, fluidKindOf } from \"../model/fluid/FluidQuads\";\nimport type { FluidKind, FluidQuads } from \"../model/fluid/FluidQuads\";\nimport { quadAmbientOcclusion, sectionAmbientOcclusionMask } from \"./_light/AmbientOcclusion\";\nimport { fluidLightLevel, LIGHT_SAMPLE_OFFSETS, lightBrightness, quadLightIndex } from \"./_light/FaceLight\";\n\n/** Static model geometry as quads: four vertices per quad, in quad order. */\nexport interface SectionTemplateData {\n quads: number;\n positions: Float32Array;\n normals: Float32Array;\n uvs: Float32Array;\n uvBounds: Float32Array;\n colors: Float32Array;\n indices: Uint16Array;\n cullFaces: Uint8Array;\n biomeTint?: Uint8Array;\n atlas: number;\n layer: number;\n ambientOcclusion?: boolean;\n}\n\n/** The pixel dimensions and animation state of a source atlas. */\nexport interface SectionAtlasSize {\n width: number;\n height: number;\n animated: boolean;\n}\n\n/** One fluid kind's sprite rectangles in atlas pixels and its linear-light vertex tint. */\nexport interface SectionFluidKind {\n atlas: number;\n still: [x: number, y: number, width: number, height: number];\n flow: [x: number, y: number, width: number, height: number];\n tint: [r: number, g: number, b: number];\n}\n\n/** Fluid cells of the section plus a one-cell shell, 18×18×18, x fastest, then z, then y. */\nexport interface SectionFluidInput {\n /** Bit 128 marks a surface rendered elsewhere; the cell still supplies neighbor fluid samples. */\n cells: Uint8Array;\n /** Linear RGB per section cell, indexed by (x + 16z + 256y) * 3. Omission uses the water kind's tint. */\n waterTints?: Float32Array;\n water?: SectionFluidKind;\n lava?: SectionFluidKind;\n}\n\n/** Section placements and their shared templates, ready for geometry building. */\nexport interface SectionGeometryInput {\n count: number;\n indices: Uint16Array;\n templates: Uint16Array;\n cullMasks: Uint8Array;\n /** Linear RGB per placement; three NaN values preserve the template's colors. */\n biomeTints?: Float32Array;\n templateData: SectionTemplateData[];\n atlases: SectionAtlasSize[];\n maxAtlasSize: number;\n fluids?: SectionFluidInput;\n /** Saved brightness levels for an 18×18×18 neighborhood; 255 means unknown/full brightness. */\n light?: Uint8Array;\n /** Minimum brightness for known light levels, from 0 to 1. */\n ambientLight?: number;\n /** Opaque full cubes in an 18×18×18 neighborhood, stored as zero or one. */\n ambientOcclusion?: Uint8Array;\n}\n\n/** Merged quads and source-atlas placements for one atlas page. */\nexport interface SectionGeometryPage {\n layer: number;\n width: number;\n height: number;\n placements: { atlas: number; x: number; y: number }[];\n positions: Float32Array;\n normals: Float32Array;\n uvs: Float32Array;\n uvBounds: Float32Array;\n colors: Float32Array;\n indices: Uint32Array;\n /** Owning section cell for each quad; each quad contributes two consecutive triangles. */\n blockIndices: Uint16Array;\n}\n\n/** Builds section-local geometry from visible quads, with bounded atlas pages per layer. */\nexport function buildSectionGeometry(input: SectionGeometryInput): SectionGeometryPage[] {\n const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;\n if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError(\"Section atlas size must be a positive integer\");\n if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError(\"Section entry count exceeds its arrays\");\n if (biomeTints && biomeTints.length !== count * 3) throw new RangeError(\"Section biome tints must contain RGB for each placement\");\n if (fluids && fluids.cells.length !== 5832) throw new RangeError(\"Section fluid cells must cover an 18×18×18 neighborhood\");\n if (fluids?.waterTints && fluids.waterTints.length !== 4096 * 3) throw new RangeError(\"Section water tints must contain RGB for 4096 cells\");\n if (light && (light.length !== 5832 || light.some(level => level > 15 && level !== 255))) {\n throw new RangeError(\"Section light must cover an 18×18×18 neighborhood with levels from 0 to 15 or 255\");\n }\n if (ambientLight !== undefined && (!Number.isFinite(ambientLight) || ambientLight < 0 || ambientLight > 1)) {\n throw new RangeError(\"Section ambient light must be a number from 0 to 1\");\n }\n if (ambientOcclusion && (ambientOcclusion.length !== 5832 || ambientOcclusion.some(value => value > 1))) {\n throw new RangeError(\"Section ambient occlusion must cover an 18×18×18 neighborhood with zero or one per cell\");\n }\n const cornerBrightness = ambientOcclusion ? new Float32Array(4) : undefined;\n for (const template of templateData) {\n const { quads } = template;\n if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 ||\n template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 ||\n template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads ||\n (template.biomeTint && template.biomeTint.length !== quads)) {\n throw new RangeError(\"Section template arrays do not match its quad count\");\n }\n }\n const visible: number[] = [];\n const visibleAtlases = new Map<number, Set<number>>();\n for (let entry = 0; entry < count; entry++) {\n const template = templateData[templates[entry]];\n if (!template.cullFaces.some(direction => !(cullMasks[entry] & direction))) continue;\n visible.push(entry);\n if (!visibleAtlases.has(template.layer)) visibleAtlases.set(template.layer, new Set());\n visibleAtlases.get(template.layer)!.add(template.atlas);\n }\n const pages: {\n layer: number; placements: SectionGeometryPage[\"placements\"]; entries: number[];\n fluids: { quads: FluidQuads; x: number; y: number; z: number; data: SectionFluidKind; tint: ArrayLike<number> }[];\n x: number; y: number; rowHeight: number; width: number; height: number;\n }[] = [];\n const locations = new Map<number, { page: number; x: number; y: number }>();\n for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a], [b]) => a - b)) {\n const firstPage = pages.length;\n for (const atlas of [...layerAtlases].sort((a, b) => Number(atlases[a].animated) - Number(atlases[b].animated) ||\n (atlases[a].animated ? a - b : atlases[b].height - atlases[a].height))) {\n const { width, height, animated } = atlases[atlas];\n if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError(\"Model atlas exceeds the section atlas size limit\");\n let selected = -1;\n for (let i = firstPage; !animated && i < pages.length; i++) {\n const page = pages[i];\n const nextRow = page.x + width > maxAtlasSize;\n if ((nextRow ? page.y + page.rowHeight : page.y) + height > maxAtlasSize) continue;\n if (nextRow) {\n page.y += page.rowHeight;\n page.x = 0;\n page.rowHeight = 0;\n }\n selected = i;\n break;\n }\n if (selected < 0) {\n selected = pages.length;\n pages.push({ layer, placements: [], entries: [], fluids: [], x: 0, y: 0, rowHeight: 0, width: 0, height: 0 });\n }\n const page = pages[selected];\n page.placements.push({ atlas, x: page.x, y: page.y });\n locations.set(atlas, { page: selected, x: page.x, y: page.y });\n page.x += width;\n page.rowHeight = Math.max(page.rowHeight, height);\n page.width = Math.max(page.width, page.x);\n page.height = Math.max(page.height, page.y + height);\n }\n }\n for (const entry of visible) pages[locations.get(templateData[templates[entry]].atlas)!.page].entries.push(entry);\n\n if (fluids) {\n const fluidPages = new Map<FluidKind, (typeof pages)[number]>();\n for (let y = 0; y < 16; y++) for (let z = 0; z < 16; z++) for (let x = 0; x < 16; x++) {\n const byte = fluids.cells[(y + 1) * 324 + (z + 1) * 18 + x + 1];\n const fluid = fluidKindOf(byte);\n if (!fluid || (byte & 128)) continue;\n const data = fluids[fluid];\n if (!data) throw new RangeError(\"Section fluid input lacks the atlas for a present fluid\");\n const quads = buildFluidQuads(fluid, (dx, dy, dz) => {\n const cell = fluids.cells[(y + 1 + dy) * 324 + (z + 1 + dz) * 18 + x + 1 + dx];\n return { fluid: fluidKindOf(cell), level: cell & 15, solid: !!(cell & 64) };\n });\n if (!quads.sprites.length) continue;\n if (!fluidPages.has(fluid)) {\n const { width, height } = atlases[data.atlas];\n if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError(\"Model atlas exceeds the section atlas size limit\");\n fluidPages.set(fluid, { layer: 2, placements: [{ atlas: data.atlas, x: 0, y: 0 }], entries: [], fluids: [],\n x: 0, y: 0, rowHeight: 0, width, height });\n }\n const tintIndex = (x + z * 16 + y * 256) * 3;\n const tint = fluid === \"water\" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;\n fluidPages.get(fluid)!.fluids.push({ quads, x, y, z, data, tint });\n }\n pages.push(...[...fluidPages.values()].sort((a, b) => Number(atlases[a.placements[0].atlas].animated) -\n Number(atlases[b.placements[0].atlas].animated) || a.placements[0].atlas - b.placements[0].atlas));\n }\n\n return pages.map(page => {\n let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);\n for (const entry of page.entries) {\n const template = templateData[templates[entry]];\n for (let quad = 0; quad < template.quads; quad++) {\n if (!(cullMasks[entry] & template.cullFaces[quad])) faces++;\n }\n }\n const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);\n const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);\n const outputIndices = new Uint32Array(faces * 6);\n const blockIndices = new Uint16Array(faces);\n let vertex = 0, indexOffset = 0;\n for (const entry of page.entries) {\n const template = templateData[templates[entry]];\n const atlas = atlases[template.atlas];\n const placement = locations.get(template.atlas)!;\n const mapU = (u: number) => (placement.x + u * atlas.width) / page.width;\n const mapV = (v: number) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;\n const offsetX = (indices[entry] % 16) * 16;\n const offsetY = Math.floor(indices[entry] / 256) * 16;\n const offsetZ = (Math.floor(indices[entry] / 16) % 16) * 16;\n const lightIndex = (offsetY / 16 + 1) * 324 + (offsetZ / 16 + 1) * 18 + offsetX / 16 + 1;\n const ambientMask = ambientOcclusion && template.ambientOcclusion !== false\n ? sectionAmbientOcclusionMask(ambientOcclusion, lightIndex) : 0;\n for (let quad = 0; quad < template.quads; quad++) {\n if (cullMasks[entry] & template.cullFaces[quad]) continue;\n blockIndices[indexOffset / 6] = indices[entry];\n if (ambientMask) quadAmbientOcclusion(template.positions, template.normals, quad, ambientMask, cornerBrightness!);\n const brightness = light ? lightBrightness(light[lightIndex + LIGHT_SAMPLE_OFFSETS[\n quadLightIndex(template.positions, template.normals, quad)]], ambientLight) : 1;\n const tint = biomeTints && template.biomeTint?.[quad] && !Number.isNaN(biomeTints[entry * 3]) ? entry * 3 : undefined;\n const start = vertex;\n for (let corner = 0; corner < 4; corner++, vertex++) {\n const source = quad * 4 + corner;\n positions[vertex * 3] = template.positions[source * 3] + offsetX;\n positions[vertex * 3 + 1] = template.positions[source * 3 + 1] + offsetY;\n positions[vertex * 3 + 2] = template.positions[source * 3 + 2] + offsetZ;\n normals[vertex * 3] = template.normals[source * 3];\n normals[vertex * 3 + 1] = template.normals[source * 3 + 1];\n normals[vertex * 3 + 2] = template.normals[source * 3 + 2];\n uvs[vertex * 2] = mapU(template.uvs[source * 2]);\n uvs[vertex * 2 + 1] = mapV(template.uvs[source * 2 + 1]);\n uvBounds[vertex * 4] = mapU(template.uvBounds[source * 4]);\n uvBounds[vertex * 4 + 1] = mapV(template.uvBounds[source * 4 + 1]);\n uvBounds[vertex * 4 + 2] = mapU(template.uvBounds[source * 4 + 2]);\n uvBounds[vertex * 4 + 3] = mapV(template.uvBounds[source * 4 + 3]);\n const factor = brightness * (ambientMask ? cornerBrightness![corner] : 1);\n colors[vertex * 3] = (tint === undefined ? template.colors[source * 3] : biomeTints![tint]) * factor;\n colors[vertex * 3 + 1] = (tint === undefined ? template.colors[source * 3 + 1] : biomeTints![tint + 1]) * factor;\n colors[vertex * 3 + 2] = (tint === undefined ? template.colors[source * 3 + 2] : biomeTints![tint + 2]) * factor;\n }\n for (let corner = 0; corner < 6; corner++) outputIndices[indexOffset++] = start + template.indices[quad * 6 + corner];\n }\n }\n for (const { quads, x, y, z, data, tint } of page.fluids) {\n const atlas = atlases[data.atlas];\n const placement = page.placements[0];\n const mapU = (u: number) => (placement.x + u * atlas.width) / page.width;\n const mapV = (v: number) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;\n const lightIndex = (y + 1) * 324 + (z + 1) * 18 + x + 1;\n for (let quad = 0; quad < quads.sprites.length; quad++) {\n blockIndices[indexOffset / 6] = x + z * 16 + y * 256;\n const rect = quads.sprites[quad] === 0 ? data.still : data.flow;\n const brightness = light ? lightBrightness(fluidLightLevel(light[lightIndex],\n light[lightIndex + (quads.normals[quad * 12 + 1] < 0 ? -324 : 324)]), ambientLight) : 1;\n const start = vertex;\n for (let corner = 0; corner < 4; corner++, vertex++) {\n const source = quad * 4 + corner;\n positions[vertex * 3] = quads.positions[source * 3] + x * 16;\n positions[vertex * 3 + 1] = quads.positions[source * 3 + 1] + y * 16;\n positions[vertex * 3 + 2] = quads.positions[source * 3 + 2] + z * 16;\n normals[vertex * 3] = quads.normals[source * 3];\n normals[vertex * 3 + 1] = quads.normals[source * 3 + 1];\n normals[vertex * 3 + 2] = quads.normals[source * 3 + 2];\n uvs[vertex * 2] = mapU((rect[0] + quads.uvs[source * 2] * rect[2]) / atlas.width);\n uvs[vertex * 2 + 1] = mapV(1 - (rect[1] + (1 - quads.uvs[source * 2 + 1]) * rect[3]) / atlas.height);\n uvBounds.set([mapU(rect[0] / atlas.width), mapV(1 - (rect[1] + rect[3]) / atlas.height),\n mapU((rect[0] + rect[2]) / atlas.width), mapV(1 - rect[1] / atlas.height)], vertex * 4);\n colors[vertex * 3] = tint[0] * brightness;\n colors[vertex * 3 + 1] = tint[1] * brightness;\n colors[vertex * 3 + 2] = tint[2] * brightness;\n }\n outputIndices.set([start, start + 1, start + 2, start, start + 2, start + 3], indexOffset);\n indexOffset += 6;\n }\n }\n return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };\n });\n}\n\n/** Returns the buffers behind each page's typed arrays for transfer to another thread. */\nexport function sectionGeometryTransferables(pages: readonly SectionGeometryPage[]): ArrayBuffer[] {\n return pages.flatMap(page => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.indices.buffer, page.blockIndices.buffer]);\n}\n","import { buildSectionGeometry, sectionGeometryTransferables, SectionGeometryInput } from \"../../world/SectionGeometry\";\n\naddEventListener(\"message\", (event: MessageEvent<{ id: number; type: \"build\"; input: SectionGeometryInput }>) => {\n const { id, input } = event.data;\n try {\n const pages = buildSectionGeometry(input);\n postMessage({ id, type: \"pages\", pages }, { transfer: sectionGeometryTransferables(pages) });\n } catch (error) {\n postMessage({ id, type: \"error\", message: error instanceof Error ? error.message : String(error) });\n }\n});\n"],"mappings":"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","names":["cornerBrightness","page"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/model/fluid/FluidQuads.ts","../../../../../src/world/_light/AmbientOcclusion.ts","../../../../../src/world/_light/FaceLight.ts","../../../../../src/world/SectionGeometry.ts","../../../../../src/env/browser/section.worker.ts"],"sourcesContent":["import type { DoubleArray, TripleArray } from \"../Model\";\n\nexport type FluidKind = \"water\" | \"lava\";\n\n/** Reads the fluid kind from bits 4 and 5 of a section cell byte. */\nexport function fluidKindOf(byte: number): FluidKind | undefined {\n const kind = byte & 48;\n return kind === 16 ? \"water\" : kind === 32 ? \"lava\" : undefined;\n}\n\n/** A neighboring cell's fluid level and full-cube occlusion state. */\nexport interface FluidSample {\n fluid?: FluidKind;\n level?: number;\n solid?: boolean;\n}\n\n/** Reads cells at integer block offsets relative to the fluid being rendered, with `(0, 0, 0)` as the center. */\nexport type FluidSampler = (x: number, y: number, z: number) => FluidSample;\n\nconst HORIZONTAL = [[0, -1], [0, 1], [-1, 0], [1, 0]] as const;\nconst EPSILON = 0.001;\n\nfunction ownHeight(sample: FluidSample): number {\n const level = sample.level ?? 0;\n return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;\n}\n\n/** Fluid faces as quads centered on the block, four vertices each, in emission order. */\nexport interface FluidQuads {\n positions: number[];\n normals: number[];\n uvs: number[];\n sprites: number[];\n}\n\n/** Builds centered fluid quads with sprite 0 (still) or 1 (flowing). */\nexport function buildFluidQuads(kind: FluidKind, sample: FluidSampler): FluidQuads {\n const positions: number[] = [], normals: number[] = [], uvs: number[] = [], sprites: number[] = [];\n const self = sample(0, 0, 0);\n const height = (x: number, z: number): number => {\n const state = sample(x, 0, z);\n if (state.fluid !== kind) return state.solid ? -1 : 0;\n return sample(x, 1, z).fluid === kind ? 1 : ownHeight(state);\n };\n const selfHeight = height(0, 0);\n const corner = (x: number, z: number): number => {\n if (selfHeight >= 1) return 1;\n const adjacent = [height(x, 0), height(0, z)];\n if (adjacent.some(value => value >= 1)) return 1;\n const values = [selfHeight, ...adjacent];\n if (adjacent.some(value => value > 0)) {\n const diagonal = height(x, z);\n if (diagonal >= 1) return 1;\n values.push(diagonal);\n }\n let sum = 0, weights = 0;\n for (const value of values) {\n if (value < 0) continue;\n const weight = value >= 0.8 ? 10 : 1;\n sum += value * weight;\n weights += weight;\n }\n return sum / weights;\n };\n const heights = [corner(-1, -1), corner(-1, 1), corner(1, 1), corner(1, -1)];\n const above = sample(0, 1, 0), below = sample(0, -1, 0);\n const renderTop = above.fluid !== kind && !(above.solid && Math.min(...heights) >= 1);\n const renderBottom = below.fluid !== kind && !below.solid;\n const bottom = renderBottom ? EPSILON : 0;\n const face = (vertices: TripleArray[], uv: DoubleArray[], normal: TripleArray, material: number) => {\n sprites.push(material);\n for (let i = 0; i < 4; i++) {\n positions.push(...vertices[i].map(value => value * 16 - 8));\n normals.push(...normal);\n uvs.push(uv[i][0], 1 - uv[i][1]);\n }\n };\n\n if (renderTop) {\n for (let i = 0; i < heights.length; i++) heights[i] -= EPSILON;\n let flowX = 0, flowZ = 0;\n for (const [x, z] of HORIZONTAL) {\n const neighbor = sample(x, 0, z);\n if (neighbor.fluid && neighbor.fluid !== kind) continue;\n let difference = 0;\n if (neighbor.fluid === kind) {\n difference = ownHeight(self) - ownHeight(neighbor);\n } else if (!neighbor.solid) {\n const lower = sample(x, -1, z);\n if (lower.fluid === kind) difference = ownHeight(self) - (ownHeight(lower) - 8 / 9);\n }\n flowX += x * difference;\n flowZ += z * difference;\n }\n const flowing = flowX !== 0 || flowZ !== 0;\n let uv: DoubleArray[] = [[0, 0], [0, 1], [1, 1], [1, 0]];\n if (flowing) {\n const angle = Math.atan2(flowZ, flowX) - Math.PI / 2;\n const s = Math.sin(angle) / 4, c = Math.cos(angle) / 4;\n uv = [[0.5 - c - s, 0.5 - c + s], [0.5 - c + s, 0.5 + c + s],\n [0.5 + c + s, 0.5 + c - s], [0.5 + c - s, 0.5 - c - s]];\n }\n face([[0, heights[0], 0], [0, heights[1], 1], [1, heights[2], 1], [1, heights[3], 0]], uv, [0, 1, 0], flowing ? 1 : 0);\n }\n if (renderBottom) {\n face([[0, bottom, 0], [1, bottom, 0], [1, bottom, 1], [0, bottom, 1]],\n [[0, 0], [1, 0], [1, 1], [0, 1]], [0, -1, 0], 0);\n }\n const sides = [\n { x: 0, z: -1, corners: [0, 3], edge: [[0, EPSILON], [1, EPSILON]] },\n { x: 0, z: 1, corners: [2, 1], edge: [[1, 1 - EPSILON], [0, 1 - EPSILON]] },\n { x: -1, z: 0, corners: [1, 0], edge: [[EPSILON, 1], [EPSILON, 0]] },\n { x: 1, z: 0, corners: [3, 2], edge: [[1 - EPSILON, 0], [1 - EPSILON, 1]] }\n ];\n for (const { x, z, corners, edge } of sides) {\n const neighbor = sample(x, 0, z);\n if (neighbor.fluid === kind || neighbor.solid) continue;\n const [h0, h1] = corners.map(index => heights[index]);\n const [[x0, z0], [x1, z1]] = edge;\n face([[x0, h0, z0], [x1, h1, z1], [x1, bottom, z1], [x0, bottom, z0]],\n [[0, (1 - h0) / 2], [0.5, (1 - h1) / 2], [0.5, 0.5], [0, 0.5]], [x, 0, z], 1);\n }\n return { positions, normals, uvs, sprites };\n}\n","const AXIS_STRIDES = [1, 9, 3] as const;\n\n/** Reads the edge and corner blockers around one cell in an 18×18×18 section neighborhood. */\nexport function sectionAmbientOcclusionMask(cells: Uint8Array, center: number): number {\n let mask = 0;\n for (let y = -1; y <= 1; y++) for (let z = -1; z <= 1; z++) for (let x = -1; x <= 1; x++) {\n if (Math.abs(x) + Math.abs(y) + Math.abs(z) < 2) continue;\n if (cells[center + y * 324 + z * 18 + x]) mask |= 1 << ((y + 1) * 9 + (z + 1) * 3 + x + 1);\n }\n return mask;\n}\n\nfunction cornerBrightness(mask: number, center: number, u: number, v: number): number {\n const sideU = (mask >>> (center + u)) & 1;\n const sideV = (mask >>> (center + v)) & 1;\n const corner = sideU && sideV ? 1 : (mask >>> (center + u + v)) & 1;\n return 1 - (sideU + sideV + corner) * 0.2;\n}\n\n/** Writes four linear AO factors for a boundary quad; inset or non-axis-aligned quads remain unchanged. */\nexport function quadAmbientOcclusion(positions: ArrayLike<number>, normals: ArrayLike<number>, quad: number,\n mask: number, output: Float32Array): void {\n output.fill(1);\n if (!mask) return;\n const start = quad * 12;\n let axis = 0;\n if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;\n if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;\n const uAxis = (axis + 1) % 3, vAxis = (axis + 2) % 3;\n if (Math.abs(Math.abs(normals[start + axis]) - 1) > 1e-6 ||\n Math.abs(normals[start + uAxis]) > 1e-6 || Math.abs(normals[start + vAxis]) > 1e-6) return;\n const sign = normals[start + axis] > 0 ? 1 : -1;\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = start + vertex * 3;\n if (Math.abs(positions[offset + axis] - sign * 8) > 0.0016 ||\n Math.abs(positions[offset + uAxis]) > 8.0016 || Math.abs(positions[offset + vAxis]) > 8.0016) return;\n }\n const center = 13 + sign * AXIS_STRIDES[axis];\n const u = AXIS_STRIDES[uAxis], v = AXIS_STRIDES[vAxis];\n const lowLow = cornerBrightness(mask, center, -u, -v);\n const highLow = cornerBrightness(mask, center, u, -v);\n const lowHigh = cornerBrightness(mask, center, -u, v);\n const highHigh = cornerBrightness(mask, center, u, v);\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = start + vertex * 3;\n const a = Math.max(0, Math.min(1, (positions[offset + uAxis] + 8) / 16));\n const b = Math.max(0, Math.min(1, (positions[offset + vAxis] + 8) / 16));\n output[vertex] = (lowLow * (1 - a) + highLow * a) * (1 - b) + (lowHigh * (1 - a) + highHigh * a) * b;\n }\n}\n","/** Converts a saved light level to linear brightness; unknown samples retain preview brightness. */\nexport function lightBrightness(level: number, ambient = 0): number {\n if (level === 255) return 1;\n const curve = level / (60 - 3 * level);\n return curve + ambient * (1 - curve);\n}\n\n/** Selects the adjacent light sample for a boundary quad, or the center sample for an inset quad. */\nexport function quadLightIndex(positions: ArrayLike<number>, normals: ArrayLike<number>, quad: number): number {\n const start = quad * 12;\n let axis = 0;\n if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;\n if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;\n const positive = normals[start + axis] > 0;\n const boundary = positive ? 8 : -8;\n for (let vertex = 0; vertex < 4; vertex++) {\n if (Math.abs(positions[start + vertex * 3 + axis] - boundary) > 0.0016) return 0;\n }\n return axis * 2 + (positive ? 1 : 2);\n}\n\n/** Fluids sample the brighter of their own cell and the cell above, or below for bottom faces. */\nexport function fluidLightLevel(center: number, neighbor: number): number {\n return Math.max(center === 255 ? 15 : center, neighbor === 255 ? 15 : neighbor);\n}\n\n/** Offsets for center and face samples in an 18×18×18 section neighborhood. */\nexport const LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18] as const;\n","import { buildFluidQuads, fluidKindOf } from \"../model/fluid/FluidQuads\";\nimport type { FluidKind, FluidQuads } from \"../model/fluid/FluidQuads\";\nimport { quadAmbientOcclusion, sectionAmbientOcclusionMask } from \"./_light/AmbientOcclusion\";\nimport { fluidLightLevel, LIGHT_SAMPLE_OFFSETS, lightBrightness, quadLightIndex } from \"./_light/FaceLight\";\n\n/** Static model geometry as quads: four vertices per quad, in quad order. */\nexport interface SectionTemplateData {\n quads: number;\n positions: Float32Array;\n normals: Float32Array;\n uvs: Float32Array;\n uvBounds: Float32Array;\n colors: Float32Array;\n shade?: Float32Array;\n indices: Uint16Array;\n cullFaces: Uint8Array;\n biomeTint?: Uint8Array;\n atlas: number;\n layer: number;\n ambientOcclusion?: boolean;\n}\n\n/** The pixel dimensions and animation state of a source atlas. */\nexport interface SectionAtlasSize {\n width: number;\n height: number;\n animated: boolean;\n}\n\n/** One fluid kind's sprite rectangles in atlas pixels and its linear-light vertex tint. */\nexport interface SectionFluidKind {\n atlas: number;\n still: [x: number, y: number, width: number, height: number];\n flow: [x: number, y: number, width: number, height: number];\n tint: [r: number, g: number, b: number];\n}\n\n/** Fluid cells of the section plus a one-cell shell, 18×18×18, x fastest, then z, then y. */\nexport interface SectionFluidInput {\n /** Bit 128 marks a surface rendered elsewhere; the cell still supplies neighbor fluid samples. */\n cells: Uint8Array;\n /** Linear RGB per section cell, indexed by (x + 16z + 256y) * 3. Omission uses the water kind's tint. */\n waterTints?: Float32Array;\n water?: SectionFluidKind;\n lava?: SectionFluidKind;\n}\n\n/** Section placements and their shared templates, ready for geometry building. */\nexport interface SectionGeometryInput {\n count: number;\n indices: Uint16Array;\n templates: Uint16Array;\n cullMasks: Uint8Array;\n /** Linear RGB per placement; three NaN values preserve the template's colors. */\n biomeTints?: Float32Array;\n templateData: SectionTemplateData[];\n atlases: SectionAtlasSize[];\n maxAtlasSize: number;\n fluids?: SectionFluidInput;\n /** Saved brightness levels for an 18×18×18 neighborhood; 255 means unknown/full brightness. */\n light?: Uint8Array;\n /** Minimum brightness for known light levels, from 0 to 1. */\n ambientLight?: number;\n /** Opaque full cubes in an 18×18×18 neighborhood, stored as zero or one. */\n ambientOcclusion?: Uint8Array;\n}\n\n/** Merged quads and source-atlas placements for one atlas page. */\nexport interface SectionGeometryPage {\n layer: number;\n width: number;\n height: number;\n placements: { atlas: number; x: number; y: number }[];\n positions: Float32Array;\n normals: Float32Array;\n uvs: Float32Array;\n uvBounds: Float32Array;\n colors: Float32Array;\n shade: Float32Array;\n indices: Uint32Array;\n /** Owning section cell for each quad; each quad contributes two consecutive triangles. */\n blockIndices: Uint16Array;\n}\n\n/** Builds section-local geometry from visible quads, with bounded atlas pages per layer. */\nexport function buildSectionGeometry(input: SectionGeometryInput): SectionGeometryPage[] {\n const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;\n if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError(\"Section atlas size must be a positive integer\");\n if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError(\"Section entry count exceeds its arrays\");\n if (biomeTints && biomeTints.length !== count * 3) throw new RangeError(\"Section biome tints must contain RGB for each placement\");\n if (fluids && fluids.cells.length !== 5832) throw new RangeError(\"Section fluid cells must cover an 18×18×18 neighborhood\");\n if (fluids?.waterTints && fluids.waterTints.length !== 4096 * 3) throw new RangeError(\"Section water tints must contain RGB for 4096 cells\");\n if (light && (light.length !== 5832 || light.some(level => level > 15 && level !== 255))) {\n throw new RangeError(\"Section light must cover an 18×18×18 neighborhood with levels from 0 to 15 or 255\");\n }\n if (ambientLight !== undefined && (!Number.isFinite(ambientLight) || ambientLight < 0 || ambientLight > 1)) {\n throw new RangeError(\"Section ambient light must be a number from 0 to 1\");\n }\n if (ambientOcclusion && (ambientOcclusion.length !== 5832 || ambientOcclusion.some(value => value > 1))) {\n throw new RangeError(\"Section ambient occlusion must cover an 18×18×18 neighborhood with zero or one per cell\");\n }\n const cornerBrightness = ambientOcclusion ? new Float32Array(4) : undefined;\n for (const template of templateData) {\n const { quads } = template;\n if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 ||\n template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 ||\n template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads ||\n (template.shade && template.shade.length !== quads * 4) ||\n (template.biomeTint && template.biomeTint.length !== quads)) {\n throw new RangeError(\"Section template arrays do not match its quad count\");\n }\n }\n const visible: number[] = [];\n const visibleAtlases = new Map<number, Set<number>>();\n for (let entry = 0; entry < count; entry++) {\n const template = templateData[templates[entry]];\n if (!template.cullFaces.some(direction => !(cullMasks[entry] & direction))) continue;\n visible.push(entry);\n if (!visibleAtlases.has(template.layer)) visibleAtlases.set(template.layer, new Set());\n visibleAtlases.get(template.layer)!.add(template.atlas);\n }\n const pages: {\n layer: number; placements: SectionGeometryPage[\"placements\"]; entries: number[];\n fluids: { quads: FluidQuads; x: number; y: number; z: number; data: SectionFluidKind; tint: ArrayLike<number> }[];\n x: number; y: number; rowHeight: number; width: number; height: number;\n }[] = [];\n const locations = new Map<number, { page: number; x: number; y: number }>();\n for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a], [b]) => a - b)) {\n const firstPage = pages.length;\n for (const atlas of [...layerAtlases].sort((a, b) => Number(atlases[a].animated) - Number(atlases[b].animated) ||\n (atlases[a].animated ? a - b : atlases[b].height - atlases[a].height))) {\n const { width, height, animated } = atlases[atlas];\n if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError(\"Model atlas exceeds the section atlas size limit\");\n let selected = -1;\n for (let i = firstPage; !animated && i < pages.length; i++) {\n const page = pages[i];\n const nextRow = page.x + width > maxAtlasSize;\n if ((nextRow ? page.y + page.rowHeight : page.y) + height > maxAtlasSize) continue;\n if (nextRow) {\n page.y += page.rowHeight;\n page.x = 0;\n page.rowHeight = 0;\n }\n selected = i;\n break;\n }\n if (selected < 0) {\n selected = pages.length;\n pages.push({ layer, placements: [], entries: [], fluids: [], x: 0, y: 0, rowHeight: 0, width: 0, height: 0 });\n }\n const page = pages[selected];\n page.placements.push({ atlas, x: page.x, y: page.y });\n locations.set(atlas, { page: selected, x: page.x, y: page.y });\n page.x += width;\n page.rowHeight = Math.max(page.rowHeight, height);\n page.width = Math.max(page.width, page.x);\n page.height = Math.max(page.height, page.y + height);\n }\n }\n for (const entry of visible) pages[locations.get(templateData[templates[entry]].atlas)!.page].entries.push(entry);\n\n if (fluids) {\n const fluidPages = new Map<FluidKind, (typeof pages)[number]>();\n for (let y = 0; y < 16; y++) for (let z = 0; z < 16; z++) for (let x = 0; x < 16; x++) {\n const byte = fluids.cells[(y + 1) * 324 + (z + 1) * 18 + x + 1];\n const fluid = fluidKindOf(byte);\n if (!fluid || (byte & 128)) continue;\n const data = fluids[fluid];\n if (!data) throw new RangeError(\"Section fluid input lacks the atlas for a present fluid\");\n const quads = buildFluidQuads(fluid, (dx, dy, dz) => {\n const cell = fluids.cells[(y + 1 + dy) * 324 + (z + 1 + dz) * 18 + x + 1 + dx];\n return { fluid: fluidKindOf(cell), level: cell & 15, solid: !!(cell & 64) };\n });\n if (!quads.sprites.length) continue;\n if (!fluidPages.has(fluid)) {\n const { width, height } = atlases[data.atlas];\n if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError(\"Model atlas exceeds the section atlas size limit\");\n fluidPages.set(fluid, { layer: 2, placements: [{ atlas: data.atlas, x: 0, y: 0 }], entries: [], fluids: [],\n x: 0, y: 0, rowHeight: 0, width, height });\n }\n const tintIndex = (x + z * 16 + y * 256) * 3;\n const tint = fluid === \"water\" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;\n fluidPages.get(fluid)!.fluids.push({ quads, x, y, z, data, tint });\n }\n pages.push(...[...fluidPages.values()].sort((a, b) => Number(atlases[a.placements[0].atlas].animated) -\n Number(atlases[b.placements[0].atlas].animated) || a.placements[0].atlas - b.placements[0].atlas));\n }\n\n return pages.map(page => {\n let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);\n for (const entry of page.entries) {\n const template = templateData[templates[entry]];\n for (let quad = 0; quad < template.quads; quad++) {\n if (!(cullMasks[entry] & template.cullFaces[quad])) faces++;\n }\n }\n const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);\n const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);\n const shade = new Float32Array(faces * 4).fill(1);\n const outputIndices = new Uint32Array(faces * 6);\n const blockIndices = new Uint16Array(faces);\n let vertex = 0, indexOffset = 0;\n for (const entry of page.entries) {\n const template = templateData[templates[entry]];\n const atlas = atlases[template.atlas];\n const placement = locations.get(template.atlas)!;\n const mapU = (u: number) => (placement.x + u * atlas.width) / page.width;\n const mapV = (v: number) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;\n const offsetX = (indices[entry] % 16) * 16;\n const offsetY = Math.floor(indices[entry] / 256) * 16;\n const offsetZ = (Math.floor(indices[entry] / 16) % 16) * 16;\n const lightIndex = (offsetY / 16 + 1) * 324 + (offsetZ / 16 + 1) * 18 + offsetX / 16 + 1;\n const ambientMask = ambientOcclusion && template.ambientOcclusion !== false\n ? sectionAmbientOcclusionMask(ambientOcclusion, lightIndex) : 0;\n for (let quad = 0; quad < template.quads; quad++) {\n if (cullMasks[entry] & template.cullFaces[quad]) continue;\n blockIndices[indexOffset / 6] = indices[entry];\n if (ambientMask) quadAmbientOcclusion(template.positions, template.normals, quad, ambientMask, cornerBrightness!);\n const brightness = light ? lightBrightness(light[lightIndex + LIGHT_SAMPLE_OFFSETS[\n quadLightIndex(template.positions, template.normals, quad)]], ambientLight) : 1;\n const tint = biomeTints && template.biomeTint?.[quad] && !Number.isNaN(biomeTints[entry * 3]) ? entry * 3 : undefined;\n const start = vertex;\n for (let corner = 0; corner < 4; corner++, vertex++) {\n const source = quad * 4 + corner;\n positions[vertex * 3] = template.positions[source * 3] + offsetX;\n positions[vertex * 3 + 1] = template.positions[source * 3 + 1] + offsetY;\n positions[vertex * 3 + 2] = template.positions[source * 3 + 2] + offsetZ;\n normals[vertex * 3] = template.normals[source * 3];\n normals[vertex * 3 + 1] = template.normals[source * 3 + 1];\n normals[vertex * 3 + 2] = template.normals[source * 3 + 2];\n shade[vertex] = template.shade?.[source] ?? 1;\n uvs[vertex * 2] = mapU(template.uvs[source * 2]);\n uvs[vertex * 2 + 1] = mapV(template.uvs[source * 2 + 1]);\n uvBounds[vertex * 4] = mapU(template.uvBounds[source * 4]);\n uvBounds[vertex * 4 + 1] = mapV(template.uvBounds[source * 4 + 1]);\n uvBounds[vertex * 4 + 2] = mapU(template.uvBounds[source * 4 + 2]);\n uvBounds[vertex * 4 + 3] = mapV(template.uvBounds[source * 4 + 3]);\n const factor = brightness * (ambientMask ? cornerBrightness![corner] : 1);\n colors[vertex * 3] = (tint === undefined ? template.colors[source * 3] : biomeTints![tint]) * factor;\n colors[vertex * 3 + 1] = (tint === undefined ? template.colors[source * 3 + 1] : biomeTints![tint + 1]) * factor;\n colors[vertex * 3 + 2] = (tint === undefined ? template.colors[source * 3 + 2] : biomeTints![tint + 2]) * factor;\n }\n for (let corner = 0; corner < 6; corner++) outputIndices[indexOffset++] = start + template.indices[quad * 6 + corner];\n }\n }\n for (const { quads, x, y, z, data, tint } of page.fluids) {\n const atlas = atlases[data.atlas];\n const placement = page.placements[0];\n const mapU = (u: number) => (placement.x + u * atlas.width) / page.width;\n const mapV = (v: number) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;\n const lightIndex = (y + 1) * 324 + (z + 1) * 18 + x + 1;\n for (let quad = 0; quad < quads.sprites.length; quad++) {\n blockIndices[indexOffset / 6] = x + z * 16 + y * 256;\n const rect = quads.sprites[quad] === 0 ? data.still : data.flow;\n const brightness = light ? lightBrightness(fluidLightLevel(light[lightIndex],\n light[lightIndex + (quads.normals[quad * 12 + 1] < 0 ? -324 : 324)]), ambientLight) : 1;\n const start = vertex;\n for (let corner = 0; corner < 4; corner++, vertex++) {\n const source = quad * 4 + corner;\n positions[vertex * 3] = quads.positions[source * 3] + x * 16;\n positions[vertex * 3 + 1] = quads.positions[source * 3 + 1] + y * 16;\n positions[vertex * 3 + 2] = quads.positions[source * 3 + 2] + z * 16;\n normals[vertex * 3] = quads.normals[source * 3];\n normals[vertex * 3 + 1] = quads.normals[source * 3 + 1];\n normals[vertex * 3 + 2] = quads.normals[source * 3 + 2];\n uvs[vertex * 2] = mapU((rect[0] + quads.uvs[source * 2] * rect[2]) / atlas.width);\n uvs[vertex * 2 + 1] = mapV(1 - (rect[1] + (1 - quads.uvs[source * 2 + 1]) * rect[3]) / atlas.height);\n uvBounds.set([mapU(rect[0] / atlas.width), mapV(1 - (rect[1] + rect[3]) / atlas.height),\n mapU((rect[0] + rect[2]) / atlas.width), mapV(1 - rect[1] / atlas.height)], vertex * 4);\n colors[vertex * 3] = tint[0] * brightness;\n colors[vertex * 3 + 1] = tint[1] * brightness;\n colors[vertex * 3 + 2] = tint[2] * brightness;\n }\n outputIndices.set([start, start + 1, start + 2, start, start + 2, start + 3], indexOffset);\n indexOffset += 6;\n }\n }\n return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, shade, indices: outputIndices, blockIndices };\n });\n}\n\n/** Returns the buffers behind each page's typed arrays for transfer to another thread. */\nexport function sectionGeometryTransferables(pages: readonly SectionGeometryPage[]): ArrayBuffer[] {\n return pages.flatMap(page => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.shade.buffer, page.indices.buffer, page.blockIndices.buffer]);\n}\n","import { buildSectionGeometry, sectionGeometryTransferables, SectionGeometryInput } from \"../../world/SectionGeometry\";\n\naddEventListener(\"message\", (event: MessageEvent<{ id: number; type: \"build\"; input: SectionGeometryInput }>) => {\n const { id, input } = event.data;\n try {\n const pages = buildSectionGeometry(input);\n postMessage({ id, type: \"pages\", pages }, { transfer: sectionGeometryTransferables(pages) });\n } catch (error) {\n postMessage({ id, type: \"error\", message: error instanceof Error ? error.message : String(error) });\n }\n});\n"],"mappings":"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","names":["cornerBrightness","page"]}
|
|
@@ -8,6 +8,7 @@ async function layoutGuiText(text, options = {}) {
|
|
|
8
8
|
}
|
|
9
9
|
const font = await Fonts.get(options.font);
|
|
10
10
|
const runs = typeof text === "string" ? [{ text }] : text;
|
|
11
|
+
await font.resolve?.(runs.map((run) => run.text).join(""));
|
|
11
12
|
const glyphs = [], lineWidths = [];
|
|
12
13
|
let line = [], width = 0;
|
|
13
14
|
let trailingNewline = false;
|
|
@@ -34,7 +35,7 @@ async function layoutGuiText(text, options = {}) {
|
|
|
34
35
|
continue;
|
|
35
36
|
}
|
|
36
37
|
const glyph = font.glyphs.get(character);
|
|
37
|
-
const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
|
|
38
|
+
const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);
|
|
38
39
|
line.push({ character, glyph, advance, style, x: 0, y: 0 });
|
|
39
40
|
width += advance;
|
|
40
41
|
while (width > maxWidth && line.length > 1) {
|
|
@@ -62,7 +63,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
62
63
|
batches.push(batch);
|
|
63
64
|
}
|
|
64
65
|
const color = new Color(isShadow ? (style.color & 16579836) >> 2 : style.color);
|
|
65
|
-
const offset = isShadow ? 1 : 0;
|
|
66
|
+
const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;
|
|
66
67
|
const top = glyph ? 7 - glyph.ascent : 0;
|
|
67
68
|
const height = glyph ? glyph.height * glyph.scale : 8;
|
|
68
69
|
const width = glyph ? glyph.width * glyph.scale : 5;
|
|
@@ -92,7 +93,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
92
93
|
for (let i = 0; i < 4; i++) batch.colors.push(color.r, color.g, color.b);
|
|
93
94
|
batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
|
|
94
95
|
};
|
|
95
|
-
for (const boldOffset of style.bold ? [0, 1] : [0]) {
|
|
96
|
+
for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {
|
|
96
97
|
if (glyph) quad(0, top, width, top + height, boldOffset);
|
|
97
98
|
else {
|
|
98
99
|
quad(0, 0, 5, 1, boldOffset);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/gui/GuiText.ts"],"sourcesContent":["import { BufferGeometry, Color, Float32BufferAttribute } from \"three\";\nimport type { AssetKey } from \"../assets/AssetKey\";\nimport { Fonts, type BitmapGlyph } from \"../assets/Fonts\";\nimport type { CompatCanvas } from \"../canvas/CanvasCompat\";\n\n/** Text appearance set on a GUI text layer or overridden by an individual text run. */\nexport interface GuiTextStyle {\n /** sRGB 0xRRGGBB; defaults to white. */\n color?: number;\n bold?: boolean;\n italic?: boolean;\n}\n\n/** A text segment with optional style overrides within {@link GuiText}. */\nexport interface GuiTextRun extends GuiTextStyle {\n text: string;\n}\n\n/** Literal text, or styled runs. Newlines are preserved. */\nexport type GuiText = string | readonly GuiTextRun[];\n\n/** Text layout settings set on a GUI text layer or passed to {@link layoutGuiText}. */\nexport interface GuiTextOptions extends GuiTextStyle {\n /** Font resource ID; defaults to minecraft:default. */\n font?: AssetKey | string;\n /** Draws a one-pixel shadow; defaults to true. */\n shadow?: boolean;\n /** Wrap width in GUI pixels. Long words break at glyph boundaries. */\n maxWidth?: number;\n /** Distance between line origins; defaults to 9 GUI pixels. */\n lineHeight?: number;\n}\n\n/** One measured glyph and its position in GUI pixels, produced by {@link layoutGuiText}. */\nexport interface PositionedGuiGlyph {\n character: string;\n glyph?: BitmapGlyph;\n x: number;\n y: number;\n advance: number;\n style: Required<GuiTextStyle>;\n}\n\n/** Measured glyphs, line widths, and overall dimensions in GUI pixels. */\nexport interface GuiTextLayout {\n glyphs: PositionedGuiGlyph[];\n lineWidths: number[];\n width: number;\n height: number;\n}\n\n/** Measures and wraps text using the same glyph advances used for rendering. */\nexport async function layoutGuiText(text: GuiText, options: GuiTextOptions = {}): Promise<GuiTextLayout> {\n const maxWidth = options.maxWidth ?? Infinity, lineHeight = options.lineHeight ?? 9;\n if (!(maxWidth > 0) || !Number.isFinite(lineHeight) || lineHeight <= 0) {\n throw new Error(\"Text wrap width and line height must be positive\");\n }\n const font = await Fonts.get(options.font);\n const runs = typeof text === \"string\" ? [{ text }] : text;\n const glyphs: PositionedGuiGlyph[] = [], lineWidths: number[] = [];\n let line: PositionedGuiGlyph[] = [], width = 0;\n let trailingNewline = false;\n const finishLine = (entries: PositionedGuiGlyph[]) => {\n let x = 0;\n for (const entry of entries) {\n glyphs.push({ ...entry, x, y: lineWidths.length * lineHeight });\n x += entry.advance;\n }\n lineWidths.push(x);\n };\n for (const run of runs) {\n const style = { color: run.color ?? options.color ?? 0xffffff,\n bold: run.bold ?? options.bold ?? false, italic: run.italic ?? options.italic ?? false };\n for (const character of run.text.replace(/\\r\\n?/g, \"\\n\")) {\n trailingNewline = character === \"\\n\";\n if (character === \"\\n\") {\n finishLine(line); line = []; width = 0;\n continue;\n }\n const glyph = font.glyphs.get(character);\n const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);\n line.push({ character, glyph, advance, style, x: 0, y: 0 });\n width += advance;\n while (width > maxWidth && line.length > 1) {\n let space = -1;\n for (let i = 0; i < line.length; i++) if (line[i].character === \" \") space = i;\n const split = space >= 0 ? space : line.length - 1;\n if (split > 0) finishLine(line.slice(0, split));\n line = line.slice(split + (space >= 0 ? 1 : 0));\n width = line.reduce((sum, entry) => sum + entry.advance, 0);\n }\n }\n }\n if (line.length || !lineWidths.length || trailingNewline) finishLine(line);\n return { glyphs, lineWidths, width: Math.max(0, ...lineWidths), height: lineWidths.length * lineHeight };\n}\n\n/** Creates glyph batches in painter order. Unsupported characters use an outlined missing glyph. */\nexport function createGuiTextGeometry(layout: GuiTextLayout, shadow = true): { image?: CompatCanvas; geometry: BufferGeometry }[] {\n interface Batch { image?: CompatCanvas; positions: number[]; uvs: number[]; colors: number[]; indices: number[]; }\n const batches: Batch[] = [];\n for (const isShadow of shadow ? [true, false] : [false]) {\n let batch: Batch | undefined;\n for (const entry of layout.glyphs) {\n const { glyph, style } = entry;\n if (glyph && !glyph.image) continue;\n if (!batch || batch.image !== glyph?.image) {\n batch = { image: glyph?.image, positions: [], uvs: [], colors: [], indices: [] };\n batches.push(batch);\n }\n const color = new Color(isShadow ? (style.color & 0xfcfcfc) >> 2 : style.color);\n const offset = isShadow ? 1 : 0;\n const top = glyph ? 7 - glyph.ascent : 0;\n const height = glyph ? glyph.height * glyph.scale : 8;\n const width = glyph ? glyph.width * glyph.scale : 5;\n const shear = (y: number) => style.italic ? 1 - 0.25 * y : 0;\n const quad = (left: number, upper: number, right: number, lower: number, boldOffset: number) => {\n const base = batch!.positions.length / 3;\n const x = entry.x + offset + boldOffset, y = entry.y + offset;\n batch!.positions.push(x + left + shear(upper), -y - upper, 0, x + right + shear(upper), -y - upper, 0,\n x + left + shear(lower), -y - lower, 0, x + right + shear(lower), -y - lower, 0);\n const u0 = glyph ? glyph.x / glyph.image!.width : 0;\n const u1 = glyph ? (glyph.x + glyph.width) / glyph.image!.width : 1;\n const v0 = glyph ? 1 - glyph.y / glyph.image!.height : 1;\n const v1 = glyph ? 1 - (glyph.y + glyph.height) / glyph.image!.height : 0;\n batch!.uvs.push(u0, v0, u1, v0, u0, v1, u1, v1);\n for (let i = 0; i < 4; i++) batch!.colors.push(color.r, color.g, color.b);\n batch!.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);\n };\n for (const boldOffset of style.bold ? [0, 1] : [0]) {\n if (glyph) quad(0, top, width, top + height, boldOffset);\n else {\n quad(0, 0, 5, 1, boldOffset); quad(0, 7, 5, 8, boldOffset);\n quad(0, 1, 1, 7, boldOffset); quad(4, 1, 5, 7, boldOffset);\n }\n }\n }\n }\n return batches.map(({ image, positions, uvs, colors, indices }) => ({ image, geometry: new BufferGeometry()\n .setAttribute(\"position\", new Float32BufferAttribute(positions, 3))\n .setAttribute(\"uv\", new Float32BufferAttribute(uvs, 2))\n .setAttribute(\"color\", new Float32BufferAttribute(colors, 3))\n .setIndex(indices) }));\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/gui/GuiText.ts"],"sourcesContent":["import { BufferGeometry, Color, Float32BufferAttribute } from \"three\";\nimport type { AssetKey } from \"../assets/AssetKey\";\nimport { Fonts, type BitmapGlyph } from \"../assets/Fonts\";\nimport type { CompatCanvas } from \"../canvas/CanvasCompat\";\n\n/** Text appearance set on a GUI text layer or overridden by an individual text run. */\nexport interface GuiTextStyle {\n /** sRGB 0xRRGGBB; defaults to white. */\n color?: number;\n bold?: boolean;\n italic?: boolean;\n}\n\n/** A text segment with optional style overrides within {@link GuiText}. */\nexport interface GuiTextRun extends GuiTextStyle {\n text: string;\n}\n\n/** Literal text, or styled runs. Newlines are preserved. */\nexport type GuiText = string | readonly GuiTextRun[];\n\n/** Text layout settings set on a GUI text layer or passed to {@link layoutGuiText}. */\nexport interface GuiTextOptions extends GuiTextStyle {\n /** Font resource ID; defaults to minecraft:default. */\n font?: AssetKey | string;\n /** Draws a one-pixel shadow; defaults to true. */\n shadow?: boolean;\n /** Wrap width in GUI pixels. Long words break at glyph boundaries. */\n maxWidth?: number;\n /** Distance between line origins; defaults to 9 GUI pixels. */\n lineHeight?: number;\n}\n\n/** One measured glyph and its position in GUI pixels, produced by {@link layoutGuiText}. */\nexport interface PositionedGuiGlyph {\n character: string;\n glyph?: BitmapGlyph;\n x: number;\n y: number;\n advance: number;\n style: Required<GuiTextStyle>;\n}\n\n/** Measured glyphs, line widths, and overall dimensions in GUI pixels. */\nexport interface GuiTextLayout {\n glyphs: PositionedGuiGlyph[];\n lineWidths: number[];\n width: number;\n height: number;\n}\n\n/** Measures and wraps text using the same glyph advances used for rendering. */\nexport async function layoutGuiText(text: GuiText, options: GuiTextOptions = {}): Promise<GuiTextLayout> {\n const maxWidth = options.maxWidth ?? Infinity, lineHeight = options.lineHeight ?? 9;\n if (!(maxWidth > 0) || !Number.isFinite(lineHeight) || lineHeight <= 0) {\n throw new Error(\"Text wrap width and line height must be positive\");\n }\n const font = await Fonts.get(options.font);\n const runs = typeof text === \"string\" ? [{ text }] : text;\n await font.resolve?.(runs.map(run => run.text).join(\"\"));\n const glyphs: PositionedGuiGlyph[] = [], lineWidths: number[] = [];\n let line: PositionedGuiGlyph[] = [], width = 0;\n let trailingNewline = false;\n const finishLine = (entries: PositionedGuiGlyph[]) => {\n let x = 0;\n for (const entry of entries) {\n glyphs.push({ ...entry, x, y: lineWidths.length * lineHeight });\n x += entry.advance;\n }\n lineWidths.push(x);\n };\n for (const run of runs) {\n const style = { color: run.color ?? options.color ?? 0xffffff,\n bold: run.bold ?? options.bold ?? false, italic: run.italic ?? options.italic ?? false };\n for (const character of run.text.replace(/\\r\\n?/g, \"\\n\")) {\n trailingNewline = character === \"\\n\";\n if (character === \"\\n\") {\n finishLine(line); line = []; width = 0;\n continue;\n }\n const glyph = font.glyphs.get(character);\n const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);\n line.push({ character, glyph, advance, style, x: 0, y: 0 });\n width += advance;\n while (width > maxWidth && line.length > 1) {\n let space = -1;\n for (let i = 0; i < line.length; i++) if (line[i].character === \" \") space = i;\n const split = space >= 0 ? space : line.length - 1;\n if (split > 0) finishLine(line.slice(0, split));\n line = line.slice(split + (space >= 0 ? 1 : 0));\n width = line.reduce((sum, entry) => sum + entry.advance, 0);\n }\n }\n }\n if (line.length || !lineWidths.length || trailingNewline) finishLine(line);\n return { glyphs, lineWidths, width: Math.max(0, ...lineWidths), height: lineWidths.length * lineHeight };\n}\n\n/** Creates glyph batches in painter order. Unsupported characters use an outlined missing glyph. */\nexport function createGuiTextGeometry(layout: GuiTextLayout, shadow = true): { image?: CompatCanvas; geometry: BufferGeometry }[] {\n interface Batch { image?: CompatCanvas; positions: number[]; uvs: number[]; colors: number[]; indices: number[]; }\n const batches: Batch[] = [];\n for (const isShadow of shadow ? [true, false] : [false]) {\n let batch: Batch | undefined;\n for (const entry of layout.glyphs) {\n const { glyph, style } = entry;\n if (glyph && !glyph.image) continue;\n if (!batch || batch.image !== glyph?.image) {\n batch = { image: glyph?.image, positions: [], uvs: [], colors: [], indices: [] };\n batches.push(batch);\n }\n const color = new Color(isShadow ? (style.color & 0xfcfcfc) >> 2 : style.color);\n const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;\n const top = glyph ? 7 - glyph.ascent : 0;\n const height = glyph ? glyph.height * glyph.scale : 8;\n const width = glyph ? glyph.width * glyph.scale : 5;\n const shear = (y: number) => style.italic ? 1 - 0.25 * y : 0;\n const quad = (left: number, upper: number, right: number, lower: number, boldOffset: number) => {\n const base = batch!.positions.length / 3;\n const x = entry.x + offset + boldOffset, y = entry.y + offset;\n batch!.positions.push(x + left + shear(upper), -y - upper, 0, x + right + shear(upper), -y - upper, 0,\n x + left + shear(lower), -y - lower, 0, x + right + shear(lower), -y - lower, 0);\n const u0 = glyph ? glyph.x / glyph.image!.width : 0;\n const u1 = glyph ? (glyph.x + glyph.width) / glyph.image!.width : 1;\n const v0 = glyph ? 1 - glyph.y / glyph.image!.height : 1;\n const v1 = glyph ? 1 - (glyph.y + glyph.height) / glyph.image!.height : 0;\n batch!.uvs.push(u0, v0, u1, v0, u0, v1, u1, v1);\n for (let i = 0; i < 4; i++) batch!.colors.push(color.r, color.g, color.b);\n batch!.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);\n };\n for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {\n if (glyph) quad(0, top, width, top + height, boldOffset);\n else {\n quad(0, 0, 5, 1, boldOffset); quad(0, 7, 5, 8, boldOffset);\n quad(0, 1, 1, 7, boldOffset); quad(4, 1, 5, 7, boldOffset);\n }\n }\n }\n }\n return batches.map(({ image, positions, uvs, colors, indices }) => ({ image, geometry: new BufferGeometry()\n .setAttribute(\"position\", new Float32BufferAttribute(positions, 3))\n .setAttribute(\"uv\", new Float32BufferAttribute(uvs, 2))\n .setAttribute(\"color\", new Float32BufferAttribute(colors, 3))\n .setIndex(indices) }));\n}\n"],"mappings":";AAAA,SAAS,gBAAgB,OAAO,8BAA8B;AAE9D,SAAS,aAA+B;AAkDxC,eAAsB,cAAc,MAAe,UAA0B,CAAC,GAA2B;AACrG,QAAM,WAAW,QAAQ,YAAY,UAAU,aAAa,QAAQ,cAAc;AAClF,MAAI,EAAE,WAAW,MAAM,CAAC,OAAO,SAAS,UAAU,KAAK,cAAc,GAAG;AACpE,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACtE;AACA,QAAM,OAAO,MAAM,MAAM,IAAI,QAAQ,IAAI;AACzC,QAAM,OAAO,OAAO,SAAS,WAAW,CAAC,EAAE,KAAK,CAAC,IAAI;AACrD,QAAM,KAAK,UAAU,KAAK,IAAI,SAAO,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC;AACvD,QAAM,SAA+B,CAAC,GAAG,aAAuB,CAAC;AACjE,MAAI,OAA6B,CAAC,GAAG,QAAQ;AAC7C,MAAI,kBAAkB;AACtB,QAAM,aAAa,CAAC,YAAkC;AAClD,QAAI,IAAI;AACR,eAAW,SAAS,SAAS;AACzB,aAAO,KAAK,EAAE,GAAG,OAAO,GAAG,GAAG,WAAW,SAAS,WAAW,CAAC;AAC9D,WAAK,MAAM;AAAA,IACf;AACA,eAAW,KAAK,CAAC;AAAA,EACrB;AACA,aAAW,OAAO,MAAM;AACpB,UAAM,QAAQ;AAAA,MAAE,OAAO,IAAI,SAAS,QAAQ,SAAS;AAAA,MACjD,MAAM,IAAI,QAAQ,QAAQ,QAAQ;AAAA,MAAO,QAAQ,IAAI,UAAU,QAAQ,UAAU;AAAA,IAAM;AAC3F,eAAW,aAAa,IAAI,KAAK,QAAQ,UAAU,IAAI,GAAG;AACtD,wBAAkB,cAAc;AAChC,UAAI,cAAc,MAAM;AACpB,mBAAW,IAAI;AAAG,eAAO,CAAC;AAAG,gBAAQ;AACrC;AAAA,MACJ;AACA,YAAM,QAAQ,KAAK,OAAO,IAAI,SAAS;AACvC,YAAM,WAAW,OAAO,WAAW,MAAM,MAAM,OAAO,OAAO,cAAc,IAAI;AAC/E,WAAK,KAAK,EAAE,WAAW,OAAO,SAAS,OAAO,GAAG,GAAG,GAAG,EAAE,CAAC;AAC1D,eAAS;AACT,aAAO,QAAQ,YAAY,KAAK,SAAS,GAAG;AACxC,YAAI,QAAQ;AACZ,iBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,IAAK,KAAI,KAAK,CAAC,EAAE,cAAc,IAAK,SAAQ;AAC7E,cAAM,QAAQ,SAAS,IAAI,QAAQ,KAAK,SAAS;AACjD,YAAI,QAAQ,EAAG,YAAW,KAAK,MAAM,GAAG,KAAK,CAAC;AAC9C,eAAO,KAAK,MAAM,SAAS,SAAS,IAAI,IAAI,EAAE;AAC9C,gBAAQ,KAAK,OAAO,CAAC,KAAK,UAAU,MAAM,MAAM,SAAS,CAAC;AAAA,MAC9D;AAAA,IACJ;AAAA,EACJ;AACA,MAAI,KAAK,UAAU,CAAC,WAAW,UAAU,gBAAiB,YAAW,IAAI;AACzE,SAAO,EAAE,QAAQ,YAAY,OAAO,KAAK,IAAI,GAAG,GAAG,UAAU,GAAG,QAAQ,WAAW,SAAS,WAAW;AAC3G;AAGO,SAAS,sBAAsB,QAAuB,SAAS,MAA4D;AAE9H,QAAM,UAAmB,CAAC;AAC1B,aAAW,YAAY,SAAS,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG;AACrD,QAAI;AACJ,eAAW,SAAS,OAAO,QAAQ;AAC/B,YAAM,EAAE,OAAO,MAAM,IAAI;AACzB,UAAI,SAAS,CAAC,MAAM,MAAO;AAC3B,UAAI,CAAC,SAAS,MAAM,UAAU,OAAO,OAAO;AACxC,gBAAQ,EAAE,OAAO,OAAO,OAAO,WAAW,CAAC,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC,GAAG,SAAS,CAAC,EAAE;AAC/E,gBAAQ,KAAK,KAAK;AAAA,MACtB;AACA,YAAM,QAAQ,IAAI,MAAM,YAAY,MAAM,QAAQ,aAAa,IAAI,MAAM,KAAK;AAC9E,YAAM,SAAS,WAAW,OAAO,gBAAgB,IAAI;AACrD,YAAM,MAAM,QAAQ,IAAI,MAAM,SAAS;AACvC,YAAM,SAAS,QAAQ,MAAM,SAAS,MAAM,QAAQ;AACpD,YAAM,QAAQ,QAAQ,MAAM,QAAQ,MAAM,QAAQ;AAClD,YAAM,QAAQ,CAAC,MAAc,MAAM,SAAS,IAAI,OAAO,IAAI;AAC3D,YAAM,OAAO,CAAC,MAAc,OAAe,OAAe,OAAe,eAAuB;AAC5F,cAAM,OAAO,MAAO,UAAU,SAAS;AACvC,cAAM,IAAI,MAAM,IAAI,SAAS,YAAY,IAAI,MAAM,IAAI;AACvD,cAAO,UAAU;AAAA,UAAK,IAAI,OAAO,MAAM,KAAK;AAAA,UAAG,CAAC,IAAI;AAAA,UAAO;AAAA,UAAG,IAAI,QAAQ,MAAM,KAAK;AAAA,UAAG,CAAC,IAAI;AAAA,UAAO;AAAA,UAChG,IAAI,OAAO,MAAM,KAAK;AAAA,UAAG,CAAC,IAAI;AAAA,UAAO;AAAA,UAAG,IAAI,QAAQ,MAAM,KAAK;AAAA,UAAG,CAAC,IAAI;AAAA,UAAO;AAAA,QAAC;AACnF,cAAM,KAAK,QAAQ,MAAM,IAAI,MAAM,MAAO,QAAQ;AAClD,cAAM,KAAK,SAAS,MAAM,IAAI,MAAM,SAAS,MAAM,MAAO,QAAQ;AAClE,cAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,MAAM,MAAO,SAAS;AACvD,cAAM,KAAK,QAAQ,KAAK,MAAM,IAAI,MAAM,UAAU,MAAM,MAAO,SAAS;AACxE,cAAO,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;AAC9C,iBAAS,IAAI,GAAG,IAAI,GAAG,IAAK,OAAO,OAAO,KAAK,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AACxE,cAAO,QAAQ,KAAK,MAAM,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAAA,MAC9E;AACA,iBAAW,cAAc,MAAM,OAAO,CAAC,GAAG,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,GAAG;AACrE,YAAI,MAAO,MAAK,GAAG,KAAK,OAAO,MAAM,QAAQ,UAAU;AAAA,aAClD;AACD,eAAK,GAAG,GAAG,GAAG,GAAG,UAAU;AAAG,eAAK,GAAG,GAAG,GAAG,GAAG,UAAU;AACzD,eAAK,GAAG,GAAG,GAAG,GAAG,UAAU;AAAG,eAAK,GAAG,GAAG,GAAG,GAAG,UAAU;AAAA,QAC7D;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AACA,SAAO,QAAQ,IAAI,CAAC,EAAE,OAAO,WAAW,KAAK,QAAQ,QAAQ,OAAO,EAAE,OAAO,UAAU,IAAI,eAAe,EACrG,aAAa,YAAY,IAAI,uBAAuB,WAAW,CAAC,CAAC,EACjE,aAAa,MAAM,IAAI,uBAAuB,KAAK,CAAC,CAAC,EACrD,aAAa,SAAS,IAAI,uBAAuB,QAAQ,CAAC,CAAC,EAC3D,SAAS,OAAO,EAAE,EAAE;AAC7B;","names":[]}
|
|
@@ -962,7 +962,8 @@ declare enum AssetParser {
|
|
|
962
962
|
NBT = "nbt",
|
|
963
963
|
IMAGE = "image",
|
|
964
964
|
LIST = "list",
|
|
965
|
-
JSON = "json"
|
|
965
|
+
JSON = "json",
|
|
966
|
+
BINARY = "binary"
|
|
966
967
|
}
|
|
967
968
|
|
|
968
969
|
/** An asset provider registered with {@link AssetLoader.addSource}. */
|
|
@@ -1280,14 +1281,20 @@ interface BitmapGlyph {
|
|
|
1280
1281
|
scale: number;
|
|
1281
1282
|
ascent: number;
|
|
1282
1283
|
advance: number;
|
|
1284
|
+
/** Extra advance and drawing offset for bold text, in GUI pixels. Defaults to 1. */
|
|
1285
|
+
boldOffset?: number;
|
|
1286
|
+
/** Shadow displacement in GUI pixels. Defaults to 1. */
|
|
1287
|
+
shadowOffset?: number;
|
|
1283
1288
|
}
|
|
1284
1289
|
/** Character-to-glyph lookup assembled from the active resource-pack fonts. */
|
|
1285
1290
|
interface BitmapFont {
|
|
1286
1291
|
glyphs: Map<string, BitmapGlyph>;
|
|
1292
|
+
/** Resolves characters through the font providers before measuring or drawing them. */
|
|
1293
|
+
resolve?(characters: string): Promise<void>;
|
|
1287
1294
|
}
|
|
1288
|
-
/** Loads Minecraft bitmap, space, and reference font providers for GUI text. */
|
|
1295
|
+
/** Loads Minecraft bitmap, Unihex, space, and reference font providers for GUI text. */
|
|
1289
1296
|
declare class Fonts {
|
|
1290
|
-
/** Combines font definitions in source-priority order.
|
|
1297
|
+
/** Combines font definitions in source-priority order. TrueType providers are skipped. */
|
|
1291
1298
|
static get(key?: AssetKey | string): Promise<BitmapFont>;
|
|
1292
1299
|
private static relatedKey;
|
|
1293
1300
|
private static load;
|
|
@@ -2514,6 +2521,7 @@ declare class HostedAssetSource extends AssetSource {
|
|
|
2514
2521
|
static readonly IMAGE: ResponseParser<TextureAsset>;
|
|
2515
2522
|
static readonly LIST: ResponseParser<ListAsset>;
|
|
2516
2523
|
static readonly JSON: ResponseParser<any>;
|
|
2524
|
+
static readonly BINARY: ResponseParser<BinaryAsset>;
|
|
2517
2525
|
static readonly PARSER_MAP: Map<AssetParser, ResponseParser<any>>;
|
|
2518
2526
|
/** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */
|
|
2519
2527
|
loadOrRetryWithDefaults<T extends MinecraftAsset>(key: AssetKey, parser: ResponseParser<T>): Promise<Maybe<T>>;
|
|
@@ -2534,6 +2542,10 @@ declare class HostedAssetSource extends AssetSource {
|
|
|
2534
2542
|
interface HostedAssetSourceOptions {
|
|
2535
2543
|
retryDefaults: boolean;
|
|
2536
2544
|
}
|
|
2545
|
+
/** Encoded asset bytes loaded without JSON or image decoding. */
|
|
2546
|
+
interface BinaryAsset extends MinecraftAsset {
|
|
2547
|
+
data: Uint8Array;
|
|
2548
|
+
}
|
|
2537
2549
|
|
|
2538
2550
|
/** A resource-pack ZIP entry, with its archive-relative path and lazily extracted bytes. */
|
|
2539
2551
|
interface ArchiveEntry {
|
|
@@ -2671,6 +2683,12 @@ interface BedrockGeometryFile {
|
|
|
2671
2683
|
[key: string]: BedrockGeometry | any;
|
|
2672
2684
|
}
|
|
2673
2685
|
|
|
2686
|
+
interface UnihexFile {
|
|
2687
|
+
indices: Int32Array;
|
|
2688
|
+
rows: Uint32Array;
|
|
2689
|
+
metrics: Uint8Array;
|
|
2690
|
+
}
|
|
2691
|
+
|
|
2674
2692
|
/** Shared in-memory caches for loaded assets and render resources. Persistent stores are managed separately. */
|
|
2675
2693
|
declare class Caching {
|
|
2676
2694
|
private static _generation;
|
|
@@ -2696,6 +2714,7 @@ declare class Caching {
|
|
|
2696
2714
|
static readonly entityTextureCache: AsyncLoadingCache<CacheKey, AssetKey>;
|
|
2697
2715
|
static readonly entityAnimationCache: AsyncLoadingCache<CacheKey, EntityAnimationFile>;
|
|
2698
2716
|
static readonly blockEntityIndexCache: AsyncLoadingCache<CacheKey, BlockEntityIndex>;
|
|
2717
|
+
static readonly unihexCache: AsyncLoadingCache<CacheKey, UnihexFile>;
|
|
2699
2718
|
static readonly fontCache: AsyncLoadingCache<CacheKey, BitmapFont>;
|
|
2700
2719
|
static readonly bannerPatternCache: AsyncLoadingCache<CacheKey, BannerPattern>;
|
|
2701
2720
|
static readonly mineRenderDataCache: AsyncLoadingCache<CacheKey, unknown>;
|
|
@@ -3811,6 +3830,7 @@ interface SectionTemplateData {
|
|
|
3811
3830
|
uvs: Float32Array;
|
|
3812
3831
|
uvBounds: Float32Array;
|
|
3813
3832
|
colors: Float32Array;
|
|
3833
|
+
shade?: Float32Array;
|
|
3814
3834
|
indices: Uint16Array;
|
|
3815
3835
|
cullFaces: Uint8Array;
|
|
3816
3836
|
biomeTint?: Uint8Array;
|
|
@@ -3874,6 +3894,7 @@ interface SectionGeometryPage {
|
|
|
3874
3894
|
uvs: Float32Array;
|
|
3875
3895
|
uvBounds: Float32Array;
|
|
3876
3896
|
colors: Float32Array;
|
|
3897
|
+
shade: Float32Array;
|
|
3877
3898
|
indices: Uint32Array;
|
|
3878
3899
|
/** Owning section cell for each quad; each quad contributes two consecutive triangles. */
|
|
3879
3900
|
blockIndices: Uint16Array;
|
|
@@ -4365,4 +4386,4 @@ declare class BrowserCache extends PersistentCache<LocalForage> {
|
|
|
4365
4386
|
*/
|
|
4366
4387
|
declare function probeImageSize(data: Uint8Array): ImageSizeInfo;
|
|
4367
4388
|
|
|
4368
|
-
export { AXES, type AnimationFrame, type AnimationMeta, type AnimatorFunction, type AnvilChunk, type AnvilEntityChunk, type AnvilExternalChunkReader, type AnvilParseOptions, AnvilParser, type AnvilRegion, type AnvilRegionReader, AnvilWorldSource, type AnvilWorldSourceOptions, ArchiveAssetSource, type ArchiveAssetSourceOptions, type ArchiveEntry, type ArchiveProxy, AssetKey, AssetLoadError, AssetLoader, AssetParser, AssetSource, type AssetType, Assets, Axis, BUILTIN_ENTITY, BUILTIN_GENERATED, type BannerPattern, type BannerPatternDraw, BannerPatterns, BasicAssetKey, type BasicMinecraftAsset, BatchedExecutor, type BedrockBone, type BedrockCube, type BedrockEntityDescription, type BedrockEntityFile, type BedrockGeometry, type BedrockGeometryFile, type Biome, type BiomeColorKind, Biomes, type BitmapFont, type BitmapGlyph, type Block, BlockEntities, type BlockEntityEntry, type BlockEntityIndex, type BlockEntityPart, type BlockEntityRotation, type BlockFluidState, type BlockInfo, type BlockModel, type BlockModelTextures, BlockObject, type BlockObjectOptions, type BlockState, type BlockStateMultipart, type BlockStateProperties, type BlockStateProperty, type BlockStatePropertyDefaults, type BlockStatePropertyValue, BlockStateResolver, type BlockStateVariant, type BlockStateVariants, BlockStates, BlockTints, type BoxGeometryKey, BrowserArchiveProxy, BrowserCache, BrowserEnv, CUBE_FACES, CUBE_FACE_OFFSETS, type CacheKey, Caching, type CameraOptions, CanvasImage, type CapeLayout, Chunk, ChunkData, Colormaps, type CompatCanvas, type CompatImage, type ComposerOptions, type ControlsMode, type ControlsOptions, CubeFace, CubeFaceIndex, DEFAULT_ELEMENTS, DEFAULT_NAMESPACE, DEFAULT_ROOT, DEFAULT_UV, DISPLAY_POSITIONS, DYE_COLORS, type DebugOptions, type DecoratedPotSide, DecoratedPots, type DeepPartial, DefaultBlockStates, DisplayPosition, DisplayTransforms, type Disposable, type DoubleArray, type DyeColor, ENTITY_ANIMATION_CHANNELS, type ElementFace, type ElementRotation, Entities, type EntityAnimation, type EntityAnimationBone, type EntityAnimationChannel, type EntityAnimationFile, type EntityAnimationKeyframe, type EntityAnimationOptions, EntityAnimationPlayer, type EntityAnimationPose, type EntityLayer, type EntityModel, type EntityModelCube, type EntityModelFile, type EntityModelLayer, type EntityModelOptions, type EntityModelPart, type EntityModelPass, EntityObject, type EntityObjectOptions, type EntityRenderMode, type EntityTransformOp, Env, type EnvProvider, type ExtractableImageData, type FluidKind, FluidModelObject, type FluidQuads, type FluidRules, type FluidSample, type FluidSampler, type FlyAction, FlyControls, type FlyControlsEventMap, Fonts, type FrameCallback, type FromTo, GUI_CONTAINER_LAYOUTS, Geometries, type GuiBookButtonState, type GuiBookOptions, type GuiBossBarColor, type GuiBossBarOptions, type GuiContainerType, GuiHelper, type GuiItemLayer, type GuiLayer, GuiLight, GuiObject, type GuiObjectOptions, type GuiRecipe, type GuiRecipeIngredient, type GuiRecipeOptions, type GuiSpriteScaling, type GuiText, type GuiTextLayer, type GuiTextLayout, type GuiTextOptions, type GuiTextRun, type GuiTextStyle, type GuiTextureLayer, type GuiTooltipOptions, HostedAssetSource, type IModelTextures, ITEM_GENERATED, type ImageInfo, ImageLoader, type ImageSizeInfo, InstanceManager, InstanceReference, type Instanceable, ItemDefaults, ItemGlint, type ItemModel, type ItemModelContext, type ItemModelTextures, type ItemTintColor, type ItemTintSource, ItemTints, type ListAsset, LitematicaParser, type LitematicaRegion, type LitematicaStructure, type LoadedSceneDocument, type LoadedSceneObject, MapControls, type MaterialKey, Materials, type Maybe, type MeshKey, Meshes, MineRenderData, type MineRenderDataManifest, type MineRenderDatasets, MineRenderError, MineRenderScene, type MineRenderSceneOptions, MineRenderWorld, type MineRenderWorldOptions, type MinecraftAsset, MinecraftCubeTexture, MinecraftFaceUV, type MinecraftTextureMeta, type Model, ModelCulling, type ModelDisplay, type ModelElement, type ModelFaces, ModelGenerator, ModelMerger, ModelObject, type ModelObjectOptions, ModelTextures, Models, type MultiBlockBlock, type MultiBlockEntity, type MultiBlockStructure, type MultipartCondition, type NBTAsset, NBTHelper, OrbitControls, type PackFormat, PackFormats, PackMetadata, PersistentCache, PlayerHeadTextures, type PositionedGuiGlyph, type QuadArray, type RawImageKey, type RenameKind, Renames, type RenderOptions, Renderer, type RendererControls, type RendererFrame, type RendererOptions, type RendererSurface, type RequestConfig, RequestError, type RequestResponse, Requests, type ResolvedBlockEntity, type ResolvedMineRenderData, type ResponseParser, SCENE_DOCUMENT_MAX_BYTES, SKIN_PARTS, type SavedLightSample, type SceneBlockDefinition, type SceneDocument, SceneDocumentLoader, type SceneEntityDefinition, SceneExporter, type SceneGLTFExportOptions, type SceneGuiDefinition, type SceneGuiLayer, SceneInspector, type SceneItemContext, type SceneModelDefinition, SceneObject, type SceneObjectDefinition, type SceneObjectDefinitionBase, type SceneObjectOptions, type SceneSkinDefinition, type SceneSkinPosePart, SceneStats, SceneStatsDisplay, SchematicParser, type SchematicParserOptions, type SectionAtlasSize, type SectionFluidInput, type SectionFluidKind, type SectionFluids, type SectionGeometryInput, type SectionGeometryPage, type SectionLightData, SectionMesh, type SectionMeshEntry, type SectionMeshTemplate, SectionModels, type SectionTemplateData, SectionWorker, type Serializable, type SkinGeometries, SkinImage, SkinObject, type SkinObjectOptions, SkinPart, type SkinTexture, type SkinTextureCoordinates, SkinTextures, Skins, type SpecialItemPart, type SpecialItemRenderer, SpecialItems, SpongeSchematicParser, type StructureNBT, StructureParser, type TextureAsset, TextureAtlas, type TextureKey, TextureLoader, Textures, Ticker, type TickerFunction, TintColors, type Transformable, type TripleArray, UVMapper, type VideoExportOptions, VideoExporter, type WorldBlockIntersection, type WorldChunkSource, type WorldEntityIntersection, WorldStreamer, type WorldStreamerOptions, WrappedImage, addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation, applyGenericRotation, axisToVec3, base64decode, base64encode, buildFluidQuads, buildSectionGeometry, capeTextureSizes, captureException, changeEvent, clampRotationDegrees, classicSkinGeometries, classicSkinTextureCoordinates, computeMorphedAttributes, copySectionLight, createCanvas, createFluidGeometry, createGuiTextGeometry, createGuiTextureGeometry, createImage, decodeSceneDocument, encodeSceneDocument, entityAnimationTime, estimateBytesUsed, fluidKindOf, getBlockFluidState, getFluidKind, interleaveAttributes, isAssetKey, isBasicAssetKey, isBlockObject, isDisposable, isDoubleArray, isEntityObject, isFlyControls, isGuiObject, isInstanceManager, isInstanceReference, isInstanceable, isInstancedMesh, isMesh, isMineRenderScene, isModelObject, isObject3D, isOrthographicCamera, isPerspectiveCamera, isQuadArray, isResourceLocation, isSceneObject, isTransformable, isTripleArray, isVector3, layoutGuiText, md5, mergeBufferAttributes, mergeBufferGeometries, mergeVertices, parseSceneDocument, prefix, probeImageSize, registerBrowserEnv, resolveBlockFluidState, resolveLegacyBlock, resolveLegacyBlockState, sampleEntityAnimation, sampleEntityKeyframes, sampleFluid, sampleSectionLight, sectionGeometryTransferables, serializeBoxGeometryKey, serializeImageKey, serializeMaterialKey, serializeMeshKey, serializeTextureKey, sha1, sha256, sha512, shutdown, sleep, slimSkinGeometries, slimSkinTextureCoordinates, timingEnd, timingStart, toDegrees, toRadians, toTrianglesDrawMode, trimCanvas, validateAnimationWeights, yieldToEventLoop };
|
|
4389
|
+
export { AXES, type AnimationFrame, type AnimationMeta, type AnimatorFunction, type AnvilChunk, type AnvilEntityChunk, type AnvilExternalChunkReader, type AnvilParseOptions, AnvilParser, type AnvilRegion, type AnvilRegionReader, AnvilWorldSource, type AnvilWorldSourceOptions, ArchiveAssetSource, type ArchiveAssetSourceOptions, type ArchiveEntry, type ArchiveProxy, AssetKey, AssetLoadError, AssetLoader, AssetParser, AssetSource, type AssetType, Assets, Axis, BUILTIN_ENTITY, BUILTIN_GENERATED, type BannerPattern, type BannerPatternDraw, BannerPatterns, BasicAssetKey, type BasicMinecraftAsset, BatchedExecutor, type BedrockBone, type BedrockCube, type BedrockEntityDescription, type BedrockEntityFile, type BedrockGeometry, type BedrockGeometryFile, type BinaryAsset, type Biome, type BiomeColorKind, Biomes, type BitmapFont, type BitmapGlyph, type Block, BlockEntities, type BlockEntityEntry, type BlockEntityIndex, type BlockEntityPart, type BlockEntityRotation, type BlockFluidState, type BlockInfo, type BlockModel, type BlockModelTextures, BlockObject, type BlockObjectOptions, type BlockState, type BlockStateMultipart, type BlockStateProperties, type BlockStateProperty, type BlockStatePropertyDefaults, type BlockStatePropertyValue, BlockStateResolver, type BlockStateVariant, type BlockStateVariants, BlockStates, BlockTints, type BoxGeometryKey, BrowserArchiveProxy, BrowserCache, BrowserEnv, CUBE_FACES, CUBE_FACE_OFFSETS, type CacheKey, Caching, type CameraOptions, CanvasImage, type CapeLayout, Chunk, ChunkData, Colormaps, type CompatCanvas, type CompatImage, type ComposerOptions, type ControlsMode, type ControlsOptions, CubeFace, CubeFaceIndex, DEFAULT_ELEMENTS, DEFAULT_NAMESPACE, DEFAULT_ROOT, DEFAULT_UV, DISPLAY_POSITIONS, DYE_COLORS, type DebugOptions, type DecoratedPotSide, DecoratedPots, type DeepPartial, DefaultBlockStates, DisplayPosition, DisplayTransforms, type Disposable, type DoubleArray, type DyeColor, ENTITY_ANIMATION_CHANNELS, type ElementFace, type ElementRotation, Entities, type EntityAnimation, type EntityAnimationBone, type EntityAnimationChannel, type EntityAnimationFile, type EntityAnimationKeyframe, type EntityAnimationOptions, EntityAnimationPlayer, type EntityAnimationPose, type EntityLayer, type EntityModel, type EntityModelCube, type EntityModelFile, type EntityModelLayer, type EntityModelOptions, type EntityModelPart, type EntityModelPass, EntityObject, type EntityObjectOptions, type EntityRenderMode, type EntityTransformOp, Env, type EnvProvider, type ExtractableImageData, type FluidKind, FluidModelObject, type FluidQuads, type FluidRules, type FluidSample, type FluidSampler, type FlyAction, FlyControls, type FlyControlsEventMap, Fonts, type FrameCallback, type FromTo, GUI_CONTAINER_LAYOUTS, Geometries, type GuiBookButtonState, type GuiBookOptions, type GuiBossBarColor, type GuiBossBarOptions, type GuiContainerType, GuiHelper, type GuiItemLayer, type GuiLayer, GuiLight, GuiObject, type GuiObjectOptions, type GuiRecipe, type GuiRecipeIngredient, type GuiRecipeOptions, type GuiSpriteScaling, type GuiText, type GuiTextLayer, type GuiTextLayout, type GuiTextOptions, type GuiTextRun, type GuiTextStyle, type GuiTextureLayer, type GuiTooltipOptions, HostedAssetSource, type IModelTextures, ITEM_GENERATED, type ImageInfo, ImageLoader, type ImageSizeInfo, InstanceManager, InstanceReference, type Instanceable, ItemDefaults, ItemGlint, type ItemModel, type ItemModelContext, type ItemModelTextures, type ItemTintColor, type ItemTintSource, ItemTints, type ListAsset, LitematicaParser, type LitematicaRegion, type LitematicaStructure, type LoadedSceneDocument, type LoadedSceneObject, MapControls, type MaterialKey, Materials, type Maybe, type MeshKey, Meshes, MineRenderData, type MineRenderDataManifest, type MineRenderDatasets, MineRenderError, MineRenderScene, type MineRenderSceneOptions, MineRenderWorld, type MineRenderWorldOptions, type MinecraftAsset, MinecraftCubeTexture, MinecraftFaceUV, type MinecraftTextureMeta, type Model, ModelCulling, type ModelDisplay, type ModelElement, type ModelFaces, ModelGenerator, ModelMerger, ModelObject, type ModelObjectOptions, ModelTextures, Models, type MultiBlockBlock, type MultiBlockEntity, type MultiBlockStructure, type MultipartCondition, type NBTAsset, NBTHelper, OrbitControls, type PackFormat, PackFormats, PackMetadata, PersistentCache, PlayerHeadTextures, type PositionedGuiGlyph, type QuadArray, type RawImageKey, type RenameKind, Renames, type RenderOptions, Renderer, type RendererControls, type RendererFrame, type RendererOptions, type RendererSurface, type RequestConfig, RequestError, type RequestResponse, Requests, type ResolvedBlockEntity, type ResolvedMineRenderData, type ResponseParser, SCENE_DOCUMENT_MAX_BYTES, SKIN_PARTS, type SavedLightSample, type SceneBlockDefinition, type SceneDocument, SceneDocumentLoader, type SceneEntityDefinition, SceneExporter, type SceneGLTFExportOptions, type SceneGuiDefinition, type SceneGuiLayer, SceneInspector, type SceneItemContext, type SceneModelDefinition, SceneObject, type SceneObjectDefinition, type SceneObjectDefinitionBase, type SceneObjectOptions, type SceneSkinDefinition, type SceneSkinPosePart, SceneStats, SceneStatsDisplay, SchematicParser, type SchematicParserOptions, type SectionAtlasSize, type SectionFluidInput, type SectionFluidKind, type SectionFluids, type SectionGeometryInput, type SectionGeometryPage, type SectionLightData, SectionMesh, type SectionMeshEntry, type SectionMeshTemplate, SectionModels, type SectionTemplateData, SectionWorker, type Serializable, type SkinGeometries, SkinImage, SkinObject, type SkinObjectOptions, SkinPart, type SkinTexture, type SkinTextureCoordinates, SkinTextures, Skins, type SpecialItemPart, type SpecialItemRenderer, SpecialItems, SpongeSchematicParser, type StructureNBT, StructureParser, type TextureAsset, TextureAtlas, type TextureKey, TextureLoader, Textures, Ticker, type TickerFunction, TintColors, type Transformable, type TripleArray, UVMapper, type VideoExportOptions, VideoExporter, type WorldBlockIntersection, type WorldChunkSource, type WorldEntityIntersection, WorldStreamer, type WorldStreamerOptions, WrappedImage, addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation, applyGenericRotation, axisToVec3, base64decode, base64encode, buildFluidQuads, buildSectionGeometry, capeTextureSizes, captureException, changeEvent, clampRotationDegrees, classicSkinGeometries, classicSkinTextureCoordinates, computeMorphedAttributes, copySectionLight, createCanvas, createFluidGeometry, createGuiTextGeometry, createGuiTextureGeometry, createImage, decodeSceneDocument, encodeSceneDocument, entityAnimationTime, estimateBytesUsed, fluidKindOf, getBlockFluidState, getFluidKind, interleaveAttributes, isAssetKey, isBasicAssetKey, isBlockObject, isDisposable, isDoubleArray, isEntityObject, isFlyControls, isGuiObject, isInstanceManager, isInstanceReference, isInstanceable, isInstancedMesh, isMesh, isMineRenderScene, isModelObject, isObject3D, isOrthographicCamera, isPerspectiveCamera, isQuadArray, isResourceLocation, isSceneObject, isTransformable, isTripleArray, isVector3, layoutGuiText, md5, mergeBufferAttributes, mergeBufferGeometries, mergeVertices, parseSceneDocument, prefix, probeImageSize, registerBrowserEnv, resolveBlockFluidState, resolveLegacyBlock, resolveLegacyBlockState, sampleEntityAnimation, sampleEntityKeyframes, sampleFluid, sampleSectionLight, sectionGeometryTransferables, serializeBoxGeometryKey, serializeImageKey, serializeMaterialKey, serializeMeshKey, serializeTextureKey, sha1, sha256, sha512, shutdown, sleep, slimSkinGeometries, slimSkinTextureCoordinates, timingEnd, timingStart, toDegrees, toRadians, toTrianglesDrawMode, trimCanvas, validateAnimationWeights, yieldToEventLoop };
|
|
@@ -149,6 +149,10 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
149
149
|
this.atlas.model.elements?.forEach((el) => {
|
|
150
150
|
const elGeo = this._getBoxGeometryFromElement(el).clone();
|
|
151
151
|
this.geometries.add(elGeo);
|
|
152
|
+
elGeo.setAttribute("shade", new BufferAttribute(
|
|
153
|
+
new Float32Array(elGeo.getAttribute("position").count).fill(!this.originalModel.itemId && el.shade === false ? 0 : 1),
|
|
154
|
+
1
|
|
155
|
+
));
|
|
152
156
|
if (this.options.cullMask) {
|
|
153
157
|
const indices = Array.from(elGeo.getIndex().array);
|
|
154
158
|
elGeo.setIndex(indices.filter((_, index) => {
|