forked from mirror/ObjToSchematic
Blocks are now exported to schematic
This commit is contained in:
parent
99aa9bcd71
commit
3e1538aa97
1402
resources/block_ids.json
Normal file
1402
resources/block_ids.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -169,14 +169,6 @@ export class AppContext {
|
||||
const exportFormat = UI.Get.layout.export.elements.export.getCachedValue() as string;
|
||||
const exporter = (exportFormat === 'schematic') ? new Schematic() : new Litematic();
|
||||
|
||||
if (exportFormat === 'schematic') {
|
||||
this._warnings.push(`
|
||||
The .schematic format does not support newer Minecraft blocks.
|
||||
For now, all blocks are exported as Stone blocks until a block palette
|
||||
is available that only uses supported blocks.
|
||||
`);
|
||||
}
|
||||
|
||||
const filePath = remote.dialog.showSaveDialogSync({
|
||||
title: 'Save structure',
|
||||
buttonLabel: 'Save',
|
||||
|
@ -26,14 +26,6 @@ export interface BlockInfo {
|
||||
faces: FaceInfo
|
||||
}
|
||||
|
||||
// https://minecraft.fandom.com/wiki/Java_Edition_data_values/Pre-flattening/Block_IDs
|
||||
/* eslint-disable */
|
||||
export enum Block {
|
||||
Stone = 1.0,
|
||||
Dirt = 3.0,
|
||||
Cobblestone = 4.0
|
||||
}
|
||||
|
||||
interface BlockPalette {
|
||||
blocks: string[];
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
import * as zlib from 'zlib';
|
||||
import * as fs from 'fs';
|
||||
import path from 'path';
|
||||
import { NBT, TagType, writeUncompressed } from 'prismarine-nbt';
|
||||
import { Vector3 } from './vector';
|
||||
import { Block } from './block_atlas';
|
||||
import { BlockMesh } from './block_mesh';
|
||||
import { LOG } from './util';
|
||||
import { AppContext } from './app_context';
|
||||
|
||||
export abstract class Exporter {
|
||||
protected _sizeVector!: Vector3;
|
||||
@ -42,13 +44,32 @@ export class Schematic extends Exporter {
|
||||
const bufferSize = this._sizeVector.x * this._sizeVector.y * this._sizeVector.z;
|
||||
|
||||
const blocksData = Array<number>(bufferSize);
|
||||
const metaData = Array<number>(bufferSize);
|
||||
const bounds = blockMesh.getVoxelMesh().getBounds();
|
||||
|
||||
const schematicBlocks: { [blockName: string]: { id: number, meta: number, name: string } } = JSON.parse(fs.readFileSync(path.join(__dirname, '../resources/block_ids.json'), 'utf8'));
|
||||
|
||||
const blocks = blockMesh.getBlocks();
|
||||
const unsupportedBlocks = new Set<string>();
|
||||
let numBlocksUnsupported = 0;
|
||||
for (const block of blocks) {
|
||||
const indexVector = Vector3.sub(block.voxel.position, bounds.min);
|
||||
const index = this._getBufferIndex(indexVector, this._sizeVector);
|
||||
blocksData[index] = Block.Stone;
|
||||
if (block.blockInfo.name in schematicBlocks) {
|
||||
const schematicBlock = schematicBlocks[block.blockInfo.name];
|
||||
blocksData[index] = new Int8Array([schematicBlock.id])[0];
|
||||
metaData[index] = new Int8Array([schematicBlock.meta])[0];
|
||||
} else {
|
||||
blocksData[index] = 1; // Default to a Stone block
|
||||
metaData[index] = 0;
|
||||
unsupportedBlocks.add(block.blockInfo.name);
|
||||
++numBlocksUnsupported;
|
||||
}
|
||||
}
|
||||
|
||||
if (unsupportedBlocks.size > 0) {
|
||||
AppContext.Get.addWarning(`${numBlocksUnsupported} blocks (${unsupportedBlocks.size} unique) are not supported by the .schematic format, Stone block are used in their place. Try using the schematic-friendly palette, or export using .litematica`);
|
||||
LOG('Unsupported blocks', unsupportedBlocks);
|
||||
}
|
||||
|
||||
const nbt: NBT = {
|
||||
@ -60,7 +81,7 @@ export class Schematic extends Exporter {
|
||||
Length: { type: TagType.Short, value: this._sizeVector.z },
|
||||
Materials: { type: TagType.String, value: 'Alpha' },
|
||||
Blocks: { type: TagType.ByteArray, value: blocksData },
|
||||
Data: { type: TagType.ByteArray, value: new Array<number>(bufferSize).fill(0) },
|
||||
Data: { type: TagType.ByteArray, value: metaData },
|
||||
Entities: { type: TagType.List, value: { type: TagType.Int, value: Array(0) } },
|
||||
TileEntities: { type: TagType.List, value: { type: TagType.Int, value: Array(0) } },
|
||||
},
|
||||
@ -136,8 +157,8 @@ export class Litematic extends Exporter {
|
||||
const blockStates = new Array<long>();
|
||||
|
||||
for (let i = blockEncoding.length; i > 0; i -= 64) {
|
||||
let right = parseInt(blockEncoding.substring(i-32, i), 2);
|
||||
let left = parseInt(blockEncoding.substring(i-64, i-32), 2);
|
||||
let right = parseInt(blockEncoding.substring(i - 32, i), 2);
|
||||
let left = parseInt(blockEncoding.substring(i - 64, i - 32), 2);
|
||||
|
||||
// TODO: Cleanup, UINT32 -> INT32
|
||||
if (right > 2147483647) {
|
||||
|
@ -5,10 +5,6 @@ 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');
|
||||
@ -48,4 +44,4 @@ async function test() {
|
||||
|
||||
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/`);
|
||||
}
|
||||
}();
|
||||
|
Loading…
Reference in New Issue
Block a user