mirror of
https://github.com/LucasDower/ObjToSchematic.git
synced 2024-12-15 02:59:55 +08:00
Added random dithering, updated headless types
This commit is contained in:
parent
173984ad8f
commit
b7331740e0
@ -181,7 +181,7 @@ export class AppContext {
|
||||
const blockMeshParams: BlockMeshParams = {
|
||||
textureAtlas: uiElements.textureAtlas.getCachedValue(),
|
||||
blockPalette: uiElements.blockPalette.getCachedValue(),
|
||||
ditheringEnabled: uiElements.dithering.getCachedValue() === 'on',
|
||||
blockAssigner: uiElements.dithering.getCachedValue(),
|
||||
colourSpace: uiElements.colourSpace.getCachedValue() === 'rgb' ? ColourSpace.RGB : ColourSpace.LAB,
|
||||
fallable: uiElements.fallable.getCachedValue() as FallableBehaviour,
|
||||
};
|
||||
|
@ -2,6 +2,23 @@ import { BlockAtlas, BlockInfo } from './block_atlas';
|
||||
import { ASSERT, ColourSpace, RGB } from './util';
|
||||
import { Vector3 } from './vector';
|
||||
|
||||
export type TBlockAssigners = 'basic' | 'ordered-dithering' | 'random-dithering';
|
||||
|
||||
export class BlockAssignerFactory {
|
||||
public static GetAssigner(blockAssigner: TBlockAssigners): IBlockAssigner {
|
||||
switch (blockAssigner) {
|
||||
case 'basic':
|
||||
return new BasicBlockAssigner();
|
||||
case 'ordered-dithering':
|
||||
return new OrderedDitheringBlockAssigner();
|
||||
case 'random-dithering':
|
||||
return new RandomDitheringBlockAssigner();
|
||||
default:
|
||||
ASSERT(false, 'Unreachable');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IBlockAssigner {
|
||||
assignBlock(voxelColour: RGB, voxelPosition: Vector3, colourSpace: ColourSpace, exclude?: string[]): BlockInfo;
|
||||
}
|
||||
@ -53,3 +70,50 @@ export class OrderedDitheringBlockAssigner implements IBlockAssigner {
|
||||
return BlockAtlas.Get.getBlock(newVoxelColour, colourSpace, exclude);
|
||||
}
|
||||
}
|
||||
|
||||
export class RandomDitheringBlockAssigner implements IBlockAssigner {
|
||||
/** 4x4x4 */
|
||||
private static _size = 4;
|
||||
private static _threshold = 256 / 8;
|
||||
|
||||
private _mapMatrix = [
|
||||
0, 16, 2, 18, 48, 32, 50, 34,
|
||||
6, 22, 4, 20, 54, 38, 52, 36,
|
||||
24, 40, 26, 42, 8, 56, 10, 58,
|
||||
30, 46, 28, 44, 14, 62, 12, 60,
|
||||
3, 19, 5, 21, 51, 35, 53, 37,
|
||||
1, 17, 7, 23, 49, 33, 55, 39,
|
||||
27, 43, 29, 45, 11, 59, 13, 61,
|
||||
25, 41, 31, 47, 9, 57, 15, 63,
|
||||
];
|
||||
|
||||
private _getThresholdValue(x: number, y: number, z: number) {
|
||||
const size = RandomDitheringBlockAssigner._size;
|
||||
ASSERT(0 <= x && x < size && 0 <= y && y < size && 0 <= z && z < size);
|
||||
const index = (x + (size * y) + (size * size * z));
|
||||
ASSERT(0 <= index && index < size * size * size);
|
||||
return (this._mapMatrix[index] / (size * size * size)) - 0.5;
|
||||
}
|
||||
|
||||
assignBlock(voxelColour: RGB, voxelPosition: Vector3, colourSpace: ColourSpace, exclude?: string[]): BlockInfo {
|
||||
this._mapMatrix = this._mapMatrix
|
||||
.map((value) => ({ value, sort: Math.random() }))
|
||||
.sort((a, b) => a.sort - b.sort)
|
||||
.map(({ value }) => value);
|
||||
|
||||
const size = RandomDitheringBlockAssigner._size;
|
||||
const map = this._getThresholdValue(
|
||||
Math.abs(voxelPosition.x % size),
|
||||
Math.abs(voxelPosition.y % size),
|
||||
Math.abs(voxelPosition.z % size),
|
||||
);
|
||||
|
||||
const newVoxelColour = new RGB(
|
||||
((255 * voxelColour.r) + map * RandomDitheringBlockAssigner._threshold) / 255,
|
||||
((255 * voxelColour.g) + map * RandomDitheringBlockAssigner._threshold) / 255,
|
||||
((255 * voxelColour.b) + map * RandomDitheringBlockAssigner._threshold) / 255,
|
||||
);
|
||||
|
||||
return BlockAtlas.Get.getBlock(newVoxelColour, colourSpace, exclude);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { BasicBlockAssigner, OrderedDitheringBlockAssigner } from './block_assigner';
|
||||
import { BasicBlockAssigner, BlockAssignerFactory, OrderedDitheringBlockAssigner, RandomDitheringBlockAssigner, TBlockAssigners } from './block_assigner';
|
||||
import { Voxel, VoxelMesh } from './voxel_mesh';
|
||||
import { BlockAtlas, BlockInfo } from './block_atlas';
|
||||
import { ColourSpace, AppError, ASSERT, RESOURCES_DIR } from './util';
|
||||
@ -20,7 +20,7 @@ export type FallableBehaviour = 'replace-falling' | 'replace-fallable' | 'place-
|
||||
export interface BlockMeshParams {
|
||||
textureAtlas: string,
|
||||
blockPalette: string,
|
||||
ditheringEnabled: boolean,
|
||||
blockAssigner: TBlockAssigners,
|
||||
colourSpace: ColourSpace,
|
||||
fallable: FallableBehaviour,
|
||||
}
|
||||
@ -53,7 +53,7 @@ export class BlockMesh {
|
||||
BlockAtlas.Get.loadPalette(blockMeshParams.blockPalette);
|
||||
this._atlasUsed = blockMeshParams.textureAtlas;
|
||||
|
||||
const blockAssigner = blockMeshParams.ditheringEnabled ? new OrderedDitheringBlockAssigner() : new BasicBlockAssigner();
|
||||
const blockAssigner = BlockAssignerFactory.GetAssigner(blockMeshParams.blockAssigner);
|
||||
|
||||
let countFalling = 0;
|
||||
const voxels = this._voxelMesh.getVoxels();
|
||||
|
@ -14,6 +14,7 @@ import { MeshType, Renderer } from '../renderer';
|
||||
import { ArcballCamera } from '../camera';
|
||||
import { TVoxelisers } from '../voxelisers/voxelisers';
|
||||
import { TExporters } from '../exporters/exporters';
|
||||
import { TBlockAssigners } from '../block_assigner';
|
||||
|
||||
export interface Group {
|
||||
label: string;
|
||||
@ -88,9 +89,10 @@ export class UI {
|
||||
elements: {
|
||||
'textureAtlas': new ComboBoxElement('Texture atlas', this._getTextureAtlases()),
|
||||
'blockPalette': new ComboBoxElement('Block palette', this._getBlockPalettes()),
|
||||
'dithering': new ComboBoxElement('Dithering', [
|
||||
{ id: 'on', displayText: 'On (recommended)' },
|
||||
{ id: 'off', displayText: 'Off' },
|
||||
'dithering': new ComboBoxElement<TBlockAssigners>('Dithering', [
|
||||
{ id: 'ordered-dithering', displayText: 'Ordered' },
|
||||
{ id: 'random-dithering', displayText: 'Random' },
|
||||
{ id: 'basic', displayText: 'Off' },
|
||||
]),
|
||||
'colourSpace': new ComboBoxElement('Colour space', [
|
||||
{ id: 'rgb', displayText: 'RGB (faster)' },
|
||||
|
@ -1,22 +1,27 @@
|
||||
export const headlessConfig = {
|
||||
import { THeadlessConfig } from './headless';
|
||||
import { TVoxelisers } from '../src/voxelisers/voxelisers';
|
||||
import { TextureFiltering } from '../src/texture';
|
||||
import { ColourSpace } from '../src/util';
|
||||
|
||||
export const headlessConfig: THeadlessConfig = {
|
||||
import: {
|
||||
absoluteFilePathLoad: 'C:/Users/<Username>/Desktop/MyModel.obj', // Must be an absolute path to the file (can be anywhere)
|
||||
},
|
||||
voxelise: {
|
||||
voxeliser: 'raybased', // 'raybased' / 'ncrb'
|
||||
voxeliser: 'bvh-ray',
|
||||
voxelMeshParams: {
|
||||
desiredHeight: 80, // 5-320 inclusive
|
||||
useMultisampleColouring: false,
|
||||
textureFiltering: 'linear', // 'linear' / 'nearest'
|
||||
textureFiltering: TextureFiltering.Linear,
|
||||
},
|
||||
},
|
||||
palette: {
|
||||
blockMeshParams: {
|
||||
textureAtlas: 'vanilla', // Must be an atlas name that exists in /resources/atlases
|
||||
blockPalette: 'all-snapshot', // Must be a palette name that exists in /resources/palettes
|
||||
ditheringEnabled: true,
|
||||
colourSpace: 'rgb', // 'rgb' / 'lab';
|
||||
fallable: 'replace-falling', // 'replace-fallable' / 'place-string';
|
||||
blockAssigner: 'ordered-dithering',
|
||||
colourSpace: ColourSpace.RGB,
|
||||
fallable: 'replace-falling',
|
||||
},
|
||||
},
|
||||
export: {
|
||||
|
@ -12,17 +12,46 @@ import { TextureFiltering } from '../src/texture';
|
||||
import { ColourSpace } from '../src/util';
|
||||
import { log, LogStyle } from './logging';
|
||||
import { headlessConfig } from './headless-config';
|
||||
import { TBlockAssigners } from '../src/block_assigner';
|
||||
import { TVoxelisers, VoxeliserFactory } from '../src/voxelisers/voxelisers';
|
||||
|
||||
export type THeadlessConfig = {
|
||||
import: {
|
||||
absoluteFilePathLoad: string,
|
||||
},
|
||||
voxelise: {
|
||||
voxeliser: TVoxelisers,
|
||||
voxelMeshParams: {
|
||||
desiredHeight: number
|
||||
useMultisampleColouring: boolean,
|
||||
textureFiltering: TextureFiltering
|
||||
},
|
||||
},
|
||||
palette: {
|
||||
blockMeshParams: {
|
||||
textureAtlas: string,
|
||||
blockPalette: string,
|
||||
blockAssigner: TBlockAssigners,
|
||||
colourSpace: ColourSpace,
|
||||
fallable: FallableBehaviour,
|
||||
},
|
||||
},
|
||||
export: {
|
||||
absoluteFilePathSave: 'C:/Users/<Username>/AppData//Roaming/.minecraft/schematics/MySchematic.schematic', // Must be an absolute path to the file (can be anywhere)
|
||||
exporter: 'schematic', // 'schematic' / 'litematic',
|
||||
},
|
||||
}
|
||||
|
||||
void async function main() {
|
||||
const mesh = _import({
|
||||
absoluteFilePathLoad: headlessConfig.import.absoluteFilePathLoad,
|
||||
});
|
||||
const voxelMesh = _voxelise(mesh, {
|
||||
voxeliser: headlessConfig.voxelise.voxeliser === 'raybased' ? new RayVoxeliser() : new NormalCorrectedRayVoxeliser(),
|
||||
voxeliser: VoxeliserFactory.GetVoxeliser(headlessConfig.voxelise.voxeliser),
|
||||
voxelMeshParams: {
|
||||
desiredHeight: headlessConfig.voxelise.voxelMeshParams.desiredHeight,
|
||||
useMultisampleColouring: headlessConfig.voxelise.voxelMeshParams.useMultisampleColouring,
|
||||
textureFiltering: headlessConfig.voxelise.voxelMeshParams.textureFiltering === 'linear' ? TextureFiltering.Linear : TextureFiltering.Nearest,
|
||||
textureFiltering: headlessConfig.voxelise.voxelMeshParams.textureFiltering,
|
||||
enableAmbientOcclusion: false,
|
||||
},
|
||||
});
|
||||
@ -30,8 +59,8 @@ void async function main() {
|
||||
blockMeshParams: {
|
||||
textureAtlas: headlessConfig.palette.blockMeshParams.textureAtlas,
|
||||
blockPalette: headlessConfig.palette.blockMeshParams.blockPalette,
|
||||
ditheringEnabled: headlessConfig.palette.blockMeshParams.ditheringEnabled,
|
||||
colourSpace: headlessConfig.palette.blockMeshParams.colourSpace === 'rgb' ? ColourSpace.RGB : ColourSpace.LAB,
|
||||
blockAssigner: headlessConfig.palette.blockMeshParams.blockAssigner as TBlockAssigners,
|
||||
colourSpace: headlessConfig.palette.blockMeshParams.colourSpace,
|
||||
fallable: headlessConfig.palette.blockMeshParams.fallable as FallableBehaviour,
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user