134 lines
4.7 KiB
Python
134 lines
4.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""把 box_of_nails.bbmodel 转换为网易自定义方块模型(netease:block_geometry)。
|
|
|
|
转换规则(与官方 CustomBlocksMod 示例的 bbmodel->json 实测结果一致):
|
|
cube.origin = [-to.x, from.y, from.z]
|
|
cube.size = to - from
|
|
cube.pivot = [-bb.origin.x, bb.origin.y, bb.origin.z]
|
|
cube.rotation / bone.rotation = [-rx, -ry, rz]
|
|
uv: up 面 -> uv=[x2,y2], uv_size=[x1-x2, y1-y2]
|
|
其余面 -> uv=[x1,y1], uv_size=[x2-x1, y2-y1]
|
|
负的 uv_size 表示贴图镜像(与原格式一致)
|
|
贴图为空(texture=null 或零面积)的面不输出
|
|
"""
|
|
import base64
|
|
import json
|
|
import os
|
|
|
|
ROOT = r"e:\MCStudioDownload\work\3027246179@qq.com\Cpp\AddOn\0aaaa4f2f16c46e8964025a5ab0ecc02"
|
|
RES = os.path.join(ROOT, "resource_pack_t7eJjrxY")
|
|
SRC = r"c:\Users\30272\.trae-cn\attachments\6ac7514c01a7d726cbee7358\7dc21437-b0c4-442b-a225-1ce20d2bdbbc_593d488a-acae-4a41-a007-98367aec6727_box_of_nails.bbmodel"
|
|
|
|
TEX_NAME = "box_of_nails"
|
|
TEX_KEY = "dn_sa_" + TEX_NAME
|
|
MODEL_ID = "dn_sa:" + TEX_NAME + "_model"
|
|
BONE_NAME = "bone"
|
|
FACE_ORDER = ("north", "east", "south", "west", "up", "down")
|
|
|
|
|
|
def num(v):
|
|
if isinstance(v, float):
|
|
if v.is_integer():
|
|
return int(v)
|
|
return round(v, 4)
|
|
return v
|
|
|
|
|
|
def arr(v):
|
|
return "[" + ", ".join(str(num(x)) for x in v) + "]"
|
|
|
|
|
|
def conv_uv(el):
|
|
out = []
|
|
for face in FACE_ORDER:
|
|
f = el["faces"].get(face)
|
|
if not f or f.get("texture") is None:
|
|
continue
|
|
x1, y1, x2, y2 = f["uv"]
|
|
if x1 == x2 or y1 == y2:
|
|
continue
|
|
if face == "up":
|
|
entry = "{" + '"uv": %s, "uv_size": %s' % (arr([x2, y2]), arr([x1 - x2, y1 - y2]))
|
|
else:
|
|
entry = "{" + '"uv": %s, "uv_size": %s' % (arr([x1, y1]), arr([x2 - x1, y2 - y1]))
|
|
if f.get("rotation"):
|
|
entry += ', "rot": %s' % num(f["rotation"])
|
|
entry += "}"
|
|
out.append('"%s": %s' % (face, entry))
|
|
return out
|
|
|
|
|
|
def main():
|
|
with open(SRC, "r", encoding="utf-8") as fp:
|
|
bb = json.load(fp)
|
|
|
|
tex = bb["textures"][0]
|
|
tw, th = tex["width"], tex["height"]
|
|
|
|
# 1) 贴图 -> resourcepack/textures/blocks
|
|
raw = base64.b64decode(tex["source"].split(",", 1)[1])
|
|
tex_dir = os.path.join(RES, "textures", "blocks")
|
|
os.makedirs(tex_dir, exist_ok=True)
|
|
tex_path = os.path.join(tex_dir, TEX_NAME + ".png")
|
|
with open(tex_path, "wb") as fp:
|
|
fp.write(raw)
|
|
|
|
# 2) 模型 -> resourcepack/models/netease_block
|
|
cube_blocks = []
|
|
for el in bb["elements"]:
|
|
lines = []
|
|
lines.append("\t\t\t\t\t{")
|
|
body = []
|
|
body.append('"origin": %s' % arr([-el["to"][0], el["from"][1], el["from"][2]]))
|
|
body.append('"size": %s' % arr([el["to"][i] - el["from"][i] for i in range(3)]))
|
|
if el.get("rotation"):
|
|
body.append('"pivot": %s' % arr([-el["origin"][0], el["origin"][1], el["origin"][2]]))
|
|
body.append('"rotation": %s' % arr([-el["rotation"][0], -el["rotation"][1], el["rotation"][2]]))
|
|
uv_lines = conv_uv(el)
|
|
txt = ",\n".join("\t\t\t\t\t\t%s" % b for b in body)
|
|
txt += ',\n\t\t\t\t\t\t"uv": {\n'
|
|
txt += ",\n".join("\t\t\t\t\t\t\t%s" % u for u in uv_lines)
|
|
txt += "\n\t\t\t\t\t\t}"
|
|
lines.append(txt)
|
|
lines.append("\t\t\t\t\t}")
|
|
cube_blocks.append("\n".join(lines))
|
|
|
|
model = []
|
|
model.append("{")
|
|
model.append('\t"format_version": "1.13.0",')
|
|
model.append('\t"netease:block_geometry": {')
|
|
model.append('\t\t"description": {')
|
|
model.append('\t\t\t"identifier": "%s",' % MODEL_ID)
|
|
model.append('\t\t\t"textures": ["%s"],' % TEX_KEY)
|
|
model.append('\t\t\t"textures_descriptions": [')
|
|
model.append('\t\t\t\t{ "width": %d, "length": %d }' % (tw, th))
|
|
model.append('\t\t\t],')
|
|
model.append('\t\t\t"use_ao": true')
|
|
model.append('\t\t},')
|
|
model.append('\t\t"bones": [')
|
|
model.append('\t\t\t{')
|
|
model.append('\t\t\t\t"name": "%s",' % BONE_NAME)
|
|
model.append('\t\t\t\t"pivot": [0, 0, 0],')
|
|
model.append('\t\t\t\t"cubes": [')
|
|
model.append(",\n".join(cube_blocks))
|
|
model.append('\t\t\t\t]')
|
|
model.append('\t\t\t}')
|
|
model.append('\t\t]')
|
|
model.append('\t}')
|
|
model.append('}')
|
|
text = "\n".join(model) + "\n"
|
|
|
|
model_dir = os.path.join(RES, "models", "netease_block")
|
|
os.makedirs(model_dir, exist_ok=True)
|
|
model_path = os.path.join(model_dir, TEX_KEY + ".json")
|
|
with open(model_path, "w", encoding="utf-8", newline="\n") as fp:
|
|
fp.write(text)
|
|
|
|
print("texture ->", tex_path)
|
|
print("model ->", model_path)
|
|
print("identifier:", MODEL_ID, "| terrain_texture key:", TEX_KEY, "| %dx%d" % (tw, th))
|
|
print("cubes:", len(bb["elements"]))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |