forked from mirror/ObjToSchematic
Bad materials trees are now open by default
This commit is contained in:
parent
9a38dd8207
commit
47f0042d9e
@ -3,12 +3,12 @@ import path from 'path';
|
||||
|
||||
import { FallableBehaviour } from './block_mesh';
|
||||
import { ArcballCamera } from './camera';
|
||||
import { RGBAColours, RGBAUtil, RGBA } from './colour';
|
||||
import { RGBA, RGBAColours, RGBAUtil } from './colour';
|
||||
import { AppConfig } from './config';
|
||||
import { EAppEvent, EventManager } from './event';
|
||||
import { IExporter } from './exporters/base_exporter';
|
||||
import { ExporterFactory, TExporters } from './exporters/exporters';
|
||||
import { MaterialMap, MaterialType, TexturedMaterial, SolidMaterial } from './mesh';
|
||||
import { MaterialMap, MaterialType, SolidMaterial, TexturedMaterial } from './mesh';
|
||||
import { Renderer } from './renderer';
|
||||
import { StatusHandler, StatusMessage } from './status';
|
||||
import { TextureFiltering } from './texture';
|
||||
@ -19,6 +19,7 @@ import { ColourSpace, EAction, getRandomID } from './util';
|
||||
import { ASSERT } from './util/error_util';
|
||||
import { FileUtil } from './util/file_util';
|
||||
import { LOG, LOG_ERROR, Logger } from './util/log_util';
|
||||
import { AppPaths, PathUtil } from './util/path_util';
|
||||
import { TWorkerJob, WorkerController } from './worker_controller';
|
||||
import { SetMaterialsParams, TFromWorkerMessage, TToWorkerMessage } from './worker_types';
|
||||
|
||||
@ -233,6 +234,16 @@ export class AppContext {
|
||||
this._materialMap[materialName] = {
|
||||
type: MaterialType.solid,
|
||||
colour: RGBAUtil.copy(RGBAColours.WHITE),
|
||||
edited: true,
|
||||
canBeTextured: oldMaterial.canBeTextured,
|
||||
};
|
||||
} else {
|
||||
this._materialMap[materialName] = {
|
||||
type: MaterialType.textured,
|
||||
alphaFactor: 1.0,
|
||||
path: PathUtil.join(AppPaths.Get.static, 'debug.png'),
|
||||
edited: true,
|
||||
canBeTextured: oldMaterial.canBeTextured,
|
||||
};
|
||||
}
|
||||
|
||||
@ -251,6 +262,8 @@ export class AppContext {
|
||||
alphaFactor: oldMaterial.alphaFactor,
|
||||
alphaPath: oldMaterial.alphaPath,
|
||||
path: newTexturePath,
|
||||
edited: true,
|
||||
canBeTextured: oldMaterial.canBeTextured,
|
||||
};
|
||||
|
||||
this._sendMaterialsToWorker((result: SetMaterialsParams.Output) => {
|
||||
@ -260,9 +273,12 @@ export class AppContext {
|
||||
|
||||
private _onMaterialColourChanged(materialName: string, newColour: RGBA) {
|
||||
ASSERT(this._materialMap[materialName].type === MaterialType.solid);
|
||||
const oldMaterial = this._materialMap[materialName] as TexturedMaterial;
|
||||
this._materialMap[materialName] = {
|
||||
type: MaterialType.solid,
|
||||
colour: newColour,
|
||||
edited: true,
|
||||
canBeTextured: oldMaterial.canBeTextured,
|
||||
};
|
||||
|
||||
this._sendMaterialsToWorker((result: SetMaterialsParams.Output) => {
|
||||
@ -282,10 +298,10 @@ export class AppContext {
|
||||
continue;
|
||||
}
|
||||
|
||||
const subTree = UITreeBuilder.create(materialName);
|
||||
const subTree = UITreeBuilder.create(material.edited ? `<i>'${materialName}'*</i>` : `'${materialName}'`);
|
||||
if (material.type === MaterialType.solid) {
|
||||
const colourId = getRandomID();
|
||||
subTree.addChild({ text: `Colour: <input type="color" id="${colourId}" value="${RGBAUtil.toHexString(material.colour)}">`, warning: false }, () => {
|
||||
subTree.addChild({ text: `Colour: <input class="colour-swatch" type="color" id="${colourId}" value="${RGBAUtil.toHexString(material.colour)}">`, warning: false }, () => {
|
||||
const tmp = document.getElementById(colourId) as HTMLInputElement;
|
||||
if (tmp) {
|
||||
tmp.addEventListener('change', () => {
|
||||
@ -294,6 +310,17 @@ export class AppContext {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (material.canBeTextured) {
|
||||
// Add option to switch to texture material
|
||||
const switchId = getRandomID();
|
||||
subTree.addChild({ text: `<a id="${switchId}">[Switch to Texture]</a>`, warning: false }, () => {
|
||||
const tmp = document.getElementById(switchId) as HTMLLinkElement;
|
||||
tmp.onclick = () => {
|
||||
this._onMaterialTypeSwitched(materialName);
|
||||
};
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const parsedPath = path.parse(material.path);
|
||||
const dirId = getRandomID();
|
||||
@ -315,7 +342,8 @@ export class AppContext {
|
||||
}
|
||||
|
||||
// Add option to replace texture
|
||||
subTree.addChild({ text: `<a id="${replaceId}">[${isMissingTexture ? 'Find' : 'Replace' } Texture]</a>`, warning: false }, () => {
|
||||
const text = isMissingTexture ? `<b><a id="${replaceId}">[Find Texture]</a></b>` : `<a id="${replaceId}">[Replace Texture]</a>`;
|
||||
subTree.addChild({ text: text, warning: false }, () => {
|
||||
const tmp = document.getElementById(replaceId) as HTMLLinkElement;
|
||||
if (tmp) {
|
||||
tmp.onclick = () => {
|
||||
|
@ -22,7 +22,7 @@ export class ObjImporter extends IImporter {
|
||||
private _tris: Tri[] = [];
|
||||
|
||||
private _materials: { [key: string]: (SolidMaterial | TexturedMaterial) } = {
|
||||
'DEFAULT_UNASSIGNED': { type: MaterialType.solid, colour: RGBAColours.WHITE },
|
||||
'DEFAULT_UNASSIGNED': { type: MaterialType.solid, colour: RGBAColours.WHITE, edited: true, canBeTextured: false },
|
||||
};
|
||||
private _mtlLibs: string[] = [];
|
||||
private _currentMaterialName: string = 'DEFAULT_UNASSIGNED';
|
||||
@ -396,12 +396,16 @@ export class ObjImporter extends IImporter {
|
||||
path: this._currentTexture,
|
||||
alphaPath: this._currentTransparencyTexture === '' ? undefined : this._currentTransparencyTexture,
|
||||
alphaFactor: this._currentAlpha,
|
||||
edited: false,
|
||||
canBeTextured: true,
|
||||
};
|
||||
this._currentTransparencyTexture = '';
|
||||
} else {
|
||||
this._materials[this._currentMaterialName] = {
|
||||
type: MaterialType.solid,
|
||||
colour: this._currentColour,
|
||||
edited: false,
|
||||
canBeTextured: false,
|
||||
};
|
||||
}
|
||||
this._currentAlpha = 1.0;
|
||||
|
45
src/mesh.ts
45
src/mesh.ts
@ -28,8 +28,13 @@ export interface Tri {
|
||||
/* eslint-disable */
|
||||
export enum MaterialType { solid, textured }
|
||||
/* eslint-enable */
|
||||
export interface SolidMaterial { colour: RGBA; type: MaterialType.solid }
|
||||
export interface TexturedMaterial {
|
||||
type BaseMaterial = {
|
||||
edited: boolean,
|
||||
canBeTextured: boolean,
|
||||
}
|
||||
|
||||
export type SolidMaterial = BaseMaterial & { colour: RGBA; type: MaterialType.solid }
|
||||
export type TexturedMaterial = BaseMaterial & {
|
||||
path: string;
|
||||
type: MaterialType.textured;
|
||||
alphaPath?: string;
|
||||
@ -146,9 +151,6 @@ export class Mesh {
|
||||
}
|
||||
|
||||
// Check used materials exist
|
||||
let wasRemapped = false;
|
||||
const debugName = (Math.random() + 1).toString(36).substring(7);
|
||||
|
||||
const missingMaterials = new Set<string>();
|
||||
for (const tri of this._tris) {
|
||||
if (!(tri.material in this._materials)) {
|
||||
@ -157,27 +159,28 @@ export class Mesh {
|
||||
|
||||
if (tri.texcoordIndices === undefined) {
|
||||
// No texcoords are defined, therefore make a solid material
|
||||
this._materials[tri.material] = { type: MaterialType.solid, colour: RGBAColours.MAGENTA };
|
||||
this._materials[tri.material] = {
|
||||
type: MaterialType.solid,
|
||||
colour: RGBAColours.MAGENTA,
|
||||
edited: true,
|
||||
canBeTextured: false,
|
||||
};
|
||||
} else {
|
||||
// Texcoords exist, therefore make a texture material
|
||||
this._materials[tri.material] = { type: MaterialType.textured, path: PathUtil.join(AppPaths.Get.static, 'debug.png'), alphaFactor: 1.0 };
|
||||
this._materials[tri.material] = {
|
||||
type: MaterialType.textured,
|
||||
path: PathUtil.join(AppPaths.Get.static, 'debug.png'),
|
||||
alphaFactor: 1.0,
|
||||
edited: true,
|
||||
canBeTextured: true,
|
||||
};
|
||||
}
|
||||
|
||||
missingMaterials.add(tri.material);
|
||||
wasRemapped = true;
|
||||
tri.material = debugName;
|
||||
}
|
||||
}
|
||||
if (wasRemapped) {
|
||||
if (missingMaterials.size > 0) {
|
||||
LOG_WARN('Triangles use these materials but they were not found', missingMaterials);
|
||||
//StatusHandler.Get.add(
|
||||
// 'warning',
|
||||
// 'Some materials were not loaded correctly',
|
||||
//);
|
||||
this._materials[debugName] = {
|
||||
type: MaterialType.solid,
|
||||
colour: RGBAColours.WHITE,
|
||||
};
|
||||
}
|
||||
|
||||
// Check texture paths are absolute and exist
|
||||
@ -194,6 +197,8 @@ export class Mesh {
|
||||
this._materials[materialName] = {
|
||||
type: MaterialType.solid,
|
||||
colour: RGBAColours.WHITE,
|
||||
edited: true,
|
||||
canBeTextured: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -365,6 +370,8 @@ export class Mesh {
|
||||
materials[materialName] = {
|
||||
type: MaterialType.solid,
|
||||
colour: RGBAUtil.copy(material.colour),
|
||||
edited: material.edited,
|
||||
canBeTextured: material.canBeTextured,
|
||||
};
|
||||
} else {
|
||||
materials[materialName] = {
|
||||
@ -372,6 +379,8 @@ export class Mesh {
|
||||
alphaFactor: material.alphaFactor,
|
||||
alphaPath: material.alphaPath,
|
||||
path: material.path,
|
||||
edited: material.edited,
|
||||
canBeTextured: material.canBeTextured,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -181,6 +181,8 @@ export class Renderer {
|
||||
material: {
|
||||
type: MaterialType.textured,
|
||||
path: material.path,
|
||||
edited: material.edited,
|
||||
canBeTextured: material.canBeTextured,
|
||||
texture: twgl.createTexture(this._gl, {
|
||||
src: material.path,
|
||||
mag: this._gl.LINEAR,
|
||||
@ -204,6 +206,8 @@ export class Renderer {
|
||||
buffer.material = {
|
||||
type: MaterialType.textured,
|
||||
path: material.path,
|
||||
edited: material.edited,
|
||||
canBeTextured: material.canBeTextured,
|
||||
texture: twgl.createTexture(this._gl, {
|
||||
src: material.path,
|
||||
mag: this._gl.LINEAR,
|
||||
@ -236,6 +240,8 @@ export class Renderer {
|
||||
this._materialBuffers.set(materialName, {
|
||||
buffer: twgl.createBufferInfoFromArrays(this._gl, buffer),
|
||||
material: {
|
||||
edited: material.edited,
|
||||
canBeTextured: material.canBeTextured,
|
||||
type: MaterialType.textured,
|
||||
path: material.path,
|
||||
texture: twgl.createTexture(this._gl, {
|
||||
|
@ -80,8 +80,8 @@ export class UITreeBuilder implements IUIOutputElement {
|
||||
|
||||
if (this.getWarning()) {
|
||||
return `
|
||||
<span class="caret" style="color:orange;" >${this._rootLabel}</span>
|
||||
<ul class="nested">${childrenHTML}</ul>
|
||||
<span class="caret caret-down" style="color:orange;" >${this._rootLabel}</span>
|
||||
<ul class="nested active">${childrenHTML}</ul>
|
||||
`;
|
||||
} else {
|
||||
return `
|
||||
@ -170,7 +170,7 @@ export class UIMessageBuilder {
|
||||
this._messages.push({
|
||||
groupId: groupId, body: `
|
||||
<div style="display: flex; align-items: center; color: var(--text-standard)">
|
||||
<div style="margin-right: 8px;" class="loader-circle spin"></div>
|
||||
<div style="margin-right: 8px;" class="loader-circle spin"></div>
|
||||
<b class="spin">${message}</b>
|
||||
</div>
|
||||
`});
|
||||
|
13
styles.css
13
styles.css
@ -657,4 +657,17 @@ a {
|
||||
}
|
||||
a:hover {
|
||||
color: var(--text-standard) !important;
|
||||
}
|
||||
|
||||
.colour-swatch {
|
||||
border: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.colour-swatch::-webkit-color-swatch {
|
||||
border: none;
|
||||
border-radius: 15px;
|
||||
}
|
Loading…
Reference in New Issue
Block a user