Updated OtS_BlockMeshConverter, refactored contextual averaging

This commit is contained in:
Lucas Dower 2023-10-15 17:03:43 +01:00
parent 0766f628a0
commit 7b61bff346
12 changed files with 636 additions and 27 deletions

3
.gitignore vendored
View File

@ -13,4 +13,5 @@
/Editor/build
# Sandbox
/Sandbox/node_modules
/Sandbox/node_modules
/Sandbox/lib

View File

@ -11,13 +11,13 @@
"dependencies": {
"@loaders.gl/core": "^3.4.14",
"@loaders.gl/gltf": "^3.4.14",
"@types/jest": "^29.5.5",
"pako": "^2.1.0",
"prismarine-nbt": "^2.2.1",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
},
"devDependencies": {
"@types/jest": "^29.5.5",
"@types/pako": "^2.0.1",
"jest": "^29.7.0"
}
@ -1164,6 +1164,7 @@
"version": "29.5.5",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.5.tgz",
"integrity": "sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==",
"dev": true,
"dependencies": {
"expect": "^29.0.0",
"pretty-format": "^29.0.0"
@ -4663,6 +4664,7 @@
"version": "29.5.5",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.5.tgz",
"integrity": "sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==",
"dev": true,
"requires": {
"expect": "^29.0.0",
"pretty-format": "^29.0.0"

View File

@ -14,13 +14,13 @@
"dependencies": {
"@loaders.gl/core": "^3.4.14",
"@loaders.gl/gltf": "^3.4.14",
"@types/jest": "^29.5.5",
"pako": "^2.1.0",
"prismarine-nbt": "^2.2.1",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
},
"devDependencies": {
"@types/jest": "^29.5.5",
"@types/pako": "^2.0.1",
"jest": "^29.7.0"
}

View File

@ -1,17 +1,41 @@
import { OtS_ReplaceMode, OtS_VoxelMesh } from './ots_voxel_mesh';
import { TAxis } from './util/type_util';
import { Vector3 } from './vector';
import { Triangle } from './triangle';
import { LinearAllocator } from './linear_allocator';
import { Axes, Ray, rayIntersectTriangle } from './ray';
import { Bounds } from './bounds';
import { RGBA, RGBAColours, RGBAUtil } from './colour';
import { OtS_Mesh, OtS_Triangle } from './ots_mesh';
import { UV } from './util';
import { OtS_VoxelMesh } from './ots_voxel_mesh';
import { OtS_BlockMesh } from './ots_block_mesh';
import { BlockMesh } from './block_mesh';
import { RGBA, RGBAColours, RGBAUtil } from './colour';
import { OtS_FaceVisibility, OtS_VoxelMesh_Neighbourhood } from './ots_voxel_mesh_neighbourhood';
import { ASSERT } from './util/error_util';
import { Vector3 } from './vector';
export type OtS_BlockData_PerBlock<T> = { name: string, colour: T }[];
export type OtS_BlockTextureData_Block = {
name: string,
textures: {
up: string,
down: string,
north: string,
south: string,
east: string,
west: string,
}
}
export type OtS_BlockData_PerFace<T> = {
blocks: OtS_BlockTextureData_Block[],
textures: { [name: string]: T },
}
type OtS_BlockMesh_DataMode<T> =
| { type: 'per-block', data: OtS_BlockData_PerBlock<T> }
| { type: 'per-face', data: OtS_BlockData_PerFace<T> }
export type OtS_FallableBehaviour = 'replace-falling' | 'replace-fallable' | 'place-string';
export type OtS_BlockMesh_ConverterConfig = {
mode: OtS_BlockMesh_DataMode<RGBA>,
dithering?: { mode: 'random' | 'ordered', magnitude: number },
fallable?: OtS_FallableBehaviour,
smoothness?: OtS_BlockMesh_DataMode<number> & { weight: number },
resolution?: number, // [1, 255]
}
export class OtS_BlockMesh_Converter {
@ -19,6 +43,11 @@ export class OtS_BlockMesh_Converter {
public constructor() {
this._config = {
mode: {
type: 'per-block', data: [
{ name: 'minecraft:stone', colour: RGBAUtil.copy(RGBAColours.WHITE) }
]
}
};
}
@ -29,6 +58,8 @@ export class OtS_BlockMesh_Converter {
public setConfig(config: OtS_BlockMesh_ConverterConfig): boolean {
// TODO: Validate
// TODO: Validata per-face data has colours for each
// TODO: Copy config
this._config = config;
@ -38,10 +69,208 @@ export class OtS_BlockMesh_Converter {
public process(voxelMesh: OtS_VoxelMesh): OtS_BlockMesh {
const blockMesh = new OtS_BlockMesh();
for (const { position } of voxelMesh.getVoxels()) {
blockMesh.addBlock(position.x, position.y, position.z, 'minecraft:stone', true);
// TODO: Fallable
// TODO: Smoothness
// TODO: Resolution
// TODO: Dithering
let neighbourhood: OtS_VoxelMesh_Neighbourhood | undefined;
if (this._config.mode.type === 'per-face') {
neighbourhood = new OtS_VoxelMesh_Neighbourhood();
neighbourhood.process(voxelMesh, 'cardinal');
}
for (const { position, colour } of voxelMesh.getVoxels()) {
let block: (string | null) = null;
if (this._config.mode.type === 'per-block') {
block = this._findClosestBlock_PerBlock(colour);
} else {
block = this._findClosestBlock_PerFace(colour, position, neighbourhood!);
}
if (block === null) {
continue;
}
blockMesh.addBlock(position.x, position.y, position.z, block, true);
}
return blockMesh;
}
private _getBlockNames(): string[] {
if (this._config.mode.type === 'per-block') {
return Object.keys(this._config.mode.data);
} else {
return this._config.mode.data.blocks.map((block) => block.name );
}
}
private _findClosestBlock_PerBlock(desiredColour: RGBA) {
ASSERT(this._config.mode.type === 'per-block');
let bestDistance = Infinity;
let bestCandidate: (string | null) = null;
for (const { name, colour } of this._config.mode.data) {
const distance = RGBAUtil.squaredDistance(colour, desiredColour);
if (distance < bestDistance) {
bestDistance = distance;
bestCandidate = name;
}
}
return bestCandidate;
}
private _findClosestBlock_PerFace(desiredColour: RGBA, position: Vector3, neighbourhood: OtS_VoxelMesh_Neighbourhood) {
ASSERT(this._config.mode.type === 'per-face');
let bestDistance = Infinity;
let bestCandidate: (string | null) = null;
for (const block of this._config.mode.data.blocks) {
const visibility = neighbourhood.getFaceVisibility(position.x, position.y, position.z);
if (visibility === null) {
return null;
}
const averageColour: RGBA = { r: 0, g: 0, b: 0, a: 0 };
{
let count = 0;
if (visibility & OtS_FaceVisibility.Up) {
const faceTexture = block.textures.up;
const faceColour = this._config.mode.data.textures[faceTexture];
RGBAUtil.add(averageColour, faceColour);
++count;
}
if (visibility & OtS_FaceVisibility.Down) {
const faceTexture = block.textures.down;
const faceColour = this._config.mode.data.textures[faceTexture];
RGBAUtil.add(averageColour, faceColour);
++count;
}
if (visibility & OtS_FaceVisibility.North) {
const faceTexture = block.textures.north;
const faceColour = this._config.mode.data.textures[faceTexture];
RGBAUtil.add(averageColour, faceColour);
++count;
}
if (visibility & OtS_FaceVisibility.East) {
const faceTexture = block.textures.east;
const faceColour = this._config.mode.data.textures[faceTexture];
RGBAUtil.add(averageColour, faceColour);
++count;
}
if (visibility & OtS_FaceVisibility.South) {
const faceTexture = block.textures.south;
const faceColour = this._config.mode.data.textures[faceTexture];
RGBAUtil.add(averageColour, faceColour);
++count;
}
if (visibility & OtS_FaceVisibility.West) {
const faceTexture = block.textures.west;
const faceColour = this._config.mode.data.textures[faceTexture];
RGBAUtil.add(averageColour, faceColour);
++count;
}
averageColour.r /= count;
averageColour.g /= count;
averageColour.b /= count;
averageColour.a /= count;
}
const distance = RGBAUtil.squaredDistance(averageColour, desiredColour);
if (distance < bestDistance) {
bestDistance = distance;
bestCandidate = block.name;
}
}
return bestCandidate;
}
/*
private _getBlocks(visibility: OtS_FaceVisibility): IterableIterator<{ name: string, colour: RGBA }> {
let currentIndex = 0;
const blockCount = this._config.mode.type === 'per-block'
? this._config.mode.data.length
: this._config.mode.data.blocks.length;
const getBlockColour = (index: number): { name: string, colour: RGBA } => {
if (this._config.mode.type === 'per-block') {
return this._config.mode.data[index];
} else {
const block = this._config.mode.data.blocks[index];
const averageColour: RGBA = { r: 0, g: 0, b: 0, a: 0 };
let count = 0;
if (visibility & OtS_FaceVisibility.Up) {
const faceTexture = block.textures.up;
const faceColour = this._config.mode.data.textures[faceTexture];
RGBAUtil.add(averageColour, faceColour);
++count;
}
if (visibility & OtS_FaceVisibility.Down) {
const faceTexture = block.textures.down;
const faceColour = this._config.mode.data.textures[faceTexture];
RGBAUtil.add(averageColour, faceColour);
++count;
}
if (visibility & OtS_FaceVisibility.North) {
const faceTexture = block.textures.north;
const faceColour = this._config.mode.data.textures[faceTexture];
RGBAUtil.add(averageColour, faceColour);
++count;
}
if (visibility & OtS_FaceVisibility.East) {
const faceTexture = block.textures.east;
const faceColour = this._config.mode.data.textures[faceTexture];
RGBAUtil.add(averageColour, faceColour);
++count;
}
if (visibility & OtS_FaceVisibility.South) {
const faceTexture = block.textures.south;
const faceColour = this._config.mode.data.textures[faceTexture];
RGBAUtil.add(averageColour, faceColour);
++count;
}
if (visibility & OtS_FaceVisibility.West) {
const faceTexture = block.textures.west;
const faceColour = this._config.mode.data.textures[faceTexture];
RGBAUtil.add(averageColour, faceColour);
++count;
}
averageColour.r /= count;
averageColour.g /= count;
averageColour.b /= count;
averageColour.a /= count;
return {
name: block.name,
colour: averageColour,
}
}
}
return {
[Symbol.iterator]: function () {
return this;
},
next: () => {
if (currentIndex < blockCount) {
const block = getBlockColour(currentIndex);
++currentIndex;
return { done: false, value: block };
} else {
return { done: true, value: undefined };
}
},
};
}
*/
}

View File

@ -0,0 +1,33 @@
import { RGBAColours } from '../src/colour';
import { OtS_VoxelMesh } from '../src/ots_voxel_mesh';
import { RGBAUtil } from '../src/colour';
import { OtS_BlockMesh_Converter } from '../src/ots_block_mesh_converter';
test('Per-block', () => {
const voxelMesh = new OtS_VoxelMesh();
voxelMesh.addVoxel(0, 0, 0, RGBAUtil.copy(RGBAColours.RED));
voxelMesh.addVoxel(1, 0, 0, RGBAUtil.copy(RGBAColours.GREEN));
voxelMesh.addVoxel(2, 0, 0, RGBAUtil.copy(RGBAColours.BLUE));
const converter = new OtS_BlockMesh_Converter();
converter.setConfig({
mode: {
type: 'per-block', data: [
{ name: 'RED-BLOCK', colour: RGBAUtil.copy(RGBAColours.RED) },
{ name: 'GREEN-BLOCK', colour: RGBAUtil.copy(RGBAColours.GREEN) },
{ name: 'BLUE-BLOCK', colour: RGBAUtil.copy(RGBAColours.BLUE) }
]
},
});
const blockMesh = converter.process(voxelMesh);
expect(blockMesh.isBlockAt(0, 0, 0)).toBe(true);
expect(blockMesh.getBlockAt(0, 0, 0)?.name).toBe('RED-BLOCK');
expect(blockMesh.isBlockAt(1, 0, 0)).toBe(true);
expect(blockMesh.getBlockAt(1, 0, 0)?.name).toBe('GREEN-BLOCK');
expect(blockMesh.isBlockAt(2, 0, 0)).toBe(true);
expect(blockMesh.getBlockAt(2, 0, 0)?.name).toBe('BLUE-BLOCK');
});

View File

@ -8,7 +8,8 @@
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"outDir": "lib"
},
"include": ["src/**/*", "index.ts"]

View File

@ -262,8 +262,10 @@ export class WorkerClient {
this._bufferGenerator_BlockMesh = undefined;
const converter = new OtS_BlockMesh_Converter();
/*
converter.setConfig({
});
*/
this._loadedBlockMesh = converter.process(this._loadedVoxelMesh);

View File

@ -1,7 +1,12 @@
import fs from 'fs';
import { RGBAColours, RGBAUtil } from 'ots-core/src/colour';
import { OtS_Mesh } from 'ots-core/src/ots_mesh';
import { OtS_Texture } from 'ots-core/src/ots_texture';
import { OtS_VoxelMesh_Converter } from '../Core/src/ots_voxel_mesh_converter';
import { OtS_BlockMesh_Converter } from '../Core/src/ots_block_mesh_converter';
import { ExporterFactory } from '../Core/src/exporters/exporters';
import { ASSERT } from 'ots-core/src/util/error_util';
(async () => {
const mesh = OtS_Mesh.create();
@ -74,19 +79,32 @@ import { OtS_VoxelMesh_Converter } from '../Core/src/ots_voxel_mesh_converter';
}
// 3. Construct a voxel mesh from the mesh
const converter = new OtS_VoxelMesh_Converter();
converter.setConfig({
const voxelMeshConverter = new OtS_VoxelMesh_Converter();
voxelMeshConverter.setConfig({
constraintAxis: 'y',
size: 380,
multisampling: false,
replaceMode: 'keep',
});
const voxelMesh = converter.process(mesh);
const voxelMesh = voxelMeshConverter.process(mesh);
// 4. Construct a block mesh from the block
// TODO
const blockMeshConverter = new OtS_BlockMesh_Converter();
blockMeshConverter.setConfig({
mode: {
type: 'per-block', data: [
{ name: 'minecraft:stone', colour: RGBAUtil.copy(RGBAColours.WHITE) },
]
},
});
const blockMesh = blockMeshConverter.process(voxelMesh);
// 5. Export the block mesh to a file
// TODO
const exporter = ExporterFactory.GetExporter('uncompressed_json');
const structure = exporter.export(blockMesh);
ASSERT(structure.type === 'single');
fs.writeFileSync('output.json', structure.content);
})();

View File

@ -11,7 +11,8 @@
"dependencies": {
"jpeg-js": "^0.4.4",
"ots-core": "file:../Core",
"pngjs": "^7.0.0"
"pngjs": "^7.0.0",
"ts-node": "^10.9.1"
}
},
"../Core": {
@ -21,22 +22,126 @@
"dependencies": {
"@loaders.gl/core": "^3.4.14",
"@loaders.gl/gltf": "^3.4.14",
"@types/jest": "^29.5.5",
"pako": "^2.1.0",
"prismarine-nbt": "^2.2.1",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
},
"devDependencies": {
"@types/jest": "^29.5.5",
"@types/pako": "^2.0.1",
"jest": "^29.7.0"
}
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
"integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"node_modules/@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA=="
},
"node_modules/@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="
},
"node_modules/@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="
},
"node_modules/@tsconfig/node16": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="
},
"node_modules/@types/node": {
"version": "20.8.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz",
"integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==",
"peer": true,
"dependencies": {
"undici-types": "~5.25.1"
}
},
"node_modules/acorn": {
"version": "8.10.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
"integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/acorn-walk": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
},
"node_modules/create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
},
"node_modules/diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"engines": {
"node": ">=0.3.1"
}
},
"node_modules/jpeg-js": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz",
"integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="
},
"node_modules/make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
},
"node_modules/ots-core": {
"resolved": "../Core",
"link": true
@ -48,14 +153,174 @@
"engines": {
"node": ">=14.19.0"
}
},
"node_modules/ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"v8-compile-cache-lib": "^3.0.1",
"yn": "3.1.1"
},
"bin": {
"ts-node": "dist/bin.js",
"ts-node-cwd": "dist/bin-cwd.js",
"ts-node-esm": "dist/bin-esm.js",
"ts-node-script": "dist/bin-script.js",
"ts-node-transpile-only": "dist/bin-transpile.js",
"ts-script": "dist/bin-script-deprecated.js"
},
"peerDependencies": {
"@swc/core": ">=1.2.50",
"@swc/wasm": ">=1.2.50",
"@types/node": "*",
"typescript": ">=2.7"
},
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
},
"@swc/wasm": {
"optional": true
}
}
},
"node_modules/typescript": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "5.25.3",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
"integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
"peer": true
},
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="
},
"node_modules/yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"engines": {
"node": ">=6"
}
}
},
"dependencies": {
"@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"requires": {
"@jridgewell/trace-mapping": "0.3.9"
}
},
"@jridgewell/resolve-uri": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
"integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA=="
},
"@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
},
"@jridgewell/trace-mapping": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"requires": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA=="
},
"@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="
},
"@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="
},
"@tsconfig/node16": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="
},
"@types/node": {
"version": "20.8.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz",
"integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==",
"peer": true,
"requires": {
"undici-types": "~5.25.1"
}
},
"acorn": {
"version": "8.10.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
"integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw=="
},
"acorn-walk": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA=="
},
"arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
},
"create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
},
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
},
"jpeg-js": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz",
"integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="
},
"make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
},
"ots-core": {
"version": "file:../Core",
"requires": {
@ -74,6 +339,48 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
"integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="
},
"ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
"requires": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"v8-compile-cache-lib": "^3.0.1",
"yn": "3.1.1"
}
},
"typescript": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"peer": true
},
"undici-types": {
"version": "5.25.3",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
"integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
"peer": true
},
"v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="
},
"yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="
}
}
}

View File

@ -5,7 +5,7 @@
"description": "",
"main": "index.js",
"scripts": {
"build": "echo \"Nothing to build\" && exit 0",
"build": "tsc",
"test": "echo \"No tests\" && exit 0"
},
"keywords": [],
@ -14,6 +14,7 @@
"dependencies": {
"jpeg-js": "^0.4.4",
"ots-core": "file:../Core",
"pngjs": "^7.0.0"
"pngjs": "^7.0.0",
"ts-node": "^10.9.1"
}
}

View File

@ -3,7 +3,6 @@ import path from 'node:path';
import OTS from 'ots-core';
import { PNG } from 'pngjs';
import { decode as jpegDecode } from 'jpeg-js';
export function createReadableStream(p: fs.PathLike) {

16
Sandbox/tsconfig.json Normal file
View File

@ -0,0 +1,16 @@
{
"compilerOptions": {
"lib": [ "es2022", "DOM" ],
"module": "commonjs",
"target": "es2022",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"outDir": "lib"
},
"include": ["src/**/*", "index.ts"]
}