Fixed schematic-friendly palette, added tests

This commit is contained in:
Lucas Dower 2022-09-17 12:00:30 +01:00
parent 27abfb348c
commit e25e7850ad
21 changed files with 172 additions and 81 deletions

View File

@ -8,10 +8,9 @@
"node": ">=14.0.0" "node": ">=14.0.0"
}, },
"scripts": { "scripts": {
"lint": "eslint --fix src tools --ext .ts", "lint": "eslint --fix src tools tests --ext .ts",
"build": "tsc", "build": "tsc",
"test": "jest --config jestconfig.json", "test": "jest --config jestconfig.json --runInBand",
"test-full": "jest --config jestconfig.full.json --runInBand",
"start": "npm run build && electron ./dist/src/main.js --enable-logging", "start": "npm run build && electron ./dist/src/main.js --enable-logging",
"atlas": "node ./dist/tools/build-atlas.js", "atlas": "node ./dist/tools/build-atlas.js",
"palette": "node ./dist/tools/build-palette.js", "palette": "node ./dist/tools/build-palette.js",
@ -64,4 +63,4 @@
"twgl.js": "^4.19.1", "twgl.js": "^4.19.1",
"varint-array": "^0.0.0" "varint-array": "^0.0.0"
} }
} }

View File

@ -1,5 +1,4 @@
import { BlockMesh } from '../block_mesh'; import { BlockMesh } from '../block_mesh';
import { TOptional } from '../util';
import { Vector3 } from '../vector'; import { Vector3 } from '../vector';
export abstract class IExporter { export abstract class IExporter {

View File

@ -104,8 +104,8 @@ export class Palette {
public remove(blockName: string): boolean { public remove(blockName: string): boolean {
const index = this._blocks.indexOf(AppUtil.Text.namespaceBlock(blockName)); const index = this._blocks.indexOf(AppUtil.Text.namespaceBlock(blockName));
if (index !== undefined) { if (index !== -1) {
this._blocks.slice(index, 1); this._blocks.splice(index, 1);
return true; return true;
} }
return false; return false;
@ -164,8 +164,8 @@ export class Palette {
} }
/** /**
* atlas. If not, the block is removed from the palette. * Removes blocks from the palette if they do not
* Checks if each block in this block palette has texture data in the given * have texture data in the given atlas.
*/ */
public removeMissingAtlasBlocks(atlas: Atlas) { public removeMissingAtlasBlocks(atlas: Atlas) {
const missingBlocks: AppTypes.TNamespacedBlockName[] = []; const missingBlocks: AppTypes.TNamespacedBlockName[] = [];

View File

@ -9,6 +9,7 @@ export class AppError extends Error {
export function ASSERT(condition: any, errorMessage = 'Assertion Failed'): asserts condition { export function ASSERT(condition: any, errorMessage = 'Assertion Failed'): asserts condition {
if (AppConfig.ASSERTIONS_ENABLED && !condition) { if (AppConfig.ASSERTIONS_ENABLED && !condition) {
Error(errorMessage);
throw Error(errorMessage); throw Error(errorMessage);
} }
} }

View File

@ -1,7 +1,7 @@
import fs from 'fs'; import fs from 'fs';
import { AppConfig } from '../config';
import util from 'util'; import util from 'util';
import { AppConfig } from '../config';
import { FileUtil } from './file_util'; import { FileUtil } from './file_util';
import { AppPaths, PathUtil } from './path_util'; import { AppPaths, PathUtil } from './path_util';

View File

@ -6,11 +6,11 @@ import { ExporterFactory } from './exporters/exporters';
import { ObjImporter } from './importers/obj_importer'; import { ObjImporter } from './importers/obj_importer';
import { Mesh } from './mesh'; import { Mesh } from './mesh';
import { ASSERT } from './util/error_util'; import { ASSERT } from './util/error_util';
import { Logger } from './util/log_util';
import { VoxelMesh } from './voxel_mesh'; import { VoxelMesh } from './voxel_mesh';
import { IVoxeliser } from './voxelisers/base-voxeliser'; import { IVoxeliser } from './voxelisers/base-voxeliser';
import { VoxeliserFactory } from './voxelisers/voxelisers'; import { VoxeliserFactory } from './voxelisers/voxelisers';
import { AssignParams, ExportParams, ImportParams, RenderBlockMeshParams, RenderMeshParams, RenderVoxelMeshParams, VoxeliseParams } from './worker_types'; import { AssignParams, ExportParams, ImportParams, RenderBlockMeshParams, RenderMeshParams, RenderVoxelMeshParams, VoxeliseParams } from './worker_types';
import { Logger } from './util/log_util';
export class WorkerClient { export class WorkerClient {
private static _instance: WorkerClient; private static _instance: WorkerClient;

View File

@ -1,6 +1,9 @@
import { AttributeData, MergeAttributeData } from '../src/render_buffer'; import { AttributeData, MergeAttributeData } from '../src/render_buffer';
import { TEST_PREAMBLE } from './preamble';
test('MergeAttributeData #1', () => { test('MergeAttributeData #1', () => {
TEST_PREAMBLE();
const a: AttributeData = { const a: AttributeData = {
indices: new Uint32Array([0, 1, 2]), indices: new Uint32Array([0, 1, 2]),
custom: { custom: {
@ -13,6 +16,8 @@ test('MergeAttributeData #1', () => {
}); });
test('MergeAttributeData #2', () => { test('MergeAttributeData #2', () => {
TEST_PREAMBLE();
const a: AttributeData = { const a: AttributeData = {
indices: new Uint32Array([0, 1, 2]), indices: new Uint32Array([0, 1, 2]),
custom: { custom: {
@ -32,7 +37,7 @@ test('MergeAttributeData #2', () => {
indices: new Uint32Array([0, 1, 2, 3, 4, 5]), indices: new Uint32Array([0, 1, 2, 3, 4, 5]),
custom: { custom: {
position: [ position: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 10, 11, 12, 13, 14, 15, 16, 17, 18,
], ],
colour: [ colour: [
@ -45,6 +50,8 @@ test('MergeAttributeData #2', () => {
}); });
test('MergeAttributeData #3', () => { test('MergeAttributeData #3', () => {
TEST_PREAMBLE();
const a: AttributeData = { const a: AttributeData = {
indices: new Uint32Array([0, 1]), indices: new Uint32Array([0, 1]),
custom: { custom: {

View File

@ -1,13 +1,16 @@
import { NormalCorrectedRayVoxeliser } from '../src/voxelisers/normal-corrected-ray-voxeliser'; import path from 'path';
import { RGBAColours } from '../src/colour';
import { ObjImporter } from '../src/importers/obj_importer'; import { ObjImporter } from '../src/importers/obj_importer';
import { TextureFiltering } from '../src/texture'; import { TextureFiltering } from '../src/texture';
import { Vector3 } from '../src/vector';
import path from 'path';
import { RGBAColours } from '../src/colour';
import { ASSERT } from '../src/util/error_util'; import { ASSERT } from '../src/util/error_util';
import { Vector3 } from '../src/vector';
import { NormalCorrectedRayVoxeliser } from '../src/voxelisers/normal-corrected-ray-voxeliser';
import { TEST_PREAMBLE } from './preamble';
test('Voxelise solid 2x2 cube', () => { test('Voxelise solid 2x2 cube', () => {
TEST_PREAMBLE();
const importer = new ObjImporter(); const importer = new ObjImporter();
importer.parseFile(path.join(__dirname, './data/cube.obj')); importer.parseFile(path.join(__dirname, './data/cube.obj'));
const mesh = importer.toMesh(); const mesh = importer.toMesh();

View File

@ -1,8 +1,11 @@
import { ObjImporter } from '../src/importers/obj_importer'; import { ObjImporter } from '../src/importers/obj_importer';
import { ASSERT } from '../src/util/error_util'; import { ASSERT } from '../src/util/error_util';
import { Vector3 } from '../src/vector'; import { Vector3 } from '../src/vector';
import { TEST_PREAMBLE } from './preamble';
test('Parse vertex #1', () => { test('Parse vertex #1', () => {
TEST_PREAMBLE();
const importer = new ObjImporter(); const importer = new ObjImporter();
importer.parseOBJLine('v 1.0 -2.0 3.0'); importer.parseOBJLine('v 1.0 -2.0 3.0');
const mesh = importer.toMesh(); const mesh = importer.toMesh();
@ -11,6 +14,8 @@ test('Parse vertex #1', () => {
}); });
test('Parse vertex #2', () => { test('Parse vertex #2', () => {
TEST_PREAMBLE();
const importer = new ObjImporter(); const importer = new ObjImporter();
importer.parseOBJLine('v 4.467e+000 9.243e+000 9.869e+000'); importer.parseOBJLine('v 4.467e+000 9.243e+000 9.869e+000');
const mesh = importer.toMesh(); const mesh = importer.toMesh();
@ -19,6 +24,8 @@ test('Parse vertex #2', () => {
}); });
test('Parse normal #1', () => { test('Parse normal #1', () => {
TEST_PREAMBLE();
const importer = new ObjImporter(); const importer = new ObjImporter();
importer.parseOBJLine('vn -1.0 -0.5 0.0'); importer.parseOBJLine('vn -1.0 -0.5 0.0');
const mesh = importer.toMesh(); const mesh = importer.toMesh();
@ -27,6 +34,8 @@ test('Parse normal #1', () => {
}); });
test('Parse texcoord #1', () => { test('Parse texcoord #1', () => {
TEST_PREAMBLE();
const importer = new ObjImporter(); const importer = new ObjImporter();
importer.parseOBJLine('vt 0.5 -0.8'); importer.parseOBJLine('vt 0.5 -0.8');
const mesh = importer.toMesh(); const mesh = importer.toMesh();
@ -35,6 +44,8 @@ test('Parse texcoord #1', () => {
}); });
test('Parse face #1', () => { test('Parse face #1', () => {
TEST_PREAMBLE();
const importer = new ObjImporter(); const importer = new ObjImporter();
importer.parseOBJLine('f 12 24 36'); importer.parseOBJLine('f 12 24 36');
const mesh = importer.toMesh(); const mesh = importer.toMesh();
@ -44,10 +55,12 @@ test('Parse face #1', () => {
expect(tri.normalIndices).toBeDefined(); ASSERT(tri.normalIndices); expect(tri.normalIndices).toBeDefined(); ASSERT(tri.normalIndices);
expect(tri.positionIndices.x === 12 - 1 && tri.positionIndices.y === 24 - 1 && tri.positionIndices.z === 36 - 1).toBe(true); expect(tri.positionIndices.x === 12 - 1 && tri.positionIndices.y === 24 - 1 && tri.positionIndices.z === 36 - 1).toBe(true);
expect(tri.texcoordIndices.x === 12 - 1 && tri.texcoordIndices.y === 24 - 1 && tri.texcoordIndices.z === 36 - 1).toBe(true); expect(tri.texcoordIndices.x === 12 - 1 && tri.texcoordIndices.y === 24 - 1 && tri.texcoordIndices.z === 36 - 1).toBe(true);
expect(tri.normalIndices.x === 12 - 1 && tri.normalIndices.y === 24 - 1 && tri.normalIndices.z === 36 - 1).toBe(true); expect(tri.normalIndices.x === 12 - 1 && tri.normalIndices.y === 24 - 1 && tri.normalIndices.z === 36 - 1).toBe(true);
}); });
test('Parse face #2', () => { test('Parse face #2', () => {
TEST_PREAMBLE();
const importer = new ObjImporter(); const importer = new ObjImporter();
importer.parseOBJLine('f 1/2 3/4 5/6'); importer.parseOBJLine('f 1/2 3/4 5/6');
const mesh = importer.toMesh(); const mesh = importer.toMesh();
@ -60,6 +73,8 @@ test('Parse face #2', () => {
}); });
test('Parse face #3', () => { test('Parse face #3', () => {
TEST_PREAMBLE();
const importer = new ObjImporter(); const importer = new ObjImporter();
importer.parseOBJLine('f 11/2/3 4/55/6 7/8/99'); importer.parseOBJLine('f 11/2/3 4/55/6 7/8/99');
const mesh = importer.toMesh(); const mesh = importer.toMesh();
@ -67,12 +82,14 @@ test('Parse face #3', () => {
const tri = mesh._tris[0]; const tri = mesh._tris[0];
expect(tri.texcoordIndices).toBeDefined(); ASSERT(tri.texcoordIndices); expect(tri.texcoordIndices).toBeDefined(); ASSERT(tri.texcoordIndices);
expect(tri.normalIndices).toBeDefined(); ASSERT(tri.normalIndices); expect(tri.normalIndices).toBeDefined(); ASSERT(tri.normalIndices);
expect(tri.positionIndices.x === 11 - 1 && tri.positionIndices.y === 4 - 1&& tri.positionIndices.z === 7 - 1).toBe(true); expect(tri.positionIndices.x === 11 - 1 && tri.positionIndices.y === 4 - 1 && tri.positionIndices.z === 7 - 1).toBe(true);
expect(tri.texcoordIndices.x === 2 - 1 && tri.texcoordIndices.y === 55 - 1 && tri.texcoordIndices.z === 8 - 1).toBe(true); expect(tri.texcoordIndices.x === 2 - 1 && tri.texcoordIndices.y === 55 - 1 && tri.texcoordIndices.z === 8 - 1).toBe(true);
expect(tri.normalIndices.x === 3 - 1 && tri.normalIndices.y === 6 - 1 && tri.normalIndices.z === 99 - 1).toBe(true); expect(tri.normalIndices.x === 3 - 1 && tri.normalIndices.y === 6 - 1 && tri.normalIndices.z === 99 - 1).toBe(true);
}); });
test('Parse mini #1', () => { test('Parse mini #1', () => {
TEST_PREAMBLE();
const importer = new ObjImporter(); const importer = new ObjImporter();
importer.parseOBJLine('v -1 2 3'); importer.parseOBJLine('v -1 2 3');
importer.parseOBJLine('v 4 -5 6'); importer.parseOBJLine('v 4 -5 6');
@ -95,7 +112,7 @@ test('Parse mini #1', () => {
expect(vertexData.v0.equals(new Vector3(-1, 2, 3))).toBe(true); expect(vertexData.v0.equals(new Vector3(-1, 2, 3))).toBe(true);
expect(vertexData.v1.equals(new Vector3(4, -5, 6))).toBe(true); expect(vertexData.v1.equals(new Vector3(4, -5, 6))).toBe(true);
expect(vertexData.v2.equals(new Vector3(7, 8, -9))).toBe(true); expect(vertexData.v2.equals(new Vector3(7, 8, -9))).toBe(true);
const texcoordData = mesh.getUVs(0); const texcoordData = mesh.getUVs(0);
expect(texcoordData.uv0.u === 0.0 && texcoordData.uv0.v === 0.5).toBe(true); expect(texcoordData.uv0.u === 0.0 && texcoordData.uv0.v === 0.5).toBe(true);
expect(texcoordData.uv1.u === 0.5 && texcoordData.uv1.v === 1.0).toBe(true); expect(texcoordData.uv1.u === 0.5 && texcoordData.uv1.v === 1.0).toBe(true);
@ -109,6 +126,8 @@ test('Parse mini #1', () => {
test('Parse mini #2', () => { test('Parse mini #2', () => {
TEST_PREAMBLE();
const importer = new ObjImporter(); const importer = new ObjImporter();
importer.parseOBJLine('v -1 2 3'); importer.parseOBJLine('v -1 2 3');
importer.parseOBJLine('v 4 -5 6'); importer.parseOBJLine('v 4 -5 6');
@ -131,7 +150,7 @@ test('Parse mini #2', () => {
expect(vertexData.v0.equals(new Vector3(7, 8, -9))).toBe(true); expect(vertexData.v0.equals(new Vector3(7, 8, -9))).toBe(true);
expect(vertexData.v1.equals(new Vector3(-1, 2, 3))).toBe(true); expect(vertexData.v1.equals(new Vector3(-1, 2, 3))).toBe(true);
expect(vertexData.v2.equals(new Vector3(4, -5, 6))).toBe(true); expect(vertexData.v2.equals(new Vector3(4, -5, 6))).toBe(true);
const texcoordData = mesh.getUVs(0); const texcoordData = mesh.getUVs(0);
expect(texcoordData.uv0.u === 0.0 && texcoordData.uv0.v === 0.5).toBe(true); expect(texcoordData.uv0.u === 0.0 && texcoordData.uv0.v === 0.5).toBe(true);
expect(texcoordData.uv1.u === 0.5 && texcoordData.uv1.v === 1.0).toBe(true); expect(texcoordData.uv1.u === 0.5 && texcoordData.uv1.v === 1.0).toBe(true);
@ -144,6 +163,8 @@ test('Parse mini #2', () => {
}); });
test('Parse mini #3', () => { test('Parse mini #3', () => {
TEST_PREAMBLE();
const importer = new ObjImporter(); const importer = new ObjImporter();
importer.parseOBJLine('v 0 0 0'); importer.parseOBJLine('v 0 0 0');
importer.parseOBJLine('v 1 0 0'); importer.parseOBJLine('v 1 0 0');
@ -168,6 +189,8 @@ test('Parse mini #3', () => {
}); });
test('Parse comments', () => { test('Parse comments', () => {
TEST_PREAMBLE();
const importer = new ObjImporter(); const importer = new ObjImporter();
importer.parseOBJLine('# v -1 2 3'); importer.parseOBJLine('# v -1 2 3');
importer.parseOBJLine('# vn 0.0 0.1 0.2'); importer.parseOBJLine('# vn 0.0 0.1 0.2');

View File

@ -1,9 +1,8 @@
import { TextureFiltering } from '../../src/texture'; import { TextureFiltering } from '../src/texture';
import { ColourSpace } from '../../src/util'; import { ColourSpace } from '../src/util';
import { AppPaths, PathUtil } from '../../src/util/path_util'; import { AppPaths, PathUtil } from '../src/util/path_util';
import { runHeadless, THeadlessConfig } from '../../tools/headless'; import { runHeadless, THeadlessConfig } from '../tools/headless';
import { FileUtil } from '../../src/util/file_util'; import { TEST_PREAMBLE } from './preamble';
import { TEST_PREAMBLE } from '../preamble';
const baseConfig: THeadlessConfig = { const baseConfig: THeadlessConfig = {
import: { import: {
@ -38,9 +37,6 @@ const baseConfig: THeadlessConfig = {
test('FULL Obj->Obj', () => { test('FULL Obj->Obj', () => {
TEST_PREAMBLE(); TEST_PREAMBLE();
AppPaths.Get.setBaseDir(PathUtil.join(__dirname, '../..'));
FileUtil.mkdirSyncIfNotExist(PathUtil.join(AppPaths.Get.testData, '../out/'));
const config: THeadlessConfig = baseConfig; const config: THeadlessConfig = baseConfig;
config.import.filepath = PathUtil.join(AppPaths.Get.resources, './samples/skull.obj'); config.import.filepath = PathUtil.join(AppPaths.Get.resources, './samples/skull.obj');

View File

@ -1,9 +1,8 @@
import { TextureFiltering } from '../../src/texture'; import { TextureFiltering } from '../src/texture';
import { ColourSpace } from '../../src/util'; import { ColourSpace } from '../src/util';
import { AppPaths, PathUtil } from '../../src/util/path_util'; import { AppPaths, PathUtil } from '../src/util/path_util';
import { runHeadless, THeadlessConfig } from '../../tools/headless'; import { runHeadless, THeadlessConfig } from '../tools/headless';
import { FileUtil } from '../../src/util/file_util'; import { TEST_PREAMBLE } from './preamble';
import { TEST_PREAMBLE } from '../preamble';
const baseConfig: THeadlessConfig = { const baseConfig: THeadlessConfig = {
import: { import: {
@ -38,9 +37,6 @@ const baseConfig: THeadlessConfig = {
test('FULL Obj->Obj', () => { test('FULL Obj->Obj', () => {
TEST_PREAMBLE(); TEST_PREAMBLE();
AppPaths.Get.setBaseDir(PathUtil.join(__dirname, '../..'));
FileUtil.mkdirSyncIfNotExist(PathUtil.join(AppPaths.Get.testData, '../out/'));
const config: THeadlessConfig = baseConfig; const config: THeadlessConfig = baseConfig;
config.import.filepath = PathUtil.join(AppPaths.Get.resources, './samples/skull.obj'); config.import.filepath = PathUtil.join(AppPaths.Get.resources, './samples/skull.obj');

View File

@ -1,9 +1,8 @@
import { TextureFiltering } from '../../src/texture'; import { TextureFiltering } from '../src/texture';
import { ColourSpace } from '../../src/util'; import { ColourSpace } from '../src/util';
import { AppPaths, PathUtil } from '../../src/util/path_util'; import { AppPaths, PathUtil } from '../src/util/path_util';
import { runHeadless, THeadlessConfig } from '../../tools/headless'; import { runHeadless, THeadlessConfig } from '../tools/headless';
import { FileUtil } from '../../src/util/file_util'; import { TEST_PREAMBLE } from './preamble';
import { TEST_PREAMBLE } from '../preamble';
const baseConfig: THeadlessConfig = { const baseConfig: THeadlessConfig = {
import: { import: {
@ -38,9 +37,6 @@ const baseConfig: THeadlessConfig = {
test('FULL Obj->Obj', () => { test('FULL Obj->Obj', () => {
TEST_PREAMBLE(); TEST_PREAMBLE();
AppPaths.Get.setBaseDir(PathUtil.join(__dirname, '../..'));
FileUtil.mkdirSyncIfNotExist(PathUtil.join(AppPaths.Get.testData, '../out/'));
const config: THeadlessConfig = baseConfig; const config: THeadlessConfig = baseConfig;
config.import.filepath = PathUtil.join(AppPaths.Get.resources, './samples/skull.obj'); config.import.filepath = PathUtil.join(AppPaths.Get.resources, './samples/skull.obj');

View File

@ -1,9 +1,8 @@
import { TextureFiltering } from '../../src/texture'; import { TextureFiltering } from '../src/texture';
import { ColourSpace } from '../../src/util'; import { ColourSpace } from '../src/util';
import { AppPaths, PathUtil } from '../../src/util/path_util'; import { AppPaths, PathUtil } from '../src/util/path_util';
import { runHeadless, THeadlessConfig } from '../../tools/headless'; import { runHeadless, THeadlessConfig } from '../tools/headless';
import { FileUtil } from '../../src/util/file_util'; import { TEST_PREAMBLE } from './preamble';
import { TEST_PREAMBLE } from '../preamble';
const baseConfig: THeadlessConfig = { const baseConfig: THeadlessConfig = {
import: { import: {
@ -38,9 +37,6 @@ const baseConfig: THeadlessConfig = {
test('FULL Obj->Schematic', () => { test('FULL Obj->Schematic', () => {
TEST_PREAMBLE(); TEST_PREAMBLE();
AppPaths.Get.setBaseDir(PathUtil.join(__dirname, '../..'));
FileUtil.mkdirSyncIfNotExist(PathUtil.join(AppPaths.Get.testData, '../out/'));
const config: THeadlessConfig = baseConfig; const config: THeadlessConfig = baseConfig;
config.import.filepath = PathUtil.join(AppPaths.Get.resources, './samples/skull.obj'); config.import.filepath = PathUtil.join(AppPaths.Get.resources, './samples/skull.obj');

9
tests/palette.test.ts Normal file
View File

@ -0,0 +1,9 @@
import { Palette } from '../src/palette';
test('Palette', () => {
const myPalette = Palette.create();
myPalette.add('minecraft:stone');
expect(myPalette.count()).toBe(1);
myPalette.remove('minecraft:stone');
expect(myPalette.count()).toBe(0);
});

View File

@ -1,5 +1,9 @@
import { Logger } from "../src/util/log_util" import { FileUtil } from '../src/util/file_util';
import { Logger } from '../src/util/log_util';
import { AppPaths, PathUtil } from '../src/util/path_util';
export const TEST_PREAMBLE = () => { export const TEST_PREAMBLE = () => {
Logger.Get.disableLogToFile(); Logger.Get.disableLogToFile();
} AppPaths.Get.setBaseDir(PathUtil.join(__dirname, '..'));
FileUtil.mkdirSyncIfNotExist(PathUtil.join(AppPaths.Get.testData, './out/'));
};

View File

@ -1,17 +1,20 @@
import { Ray, Axes, rayIntersectTriangle } from '../src/ray'; import { Axes, Ray, rayIntersectTriangle } from '../src/ray';
import { Vector3 } from '../src/vector';
import { Triangle } from '../src/triangle'; import { Triangle } from '../src/triangle';
import { ASSERT } from '../src/util/error_util'; import { ASSERT } from '../src/util/error_util';
import { Vector3 } from '../src/vector';
import { TEST_PREAMBLE } from './preamble';
test('rayIntersectTriangle x-axis #1', () => { test('rayIntersectTriangle x-axis #1', () => {
TEST_PREAMBLE();
const ray: Ray = { const ray: Ray = {
origin: new Vector3(-1, 0, 0), origin: new Vector3(-1, 0, 0),
axis: Axes.x, axis: Axes.x,
}; };
const tri = new Triangle( const tri = new Triangle(
new Vector3(5, -1, -1), new Vector3(5, -1, -1),
new Vector3(5, 0, 1), new Vector3(5, 0, 1),
new Vector3(5, 1, -1), new Vector3(5, 1, -1),
); );
const intersects = rayIntersectTriangle(ray, tri.v0, tri.v1, tri.v2); const intersects = rayIntersectTriangle(ray, tri.v0, tri.v1, tri.v2);
expect(intersects).toBeDefined(); expect(intersects).toBeDefined();
@ -20,28 +23,32 @@ test('rayIntersectTriangle x-axis #1', () => {
}); });
test('rayIntersectTriangle x-axis #2', () => { test('rayIntersectTriangle x-axis #2', () => {
TEST_PREAMBLE();
const ray: Ray = { const ray: Ray = {
origin: new Vector3(1, 0, 0), origin: new Vector3(1, 0, 0),
axis: Axes.x, axis: Axes.x,
}; };
const tri = new Triangle( const tri = new Triangle(
new Vector3(0, -1, -1), new Vector3(0, -1, -1),
new Vector3(0, 0, 1), new Vector3(0, 0, 1),
new Vector3(0, 1, -1), new Vector3(0, 1, -1),
); );
const intersects = rayIntersectTriangle(ray, tri.v0, tri.v1, tri.v2); const intersects = rayIntersectTriangle(ray, tri.v0, tri.v1, tri.v2);
expect(intersects).toBeUndefined(); expect(intersects).toBeUndefined();
}); });
test('rayIntersectTriangle y-axis #1', () => { test('rayIntersectTriangle y-axis #1', () => {
TEST_PREAMBLE();
const ray: Ray = { const ray: Ray = {
origin: new Vector3(0, -1, 0), origin: new Vector3(0, -1, 0),
axis: Axes.y, axis: Axes.y,
}; };
const tri = new Triangle( const tri = new Triangle(
new Vector3(-1, 6, -1), new Vector3(-1, 6, -1),
new Vector3( 0, 6, 1), new Vector3(0, 6, 1),
new Vector3( 1, 6, -1), new Vector3(1, 6, -1),
); );
const intersects = rayIntersectTriangle(ray, tri.v0, tri.v1, tri.v2); const intersects = rayIntersectTriangle(ray, tri.v0, tri.v1, tri.v2);
expect(intersects).toBeDefined(); expect(intersects).toBeDefined();
@ -50,28 +57,32 @@ test('rayIntersectTriangle y-axis #1', () => {
}); });
test('rayIntersectTriangle y-axis #2', () => { test('rayIntersectTriangle y-axis #2', () => {
TEST_PREAMBLE();
const ray: Ray = { const ray: Ray = {
origin: new Vector3(0, 1, 0), origin: new Vector3(0, 1, 0),
axis: Axes.y, axis: Axes.y,
}; };
const tri = new Triangle( const tri = new Triangle(
new Vector3(-1, 0, -1), new Vector3(-1, 0, -1),
new Vector3( 0, 0, 1), new Vector3(0, 0, 1),
new Vector3( 1, 0, -1), new Vector3(1, 0, -1),
); );
const intersects = rayIntersectTriangle(ray, tri.v0, tri.v1, tri.v2); const intersects = rayIntersectTriangle(ray, tri.v0, tri.v1, tri.v2);
expect(intersects).toBeUndefined(); expect(intersects).toBeUndefined();
}); });
test('rayIntersectTriangle z-axis #1', () => { test('rayIntersectTriangle z-axis #1', () => {
TEST_PREAMBLE();
const ray: Ray = { const ray: Ray = {
origin: new Vector3(0, 0, -1), origin: new Vector3(0, 0, -1),
axis: Axes.z, axis: Axes.z,
}; };
const tri = new Triangle( const tri = new Triangle(
new Vector3(-1, -1, 7), new Vector3(-1, -1, 7),
new Vector3( 0, 1, 7), new Vector3(0, 1, 7),
new Vector3( 1, -1, 7), new Vector3(1, -1, 7),
); );
const intersects = rayIntersectTriangle(ray, tri.v0, tri.v1, tri.v2); const intersects = rayIntersectTriangle(ray, tri.v0, tri.v1, tri.v2);
expect(intersects).toBeDefined(); expect(intersects).toBeDefined();
@ -80,14 +91,16 @@ test('rayIntersectTriangle z-axis #1', () => {
}); });
test('rayIntersectTriangle z-axis #2', () => { test('rayIntersectTriangle z-axis #2', () => {
TEST_PREAMBLE();
const ray: Ray = { const ray: Ray = {
origin: new Vector3(0, 0, 1), origin: new Vector3(0, 0, 1),
axis: Axes.z, axis: Axes.z,
}; };
const tri = new Triangle( const tri = new Triangle(
new Vector3(-1, -1, 0), new Vector3(-1, -1, 0),
new Vector3( 0, 1, 0), new Vector3(0, 1, 0),
new Vector3( 1, -1, 0), new Vector3(1, -1, 0),
); );
const intersects = rayIntersectTriangle(ray, tri.v0, tri.v1, tri.v2); const intersects = rayIntersectTriangle(ray, tri.v0, tri.v1, tri.v2);
expect(intersects).toBeUndefined(); expect(intersects).toBeUndefined();

View File

@ -0,0 +1,15 @@
import { WorkerClient } from '../src/worker_client';
import { headlessConfig } from '../tools/headless-config';
import { TEST_PREAMBLE } from './preamble';
test('Schematic-friendly Palette', () => {
TEST_PREAMBLE();
const worker = WorkerClient.Get;
const config = headlessConfig;
config.assign.blockPalette = 'schematic-friendly';
worker.import(headlessConfig.import);
worker.voxelise(headlessConfig.voxelise);
worker.assign(headlessConfig.assign);
});

View File

@ -1,6 +1,9 @@
import { StatusHandler } from '../src/status'; import { StatusHandler } from '../src/status';
import { TEST_PREAMBLE } from './preamble';
test('Status', () => { test('Status', () => {
TEST_PREAMBLE();
StatusHandler.Get.add( StatusHandler.Get.add(
'warning', 'warning',
'This is a warning', 'This is a warning',
@ -11,6 +14,8 @@ test('Status', () => {
}); });
test('Status', () => { test('Status', () => {
TEST_PREAMBLE();
StatusHandler.Get.add( StatusHandler.Get.add(
'warning', 'warning',
'This is a warning', 'This is a warning',
@ -23,9 +28,9 @@ test('Status', () => {
'info', 'info',
'This is some more info', 'This is some more info',
); );
expect(StatusHandler.Get.getStatusMessages( 'info').length).toBe(2); expect(StatusHandler.Get.getStatusMessages('info').length).toBe(2);
expect(StatusHandler.Get.getStatusMessages( 'warning').length).toBe(1); expect(StatusHandler.Get.getStatusMessages('warning').length).toBe(1);
StatusHandler.Get.clear(); StatusHandler.Get.clear();
expect(StatusHandler.Get.getStatusMessages( 'info').length).toBe(0); expect(StatusHandler.Get.getStatusMessages('info').length).toBe(0);
expect(StatusHandler.Get.getStatusMessages( 'warning').length).toBe(0); expect(StatusHandler.Get.getStatusMessages('warning').length).toBe(0);
}); });

View File

@ -1,7 +1,11 @@
import { RegExpBuilder, REGEX_NUMBER, REGEX_NZ_ANY } from '../src/util/regex_util'; import { AppUtil } from '../src/util';
import { ASSERT } from '../src/util/error_util'; import { ASSERT } from '../src/util/error_util';
import { REGEX_NUMBER, REGEX_NZ_ANY, RegExpBuilder } from '../src/util/regex_util';
import { TEST_PREAMBLE } from './preamble';
test('RegExpBuilder', () => { test('RegExpBuilder', () => {
TEST_PREAMBLE();
const regex = new RegExpBuilder() const regex = new RegExpBuilder()
.add(/hello/) .add(/hello/)
.toRegExp(); .toRegExp();
@ -10,6 +14,8 @@ test('RegExpBuilder', () => {
}); });
test('RegExpBuilder REGEX_NUMBER', () => { test('RegExpBuilder REGEX_NUMBER', () => {
TEST_PREAMBLE();
const tests = [ const tests = [
{ f: '0', s: 0 }, { f: '0', s: 0 },
{ f: '0.0', s: 0.0 }, { f: '0.0', s: 0.0 },
@ -26,6 +32,8 @@ test('RegExpBuilder REGEX_NUMBER', () => {
}); });
test('RegExpBuilder Required-whitespace', () => { test('RegExpBuilder Required-whitespace', () => {
TEST_PREAMBLE();
const regex = new RegExpBuilder() const regex = new RegExpBuilder()
.add(/hello/) .add(/hello/)
.addNonzeroWhitespace() .addNonzeroWhitespace()
@ -37,6 +45,8 @@ test('RegExpBuilder Required-whitespace', () => {
}); });
test('RegExpBuilder Optional', () => { test('RegExpBuilder Optional', () => {
TEST_PREAMBLE();
const regex = new RegExpBuilder() const regex = new RegExpBuilder()
.add(/hello/) .add(/hello/)
.addNonzeroWhitespace() .addNonzeroWhitespace()
@ -49,6 +59,8 @@ test('RegExpBuilder Optional', () => {
}); });
test('RegExpBuilder Capture', () => { test('RegExpBuilder Capture', () => {
TEST_PREAMBLE();
const regex = new RegExpBuilder() const regex = new RegExpBuilder()
.add(/[0-9]+/, 'myNumber') .add(/[0-9]+/, 'myNumber')
.toRegExp(); .toRegExp();
@ -61,6 +73,8 @@ test('RegExpBuilder Capture', () => {
}); });
test('RegExpBuilder Capture-multiple', () => { test('RegExpBuilder Capture-multiple', () => {
TEST_PREAMBLE();
const regex = new RegExpBuilder() const regex = new RegExpBuilder()
.add(/[0-9]+/, 'x') .add(/[0-9]+/, 'x')
.addNonzeroWhitespace() .addNonzeroWhitespace()
@ -82,6 +96,8 @@ test('RegExpBuilder Capture-multiple', () => {
}); });
test('RegExpBuilder Capture-multiple', () => { test('RegExpBuilder Capture-multiple', () => {
TEST_PREAMBLE();
const regex = new RegExpBuilder() const regex = new RegExpBuilder()
.add(/f/) .add(/f/)
.addNonzeroWhitespace() .addNonzeroWhitespace()
@ -124,6 +140,8 @@ test('RegExpBuilder Capture-multiple', () => {
}); });
test('RegExpBuilder Capture-multiple', () => { test('RegExpBuilder Capture-multiple', () => {
TEST_PREAMBLE();
const regex = new RegExpBuilder() const regex = new RegExpBuilder()
.add(/usemtl/) .add(/usemtl/)
.add(/ /) .add(/ /)
@ -136,3 +154,11 @@ test('RegExpBuilder Capture-multiple', () => {
expect(exec.groups['path']).toBe('hellothere.txt'); expect(exec.groups['path']).toBe('hellothere.txt');
} }
}); });
test('Namespace block', () => {
expect(AppUtil.Text.namespaceBlock('stone')).toBe('minecraft:stone');
});
test('Namespace already namespaced block', () => {
expect(AppUtil.Text.namespaceBlock('minecraft:stone')).toBe('minecraft:stone');
});

View File

@ -1,9 +1,12 @@
import { Vector3 } from '../src/vector';
import { VoxelMesh } from '../src/voxel_mesh';
import { RGBAColours } from '../src/colour'; import { RGBAColours } from '../src/colour';
import { ASSERT } from '../src/util/error_util'; import { ASSERT } from '../src/util/error_util';
import { Vector3 } from '../src/vector';
import { VoxelMesh } from '../src/voxel_mesh';
import { TEST_PREAMBLE } from './preamble';
test('Voxel neighbours', () => { test('Voxel neighbours', () => {
TEST_PREAMBLE();
const voxelMesh = new VoxelMesh({ const voxelMesh = new VoxelMesh({
voxelOverlapRule: 'first', voxelOverlapRule: 'first',
enableAmbientOcclusion: true, enableAmbientOcclusion: true,

View File

@ -1,4 +1,4 @@
import { Logger, LOG_MAJOR } from '../src/util/log_util'; import { LOG_MAJOR, Logger } from '../src/util/log_util';
import { AppPaths, PathUtil } from '../src/util/path_util'; import { AppPaths, PathUtil } from '../src/util/path_util';
import { runHeadless } from './headless'; import { runHeadless } from './headless';
import { headlessConfig } from './headless-config'; import { headlessConfig } from './headless-config';