Compare commits
3 commits
next
...
decorated-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
116102a776 | ||
|
|
eb76f53280 | ||
|
|
0a932b5d35 |
4 changed files with 119 additions and 11 deletions
|
|
@ -35,7 +35,7 @@ export type JsonAtlas = {
|
|||
}
|
||||
}
|
||||
|
||||
export const makeTextureAtlas = (input: string[], getInputData: (name) => { contents: string, tileWidthMult?: number }, tilesCount = input.length, suSvOptimize: 'remove' | null = null): {
|
||||
export const makeTextureAtlas = (input: string[], getInputData: (name) => { contents: string, tileWidthMult?: number, origSizeTextures?}, tilesCount = input.length, suSvOptimize: 'remove' | null = null): {
|
||||
image: Buffer,
|
||||
canvas: Canvas,
|
||||
json: JsonAtlas
|
||||
|
|
@ -49,6 +49,7 @@ export const makeTextureAtlas = (input: string[], getInputData: (name) => { cont
|
|||
|
||||
const texturesIndex = {}
|
||||
|
||||
let skipXY = [] as [x: number, y: number][]
|
||||
let offset = 0
|
||||
const suSv = tileSize / imgSize
|
||||
for (const i in input) {
|
||||
|
|
@ -56,20 +57,44 @@ export const makeTextureAtlas = (input: string[], getInputData: (name) => { cont
|
|||
const x = (pos % texSize) * tileSize
|
||||
const y = Math.floor(pos / texSize) * tileSize
|
||||
|
||||
if (skipXY.some(([sx, sy]) => sx === x + 1 && sy === y)) {
|
||||
// todo more offsets
|
||||
offset++
|
||||
}
|
||||
|
||||
const img = new Image()
|
||||
const keyValue = input[i];
|
||||
const inputData = getInputData(keyValue);
|
||||
const keyValue = input[i]
|
||||
const inputData = getInputData(keyValue)
|
||||
img.src = inputData.contents
|
||||
const renderWidth = tileSize * (inputData.tileWidthMult ?? 1)
|
||||
g.drawImage(img, 0, 0, renderWidth, tileSize, x, y, renderWidth, tileSize)
|
||||
let su = suSv
|
||||
let sv = suSv
|
||||
let renderWidth = tileSize * (inputData.tileWidthMult ?? 1)
|
||||
let renderHeight = tileSize
|
||||
if (inputData.origSizeTextures?.[keyValue]) {
|
||||
// todo check have enough space
|
||||
renderWidth = Math.ceil(img.width / tileSize) * tileSize
|
||||
renderHeight = Math.ceil(img.height / tileSize) * tileSize
|
||||
su = renderWidth / imgSize
|
||||
sv = renderHeight / imgSize
|
||||
if (renderWidth > tileSize) {
|
||||
offset += Math.ceil(renderWidth / tileSize) - 1
|
||||
}
|
||||
if (renderHeight > tileSize) {
|
||||
const skipYs = Math.ceil(renderHeight / tileSize) - 1
|
||||
for (let i = 1; i <= skipYs; i++) {
|
||||
skipXY.push([x, y + i])
|
||||
}
|
||||
}
|
||||
}
|
||||
g.drawImage(img, 0, 0, renderWidth, renderHeight, x, y, renderWidth, renderHeight)
|
||||
|
||||
const cleanName = keyValue.split('.').slice(0, -1).join('.') || keyValue
|
||||
texturesIndex[cleanName] = {
|
||||
u: x / imgSize,
|
||||
v: y / imgSize,
|
||||
...suSvOptimize === 'remove' ? {} : {
|
||||
su: suSv,
|
||||
sv: suSv
|
||||
su: su,
|
||||
sv: sv
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -91,7 +116,7 @@ export function makeBlockTextureAtlas (mcAssets: McAssets) {
|
|||
// const textureFiles = mostEncounteredBlocks.map(x => x + '.png')
|
||||
textureFiles.unshift(...localTextures)
|
||||
|
||||
const { generated: additionalTextures, twoTileTextures } = getAdditionalTextures()
|
||||
const { generated: additionalTextures, twoTileTextures, origSizeTextures } = getAdditionalTextures()
|
||||
textureFiles.push(...Object.keys(additionalTextures))
|
||||
|
||||
const atlas = makeTextureAtlas(textureFiles, name => {
|
||||
|
|
@ -105,6 +130,7 @@ export function makeBlockTextureAtlas (mcAssets: McAssets) {
|
|||
return {
|
||||
contents,
|
||||
tileWidthMult: twoTileTextures.includes(name) ? 2 : undefined,
|
||||
origSizeTextures
|
||||
}
|
||||
})
|
||||
return atlas
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"texture_size": [32, 32],
|
||||
"textures": {
|
||||
"0": "entity/decorated_pot/decorated_pot_base"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Body",
|
||||
"from": [1, 0, 1],
|
||||
"to": [15, 16, 15],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 6.5, 7, 13.5], "texture": "#0"},
|
||||
"east": {"uv": [0, 6.5, 7, 13.5], "texture": "#0"},
|
||||
"south": {"uv": [0, 6.5, 7, 13.5], "texture": "#0"},
|
||||
"west": {"uv": [0, 6.5, 7, 13.5], "texture": "#0"},
|
||||
"up": {"uv": [7, 6.5, 14, 13.5], "texture": "#0"},
|
||||
"down": {"uv": [7, 6.5, 14, 13.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Neck",
|
||||
"from": [5, 16, 5],
|
||||
"to": [11, 17, 11],
|
||||
"faces": {
|
||||
"north": {"uv": [6, 5.5, 9, 6], "texture": "#0"},
|
||||
"east": {"uv": [9, 5.5, 12, 6], "texture": "#0"},
|
||||
"south": {"uv": [2.5, 5.5, 5.5, 6], "texture": "#0"},
|
||||
"west": {"uv": [0, 5.5, 3, 6], "texture": "#0"},
|
||||
"up": {"uv": [0, 0, 3, 3], "texture": "#0"},
|
||||
"down": {"uv": [0, 0, 3, 3], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Head",
|
||||
"from": [4, 17, 4],
|
||||
"to": [12, 20, 12],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 4, 4, 5.5], "texture": "#0"},
|
||||
"east": {"uv": [4, 4, 8, 5.5], "texture": "#0"},
|
||||
"south": {"uv": [8, 4, 12, 5.5], "texture": "#0"},
|
||||
"west": {"uv": [12, 4, 16, 5.5], "texture": "#0"},
|
||||
"up": {"uv": [4, 0, 8, 4], "texture": "#0"},
|
||||
"down": {"uv": [8, 0, 12, 4], "texture": "#0"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=east": {
|
||||
"model": "decorated_pot",
|
||||
"y": 90
|
||||
},
|
||||
"facing=south": {
|
||||
"model": "decorated_pot",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "decorated_pot",
|
||||
"y": 270
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "decorated_pot"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import { fileURLToPath } from 'url'
|
|||
|
||||
// todo refactor
|
||||
const twoTileTextures: string[] = []
|
||||
const origSizeTextures: string[] = []
|
||||
let currentImage: Jimp
|
||||
let currentBlockName: string
|
||||
let currentMcAssets: McAssets
|
||||
|
|
@ -82,7 +83,7 @@ const getBlockTexturesFromJimp = async <T extends Record<string, Jimp>> (sides:
|
|||
for (const [side, jimp] of Object.entries(sides)) {
|
||||
const textureName = `${textureNameBase}_${side}`
|
||||
const sideTexture = withUv ? { uv: [0, 0, jimp.getWidth(), jimp.getHeight()], texture: textureName } : textureName
|
||||
const base64 = await jimp.getBase64Async(jimp.getMIME())
|
||||
const base64Url = await jimp.getBase64Async(jimp.getMIME())
|
||||
if (side === 'side') {
|
||||
sidesTextures['north'] = sideTexture
|
||||
sidesTextures['east'] = sideTexture
|
||||
|
|
@ -91,7 +92,7 @@ const getBlockTexturesFromJimp = async <T extends Record<string, Jimp>> (sides:
|
|||
} else {
|
||||
sidesTextures[side] = sideTexture
|
||||
}
|
||||
generatedImageTextures[textureName] = base64
|
||||
generatedImageTextures[textureName] = base64Url
|
||||
}
|
||||
|
||||
return sidesTextures
|
||||
|
|
@ -401,6 +402,20 @@ const handleChest = async (dataBase: string, match: RegExpExecArray) => {
|
|||
currentMcAssets.blocksStates[currentBlockName] = blockStates
|
||||
}
|
||||
|
||||
const handleDecoratedPot = async (dataBase: string, match: RegExpExecArray) => {
|
||||
currentMcAssets.blocksStates[currentBlockName] = JSON.parse(fs.readFileSync(path.join(__dirname, 'blockStates/decorated_pot.json'), 'utf-8'))
|
||||
const blockModel = JSON.parse(fs.readFileSync(path.join(__dirname, 'blockModels/decorated_pot.json'), 'utf-8'))
|
||||
currentImage = await Jimp.read(dataBase + `entity/decorated_pot/decorated_pot_base.png`)
|
||||
// resize from 32x32 to 16x16 without cropping the image
|
||||
// const baseBase64 = await currentImage.clone().resize(16, 16).getBase64Async(Jimp.MIME_PNG)
|
||||
// const baseBase64 = await currentImage.getBase64Async(Jimp.MIME_PNG)
|
||||
blockModel.textures.particle = 'flower_pot'
|
||||
generatedImageTextures['decorated_pot_base'] = `data:image/png;base64,${fs.readFileSync(path.join(dataBase, 'entity/decorated_pot/decorated_pot_base.png'), 'base64')}`
|
||||
// generatedImageTextures['decorated_pot_base'] = baseBase64
|
||||
origSizeTextures['decorated_pot_base'] = true
|
||||
currentMcAssets.blocksModels[currentBlockName] = blockModel
|
||||
}
|
||||
|
||||
const handlers = [
|
||||
[/(.+)_shulker_box$/, handleShulkerBox],
|
||||
[/^shulker_box$/, handleShulkerBox],
|
||||
|
|
@ -410,6 +425,7 @@ const handlers = [
|
|||
[/(.+)_wall_sign$/, handleSign],
|
||||
[/(.+)_sign$/, handleSign],
|
||||
[/^(?:(ender|trapped)_)?chest$/, handleChest],
|
||||
[/^decorated_pot$/, handleDecoratedPot],
|
||||
// [/(^|(.+)_)bed$/, handleBed],
|
||||
// no-op just suppress warning
|
||||
[/(^light|^moving_piston$)/, true],
|
||||
|
|
@ -462,5 +478,5 @@ export const prepareMoreGeneratedBlocks = async (mcAssets: McAssets) => {
|
|||
}
|
||||
|
||||
export const getAdditionalTextures = () => {
|
||||
return { generated: generatedImageTextures, twoTileTextures }
|
||||
return { generated: generatedImageTextures, twoTileTextures, origSizeTextures }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue