@bitmagic/cli 0.1.71-dev.3 → 0.1.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/blender-level/README.md +3 -1
- package/assets/blender-level/bmedit/__init__.py +26 -0
- package/assets/blender-level/bmedit/blender.py +652 -0
- package/assets/blender-level/bmedit/colour.py +61 -0
- package/assets/blender-level/review.py +42 -6
- package/assets/blender-level/review_asset.py +138 -0
- package/assets/blender-level/tests/test_bmedit_colour.py +36 -0
- package/dist/commands/publish.js +4 -0
- package/dist/commands/publish.js.map +1 -1
- package/dist/publish/art-style.d.ts +10 -0
- package/dist/publish/art-style.js +17 -0
- package/dist/publish/art-style.js.map +1 -0
- package/dist/publish/client.d.ts +6 -0
- package/dist/publish/client.js.map +1 -1
- package/dist/scaffold/blender-level-skill-files.js +1 -0
- package/dist/scaffold/blender-level-skill-files.js.map +1 -1
- package/package.json +4 -4
|
@@ -13,9 +13,11 @@ skill's step 1 tells an agent how to copy them into a project's `tools/blender-l
|
|
|
13
13
|
|---|---|---|
|
|
14
14
|
| `find_blender.py` | python3 | prints the Blender executable, or how to install one |
|
|
15
15
|
| `bmlevel/` | Blender, or python3 for a dry run | the authoring vocabulary (`__init__.py`), the bpy-free maths and JSON writers (`core.py`), the Blender backend (`scene_bpy.py`) and the recording backend (`scene_null.py`) |
|
|
16
|
+
| `bmedit/` | Blender (`colour.py`: python3) | edit GLBs and make props: `load(id)` from `build/inputs/<id>.glb`, `paint` / `recolor` / `replace_colour` by face, `box` / `cylinder` / `cone` / `sphere`, `join`, `turn`, `scatter`, `export(id)` to `build/assets/<id>.glb`; smart props (moving parts the engine animates) with `part()`, `anchor()` and `export(..., smart=)` — the vocabulary the web Creator's `blender` tool runs on the Asset Forger (`game/agent-docs/blender.md`) |
|
|
17
|
+
| `review_asset.py` | Blender | two three-quarter renders per GLB and a contact sheet: the review for props and edited assets |
|
|
16
18
|
| `example_level.py` | either | a complete hut-and-courtyard level using every helper; the tests' fixture |
|
|
17
19
|
| `audit.py` | Blender | ray-cast audit of the COLLIDERS: floor continuity, door and route clearance, sealed envelopes, z-fighting candidates |
|
|
18
|
-
| `review.py` | Blender | deterministic review renders (overview, every door, every stair, every room) and a contact sheet; `--shot 'FROM -> TO'` aims a frame anywhere, `--only` renders just those, `--lighting game` swaps the review fill for the engine's interior preset and the level's own lamps |
|
|
20
|
+
| `review.py` | Blender | deterministic review renders (overview, every door, every stair, every room) and a contact sheet; `--shot 'FROM -> TO'` aims a frame anywhere, `--only` renders just those, `--lighting game` swaps the review fill for the engine's interior preset and the level's own lamps, `--engine cycles` renders without an OpenGL context |
|
|
19
21
|
| `sync_world.py` | python3 | carries the doors, spawn and `terrain.shape: 'none'` into `src/work/world.json` |
|
|
20
22
|
| `tests/` | python3 | `python3 -m unittest discover -s tests` — no Blender needed; `cli`'s `pnpm test` runs it |
|
|
21
23
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""bmedit — edit a game's GLBs and make new low-poly props in a short Blender script.
|
|
2
|
+
|
|
3
|
+
from bmedit import load, palette, recolor, cone, box, join, export
|
|
4
|
+
ground = load('ground') # the game's asset, imported
|
|
5
|
+
palette(ground) # its face colours, most used first
|
|
6
|
+
recolor(ground, '#eef3f7', where=lambda p, n, c: n[1] > 0.6) # snow on everything flat
|
|
7
|
+
export('ground', ground) # replaces the asset, same id
|
|
8
|
+
|
|
9
|
+
post = join([box('post', (0.2, 1.2, 0.2), color='#6b4a2f'),
|
|
10
|
+
box('cap', (0.3, 0.1, 0.3), at=(0, 1.2, 0), color='#4a3220')], 'post')
|
|
11
|
+
export('fence-post', post) # a new asset, 1.3 m tall
|
|
12
|
+
|
|
13
|
+
Positions, sizes and normals are in GAME coordinates — metres, Y up, +Z forward, yaw in radians
|
|
14
|
+
about +Y — the same as bmlevel; the Blender axis flip happens inside. Colours are sRGB: '#rrggbb',
|
|
15
|
+
0-255 or 0-1 triples. Painting is per face (flat low-poly look), stored as the mesh's COLOR_0.
|
|
16
|
+
|
|
17
|
+
`load()` and `export()` are the only file access a script has. The host decides where they point
|
|
18
|
+
(`configure()`): the Asset Forger's job directory, or the GDK project's `build/` folder.
|
|
19
|
+
"""
|
|
20
|
+
try: # inside Blender
|
|
21
|
+
import bpy # noqa: F401
|
|
22
|
+
except ImportError: # plain python3: only bmedit.colour is usable (its tests run here)
|
|
23
|
+
__all__: list[str] = []
|
|
24
|
+
else:
|
|
25
|
+
from bmedit.blender import * # noqa: F401,F403
|
|
26
|
+
from bmedit.blender import __all__, configure, exports # noqa: F401
|
|
@@ -0,0 +1,652 @@
|
|
|
1
|
+
"""The Blender half of bmedit: every builder, edit and the export. See __init__.py."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import math
|
|
5
|
+
import os
|
|
6
|
+
import random
|
|
7
|
+
import re
|
|
8
|
+
from typing import Callable, Iterable, Optional, Sequence, Union
|
|
9
|
+
|
|
10
|
+
import bmesh
|
|
11
|
+
import bpy
|
|
12
|
+
from mathutils import Matrix, Vector
|
|
13
|
+
|
|
14
|
+
from bmedit.colour import Colour, distance, mix, to_hex, to_linear
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
'load', 'box', 'cylinder', 'cone', 'sphere', 'join', 'copy', 'move', 'remove', 'objects',
|
|
18
|
+
'paint', 'recolor', 'replace_colour', 'palette', 'decimate', 'scatter', 'bounds', 'describe',
|
|
19
|
+
'height_at', 'turn', 'part', 'anchor', 'export', 'mix',
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
MAX_EXPORTS = 8
|
|
23
|
+
_ID = re.compile(r'^[a-z0-9][a-z0-9_-]{0,63}$')
|
|
24
|
+
_state: dict = {'inputs': os.path.abspath('build/inputs'), 'out': os.path.abspath('build/assets'), 'exports': []}
|
|
25
|
+
|
|
26
|
+
Objects = Union[bpy.types.Object, Iterable[bpy.types.Object]]
|
|
27
|
+
Vec = Sequence[float]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def configure(inputs_dir: str, out_dir: str) -> None:
|
|
31
|
+
"""Where load() reads and export() writes. Called by the host before the script runs."""
|
|
32
|
+
_state['inputs'] = os.path.abspath(inputs_dir)
|
|
33
|
+
_state['out'] = os.path.abspath(out_dir)
|
|
34
|
+
_state['exports'] = []
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def exports() -> list[dict]:
|
|
38
|
+
"""What the script exported, for the host: [{id, file, targetHeight, triangles}]."""
|
|
39
|
+
return list(_state['exports'])
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# ---- coordinates ---------------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
def _to_b(p: Vec) -> Vector:
|
|
45
|
+
return Vector((p[0], -p[2], p[1]))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _to_game(v: Vec) -> tuple[float, float, float]:
|
|
49
|
+
return (v[0], v[2], -v[1])
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _list(objs: Objects) -> list[bpy.types.Object]:
|
|
53
|
+
if isinstance(objs, bpy.types.Object):
|
|
54
|
+
return [objs]
|
|
55
|
+
return [o for o in objs if o.type == 'MESH']
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def objects() -> list[bpy.types.Object]:
|
|
59
|
+
"""Every mesh object in the scene."""
|
|
60
|
+
return [o for o in bpy.context.scene.objects if o.type == 'MESH']
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# ---- load ----------------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
def load(input_id: str) -> list[bpy.types.Object]:
|
|
66
|
+
"""Import one of the job's input GLBs (the game asset with that id) and return its meshes.
|
|
67
|
+
|
|
68
|
+
Transforms are applied, so every vertex position is where the game draws it."""
|
|
69
|
+
if not _ID.match(input_id):
|
|
70
|
+
raise ValueError(f'bad input id {input_id!r}')
|
|
71
|
+
path = os.path.join(_state['inputs'], f'{input_id}.glb')
|
|
72
|
+
if not os.path.exists(path):
|
|
73
|
+
have = sorted(f[:-4] for f in os.listdir(_state['inputs'])) if os.path.isdir(_state['inputs']) else []
|
|
74
|
+
raise FileNotFoundError(f'no input {input_id!r}; this job has {have}')
|
|
75
|
+
before = set(bpy.data.objects)
|
|
76
|
+
bpy.ops.import_scene.gltf(filepath=path)
|
|
77
|
+
new = [o for o in bpy.data.objects if o not in before]
|
|
78
|
+
meshes = [o for o in new if o.type == 'MESH']
|
|
79
|
+
for o in new:
|
|
80
|
+
if o.type != 'MESH':
|
|
81
|
+
continue
|
|
82
|
+
# Bake parent + own transform into the mesh, so positions are world positions.
|
|
83
|
+
world = o.matrix_world.copy()
|
|
84
|
+
o.parent = None
|
|
85
|
+
o.data.transform(world)
|
|
86
|
+
o.matrix_world = Matrix.Identity(4)
|
|
87
|
+
for o in new:
|
|
88
|
+
if o.type != 'MESH':
|
|
89
|
+
bpy.data.objects.remove(o, do_unlink=True)
|
|
90
|
+
for o in meshes:
|
|
91
|
+
_face_up(o)
|
|
92
|
+
return meshes
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _face_up(obj: bpy.types.Object) -> None:
|
|
96
|
+
"""Flip a mesh whose faces mostly point DOWN. Some generated grounds are wound inside-out and
|
|
97
|
+
drawn double-sided; left as they are, `n[1] > 0.7` would find no flat ground to paint."""
|
|
98
|
+
mesh = obj.data
|
|
99
|
+
total = sum(p.area * p.normal.z for p in mesh.polygons)
|
|
100
|
+
area = sum(p.area for p in mesh.polygons)
|
|
101
|
+
if area > 0 and total / area < -0.3:
|
|
102
|
+
mesh.flip_normals()
|
|
103
|
+
print(f'[bmedit] {obj.name}: faces pointed down; flipped')
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# ---- primitives ----------------------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
def _vertex_material() -> bpy.types.Material:
|
|
109
|
+
mat = bpy.data.materials.get('bmedit_vertex')
|
|
110
|
+
if mat is None:
|
|
111
|
+
mat = bpy.data.materials.new('bmedit_vertex')
|
|
112
|
+
mat.use_nodes = True
|
|
113
|
+
nodes = mat.node_tree.nodes
|
|
114
|
+
bsdf = nodes['Principled BSDF']
|
|
115
|
+
bsdf.inputs['Roughness'].default_value = 1.0
|
|
116
|
+
attr = nodes.new('ShaderNodeVertexColor')
|
|
117
|
+
attr.layer_name = 'Col'
|
|
118
|
+
mat.node_tree.links.new(attr.outputs['Color'], bsdf.inputs['Base Color'])
|
|
119
|
+
return mat
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _finish(name: str, bm: bmesh.types.BMesh, color: Colour, at: Vec, yaw: float) -> bpy.types.Object:
|
|
123
|
+
mesh = bpy.data.meshes.new(name)
|
|
124
|
+
bm.to_mesh(mesh)
|
|
125
|
+
bm.free()
|
|
126
|
+
for poly in mesh.polygons:
|
|
127
|
+
poly.use_smooth = False
|
|
128
|
+
mesh.materials.append(_vertex_material())
|
|
129
|
+
obj = bpy.data.objects.new(name, mesh)
|
|
130
|
+
bpy.context.scene.collection.objects.link(obj)
|
|
131
|
+
_colour_layer(obj)
|
|
132
|
+
_fill(obj, to_linear(color))
|
|
133
|
+
# Straight into the vertices: the object keeps an identity transform, so every position a
|
|
134
|
+
# later call reads (bounds, paint, scatter) is already where the game draws it.
|
|
135
|
+
mesh.transform(Matrix.Translation(_to_b(at)) @ Matrix.Rotation(yaw, 4, 'Z'))
|
|
136
|
+
return obj
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def box(name: str, size: Vec, at: Vec = (0, 0, 0), color: Colour = '#999999', yaw: float = 0.0) -> bpy.types.Object:
|
|
140
|
+
"""A box `size` = (width x, height y, depth z) whose BOTTOM centre sits at `at`."""
|
|
141
|
+
bm = bmesh.new()
|
|
142
|
+
bmesh.ops.create_cube(bm, size=1.0)
|
|
143
|
+
bmesh.ops.scale(bm, vec=Vector((size[0], size[2], size[1])), verts=bm.verts)
|
|
144
|
+
bmesh.ops.translate(bm, vec=Vector((0, 0, size[1] / 2)), verts=bm.verts)
|
|
145
|
+
return _finish(name, bm, color, at, yaw)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def cylinder(name: str, radius: float, height: float, at: Vec = (0, 0, 0), color: Colour = '#999999',
|
|
149
|
+
segments: int = 8, top_radius: Optional[float] = None, yaw: float = 0.0) -> bpy.types.Object:
|
|
150
|
+
"""An upright cylinder (or frustum, with top_radius) standing on `at`."""
|
|
151
|
+
bm = bmesh.new()
|
|
152
|
+
bmesh.ops.create_cone(bm, cap_ends=True, cap_tris=False, segments=max(3, segments),
|
|
153
|
+
radius1=radius, radius2=radius if top_radius is None else top_radius, depth=height)
|
|
154
|
+
bmesh.ops.translate(bm, vec=Vector((0, 0, height / 2)), verts=bm.verts)
|
|
155
|
+
return _finish(name, bm, color, at, yaw)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def cone(name: str, radius: float, height: float, at: Vec = (0, 0, 0), color: Colour = '#999999',
|
|
159
|
+
segments: int = 8, yaw: float = 0.0) -> bpy.types.Object:
|
|
160
|
+
"""An upright cone standing on `at` — a pine layer, a roof tip, a spike."""
|
|
161
|
+
return cylinder(name, radius, height, at, color, segments, top_radius=0.0, yaw=yaw)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def sphere(name: str, radius: float, at: Vec = (0, 0, 0), color: Colour = '#999999', detail: int = 1) -> bpy.types.Object:
|
|
165
|
+
"""A faceted ball centred on `at` (detail 1 = 80 faces, 2 = 320)."""
|
|
166
|
+
bm = bmesh.new()
|
|
167
|
+
bmesh.ops.create_icosphere(bm, subdivisions=max(1, min(3, detail)), radius=radius)
|
|
168
|
+
return _finish(name, bm, color, at, 0.0)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
# ---- object edits --------------------------------------------------------------------------
|
|
172
|
+
|
|
173
|
+
def join(objs: Objects, name: str) -> bpy.types.Object:
|
|
174
|
+
"""Merge meshes into one object (one draw call in the game)."""
|
|
175
|
+
items = _list(objs)
|
|
176
|
+
if not items:
|
|
177
|
+
raise ValueError('join() needs at least one mesh')
|
|
178
|
+
for o in items:
|
|
179
|
+
_colour_layer(o)
|
|
180
|
+
with bpy.context.temp_override(active_object=items[0], selected_editable_objects=items, selected_objects=items):
|
|
181
|
+
bpy.ops.object.join()
|
|
182
|
+
items[0].name = name
|
|
183
|
+
items[0].data.name = name
|
|
184
|
+
return items[0]
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def copy(obj: bpy.types.Object, at: Optional[Vec] = None, yaw: float = 0.0, scale: float = 1.0,
|
|
188
|
+
name: Optional[str] = None) -> bpy.types.Object:
|
|
189
|
+
"""A copy of `obj`, rotated by `yaw` and scaled about its bottom centre, then moved so that
|
|
190
|
+
bottom centre sits at `at` (default: where it was)."""
|
|
191
|
+
dup = obj.copy()
|
|
192
|
+
dup.data = obj.data.copy()
|
|
193
|
+
dup.name = name or f'{obj.name}.copy'
|
|
194
|
+
bpy.context.scene.collection.objects.link(dup)
|
|
195
|
+
move(dup, at=at, yaw=yaw, scale=scale)
|
|
196
|
+
return dup
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def move(obj: bpy.types.Object, at: Optional[Vec] = None, yaw: float = 0.0, scale: float = 1.0) -> None:
|
|
200
|
+
"""Rotate/scale `obj` about its bottom centre, then put that point at `at` (game coords)."""
|
|
201
|
+
lo, hi = bounds(obj)
|
|
202
|
+
base = Vector(_to_b(((lo[0] + hi[0]) / 2, lo[1], (lo[2] + hi[2]) / 2)))
|
|
203
|
+
target = _to_b(at) if at is not None else base
|
|
204
|
+
m = Matrix.Translation(target) @ Matrix.Rotation(yaw, 4, 'Z') @ Matrix.Scale(scale, 4) @ Matrix.Translation(-base)
|
|
205
|
+
obj.data.transform(m)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def turn(objs: Objects, angle: float, axis: Vec = (0, 1, 0), about: Optional[Vec] = None) -> None:
|
|
209
|
+
"""Rotate by `angle` radians about `axis` (game coords, right-handed: about +Z, +Y turns toward
|
|
210
|
+
-X) through the point `about` (default: the objects' box centre). A spoke is a box standing on
|
|
211
|
+
the hub turned about the hub; a leaning leg is turned about its foot."""
|
|
212
|
+
items = _list(objs)
|
|
213
|
+
if about is None:
|
|
214
|
+
lo, hi = bounds(items)
|
|
215
|
+
about = tuple((lo[k] + hi[k]) / 2 for k in range(3))
|
|
216
|
+
pivot = _to_b(about)
|
|
217
|
+
a = _to_b(axis)
|
|
218
|
+
m = Matrix.Translation(pivot) @ Matrix.Rotation(angle, 4, Vector(a).normalized()) @ Matrix.Translation(-pivot)
|
|
219
|
+
for o in items:
|
|
220
|
+
o.data.transform(m)
|
|
221
|
+
for child in o.children:
|
|
222
|
+
child.location = m @ child.location
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def remove(objs: Objects) -> None:
|
|
226
|
+
for o in _list(objs):
|
|
227
|
+
bpy.data.objects.remove(o, do_unlink=True)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def decimate(objs: Objects, ratio: float) -> None:
|
|
231
|
+
"""Keep about `ratio` (0..1) of each mesh's triangles — cheaper, chunkier."""
|
|
232
|
+
for o in _list(objs):
|
|
233
|
+
mod = o.modifiers.new('decimate', 'DECIMATE')
|
|
234
|
+
mod.ratio = max(0.01, min(1.0, ratio))
|
|
235
|
+
with bpy.context.temp_override(object=o, active_object=o):
|
|
236
|
+
bpy.ops.object.modifier_apply(modifier=mod.name)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
# ---- colour --------------------------------------------------------------------------------
|
|
240
|
+
|
|
241
|
+
def _colour_layer(obj: bpy.types.Object):
|
|
242
|
+
"""The object's face-corner colour attribute — an imported GLB's own COLOR_0 (byte or float:
|
|
243
|
+
both read and write linear `.color`), else a new one filled from its materials' colours, with
|
|
244
|
+
the materials switched to show it (white base, colour from the attribute)."""
|
|
245
|
+
mesh = obj.data
|
|
246
|
+
attrs = mesh.color_attributes
|
|
247
|
+
layer = attrs.active_color
|
|
248
|
+
if layer is not None and layer.domain == 'CORNER':
|
|
249
|
+
return layer
|
|
250
|
+
old = layer
|
|
251
|
+
new = attrs.new('Col', 'FLOAT_COLOR', 'CORNER')
|
|
252
|
+
base = [_material_colour(m) for m in mesh.materials] or [(0.8, 0.8, 0.8, 1.0)]
|
|
253
|
+
for poly in mesh.polygons:
|
|
254
|
+
for li in poly.loop_indices:
|
|
255
|
+
if old is not None: # a POINT-domain layer: each corner takes its vertex's colour
|
|
256
|
+
new.data[li].color = old.data[mesh.loops[li].vertex_index].color
|
|
257
|
+
else:
|
|
258
|
+
new.data[li].color = base[min(poly.material_index, len(base) - 1)]
|
|
259
|
+
attrs.active_color = new
|
|
260
|
+
# The glTF exporter's 'ACTIVE' mode writes the RENDER colour attribute.
|
|
261
|
+
attrs.default_color_name = new.name
|
|
262
|
+
for mat in mesh.materials:
|
|
263
|
+
_show_vertex_colour(mat, new.name)
|
|
264
|
+
return new
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def _material_colour(mat) -> tuple[float, float, float, float]:
|
|
268
|
+
if mat is None:
|
|
269
|
+
return (0.8, 0.8, 0.8, 1.0)
|
|
270
|
+
if mat.use_nodes and 'Principled BSDF' in mat.node_tree.nodes:
|
|
271
|
+
c = mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value
|
|
272
|
+
return (c[0], c[1], c[2], 1.0)
|
|
273
|
+
c = mat.diffuse_color
|
|
274
|
+
return (c[0], c[1], c[2], 1.0)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def _show_vertex_colour(mat, layer_name: str) -> None:
|
|
278
|
+
"""Base colour from the attribute, unless an image texture drives it (then the attribute tints)."""
|
|
279
|
+
if mat is None or not mat.use_nodes or 'Principled BSDF' not in mat.node_tree.nodes:
|
|
280
|
+
return
|
|
281
|
+
for node in mat.node_tree.nodes:
|
|
282
|
+
if node.bl_idname == 'ShaderNodeVertexColor':
|
|
283
|
+
node.layer_name = layer_name
|
|
284
|
+
return
|
|
285
|
+
bsdf = mat.node_tree.nodes['Principled BSDF']
|
|
286
|
+
base = bsdf.inputs['Base Color']
|
|
287
|
+
if base.is_linked:
|
|
288
|
+
return
|
|
289
|
+
base.default_value = (1.0, 1.0, 1.0, 1.0)
|
|
290
|
+
attr = mat.node_tree.nodes.new('ShaderNodeVertexColor')
|
|
291
|
+
attr.layer_name = layer_name
|
|
292
|
+
mat.node_tree.links.new(attr.outputs['Color'], base)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def _fill(obj: bpy.types.Object, rgba) -> None:
|
|
296
|
+
layer = _colour_layer(obj)
|
|
297
|
+
for d in layer.data:
|
|
298
|
+
d.color = rgba
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def _faces(obj: bpy.types.Object):
|
|
302
|
+
"""(polygon, game centre, game normal, current sRGB hex) per face."""
|
|
303
|
+
layer = _colour_layer(obj)
|
|
304
|
+
mesh = obj.data
|
|
305
|
+
# The shading normals (an imported GLB's own NORMAL data), not the winding: generated grounds
|
|
306
|
+
# are often wound the other way and drawn double-sided, so poly.normal can point down.
|
|
307
|
+
corners = mesh.corner_normals
|
|
308
|
+
for poly in mesh.polygons:
|
|
309
|
+
c = layer.data[poly.loop_indices[0]].color
|
|
310
|
+
n = Vector((0.0, 0.0, 0.0))
|
|
311
|
+
for li in poly.loop_indices:
|
|
312
|
+
n += corners[li].vector
|
|
313
|
+
n = n.normalized() if n.length > 1e-9 else poly.normal
|
|
314
|
+
yield poly, _to_game(poly.center), _to_game(n), to_hex(c), layer
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def paint(objs: Objects, fn: Callable[[tuple, tuple, str], Optional[Colour]]) -> int:
|
|
318
|
+
"""Call fn(position, normal, current_hex) for every face; a colour it returns repaints that
|
|
319
|
+
face, None keeps it. Position and normal are game coords (normal[1] > 0.7: roughly flat
|
|
320
|
+
ground; < 0.3: steep or a wall). Returns the number of faces repainted."""
|
|
321
|
+
changed = 0
|
|
322
|
+
for o in _list(objs):
|
|
323
|
+
for poly, pos, normal, current, layer in _faces(o):
|
|
324
|
+
out = fn(pos, normal, current)
|
|
325
|
+
if out is None:
|
|
326
|
+
continue
|
|
327
|
+
rgba = to_linear(out)
|
|
328
|
+
for li in poly.loop_indices:
|
|
329
|
+
layer.data[li].color = rgba
|
|
330
|
+
changed += 1
|
|
331
|
+
return changed
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def recolor(objs: Objects, colour: Colour, where: Optional[Callable[[tuple, tuple, str], bool]] = None) -> int:
|
|
335
|
+
"""Paint every face (or those `where(position, normal, current_hex)` accepts) one colour."""
|
|
336
|
+
return paint(objs, lambda p, n, c: colour if where is None or where(p, n, c) else None)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def replace_colour(objs: Objects, mapping: dict, tolerance: float = 0.08) -> int:
|
|
340
|
+
"""Swap colours: {'#3f8f3a': '#eef3f7', ...}. A face within `tolerance` of a key takes its
|
|
341
|
+
value — the way to turn 'the green of the leaves' white without touching the bark."""
|
|
342
|
+
keys = list(mapping.items())
|
|
343
|
+
|
|
344
|
+
def swap(_p, _n, current):
|
|
345
|
+
best = min(keys, key=lambda kv: distance(kv[0], current))
|
|
346
|
+
return best[1] if distance(best[0], current) <= tolerance else None
|
|
347
|
+
return paint(objs, swap)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def palette(objs: Objects, top: int = 12) -> list[tuple[str, int]]:
|
|
351
|
+
"""The face colours in use, most common first, as [(hex, faces)] — printed too, so the build
|
|
352
|
+
log shows what an edit has to work with. Near-identical colours are merged."""
|
|
353
|
+
counts: dict[str, int] = {}
|
|
354
|
+
for o in _list(objs):
|
|
355
|
+
for _poly, _p, _n, current, _l in _faces(o):
|
|
356
|
+
for known in counts:
|
|
357
|
+
if distance(known, current) < 0.03:
|
|
358
|
+
counts[known] += 1
|
|
359
|
+
break
|
|
360
|
+
else:
|
|
361
|
+
counts[current] = 1
|
|
362
|
+
ranked = sorted(counts.items(), key=lambda kv: -kv[1])[:top]
|
|
363
|
+
print('[bmedit] palette: ' + ', '.join(f'{h} x{n}' for h, n in ranked))
|
|
364
|
+
return ranked
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
# ---- placement -----------------------------------------------------------------------------
|
|
368
|
+
|
|
369
|
+
def bounds(objs: Objects) -> tuple[tuple[float, float, float], tuple[float, float, float]]:
|
|
370
|
+
"""(min, max) corners in game coords over every vertex."""
|
|
371
|
+
lo = [math.inf] * 3
|
|
372
|
+
hi = [-math.inf] * 3
|
|
373
|
+
for o in _list(objs):
|
|
374
|
+
for v in o.data.vertices:
|
|
375
|
+
g = _to_game(o.matrix_world @ v.co)
|
|
376
|
+
for i in range(3):
|
|
377
|
+
lo[i] = min(lo[i], g[i])
|
|
378
|
+
hi[i] = max(hi[i], g[i])
|
|
379
|
+
if lo[0] == math.inf:
|
|
380
|
+
return (0.0, 0.0, 0.0), (0.0, 0.0, 0.0)
|
|
381
|
+
return (lo[0], lo[1], lo[2]), (hi[0], hi[1], hi[2])
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
def height_at(objs: Objects, x: float, z: float) -> Optional[float]:
|
|
385
|
+
"""The top surface's height at game (x, z), or None off the mesh."""
|
|
386
|
+
best = None
|
|
387
|
+
for o in _list(objs):
|
|
388
|
+
origin = _to_b((x, 1e4, z))
|
|
389
|
+
hit, loc, _n, _i = o.ray_cast(o.matrix_world.inverted() @ origin, Vector((0, 0, -1)))
|
|
390
|
+
if hit:
|
|
391
|
+
y = _to_game(o.matrix_world @ loc)[1]
|
|
392
|
+
best = y if best is None else max(best, y)
|
|
393
|
+
return best
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def scatter(proto: bpy.types.Object, count: int, on: Optional[Objects] = None,
|
|
397
|
+
area: Sequence[float] = (0.0, 0.0, 20.0), seed: int = 1, min_spacing: float = 2.0,
|
|
398
|
+
scale: Sequence[float] = (0.8, 1.2), avoid: Sequence[Sequence[float]] = (),
|
|
399
|
+
max_slope: float = 0.5) -> list[bpy.types.Object]:
|
|
400
|
+
"""Place up to `count` copies of `proto` at random inside the circle `area` = (x, z, radius),
|
|
401
|
+
random yaw and scale, standing on `on`'s surface (flat enough: normal-y >= 1 - max_slope).
|
|
402
|
+
`avoid` = [(x, z, radius), ...] keeps spots clear (the spawn, a path). Returns the copies."""
|
|
403
|
+
rng = random.Random(seed)
|
|
404
|
+
placed: list[tuple[float, float]] = []
|
|
405
|
+
out = []
|
|
406
|
+
ground = _list(on) if on is not None else []
|
|
407
|
+
for _ in range(count * 30):
|
|
408
|
+
if len(out) >= count:
|
|
409
|
+
break
|
|
410
|
+
a = rng.uniform(0, math.tau)
|
|
411
|
+
r = area[2] * math.sqrt(rng.random())
|
|
412
|
+
x, z = area[0] + r * math.cos(a), area[1] + r * math.sin(a)
|
|
413
|
+
if any((x - px) ** 2 + (z - pz) ** 2 < min_spacing ** 2 for px, pz in placed):
|
|
414
|
+
continue
|
|
415
|
+
if any((x - ax) ** 2 + (z - az) ** 2 < ar ** 2 for ax, az, ar in avoid):
|
|
416
|
+
continue
|
|
417
|
+
y = 0.0
|
|
418
|
+
if ground:
|
|
419
|
+
hit = _surface(ground, x, z)
|
|
420
|
+
if hit is None or hit[1] < 1.0 - max_slope:
|
|
421
|
+
continue
|
|
422
|
+
y = hit[0]
|
|
423
|
+
out.append(copy(proto, at=(x, y, z), yaw=rng.uniform(0, math.tau), scale=rng.uniform(*scale),
|
|
424
|
+
name=f'{proto.name}.{len(out)}'))
|
|
425
|
+
placed.append((x, z))
|
|
426
|
+
return out
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
def _surface(objs: list, x: float, z: float) -> Optional[tuple[float, float]]:
|
|
430
|
+
best = None
|
|
431
|
+
for o in objs:
|
|
432
|
+
origin = o.matrix_world.inverted() @ _to_b((x, 1e4, z))
|
|
433
|
+
hit, loc, normal, _i = o.ray_cast(origin, Vector((0, 0, -1)))
|
|
434
|
+
if hit:
|
|
435
|
+
y = _to_game(o.matrix_world @ loc)[1]
|
|
436
|
+
if best is None or y > best[0]:
|
|
437
|
+
best = (y, _to_game(normal)[1])
|
|
438
|
+
return best
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def describe(objs: Objects) -> None:
|
|
442
|
+
"""Print name, triangle count and size of each mesh — cheap orientation for an edit."""
|
|
443
|
+
for o in _list(objs):
|
|
444
|
+
lo, hi = bounds(o)
|
|
445
|
+
tris = sum(len(p.vertices) - 2 for p in o.data.polygons)
|
|
446
|
+
size = tuple(round(hi[i] - lo[i], 2) for i in range(3))
|
|
447
|
+
print(f'[bmedit] {o.name}: {tris} tris, size {size}, min {tuple(round(v, 2) for v in lo)}')
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
# ---- export --------------------------------------------------------------------------------
|
|
451
|
+
|
|
452
|
+
def _coplanar_overlaps(items: list, limit: int = 5) -> tuple[int, list[str]]:
|
|
453
|
+
"""Faces that lie in the same plane, facing the same way, and overlap: they z-fight (flicker
|
|
454
|
+
between their colours) in the game. Typical cause: trim laid flush on a surface — a rim whose
|
|
455
|
+
top cap sits at the platform's height, a stripe on a wall. Returns (count, examples)."""
|
|
456
|
+
faces = []
|
|
457
|
+
for o in items:
|
|
458
|
+
layer = o.data.color_attributes.active_color
|
|
459
|
+
for poly in o.data.polygons:
|
|
460
|
+
n = poly.normal
|
|
461
|
+
if n.length < 1e-6:
|
|
462
|
+
continue
|
|
463
|
+
pts = [o.data.vertices[v].co.copy() for v in poly.vertices]
|
|
464
|
+
colour = to_hex(layer.data[poly.loop_indices[0]].color) if layer and layer.domain == 'CORNER' else '?'
|
|
465
|
+
faces.append((n.normalized(), n.normalized().dot(pts[0]), pts, poly.center.copy(), poly.area, colour))
|
|
466
|
+
buckets: dict = {}
|
|
467
|
+
for i, (n, d, _p, _c, _a, _col) in enumerate(faces):
|
|
468
|
+
key = (round(n.x, 2), round(n.y, 2), round(n.z, 2), round(d * 200)) # same direction, within ~5 mm
|
|
469
|
+
buckets.setdefault(key, []).append(i)
|
|
470
|
+
|
|
471
|
+
def inside(point, pts, n) -> bool:
|
|
472
|
+
# Convex polygon test in its own plane: the point is on the inner side of every edge.
|
|
473
|
+
sign = 0
|
|
474
|
+
for k in range(len(pts)):
|
|
475
|
+
edge = pts[(k + 1) % len(pts)] - pts[k]
|
|
476
|
+
side = n.dot(edge.cross(point - pts[k]))
|
|
477
|
+
if abs(side) < 1e-7:
|
|
478
|
+
continue
|
|
479
|
+
if sign == 0:
|
|
480
|
+
sign = 1 if side > 0 else -1
|
|
481
|
+
elif (side > 0) != (sign > 0):
|
|
482
|
+
return False
|
|
483
|
+
return True
|
|
484
|
+
|
|
485
|
+
count, examples = 0, []
|
|
486
|
+
for group in buckets.values():
|
|
487
|
+
if len(group) < 2:
|
|
488
|
+
continue
|
|
489
|
+
for x in range(len(group)):
|
|
490
|
+
for y in range(x + 1, len(group)):
|
|
491
|
+
fa, fb = faces[group[x]], faces[group[y]]
|
|
492
|
+
small, big = (fa, fb) if fa[4] <= fb[4] else (fb, fa)
|
|
493
|
+
# Two faces of one colour flicker between identical pixels: invisible, not reported.
|
|
494
|
+
if small[5] == big[5] or not inside(small[3], big[2], big[0]):
|
|
495
|
+
continue
|
|
496
|
+
count += 1
|
|
497
|
+
if len(examples) < limit:
|
|
498
|
+
g = _to_game(small[3])
|
|
499
|
+
examples.append(f'({g[0]:.2f}, {g[1]:.2f}, {g[2]:.2f}) {small[5]} vs {big[5]}')
|
|
500
|
+
return count, examples
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
PART_PREFIX = 'BM_part_'
|
|
504
|
+
_PART_NAME = re.compile(r'^[A-Za-z][A-Za-z0-9_]*$')
|
|
505
|
+
MOTIONS = ('spin', 'upright', 'pendulum', 'none')
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
def part(obj: bpy.types.Object, name: str) -> bpy.types.Object:
|
|
509
|
+
"""Mark `obj` as the moving part `name` of a smart prop (export it with `smart=`). A part
|
|
510
|
+
is one object: join its pieces first. Names: letters, digits and _, starting with a letter."""
|
|
511
|
+
if not _PART_NAME.match(name):
|
|
512
|
+
raise ValueError(f'part name {name!r}: letters, digits and _, starting with a letter')
|
|
513
|
+
obj.name = f'{PART_PREFIX}{name}'
|
|
514
|
+
obj.data.name = obj.name
|
|
515
|
+
return obj
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
ANCHOR_PREFIX = 'BM_anchor_'
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
def anchor(obj: bpy.types.Object, name: str, at: Vec) -> bpy.types.Object:
|
|
522
|
+
"""A named point game code will want: a door, an entrance, a seat, a cabin floor. `at` is in
|
|
523
|
+
game coordinates at rest. On a part (after part()) it rides with the part and code finds it as
|
|
524
|
+
`smart.pivotOf(id, 'cabin_3').getObjectByName('BM_anchor_floor')` — every part may reuse the
|
|
525
|
+
same names. On any other exported object it stays put, found on the placed object:
|
|
526
|
+
`getObjectIdService().getObjectById(id).getObjectByName('BM_anchor_door')` — so those names
|
|
527
|
+
must be unique within the prop."""
|
|
528
|
+
if not _PART_NAME.match(name):
|
|
529
|
+
raise ValueError(f'anchor name {name!r}: letters, digits and _, starting with a letter')
|
|
530
|
+
owner = obj.name[len(PART_PREFIX):] if obj.name.startswith(PART_PREFIX) else re.sub(r'[^A-Za-z0-9_]', '_', obj.name)
|
|
531
|
+
empty = bpy.data.objects.new(f'{ANCHOR_PREFIX}{owner}__{name}', None)
|
|
532
|
+
bpy.context.scene.collection.objects.link(empty)
|
|
533
|
+
empty.parent = obj # the part keeps an identity transform, so `at` is also its local position
|
|
534
|
+
empty.location = _to_b(at)
|
|
535
|
+
return empty
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
def _vec(value, what: str) -> dict:
|
|
539
|
+
if not (isinstance(value, (list, tuple)) and len(value) == 3):
|
|
540
|
+
raise ValueError(f'{what} must be (x, y, z)')
|
|
541
|
+
return {'x': float(value[0]), 'y': float(value[1]), 'z': float(value[2])}
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
def _smart_declaration(smart: dict, items: list, lo, hi) -> tuple[dict, list[dict]]:
|
|
545
|
+
"""Validate `smart` against the exported objects; return the GLB's bmSmartObject extras and
|
|
546
|
+
the asset-record light emitters (offsets in the asset frame: bottom-centre origin)."""
|
|
547
|
+
names = {o.name[len(PART_PREFIX):]: o for o in items if o.name.startswith(PART_PREFIX)}
|
|
548
|
+
parts = []
|
|
549
|
+
for p in smart.get('parts', []):
|
|
550
|
+
name = p.get('name')
|
|
551
|
+
if name not in names:
|
|
552
|
+
raise ValueError(f'smart part {name!r} has no object: call part(obj, {name!r}) on one of the exported objects')
|
|
553
|
+
motion = dict(p.get('motion') or {})
|
|
554
|
+
if motion.get('kind') not in MOTIONS:
|
|
555
|
+
raise ValueError(f'smart part {name!r}: motion kind must be one of {MOTIONS}')
|
|
556
|
+
if 'axis' in motion:
|
|
557
|
+
motion['axis'] = [float(v) for v in motion['axis']]
|
|
558
|
+
entry = {'name': name, 'motion': motion}
|
|
559
|
+
if p.get('parent'):
|
|
560
|
+
if p['parent'] not in names:
|
|
561
|
+
raise ValueError(f'smart part {name!r}: parent {p["parent"]!r} is not a part')
|
|
562
|
+
entry['parent'] = p['parent']
|
|
563
|
+
if p.get('pivot') is not None:
|
|
564
|
+
entry['pivot'] = _vec(p['pivot'], f'smart part {name!r} pivot')
|
|
565
|
+
parts.append(entry)
|
|
566
|
+
origin = ((lo[0] + hi[0]) / 2, lo[1], (lo[2] + hi[2]) / 2)
|
|
567
|
+
lights = []
|
|
568
|
+
for i, l in enumerate(smart.get('lights', [])):
|
|
569
|
+
if 'color' not in l:
|
|
570
|
+
raise ValueError('a smart light needs a color')
|
|
571
|
+
where = l.get('position')
|
|
572
|
+
if where is None:
|
|
573
|
+
if l.get('part') not in names:
|
|
574
|
+
raise ValueError('a smart light needs a position, or a part to sit at the centre of')
|
|
575
|
+
plo, phi = bounds(names[l['part']])
|
|
576
|
+
where = tuple((plo[k] + phi[k]) / 2 for k in range(3))
|
|
577
|
+
offset = {'x': where[0] - origin[0], 'y': where[1] - origin[1], 'z': where[2] - origin[2]}
|
|
578
|
+
emitter = {'color': to_hex(to_linear(l['color'])), 'offset': offset}
|
|
579
|
+
for key in ('intensity', 'distance'):
|
|
580
|
+
if key in l:
|
|
581
|
+
emitter[key] = float(l[key])
|
|
582
|
+
if l.get('part'):
|
|
583
|
+
if l['part'] not in names:
|
|
584
|
+
raise ValueError(f'smart light: part {l["part"]!r} is not a part')
|
|
585
|
+
emitter['part'] = l['part']
|
|
586
|
+
lights.append(emitter)
|
|
587
|
+
return {'parts': parts}, lights
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
def export(asset_id: str, objs: Optional[Objects] = None, smart: Optional[dict] = None) -> dict:
|
|
591
|
+
"""Write `objs` (default: every mesh in the scene) as the game asset `asset_id`. An id the game
|
|
592
|
+
already has REPLACES that asset everywhere it is placed; a new id adds one, sized to the
|
|
593
|
+
meshes' real height. Returns {id, targetHeight, triangles}.
|
|
594
|
+
|
|
595
|
+
`smart` makes it a SMART OBJECT the engine animates with no game code:
|
|
596
|
+
{'parts': [{'name': 'wheel', 'motion': {'kind': 'spin', 'axis': (0, 0, 1), 'rpm': 3}},
|
|
597
|
+
{'name': 'cabin_1', 'parent': 'wheel', 'motion': {'kind': 'upright'}}],
|
|
598
|
+
'lights': [{'color': '#ffd27a', 'part': 'cabin_1', 'intensity': 4}]}
|
|
599
|
+
Every part is an exported object marked with part(obj, name). Pivots default to the part's
|
|
600
|
+
box centre (the top centre for upright / pendulum); give 'pivot': (x, y, z) to override."""
|
|
601
|
+
if not _ID.match(asset_id):
|
|
602
|
+
raise ValueError(f'asset id {asset_id!r}: use lowercase letters, digits, - and _')
|
|
603
|
+
if any(e['id'] == asset_id for e in _state['exports']):
|
|
604
|
+
raise ValueError(f'{asset_id!r} was already exported in this script')
|
|
605
|
+
if len(_state['exports']) >= MAX_EXPORTS:
|
|
606
|
+
raise ValueError(f'at most {MAX_EXPORTS} exports per script')
|
|
607
|
+
items = _list(objs) if objs is not None else objects()
|
|
608
|
+
if not items:
|
|
609
|
+
raise ValueError('nothing to export')
|
|
610
|
+
for o in items:
|
|
611
|
+
_colour_layer(o)
|
|
612
|
+
lo, hi = bounds(items)
|
|
613
|
+
overlaps, where = _coplanar_overlaps(items)
|
|
614
|
+
if overlaps:
|
|
615
|
+
print(f'[bmedit] WARNING {asset_id}: {overlaps} overlapping coplanar face pair(s) will FLICKER in the game '
|
|
616
|
+
f'(z-fighting), e.g. at {"; ".join(where)}. Lift the upper surface by at least 1 cm, or make '
|
|
617
|
+
f'the trim not cover the surface under it.')
|
|
618
|
+
extras, lights = _smart_declaration(smart, items, lo, hi) if smart else (None, [])
|
|
619
|
+
scene = bpy.context.scene
|
|
620
|
+
if extras is not None:
|
|
621
|
+
scene['bmSmartObject'] = extras # scene custom properties are the GLB's scene extras
|
|
622
|
+
os.makedirs(_state['out'], exist_ok=True)
|
|
623
|
+
path = os.path.join(_state['out'], f'{asset_id}.glb')
|
|
624
|
+
try:
|
|
625
|
+
anchors = [c for o in items for c in o.children if c.name.startswith(ANCHOR_PREFIX)]
|
|
626
|
+
chosen = items + anchors
|
|
627
|
+
with bpy.context.temp_override(selected_objects=chosen, selected_editable_objects=chosen):
|
|
628
|
+
bpy.ops.object.select_all(action='DESELECT')
|
|
629
|
+
for o in chosen:
|
|
630
|
+
o.select_set(True)
|
|
631
|
+
bpy.ops.export_scene.gltf(
|
|
632
|
+
filepath=path, export_format='GLB', use_selection=True, export_apply=True, export_yup=True,
|
|
633
|
+
export_normals=True, export_vertex_color='ACTIVE', export_lights=False, export_cameras=False,
|
|
634
|
+
export_extras=extras is not None,
|
|
635
|
+
)
|
|
636
|
+
finally:
|
|
637
|
+
if 'bmSmartObject' in scene:
|
|
638
|
+
del scene['bmSmartObject']
|
|
639
|
+
record = {
|
|
640
|
+
'id': asset_id,
|
|
641
|
+
'file': f'{asset_id}.glb',
|
|
642
|
+
'targetHeight': round(max(0.01, hi[1] - lo[1]), 3),
|
|
643
|
+
'triangles': sum(sum(len(p.vertices) - 2 for p in o.data.polygons) for o in items),
|
|
644
|
+
}
|
|
645
|
+
if extras is not None:
|
|
646
|
+
record['smartParts'] = [p['name'] for p in extras['parts']]
|
|
647
|
+
if lights:
|
|
648
|
+
record['lights'] = lights
|
|
649
|
+
_state['exports'].append(record)
|
|
650
|
+
moving = f', smart: {", ".join(record["smartParts"])}' if extras else ''
|
|
651
|
+
print(f'[bmedit] exported {asset_id}: {record["triangles"]} tris, {record["targetHeight"]} m tall{moving}')
|
|
652
|
+
return record
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Colour maths for bmedit, free of bpy so plain python3 tests cover it.
|
|
2
|
+
|
|
3
|
+
Scripts speak sRGB — the numbers a colour picker shows, as `'#d8e4ea'`, `(216, 228, 234)` or
|
|
4
|
+
`(0.85, 0.89, 0.92)`. Blender's float colour attributes and glTF's COLOR_0 are LINEAR, so every
|
|
5
|
+
value is converted once on the way in and back on the way out. Storing sRGB numbers as linear is
|
|
6
|
+
what turned early forged levels pastel.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import Sequence, Union
|
|
11
|
+
|
|
12
|
+
Colour = Union[str, Sequence[float]]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def srgb_to_linear(c: float) -> float:
|
|
16
|
+
return c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def linear_to_srgb(c: float) -> float:
|
|
20
|
+
c = max(0.0, min(1.0, c))
|
|
21
|
+
return c * 12.92 if c <= 0.0031308 else 1.055 * c ** (1 / 2.4) - 0.055
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def parse_srgb(colour: Colour) -> tuple[float, float, float]:
|
|
25
|
+
"""'#rrggbb', 0-255 ints or 0-1 floats → sRGB floats in 0..1."""
|
|
26
|
+
if isinstance(colour, str):
|
|
27
|
+
h = colour.lstrip('#')
|
|
28
|
+
if len(h) == 3:
|
|
29
|
+
h = ''.join(ch * 2 for ch in h)
|
|
30
|
+
if len(h) != 6:
|
|
31
|
+
raise ValueError(f'colour {colour!r} is not #rgb or #rrggbb')
|
|
32
|
+
return (int(h[0:2], 16) / 255, int(h[2:4], 16) / 255, int(h[4:6], 16) / 255)
|
|
33
|
+
values = [float(v) for v in colour][:3]
|
|
34
|
+
if len(values) != 3:
|
|
35
|
+
raise ValueError(f'colour {colour!r} needs three channels')
|
|
36
|
+
if any(v > 1.0 for v in values):
|
|
37
|
+
values = [v / 255 for v in values]
|
|
38
|
+
return (values[0], values[1], values[2])
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def to_linear(colour: Colour) -> tuple[float, float, float, float]:
|
|
42
|
+
r, g, b = parse_srgb(colour)
|
|
43
|
+
return (srgb_to_linear(r), srgb_to_linear(g), srgb_to_linear(b), 1.0)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def to_hex(linear: Sequence[float]) -> str:
|
|
47
|
+
"""A stored linear colour as the sRGB hex a script would write."""
|
|
48
|
+
return '#' + ''.join(f'{round(linear_to_srgb(c) * 255):02x}' for c in linear[:3])
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def distance(a: Colour, b: Colour) -> float:
|
|
52
|
+
"""Distance between two sRGB colours, 0..~1.7; under 0.1 reads as 'the same colour'."""
|
|
53
|
+
pa, pb = parse_srgb(a), parse_srgb(b)
|
|
54
|
+
return sum((x - y) ** 2 for x, y in zip(pa, pb)) ** 0.5
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def mix(a: Colour, b: Colour, t: float) -> tuple[float, float, float]:
|
|
58
|
+
"""sRGB blend of two colours; t=0 is a, t=1 is b."""
|
|
59
|
+
pa, pb = parse_srgb(a), parse_srgb(b)
|
|
60
|
+
t = max(0.0, min(1.0, t))
|
|
61
|
+
return (pa[0] + (pb[0] - pa[0]) * t, pa[1] + (pb[1] - pa[1]) * t, pa[2] + (pb[2] - pa[2]) * t)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Headless review renders of a built level, run inside Blender:
|
|
2
2
|
|
|
3
3
|
"$BLENDER" -b --python tools/blender-level/review.py -- build/level/hut.blend build/level/hut.mesh-level.json build/level/review/
|
|
4
|
-
[--lighting review|game] [--shot 'FROM -> TO']... [--only] [--fov <degrees>]
|
|
4
|
+
[--lighting review|game] [--shot 'FROM -> TO']... [--only] [--fov <degrees>] [--engine eevee|cycles]
|
|
5
5
|
|
|
6
6
|
Opens the .blend (named parts intact) and renders a deterministic set of shots from the level
|
|
7
7
|
JSON — `overview` (top-down), `door-<id>-a/b` (both approaches of every door), `stairs-<name>`
|
|
@@ -18,6 +18,10 @@ is a look at the GEOMETRY. `--lighting game` instead runs the engine's `interior
|
|
|
18
18
|
`lamp()`s and `spot()`s the level JSON declares, so the lighting pass can be judged here rather
|
|
19
19
|
than through a `bitmagic verify`. EEVEE is not three.js — trust "too dark" and "too bright", not
|
|
20
20
|
an exact colour.
|
|
21
|
+
|
|
22
|
+
`--engine cycles` renders with Cycles instead of EEVEE, on the GPU through OptiX or CUDA when
|
|
23
|
+
there is one, else on the CPU. EEVEE needs an OpenGL context, which a headless Linux server with
|
|
24
|
+
only the CUDA driver (no EGL) cannot give it; Cycles in background mode needs none.
|
|
21
25
|
"""
|
|
22
26
|
import json
|
|
23
27
|
import math
|
|
@@ -44,7 +48,7 @@ def flag_values(name: str) -> list[str]:
|
|
|
44
48
|
|
|
45
49
|
# `--shot`, `--lighting` and `--fov` each consume the token after them, which would otherwise read
|
|
46
50
|
# as a positional path.
|
|
47
|
-
consumed = {argv[i + 1] for i, a in enumerate(argv) if a in ('--shot', '--lighting', '--fov') and i + 1 < len(argv)}
|
|
51
|
+
consumed = {argv[i + 1] for i, a in enumerate(argv) if a in ('--shot', '--lighting', '--fov', '--engine') and i + 1 < len(argv)}
|
|
48
52
|
positional = [a for a in positional if a not in consumed]
|
|
49
53
|
if len(positional) < 3:
|
|
50
54
|
print(__doc__)
|
|
@@ -57,6 +61,10 @@ if LIGHTING not in ('review', 'game'):
|
|
|
57
61
|
SHOT_SPECS = flag_values('--shot')
|
|
58
62
|
ONLY = '--only' in argv
|
|
59
63
|
FOV = float(flag_value('--fov')) if flag_value('--fov') else None
|
|
64
|
+
ENGINE = (flag_value('--engine', 'eevee') or 'eevee').lower()
|
|
65
|
+
if ENGINE not in ('eevee', 'cycles'):
|
|
66
|
+
print(f"--engine takes 'eevee' or 'cycles', not {ENGINE!r}")
|
|
67
|
+
sys.exit(2)
|
|
60
68
|
if ONLY and not SHOT_SPECS:
|
|
61
69
|
print('--only needs at least one --shot')
|
|
62
70
|
sys.exit(2)
|
|
@@ -70,10 +78,38 @@ os.makedirs(OUT, exist_ok=True)
|
|
|
70
78
|
|
|
71
79
|
bpy.ops.wm.open_mainfile(filepath=os.path.abspath(BLEND))
|
|
72
80
|
scene = bpy.context.scene
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def use_cycles() -> str:
|
|
84
|
+
"""Cycles on the first GPU backend that has a device (OptiX, then CUDA), else the CPU. Low
|
|
85
|
+
samples plus the denoiser: this is a look at geometry, not a beauty render."""
|
|
86
|
+
scene.render.engine = 'CYCLES'
|
|
87
|
+
prefs = bpy.context.preferences.addons['cycles'].preferences
|
|
88
|
+
backend = 'CPU'
|
|
89
|
+
for kind in ('OPTIX', 'CUDA'):
|
|
90
|
+
try:
|
|
91
|
+
prefs.compute_device_type = kind
|
|
92
|
+
except TypeError: # this Blender build lacks the backend
|
|
93
|
+
continue
|
|
94
|
+
prefs.get_devices()
|
|
95
|
+
if any(d.type == kind for d in prefs.devices):
|
|
96
|
+
for d in prefs.devices:
|
|
97
|
+
d.use = d.type == kind
|
|
98
|
+
backend = kind
|
|
99
|
+
break
|
|
100
|
+
scene.cycles.device = 'CPU' if backend == 'CPU' else 'GPU'
|
|
101
|
+
scene.cycles.samples = 16
|
|
102
|
+
scene.cycles.use_denoising = True
|
|
103
|
+
return backend
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
if ENGINE == 'cycles':
|
|
107
|
+
print(f'ENGINE cycles on {use_cycles()}', flush=True)
|
|
108
|
+
else:
|
|
109
|
+
engines = [e.identifier for e in bpy.types.RenderSettings.bl_rna.properties['engine'].enum_items]
|
|
110
|
+
scene.render.engine = 'BLENDER_EEVEE_NEXT' if 'BLENDER_EEVEE_NEXT' in engines else 'BLENDER_EEVEE'
|
|
111
|
+
if hasattr(scene, 'eevee'):
|
|
112
|
+
scene.eevee.taa_render_samples = 16
|
|
77
113
|
scene.render.resolution_x, scene.render.resolution_y = WIDTH, HEIGHT
|
|
78
114
|
scene.render.resolution_percentage = 100
|
|
79
115
|
scene.render.image_settings.file_format = 'PNG'
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""Headless review renders of GLB assets (bmedit exports), run inside Blender:
|
|
2
|
+
|
|
3
|
+
"$BLENDER" -b --python tools/blender-level/review_asset.py -- <out dir> <a.glb> [<b.glb> ...] [--engine eevee|cycles]
|
|
4
|
+
|
|
5
|
+
Renders each asset alone from two three-quarter angles — front-left and back-right, from above,
|
|
6
|
+
framed to its size — into the output directory, plus `contact-sheet.png` with all of them (two
|
|
7
|
+
columns per asset, in the order given; at most four assets). It is a look at shape and colour:
|
|
8
|
+
a flat sky light and a sun, vertex colours as authored. Blender is not three.js — trust "wrong
|
|
9
|
+
colour family", "too dark", "floating", not an exact shade.
|
|
10
|
+
"""
|
|
11
|
+
import math
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
import bpy
|
|
16
|
+
from mathutils import Vector
|
|
17
|
+
|
|
18
|
+
argv = sys.argv[sys.argv.index('--') + 1:] if '--' in sys.argv else sys.argv[1:]
|
|
19
|
+
ENGINE = argv[argv.index('--engine') + 1].lower() if '--engine' in argv and argv.index('--engine') + 1 < len(argv) else 'eevee'
|
|
20
|
+
positional = [a for a in argv if not a.startswith('--') and a != ENGINE]
|
|
21
|
+
if len(positional) < 2 or ENGINE not in ('eevee', 'cycles'):
|
|
22
|
+
print(__doc__)
|
|
23
|
+
sys.exit(2)
|
|
24
|
+
OUT, GLBS = positional[0], positional[1:5]
|
|
25
|
+
WIDTH, HEIGHT = 640, 480
|
|
26
|
+
os.makedirs(OUT, exist_ok=True)
|
|
27
|
+
|
|
28
|
+
bpy.ops.wm.read_factory_settings(use_empty=True)
|
|
29
|
+
scene = bpy.context.scene
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def use_cycles() -> str:
|
|
33
|
+
"""Cycles on the first GPU backend that has a device (OptiX, then CUDA), else the CPU."""
|
|
34
|
+
scene.render.engine = 'CYCLES'
|
|
35
|
+
prefs = bpy.context.preferences.addons['cycles'].preferences
|
|
36
|
+
backend = 'CPU'
|
|
37
|
+
for kind in ('OPTIX', 'CUDA'):
|
|
38
|
+
try:
|
|
39
|
+
prefs.compute_device_type = kind
|
|
40
|
+
except TypeError:
|
|
41
|
+
continue
|
|
42
|
+
prefs.get_devices()
|
|
43
|
+
if any(d.type == kind for d in prefs.devices):
|
|
44
|
+
for d in prefs.devices:
|
|
45
|
+
d.use = d.type == kind
|
|
46
|
+
backend = kind
|
|
47
|
+
break
|
|
48
|
+
scene.cycles.device = 'CPU' if backend == 'CPU' else 'GPU'
|
|
49
|
+
scene.cycles.samples = 16
|
|
50
|
+
scene.cycles.use_denoising = True
|
|
51
|
+
return backend
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
if ENGINE == 'cycles':
|
|
55
|
+
print(f'ENGINE cycles on {use_cycles()}', flush=True)
|
|
56
|
+
else:
|
|
57
|
+
engines = [e.identifier for e in bpy.types.RenderSettings.bl_rna.properties['engine'].enum_items]
|
|
58
|
+
scene.render.engine = 'BLENDER_EEVEE_NEXT' if 'BLENDER_EEVEE_NEXT' in engines else 'BLENDER_EEVEE'
|
|
59
|
+
if hasattr(scene, 'eevee'):
|
|
60
|
+
scene.eevee.taa_render_samples = 16
|
|
61
|
+
scene.render.resolution_x, scene.render.resolution_y = WIDTH, HEIGHT
|
|
62
|
+
scene.render.resolution_percentage = 100
|
|
63
|
+
scene.render.image_settings.file_format = 'PNG'
|
|
64
|
+
scene.world = bpy.data.worlds.new('review')
|
|
65
|
+
scene.world.use_nodes = True
|
|
66
|
+
bg = scene.world.node_tree.nodes['Background']
|
|
67
|
+
bg.inputs[0].default_value = (0.45, 0.55, 0.7, 1)
|
|
68
|
+
bg.inputs[1].default_value = 0.7
|
|
69
|
+
|
|
70
|
+
cam_data = bpy.data.cameras.new('review')
|
|
71
|
+
cam_data.lens = 35
|
|
72
|
+
cam = bpy.data.objects.new('review', cam_data)
|
|
73
|
+
scene.collection.objects.link(cam)
|
|
74
|
+
scene.camera = cam
|
|
75
|
+
sun_data = bpy.data.lights.new('review-sun', 'SUN')
|
|
76
|
+
sun_data.energy = 3.0
|
|
77
|
+
sun = bpy.data.objects.new('review-sun', sun_data)
|
|
78
|
+
scene.collection.objects.link(sun)
|
|
79
|
+
sun.rotation_euler = (math.radians(45), math.radians(10), math.radians(35))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def load(path: str) -> list:
|
|
83
|
+
before = set(bpy.data.objects)
|
|
84
|
+
bpy.ops.import_scene.gltf(filepath=path)
|
|
85
|
+
return [o for o in bpy.data.objects if o not in before]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def frame(objs: list) -> tuple[Vector, float]:
|
|
89
|
+
pts = [o.matrix_world @ Vector(c) for o in objs if o.type == 'MESH' for c in o.bound_box]
|
|
90
|
+
lo = Vector((min(p.x for p in pts), min(p.y for p in pts), min(p.z for p in pts)))
|
|
91
|
+
hi = Vector((max(p.x for p in pts), max(p.y for p in pts), max(p.z for p in pts)))
|
|
92
|
+
return (lo + hi) / 2, max((hi - lo).length / 2, 0.1)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
paths: list[str] = []
|
|
96
|
+
names: list[str] = []
|
|
97
|
+
for glb in GLBS:
|
|
98
|
+
stem = os.path.splitext(os.path.basename(glb))[0]
|
|
99
|
+
objs = load(glb)
|
|
100
|
+
centre, radius = frame(objs)
|
|
101
|
+
distance = radius / math.tan(math.radians(20)) * 1.1
|
|
102
|
+
# Blender is Z up; the game's +Z forward is Blender's -Y, so "front" looks from -Y.
|
|
103
|
+
for label, yaw in (('front', math.radians(-35)), ('back', math.radians(145))):
|
|
104
|
+
direction = Vector((math.sin(yaw), -math.cos(yaw), 0.55)).normalized()
|
|
105
|
+
cam.location = centre + direction * distance
|
|
106
|
+
cam.rotation_euler = (centre - cam.location).to_track_quat('-Z', 'Y').to_euler()
|
|
107
|
+
cam_data.clip_end = distance * 4
|
|
108
|
+
path = os.path.join(OUT, f'{stem}-{label}.png')
|
|
109
|
+
scene.render.filepath = path
|
|
110
|
+
bpy.ops.render.render(write_still=True)
|
|
111
|
+
paths.append(path)
|
|
112
|
+
names.append(f'{stem}-{label}')
|
|
113
|
+
for o in objs:
|
|
114
|
+
bpy.data.objects.remove(o, do_unlink=True)
|
|
115
|
+
|
|
116
|
+
import numpy as np # Blender bundles numpy # noqa: E402
|
|
117
|
+
|
|
118
|
+
cols = 2
|
|
119
|
+
thumb_w, thumb_h = WIDTH // 2, HEIGHT // 2
|
|
120
|
+
rows = math.ceil(len(paths) / cols)
|
|
121
|
+
sheet = np.zeros((rows * thumb_h, cols * thumb_w, 4), dtype=np.float32)
|
|
122
|
+
sheet[..., 3] = 1
|
|
123
|
+
for i, p in enumerate(paths):
|
|
124
|
+
img = bpy.data.images.load(p)
|
|
125
|
+
px = np.array(img.pixels[:], dtype=np.float32).reshape(img.size[1], img.size[0], 4)
|
|
126
|
+
small = px[::2, ::2][:thumb_h, :thumb_w]
|
|
127
|
+
r, c = divmod(i, cols)
|
|
128
|
+
y0 = (rows - 1 - r) * thumb_h # Blender image rows run bottom-up
|
|
129
|
+
sheet[y0:y0 + small.shape[0], c * thumb_w:c * thumb_w + small.shape[1]] = small
|
|
130
|
+
bpy.data.images.remove(img)
|
|
131
|
+
out_img = bpy.data.images.new('contact', cols * thumb_w, rows * thumb_h, alpha=True)
|
|
132
|
+
out_img.pixels = sheet.ravel().tolist()
|
|
133
|
+
sheet_path = os.path.join(OUT, 'contact-sheet.png')
|
|
134
|
+
out_img.filepath_raw = sheet_path
|
|
135
|
+
out_img.file_format = 'PNG'
|
|
136
|
+
out_img.save()
|
|
137
|
+
order = ', '.join(f'{i + 1}:{n}' for i, n in enumerate(names))
|
|
138
|
+
print(f'CONTACT_SHEET {sheet_path} ({cols} per row, left to right, top to bottom: {order})')
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Blender-free checks of bmedit's colour maths: `python3 -m unittest discover -s tools/blender-level/tests`."""
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import unittest
|
|
5
|
+
|
|
6
|
+
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
|
|
7
|
+
from bmedit.colour import distance, mix, parse_srgb, to_hex, to_linear # noqa: E402
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ColourTest(unittest.TestCase):
|
|
11
|
+
def test_parses_every_spelling_of_a_colour(self):
|
|
12
|
+
self.assertEqual(parse_srgb('#ff8000'), (1.0, 128 / 255, 0.0))
|
|
13
|
+
self.assertEqual(parse_srgb('f80'), (1.0, 136 / 255, 0.0))
|
|
14
|
+
self.assertEqual(parse_srgb((255, 128, 0)), (1.0, 128 / 255, 0.0))
|
|
15
|
+
self.assertEqual(parse_srgb((1.0, 0.5, 0.0)), (1.0, 0.5, 0.0))
|
|
16
|
+
with self.assertRaises(ValueError):
|
|
17
|
+
parse_srgb('#12')
|
|
18
|
+
|
|
19
|
+
def test_stores_linear_and_reads_back_the_same_hex(self):
|
|
20
|
+
# sRGB mid-grey is ~0.214 linear: the stored value must NOT be the picker's 0.5.
|
|
21
|
+
r, g, b, a = to_linear('#808080')
|
|
22
|
+
self.assertAlmostEqual(r, 0.2158, places=3)
|
|
23
|
+
self.assertEqual(a, 1.0)
|
|
24
|
+
for hex_colour in ('#eef3f7', '#3c7524', '#000000', '#ffffff'):
|
|
25
|
+
self.assertEqual(to_hex(to_linear(hex_colour)), hex_colour)
|
|
26
|
+
|
|
27
|
+
def test_distance_and_mix(self):
|
|
28
|
+
self.assertEqual(distance('#ffffff', '#ffffff'), 0.0)
|
|
29
|
+
self.assertLess(distance('#3c7524', '#3d7625'), 0.03)
|
|
30
|
+
self.assertGreater(distance('#3c7524', '#eef3f7'), 0.5)
|
|
31
|
+
self.assertEqual(mix('#000000', '#ffffff', 0.5), (0.5, 0.5, 0.5))
|
|
32
|
+
self.assertEqual(mix('#000000', '#ffffff', 2.0), (1.0, 1.0, 1.0))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == '__main__':
|
|
36
|
+
unittest.main()
|
package/dist/commands/publish.js
CHANGED
|
@@ -49,6 +49,7 @@ import { readVerifyRecord } from '../verify/result.js';
|
|
|
49
49
|
import { readFaviconOverride } from '../publish/favicon.js';
|
|
50
50
|
import { readCategories } from '../publish/categories.js';
|
|
51
51
|
import { readPlatformIndicators } from '../publish/platform.js';
|
|
52
|
+
import { readArtStyleIndicator } from '../publish/art-style.js';
|
|
52
53
|
import { allVerifyScreenshotPaths, verifyArtifactPaths } from '../verify/artifacts.js';
|
|
53
54
|
import { checkVerifyGate, injectMetaBlock } from '../publish/meta-block.js';
|
|
54
55
|
import { ORIGINAL_PROMPT_FLAG } from '../telemetry/creator-prompt.js';
|
|
@@ -328,6 +329,7 @@ export async function runPublish(args, deps = defaultDeps()) {
|
|
|
328
329
|
for (const note of platform.notes)
|
|
329
330
|
log(note);
|
|
330
331
|
const categories = readCategories(context.root);
|
|
332
|
+
const artStyle = readArtStyleIndicator(context.root);
|
|
331
333
|
// `visibility`, `name`, `description`, and `thumbnailUrl` are re-sent EXACTLY as `begin` got
|
|
332
334
|
// them, not implied. `complete` re-authorizes against its OWN body — `begin` writes nothing,
|
|
333
335
|
// so nothing it validated is bound. Sending a DIFFERENT visibility here than `begin` saw
|
|
@@ -363,6 +365,8 @@ export async function runPublish(args, deps = defaultDeps()) {
|
|
|
363
365
|
// ABSENT key means "preserve what is stored" server-side and is a different message from
|
|
364
366
|
// 'desktop'/null; see readPlatformIndicators.
|
|
365
367
|
...platform.fields,
|
|
368
|
+
// The game's medium, same absent-key rule; see readArtStyleIndicator.
|
|
369
|
+
...(artStyle !== undefined ? { artStyle } : {}),
|
|
366
370
|
// Category tags from `worldProfileData.categories`, same absent-key rule: an undeclared
|
|
367
371
|
// set lets the server keep stored tags or AI-classify an untagged game; a declared set
|
|
368
372
|
// (even empty) is the creator's choice and wins. See publish/categories.ts.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ArtStyle } from '@bitmagic/asset-core/art-style';
|
|
2
|
+
/**
|
|
3
|
+
* The `artStyle` a publish syncs to the catalog, in the shape `publish/complete` accepts it.
|
|
4
|
+
*
|
|
5
|
+
* The column is sticky server-side, so `undefined` (omit the key) means "keep what is stored":
|
|
6
|
+
* that is what an unreadable game.json or a value that is neither style sends — a typo must not
|
|
7
|
+
* overwrite a correct stored style. A readable game.json that declares nothing sends `voxel`,
|
|
8
|
+
* because absent there MEANS voxel.
|
|
9
|
+
*/
|
|
10
|
+
export declare function readArtStyleIndicator(root: string): ArtStyle | undefined;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { DEFAULT_ART_STYLE } from '@bitmagic/asset-core/art-style';
|
|
2
|
+
import { readArtStyleDeclaration } from '../project/art-style.js';
|
|
3
|
+
/**
|
|
4
|
+
* The `artStyle` a publish syncs to the catalog, in the shape `publish/complete` accepts it.
|
|
5
|
+
*
|
|
6
|
+
* The column is sticky server-side, so `undefined` (omit the key) means "keep what is stored":
|
|
7
|
+
* that is what an unreadable game.json or a value that is neither style sends — a typo must not
|
|
8
|
+
* overwrite a correct stored style. A readable game.json that declares nothing sends `voxel`,
|
|
9
|
+
* because absent there MEANS voxel.
|
|
10
|
+
*/
|
|
11
|
+
export function readArtStyleIndicator(root) {
|
|
12
|
+
const declaration = readArtStyleDeclaration(root);
|
|
13
|
+
if (!declaration.workCopyReadable || declaration.rejected !== undefined)
|
|
14
|
+
return undefined;
|
|
15
|
+
return declaration.artStyle ?? DEFAULT_ART_STYLE;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=art-style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"art-style.js","sourceRoot":"","sources":["../../src/publish/art-style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAiB,MAAM,gCAAgC,CAAC;AAClF,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAElE;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,MAAM,WAAW,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,WAAW,CAAC,gBAAgB,IAAI,WAAW,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1F,OAAO,WAAW,CAAC,QAAQ,IAAI,iBAAiB,CAAC;AACnD,CAAC"}
|
package/dist/publish/client.d.ts
CHANGED
|
@@ -136,6 +136,12 @@ export interface CompletePublishRequest {
|
|
|
136
136
|
primaryPlatform?: 'desktop' | 'mobile';
|
|
137
137
|
/** `null` clears the stored orientation — the project no longer declares one. */
|
|
138
138
|
mobileOrientation?: 'portrait' | 'landscape' | null;
|
|
139
|
+
/**
|
|
140
|
+
* The project's game.json `artStyle` (absent there = voxel), so the catalog knows the game's
|
|
141
|
+
* medium — an admin-generated cover is drawn in it. Sticky server-side and forward-compatible
|
|
142
|
+
* like the platform fields: absent keeps what is stored, an older server ignores the key.
|
|
143
|
+
*/
|
|
144
|
+
artStyle?: 'voxel' | 'low-poly';
|
|
139
145
|
/**
|
|
140
146
|
* Category tags declared in the project's `worldProfileData.categories` — see
|
|
141
147
|
* `publish/categories.ts` for the three messages (absent / non-empty / explicit empty).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/publish/client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/publish/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -455,6 +455,7 @@ The standard set is what you read first. After that, ask for what you want to se
|
|
|
455
455
|
| \`--fov <deg>\` | horizontal field of view for the perspective shots; default 24 mm ≈ 74° |
|
|
456
456
|
| \`--lighting review\` | default. A camera-mounted fill and a sun, so nothing can hide in shadow |
|
|
457
457
|
| \`--lighting game\` | the engine's \`interior\` preset — the sun at 8%, the hemisphere at 0.65, your \`lamp()\`s and \`spot()\`s as real lights, emissive materials glowing at their \`glow\` |
|
|
458
|
+
| \`--engine cycles\` | render with Cycles (OptiX or CUDA GPU, else CPU) instead of EEVEE — for a headless Linux box where EEVEE fails with no EGL/GLX context |
|
|
458
459
|
|
|
459
460
|
Judge geometry under \`--lighting review\`; judge the lighting pass under \`--lighting game\`. The
|
|
460
461
|
second is close enough to the engine that a room which is black there is black in the game, so
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blender-level-skill-files.js","sourceRoot":"","sources":["../../src/scaffold/blender-level-skill-files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,UAAU,wBAAwB;IACtC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8QR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,iCAAiC;IAC/C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyFR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,OAAO
|
|
1
|
+
{"version":3,"file":"blender-level-skill-files.js","sourceRoot":"","sources":["../../src/scaffold/blender-level-skill-files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,UAAU,wBAAwB;IACtC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8QR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,iCAAiC;IAC/C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyFR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4FR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyER,CAAC;AACF,CAAC;AAED,MAAM,UAAU,mCAAmC;IACjD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgHR,CAAC;AACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitmagic/cli",
|
|
3
|
-
"version": "0.1.71
|
|
3
|
+
"version": "0.1.71",
|
|
4
4
|
"description": "Build Bitmagic games from your own agent tool",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"author": "Bitmagic Oy",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"playwright-core": "^1.59.1",
|
|
26
26
|
"tar": "^7.4.3",
|
|
27
27
|
"ws": "^8.21.3",
|
|
28
|
-
"@bitmagic/
|
|
29
|
-
"@bitmagic/
|
|
30
|
-
"@bitmagic/world-forger": "0.1.31
|
|
28
|
+
"@bitmagic/asset-core": "0.2.26",
|
|
29
|
+
"@bitmagic/animation-forger": "0.1.26",
|
|
30
|
+
"@bitmagic/world-forger": "0.1.31"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@eslint/js": "^9.38.0",
|