Fixed .litematica exporting

This commit is contained in:
Lucas Dower 2021-09-10 19:17:50 +01:00
parent b9aa86d59d
commit 94b76ef0eb
7 changed files with 333 additions and 212 deletions

View File

@ -1,104 +1,112 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<title>ObjToSchematic</title>
<link rel="stylesheet" href="./styles.css">
<link rel="stylesheet" href="./src/vendor/bootstrap.css">
</head>
<head>
<meta charset="utf8">
<title>ObjToSchematic</title>
<link rel="stylesheet" href="./styles.css">
<link rel="stylesheet" href="./src/vendor/bootstrap.css">
</head>
<body>
<canvas id="c"></canvas>
<div class="toolbar">
<div class="container">
<div class="row">
<div class="col">
<div class="input-group">
<input type="file" accept=".obj" class="form-control" id="fileInput">
<button id="loadBtn" class="btn btn-primary border-0" type="button">
<img src="./resources/svg/load.svg" alt="">
Load
</button>
</div>
<body>
<canvas id="c"></canvas>
<div class="toolbar">
<div class="container">
<div class="row">
<div class="col">
<div class="input-group">
<input type="file" accept=".obj" class="form-control" id="fileInput">
<button id="loadBtn" class="btn btn-primary border-0" type="button">
<img src="./resources/svg/load.svg" alt="">
Load
</button>
</div>
<div class="col">
<div class="input-group">
<label class="input-group-text ">Voxel size</label>
<input id="voxelInput" type="number" min="0.1" step="0.1" value="0.1" class="form-control border-0" disabled>
<button id="splitBtn" class="btn btn-primary border-0" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Half voxel size (faster)" disabled>
<img src="./resources/svg/split.svg" alt="">
</button>
<!--
</div>
<div class="col">
<div class="input-group">
<label class="input-group-text ">Voxel size</label>
<input id="voxelInput" type="number" min="0.1" step="0.1" value="0.1" class="form-control border-0"
disabled>
<button id="splitBtn" class="btn btn-primary border-0" type="button" data-bs-toggle="tooltip"
data-bs-placement="bottom" title="Half voxel size (faster)" disabled>
<img src="./resources/svg/split.svg" alt="">
</button>
<!--
<button id="joinBtn" class="btn btn-primary border-0" type="button" disabled>
<img src="./resources/svg/join.svg" alt="">
</button>
-->
<button id="voxelBtn" class="btn btn-primary border-0" type="button" disabled>
<img src="./resources/svg/voxel.svg" alt="">
Voxelise
</button>
</div>
</div>
<div class="col">
<div class="d-grid">
<button id="exportBtnDisclaimer" class="btn btn-danger border-0" type="button" disabled>
<img src="./resources/svg/save.svg" alt="">
Export schematic
</button>
</div>
<button id="voxelBtn" class="btn btn-primary border-0" type="button" disabled>
<img src="./resources/svg/voxel.svg" alt="">
Voxelise
</button>
</div>
</div>
</div>
</div>
<div id="toast" class="toast canvas-toast align-items-center text-white bg-danger border-0" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div id="toastText" class="toast-body ms-2">
toastText
</div>
</div>
</div>
<!-- EXPORT DISCLAIMER -->
<div id="modalExport" class="modal custom-modal-background fade" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div id="modalExportText" class="modal-body">
<p>modalText</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button id="exportBtn" type="button" class="btn btn-danger">
<img src="./resources/svg/save.svg" alt="">
Export
<div class="col">
<div class="btn-group" role="group" aria-label="Basic example">
<button id="exportSchematic" type="button" class="btn btn-danger" disabled>
<img src="./resources/svg/save.svg" alt="">
Export .schematic
</button>
<button id="exportLitematic" type="button" class="btn btn-danger" disabled>
<img src="./resources/svg/save.svg" alt="">
Export .litematic
</button>
</div>
</div>
</div>
</div>
</div>
<!-- GENERAL DISCLAIMER -->
<div id="modalGeneral" class="modal custom-modal-background fade" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div id="modalGeneralText" class="modal-body">
<p>modalText</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Okay</button>
</div>
<div id="toast" class="toast canvas-toast align-items-center text-white bg-danger border-0" role="alert"
aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div id="toastText" class="toast-body ms-2">
toastText
</div>
</div>
</div>
<!-- EXPORT DISCLAIMER -->
<div id="modalExport" class="modal custom-modal-background fade" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div id="modalExportText" class="modal-body">
<p>modalText</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button id="exportBtn" type="button" class="btn btn-danger">
<img src="./resources/svg/save.svg" alt="">
Export
</button>
</div>
</div>
</div>
</div>
</body>
<!-- GENERAL DISCLAIMER -->
<div id="modalGeneral" class="modal custom-modal-background fade" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div id="modalGeneralText" class="modal-body">
<p>modalText</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Okay</button>
</div>
</div>
</div>
</div>
<script src="./src/vendor/jquery-3.6.0.min.js"></script>
<script src="./src/vendor/jquery-3.3.1.slim.min.js"></script>
<script src="./src/vendor/popper.min.js"></script>
<script src="./src/vendor/bootstrap.min.js"></script>
<script>
require("./dist/client.js")
</body>
<script src="./src/vendor/jquery-3.6.0.min.js"></script>
<script src="./src/vendor/jquery-3.3.1.slim.min.js"></script>
<script src="./src/vendor/popper.min.js"></script>
<script src="./src/vendor/bootstrap.min.js"></script>
<script>
require("./dist/client.js")
</script>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 738 KiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

@ -2,7 +2,7 @@ import { Renderer } from "./renderer";
import { Mesh } from "./mesh";
import { VoxelManager } from "./voxel_manager";
import { Vector3 } from "./vector.js";
import { Schematic, Litematic } from "./schematic";
import { Schematic, Litematic, Exporter } from "./schematic";
//const dialog = from 'electron').remote.dialog;
import {remote} from 'electron';
import * as bootstrap from "bootstrap";
@ -13,6 +13,11 @@ enum ToastColour {
GREEN = "bg-success"
}
export enum ExportFormat {
SCHEMATIC = "schematic",
LITEMATIC = "litematic"
}
export class AppContext {
@ -24,7 +29,9 @@ export class AppContext {
private _toast: bootstrap.Toast;
private _modalExport: bootstrap.Modal;
//private _modalVoxelise: bootstrap.Modal;
private _modalGeneral: bootstrap.Modal;
private _cachedFormat?: ExportFormat;
constructor() {
@ -41,9 +48,10 @@ export class AppContext {
this._toast = new bootstrap.Toast(<HTMLElement>document.getElementById('toast'), {delay: 3000});
this._modalExport = new bootstrap.Modal(<HTMLElement>document.getElementById('modalExport'), {});
//this._modalVoxelise = new bootstrap.Modal(<HTMLElement>document.getElementById('modalVoxelise'), {});
this._modalGeneral = new bootstrap.Modal(<HTMLElement>document.getElementById('modalGeneral'), {});
this._showModalGeneral("Note that in this current version, all blocks in the schematic will be exported as Stone blocks. This will be changed in version 0.4.");
//this._showModalGeneral("Note that in this current version, all blocks in the schematic will be exported as Stone blocks. This will be changed in version 0.4.");
}
public load() {
@ -61,7 +69,7 @@ export class AppContext {
try {
this._loadedMesh = new Mesh(files[0].path, this._gl);
} catch (err) {
} catch (err: any) {
this._showToast(err.message, ToastColour.RED);
console.log(err);
return;
@ -74,7 +82,9 @@ export class AppContext {
$('#voxelInput').prop('disabled', false);
$('#voxelBtn').prop('disabled', false);
$('#splitBtn').prop('disabled', true);
$('#exportBtnDisclaimer').prop('disabled', true);
$('#exportSchematic').prop('disabled', true);
$('#exportLitematic').prop('disabled', true);
this._showToast(`Successfully loaded ${file.name}`, ToastColour.GREEN);
}
@ -92,6 +102,11 @@ export class AppContext {
}
*/
public voxeliseDisclaimer() {
//this._modalVoxelise.show();
this.voxelise();
}
public voxelise() {
const newVoxelSize = $("#voxelInput").prop('value');
if (newVoxelSize < 0.001) {
@ -112,38 +127,49 @@ export class AppContext {
this._renderer.clear();
this._renderer.registerVoxelMesh(this._voxelManager);
this._renderer.compile();
} catch (err) {
} catch (err: any) {
this._showToast(err.message, ToastColour.RED);
return;
}
$('#exportBtnDisclaimer').prop('disabled', false);
//$('#splitBtn').prop('disabled', false);
$('#exportSchematic').prop('disabled', false);
$('#exportLitematic').prop('disabled', false);
this._showToast("Voxelised successfully", ToastColour.GREEN);
}
public exportDisclaimer() {
public exportDisclaimer(exportFormat: ExportFormat) {
const schematicHeight = Math.ceil(this._voxelManager.maxZ - this._voxelManager.minZ);
let message = "";
if (schematicHeight > 320) {
let message = `Note, this schematic is <b>${schematicHeight}</b> blocks tall, this is larger than the height of a Minecraft world (320 in 1.17, 256 in <=1.16).`
this._showModalExport(message);
} else {
this.export();
message += `Note, this structure is <b>${schematicHeight}</b> blocks tall, this is larger than the height of a Minecraft world (320 in 1.17, 256 in <=1.16). `;
}
if (exportFormat == ExportFormat.SCHEMATIC) {
message += "Schematic files only support pre-1.13 blocks. As a result, all blocks will be exported as Stone. To export the blocks use the .litematic format with the Litematica mod.";
}
this._cachedFormat = exportFormat;
if (message.length == 0) {
this.export();
} else {
this._showModalExport(message);
}
}
public export() {
this._modalExport.hide();
const filePath = remote.dialog.showSaveDialogSync({
title: "Save schematic",
title: "Save structure",
buttonLabel: "Save",
filters: [{
filters: this._cachedFormat == ExportFormat.SCHEMATIC ? [{
name: 'Schematic',
extensions: ['schematic']
}] : [{
name: 'Litematic',
extensions: ['litematic']
}]
});
@ -153,15 +179,20 @@ export class AppContext {
}
try {
const schematic = new Litematic(this._voxelManager);
schematic.exportSchematic(filePath);
let exporter: Exporter;
if (this._cachedFormat == ExportFormat.SCHEMATIC) {
exporter = new Schematic(this._voxelManager);
} else {
exporter = new Litematic(this._voxelManager);
}
exporter.export(filePath);
} catch (err) {
this._showToast("Failed to export schematic", ToastColour.RED);
this._showToast("Failed to export", ToastColour.RED);
console.error(err);
return;
}
this._showToast("Successfully saved schematic", ToastColour.GREEN);
this._showToast("Successfully saved", ToastColour.GREEN);
}

View File

@ -1,4 +1,5 @@
import { AppContext } from "./app_context";
import { ExportFormat } from "./app_context";
const context = new AppContext();
@ -9,7 +10,7 @@ $("#loadBtn").on("click", () => {
$("#voxelBtn").on("click", () => {
context.voxelise();
context.voxeliseDisclaimer();
});
@ -20,15 +21,20 @@ $("#splitBtn").on("click", () => {
*/
$("#exportBtnDisclaimer").on("click", async () => {
context.exportDisclaimer();
});
$("#exportBtn").on("click", async () => {
context.export();
});
$("#exportSchematic").on("click", async () => {
context.exportDisclaimer(ExportFormat.SCHEMATIC);
});
$("#exportLitematic").on("click", async () => {
context.exportDisclaimer(ExportFormat.LITEMATIC);
});
function render(time: number) {
context.draw();
requestAnimationFrame(render);

View File

@ -1,34 +1,63 @@
import zlib from "zlib";
import fs from "fs";
import * as zlib from "zlib";
import * as fs from "fs";
import { NBT, TagType, writeUncompressed } from "prismarine-nbt";
import { Vector3 } from "./vector";
import { VoxelManager } from "./voxel_manager";
import { Block } from "./block_atlas";
import { powerMonitor } from "electron";
export class Schematic {
export abstract class Exporter {
private _sizeVector: Vector3;
private _schematic: NBT;
protected _voxelManager: VoxelManager
protected _minPos: Vector3
protected _maxPos: Vector3
protected _sizeVector: Vector3
constructor(voxelManager: VoxelManager) {
const minPos = new Vector3(voxelManager.minX, voxelManager.minY, voxelManager.minZ);
const maxPos = new Vector3(voxelManager.maxX, voxelManager.maxY, voxelManager.maxZ);
this._voxelManager = voxelManager;
this._minPos = new Vector3(voxelManager.minX, voxelManager.minY, voxelManager.minZ);
this._maxPos = new Vector3(voxelManager.maxX, voxelManager.maxY, voxelManager.maxZ);
this._sizeVector = Vector3.sub(this._maxPos, this._minPos).addScalar(1);
console.log(this._minPos, this._maxPos);
}
abstract convertToNBT(): NBT
export(filePath: string): boolean {
const nbt = this.convertToNBT();
const outBuffer = fs.createWriteStream(filePath);
const newBuffer = writeUncompressed(nbt, "big");
zlib.gzip(newBuffer, (err, buffer) => {
if (!err) {
outBuffer.write(buffer);
outBuffer.end();
}
return err;
});
return false;
}
}
export class Schematic extends Exporter {
convertToNBT() {
this._sizeVector = Vector3.addScalar(Vector3.sub(maxPos, minPos), 1);
const bufferSize = this._sizeVector.x * this._sizeVector.y * this._sizeVector.z;
let blocksData = Array<number>(bufferSize);
voxelManager.voxels.forEach(voxel => {
//console.log(voxel);
const indexVector = Vector3.sub(voxel.position, minPos);
const index = this._getBufferIndex(indexVector);
//this._schematic.value.Blocks.value[index] = 1;
this._voxelManager.voxels.forEach(voxel => {
const indexVector = Vector3.sub(voxel.position, this._minPos);
const index = this._getBufferIndex(indexVector, this._sizeVector);
blocksData[index] = Block.Stone;
});
this._schematic = {
const nbt: NBT = {
type: TagType.Compound,
name: 'Schematic',
value: {
@ -42,110 +71,121 @@ export class Schematic {
TileEntities: { type: TagType.List, value: { type: TagType.Int, value: Array(0) } }
}
};
return nbt;
}
_getBufferIndex(vec: Vector3) {
return (this._sizeVector.z * this._sizeVector.x * vec.y) + (this._sizeVector.x * vec.z) + vec.x;
}
exportSchematic(filePath: string) {
const outBuffer = fs.createWriteStream(filePath);
const newBuffer = writeUncompressed(this._schematic, "big");
zlib.gzip(newBuffer, (err, buffer) => {
if (!err) {
outBuffer.write(buffer);
outBuffer.end(() => console.log('Written!'));
}
else {
throw err;
}
});
_getBufferIndex(vec: Vector3, sizeVector: Vector3) {
return (sizeVector.z * sizeVector.x * vec.y) + (sizeVector.x * vec.z) + vec.x;
}
}
type BlockID = number;
type long = [number, number];
interface BlockMapping {
[name: string]: BlockID
}
export class Litematic {
private _sizeVector: Vector3;
private _litematic: NBT;
export class Litematic extends Exporter {
// XZY
_getBufferIndex(vec: Vector3) {
return (this._sizeVector.z * this._sizeVector.x * vec.y) + (this._sizeVector.x * vec.z) + vec.x;
}
constructor(voxelManager: VoxelManager) {
const minPos = new Vector3(voxelManager.minX, voxelManager.minY, voxelManager.minZ);
const maxPos = new Vector3(voxelManager.maxX, voxelManager.maxY, voxelManager.maxZ);
this._sizeVector = Vector3.sub(maxPos, minPos).addScalar(1);
console.log("sizeVector", this._sizeVector);
const bufferSize = this._sizeVector.x * this._sizeVector.y * this._sizeVector.z;
let buffer = Array<number>(bufferSize);
for (let i = 0; i < bufferSize; ++i) {
buffer[i] = 0;
}
const blockPalette = voxelManager.blockPalette;
let blockMapping: { [name: string]: number } = {"air": 0};
_createBlockMapping(): BlockMapping {
const blockPalette = this._voxelManager.blockPalette;
let blockMapping: BlockMapping = {"air": 0};
for (let i = 0; i < blockPalette.length; ++i) {
const blockName = blockPalette[i];
blockMapping[blockName] = i + 1; // Ensure 0 maps to air
}
console.log(blockMapping);
const paletteSize = blockPalette.length + 1;
const stride = (paletteSize - 1).toString(2).length;
const numBits = stride * bufferSize;
const numLongs = Math.ceil(numBits / 64);
console.log("numLongs", numLongs);
console.log("stride", stride);
return blockMapping;
}
voxelManager.voxels.forEach(voxel => {
const indexVector = Vector3.sub(voxel.position, minPos);
_createBlockBuffer(blockMapping: BlockMapping): Array<BlockID> {
const bufferSize = this._sizeVector.x * this._sizeVector.y * this._sizeVector.z;
console.log(this._sizeVector);
let buffer = Array<BlockID>(bufferSize).fill(0);
this._voxelManager.voxels.forEach(voxel => {
const indexVector = Vector3.sub(voxel.position, this._minPos);
const index = this._getBufferIndex(indexVector);
buffer[index] = blockMapping[voxel.block];
buffer[index] = blockMapping[voxel.block || "air"];
});
let blockStates: [number, number][] = [];
for (let i = 0; i < numLongs; ++i) {
blockStates.push([0, 0]);
}
return buffer;
}
let str = "";
for (let i = 0; i < bufferSize; ++i) {
str = buffer[i].toString(2).padStart(stride, "0") + str;
}
let a = Math.ceil(str.length / 64) * 64;
str = str.padStart(a, "0");
_createBlockStates(blockMapping: BlockMapping) {
const blockEncoding = this._encodeBlockBuffer(blockMapping);
let j = 0;
for (let i = str.length; i > 0; i -= 64) {
let right = parseInt(str.substring(i-32, i), 2);
let left = parseInt(str.substring(i-64, i-32), 2);
if (right > Math.pow(2, 30)) {
right = -((right << 1) >> 1);
let 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);
// TODO: Cleanup, UINT32 -> INT32
if (right > 2147483647) {
//right = -(-right & 0xFFFFFFFF);
right -= 4294967296;
}
if (left > Math.pow(2, 30)) {
left = -((left << 1) >> 1);
if (left > 2147483647) {
//left = -(-left & 0xFFFFFFFF);
left -= 4294967296;
}
blockStates[j] = [left, right];
++j;
}
console.log(blockStates);
let blockStatePalette = Array(paletteSize);
for (const block of blockPalette) {
let index = blockMapping[block];
let blockName = "minecraft:" + block;
blockStates.push([left, right]);
}
return blockStates;
}
_encodeBlockBuffer(blockMapping: BlockMapping) {
let blockBuffer = this._createBlockBuffer(blockMapping);
const paletteSize = Object.keys(blockMapping).length;
let stride = (paletteSize - 1).toString(2).length;
stride = Math.max(2, stride);
let encoding = "";
for (let i = blockBuffer.length - 1; i >= 0; --i) {
encoding += blockBuffer[i].toString(2).padStart(stride, "0");
}
const requiredLength = Math.ceil(encoding.length / 64) * 64;
encoding = encoding.padStart(requiredLength, "0");
return encoding;
}
_createBlockStatePalette(blockMapping: BlockMapping) {
let blockStatePalette = Array(Object.keys(blockMapping).length);
for (const block of Object.keys(blockMapping)) {
const index = blockMapping[block];
const blockName = "minecraft:" + block;
blockStatePalette[index] = { Name: { type: TagType.String, value: blockName } };
}
blockStatePalette[0] = { Name: { type: TagType.String, value: "minecraft:air" } };
this._litematic = {
return blockStatePalette;
}
convertToNBT() {
const bufferSize = this._sizeVector.x * this._sizeVector.y * this._sizeVector.z;
const blockMapping = this._createBlockMapping();
const blockStates = this._createBlockStates(blockMapping);
const blockStatePalette = this._createBlockStatePalette(blockMapping);
const nbt: NBT = {
type: TagType.Compound,
name: 'Litematic',
value: {
@ -164,7 +204,7 @@ export class Litematic {
RegionCount: { type: TagType.Int, value: 1 },
TimeCreated: { type: TagType.Long, value: [0, 0] },
TimeModified: { type: TagType.Long, value: [0, 0] },
TotalBlocks: { type: TagType.Int, value: voxelManager.voxels.length },
TotalBlocks: { type: TagType.Int, value: this._voxelManager.voxels.length },
TotalVolume: { type: TagType.Int, value: bufferSize },
},
},
@ -200,21 +240,8 @@ export class Litematic {
Version: { type: TagType.Int, value: 5 }
}
};
}
exportSchematic(filePath: string) {
const outBuffer = fs.createWriteStream(filePath);
const newBuffer = writeUncompressed(this._litematic, "big");
zlib.gzip(newBuffer, (err, buffer) => {
if (!err) {
outBuffer.write(buffer);
outBuffer.end(() => console.log('Written!'));
}
else {
throw err;
}
});
return nbt;
}
}

18
src/test.js Normal file
View File

@ -0,0 +1,18 @@
let val = 2147483649;
function fa(val) {
if (val > 2147483647) {
return -(-val & 0xFFFFFFFF);
}
return val;
}
function fb(val) {
if (val > 2147483647) {
return val - 4294967296;
}
return val;
}
console.log(fa(val), fb(val));

View File

@ -9,7 +9,8 @@ import { Mesh, MaterialType } from "./mesh";
interface Block {
position: Vector3;
block: string
colours: Array<RGB>;
block?: string
}
@ -107,6 +108,25 @@ export class VoxelManager {
return this.voxelsHash.contains(pos);
}
assignBlocks() {
this.blockPalette = [];
for (let i = 0; i < this.voxels.length; ++i) {
let averageColour = this.voxels[i].colours.reduce((a, c) => {return {r: a.r + c.r, g: a.g + c.g, b: a.b + c.b}})
let n = this.voxels[i].colours.length;
averageColour.r /= n;
averageColour.g /= n;
averageColour.b /= n;
const block = this.blockAtlas.getBlock(averageColour);
this.voxels[i].block = block.name;
this.voxelTexcoords.push(block.texcoord);
if (!this.blockPalette.includes(block.name)) {
this.blockPalette.push(block.name);
}
}
}
addVoxel(vec: Vector3, block: BlockInfo) {
// (0.5, 0.5, 0.5) -> (0, 0, 0);
@ -124,15 +144,25 @@ export class VoxelManager {
// Convert to
const pos = this._toGridPosition(vec);
if (this.voxelsHash.contains(pos)) {
return;
for (let i = 0; i < this.voxels.length; ++i) {
if (this.voxels[i].position.equals(pos)) {
this.voxels[i].colours.push(block.colour);
//console.log("Overlap");
return;
}
}
} else {
this.voxels.push({position: pos, colours: [block.colour]});
//this.voxelTexcoords.push(block.texcoord);
this.voxelsHash.add(pos);
}
/*
if (!this.blockPalette.includes(block.name)) {
this.blockPalette.push(block.name);
}
this.voxels.push({position: pos, block: block.name});
this.voxelTexcoords.push(block.texcoord);
this.voxelsHash.add(pos);
*/
this.minX = Math.min(this.minX, pos.x);
this.minY = Math.min(this.minY, pos.y);
@ -356,9 +386,9 @@ export class VoxelManager {
} else {
// We've reached the voxel level, stop
const voxelColour = this._getVoxelColour(triangle, aabb.centre);
const blockTexcoord = this.blockAtlas.getBlock(voxelColour);
const block = this.blockAtlas.getBlock(voxelColour);
this.addVoxel(aabb.centre, blockTexcoord);
this.addVoxel(aabb.centre, block);
triangleAABBs.push(aabb);
}
}
@ -383,6 +413,7 @@ export class VoxelManager {
this.voxeliseTriangle(triangle);
}
}
this.assignBlocks();
console.log(this.blockPalette);
}