Skip to content

Commit

Permalink
Merge pull request #3 from LucasDower/schematic
Browse files Browse the repository at this point in the history
Schematic exporting
  • Loading branch information
LucasDower authored Jul 6, 2021
2 parents 760e222 + 1d16c2e commit 24aaa00
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 37 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ A tool to convert .obj files into Minecraft Schematics

![MeshingPreview](/resources/greedy_meshing.png)

![MinecraftPreview](/resources/minecraft.png)

# Progress
0.1
* ✔️ **.json model loading**
Expand All @@ -18,7 +20,7 @@ A tool to convert .obj files into Minecraft Schematics

0.2
* ✔️ **Greedy voxel meshing**
* Export to schematic
* ✔️ **Export to schematic**

0.3
* Building guides
Expand Down
43 changes: 31 additions & 12 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,37 @@
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>

<body>
<nav id="nav" class="navbar navbar-dark bg-dark">
<div class="input-group w-25 mx-auto">
<input type="file" class="form-control" id="objFile" aria-describedby="inputGroupFileAddon04" aria-label="Upload">
<button id="objBtn" class="btn btn-primary" type="button" id="inputGroupFileAddon04">Load</button>
</div>
<div class="input-group w-25 mx-auto">
<label class="input-group-text" for="inputGroupFileAddon03">Voxel size</label>
<input type="number" min="0.1" step="0.1" value="0.1" class="form-control" id="voxelInput" aria-describedby="inputGroupFileAddon03" aria-label="Voxel size" disabled>
<button id="voxelBtn" class="btn btn-primary" type="button" id="inputGroupFileAddon03" disabled>Voxelise</button>
</div>
</nav>
<body id="bootstrap-overrides">

<div class="container bg-dark">
<div class="row mb-2 mt-2">
<!-- LEFT -->
<div class="col">
<div class="input-group">
<input type="file" class="form-control" id="objFile" aria-describedby="inputGroupFileAddon04" aria-label="Upload">
<button id="objBtn" class="btn btn-primary" type="button" id="inputGroupFileAddon04">Load</button>
</div>
</div>

<!-- MIDDLE -->
<div class="col">
<div class="input-group">
<label class="input-group-text" for="inputGroupFileAddon03">Voxel size</label>
<input type="number" min="0.1" step="0.1" value="0.1" class="form-control" id="voxelInput" aria-describedby="inputGroupFileAddon03" aria-label="Voxel size" disabled>
<button id="voxelBtn" class="btn btn-primary" type="button" disabled>Voxelise</button>
</div>
</div>

<!-- RIGHT -->
<div class="col">
<div class="d-grid gap-2">
<button id="exportBtn" class="btn btn-danger" type="button" disabled>Export schematic</button>
</div>
</div>
</div>
</div>

<!-- CANVAS -->
<canvas id="c"></canvas>
</body>

Expand Down
1 change: 1 addition & 0 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function createWindow () {
mainWindow = new BrowserWindow({width, height, webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true
}});

// Load index.html
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "objtoschematic",
"version": "0.1.0",
"version": "0.2.0",
"description": "A tool to convert .obj files into voxels and then into Minecraft Schematic files",
"main": "main.js",
"engines": {"node": ">=14.0.0"},
"scripts": {
"start": "electron .",
"build": "electron-packager . ObjToSchematic --platform=win32 --arch=x64"
Expand All @@ -22,6 +23,7 @@
"electron-packager": "^15.2.0",
"expand-vertex-data": "^1.1.2",
"load-wavefront-obj": "^0.8.0",
"prismarine-nbt": "^1.6.0",
"twgl.js": "^4.19.1",
"wavefront-obj-parser": "^2.0.1"
},
Expand Down
Binary file added resources/minecraft.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 0 additions & 10 deletions resources/sub_tri.mtl

This file was deleted.

45 changes: 33 additions & 12 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,22 @@ const { Renderer } = require('./src/renderer.js');
const { Mesh } = require('./src/mesh.js');
const { VoxelManager } = require('./src/voxel_manager.js');
const { Vector3 } = require('./src/vector.js');
const { Schematic } = require('./src/schematic.js');

//const voxelSize = document.querySelector("#voxelInput").value;
const voxelSize = 0.025;
const dialog = require('electron').remote.dialog;

const voxelSize = document.querySelector("#voxelInput").value;
let renderer = new Renderer(voxelSize);
const voxelManager = new VoxelManager(voxelSize);

const nav = document.querySelector("#nav");
let canvas = document.querySelector("#c");
const canvas = document.querySelector("#c");

const showMeshing = false;
const showFailedAABBs = true;
const showFailedAABBs = false;

function resizeCanvas() {
canvas.height = window.innerHeight - 54;
canvas.width = window.innerWidth;
}

resizeCanvas();
let loadedMesh = null;

// CHOOSE FILE
document.querySelector("#objBtn").addEventListener('click', () => {
const files = document.querySelector("#objFile").files;

Expand All @@ -41,6 +37,7 @@ document.querySelector("#objBtn").addEventListener('click', () => {
});


// VOXELISE BUTTON
document.querySelector("#voxelBtn").addEventListener('click', () => {
const voxelSize = document.querySelector("#voxelInput").value;

Expand Down Expand Up @@ -72,12 +69,36 @@ document.querySelector("#voxelBtn").addEventListener('click', () => {
renderer.registerBox(box.centre, box.size, true);
}
}

document.querySelector("#exportBtn").disabled = false;

renderer.compileRegister();
});


// EXPORT SCHEMATIC
document.querySelector("#exportBtn").addEventListener('click', async function() {

const {filePath} = await dialog.showSaveDialog({
title: "Save schematic",
buttonLabel: "Save",
filters: [{
name: 'Schematic',
extensions: ['schematic']
}]
});

const schematic = new Schematic(voxelManager);
schematic.exportSchematic(filePath);
});

//const suzanne = new Mesh('./resources/suzanne.obj');
//voxelManager.voxeliseMesh(suzanne);
//const schematic = new Schematic(voxelManager);

function render(time) {
resizeCanvas();
canvas.height = window.innerHeight - 54;
canvas.width = window.innerWidth;

renderer.begin();
renderer.end();
Expand Down
62 changes: 62 additions & 0 deletions src/schematic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const zlib = require("zlib");
const fs = require('fs');
const { parse, writeUncompressed } = require('prismarine-nbt');
const { Vector3 } = require('./vector.js');
const dialog = require('electron').remote.dialog;

class Schematic {

_getBufferIndex(vec) {
return (this.sizeVector.z * this.sizeVector.x * vec.y) + (this.sizeVector.x * vec.z) + vec.x;
}

constructor(voxelManager) {
const minPos = voxelManager._voxelCentreToPosition(new Vector3(voxelManager.minX, voxelManager.minY, voxelManager.minZ));
const maxPos = voxelManager._voxelCentreToPosition(new Vector3(voxelManager.maxX, voxelManager.maxY, voxelManager.maxZ));

this.sizeVector = Vector3.addScalar(Vector3.sub(maxPos, minPos), 1);
const bufferSize = this.sizeVector.x * this.sizeVector.y * this.sizeVector.z;

this.schematic = {
type: 'compound',
name: 'Schematic',
value: {
Width: { type: 'short', value: this.sizeVector.x },
Height: { type: 'short', value: this.sizeVector.y },
Length: { type: 'short', value: this.sizeVector.z },
Materials: { type: 'string', value: 'Alpha' },
Blocks: { type: 'byteArray', value: new Array(bufferSize) },
Data: { type: 'byteArray', value: new Array(bufferSize).fill(0) },
Entities: { type: 'list', value: {type: "int", value: Array(0)} },
TileEntities: { type: 'list', value: {type: "int", value: Array(0)} }
}
};

for (let i = 0; i < voxelManager.voxels.length; ++i) {
const voxel = voxelManager.voxels[i];
const pos = voxelManager._voxelCentreToPosition(voxel);

const indexVector = Vector3.sub(pos, minPos);
const index = this._getBufferIndex(indexVector);
this.schematic.value.Blocks.value[index] = 1;
}
}

exportSchematic(filePath) {
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 {
console.log(err);
}
});
}

}

module.exports.Schematic = Schematic;
6 changes: 5 additions & 1 deletion styles.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
body {
margin: 0;
font-family: monospace;
background-color: red;
}


canvas {
display: block;
width: 100;
Expand All @@ -29,4 +29,8 @@ div.hidden {
.rounded-pill-right {
border-top-right-radius: 50rem !important;
border-bottom-right-radius: 50rem !important;
}

#bootstrap-overrides {
background-color: #212529;
}

0 comments on commit 24aaa00

Please sign in to comment.