mirror of
https://github.com/LucasDower/ObjToSchematic.git
synced 2025-04-12 15:00:22 +08:00
Added Sandbox
package for API examples
This commit is contained in:
parent
a7838305ca
commit
06a915d3b7
5
.gitignore
vendored
5
.gitignore
vendored
@ -10,4 +10,7 @@
|
||||
/Editor/node_modules
|
||||
/Editor/.firebase
|
||||
/Editor/.firebaserc
|
||||
/Editor/webpack/
|
||||
/Editor/webpack/
|
||||
|
||||
# Sandbox
|
||||
/Sandbox/node_modules
|
@ -1,71 +0,0 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import { ObjImporter } from "../src/importers/obj_importer";
|
||||
import { OtS_VoxelMesh_Converter } from '../src/ots_voxel_mesh_converter';
|
||||
import { BlockMesh } from '../src/block_mesh';
|
||||
import { PALETTE_ALL_RELEASE } from '../../Editor/res/palettes/all'; // TODO: Disallowed import
|
||||
import { ExporterFactory } from '../src/exporters/exporters';
|
||||
import { ASSERT } from '../src/util/error_util';
|
||||
import { createReadableStream, createOtSTexture } from '../tools/util'; // TODO: Disallowed import
|
||||
|
||||
(async () => {
|
||||
// 1. Import a mesh
|
||||
const pathModel = path.join(__dirname, '../res/samples/skull.obj');
|
||||
const readableStream = createReadableStream(pathModel);
|
||||
|
||||
const loader = new ObjImporter();
|
||||
const mesh = await loader.import(readableStream);
|
||||
|
||||
// 2. Assign materials
|
||||
const pathTexture = path.join(__dirname, '../res/samples/skull.jpg');
|
||||
const texture = createOtSTexture(pathTexture);
|
||||
ASSERT(texture !== undefined, `Could not parse ${pathTexture}`);
|
||||
|
||||
// Update the 'skull' material
|
||||
const success = mesh.setMaterial({
|
||||
type: 'textured',
|
||||
name: 'skull',
|
||||
texture: texture,
|
||||
});
|
||||
ASSERT(success, 'Could not update skull material');
|
||||
|
||||
// 3. Construct a voxel mesh from the mesh
|
||||
const converter = new OtS_VoxelMesh_Converter();
|
||||
converter.setConfig({
|
||||
constraintAxis: 'y',
|
||||
size: 380,
|
||||
multisampling: false,
|
||||
replaceMode: 'keep',
|
||||
});
|
||||
|
||||
const voxelMesh = converter.process(mesh);
|
||||
|
||||
// 4. Construct a block mesh from the block
|
||||
// NOTE: This will be placeholder and will be changed
|
||||
const blockMesh = BlockMesh.createFromVoxelMesh(voxelMesh, {
|
||||
atlasJSON: JSON.parse(fs.readFileSync(path.join(__dirname, '../res/atlases/vanilla.atlas'), 'utf8')),
|
||||
blockPalette: new Set(PALETTE_ALL_RELEASE),
|
||||
calculateLighting: false,
|
||||
contextualAveraging: true,
|
||||
dithering: 'off',
|
||||
ditheringMagnitude: 0,
|
||||
errorWeight: 0.02,
|
||||
resolution: 16,
|
||||
fallable: 'do-nothing',
|
||||
lightThreshold: 0,
|
||||
});
|
||||
|
||||
// 5. Export the block mesh to a file
|
||||
// NOTE: This will be placeholder and will be changed
|
||||
const exporter = ExporterFactory.GetExporter('litematic');
|
||||
const exportData = exporter.export(blockMesh.blockMesh);
|
||||
|
||||
if (exportData.type === 'single') {
|
||||
fs.writeFileSync('export' + exportData.extension, exportData.content);
|
||||
} else {
|
||||
exportData.regions.forEach((region) => {
|
||||
fs.writeFileSync(region.name + exportData.extension, region.content);
|
||||
});
|
||||
}
|
||||
})();
|
@ -1,3 +1,12 @@
|
||||
export function testExport(x: number, y: number) {
|
||||
return x + y;
|
||||
}
|
||||
import { ImporterFactory } from './src/importers/importers';
|
||||
import { OtS_Texture } from './src/ots_texture';
|
||||
import { OtS_VoxelMesh } from './src/ots_voxel_mesh';
|
||||
import { OtS_VoxelMesh_Converter } from './src/ots_voxel_mesh_converter';
|
||||
|
||||
export default {
|
||||
getImporter: ImporterFactory.GetImporter,
|
||||
texture: OtS_Texture,
|
||||
|
||||
voxelMeshConverter: OtS_VoxelMesh_Converter,
|
||||
voxelMesh: OtS_VoxelMesh,
|
||||
};
|
@ -6,7 +6,7 @@ import { ObjImporter } from './obj_importer';
|
||||
export type TImporters = 'obj' | 'gltf';
|
||||
|
||||
|
||||
export class ImporterFactor {
|
||||
export class ImporterFactory {
|
||||
public static GetImporter(importer: TImporters): IImporter {
|
||||
switch (importer) {
|
||||
case 'obj':
|
||||
|
44
Sandbox/index.ts
Normal file
44
Sandbox/index.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { strict as assert } from 'node:assert';
|
||||
import path from 'node:path';
|
||||
import OTS from 'ots-core';
|
||||
|
||||
import { createOtSTexture, createReadableStream } from './src/util';
|
||||
|
||||
(async () => {
|
||||
// 1. Import a mesh
|
||||
const pathModel = path.join(__dirname, '../res/samples/skull.obj');
|
||||
const readableStream = createReadableStream(pathModel);
|
||||
|
||||
const importer = OTS.getImporter('obj');
|
||||
const mesh = await importer.import(readableStream);
|
||||
|
||||
// 2. Assign materials
|
||||
const pathTexture = path.join(__dirname, '../res/samples/skull.jpg');
|
||||
const texture = createOtSTexture(pathTexture);
|
||||
assert(texture !== undefined, `Could not parse ${pathTexture}`);
|
||||
|
||||
// Update the 'skull' material
|
||||
const success = mesh.setMaterial({
|
||||
type: 'textured',
|
||||
name: 'skull',
|
||||
texture: texture,
|
||||
});
|
||||
assert(success, 'Could not update skull material');
|
||||
|
||||
// 3. Construct a voxel mesh from the mesh
|
||||
const converter = new OTS.voxelMeshConverter();
|
||||
converter.setConfig({
|
||||
constraintAxis: 'y',
|
||||
size: 380,
|
||||
multisampling: false,
|
||||
replaceMode: 'keep',
|
||||
});
|
||||
|
||||
const voxelMesh = converter.process(mesh);
|
||||
|
||||
// 4. Construct a block mesh from the block
|
||||
// TODO
|
||||
|
||||
// 5. Export the block mesh to a file
|
||||
// TODO
|
||||
})();
|
79
Sandbox/package-lock.json
generated
Normal file
79
Sandbox/package-lock.json
generated
Normal file
@ -0,0 +1,79 @@
|
||||
{
|
||||
"name": "ots-sandbox",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ots-sandbox",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"jpeg-js": "^0.4.4",
|
||||
"ots-core": "file:../Core",
|
||||
"pngjs": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"../Core": {
|
||||
"name": "ots-core",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@loaders.gl/core": "^3.4.14",
|
||||
"@loaders.gl/gltf": "^3.4.14",
|
||||
"@types/jest": "^29.5.5",
|
||||
"pako": "^2.1.0",
|
||||
"prismarine-nbt": "^2.2.1",
|
||||
"ts-jest": "^29.1.1",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/pako": "^2.0.1",
|
||||
"jest": "^29.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jpeg-js": {
|
||||
"version": "0.4.4",
|
||||
"resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz",
|
||||
"integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="
|
||||
},
|
||||
"node_modules/ots-core": {
|
||||
"resolved": "../Core",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/pngjs": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
|
||||
"integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
|
||||
"engines": {
|
||||
"node": ">=14.19.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"jpeg-js": {
|
||||
"version": "0.4.4",
|
||||
"resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz",
|
||||
"integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="
|
||||
},
|
||||
"ots-core": {
|
||||
"version": "file:../Core",
|
||||
"requires": {
|
||||
"@loaders.gl/core": "^3.4.14",
|
||||
"@loaders.gl/gltf": "^3.4.14",
|
||||
"@types/jest": "^29.5.5",
|
||||
"@types/pako": "^2.0.1",
|
||||
"jest": "^29.7.0",
|
||||
"pako": "^2.1.0",
|
||||
"prismarine-nbt": "^2.2.1",
|
||||
"ts-jest": "^29.1.1",
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
},
|
||||
"pngjs": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
|
||||
"integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="
|
||||
}
|
||||
}
|
||||
}
|
18
Sandbox/package.json
Normal file
18
Sandbox/package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "ots-sandbox",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"jpeg-js": "^0.4.4",
|
||||
"ots-core": "file:../Core",
|
||||
"pngjs": "^7.0.0"
|
||||
}
|
||||
}
|
42
Sandbox/src/util.ts
Normal file
42
Sandbox/src/util.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import OTS from 'ots-core';
|
||||
|
||||
import { PNG } from 'pngjs';
|
||||
import { decode as jpegDecode } from 'jpeg-js';
|
||||
|
||||
export function createReadableStream(p: fs.PathLike) {
|
||||
return new ReadableStream({
|
||||
async start(controller) {
|
||||
const readStream = fs.createReadStream(p);
|
||||
|
||||
readStream.on('data', (chunk) => {
|
||||
controller.enqueue(chunk);
|
||||
});
|
||||
|
||||
readStream.on('end', () => {
|
||||
controller.close();
|
||||
});
|
||||
|
||||
readStream.on('error', (err) => {
|
||||
throw err;
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function createOtSTexture(p: fs.PathLike) {
|
||||
const ext = path.extname(p.toString());
|
||||
switch (ext) {
|
||||
case '.jpg':
|
||||
case '.jpeg': {
|
||||
var jpegData = fs.readFileSync(p);
|
||||
const jpeg = jpegDecode(jpegData, {
|
||||
maxMemoryUsageInMB: undefined,
|
||||
formatAsRGBA: true,
|
||||
});
|
||||
return new OTS.texture(Uint8ClampedArray.from(jpeg.data), jpeg.width, jpeg.width, 'nearest', 'repeat');
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user