From 37cccb72dd23f6b8dadf25e5f03aa27bbe9aee20 Mon Sep 17 00:00:00 2001 From: Lucas Dower Date: Mon, 17 Jan 2022 19:20:30 +0000 Subject: [PATCH] Last changes for 0.4 --- README.md | 1 - package.json | 4 ++-- src/app_context.ts | 18 +++++++++++++----- src/mesh.ts | 24 +++++++++--------------- src/renderer.ts | 2 ++ src/ui/elements/button.ts | 16 ++++++++-------- src/ui/elements/combobox.ts | 9 ++++----- src/ui/elements/file_input.ts | 30 +++++++++++++++--------------- src/ui/elements/label.ts | 8 ++++---- src/ui/elements/output.ts | 15 +++++++-------- src/ui/elements/slider.ts | 28 ++++++++++++++-------------- src/ui/layout.ts | 18 +++++++++--------- src/util.ts | 6 ++++++ 13 files changed, 93 insertions(+), 86 deletions(-) diff --git a/README.md b/README.md index 1bab01d4..2c20e8d5 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ You can either download the [latest release](https://github.com/LucasDower/ObjTo * Navigate to `/ObjToSchematic-main`. * Run `npm install`. * Run `npm start`. -* Note, for now, all .obj models **must** be triangulated before importing. Support for choosing the block palette is not yet supported. Instead, you can edit `/tools/default-ignore-list.txt` to include blocks you don't want to be used and then run `npm run-script atlas`. You can also place custom textures in `/tools/blocks/` for more accurate block-colour matching when building with resource packs. diff --git a/package.json b/package.json index 593e4d54..75957482 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "objtoschematic", - "version": "0.3.0", + "version": "0.4.0", "description": "A tool to convert .obj files into voxels and then into Minecraft Schematic files", "main": "./dist/main.js", "engines": { "node": ">=14.0.0" }, "scripts": { - "lint": "eslint --fix ./src/*.ts", + "lint": "eslint --fix ./src/**/*.ts", "build": "npm run lint && tsc", "start": "npm run build && electron ./dist/main.js --enable-logging", "atlas": "npx ts-node tools/build-atlas.ts", diff --git a/src/app_context.ts b/src/app_context.ts index 7fef5678..75613104 100644 --- a/src/app_context.ts +++ b/src/app_context.ts @@ -13,6 +13,7 @@ import fs from 'fs'; import { ButtonElement } from './ui/elements/button'; import { LabelElement } from './ui/elements/label'; import { OutputElement } from './ui/elements/output'; +import { CustomError } from './util'; /* eslint-disable */ export enum ActionReturnType { @@ -93,7 +94,8 @@ export class AppContext { components: [ { label: new LabelElement('label3', 'Ratio'), - type: new SliderElement('ratio', 0.0, 1.0, 0.01, 0.5) }, + type: new SliderElement('ratio', 0.0, 1.0, 0.01, 0.5), + }, ], submitButton: new ButtonElement('simplifyMesh', 'Simplify mesh', () => { }), output: new OutputElement('output2'), @@ -103,7 +105,7 @@ export class AppContext { components: [ { label: new LabelElement('label4', 'Voxel size'), - type: new SliderElement('voxelSize', 0.01, 0.5, 0.01, 0.1), + type: new SliderElement('voxelSize', 0.01, 0.5, 0.01, 0.10001), }, { label: new LabelElement('label5', 'Ambient occlusion'), @@ -182,9 +184,15 @@ export class AppContext { public do(action: Action) { const status = this._actionMap.get(action)!(); if (status) { - this._ui[action].output.setMessage(status.message, status.type); if (status.error) { - console.error(status.error); + console.error('CAUGHT', status.error); + if (status.error instanceof CustomError) { + this._ui[action].output.setMessage(status.error.message, status.type); + } else { + this._ui[action].output.setMessage(status.message, status.type); + } + } else { + this._ui[action].output.setMessage(status.message, status.type); } } } @@ -206,7 +214,7 @@ export class AppContext { } try { - this._loadedMesh = new Mesh(objPath, this._gl); + this._loadedMesh = new Mesh(objPath, mtlPath); this._loadedMesh.loadTextures(this._gl); } catch (err: unknown) { return { error: err, message: 'Could not load mesh', type: ActionReturnType.Failure }; diff --git a/src/mesh.ts b/src/mesh.ts index 591909c4..070d9c89 100644 --- a/src/mesh.ts +++ b/src/mesh.ts @@ -4,7 +4,7 @@ import * as path from 'path'; import { Triangle } from './triangle'; import { Vector3 } from './vector'; -import { RGB, UV } from './util'; +import { RGB, UV, CustomError } from './util'; import { TextureFormat } from './texture'; import { triangleArea } from './math'; @@ -113,32 +113,26 @@ class Material { export class Mesh { public materials: Array; - constructor(objPathString: string, gl: WebGLRenderingContext) { + constructor(objPathString: string, mtlPathString: string) { // Parse .obj const wavefrontString = fs.readFileSync(objPathString).toString('utf8'); const parsedOBJ = this._parseOBJFile(wavefrontString); - - // TODO: Create blank .mtl when not found - if (!parsedOBJ.mtlPath) { - throw Error('No .mtl file found.'); - } - const objPath = path.parse(objPathString); - if (!path.isAbsolute(parsedOBJ.mtlPath)) { - parsedOBJ.mtlPath = path.join(objPath.dir, parsedOBJ.mtlPath); - } - parsedOBJ.mtlPath = parsedOBJ.mtlPath.trimEnd(); // Parse .mtl - const materialString = fs.readFileSync(parsedOBJ.mtlPath).toString('utf8'); + const materialString = fs.readFileSync(mtlPathString).toString('utf8'); const parsedMTL = this._parseMaterial(materialString, objPath); - this.materials = this._mergeMaterialData(parsedOBJ, parsedMTL); this._centreMesh(); this._normaliseMesh(); - console.log(this.materials); + // TODO: Throw at source + for (const material of this.materials) { + if (material.materialData === undefined) { + throw new CustomError('Could not link .obj with .mtl, possible mismatch?'); + } + } } private _addMaterial(materialsJSON: Materials, materialName: string, materialDiffuseColour: RGB, materialDiffuseTexturePath: string, materialFormat: TextureFormat) { diff --git a/src/renderer.ts b/src/renderer.ts index d4f7d80b..9d0021c0 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -195,6 +195,8 @@ export class Renderer { } public registerMesh(mesh: Mesh) { + this._gl.disable(this._gl.CULL_FACE); + mesh.materials.forEach((material) => { const materialBuffer = new BottomlessBuffer([ { name: 'position', numComponents: 3 }, diff --git a/src/ui/elements/button.ts b/src/ui/elements/button.ts index 46c9c101..a11b78f0 100644 --- a/src/ui/elements/button.ts +++ b/src/ui/elements/button.ts @@ -1,5 +1,5 @@ -import { BaseUIElement } from "../layout"; -import { assert } from "../../util"; +import { BaseUIElement } from '../layout'; +import { assert } from '../../util'; export class ButtonElement extends BaseUIElement { private _label: string; @@ -24,7 +24,7 @@ export class ButtonElement extends BaseUIElement { const element = document.getElementById(this._id) as HTMLDivElement; assert(element !== null); - element.addEventListener("click", () => { + element.addEventListener('click', () => { if (this._isEnabled) { this._onClick(); } @@ -36,11 +36,11 @@ export class ButtonElement extends BaseUIElement { assert(element !== null); if (this._isEnabled) { - //element.classList.add("button"); - element.classList.remove("button-disabled"); + // element.classList.add("button"); + element.classList.remove('button-disabled'); } else { - element.classList.add("button-disabled"); - //element.classList.remove("button"); + element.classList.add('button-disabled'); + // element.classList.remove("button"); } } -} \ No newline at end of file +} diff --git a/src/ui/elements/combobox.ts b/src/ui/elements/combobox.ts index 9a33250e..e89cffe7 100644 --- a/src/ui/elements/combobox.ts +++ b/src/ui/elements/combobox.ts @@ -1,5 +1,5 @@ -import { BaseUIElement } from "../layout"; -import { assert } from "../../util"; +import { BaseUIElement } from '../layout'; +import { assert } from '../../util'; export interface ComboBoxItem { id: string; @@ -15,7 +15,7 @@ export class ComboBoxElement extends BaseUIElement { } public generateHTML() { - let itemsHTML = ""; + let itemsHTML = ''; for (const item of this._items) { itemsHTML += ``; } @@ -34,7 +34,6 @@ export class ComboBoxElement extends BaseUIElement { const element = document.getElementById(this._id) as HTMLSelectElement; assert(element !== null); return this._items[element.selectedIndex].id; - } protected _onEnabledChanged() { @@ -42,4 +41,4 @@ export class ComboBoxElement extends BaseUIElement { assert(element !== null); element.disabled = !this._isEnabled; } -} \ No newline at end of file +} diff --git a/src/ui/elements/file_input.ts b/src/ui/elements/file_input.ts index a11c0432..7f8e37cb 100644 --- a/src/ui/elements/file_input.ts +++ b/src/ui/elements/file_input.ts @@ -1,8 +1,8 @@ -import { BaseUIElement } from "../layout"; -import { assert } from "../../util"; +import { BaseUIElement } from '../layout'; +import { assert } from '../../util'; -import { remote } from "electron"; -import * as path from "path"; +import { remote } from 'electron'; +import * as path from 'path'; export class FileInputElement extends BaseUIElement { private _fileExtension: string; @@ -11,7 +11,7 @@ export class FileInputElement extends BaseUIElement { public constructor(id: string, fileExtension: string) { super(id); this._fileExtension = fileExtension; - this._loadedFilePath = ""; + this._loadedFilePath = ''; } public generateHTML() { @@ -32,18 +32,18 @@ export class FileInputElement extends BaseUIElement { } const files = remote.dialog.showOpenDialogSync({ - title: "Load file", - buttonLabel: "Load", + title: 'Load file', + buttonLabel: 'Load', filters: [{ name: 'Waveform obj file', - extensions: [`${this._fileExtension}`] - }] + extensions: [`${this._fileExtension}`], + }], }); if (files && files.length === 1) { const filePath = files[0]; this._loadedFilePath = filePath; } else { - this._loadedFilePath = ""; + this._loadedFilePath = ''; } const parsedPath = path.parse(this._loadedFilePath); element.innerHTML = parsedPath.name + parsedPath.ext; @@ -59,11 +59,11 @@ export class FileInputElement extends BaseUIElement { assert(element !== null); if (this._isEnabled) { - //element.classList.add("button"); - element.classList.remove("input-text-disabled"); + // element.classList.add("button"); + element.classList.remove('input-text-disabled'); } else { - element.classList.add("input-text-disabled"); - //element.classList.remove("button"); + element.classList.add('input-text-disabled'); + // element.classList.remove("button"); } } -} \ No newline at end of file +} diff --git a/src/ui/elements/label.ts b/src/ui/elements/label.ts index ef661967..7e3975e4 100644 --- a/src/ui/elements/label.ts +++ b/src/ui/elements/label.ts @@ -1,4 +1,4 @@ -import { assert } from "../../util"; +import { assert } from '../../util'; export class LabelElement { private _id: string; @@ -22,9 +22,9 @@ export class LabelElement { assert(element !== null); if (isEnabled) { - element.classList.remove("sub-left-disabled"); + element.classList.remove('sub-left-disabled'); } else { - element.classList.add("sub-left-disabled"); + element.classList.add('sub-left-disabled'); } } -} \ No newline at end of file +} diff --git a/src/ui/elements/output.ts b/src/ui/elements/output.ts index 53991742..797414b4 100644 --- a/src/ui/elements/output.ts +++ b/src/ui/elements/output.ts @@ -1,6 +1,5 @@ -import { BaseUIElement } from "../layout"; -import { assert } from "../../util"; -import { ActionReturnType } from "../../app_context"; +import { assert } from '../../util'; +import { ActionReturnType } from '../../app_context'; export class OutputElement { private _id: string; @@ -21,12 +20,12 @@ export class OutputElement { assert(element !== null); element.innerHTML = message; - element.classList.remove("border-warning"); - element.classList.remove("border-error"); + element.classList.remove('border-warning'); + element.classList.remove('border-error'); if (returnType === ActionReturnType.Warning) { - element.classList.add("border-warning"); + element.classList.add('border-warning'); } else if (returnType === ActionReturnType.Failure) { - element.classList.add("border-error"); + element.classList.add('border-error'); } } -} \ No newline at end of file +} diff --git a/src/ui/elements/slider.ts b/src/ui/elements/slider.ts index 57f3b843..cabadff7 100644 --- a/src/ui/elements/slider.ts +++ b/src/ui/elements/slider.ts @@ -1,6 +1,6 @@ -import { BaseUIElement } from "../layout"; -import { assert } from "../../util"; -import { clamp } from "../../math"; +import { BaseUIElement } from '../layout'; +import { assert } from '../../util'; +import { clamp } from '../../math'; export class SliderElement extends BaseUIElement { private _min: number; @@ -36,13 +36,13 @@ export class SliderElement extends BaseUIElement { this._dragging = true; }; - document.addEventListener("mousemove", (e: any) => { + document.addEventListener('mousemove', (e: any) => { if (this._dragging) { this._updateValue(e); } }); - document.addEventListener("mouseup", (e: any) => { + document.addEventListener('mouseup', (e: any) => { if (this._dragging) { this._updateValue(e); } @@ -56,7 +56,7 @@ export class SliderElement extends BaseUIElement { } const element = document.getElementById(this._id) as HTMLDivElement; - const elementBar = document.getElementById(this._id + "-bar") as HTMLDivElement; + const elementBar = document.getElementById(this._id + '-bar') as HTMLDivElement; assert(element !== null && elementBar !== null); const mouseEvent = e as MouseEvent; @@ -73,17 +73,17 @@ export class SliderElement extends BaseUIElement { protected _onEnabledChanged() { const element = document.getElementById(this._id) as HTMLDivElement; - const elementBar = document.getElementById(this._id + "-bar") as HTMLDivElement; + const elementBar = document.getElementById(this._id + '-bar') as HTMLDivElement; assert(element !== null && elementBar !== null); if (this._isEnabled) { - //element.classList.add("button"); - element.classList.remove("new-slider-disabled"); - elementBar.classList.remove("new-slider-bar-disabled"); + // element.classList.add("button"); + element.classList.remove('new-slider-disabled'); + elementBar.classList.remove('new-slider-bar-disabled'); } else { - element.classList.add("new-slider-disabled"); - elementBar.classList.add("new-slider-bar-disabled"); - //element.classList.remove("button"); + element.classList.add('new-slider-disabled'); + elementBar.classList.add('new-slider-bar-disabled'); + // element.classList.remove("button"); } } -} \ No newline at end of file +} diff --git a/src/ui/layout.ts b/src/ui/layout.ts index 0a54451a..bda094b4 100644 --- a/src/ui/layout.ts +++ b/src/ui/layout.ts @@ -1,6 +1,6 @@ -import { ButtonElement } from "./elements/button"; -import { LabelElement } from "./elements/label"; -import { OutputElement } from "./elements/output"; +import { ButtonElement } from './elements/button'; +import { LabelElement } from './elements/label'; +import { OutputElement } from './elements/output'; export interface Group { label: string; @@ -47,7 +47,7 @@ function buildSubcomp(subcomp: Component) { } function buildComponent(componentParams: Group) { - let innerHTML = ""; + let innerHTML = ''; for (const subcomp of componentParams.components) { innerHTML += buildSubcomp(subcomp); } @@ -77,9 +77,9 @@ export function registerUI(uiGroups: Group[]) { } export function buildUI(myItems: Group[]) { - let itemHTML = ""; + let itemHTML = ''; for (const item of myItems) { - itemHTML += ` + itemHTML += `
@@ -94,10 +94,10 @@ export function buildUI(myItems: Group[]) {
`; - itemHTML += buildComponent(item); + itemHTML += buildComponent(item); } - document.getElementById("properties")!.innerHTML = `