ok really im close now
This commit is contained in:
parent
22e9cb094d
commit
89759068e5
16 changed files with 53 additions and 87 deletions
41
hack/build.ts
Normal file
41
hack/build.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
import chalk from "chalk";
|
||||
import { generate } from "./generate";
|
||||
import { globSync } from "glob";
|
||||
import { rmSync, mkdirSync, cpSync } from "node:fs";
|
||||
import { convertMeshes } from "./convert-meshes";
|
||||
import glslPlugin from "./glsl-plugin";
|
||||
|
||||
console.log(chalk.green`>> Cleaing up ./html ...`);
|
||||
rmSync("html", { recursive: true, force: true });
|
||||
mkdirSync("html");
|
||||
|
||||
const works = globSync("src/*/main.ts");
|
||||
|
||||
console.log(chalk.green`>> Building ...`);
|
||||
console.log(chalk.yellow(` Found ${works.length} works.`));
|
||||
|
||||
await Bun.build({
|
||||
entrypoints: works,
|
||||
outdir: "html",
|
||||
splitting: true,
|
||||
loader: {
|
||||
".glsl": "text",
|
||||
".wgsl": "text",
|
||||
},
|
||||
minify: true,
|
||||
plugins: [glslPlugin],
|
||||
});
|
||||
|
||||
console.log(chalk.green`>> Generating HTML and Markdown ...`);
|
||||
await generate(works);
|
||||
|
||||
console.log(chalk.green`>> Copying public files ...`);
|
||||
const publics = globSync("src/public/*");
|
||||
for (const file of publics) {
|
||||
const dest = file.replace("src/public/", "html/");
|
||||
cpSync(file, dest);
|
||||
console.log(chalk.yellow(` -> ${dest}...`));
|
||||
}
|
||||
|
||||
console.log(chalk.green`>> Convert meshes ...`);
|
||||
await convertMeshes();
|
59
hack/convert-meshes.ts
Normal file
59
hack/convert-meshes.ts
Normal file
|
@ -0,0 +1,59 @@
|
|||
import chalk from "chalk";
|
||||
import { globSync } from "glob";
|
||||
|
||||
export const convertMeshes = async () => {
|
||||
const meshes = globSync("src/meshes/*.ply");
|
||||
|
||||
for (const file of meshes) {
|
||||
const ply = await Bun.file(file).text();
|
||||
|
||||
const [header, body] = ply.split("end_header");
|
||||
const colorSize = header.includes("red") ? 4 : 0;
|
||||
|
||||
const values: number[] = [];
|
||||
|
||||
for (const line of body.split("\n")) {
|
||||
// line looks like
|
||||
// x y z r g b a u v
|
||||
// We need to convert it to
|
||||
// x y z 1 r g b a u v
|
||||
|
||||
const [x, y, z, r, g, b, a, u, v] = line.split(" ");
|
||||
|
||||
if (!g) {
|
||||
continue;
|
||||
}
|
||||
|
||||
values.push(
|
||||
parseFloat(x),
|
||||
parseFloat(y),
|
||||
parseFloat(z),
|
||||
1,
|
||||
parseFloat(r),
|
||||
parseFloat(g)
|
||||
);
|
||||
|
||||
if (colorSize > 0) {
|
||||
values.push(parseFloat(b), parseFloat(a), parseFloat(u), parseFloat(v));
|
||||
}
|
||||
}
|
||||
|
||||
const outFile = file.replace(".ply", ".ts");
|
||||
const outString = `
|
||||
import { Mesh } from "../renderer/mesh";
|
||||
|
||||
// prettier-ignore
|
||||
const mesh = new Float32Array(${JSON.stringify(values, null, 2)});
|
||||
|
||||
export default new Mesh({
|
||||
mesh,
|
||||
positionSize: 4 * 4,
|
||||
colorSize: ${colorSize} * 4,
|
||||
uvSize: 2 * 4,
|
||||
});
|
||||
`;
|
||||
|
||||
await Bun.write(outFile, outString);
|
||||
console.log(chalk.yellow(` -> ${file}...`));
|
||||
}
|
||||
};
|
39
hack/generate.ts
Normal file
39
hack/generate.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import indexTemplate from "./templates/index.html.txt";
|
||||
import workTemplate from "./templates/work.html.txt";
|
||||
import readmeTemplate from "./templates/README.md.txt";
|
||||
import chalk from "chalk";
|
||||
import { mkdirSync } from "node:fs";
|
||||
|
||||
export const generate = async (works: string[]) => {
|
||||
const allWorks = works
|
||||
.map((file) => file.replace("src/", "").replace("/main.ts", ""))
|
||||
.sort()
|
||||
.reverse();
|
||||
|
||||
for (const work of allWorks) {
|
||||
const html = `${workTemplate}`.replace(/##name##/g, work);
|
||||
|
||||
mkdirSync(`html/${work}`, { recursive: true });
|
||||
await Bun.write(`html/${work}/index.html`, html);
|
||||
console.log(chalk.yellow(` -> html/${work}/index.html...`));
|
||||
}
|
||||
|
||||
const index = indexTemplate.replace(
|
||||
"<!--/INSERT/-->",
|
||||
allWorks
|
||||
.map((work) => `<li><a href="/${work}">./${work}</a></li>`)
|
||||
.join("\n ")
|
||||
);
|
||||
await Bun.write("html/index.html", index);
|
||||
console.log(chalk.yellow(` -> html/index.html...`));
|
||||
|
||||
const readme = readmeTemplate.replace(
|
||||
"<!--/INSERT/-->",
|
||||
allWorks
|
||||
.reverse()
|
||||
.map((work) => `- [./${work}](https://art.mekanoe.com/${work})`)
|
||||
.join("\n")
|
||||
);
|
||||
await Bun.write("README.md", readme);
|
||||
console.log(chalk.yellow(` -> README.md...`));
|
||||
};
|
5
hack/glsl-plugin.ts
Normal file
5
hack/glsl-plugin.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import glsl from "esbuild-plugin-glsl";
|
||||
|
||||
export default glsl({
|
||||
minify: true,
|
||||
});
|
41
hack/templates/README.md.txt
Normal file
41
hack/templates/README.md.txt
Normal file
|
@ -0,0 +1,41 @@
|
|||
# noeidelon
|
||||
|
||||
Foxes dream of electron beams.
|
||||
|
||||
**noe** + **eidelon** _(n. a thing, an image, a reflection)_
|
||||
|
||||
https://art.mekanoe.com
|
||||
|
||||
## Artworks
|
||||
|
||||
<!--/INSERT/-->
|
||||
|
||||
## Development
|
||||
|
||||
`nix` to install bun... or do it globally.
|
||||
|
||||
`bun run .` to generate HTMLs
|
||||
|
||||
`bun serve` to serve them locally
|
||||
|
||||
`bun dev` if you're developing the templates for auto-generation.
|
||||
|
||||
### Infrastructure
|
||||
|
||||
- The "generator" does
|
||||
|
||||
- Generates a work list from .js files within `html`
|
||||
- Creates this README.md file
|
||||
- Creates the index.html file
|
||||
- Creates individual HTML files for each work
|
||||
|
||||
- The platform supplies
|
||||
- Shader types
|
||||
- Primitive objects
|
||||
- A canvas to draw on
|
||||
- WebGL hooks
|
||||
- Helpers, etc
|
||||
|
||||
## License
|
||||
|
||||
Code and images are licensed under the AGPLv3 license. See [LICENSE](./LICENSE) for more information.
|
37
hack/templates/index.html.txt
Normal file
37
hack/templates/index.html.txt
Normal file
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<title>com.mekanoe.art //</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href="index.css" />
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
font-family: "Atkinson Hyperlegible", sans-serif;
|
||||
background-color: hsl(32, 19%, 14%);
|
||||
color: hsl(39, 75%, 51%);
|
||||
line-height: 1.5;
|
||||
text-shadow: 1px 1px 3px hsl(38, 45%, 22%);
|
||||
}
|
||||
</style>
|
||||
<main>
|
||||
<header>
|
||||
<div>com.mekanoe.art //</div>
|
||||
<div class="subtext">
|
||||
<< noeidelon >>
|
||||
<a href="https://github.com/mekanoe/noeidelon">[github]</a>
|
||||
<a href="https://sapphic.engineer/noe" rel="me">[fedi]</a>
|
||||
<br />a collection of 3D works
|
||||
</div>
|
||||
</header>
|
||||
<section id="works">
|
||||
<ul>
|
||||
<!--/INSERT/-->
|
||||
</ul>
|
||||
</section>
|
||||
</main>
|
31
hack/templates/work.html.txt
Normal file
31
hack/templates/work.html.txt
Normal file
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<title>com.mekanoe.art // ##name##</title>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
main {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/work.css" />
|
||||
<main>
|
||||
<canvas id="canvas" width="1280" height="720"></canvas>
|
||||
<div id="telemetry">XX.X FPS (XX.X ms)</div>
|
||||
</main>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/3.4.2/gl-matrix-min.min.js"
|
||||
integrity="sha512-cR3oS5mKRWD+38vYi1CNJk1DLpi104ovuQBuVv9p7nNxeqzSNiHzlboK2BZQybmpTi1QNnQ5unYajpURcMjeZQ=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script src="/##name##/main.js" type="module"></script>
|
Loading…
Add table
Add a link
Reference in a new issue