mirror of
https://github.com/LucasDower/ObjToSchematic.git
synced 2025-04-12 15:00:22 +08:00
Update voxel mesh constructor
This commit is contained in:
parent
0a5c4376ab
commit
fcbb67c559
@ -20,20 +20,38 @@ export class OtS_VoxelMesh {
|
||||
private _bounds: Bounds;
|
||||
private _replaceMode: OtS_ReplaceMode;
|
||||
|
||||
public constructor() {
|
||||
/**
|
||||
* Create a new voxel mesh
|
||||
* @returns A new `OtS_VoxelMesh` instance
|
||||
*/
|
||||
public static Create(): OtS_VoxelMesh {
|
||||
return new OtS_VoxelMesh();
|
||||
}
|
||||
|
||||
private constructor() {
|
||||
this._voxels = new Map();
|
||||
this._bounds = Bounds.getEmptyBounds();
|
||||
this._isBoundsDirty = false;
|
||||
this._replaceMode = 'average';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behaviour for what should happen when adding a voxel in a
|
||||
* position where one already exists
|
||||
* @param replaceMode The behaviour to set
|
||||
*/
|
||||
public setReplaceMode(replaceMode: OtS_ReplaceMode) {
|
||||
this._replaceMode = replaceMode;
|
||||
}
|
||||
|
||||
public addVoxel(x: number, y: number, z: number, colour: RGBA, replaceMode?: OtS_ReplaceMode) {
|
||||
const useReplaceMode = replaceMode ?? this._replaceMode;
|
||||
|
||||
/**
|
||||
* Add a voxel at a position with a particular colour
|
||||
* @param x The x-coordinate (north/south)
|
||||
* @param y The y-coordinate (up/down)
|
||||
* @param z The z-coordinate (east/west)
|
||||
* @param colour The colour of the voxel
|
||||
*/
|
||||
public addVoxel(x: number, y: number, z: number, colour: RGBA) {
|
||||
const key = Vector3.Hash(x, y, z);
|
||||
let voxel: (OtS_Voxel_Internal | undefined) = this._voxels.get(key);
|
||||
|
||||
@ -48,13 +66,13 @@ export class OtS_VoxelMesh {
|
||||
//this._bounds.extendByPoint(position);
|
||||
this._isBoundsDirty = true;
|
||||
} else {
|
||||
if (useReplaceMode === 'average') {
|
||||
if (this._replaceMode === 'average') {
|
||||
voxel.colour.r = ((voxel.colour.r * voxel.collisions) + colour.r) / (voxel.collisions + 1);
|
||||
voxel.colour.g = ((voxel.colour.g * voxel.collisions) + colour.g) / (voxel.collisions + 1);
|
||||
voxel.colour.b = ((voxel.colour.b * voxel.collisions) + colour.b) / (voxel.collisions + 1);
|
||||
voxel.colour.a = ((voxel.colour.a * voxel.collisions) + colour.a) / (voxel.collisions + 1);
|
||||
++voxel.collisions;
|
||||
} else if (useReplaceMode === 'replace') {
|
||||
} else if (this._replaceMode === 'replace') {
|
||||
voxel.colour = RGBAUtil.copy(colour);
|
||||
voxel.collisions = 1;
|
||||
}
|
||||
@ -62,7 +80,11 @@ export class OtS_VoxelMesh {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a voxel from a given location.
|
||||
* Remoave a voxel at a position
|
||||
* @param x The x-coordinate (north/south)
|
||||
* @param y The y-coordinate (up/down)
|
||||
* @param z The z-coordinate (east/west)
|
||||
* @returns Whether or not a voxel was found and removed
|
||||
*/
|
||||
public removeVoxel(x: number, y: number, z: number): boolean {
|
||||
const key = Vector3.Hash(x, y, z);
|
||||
@ -72,9 +94,11 @@ export class OtS_VoxelMesh {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the colour of a voxel at a location, if one exists.
|
||||
* @note Modifying the returned colour will not update the voxel's colour.
|
||||
* For that, use `addVoxel` with the replaceMode set to 'replace'
|
||||
* Returns a copy of the voxel at a location, if one exists
|
||||
* @param x The x-coordinate (north/south)
|
||||
* @param y The y-coordinate (up/down)
|
||||
* @param z The z-coordinate (east/west)
|
||||
* @returns The copy of the voxel or null if one does not exist
|
||||
*/
|
||||
public getVoxelAt(x: number, y: number, z: number): (OtS_Voxel | null) {
|
||||
const key = Vector3.Hash(x, y, z);
|
||||
@ -91,15 +115,23 @@ export class OtS_VoxelMesh {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether or not there is a voxel at a given location.
|
||||
* Get whether or not there is a voxel at a given location
|
||||
* @param x The x-coordinate (north/south)
|
||||
* @param y The y-coordinate (up/down)
|
||||
* @param z The z-coordinate (east/west)
|
||||
* @returns Whether or not a voxel is at this location
|
||||
*/
|
||||
public isVoxelAt(x: number, y: number, z: number) {
|
||||
public isVoxelAt(x: number, y: number, z: number): boolean {
|
||||
const key = Vector3.Hash(x, y, z);
|
||||
return this._voxels.has(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether or not there is a opaque voxel at a given location.
|
||||
* Get whether or not there is a opaque voxel at a given location
|
||||
* @param x The x-coordinate (north/south)
|
||||
* @param y The y-coordinate (up/down)
|
||||
* @param z The z-coordinate (east/west)
|
||||
* @returns Whether or not an opaque voxel is at this location
|
||||
*/
|
||||
public isOpaqueVoxelAt(x: number, y: number, z: number) {
|
||||
const voxel = this.getVoxelAt(x, y, z);
|
||||
@ -107,7 +139,8 @@ export class OtS_VoxelMesh {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bounds/dimensions of the VoxelMesh.
|
||||
* Get the bounds/dimensions of the voxel mesh
|
||||
* @returns The bounds of the voxel mesh
|
||||
*/
|
||||
public getBounds(): Bounds {
|
||||
if (this._isBoundsDirty) {
|
||||
@ -129,7 +162,8 @@ export class OtS_VoxelMesh {
|
||||
|
||||
/**
|
||||
* Iterate over the voxels in this VoxelMesh, note that these are copies
|
||||
* and editing each entry will not modify the underlying voxel.
|
||||
* and editing each entry will not modify the underlying voxel
|
||||
* @returns An iterator to the voxels
|
||||
*/
|
||||
public getVoxels(): IterableIterator<OtS_Voxel> {
|
||||
const voxelsCopy: OtS_Voxel[] = Array.from(this._voxels.values()).map((voxel) => {
|
||||
|
@ -40,7 +40,8 @@ export class OtS_VoxelMesh_Converter {
|
||||
}
|
||||
|
||||
public process(mesh: OtS_Mesh): OtS_VoxelMesh {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.setReplaceMode('average');
|
||||
|
||||
const { scale, offset } = this._calcScaleOffset(mesh);
|
||||
|
||||
@ -117,7 +118,7 @@ export class OtS_VoxelMesh_Converter {
|
||||
);
|
||||
}
|
||||
|
||||
voxelMesh.addVoxel(voxelPosition.x, voxelPosition.y, voxelPosition.z, voxelColour, this._config.replaceMode);
|
||||
voxelMesh.addVoxel(voxelPosition.x, voxelPosition.y, voxelPosition.z, voxelColour);
|
||||
}
|
||||
|
||||
private _getVoxelColour(triangle: OtS_Triangle, location: Vector3): RGBA {
|
||||
|
@ -3,7 +3,7 @@ import { OtS_Colours, RGBAUtil } from '../src/colour';
|
||||
import { OtS_BlockMesh_Converter } from '../src/ots_block_mesh_converter';
|
||||
|
||||
test('Per-block', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(0, 0, 0, OtS_Colours.RED);
|
||||
voxelMesh.addVoxel(1, 0, 0, OtS_Colours.GREEN);
|
||||
voxelMesh.addVoxel(2, 0, 0, OtS_Colours.BLUE);
|
||||
@ -32,7 +32,7 @@ test('Per-block', () => {
|
||||
});
|
||||
|
||||
test('Per-face', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(0, 0, 0, OtS_Colours.RED);
|
||||
voxelMesh.addVoxel(0, -1, 0, OtS_Colours.BLUE);
|
||||
voxelMesh.addVoxel(1, 0, 0, OtS_Colours.BLUE);
|
||||
|
@ -3,13 +3,13 @@ import { ASSERT } from '../src/util/error_util';
|
||||
import { Vector3 } from '../src/vector';
|
||||
|
||||
test('VoxelMesh #1', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
expect(voxelMesh.getVoxelCount()).toBe(0);
|
||||
expect(voxelMesh.getVoxelAt(0, 0, 0)).toBe(null);
|
||||
});
|
||||
|
||||
test('VoxelMesh #2', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(1, 2, 3, { r: 1.0, g: 0.5, b: 0.25, a: 0.125 }, 'keep');
|
||||
expect(voxelMesh.getVoxelCount()).toBe(1);
|
||||
expect(voxelMesh.isVoxelAt(1, 2, 3)).toBe(true);
|
||||
@ -22,7 +22,7 @@ test('VoxelMesh #2', () => {
|
||||
});
|
||||
|
||||
test('VoxelMesh #3', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(1, 2, 3, { r: 1.0, g: 0.5, b: 0.25, a: 0.125 }, 'keep');
|
||||
const voxel = voxelMesh.getVoxelAt(1, 2, 3);
|
||||
|
||||
@ -32,7 +32,7 @@ test('VoxelMesh #3', () => {
|
||||
});
|
||||
|
||||
test('VoxelMesh #4', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(1, 2, 3, { r: 1.0, g: 0.5, b: 0.25, a: 0.125 }, 'keep');
|
||||
expect(voxelMesh.getVoxelAt(1, 2, 3)?.colour).toStrictEqual({ r: 1.0, g: 0.5, b: 0.25, a: 0.125 });
|
||||
|
||||
@ -41,7 +41,7 @@ test('VoxelMesh #4', () => {
|
||||
});
|
||||
|
||||
test('VoxelMesh #5', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(1, 2, 3, { r: 1.0, g: 0.5, b: 0.25, a: 0.125 }, 'replace');
|
||||
expect(voxelMesh.getVoxelAt(1, 2, 3)?.colour).toStrictEqual({ r: 1.0, g: 0.5, b: 0.25, a: 0.125 });
|
||||
|
||||
@ -50,7 +50,7 @@ test('VoxelMesh #5', () => {
|
||||
});
|
||||
|
||||
test('VoxelMesh #6', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(1, 2, 3, { r: 1.0, g: 0.5, b: 0.125, a: 1.0 }, 'average');
|
||||
expect(voxelMesh.getVoxelAt(1, 2, 3)?.colour).toStrictEqual({ r: 1.0, g: 0.5, b: 0.125, a: 1.0 });
|
||||
|
||||
@ -59,7 +59,7 @@ test('VoxelMesh #6', () => {
|
||||
});
|
||||
|
||||
test('VoxelMesh #7', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(1, 2, 3, { r: 1.0, g: 1.0, b: 1.0, a: 1.0 }, 'average');
|
||||
expect(voxelMesh.getVoxelAt(1, 2, 3)?.colour).toStrictEqual({ r: 1.0, g: 1.0, b: 1.0, a: 1.0 });
|
||||
|
||||
@ -74,7 +74,7 @@ test('VoxelMesh #7', () => {
|
||||
});
|
||||
|
||||
test('VoxelMesh #8', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(1, 2, 3, { r: 1.0, g: 1.0, b: 1.0, a: 1.0 }, 'average');
|
||||
expect(voxelMesh.getVoxelCount()).toBe(1);
|
||||
expect(voxelMesh.isVoxelAt(1, 2, 3)).toBe(true);
|
||||
@ -87,7 +87,7 @@ test('VoxelMesh #8', () => {
|
||||
});
|
||||
|
||||
test('VoxelMesh #9', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(1, 2, 3, { r: 1.0, g: 1.0, b: 1.0, a: 1.0 }, 'average');
|
||||
expect(voxelMesh.getBounds().getCentre().equals(new Vector3(1, 2, 3))).toBe(true);
|
||||
expect(voxelMesh.getBounds().getDimensions().equals(new Vector3(0, 0, 0))).toBe(true);
|
||||
@ -100,7 +100,7 @@ test('VoxelMesh #9', () => {
|
||||
});
|
||||
|
||||
test('VoxelMesh #10', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(1, 0, 0, { r: 1.0, g: 0.0, b: 0.0, a: 1.0 }, 'replace');
|
||||
voxelMesh.addVoxel(0, 1, 0, { r: 0.0, g: 1.0, b: 0.0, a: 1.0 }, 'replace');
|
||||
voxelMesh.addVoxel(0, 0, 1, { r: 0.0, g: 0.0, b: 1.0, a: 1.0 }, 'replace');
|
||||
|
@ -3,7 +3,7 @@ import { OtS_VoxelMesh } from '../src/ots_voxel_mesh';
|
||||
import { OtS_FaceVisibility, OtS_VoxelMesh_Neighbourhood } from '../src/ots_voxel_mesh_neighbourhood';
|
||||
|
||||
test('VoxelMesh Neighbourhood #1', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(0, 0, 0, OtS_Colours.WHITE, 'replace');
|
||||
|
||||
const neighbourhood = new OtS_VoxelMesh_Neighbourhood();
|
||||
@ -19,7 +19,7 @@ test('VoxelMesh Neighbourhood #2', () => {
|
||||
});
|
||||
|
||||
test('VoxelMesh Neighbourhood #3', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(0, 0, 0, OtS_Colours.WHITE, 'replace');
|
||||
voxelMesh.addVoxel(0, 1, 0, OtS_Colours.WHITE, 'replace');
|
||||
|
||||
@ -34,7 +34,7 @@ test('VoxelMesh Neighbourhood #3', () => {
|
||||
});
|
||||
|
||||
test('VoxelMesh Neighbourhood #4', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(0, 0, 0, OtS_Colours.WHITE, 'replace');
|
||||
voxelMesh.addVoxel(1, 0, 0, OtS_Colours.WHITE, 'replace');
|
||||
voxelMesh.addVoxel(0, 1, 0, OtS_Colours.WHITE, 'replace');
|
||||
@ -61,7 +61,7 @@ test('VoxelMesh Neighbourhood #5', () => {
|
||||
});
|
||||
|
||||
test('VoxelMesh Neighbourhood #6', () => {
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(0, 0, 0, OtS_Colours.WHITE, 'replace');
|
||||
voxelMesh.addVoxel(1, 1, 1, OtS_Colours.WHITE, 'replace');
|
||||
|
||||
@ -74,7 +74,7 @@ test('VoxelMesh Neighbourhood #6', () => {
|
||||
|
||||
test('VoxelMesh Neighbourhood #6', () => {
|
||||
// Checking a non-cardinal neighbour when processing using 'cardinal' mode
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(0, 0, 0, OtS_Colours.WHITE, 'replace');
|
||||
voxelMesh.addVoxel(1, 1, 1, OtS_Colours.WHITE, 'replace');
|
||||
|
||||
@ -92,7 +92,7 @@ test('VoxelMesh Neighbourhood #6', () => {
|
||||
|
||||
test('VoxelMesh Neighbourhood #6', () => {
|
||||
// Checking a cardinal neighbour when processing using 'non-cardinal' mode
|
||||
const voxelMesh = new OtS_VoxelMesh();
|
||||
const voxelMesh = OtS_VoxelMesh.Create();
|
||||
voxelMesh.addVoxel(0, 0, 0, OtS_Colours.WHITE, 'replace');
|
||||
voxelMesh.addVoxel(1, 0, 0, OtS_Colours.WHITE, 'replace');
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user