wip compile blockstates
This commit is contained in:
33
index.html
33
index.html
@@ -2,9 +2,40 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Title</title>
|
<title>Artisan Renderer</title>
|
||||||
|
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="color-scheme" content="dark light">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="./style.css">
|
||||||
|
<link rel="stylesheet" href="./src/minerama.css">
|
||||||
|
<link rel="shortcut icon" href="https://minecraft.net/favicon.ico" type="image/x-icon">
|
||||||
|
<script type="module" src="./src/minerama.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<h1>hello</h1>
|
||||||
|
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Assumenda at dolore eaque eos est
|
||||||
|
inventore magnam molestias officia, possimus quae qui quidem similique tenetur unde ut
|
||||||
|
voluptas, voluptates. Fuga, recusandae!</p>
|
||||||
|
|
||||||
|
<mc-diorama>
|
||||||
|
<script type="text/mc-world">
|
||||||
|
p stone_bricks
|
||||||
|
p stone
|
||||||
|
p deepslate
|
||||||
|
p stone_brick_stairs
|
||||||
|
p stone_brick_wall
|
||||||
|
</script>
|
||||||
|
</mc-diorama>
|
||||||
|
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis facilis hic id modi odit
|
||||||
|
officia. Accusamus asperiores eaque explicabo inventore ipsam nesciunt non numquam
|
||||||
|
perferendis, quia reprehenderit temporibus veritatis voluptatem.</p>
|
||||||
|
</main>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
19
mise.toml
19
mise.toml
@@ -4,21 +4,6 @@ node = "latest"
|
|||||||
tinymist = "0.15.0"
|
tinymist = "0.15.0"
|
||||||
typst = "0.15.0"
|
typst = "0.15.0"
|
||||||
|
|
||||||
[tasks.build]
|
|
||||||
run = [
|
|
||||||
"rm .typ-bundle/*",
|
|
||||||
"typst compile main.typ .typ-bundle --format bundle --features bundle,html",
|
|
||||||
"vite build",
|
|
||||||
]
|
|
||||||
sources = ["!dist", "!node_modules", "!.idea", "**/*.typ", "src/**/*"]
|
|
||||||
|
|
||||||
[tasks.dev-vite]
|
|
||||||
run = "vite dev"
|
|
||||||
sources = ["!dist", "!node_modules", "!.idea", "**/*.typ", "src/**/*"]
|
|
||||||
|
|
||||||
[tasks.dev-typ]
|
|
||||||
run = "typst watch main.typ .typ-bundle --format bundle --features bundle,html --no-serve"
|
|
||||||
sources = ["!dist", "!node_modules", "!.idea", "**/*.typ", "src/**/*"]
|
|
||||||
|
|
||||||
[tasks.dev]
|
[tasks.dev]
|
||||||
depends = ["dev-vite", "dev-typ"]
|
run = "vite dev"
|
||||||
|
sources = ["!dist", "!devel", "!node_modules", "!.idea", "**/*.typ", "src/**/*"]
|
||||||
45
src/beautify.esm.js
Normal file
45
src/beautify.esm.js
Normal file
File diff suppressed because one or more lines are too long
0
src/minerama.css
Normal file
0
src/minerama.css
Normal file
114
src/minerama.js
Normal file
114
src/minerama.js
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
export class Renderer {
|
||||||
|
constructor() {
|
||||||
|
this.canvas = document.createElement('canvas');
|
||||||
|
this.canvas.style.display = 'none';
|
||||||
|
document.body.appendChild(this.canvas);
|
||||||
|
this.gl = this.canvas.getContext('webgl2', {antialias: false, alpha: true})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderVariantCondition(key) {
|
||||||
|
if (key) {
|
||||||
|
return key.split(',').map(
|
||||||
|
it => it.split("=")
|
||||||
|
).map(
|
||||||
|
([n, v]) => `state[${JSON.stringify(n)}] === ${JSON.stringify(v)}`
|
||||||
|
).join(" && ")
|
||||||
|
} else {
|
||||||
|
return 'true';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderApply(data) {
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
const parts = [];
|
||||||
|
|
||||||
|
let total = 0.0;
|
||||||
|
for (const {weight = 1.0} of data) total += weight;
|
||||||
|
|
||||||
|
let accum = 0.0;
|
||||||
|
for (const elem of data) {
|
||||||
|
const {weight = 1.0} = elem;
|
||||||
|
accum += weight;
|
||||||
|
|
||||||
|
if (accum === total) {
|
||||||
|
parts.push(JSON.stringify(elem));
|
||||||
|
} else {
|
||||||
|
parts.push(`(hash % ${total}) < ${accum} ? ${JSON.stringify(elem)} : `)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parts.join('');
|
||||||
|
} else {
|
||||||
|
return JSON.stringify(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} data
|
||||||
|
* @returns {String}
|
||||||
|
*/
|
||||||
|
function renderBlockstateResolver(data) {
|
||||||
|
const {variants, multipart} = data;
|
||||||
|
|
||||||
|
if (variants) {
|
||||||
|
if (Object.keys(variants).length === 1 && variants[""]) {
|
||||||
|
return `return ${(renderApply(variants[""]))};`;
|
||||||
|
} else {
|
||||||
|
let cases = [];
|
||||||
|
for (const [key, defn] of Object.entries(variants)) {
|
||||||
|
cases.push(`if (${(renderVariantCondition(key))}) return ${(renderApply(defn))};`)
|
||||||
|
}
|
||||||
|
cases.push(`return {"model": ":missing"};`)
|
||||||
|
return cases.join('else ')
|
||||||
|
}
|
||||||
|
} else if (multipart) {
|
||||||
|
return 'console.warn("NOT IMPLEMENTED")'
|
||||||
|
} else {
|
||||||
|
console.warn('invalid blockstate', data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} src
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async function parse(src) {
|
||||||
|
const lines = src.replace(/#.*?(?:\n|$)/, '\n').trim().split(/(?:\n[ \t]*)+/);
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
const args = line.split(/[ \t]+/);
|
||||||
|
const cmd = args[0].toLowerCase();
|
||||||
|
|
||||||
|
if (cmd === 'p') {
|
||||||
|
const block = args[1];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(`assets/minecraft/blockstates/${block}.json`);
|
||||||
|
let data = await res.json();
|
||||||
|
let resolver_src = renderBlockstateResolver(data);
|
||||||
|
// console.log(beautify.js(`${block} = (state, hash) => {${resolver_src}}`))
|
||||||
|
|
||||||
|
let resolver = new Function("state", "hash", resolver_src);
|
||||||
|
console.log(resolver)
|
||||||
|
|
||||||
|
} catch (ex) {
|
||||||
|
console.warn(`Fetch for ${block} failed:`, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MCDioramaElement extends HTMLElement {
|
||||||
|
connectedCallback() {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
this.appendChild(canvas);
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const script = this.querySelector('script[type="text/mc-world"]');
|
||||||
|
parse(script.textContent);
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('mc-diorama', MCDioramaElement);
|
||||||
Reference in New Issue
Block a user