Skip to content

Commit

Permalink
shapes
Browse files Browse the repository at this point in the history
  • Loading branch information
ewanhowell5195 committed Oct 29, 2024
1 parent 2c50b69 commit 6a66bf2
Show file tree
Hide file tree
Showing 23 changed files with 202 additions and 103 deletions.
249 changes: 146 additions & 103 deletions scripts/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const charMap = {
start: "┫"
}

console.log("Processing fonts...")

const fonts = JSON.parse(fs.readFileSync("../fonts.json"))

const ten = fonts.find(e => e.id === "minecraft-ten")
Expand Down Expand Up @@ -64,9 +66,9 @@ for (const font of fonts) {

fs.writeFileSync(`../fonts/${font.id}/textures.json`, JSON.stringify(JSON.parse(fs.readFileSync(`../fonts/${font.id}/textures.json`)), null, 2) + "\n")

fs.mkdirSync(`temp/${font.id}/textures`, { recursive: true })
fs.mkdirSync(`temp/${font.id}/overlays`, { recursive: true })
fs.mkdirSync(`temp/${font.id}/thumbnails`, { recursive: true })
fs.mkdirSync(`temp/fonts/${font.id}/textures`, { recursive: true })
fs.mkdirSync(`temp/fonts/${font.id}/overlays`, { recursive: true })
fs.mkdirSync(`temp/fonts/${font.id}/thumbnails`, { recursive: true })

const textures = fs.readdirSync(`../fonts/${font.id}/textures`).map(e => ["textures", e]).concat(fs.readdirSync(`../fonts/${font.id}/overlays`).map(e => ["overlays", e]))

Expand All @@ -84,7 +86,7 @@ for (const font of fonts) {
if (!file[1].endsWith(".png") || file[1] === "overlay.png") continue

const texture = await loadTexture(file[0] ? `../fonts/${font.id}/${file[0]}/${file[1]}` : file[2])
if (file[0]) texture.image.saveAs(`temp/${font.id}/${file[0]}/${file[1]}`)
if (file[0]) texture.image.saveAs(`temp/fonts/${font.id}/${file[0]}/${file[1]}`)

const scaleFactor = texture.image.width / 1000
const [scene, camera] = makeTitleScene(scaleFactor)
Expand All @@ -102,7 +104,7 @@ for (const font of fonts) {
else text = `┫${text}┣`
}

await addTitleText(scene, text, {
addTitleText(scene, text, {
font: font.id,
texture
})
Expand Down Expand Up @@ -132,14 +134,54 @@ for (const font of fonts) {
canvas = bordered
}

canvas.saveAs(`temp/${font.id}/thumbnails/${file[1]}`)
canvas.saveAs(`temp/fonts/${font.id}/thumbnails/${file[1]}`)
console.log(`Done ${font.id} ${file[1]}`)
}
}

console.log("Processed fonts")
console.log("Processing shapes...")

const shapes = {}

const shapesList = JSON.parse(fs.readFileSync("../shapes.json"))

for (const [id, shape] of Object.entries(shapesList)) {
shapes[id] = JSON.parse(fs.readFileSync(`../shapes/${id}/model.json`)).elements
for (const element of shapes[id]) {
for (const [direction, face] of Object.entries(element.faces)) {
if (face.rotation === 180) face.uv = [face.uv.slice(2), face.uv.slice(0, 2)].flat()
element.faces[direction] = face.uv
}
}

fs.mkdirSync(`temp/shapes/${id}/textures`, { recursive: true })
fs.mkdirSync(`temp/shapes/${id}/thumbnails`, { recursive: true })

const textures = Object.entries(JSON.parse(fs.readFileSync(`../shapes/${id}/textures.json`))).flatMap(([id, data]) => [id, ...(data.variants ? Object.keys(data.variants) : [])])

for (const name of textures) {
const texture = await loadTexture(`../shapes/${id}/textures/${name}.png`)
texture.image.saveAs(`temp/shapes/${id}/textures/${name}.png`)

const scaleFactor = texture.image.width / shape.width
const [scene, camera] = makeTitleScene(scaleFactor)

addShape(scene, shapes[id], texture)

let canvas = await renderTitleScene(scene, camera, scaleFactor)

canvas.saveAs(`temp/shapes/${id}/thumbnails/${name}.png`)
console.log(`Done ${id} ${name}.png`)
}
}

fs.writeFileSync("../shapes/shapes.json", JSON.stringify(shapes))

console.log("Processed shapes")
console.log("Compressing textures...")

compress_images("temp/**/*.png", "../fonts/", {
compress_images("temp/**/*.png", "../", {
statistic: false,
autoupdate: true,
compress_force: true,
Expand Down Expand Up @@ -183,7 +225,81 @@ function makeTitleScene(scaleFactor) {
return [scene, camera]
}

async function addTitleText(scene, str, args) {
function addModel(scene, model, group, material, cubes, i, font, width, args) {
let min = Infinity
let max = -Infinity
const character = new THREE.Group()
for (let cube of model) {
if (!cube.parsed) {
cube.parsed = true
for (const [direction, uv] of Object.entries(cube.faces)) {
cube.faces[direction] = { uv }
}
}

cube = JSON.parse(JSON.stringify(cube))
min = Math.min(min, cube.from[0], cube.to[0])
max = Math.max(max, cube.from[0], cube.to[0])

if (args.type === "bottom") {
if (cube.to[2] > cube.from[2]) {
cube.to[2] += 20
} else {
cube.from[2] += 20
}
}

const geometry = new THREE.BoxGeometry(cube.to[0] - cube.from[0], cube.to[1] - cube.from[1], cube.to[2] - cube.from[2])
const mesh = new THREE.Mesh(geometry, material)

mesh.position.fromArray([
(cube.from[0] + cube.to[0]) / 2,
(cube.from[1] + cube.to[1]) / 2,
(cube.from[2] + cube.to[2]) / 2
])

const indexes = {
north: 40,
east: 0,
south: 32,
west: 8,
up: 16,
down: 24
}

for (const key of Object.keys(indexes)) {
const face = cube.faces[key]
const i = indexes[key]
if (face) {
const uv = [
[face.uv[0] / 16, 1 - (face.uv[1] / 16)],
[face.uv[2] / 16, 1 - (face.uv[1] / 16)],
[face.uv[0] / 16, 1 - (face.uv[3] / 16)],
[face.uv[2] / 16, 1 - (face.uv[3] / 16)]
]
mesh.geometry.attributes.uv.array.set(uv[0], i + 0)
mesh.geometry.attributes.uv.array.set(uv[1], i + 2)
mesh.geometry.attributes.uv.array.set(uv[2], i + 4)
mesh.geometry.attributes.uv.array.set(uv[3], i + 6)
} else {
mesh.geometry.attributes.uv.array.set([1, 1], i + 0)
mesh.geometry.attributes.uv.array.set([1, 1], i + 2)
mesh.geometry.attributes.uv.array.set([1, 1], i + 4)
mesh.geometry.attributes.uv.array.set([1, 1], i + 6)
}
}
character.add(mesh)
cubes.push(mesh)
}
if (i) max += font.characterSpacing ?? 0
for (const cube of character.children) {
cube.position.x -= width + max
}
group.add(character)
return max - min
}

function addTitleText(scene, str, args) {
const font = fonts.find(e => e.id === args.font)

args.texture.colorSpace = THREE.SRGBColorSpace
Expand All @@ -206,110 +322,37 @@ async function addTitleText(scene, str, args) {
continue
}
if (!font.characters[char]) continue
let min = Infinity
let max = -Infinity
const character = new THREE.Group()
for (let cube of font.characters[char]) {
if (!cube.parsed) {
cube.parsed = true
for (const [direction, uv] of Object.entries(cube.faces)) {
cube.faces[direction] = { uv }
}
}

cube = JSON.parse(JSON.stringify(cube))
min = Math.min(min, cube.from[0], cube.to[0])
max = Math.max(max, cube.from[0], cube.to[0])

if (args.type === "bottom") {
if (cube.to[2] > cube.from[2]) {
cube.to[2] += 20
} else {
cube.from[2] += 20
}
}

const geometry = new THREE.BoxGeometry(cube.to[0] - cube.from[0], cube.to[1] - cube.from[1], cube.to[2] - cube.from[2])
const mesh = new THREE.Mesh(geometry, material)

mesh.position.fromArray([
(cube.from[0] + cube.to[0]) / 2,
(cube.from[1] + cube.to[1]) / 2,
(cube.from[2] + cube.to[2]) / 2
])

const indexes = {
north: 40,
east: 0,
south: 32,
west: 8,
up: 16,
down: 24
}

for (const key of Object.keys(indexes)) {
const face = cube.faces[key]
const i = indexes[key]
if (face) {
const uv = [
[face.uv[0] / 16, 1 - (face.uv[1] / 16)],
[face.uv[2] / 16, 1 - (face.uv[1] / 16)],
[face.uv[0] / 16, 1 - (face.uv[3] / 16)],
[face.uv[2] / 16, 1 - (face.uv[3] / 16)]
]
mesh.geometry.attributes.uv.array.set(uv[0], i + 0)
mesh.geometry.attributes.uv.array.set(uv[1], i + 2)
mesh.geometry.attributes.uv.array.set(uv[2], i + 4)
mesh.geometry.attributes.uv.array.set(uv[3], i + 6)
} else {
mesh.geometry.attributes.uv.array.set([1, 1], i + 0)
mesh.geometry.attributes.uv.array.set([1, 1], i + 2)
mesh.geometry.attributes.uv.array.set([1, 1], i + 4)
mesh.geometry.attributes.uv.array.set([1, 1], i + 6)
}
}
character.add(mesh)
cubes.push(mesh)
}
if (i) max += font.characterSpacing ?? 0
for (const cube of character.children) {
cube.position.x -= width + max
}
group.add(character)
width += max - min
const model = font.characters[char]
width += addModel(scene, model, group, material, cubes, i, font, width, args)
}

for (const cube of cubes) {
cube.position.x += width / 2
}

if (args.row) {
group.position.y += font.height * args.row
}
scene.add(group)
}

if (args.type === "bottom") {
group.scale.setX(0.75)
group.scale.setY(1.6)
group.scale.setZ(0.75)
group.rotation.fromArray([torad(-90), 0, 0])
group.position.z += font.height + 49
group.position.y -= 25 - font.depth
} else if (args.type === "small") {
group.scale.setX(0.35)
group.scale.setY(0.35)
group.scale.setZ(0.35)
group.position.y -= font.height * 0.35
}
function addShape(scene, model, texture) {
texture.colorSpace = THREE.SRGBColorSpace
texture.magFilter = THREE.NearestFilter
texture.minFilter = THREE.NearestFilter
texture.flipY = true

if (args.scale) {
group.scale.setX(group.scale.x * args.scale[0])
group.scale.setY(group.scale.y * args.scale[1])
group.scale.setZ(group.scale.z * args.scale[2])
}
const material = new THREE.MeshBasicMaterial({
map: texture,
transparent: true,
alphaTest: 0.01
})

if (args.rotation) {
const old = group.rotation.toArray()
group.rotation.fromArray(args.rotation.map((e, i) => torad(e) + old[i]))
let width = 0
const cubes = []
const group = new THREE.Group()

width += addModel(scene, model, group, material, cubes, 0, {}, width, {})

for (const cube of cubes) {
cube.position.x += width / 2
}

scene.add(group)
Expand Down
5 changes: 5 additions & 0 deletions shapes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"minecraft-ten-blank": {
"width": 28
}
}
32 changes: 32 additions & 0 deletions shapes/minecraft-ten-blank/model.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"credit": "By Ewan Howell",
"texture_size": [28, 86],
"textures": {
"1": "minecraft_ten_blank:flat",
"particle": "minecraft_ten_blank:flat"
},
"elements": [
{
"from": [-6, 2, -3],
"to": [22, 42, 19],
"faces": {
"north": {"uv": [0, 4.09302, 16, 11.53488], "texture": "#1"},
"south": {"uv": [16, 4.09302, 0, 11.53488], "texture": "#1"},
"up": {"uv": [16, 4.09302, 0, 0], "texture": "#1"},
"down": {"uv": [16, 15.62791, 0, 11.53488], "texture": "#1"}
}
},
{
"from": [24, 44, 21],
"to": [-8, 0, -5],
"faces": {
"north": {"uv": [0, 15.81395, 0.57143, 16], "texture": "#1"},
"east": {"uv": [0, 15.81395, 0.57143, 16], "texture": "#1"},
"south": {"uv": [0, 15.81395, 0.57143, 16], "texture": "#1"},
"west": {"uv": [0, 15.81395, 0.57143, 16], "texture": "#1"},
"up": {"uv": [0, 15.81395, 0.57143, 16], "texture": "#1"},
"down": {"uv": [0, 15.81395, 0.57143, 16], "texture": "#1"}
}
}
]
}
18 changes: 18 additions & 0 deletions shapes/minecraft-ten-blank/textures.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"flat": {
"author": "Ewan Howell"
},
"creeper": {
"category": "Heads",
"author": "BitseK",
"variants": {
"creaking": {},
"enderman": {},
"glow_squid": {},
"villager": {},
"vindicator": {},
"witch": {},
"zombie_villager": {}
}
}
}
Binary file added shapes/minecraft-ten-blank/textures/creaking.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/textures/creeper.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/textures/enderman.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/textures/flat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/textures/glow_squid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/textures/villager.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/textures/vindicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/textures/witch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/thumbnails/creaking.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/thumbnails/creeper.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/thumbnails/enderman.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/thumbnails/flat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/thumbnails/glow_squid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/thumbnails/villager.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/thumbnails/vindicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shapes/minecraft-ten-blank/thumbnails/witch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions shapes/shapes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"minecraft-ten-blank":[{"from":[-6,2,-3],"to":[22,42,19],"faces":{"north":{"uv":[0,4.09302,16,11.53488]},"south":{"uv":[16,4.09302,0,11.53488]},"up":{"uv":[16,4.09302,0,0]},"down":{"uv":[16,15.62791,0,11.53488]}},"parsed":true},{"from":[24,44,21],"to":[-8,0,-5],"faces":{"north":{"uv":[0,15.81395,0.57143,16]},"east":{"uv":[0,15.81395,0.57143,16]},"south":{"uv":[0,15.81395,0.57143,16]},"west":{"uv":[0,15.81395,0.57143,16]},"up":{"uv":[0,15.81395,0.57143,16]},"down":{"uv":[0,15.81395,0.57143,16]}},"parsed":true}]}

0 comments on commit 6a66bf2

Please sign in to comment.