* Added 'rotation' option when loading a model

* Fixed `voxelise` action not enabling after `import` action succeeds
This commit is contained in:
Lucas Dower 2023-01-21 00:25:02 +00:00
parent 57ac9dd714
commit e4e95b0a1f
No known key found for this signature in database
GPG Key ID: B3EE6B8499593605
12 changed files with 71 additions and 46 deletions

View File

@ -188,6 +188,7 @@ export class AppContext {
action: 'Import',
params: {
filepath: uiElements.input.getValue(),
rotation: uiElements.rotation.getValue(),
},
};
@ -295,7 +296,7 @@ export class AppContext {
const callback = (payload: TFromWorkerMessage) => {
// This callback is not managed through `AppContext::do`, therefore
// we need to check the payload is not an error
this._ui.enableTo(EAction.Materials);
this._ui.enableTo(EAction.Voxelise);
switch (payload.action) {
case 'KnownError':

View File

@ -3,6 +3,7 @@ import path from 'path';
import { Bounds } from './bounds';
import { RGBA, RGBAColours, RGBAUtil } from './colour';
import { degreesToRadians } from './math';
import { StatusHandler } from './status';
import { Texture, TextureConverter, TextureFiltering } from './texture';
import { Triangle, UVTriangle } from './triangle';
@ -81,6 +82,39 @@ export class Mesh {
this._loadTextures();
}
public rotateMesh(pitch: number, roll: number, yaw: number) {
const cosa = Math.cos(yaw * degreesToRadians);
const sina = Math.sin(yaw * degreesToRadians);
const cosb = Math.cos(pitch * degreesToRadians);
const sinb = Math.sin(pitch * degreesToRadians);
const cosc = Math.cos(roll * degreesToRadians);
const sinc = Math.sin(roll * degreesToRadians);
const Axx = cosa*cosb;
const Axy = cosa*sinb*sinc - sina*cosc;
const Axz = cosa*sinb*cosc + sina*sinc;
const Ayx = sina*cosb;
const Ayy = sina*sinb*sinc + cosa*cosc;
const Ayz = sina*sinb*cosc - cosa*sinc;
const Azx = -sinb;
const Azy = cosb*sinc;
const Azz = cosb*cosc;
this._vertices.forEach((vertex) => {
const px = vertex.x;
const py = vertex.y;
const pz = vertex.z;
vertex.x = Axx * px + Axy * py + Axz * pz;
vertex.y = Ayx * px + Ayy * py + Ayz * pz;
vertex.z = Azx * px + Azy * py + Azz * pz;
});
}
public getBounds() {
const bounds = Bounds.getInfiniteBounds();
if (this._transform) {

View File

@ -11,7 +11,7 @@ export class VectorSpinboxElement extends ConfigUIElement<Vector3, HTMLDivElemen
private _showY: boolean;
public constructor() {
super();
super(new Vector3(0, 0, 0));
this._mouseover = null;
this._dragging = null;
this._lastClientX = 0.0;
@ -67,37 +67,18 @@ export class VectorSpinboxElement extends ConfigUIElement<Vector3, HTMLDivElemen
}
private _registerAxis(axis: TAxis) {
const elementKey = UIUtil.getElementById(this._getKeyId(axis));
const elementValue = UIUtil.getElementById(this._getValueId(axis));
elementKey.onmouseenter = () => {
this._mouseover = axis;
if (this.getEnabled()) {
elementKey.classList.add('spinbox-key-hover');
elementValue.classList.add('spinbox-value-hover');
}
};
elementValue.onmouseenter = () => {
this._mouseover = axis;
if (this.getEnabled()) {
elementKey.classList.add('spinbox-key-hover');
elementValue.classList.add('spinbox-value-hover');
}
};
elementKey.onmouseleave = () => {
this._mouseover = null;
if (this._dragging !== axis) {
elementKey.classList.remove('spinbox-key-hover');
elementValue.classList.remove('spinbox-value-hover');
}
};
elementValue.onmouseleave = () => {
this._mouseover = null;
if (this._dragging !== axis) {
elementKey.classList.remove('spinbox-key-hover');
elementValue.classList.remove('spinbox-value-hover');
}
};
@ -125,9 +106,7 @@ export class VectorSpinboxElement extends ConfigUIElement<Vector3, HTMLDivElemen
document.addEventListener('mouseup', () => {
if (this._dragging !== null) {
const elementKey = UIUtil.getElementById(this._getKeyId(this._dragging));
const elementValue = UIUtil.getElementById(this._getKeyId(this._dragging));
elementKey.classList.remove('spinbox-key-hover');
elementValue.classList.remove('spinbox-value-hover');
}

View File

@ -25,6 +25,7 @@ import { FileInputElement } from './elements/file_input';
import { OutputElement } from './elements/output';
import { SliderElement } from './elements/slider';
import { ToolbarItemElement } from './elements/toolbar_item';
import { VectorSpinboxElement } from './elements/vector_spinbox';
export interface Group {
label: string;
@ -48,8 +49,10 @@ export class UI {
'input': new FileInputElement()
.setFileExtensions(['obj'])
.setLabel('Wavefront .obj file'),
'rotation': new VectorSpinboxElement()
.setLabel('Rotation'),
},
elementsOrder: ['input'],
elementsOrder: ['input', 'rotation'],
submitButton: new ButtonElement()
.setOnClick(() => {
this._appContext.do(EAction.Import);

View File

@ -75,6 +75,7 @@ export class WorkerClient {
importer.parseFile(params.filepath);
this._loadedMesh = importer.toMesh();
this._loadedMesh.processMesh();
this._loadedMesh.rotateMesh(params.rotation.y, params.rotation.x, params.rotation.z);
return {
triangleCount: this._loadedMesh.getTriangleCount(),

View File

@ -21,20 +21,10 @@ export namespace InitParams {
}
}
export namespace SetMaterialsParams {
export type Input = {
materials: MaterialMap
}
export type Output = {
materials: MaterialMap,
materialsChanged: string[],
}
}
export namespace ImportParams {
export type Input = {
filepath: string,
rotation: Vector3,
}
export type Output = {
@ -55,6 +45,17 @@ export namespace RenderMeshParams {
}
}
export namespace SetMaterialsParams {
export type Input = {
materials: MaterialMap
}
export type Output = {
materials: MaterialMap,
materialsChanged: string[],
}
}
export namespace VoxeliseParams {
export type Input = {
constraintAxis: TAxis,

View File

@ -395,23 +395,20 @@ select:disabled {
}
.spinbox-value {
display: flex;
align-items: center;
justify-content: center;
height: calc(var(--property-height) - 2px);
background: var(--prop-standard);
border-radius: 5px;
flex-grow: 1;
height: calc(32px - 8.5px);
padding: 8.5px 0px 0px 0px;
font-weight: 300;
border-width: 1px 1px 1px 0px;
border-style: solid;
border: rgba(255, 255, 255, 0.0);
color: var(--text-disabled);
align-self: center;
text-align: center;
border: 1px solid rgba(255, 255, 255, 0.0);
color: var(--text-standard);
}
.spinbox-value-hover {
border: rgba(255, 255, 255, 0.2) !important;
border: 1px solid rgba(255, 255, 255, 0.2) !important;
background: var(--prop-hovered) !important;
cursor: ew-resize;
}

View File

@ -1,12 +1,14 @@
import { TextureFiltering } from '../src/texture';
import { ColourSpace } from '../src/util';
import { AppPaths, PathUtil } from '../src/util/path_util';
import { Vector3 } from '../src/vector';
import { runHeadless, THeadlessConfig } from '../tools/headless';
import { TEST_PREAMBLE } from './preamble';
const baseConfig: THeadlessConfig = {
import: {
filepath: '', // Must be an absolute path
rotation: new Vector3(0, 0, 0),
},
voxelise: {
voxeliser: 'bvh-ray',

View File

@ -1,12 +1,14 @@
import { TextureFiltering } from '../src/texture';
import { ColourSpace } from '../src/util';
import { AppPaths, PathUtil } from '../src/util/path_util';
import { Vector3 } from '../src/vector';
import { runHeadless, THeadlessConfig } from '../tools/headless';
import { TEST_PREAMBLE } from './preamble';
const baseConfig: THeadlessConfig = {
import: {
filepath: '', // Must be an absolute path
rotation: new Vector3(0, 0, 0),
},
voxelise: {
voxeliser: 'bvh-ray',

View File

@ -1,12 +1,14 @@
import { TextureFiltering } from '../src/texture';
import { ColourSpace } from '../src/util';
import { AppPaths, PathUtil } from '../src/util/path_util';
import { Vector3 } from '../src/vector';
import { runHeadless, THeadlessConfig } from '../tools/headless';
import { TEST_PREAMBLE } from './preamble';
const baseConfig: THeadlessConfig = {
import: {
filepath: '', // Must be an absolute path
rotation: new Vector3(0, 0, 0),
},
voxelise: {
voxeliser: 'bvh-ray',

View File

@ -1,12 +1,14 @@
import { TextureFiltering } from '../src/texture';
import { ColourSpace } from '../src/util';
import { AppPaths, PathUtil } from '../src/util/path_util';
import { Vector3 } from '../src/vector';
import { runHeadless, THeadlessConfig } from '../tools/headless';
import { TEST_PREAMBLE } from './preamble';
const baseConfig: THeadlessConfig = {
import: {
filepath: '', // Must be an absolute path
rotation: new Vector3(0, 0, 0),
},
voxelise: {
voxeliser: 'bvh-ray',

View File

@ -1,10 +1,11 @@
import { TextureFiltering } from '../src/texture';
import { ColourSpace } from '../src/util';
import { Vector3 } from '../src/vector';
import { THeadlessConfig } from './headless';
export const headlessConfig: THeadlessConfig = {
import: {
filepath: '/Users/lucasdower/ObjToSchematic/res/samples/skull.obj', // Must be an absolute path
rotation: new Vector3(0, 0, 0),
},
voxelise: {
constraintAxis: 'y',