forked from mirror/ObjToSchematic
Updated atlas script, added palette script
This commit is contained in:
parent
24a4038362
commit
ed2a61af1a
@ -26,7 +26,7 @@
|
||||
"func-call-spacing": "off",
|
||||
"no-trailing-spaces": "off",
|
||||
"new-cap": "off",
|
||||
"no-console": "error",
|
||||
"no-console": "warn",
|
||||
"no-unused-vars": "warn"
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,12 @@
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint --fix ./src/**/*.ts",
|
||||
"lint": "eslint --fix ./src/**/*.ts && eslint --fix ./src/**/*.ts",
|
||||
"debug": "tsc && electron ./dist/main.js --enable-logging",
|
||||
"build": "npm run lint && tsc",
|
||||
"start": "npm run build && electron ./dist/main.js --enable-logging",
|
||||
"atlas": "npx ts-node tools/build-atlas.ts",
|
||||
"palette": "npx ts-node tools/build-palette.ts",
|
||||
"export": "electron-packager . ObjToSchematic --platform=win32 --arch=x64"
|
||||
},
|
||||
"repository": {
|
||||
|
File diff suppressed because it is too large
Load Diff
BIN
resources/atlases/vanilla.png
Normal file
BIN
resources/atlases/vanilla.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 381 KiB |
Binary file not shown.
Before Width: | Height: | Size: 434 KiB |
245
resources/palettes/all-supported.palette
Normal file
245
resources/palettes/all-supported.palette
Normal file
@ -0,0 +1,245 @@
|
||||
{
|
||||
"blocks": [
|
||||
"acacia_log",
|
||||
"acacia_planks",
|
||||
"acacia_wood",
|
||||
"ancient_debris",
|
||||
"andesite",
|
||||
"basalt",
|
||||
"bedrock",
|
||||
"birch_log",
|
||||
"birch_planks",
|
||||
"birch_wood",
|
||||
"blackstone",
|
||||
"black_concrete",
|
||||
"black_concrete_powder",
|
||||
"black_glazed_terracotta",
|
||||
"black_terracotta",
|
||||
"black_wool",
|
||||
"blue_concrete",
|
||||
"blue_concrete_powder",
|
||||
"blue_glazed_terracotta",
|
||||
"blue_ice",
|
||||
"blue_terracotta",
|
||||
"blue_wool",
|
||||
"bone_block",
|
||||
"bookshelf",
|
||||
"brain_coral_block",
|
||||
"bricks",
|
||||
"brown_concrete",
|
||||
"brown_concrete_powder",
|
||||
"brown_glazed_terracotta",
|
||||
"brown_mushroom_block",
|
||||
"brown_terracotta",
|
||||
"brown_wool",
|
||||
"bubble_coral_block",
|
||||
"cartography_table",
|
||||
"chiseled_nether_bricks",
|
||||
"chiseled_polished_blackstone",
|
||||
"chiseled_quartz_block",
|
||||
"chiseled_red_sandstone",
|
||||
"chiseled_sandstone",
|
||||
"chiseled_stone_bricks",
|
||||
"clay",
|
||||
"coal_block",
|
||||
"coal_ore",
|
||||
"coarse_dirt",
|
||||
"cobblestone",
|
||||
"cracked_nether_bricks",
|
||||
"cracked_polished_blackstone_bricks",
|
||||
"cracked_stone_bricks",
|
||||
"crafting_table",
|
||||
"crimson_hyphae",
|
||||
"crimson_planks",
|
||||
"crimson_stem",
|
||||
"crying_obsidian",
|
||||
"cut_red_sandstone",
|
||||
"cut_sandstone",
|
||||
"cyan_concrete",
|
||||
"cyan_concrete_powder",
|
||||
"cyan_glazed_terracotta",
|
||||
"cyan_terracotta",
|
||||
"cyan_wool",
|
||||
"dark_oak_log",
|
||||
"dark_oak_planks",
|
||||
"dark_oak_wood",
|
||||
"dark_prismarine",
|
||||
"dead_brain_coral_block",
|
||||
"dead_bubble_coral_block",
|
||||
"dead_fire_coral_block",
|
||||
"dead_horn_coral_block",
|
||||
"dead_tube_coral_block",
|
||||
"diamond_block",
|
||||
"diamond_ore",
|
||||
"diorite",
|
||||
"dirt",
|
||||
"emerald_block",
|
||||
"emerald_ore",
|
||||
"end_stone",
|
||||
"end_stone_bricks",
|
||||
"fire_coral_block",
|
||||
"fletching_table",
|
||||
"frosted_ice_0",
|
||||
"frosted_ice_1",
|
||||
"frosted_ice_2",
|
||||
"frosted_ice_3",
|
||||
"gilded_blackstone",
|
||||
"glowstone",
|
||||
"gold_block",
|
||||
"gold_ore",
|
||||
"granite",
|
||||
"gravel",
|
||||
"gray_concrete",
|
||||
"gray_concrete_powder",
|
||||
"gray_glazed_terracotta",
|
||||
"gray_stained_glass",
|
||||
"gray_terracotta",
|
||||
"gray_wool",
|
||||
"green_concrete",
|
||||
"green_concrete_powder",
|
||||
"green_glazed_terracotta",
|
||||
"green_terracotta",
|
||||
"green_wool",
|
||||
"hay_block",
|
||||
"honeycomb_block",
|
||||
"horn_coral_block",
|
||||
"ice",
|
||||
"iron_block",
|
||||
"iron_ore",
|
||||
"jungle_log",
|
||||
"jungle_planks",
|
||||
"jungle_wood",
|
||||
"lapis_block",
|
||||
"lapis_ore",
|
||||
"light_blue_concrete",
|
||||
"light_blue_concrete_powder",
|
||||
"light_blue_glazed_terracotta",
|
||||
"light_blue_terracotta",
|
||||
"light_blue_wool",
|
||||
"light_gray_concrete",
|
||||
"light_gray_concrete_powder",
|
||||
"light_gray_glazed_terracotta",
|
||||
"light_gray_terracotta",
|
||||
"light_gray_wool",
|
||||
"lime_concrete",
|
||||
"lime_concrete_powder",
|
||||
"lime_glazed_terracotta",
|
||||
"lime_terracotta",
|
||||
"lime_wool",
|
||||
"lodestone",
|
||||
"magenta_concrete",
|
||||
"magenta_concrete_powder",
|
||||
"magenta_glazed_terracotta",
|
||||
"magenta_terracotta",
|
||||
"magenta_wool",
|
||||
"magma_block",
|
||||
"melon",
|
||||
"mossy_cobblestone",
|
||||
"mossy_stone_bricks",
|
||||
"mushroom_stem",
|
||||
"mushroom_stem_inventory",
|
||||
"netherite_block",
|
||||
"netherrack",
|
||||
"nether_bricks",
|
||||
"nether_gold_ore",
|
||||
"nether_quartz_ore",
|
||||
"nether_wart_block",
|
||||
"note_block",
|
||||
"oak_log",
|
||||
"oak_planks",
|
||||
"oak_wood",
|
||||
"obsidian",
|
||||
"orange_concrete",
|
||||
"orange_concrete_powder",
|
||||
"orange_glazed_terracotta",
|
||||
"orange_terracotta",
|
||||
"orange_wool",
|
||||
"packed_ice",
|
||||
"pink_concrete",
|
||||
"pink_concrete_powder",
|
||||
"pink_glazed_terracotta",
|
||||
"pink_terracotta",
|
||||
"pink_wool",
|
||||
"polished_andesite",
|
||||
"polished_basalt",
|
||||
"polished_blackstone",
|
||||
"polished_blackstone_bricks",
|
||||
"polished_diorite",
|
||||
"polished_granite",
|
||||
"prismarine",
|
||||
"prismarine_bricks",
|
||||
"purple_concrete",
|
||||
"purple_concrete_powder",
|
||||
"purple_glazed_terracotta",
|
||||
"purple_terracotta",
|
||||
"purple_wool",
|
||||
"purpur_block",
|
||||
"purpur_pillar",
|
||||
"quartz_block",
|
||||
"quartz_bricks",
|
||||
"quartz_pillar",
|
||||
"redstone_block",
|
||||
"redstone_lamp",
|
||||
"redstone_ore",
|
||||
"red_concrete",
|
||||
"red_concrete_powder",
|
||||
"red_glazed_terracotta",
|
||||
"red_mushroom_block",
|
||||
"red_nether_bricks",
|
||||
"red_sand",
|
||||
"red_terracotta",
|
||||
"red_wool",
|
||||
"sand",
|
||||
"sea_lantern",
|
||||
"shroomlight",
|
||||
"smithing_table",
|
||||
"smooth_quartz",
|
||||
"smooth_red_sandstone",
|
||||
"smooth_sandstone",
|
||||
"smooth_stone",
|
||||
"smooth_stone_slab_double",
|
||||
"snow_block",
|
||||
"soul_sand",
|
||||
"soul_soil",
|
||||
"sponge",
|
||||
"spruce_log",
|
||||
"spruce_planks",
|
||||
"spruce_wood",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"stripped_acacia_log",
|
||||
"stripped_acacia_wood",
|
||||
"stripped_birch_log",
|
||||
"stripped_birch_wood",
|
||||
"stripped_crimson_hyphae",
|
||||
"stripped_crimson_stem",
|
||||
"stripped_dark_oak_log",
|
||||
"stripped_dark_oak_wood",
|
||||
"stripped_jungle_log",
|
||||
"stripped_jungle_wood",
|
||||
"stripped_oak_log",
|
||||
"stripped_oak_wood",
|
||||
"stripped_spruce_log",
|
||||
"stripped_spruce_wood",
|
||||
"stripped_warped_hyphae",
|
||||
"stripped_warped_stem",
|
||||
"target",
|
||||
"terracotta",
|
||||
"tube_coral_block",
|
||||
"warped_hyphae",
|
||||
"warped_planks",
|
||||
"warped_stem",
|
||||
"warped_wart_block",
|
||||
"wet_sponge",
|
||||
"white_concrete",
|
||||
"white_concrete_powder",
|
||||
"white_glazed_terracotta",
|
||||
"white_terracotta",
|
||||
"white_wool",
|
||||
"yellow_concrete",
|
||||
"yellow_concrete_powder",
|
||||
"yellow_glazed_terracotta",
|
||||
"yellow_terracotta",
|
||||
"yellow_wool"
|
||||
]
|
||||
}
|
84
resources/palettes/coloured-blocks.palette
Normal file
84
resources/palettes/coloured-blocks.palette
Normal file
@ -0,0 +1,84 @@
|
||||
{
|
||||
"blocks": [
|
||||
"black_concrete",
|
||||
"black_concrete_powder",
|
||||
"black_glazed_terracotta",
|
||||
"black_terracotta",
|
||||
"black_wool",
|
||||
"blue_concrete",
|
||||
"blue_concrete_powder",
|
||||
"blue_glazed_terracotta",
|
||||
"blue_terracotta",
|
||||
"blue_wool",
|
||||
"brown_concrete",
|
||||
"brown_concrete_powder",
|
||||
"brown_glazed_terracotta",
|
||||
"brown_terracotta",
|
||||
"brown_wool",
|
||||
"cyan_concrete",
|
||||
"cyan_concrete_powder",
|
||||
"cyan_glazed_terracotta",
|
||||
"cyan_terracotta",
|
||||
"cyan_wool",
|
||||
"gray_concrete",
|
||||
"gray_concrete_powder",
|
||||
"gray_glazed_terracotta",
|
||||
"gray_terracotta",
|
||||
"gray_wool",
|
||||
"green_concrete",
|
||||
"green_concrete_powder",
|
||||
"green_glazed_terracotta",
|
||||
"green_terracotta",
|
||||
"green_wool",
|
||||
"light_blue_concrete",
|
||||
"light_blue_concrete_powder",
|
||||
"light_blue_glazed_terracotta",
|
||||
"light_blue_terracotta",
|
||||
"light_blue_wool",
|
||||
"light_gray_concrete",
|
||||
"light_gray_concrete_powder",
|
||||
"light_gray_glazed_terracotta",
|
||||
"light_gray_terracotta",
|
||||
"light_gray_wool",
|
||||
"lime_concrete",
|
||||
"lime_concrete_powder",
|
||||
"lime_glazed_terracotta",
|
||||
"lime_terracotta",
|
||||
"lime_wool",
|
||||
"magenta_concrete",
|
||||
"magenta_concrete_powder",
|
||||
"magenta_glazed_terracotta",
|
||||
"magenta_terracotta",
|
||||
"magenta_wool",
|
||||
"orange_concrete",
|
||||
"orange_concrete_powder",
|
||||
"orange_glazed_terracotta",
|
||||
"orange_terracotta",
|
||||
"orange_wool",
|
||||
"pink_concrete",
|
||||
"pink_concrete_powder",
|
||||
"pink_glazed_terracotta",
|
||||
"pink_terracotta",
|
||||
"pink_wool",
|
||||
"purple_concrete",
|
||||
"purple_concrete_powder",
|
||||
"purple_glazed_terracotta",
|
||||
"purple_terracotta",
|
||||
"purple_wool",
|
||||
"red_concrete",
|
||||
"red_concrete_powder",
|
||||
"red_glazed_terracotta",
|
||||
"red_terracotta",
|
||||
"red_wool",
|
||||
"white_concrete",
|
||||
"white_concrete_powder",
|
||||
"white_glazed_terracotta",
|
||||
"white_terracotta",
|
||||
"white_wool",
|
||||
"yellow_concrete",
|
||||
"yellow_concrete_powder",
|
||||
"yellow_glazed_terracotta",
|
||||
"yellow_terracotta",
|
||||
"yellow_wool"
|
||||
]
|
||||
}
|
56
resources/palettes/greyscale.palette
Normal file
56
resources/palettes/greyscale.palette
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"blocks": [
|
||||
"andesite",
|
||||
"basalt",
|
||||
"bedrock",
|
||||
"blackstone",
|
||||
"black_concrete",
|
||||
"black_concrete_powder",
|
||||
"black_terracotta",
|
||||
"black_wool",
|
||||
"bone_block",
|
||||
"chiseled_polished_blackstone",
|
||||
"chiseled_quartz_block",
|
||||
"chiseled_stone_bricks",
|
||||
"coal_block",
|
||||
"coal_ore",
|
||||
"cobblestone",
|
||||
"cracked_polished_blackstone_bricks",
|
||||
"cracked_stone_bricks",
|
||||
"cyan_terracotta",
|
||||
"dead_brain_coral_block",
|
||||
"dead_bubble_coral_block",
|
||||
"dead_fire_coral_block",
|
||||
"dead_horn_coral_block",
|
||||
"dead_tube_coral_block",
|
||||
"diorite",
|
||||
"gravel",
|
||||
"gray_concrete",
|
||||
"gray_concrete_powder",
|
||||
"gray_wool",
|
||||
"iron_block",
|
||||
"light_gray_concrete",
|
||||
"light_gray_concrete_powder",
|
||||
"light_gray_terracotta",
|
||||
"light_gray_wool",
|
||||
"netherite_block",
|
||||
"polished_andesite",
|
||||
"polished_basalt",
|
||||
"polished_blackstone",
|
||||
"polished_blackstone_bricks",
|
||||
"polished_diorite",
|
||||
"quartz_block",
|
||||
"quartz_bricks",
|
||||
"quartz_pillar",
|
||||
"smooth_quartz",
|
||||
"smooth_stone",
|
||||
"smooth_stone_slab_double",
|
||||
"snow_block",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"white_concrete",
|
||||
"white_concrete_powder",
|
||||
"white_terracotta",
|
||||
"white_wool"
|
||||
]
|
||||
}
|
@ -8,7 +8,6 @@ import { ASSERT, CustomError, CustomWarning, LOG, LOG_ERROR } from './util';
|
||||
import { remote } from 'electron';
|
||||
import { VoxelMesh } from './voxel_mesh';
|
||||
import { BlockMesh } from './block_mesh';
|
||||
import { TextureFiltering } from './texture';
|
||||
|
||||
/* eslint-disable */
|
||||
export enum ActionReturnType {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { HashMap } from './hash_map';
|
||||
import { UV, RGB } from './util';
|
||||
import { UV, RGB, ASSERT } from './util';
|
||||
import { Vector3 } from './vector';
|
||||
|
||||
import fs from 'fs';
|
||||
@ -36,22 +36,30 @@ export enum Block {
|
||||
/* eslint-enable */
|
||||
export class BlockAtlas {
|
||||
private _cachedBlocks: HashMap<Vector3, number>;
|
||||
private readonly _blocks: Array<BlockInfo>;
|
||||
public readonly _atlasSize: number;
|
||||
private _blocks: Array<BlockInfo>;
|
||||
private _atlasSize: number;
|
||||
private _atlasLoaded: boolean;
|
||||
|
||||
private static _instance: BlockAtlas;
|
||||
|
||||
public static get Get() {
|
||||
return this._instance || (this._instance = new this());
|
||||
}
|
||||
|
||||
private constructor() {
|
||||
this._cachedBlocks = new HashMap(0);
|
||||
this._blocks = [];
|
||||
this._atlasSize = 0;
|
||||
this._atlasLoaded = false;
|
||||
|
||||
this.loadAtlas(path.join(__dirname, '../resources/atlases/vanilla.atlas'));
|
||||
}
|
||||
|
||||
public loadAtlas(absolutePath: string) {
|
||||
this._cachedBlocks = new HashMap(1024);
|
||||
|
||||
const _path = path.join(__dirname, '../resources/blocks.json');
|
||||
const blocksString = fs.readFileSync(_path, 'utf-8');
|
||||
const blocksString = fs.readFileSync(absolutePath, 'utf-8');
|
||||
if (!blocksString) {
|
||||
throw Error('Could not load blocks.json');
|
||||
throw Error('Could not load vanilla.atlas');
|
||||
}
|
||||
|
||||
const json = JSON.parse(blocksString);
|
||||
@ -64,10 +72,13 @@ export class BlockAtlas {
|
||||
block.colour.b,
|
||||
);
|
||||
}
|
||||
|
||||
this._atlasLoaded = true;
|
||||
}
|
||||
|
||||
|
||||
public getBlock(voxelColour: RGB): BlockInfo {
|
||||
ASSERT(this._atlasLoaded);
|
||||
|
||||
const cachedBlockIndex = this._cachedBlocks.get(voxelColour.toVector3());
|
||||
if (cachedBlockIndex) {
|
||||
return this._blocks[cachedBlockIndex];
|
||||
@ -90,4 +101,9 @@ export class BlockAtlas {
|
||||
this._cachedBlocks.add(voxelColour.toVector3(), blockChoiceIndex);
|
||||
return this._blocks[blockChoiceIndex];
|
||||
}
|
||||
|
||||
public getAtlasSize() {
|
||||
ASSERT(this._atlasLoaded);
|
||||
return this._atlasSize;
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import { RenderBuffer } from './buffer';
|
||||
import { GeometryTemplates } from './geometry';
|
||||
import { Mesh, SolidMaterial, TexturedMaterial, MaterialType } from './mesh';
|
||||
import { BlockAtlas } from './block_atlas';
|
||||
import { LOG, RGB } from './util';
|
||||
import { ASSERT, fileExists, LOG, RGB } from './util';
|
||||
import { VoxelMesh } from './voxel_mesh';
|
||||
import { BlockMesh } from './block_mesh';
|
||||
|
||||
@ -53,8 +53,10 @@ export class Renderer {
|
||||
this._blockBuffer = new RenderBuffer([]);
|
||||
this._materialBuffers = [];
|
||||
|
||||
const texturePath = path.join(__dirname, '../resources/atlases/vanilla.png');
|
||||
ASSERT(fileExists(texturePath), `Atlas cannot be found at ${texturePath}`);
|
||||
this._atlasTexture = twgl.createTexture(this._gl, {
|
||||
src: path.join(__dirname, '../resources/blocks.png'),
|
||||
src: texturePath,
|
||||
mag: this._gl.NEAREST,
|
||||
});
|
||||
}
|
||||
@ -179,7 +181,7 @@ export class Renderer {
|
||||
u_worldViewProjection: ArcballCamera.Get.getWorldViewProjection(),
|
||||
u_texture: this._atlasTexture,
|
||||
u_voxelSize: this._voxelSize,
|
||||
u_atlasSize: BlockAtlas.Get._atlasSize,
|
||||
u_atlasSize: BlockAtlas.Get.getAtlasSize(),
|
||||
});
|
||||
}
|
||||
|
||||
|
33
src/util.ts
33
src/util.ts
@ -1,6 +1,8 @@
|
||||
import { AppConfig } from './config';
|
||||
import { Vector3 } from './vector';
|
||||
|
||||
import fs from 'fs';
|
||||
|
||||
export class UV {
|
||||
public u: number;
|
||||
public v: number;
|
||||
@ -111,29 +113,12 @@ export function ASSERT(condition: any, errorMessage = 'Assertion Failed'): asser
|
||||
}
|
||||
}
|
||||
|
||||
export function LOG(message: any) {
|
||||
if (AppConfig.LOGGING_ENABLED) {
|
||||
/* eslint-disable */
|
||||
console.log(message);
|
||||
/* eslint-enable */
|
||||
}
|
||||
}
|
||||
/* eslint-disable */
|
||||
export const LOG = console.log;
|
||||
export const LOG_WARN = console.warn;
|
||||
export const LOG_ERROR = console.error;
|
||||
|
||||
export function LOG_WARN(message: any) {
|
||||
if (AppConfig.LOGGING_ENABLED) {
|
||||
/* eslint-disable */
|
||||
console.warn(message);
|
||||
/* eslint-enable */
|
||||
}
|
||||
}
|
||||
|
||||
export function LOG_ERROR(message: any) {
|
||||
if (AppConfig.LOGGING_ENABLED) {
|
||||
/* eslint-disable */
|
||||
console.error(message);
|
||||
/* eslint-enable */
|
||||
}
|
||||
}
|
||||
/* eslint-enable */
|
||||
|
||||
export class CustomError extends Error {
|
||||
constructor(msg: string) {
|
||||
@ -148,3 +133,7 @@ export class CustomWarning extends Error {
|
||||
Object.setPrototypeOf(this, CustomWarning.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export function fileExists(absolutePath: string) {
|
||||
return fs.existsSync(absolutePath);
|
||||
}
|
||||
|
239
tools/all-supported-blocks.txt
Normal file
239
tools/all-supported-blocks.txt
Normal file
@ -0,0 +1,239 @@
|
||||
acacia_log
|
||||
acacia_planks
|
||||
acacia_wood
|
||||
ancient_debris
|
||||
andesite
|
||||
basalt
|
||||
bedrock
|
||||
birch_log
|
||||
birch_planks
|
||||
birch_wood
|
||||
blackstone
|
||||
black_concrete
|
||||
black_concrete_powder
|
||||
black_glazed_terracotta
|
||||
black_terracotta
|
||||
black_wool
|
||||
blue_concrete
|
||||
blue_concrete_powder
|
||||
blue_glazed_terracotta
|
||||
blue_ice
|
||||
blue_terracotta
|
||||
blue_wool
|
||||
bone_block
|
||||
bookshelf
|
||||
brain_coral_block
|
||||
bricks
|
||||
brown_concrete
|
||||
brown_concrete_powder
|
||||
brown_glazed_terracotta
|
||||
brown_mushroom_block
|
||||
brown_terracotta
|
||||
brown_wool
|
||||
bubble_coral_block
|
||||
cartography_table
|
||||
chiseled_nether_bricks
|
||||
chiseled_polished_blackstone
|
||||
chiseled_quartz_block
|
||||
chiseled_red_sandstone
|
||||
chiseled_sandstone
|
||||
chiseled_stone_bricks
|
||||
clay
|
||||
coal_block
|
||||
coal_ore
|
||||
coarse_dirt
|
||||
cobblestone
|
||||
cracked_nether_bricks
|
||||
cracked_polished_blackstone_bricks
|
||||
cracked_stone_bricks
|
||||
crafting_table
|
||||
crimson_hyphae
|
||||
crimson_planks
|
||||
crimson_stem
|
||||
crying_obsidian
|
||||
cut_red_sandstone
|
||||
cut_sandstone
|
||||
cyan_concrete
|
||||
cyan_concrete_powder
|
||||
cyan_glazed_terracotta
|
||||
cyan_terracotta
|
||||
cyan_wool
|
||||
dark_oak_log
|
||||
dark_oak_planks
|
||||
dark_oak_wood
|
||||
dark_prismarine
|
||||
dead_brain_coral_block
|
||||
dead_bubble_coral_block
|
||||
dead_fire_coral_block
|
||||
dead_horn_coral_block
|
||||
dead_tube_coral_block
|
||||
diamond_block
|
||||
diamond_ore
|
||||
diorite
|
||||
dirt
|
||||
emerald_block
|
||||
emerald_ore
|
||||
end_stone
|
||||
end_stone_bricks
|
||||
fire_coral_block
|
||||
fletching_table
|
||||
frosted_ice_0
|
||||
frosted_ice_1
|
||||
frosted_ice_2
|
||||
frosted_ice_3
|
||||
gilded_blackstone
|
||||
glowstone
|
||||
gold_block
|
||||
gold_ore
|
||||
granite
|
||||
gravel
|
||||
gray_concrete
|
||||
gray_concrete_powder
|
||||
gray_glazed_terracotta
|
||||
gray_terracotta
|
||||
gray_wool
|
||||
green_concrete
|
||||
green_concrete_powder
|
||||
green_glazed_terracotta
|
||||
green_terracotta
|
||||
green_wool
|
||||
hay_block
|
||||
honeycomb_block
|
||||
horn_coral_block
|
||||
ice
|
||||
iron_block
|
||||
iron_ore
|
||||
jungle_log
|
||||
jungle_planks
|
||||
jungle_wood
|
||||
lapis_block
|
||||
lapis_ore
|
||||
light_blue_concrete
|
||||
light_blue_concrete_powder
|
||||
light_blue_glazed_terracotta
|
||||
light_blue_terracotta
|
||||
light_blue_wool
|
||||
light_gray_concrete
|
||||
light_gray_concrete_powder
|
||||
light_gray_glazed_terracotta
|
||||
light_gray_terracotta
|
||||
light_gray_wool
|
||||
lime_concrete
|
||||
lime_concrete_powder
|
||||
lime_glazed_terracotta
|
||||
lime_terracotta
|
||||
lime_wool
|
||||
lodestone
|
||||
magenta_concrete
|
||||
magenta_concrete_powder
|
||||
magenta_glazed_terracotta
|
||||
magenta_terracotta
|
||||
magenta_wool
|
||||
magma_block
|
||||
melon
|
||||
mossy_cobblestone
|
||||
mossy_stone_bricks
|
||||
mushroom_stem
|
||||
netherite_block
|
||||
netherrack
|
||||
nether_bricks
|
||||
nether_gold_ore
|
||||
nether_quartz_ore
|
||||
nether_wart_block
|
||||
note_block
|
||||
oak_log
|
||||
oak_planks
|
||||
oak_wood
|
||||
obsidian
|
||||
orange_concrete
|
||||
orange_concrete_powder
|
||||
orange_glazed_terracotta
|
||||
orange_terracotta
|
||||
orange_wool
|
||||
packed_ice
|
||||
pink_concrete
|
||||
pink_concrete_powder
|
||||
pink_glazed_terracotta
|
||||
pink_terracotta
|
||||
pink_wool
|
||||
polished_andesite
|
||||
polished_basalt
|
||||
polished_blackstone
|
||||
polished_blackstone_bricks
|
||||
polished_diorite
|
||||
polished_granite
|
||||
prismarine
|
||||
prismarine_bricks
|
||||
purple_concrete
|
||||
purple_concrete_powder
|
||||
purple_glazed_terracotta
|
||||
purple_terracotta
|
||||
purple_wool
|
||||
purpur_block
|
||||
purpur_pillar
|
||||
quartz_block
|
||||
quartz_bricks
|
||||
quartz_pillar
|
||||
redstone_block
|
||||
redstone_lamp
|
||||
redstone_ore
|
||||
red_concrete
|
||||
red_concrete_powder
|
||||
red_glazed_terracotta
|
||||
red_mushroom_block
|
||||
red_nether_bricks
|
||||
red_sand
|
||||
red_terracotta
|
||||
red_wool
|
||||
sand
|
||||
sea_lantern
|
||||
shroomlight
|
||||
smithing_table
|
||||
smooth_quartz
|
||||
smooth_red_sandstone
|
||||
smooth_sandstone
|
||||
smooth_stone
|
||||
smooth_stone_slab_double
|
||||
snow_block
|
||||
soul_sand
|
||||
soul_soil
|
||||
sponge
|
||||
spruce_log
|
||||
spruce_planks
|
||||
spruce_wood
|
||||
stone
|
||||
stone_bricks
|
||||
stripped_acacia_log
|
||||
stripped_acacia_wood
|
||||
stripped_birch_log
|
||||
stripped_birch_wood
|
||||
stripped_crimson_hyphae
|
||||
stripped_crimson_stem
|
||||
stripped_dark_oak_log
|
||||
stripped_dark_oak_wood
|
||||
stripped_jungle_log
|
||||
stripped_jungle_wood
|
||||
stripped_oak_log
|
||||
stripped_oak_wood
|
||||
stripped_spruce_log
|
||||
stripped_spruce_wood
|
||||
stripped_warped_hyphae
|
||||
stripped_warped_stem
|
||||
target
|
||||
terracotta
|
||||
tube_coral_block
|
||||
warped_hyphae
|
||||
warped_planks
|
||||
warped_stem
|
||||
warped_wart_block
|
||||
wet_sponge
|
||||
white_concrete
|
||||
white_concrete_powder
|
||||
white_glazed_terracotta
|
||||
white_terracotta
|
||||
white_wool
|
||||
yellow_concrete
|
||||
yellow_concrete_powder
|
||||
yellow_glazed_terracotta
|
||||
yellow_terracotta
|
||||
yellow_wool
|
@ -1,43 +1,50 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import images from "images";
|
||||
import { RGB, UV } from "../src/util";
|
||||
import { log, LogStyle } from "./logging";
|
||||
import { PNG } from "pngjs";
|
||||
import { isDirSetup, ASSERT, getAverageColour } from "./misc";
|
||||
import chalk from "chalk";
|
||||
import prompt from "prompt";
|
||||
const AdmZip = require("adm-zip");
|
||||
import { RGB, UV } from '../src/util';
|
||||
import { log, LogStyle } from './logging';
|
||||
import { isDirSetup, ASSERT, getAverageColour } from './misc';
|
||||
|
||||
prompt.start();
|
||||
prompt.get([{
|
||||
name: 'response',
|
||||
description: 'Do you want to fetch textures and models? (Y/n)',
|
||||
type: 'string',
|
||||
required: true,
|
||||
message: 'Respond with yes or no',
|
||||
conform: (response) => {
|
||||
return ["yes", "Y", "y", "no", "N", "n"].includes(response);
|
||||
}
|
||||
}], (err, res) => {
|
||||
if (err) {
|
||||
process.exit(1);
|
||||
}
|
||||
handleResponse(res);
|
||||
});
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import images from 'images';
|
||||
import { PNG } from 'pngjs';
|
||||
import chalk from 'chalk';
|
||||
import prompt from 'prompt';
|
||||
const AdmZip = require('adm-zip');
|
||||
|
||||
const handleResponse = (results: any) => {
|
||||
const responseYes = ["yes", "Y", "y"].includes(results.response as any);
|
||||
if (!responseYes) {
|
||||
buildAtlas();
|
||||
const schemaFetch: prompt.Schema = {
|
||||
properties: {
|
||||
response: {
|
||||
pattern: /^[YyNn]$/,
|
||||
description: 'Do you want to fetch textures and models? (Y/n)',
|
||||
message: 'Response must be Y or N',
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
pattern: /^[a-zA-Z\-]+$/,
|
||||
description: 'What do you want to call this texture atlas?',
|
||||
message: 'Must be only letters or dash',
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
void async function main() {
|
||||
const promptUser = await prompt.get(schemaFetch);
|
||||
|
||||
const responseYes = ['Y', 'y'].includes(promptUser.response as string);
|
||||
if (responseYes) {
|
||||
fetchModelsAndTextures();
|
||||
}
|
||||
|
||||
const versionsDir = path.join(process.env.APPDATA!, "./.minecraft/versions");
|
||||
buildAtlas(promptUser.name as string);
|
||||
}();
|
||||
|
||||
function fetchModelsAndTextures() {
|
||||
const versionsDir = path.join(process.env.APPDATA!, './.minecraft/versions');
|
||||
if (!fs.existsSync(versionsDir)) {
|
||||
log(LogStyle.Failure, "Could not fid .minecraft/versions\n");
|
||||
log(LogStyle.Failure, 'Could not fid .minecraft/versions\n');
|
||||
process.exit(1);
|
||||
}
|
||||
log(LogStyle.Success, ".minecraft/versions found successfully\n");
|
||||
log(LogStyle.Success, '.minecraft/versions found successfully\n');
|
||||
|
||||
const versions = fs.readdirSync(versionsDir)
|
||||
.filter((file) => fs.lstatSync(path.join(versionsDir, file)).isDirectory())
|
||||
@ -45,75 +52,66 @@ const handleResponse = (results: any) => {
|
||||
.sort((a, b) => b.birthtime.getTime() - a.birthtime.getTime());
|
||||
|
||||
for (let i = 0; i < versions.length; ++i) {
|
||||
const versionName = versions[i].file
|
||||
const versionName = versions[i].file;
|
||||
log(LogStyle.Info, `Searching in ${versionName} for ${versionName}.jar`);
|
||||
|
||||
const versionDir = path.join(versionsDir, versionName);
|
||||
const versionFiles = fs.readdirSync(versionDir);
|
||||
if (!versionFiles.includes(versionName + ".jar")) {
|
||||
if (!versionFiles.includes(versionName + '.jar')) {
|
||||
continue;
|
||||
}
|
||||
log(LogStyle.Success, `Up ${versionName}.jar successfully\n`);
|
||||
log(LogStyle.Success, `Found ${versionName}.jar successfully\n`);
|
||||
|
||||
const versionJarPath = path.join(versionDir, `${versionName}.jar`);
|
||||
|
||||
log(LogStyle.Info, `Upzipping ${versionName}.jar...`);
|
||||
var zip = new AdmZip(versionJarPath);
|
||||
const zip = new AdmZip(versionJarPath);
|
||||
const zipEntries = zip.getEntries();
|
||||
zipEntries.forEach((zipEntry: any) => {
|
||||
if (zipEntry.entryName.startsWith("assets/minecraft/textures/block")) {
|
||||
zip.extractEntryTo(zipEntry.entryName, path.join(__dirname, "./blocks"), false, true);
|
||||
} else if (zipEntry.entryName.startsWith("assets/minecraft/models/block")) {
|
||||
zip.extractEntryTo(zipEntry.entryName, path.join(__dirname, "./models"), false, true);
|
||||
if (zipEntry.entryName.startsWith('assets/minecraft/textures/block')) {
|
||||
zip.extractEntryTo(zipEntry.entryName, path.join(__dirname, './blocks'), false, true);
|
||||
} else if (zipEntry.entryName.startsWith('assets/minecraft/models/block')) {
|
||||
zip.extractEntryTo(zipEntry.entryName, path.join(__dirname, './models'), false, true);
|
||||
}
|
||||
});
|
||||
log(LogStyle.Success, `Extracted textures and models successfully\n`);
|
||||
|
||||
buildAtlas();
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const buildAtlas = () => {
|
||||
// Check /blocks and /models is setup correctly
|
||||
log(LogStyle.None, "Checking Minecraft assets are provided...");
|
||||
function buildAtlas(atlasName: string) {
|
||||
// Check /blocks and /models is setup correctly
|
||||
log(LogStyle.None, 'Checking Minecraft assets are provided...');
|
||||
|
||||
const texturesDirSetup = isDirSetup("./models", "assets/minecraft/textures/block");
|
||||
ASSERT(texturesDirSetup, "/blocks is not setup correctly");
|
||||
const texturesDirSetup = isDirSetup('./models', 'assets/minecraft/textures/block');
|
||||
ASSERT(texturesDirSetup, '/blocks is not setup correctly');
|
||||
|
||||
const modelsDirSetup = isDirSetup("./models", "assets/minecraft/models/block");
|
||||
ASSERT(modelsDirSetup, "/models is not setup correctly");
|
||||
const modelsDirSetup = isDirSetup('./models', 'assets/minecraft/models/block');
|
||||
ASSERT(modelsDirSetup, '/models is not setup correctly');
|
||||
|
||||
// Load the ignore list
|
||||
log(LogStyle.None, "Loading ignore list...")
|
||||
log(LogStyle.None, 'Loading ignore list...');
|
||||
let ignoreList: Array<string> = [];
|
||||
const ignoreListPath = path.join(__dirname, "./ignore-list.txt");
|
||||
const defaultIgnoreListPath = path.join(__dirname, "./default-ignore-list.txt");
|
||||
const ignoreListPath = path.join(__dirname, './ignore-list.txt');
|
||||
if (fs.existsSync(ignoreListPath)) {
|
||||
log(LogStyle.Success, "Found custom ignore list");
|
||||
ignoreList = fs.readFileSync(ignoreListPath, "utf-8").replace(/\r/g, "").split("\n");
|
||||
} else if (fs.existsSync(defaultIgnoreListPath)) {
|
||||
log(LogStyle.Success, "Found default ignore list");
|
||||
ignoreList = fs.readFileSync(defaultIgnoreListPath, "utf-8").replace(/\r/g, "").split("\n");
|
||||
log(LogStyle.Success, 'Found custom ignore list');
|
||||
ignoreList = fs.readFileSync(ignoreListPath, 'utf-8').replace(/\r/g, '').split('\n');
|
||||
} else {
|
||||
log(LogStyle.Warning, "No ignore list found, looked for ignore-list.txt and default-ignore-list.txt");
|
||||
log(LogStyle.Warning, 'No ignore list found, looked for ignore-list.txt');
|
||||
}
|
||||
log(LogStyle.Info, `${ignoreList.length} blocks found in ignore list\n`);
|
||||
|
||||
|
||||
//
|
||||
log(LogStyle.None, "Loading block models...")
|
||||
|
||||
/* eslint-disable */
|
||||
enum parentModel {
|
||||
Cube = "minecraft:block/cube",
|
||||
CubeAll = "minecraft:block/cube_all",
|
||||
CubeColumn = "minecraft:block/cube_column",
|
||||
CubeColumnHorizontal = "minecraft:block/cube_column_horizontal",
|
||||
TemplateSingleFace = "minecraft:block/template_single_face",
|
||||
TemplateGlazedTerracotta = "minecraft:block/template_glazed_terracotta",
|
||||
Cube = 'minecraft:block/cube',
|
||||
CubeAll = 'minecraft:block/cube_all',
|
||||
CubeColumn = 'minecraft:block/cube_column',
|
||||
CubeColumnHorizontal = 'minecraft:block/cube_column_horizontal',
|
||||
TemplateSingleFace = 'minecraft:block/template_single_face',
|
||||
TemplateGlazedTerracotta = 'minecraft:block/template_glazed_terracotta',
|
||||
}
|
||||
|
||||
/* eslint-enable */
|
||||
|
||||
interface Model {
|
||||
name: string,
|
||||
colour?: RGB,
|
||||
@ -121,23 +119,24 @@ const buildAtlas = () => {
|
||||
[face: string]: Texture
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface Texture {
|
||||
name: string,
|
||||
texcoord?: UV,
|
||||
colour?: RGB
|
||||
}
|
||||
|
||||
const faces = ["north", "south", "up", "down", "east", "west"];
|
||||
let allModels: Array<Model> = [];
|
||||
let usedTextures: Set<string> = new Set();
|
||||
fs.readdirSync(path.join(__dirname, "./models")).forEach(filename => {
|
||||
if (path.extname(filename) !== ".json") {
|
||||
|
||||
log(LogStyle.None, 'Loading block models...');
|
||||
const faces = ['north', 'south', 'up', 'down', 'east', 'west'];
|
||||
const allModels: Array<Model> = [];
|
||||
const usedTextures: Set<string> = new Set();
|
||||
fs.readdirSync(path.join(__dirname, './models')).forEach((filename) => {
|
||||
if (path.extname(filename) !== '.json') {
|
||||
return;
|
||||
};
|
||||
|
||||
const filePath = path.join(__dirname, "./models", filename);
|
||||
const fileData = fs.readFileSync(filePath, "utf8");
|
||||
const filePath = path.join(__dirname, './models', filename);
|
||||
const fileData = fs.readFileSync(filePath, 'utf8');
|
||||
const modelData = JSON.parse(fileData);
|
||||
const parsedPath = path.parse(filePath);
|
||||
const modelName = parsedPath.name;
|
||||
@ -148,58 +147,58 @@ const buildAtlas = () => {
|
||||
|
||||
let faceData: { [face: string]: Texture } = {};
|
||||
switch (modelData.parent) {
|
||||
case parentModel.CubeAll:
|
||||
faceData = {
|
||||
up: { name: modelData.textures.all },
|
||||
down: { name: modelData.textures.all },
|
||||
north: { name: modelData.textures.all },
|
||||
south: { name: modelData.textures.all },
|
||||
east: { name: modelData.textures.all },
|
||||
west: { name: modelData.textures.all }
|
||||
}
|
||||
break;
|
||||
case parentModel.CubeColumn:
|
||||
faceData = {
|
||||
up: { name: modelData.textures.end },
|
||||
down: { name: modelData.textures.end },
|
||||
north: { name: modelData.textures.side },
|
||||
south: { name: modelData.textures.side },
|
||||
east: { name: modelData.textures.side },
|
||||
west: { name: modelData.textures.side }
|
||||
}
|
||||
break;
|
||||
case parentModel.Cube:
|
||||
faceData = {
|
||||
up: { name: modelData.textures.up },
|
||||
down: { name: modelData.textures.down },
|
||||
north: { name: modelData.textures.north },
|
||||
south: { name: modelData.textures.south },
|
||||
east: { name: modelData.textures.east },
|
||||
west: { name: modelData.textures.west }
|
||||
}
|
||||
break;
|
||||
case parentModel.TemplateSingleFace:
|
||||
faceData = {
|
||||
up: { name: modelData.textures.texture },
|
||||
down: { name: modelData.textures.texture },
|
||||
north: { name: modelData.textures.texture },
|
||||
south: { name: modelData.textures.texture },
|
||||
east: { name: modelData.textures.texture },
|
||||
west: { name: modelData.textures.texture }
|
||||
}
|
||||
break;
|
||||
case parentModel.TemplateGlazedTerracotta:
|
||||
faceData = {
|
||||
up: { name: modelData.textures.pattern },
|
||||
down: { name: modelData.textures.pattern },
|
||||
north: { name: modelData.textures.pattern },
|
||||
south: { name: modelData.textures.pattern },
|
||||
east: { name: modelData.textures.pattern },
|
||||
west: { name: modelData.textures.pattern }
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
case parentModel.CubeAll:
|
||||
faceData = {
|
||||
up: { name: modelData.textures.all },
|
||||
down: { name: modelData.textures.all },
|
||||
north: { name: modelData.textures.all },
|
||||
south: { name: modelData.textures.all },
|
||||
east: { name: modelData.textures.all },
|
||||
west: { name: modelData.textures.all },
|
||||
};
|
||||
break;
|
||||
case parentModel.CubeColumn:
|
||||
faceData = {
|
||||
up: { name: modelData.textures.end },
|
||||
down: { name: modelData.textures.end },
|
||||
north: { name: modelData.textures.side },
|
||||
south: { name: modelData.textures.side },
|
||||
east: { name: modelData.textures.side },
|
||||
west: { name: modelData.textures.side },
|
||||
};
|
||||
break;
|
||||
case parentModel.Cube:
|
||||
faceData = {
|
||||
up: { name: modelData.textures.up },
|
||||
down: { name: modelData.textures.down },
|
||||
north: { name: modelData.textures.north },
|
||||
south: { name: modelData.textures.south },
|
||||
east: { name: modelData.textures.east },
|
||||
west: { name: modelData.textures.west },
|
||||
};
|
||||
break;
|
||||
case parentModel.TemplateSingleFace:
|
||||
faceData = {
|
||||
up: { name: modelData.textures.texture },
|
||||
down: { name: modelData.textures.texture },
|
||||
north: { name: modelData.textures.texture },
|
||||
south: { name: modelData.textures.texture },
|
||||
east: { name: modelData.textures.texture },
|
||||
west: { name: modelData.textures.texture },
|
||||
};
|
||||
break;
|
||||
case parentModel.TemplateGlazedTerracotta:
|
||||
faceData = {
|
||||
up: { name: modelData.textures.pattern },
|
||||
down: { name: modelData.textures.pattern },
|
||||
north: { name: modelData.textures.pattern },
|
||||
south: { name: modelData.textures.pattern },
|
||||
east: { name: modelData.textures.pattern },
|
||||
west: { name: modelData.textures.pattern },
|
||||
};
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
for (const face of faces) {
|
||||
@ -208,7 +207,7 @@ const buildAtlas = () => {
|
||||
|
||||
allModels.push({
|
||||
name: modelName,
|
||||
faces: faceData
|
||||
faces: faceData,
|
||||
});
|
||||
});
|
||||
log(LogStyle.Success, `${allModels.length} blocks loaded\n`);
|
||||
@ -216,15 +215,16 @@ const buildAtlas = () => {
|
||||
const atlasSize = Math.ceil(Math.sqrt(usedTextures.size));
|
||||
const atlasWidth = atlasSize * 16;
|
||||
|
||||
let offsetX = 0, offsetY = 0;
|
||||
let offsetX = 0;
|
||||
let offsetY = 0;
|
||||
const outputImage = images(atlasWidth * 3, atlasWidth * 3);
|
||||
|
||||
let textureDetails: { [textureName: string]: { texcoord: UV, colour: RGB } } = {};
|
||||
const textureDetails: { [textureName: string]: { texcoord: UV, colour: RGB } } = {};
|
||||
|
||||
log(LogStyle.None, "Building blocks.png...");
|
||||
usedTextures.forEach(textureName => {
|
||||
const shortName = textureName.split("/")[1]; // Eww
|
||||
const absolutePath = path.join(__dirname, "./blocks", shortName + ".png");
|
||||
log(LogStyle.None, `Building ${atlasName}.png...`);
|
||||
usedTextures.forEach((textureName) => {
|
||||
const shortName = textureName.split('/')[1]; // Eww
|
||||
const absolutePath = path.join(__dirname, './blocks', shortName + '.png');
|
||||
const fileData = fs.readFileSync(absolutePath);
|
||||
const pngData = PNG.sync.read(fileData);
|
||||
const image = images(absolutePath);
|
||||
@ -238,10 +238,10 @@ const buildAtlas = () => {
|
||||
textureDetails[textureName] = {
|
||||
texcoord: {
|
||||
u: 16 * (3 * offsetX + 1) / (atlasWidth * 3),
|
||||
v: 16 * (3 * offsetY + 1) / (atlasWidth * 3)
|
||||
v: 16 * (3 * offsetY + 1) / (atlasWidth * 3),
|
||||
},
|
||||
colour: getAverageColour(pngData)
|
||||
}
|
||||
colour: getAverageColour(pngData),
|
||||
},
|
||||
|
||||
++offsetX;
|
||||
if (offsetX >= atlasSize) {
|
||||
@ -252,9 +252,9 @@ const buildAtlas = () => {
|
||||
|
||||
|
||||
// Build up the output JSON
|
||||
log(LogStyle.None, "Building blocks.json...\n");
|
||||
log(LogStyle.None, `Building ${atlasName}.atlas...\n`);
|
||||
for (const model of allModels) {
|
||||
let blockColour = { r: 0, g: 0, b: 0 };
|
||||
const blockColour = new RGB(0, 0, 0);
|
||||
for (const face of faces) {
|
||||
const faceTexture = textureDetails[model.faces[face].name];
|
||||
const faceColour = faceTexture.colour;
|
||||
@ -270,12 +270,19 @@ const buildAtlas = () => {
|
||||
}
|
||||
|
||||
|
||||
log(LogStyle.None, "Exporting...");
|
||||
outputImage.save(path.join(__dirname, "../resources/blocks.png"));
|
||||
log(LogStyle.Success, "blocks.png exported to /resources");
|
||||
let outputJSON = { atlasSize: atlasSize, blocks: allModels };
|
||||
fs.writeFileSync(path.join(__dirname, "../resources/blocks.json"), JSON.stringify(outputJSON, null, 4));
|
||||
log(LogStyle.Success, "blocks.json exported to /resources\n");
|
||||
log(LogStyle.None, 'Exporting...');
|
||||
const atlasDir = path.join(__dirname, `../resources/atlases/${atlasName}.png`);
|
||||
outputImage.save(atlasDir);
|
||||
log(LogStyle.Success, `${atlasName}.png exported to /resources/atlases/`);
|
||||
const outputJSON = {
|
||||
atlasSize: atlasSize,
|
||||
atlasTexture: atlasDir,
|
||||
blocks: allModels,
|
||||
};
|
||||
fs.writeFileSync(path.join(__dirname, `../resources/atlases/${atlasName}.atlas`), JSON.stringify(outputJSON, null, 4));
|
||||
log(LogStyle.Success, `${atlasName}.atlas exported to /resources/atlases/\n`);
|
||||
|
||||
console.log(chalk.cyanBright(chalk.inverse("DONE") + " Now run " + chalk.inverse(" npm start ") + " and the new blocks will be used"));
|
||||
}
|
||||
/* eslint-disable */
|
||||
console.log(chalk.cyanBright(chalk.inverse('DONE') + ' Now run ' + chalk.inverse(' npm start ') + ' and the new blocks will be used'));
|
||||
/* eslint-enable */
|
||||
}
|
||||
|
51
tools/build-palette.ts
Normal file
51
tools/build-palette.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { log, LogStyle } from './logging';
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import prompt from 'prompt';
|
||||
|
||||
void async function main() {
|
||||
test();
|
||||
}();
|
||||
|
||||
async function test() {
|
||||
log(LogStyle.Info, 'Creating a new palette...');
|
||||
|
||||
const paletteBlocksDir = path.join(__dirname, './new-palette-blocks.txt');
|
||||
if (!fs.existsSync(paletteBlocksDir)) {
|
||||
log(LogStyle.Failure, 'Could not find /tools/new-palette-blocks.txt');
|
||||
return;
|
||||
}
|
||||
log(LogStyle.Success, 'Found list of blocks to use in /tools/new-palette-blocks.txt');
|
||||
|
||||
let blocksToUse: string[] = fs.readFileSync(paletteBlocksDir, 'utf8').replace(/\r/g, '').split('\n');
|
||||
blocksToUse = blocksToUse.filter((block) => {
|
||||
return block.length !== 0;
|
||||
});
|
||||
if (blocksToUse.length === 0) {
|
||||
log(LogStyle.Failure, 'No blocks listed for palette');
|
||||
log(LogStyle.Info, 'List the blocks you want from /tools/all-supported-blocks.txt ');
|
||||
return;
|
||||
}
|
||||
log(LogStyle.Info, `Found ${blocksToUse.length} blocks to use`);
|
||||
|
||||
const schema: prompt.Schema = {
|
||||
properties: {
|
||||
paletteName: {
|
||||
pattern: /^[a-zA-Z\-]+$/,
|
||||
description: 'What do you want to call this block palette? (e.g. my-block-palette)',
|
||||
message: 'Must be only letters or dash',
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const promptUser = await prompt.get(schema);
|
||||
|
||||
const paletteJSON = {
|
||||
blocks: blocksToUse,
|
||||
};
|
||||
|
||||
fs.writeFileSync(path.join(__dirname, `../resources/palettes/${promptUser.paletteName}.palette`), JSON.stringify(paletteJSON, null, 4));
|
||||
log(LogStyle.Success, `Successfully created ${promptUser.paletteName}.palette in /resources/palettes/`);
|
||||
}
|
@ -14,6 +14,7 @@ black_stained_glass.json
|
||||
light_blue_stained_glass.json
|
||||
green_stained_glass.json
|
||||
light_gray_stained_glass.json
|
||||
gray_stained_glass.json
|
||||
magenta_stained_glass.json
|
||||
pink_stained_glass.json
|
||||
blue_stained_glass.json
|
||||
@ -24,6 +25,5 @@ glass.json
|
||||
spawner.json
|
||||
brown_mushroom_block_inventory.json
|
||||
red_mushroom_block_inventory.json
|
||||
cartography_table.json
|
||||
fletching_table.json
|
||||
mushroom_stem_inventory.json
|
||||
redstone_lamp_on.json
|
@ -1,24 +1,28 @@
|
||||
import chalk from "chalk";
|
||||
import chalk from 'chalk';
|
||||
|
||||
export enum LogStyle {
|
||||
None = "None",
|
||||
Info = "Info",
|
||||
Warning = "Warning",
|
||||
Failure = "Failure",
|
||||
Success = "Success"
|
||||
None = 'None',
|
||||
Info = 'Info',
|
||||
Warning = 'Warning',
|
||||
Failure = 'Failure',
|
||||
Success = 'Success'
|
||||
}
|
||||
|
||||
const LogStyleDetails: {[style: string]: {style: chalk.Chalk, prefix: string}} = {};
|
||||
LogStyleDetails[LogStyle.Info] = {style: chalk.white, prefix: chalk.white.inverse("INFO")};
|
||||
LogStyleDetails[LogStyle.Warning] = {style: chalk.yellow, prefix: chalk.yellow.inverse("WARN")};
|
||||
LogStyleDetails[LogStyle.Failure] = {style: chalk.red, prefix: chalk.red.inverse("UHOH")};
|
||||
LogStyleDetails[LogStyle.Success] = {style: chalk.green, prefix: chalk.green.inverse(" OK ")};
|
||||
LogStyleDetails[LogStyle.Info] = {style: chalk.white, prefix: chalk.white.inverse('INFO')};
|
||||
LogStyleDetails[LogStyle.Warning] = {style: chalk.yellow, prefix: chalk.yellow.inverse('WARN')};
|
||||
LogStyleDetails[LogStyle.Failure] = {style: chalk.red, prefix: chalk.red.inverse('UHOH')};
|
||||
LogStyleDetails[LogStyle.Success] = {style: chalk.green, prefix: chalk.green.inverse(' OK ')};
|
||||
|
||||
export function log(style: LogStyle, message: string) {
|
||||
if (style === LogStyle.None) {
|
||||
/* eslint-disable */
|
||||
console.log(chalk.whiteBright(message));
|
||||
/* eslint-enable */
|
||||
} else {
|
||||
const details: {style: chalk.Chalk, prefix: string} = LogStyleDetails[style];
|
||||
console.log(details.prefix + " " + details.style(message));
|
||||
/* eslint-disable */
|
||||
console.log(details.prefix + ' ' + details.style(message));
|
||||
/* eslint-enable */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,19 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { PNG, PNGWithMetadata } from "pngjs";
|
||||
import { log, LogStyle } from "./logging";
|
||||
import { log, LogStyle } from './logging';
|
||||
import { RGB } from '../src/util';
|
||||
|
||||
export const ASSERT = (condition: boolean, onFailMessage: string) => { if (!condition) { log(LogStyle.Failure, onFailMessage); process.exit(0); } }
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { PNG } from 'pngjs';
|
||||
|
||||
export const ASSERT = (condition: boolean, onFailMessage: string) => {
|
||||
if (!condition) {
|
||||
log(LogStyle.Failure, onFailMessage);
|
||||
process.exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
export function isDirSetup(relativePath: string, jarAssetDir: string) {
|
||||
const dir = path.join(__dirname, relativePath)
|
||||
const dir = path.join(__dirname, relativePath);
|
||||
if (fs.existsSync(dir)) {
|
||||
if (fs.readdirSync(dir).length > 0) {
|
||||
return true;
|
||||
@ -19,16 +26,18 @@ export function isDirSetup(relativePath: string, jarAssetDir: string) {
|
||||
}
|
||||
|
||||
export function getAverageColour(image: PNG) {
|
||||
let r = 0, g = 0, b = 0;
|
||||
let r = 0;
|
||||
let g = 0;
|
||||
let b = 0;
|
||||
for (let x = 0; x < image.width; ++x) {
|
||||
for (let y = 0; y < image.height; ++y) {
|
||||
const index = 4 * (image.width * y + x);
|
||||
const rgba = image.data.slice(index, index + 4);
|
||||
const rgba = image.data.slice(index, index + 4);
|
||||
r += rgba[0];
|
||||
g += rgba[1];
|
||||
b += rgba[2];
|
||||
}
|
||||
}
|
||||
const numPixels = image.width * image.height;
|
||||
return { r: r / (255 * numPixels), g: g / (255 * numPixels), b: b / (255 * numPixels) };
|
||||
}
|
||||
return new RGB(r / (255 * numPixels), g / (255 * numPixels), b / (255 * numPixels));
|
||||
}
|
||||
|
80
tools/new-palette-blocks.txt
Normal file
80
tools/new-palette-blocks.txt
Normal file
@ -0,0 +1,80 @@
|
||||
black_concrete
|
||||
black_concrete_powder
|
||||
black_glazed_terracotta
|
||||
black_terracotta
|
||||
black_wool
|
||||
blue_concrete
|
||||
blue_concrete_powder
|
||||
blue_glazed_terracotta
|
||||
blue_terracotta
|
||||
blue_wool
|
||||
brown_concrete
|
||||
brown_concrete_powder
|
||||
brown_glazed_terracotta
|
||||
brown_terracotta
|
||||
brown_wool
|
||||
cyan_concrete
|
||||
cyan_concrete_powder
|
||||
cyan_glazed_terracotta
|
||||
cyan_terracotta
|
||||
cyan_wool
|
||||
gray_concrete
|
||||
gray_concrete_powder
|
||||
gray_glazed_terracotta
|
||||
gray_terracotta
|
||||
gray_wool
|
||||
green_concrete
|
||||
green_concrete_powder
|
||||
green_glazed_terracotta
|
||||
green_terracotta
|
||||
green_wool
|
||||
light_blue_concrete
|
||||
light_blue_concrete_powder
|
||||
light_blue_glazed_terracotta
|
||||
light_blue_terracotta
|
||||
light_blue_wool
|
||||
light_gray_concrete
|
||||
light_gray_concrete_powder
|
||||
light_gray_glazed_terracotta
|
||||
light_gray_terracotta
|
||||
light_gray_wool
|
||||
lime_concrete
|
||||
lime_concrete_powder
|
||||
lime_glazed_terracotta
|
||||
lime_terracotta
|
||||
lime_wool
|
||||
magenta_concrete
|
||||
magenta_concrete_powder
|
||||
magenta_glazed_terracotta
|
||||
magenta_terracotta
|
||||
magenta_wool
|
||||
orange_concrete
|
||||
orange_concrete_powder
|
||||
orange_glazed_terracotta
|
||||
orange_terracotta
|
||||
orange_wool
|
||||
pink_concrete
|
||||
pink_concrete_powder
|
||||
pink_glazed_terracotta
|
||||
pink_terracotta
|
||||
pink_wool
|
||||
purple_concrete
|
||||
purple_concrete_powder
|
||||
purple_glazed_terracotta
|
||||
purple_terracotta
|
||||
purple_wool
|
||||
red_concrete
|
||||
red_concrete_powder
|
||||
red_glazed_terracotta
|
||||
red_terracotta
|
||||
red_wool
|
||||
white_concrete
|
||||
white_concrete_powder
|
||||
white_glazed_terracotta
|
||||
white_terracotta
|
||||
white_wool
|
||||
yellow_concrete
|
||||
yellow_concrete_powder
|
||||
yellow_glazed_terracotta
|
||||
yellow_terracotta
|
||||
yellow_wool
|
Loading…
Reference in New Issue
Block a user