mirror of
https://github.com/LucasDower/ObjToSchematic.git
synced 2025-02-23 13:49:07 +08:00
Tidied how progress is announced
This commit is contained in:
parent
b495aa73a3
commit
f8f57ba0b8
@ -67,15 +67,10 @@ export class BlockMesh {
|
||||
const blockAssigner = BlockAssignerFactory.GetAssigner(blockMeshParams.blockAssigner);
|
||||
|
||||
let countFalling = 0;
|
||||
let nextPercentage = 0.0;
|
||||
ProgressManager.Get.start('Assigning');
|
||||
const taskHandle = ProgressManager.Get.start('Assigning');
|
||||
const voxels = this._voxelMesh.getVoxels();
|
||||
for (let voxelIndex = 0; voxelIndex < voxels.length; ++voxelIndex) {
|
||||
const percentage = voxelIndex / voxels.length;
|
||||
if (voxelIndex / voxels.length >= nextPercentage) {
|
||||
ProgressManager.Get.progress('Assigning', percentage);
|
||||
nextPercentage += 0.05;
|
||||
}
|
||||
ProgressManager.Get.progress(taskHandle, voxelIndex / voxels.length);
|
||||
|
||||
const voxel = voxels[voxelIndex];
|
||||
let block = blockAssigner.assignBlock(atlasPalette, voxel.colour, voxel.position, blockMeshParams.colourSpace);
|
||||
@ -104,7 +99,7 @@ export class BlockMesh {
|
||||
this._blocksUsed.push(block.name);
|
||||
}
|
||||
}
|
||||
ProgressManager.Get.end('Assigning');
|
||||
ProgressManager.Get.end(taskHandle);
|
||||
|
||||
if (blockMeshParams.fallable === 'do-nothing' && countFalling > 0) {
|
||||
StatusHandler.Get.add('warning', `${countFalling.toLocaleString()} blocks will fall under gravity when this structure is placed`);
|
||||
|
@ -71,8 +71,7 @@ export class BufferGenerator {
|
||||
const materialBuffers: TMeshBufferDescription[] = [];
|
||||
|
||||
let trianglesHandled = 0;
|
||||
let nextPercentage = 0;
|
||||
ProgressManager.Get.start('MeshBuffer');
|
||||
const taskHandle = ProgressManager.Get.start('MeshBuffer');
|
||||
|
||||
// Create the buffers for each material and fill with data from the triangles
|
||||
materialTriangleCount.forEach((triangleCount: number, materialName: string) => {
|
||||
@ -80,11 +79,7 @@ export class BufferGenerator {
|
||||
|
||||
let insertIndex = 0;
|
||||
for (let triIndex = 0; triIndex < numTris; ++triIndex) {
|
||||
const percentage = trianglesHandled / numTris;
|
||||
if (percentage >= nextPercentage) {
|
||||
ProgressManager.Get.progress('MeshBuffer', percentage);
|
||||
nextPercentage += 0.05;
|
||||
}
|
||||
ProgressManager.Get.progress(taskHandle, trianglesHandled / numTris);
|
||||
|
||||
const material = mesh.getMaterialByTriangle(triIndex);
|
||||
if (material === materialName) {
|
||||
@ -135,7 +130,7 @@ export class BufferGenerator {
|
||||
});
|
||||
});
|
||||
|
||||
ProgressManager.Get.end('MeshBuffer');
|
||||
ProgressManager.Get.end(taskHandle);
|
||||
|
||||
return materialBuffers;
|
||||
}
|
||||
@ -147,14 +142,9 @@ export class BufferGenerator {
|
||||
const cube: AttributeData = GeometryTemplates.getBoxBufferData(new Vector3(0, 0, 0));
|
||||
const voxels = voxelMesh.getVoxels();
|
||||
|
||||
let nextPercentage = 0.0;
|
||||
ProgressManager.Get.start('VoxelMeshBuffer');
|
||||
const taskHandle = ProgressManager.Get.start('VoxelMeshBuffer');
|
||||
for (let i = 0; i < numVoxels; ++i) {
|
||||
const percentage = i / numVoxels;
|
||||
if (i / numVoxels >= nextPercentage) {
|
||||
ProgressManager.Get.progress('VoxelMeshBuffer', percentage);
|
||||
nextPercentage += 0.05;
|
||||
}
|
||||
ProgressManager.Get.progress(taskHandle, i / numVoxels);
|
||||
|
||||
const voxel = voxels[i];
|
||||
const voxelColourArray = [voxel.colour.r, voxel.colour.g, voxel.colour.b, voxel.colour.a];
|
||||
@ -187,7 +177,7 @@ export class BufferGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
ProgressManager.Get.end('VoxelMeshBuffer');
|
||||
ProgressManager.Get.end(taskHandle);
|
||||
|
||||
return {
|
||||
buffer: newBuffer,
|
||||
@ -204,14 +194,9 @@ export class BufferGenerator {
|
||||
const faceOrder = ['north', 'south', 'up', 'down', 'east', 'west'];
|
||||
let insertIndex = 0;
|
||||
|
||||
let nextPercentage = 0.0;
|
||||
ProgressManager.Get.start('BlockMeshBuffer');
|
||||
const taskHandle = ProgressManager.Get.start('BlockMeshBuffer');
|
||||
for (let i = 0; i < numBlocks; ++i) {
|
||||
const percentage = i / numBlocks;
|
||||
if (i / numBlocks >= nextPercentage) {
|
||||
ProgressManager.Get.progress('BlockMeshBuffer', percentage);
|
||||
nextPercentage += 0.05;
|
||||
}
|
||||
ProgressManager.Get.progress(taskHandle, i / numBlocks);
|
||||
|
||||
for (let f = 0; f < AppConstants.FACES_PER_VOXEL; ++f) {
|
||||
const faceName = faceOrder[f];
|
||||
@ -222,7 +207,7 @@ export class BufferGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
ProgressManager.Get.end('BlockMeshBuffer');
|
||||
ProgressManager.Get.end(taskHandle);
|
||||
|
||||
return {
|
||||
buffer: newBuffer,
|
||||
|
@ -1,6 +1,19 @@
|
||||
import { EAppEvent, EventManager } from './event';
|
||||
import { ASSERT } from './util/error_util';
|
||||
|
||||
export type TTaskID =
|
||||
| 'Importing'
|
||||
| 'MeshBuffer'
|
||||
| 'Voxelising'
|
||||
| 'VoxelMeshBuffer'
|
||||
| 'Assigning'
|
||||
| 'BlockMeshBuffer'
|
||||
| 'Exporting';
|
||||
|
||||
export type TTaskHandle = {
|
||||
nextPercentage: number,
|
||||
id: TTaskID,
|
||||
}
|
||||
|
||||
export class ProgressManager {
|
||||
/* Singleton */
|
||||
@ -9,7 +22,7 @@ export class ProgressManager {
|
||||
return this._instance || (this._instance = new this());
|
||||
}
|
||||
|
||||
private _tasks: string[];
|
||||
private _tasks: TTaskID[];
|
||||
|
||||
private constructor() {
|
||||
this._tasks = [];
|
||||
@ -18,35 +31,38 @@ export class ProgressManager {
|
||||
/**
|
||||
* Start tracking the progress of a task.
|
||||
* @param taskId The id of the task (created here).
|
||||
* @param max The maximum number the task progress index can reach.
|
||||
* For example, if you are iterating over an array of 1000 elements, this will be 1000.
|
||||
* @param divisions The number of updates the manager should track.
|
||||
* For example, 4 means an event will be emitted for 20%, 40%, 60%, 80% progress.
|
||||
*/
|
||||
public start(taskId: string) {
|
||||
public start(taskId: TTaskID): TTaskHandle {
|
||||
ASSERT(!this._tasks.includes(taskId), 'Task with that Id already being tracked');
|
||||
this._tasks.push(taskId);
|
||||
EventManager.Get.broadcast(EAppEvent.onTaskStart, taskId);
|
||||
|
||||
return {
|
||||
nextPercentage: 0.0,
|
||||
id: taskId,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Announce progress has been made on a task.
|
||||
* @param taskId The id of the task (created in `start`).
|
||||
* @param progressIndex The index of the progress made so far.
|
||||
* For example, if you are iteratinve over an array of 1000 elements, and are on index 230, this should be 230.
|
||||
* @param percentage A number between 0.0 and 1.0, inclusive.
|
||||
*/
|
||||
public progress(taskId: string, percentage: number) {
|
||||
EventManager.Get.broadcast(EAppEvent.onTaskProgress, taskId, percentage);
|
||||
public progress(tracker: TTaskHandle, percentage: number) {
|
||||
if (percentage > tracker.nextPercentage) {
|
||||
EventManager.Get.broadcast(EAppEvent.onTaskProgress, tracker.id, percentage);
|
||||
tracker.nextPercentage += 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Announce a task has completed.
|
||||
* @param taskId The id of the task (created in `start`).
|
||||
*/
|
||||
public end(taskId: string) {
|
||||
const taskIndex = this._tasks.findIndex((task) => { return task === taskId });
|
||||
public end(tracker: TTaskHandle) {
|
||||
const taskIndex = this._tasks.findIndex((task) => { return task === tracker.id; });
|
||||
ASSERT(taskIndex !== -1, 'Task with that Id is not being tracked');
|
||||
this._tasks.splice(taskIndex, 1);
|
||||
EventManager.Get.broadcast(EAppEvent.onTaskEnd, taskId);
|
||||
EventManager.Get.broadcast(EAppEvent.onTaskEnd, tracker.id);
|
||||
}
|
||||
}
|
||||
|
@ -78,14 +78,9 @@ export class BVHRayVoxeliser extends IVoxeliser {
|
||||
LOG('Rays created...');
|
||||
|
||||
// Ray test BVH
|
||||
let nextPercentage = 0.0;
|
||||
ProgressManager.Get.start('Voxelising');
|
||||
const taskHandle = ProgressManager.Get.start('Voxelising');
|
||||
for (rayIndex = 0; rayIndex < rays.length; ++rayIndex) {
|
||||
const percentage = rayIndex / rays.length;
|
||||
if (rayIndex / rays.length >= nextPercentage) {
|
||||
ProgressManager.Get.progress('Voxelising', percentage);
|
||||
nextPercentage += 0.05;
|
||||
}
|
||||
ProgressManager.Get.progress(taskHandle, rayIndex / rays.length);
|
||||
|
||||
const ray = rays[rayIndex];
|
||||
const intersections = bvh.intersectRay(ray.origin, axesToDirection(ray.axis), false);
|
||||
@ -107,7 +102,7 @@ export class BVHRayVoxeliser extends IVoxeliser {
|
||||
}
|
||||
}
|
||||
}
|
||||
ProgressManager.Get.end('Voxelising');
|
||||
ProgressManager.Get.end(taskHandle);
|
||||
|
||||
return voxelMesh;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import { Bounds } from '../bounds';
|
||||
import { RGBA, RGBAUtil } from '../colour';
|
||||
import { AppConfig } from '../config';
|
||||
import { Mesh } from '../mesh';
|
||||
import { ProgressManager } from '../progress';
|
||||
import { Axes, Ray, rayIntersectTriangle } from '../ray';
|
||||
import { Triangle, UVTriangle } from '../triangle';
|
||||
import { UV } from '../util';
|
||||
@ -33,36 +34,42 @@ export class NormalCorrectedRayVoxeliser extends IVoxeliser {
|
||||
useMesh.scaleMesh(this._scale);
|
||||
const bounds = useMesh.getBounds();
|
||||
this._size = Vector3.sub(bounds.max, bounds.min);
|
||||
this._offset =new Vector3(
|
||||
this._offset = new Vector3(
|
||||
this._size.x % 2 < 0.001 ? 0.5 : 0.0,
|
||||
this._size.y % 2 < 0.001 ? 0.5 : 0.0,
|
||||
this._size.z % 2 < 0.001 ? 0.5 : 0.0,
|
||||
);
|
||||
|
||||
for (let triIndex = 0; triIndex < useMesh.getTriangleCount(); ++triIndex) {
|
||||
const numTris = useMesh.getTriangleCount();
|
||||
|
||||
const taskHandle = ProgressManager.Get.start('Voxelising');
|
||||
for (let triIndex = 0; triIndex < numTris; ++triIndex) {
|
||||
ProgressManager.Get.progress(taskHandle, triIndex / numTris);
|
||||
|
||||
const uvTriangle = useMesh.getUVTriangle(triIndex);
|
||||
const normals = useMesh.getNormals(triIndex);
|
||||
const material = useMesh.getMaterialByTriangle(triIndex);
|
||||
this._voxeliseTri(uvTriangle, material, normals);
|
||||
}
|
||||
ProgressManager.Get.end(taskHandle);
|
||||
|
||||
return this._voxelMesh;
|
||||
}
|
||||
|
||||
private _voxeliseTri(triangle: UVTriangle, materialName: string, normals: { v0: Vector3, v1: Vector3, v2: Vector3}) {
|
||||
private _voxeliseTri(triangle: UVTriangle, materialName: string, normals: { v0: Vector3, v1: Vector3, v2: Vector3 }) {
|
||||
const rayList = this._generateRays(triangle.v0, triangle.v1, triangle.v2,
|
||||
this._offset,
|
||||
);
|
||||
|
||||
|
||||
rayList.forEach((ray) => {
|
||||
const intersection = rayIntersectTriangle(ray, triangle.v0, triangle.v1, triangle.v2);
|
||||
if (intersection) {
|
||||
if (intersection) {
|
||||
// Move transition away from normal
|
||||
const norm = normals.v0.normalise();
|
||||
intersection.sub(Vector3.mulScalar(norm, 0.5));
|
||||
// Correct size parity
|
||||
intersection.add(this._offset);
|
||||
|
||||
|
||||
let voxelPosition: Vector3;
|
||||
switch (ray.axis) {
|
||||
case Axes.x:
|
||||
@ -109,7 +116,7 @@ export class NormalCorrectedRayVoxeliser extends IVoxeliser {
|
||||
triangle.uv0.u * w0 + triangle.uv1.u * w1 + triangle.uv2.u * w2,
|
||||
triangle.uv0.v * w0 + triangle.uv1.v * w1 + triangle.uv2.v * w2,
|
||||
);
|
||||
|
||||
|
||||
return this._mesh!.sampleMaterial(materialName, uv, this._voxeliseParams!.textureFiltering);
|
||||
}
|
||||
|
||||
@ -126,14 +133,14 @@ export class NormalCorrectedRayVoxeliser extends IVoxeliser {
|
||||
Math.floor(Math.max(v0.z, v1.z, v2.z)),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
const rayList: Array<Ray> = [];
|
||||
this._traverseX(rayList, bounds, offset);
|
||||
this._traverseY(rayList, bounds, offset);
|
||||
this._traverseZ(rayList, bounds, offset);
|
||||
return rayList;
|
||||
}
|
||||
|
||||
|
||||
private _traverseX(rayList: Array<Ray>, bounds: Bounds, offset: Vector3) {
|
||||
for (let y = bounds.min.y - offset.y; y <= bounds.max.y + offset.y; ++y) {
|
||||
for (let z = bounds.min.z - offset.z; z <= bounds.max.z + offset.z; ++z) {
|
||||
@ -144,7 +151,7 @@ export class NormalCorrectedRayVoxeliser extends IVoxeliser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private _traverseY(rayList: Array<Ray>, bounds: Bounds, offset: Vector3) {
|
||||
for (let x = bounds.min.x - offset.x; x <= bounds.max.x + offset.x; ++x) {
|
||||
for (let z = bounds.min.z - offset.z; z <= bounds.max.z + offset.z; ++z) {
|
||||
@ -155,7 +162,7 @@ export class NormalCorrectedRayVoxeliser extends IVoxeliser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private _traverseZ(rayList: Array<Ray>, bounds: Bounds, offset: Vector3) {
|
||||
for (let x = bounds.min.x - offset.x; x <= bounds.max.x + offset.x; ++x) {
|
||||
for (let y = bounds.min.y - offset.y; y <= bounds.max.y + offset.y; ++y) {
|
||||
|
@ -2,6 +2,7 @@ import { Bounds } from '../bounds';
|
||||
import { RGBA, RGBAUtil } from '../colour';
|
||||
import { AppConfig } from '../config';
|
||||
import { Mesh } from '../mesh';
|
||||
import { ProgressManager } from '../progress';
|
||||
import { Axes, Ray, rayIntersectTriangle } from '../ray';
|
||||
import { Triangle, UVTriangle } from '../triangle';
|
||||
import { UV } from '../util';
|
||||
@ -33,18 +34,24 @@ export class RayVoxeliser extends IVoxeliser {
|
||||
useMesh.scaleMesh(this._scale);
|
||||
useMesh.translateMesh(this._offset);
|
||||
|
||||
for (let triIndex = 0; triIndex < useMesh.getTriangleCount(); ++triIndex) {
|
||||
const numTris = useMesh.getTriangleCount();
|
||||
|
||||
const taskHandle = ProgressManager.Get.start('Voxelising');
|
||||
for (let triIndex = 0; triIndex < numTris; ++triIndex) {
|
||||
ProgressManager.Get.progress(taskHandle, triIndex / numTris);
|
||||
|
||||
const uvTriangle = useMesh.getUVTriangle(triIndex);
|
||||
const material = useMesh.getMaterialByTriangle(triIndex);
|
||||
this._voxeliseTri(uvTriangle, material);
|
||||
}
|
||||
ProgressManager.Get.end(taskHandle);
|
||||
|
||||
return this._voxelMesh;
|
||||
}
|
||||
|
||||
private _voxeliseTri(triangle: UVTriangle, materialName: string) {
|
||||
const rayList = this._generateRays(triangle.v0, triangle.v1, triangle.v2);
|
||||
|
||||
|
||||
rayList.forEach((ray) => {
|
||||
const intersection = rayIntersectTriangle(ray, triangle.v0, triangle.v1, triangle.v2);
|
||||
if (intersection) {
|
||||
@ -93,7 +100,7 @@ export class RayVoxeliser extends IVoxeliser {
|
||||
triangle.uv0.u * w0 + triangle.uv1.u * w1 + triangle.uv2.u * w2,
|
||||
triangle.uv0.v * w0 + triangle.uv1.v * w1 + triangle.uv2.v * w2,
|
||||
);
|
||||
|
||||
|
||||
return this._mesh!.sampleMaterial(materialName, uv, this._voxeliseParams!.textureFiltering);
|
||||
}
|
||||
|
||||
@ -110,14 +117,14 @@ export class RayVoxeliser extends IVoxeliser {
|
||||
Math.ceil(Math.max(v0.z, v1.z, v2.z)),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
const rayList: Array<Ray> = [];
|
||||
this._traverseX(rayList, bounds);
|
||||
this._traverseY(rayList, bounds);
|
||||
this._traverseZ(rayList, bounds);
|
||||
return rayList;
|
||||
}
|
||||
|
||||
|
||||
private _traverseX(rayList: Array<Ray>, bounds: Bounds) {
|
||||
for (let y = bounds.min.y; y <= bounds.max.y; ++y) {
|
||||
for (let z = bounds.min.z; z <= bounds.max.z; ++z) {
|
||||
@ -128,7 +135,7 @@ export class RayVoxeliser extends IVoxeliser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private _traverseY(rayList: Array<Ray>, bounds: Bounds) {
|
||||
for (let x = bounds.min.x; x <= bounds.max.x; ++x) {
|
||||
for (let z = bounds.min.z; z <= bounds.max.z; ++z) {
|
||||
@ -139,7 +146,7 @@ export class RayVoxeliser extends IVoxeliser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private _traverseZ(rayList: Array<Ray>, bounds: Bounds) {
|
||||
for (let x = bounds.min.x; x <= bounds.max.x; ++x) {
|
||||
for (let y = bounds.min.y; y <= bounds.max.y; ++y) {
|
||||
|
Loading…
Reference in New Issue
Block a user