axonis22 commited on
Commit
1aa8a1f
·
verified ·
1 Parent(s): c202379

Muse Engine 32 WebGL2 release candidate

Browse files
.gitattributes CHANGED
@@ -34,3 +34,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  assets/khronos-toy-car.glb filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  assets/khronos-toy-car.glb filter=lfs diff=lfs merge=lfs -text
37
+ assets/testpack/kenney-yard-zup-cm.fbx filter=lfs diff=lfs merge=lfs -text
38
+ assets/testpack/swat-biped-max.fbx filter=lfs diff=lfs merge=lfs -text
39
+ assets/testpack/swat-gltf.glb filter=lfs diff=lfs merge=lfs -text
40
+ assets/testpack/swat-maya-zup-cm.fbx filter=lfs diff=lfs merge=lfs -text
assets/testpack/LICENSE-TESTPACK.md ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Test pack licence (Phase 30–32)
2
+
3
+ | File | What it is | Source | Licence |
4
+ |---|---|---|---|
5
+ | `kenney-yard.glb` | "Kenney Yard" test level: glTF 2.0 binary, **metres, +Y up**, no spawn node (tests automatic spawn search) | Built by Grok Bot (coach) in Blender 4.2 LTS with `build_yard.py` from Kenney **Starter Kit FPS** models: `platform-large-grass`, `platform`, `wall-high`, `wall-low`, `grass` (+ their embedded `colormap` texture) | **CC0-1.0** (Kenney's models are CC0; the arrangement is also released as CC0) |
6
+ | `kenney-yard-zup-cm.fbx` | The same level as FBX 7.4 binary exported **Autodesk-style: Z-up, centimetres** (UnitScaleFactor 1 = cm, UpAxis = Z, objects ×100), texture embedded, `PlayerStart` empty at (-600, 600, 60) cm | Same as above | **CC0-1.0** |
7
+ | `build_yard.py` | Blender script that rebuilds both files | Grok Bot (coach) | MIT (this repo) |
8
+ | `swat-gltf.glb` | "SWAT" animated test character (Phase 31): glTF 2.0 binary, **metres, +Y up**, 62-bone skeleton, 4 skinned meshes, 11 clips with **Quaternius-style names** (`Rig|idle_relaxed`, `Rig|Walk_Forward`, `Rig|Jog_Fwd`, `Rig|FireWeapon`, `Rig|Die_Forward`, …) | Rebuilt by Grok Bot (coach) in Blender 4.2 LTS with `build_characters.py` from **Quaternius "SWAT"** (Ultimate Modular Men Pack), downloaded from Poly Pizza https://poly.pizza/m/Btfn3G5Xv4 (file `713f6535-f4f3-4367-a4c6-ced126ae0936.glb`, sha256 `a835107bac833eb916c494e10997ae1709e85957ea6f6c59ace3c9a66f6d1fec`). A subset of the 24 original clips is kept and renamed. | **CC0-1.0** (Poly Pizza page: "Licence: CC0 1.0"; the rebuild is also released as CC0) |
9
+ | `swat-maya-zup-cm.fbx` | The same character as FBX 7.4 binary exported **Autodesk/Maya-style**: **Z-up, centimetres**, animation **baked at 30 fps**, bones in a `Character1:` namespace (`Character1:Hips` …, armature `Character1:Reference`), leaf bones added, **11 takes in one file** with *Mixamo-style names* (`Rifle Idle`, `Walking`, `Rifle Run`, `Firing Rifle`, `Knocked Out` …). "Knocked Out" is deliberately not auto-matched, to test the clip picker. It is only named like Mixamo clips; no Mixamo content is used. | Same as above | **CC0-1.0** |
10
+ | `build_characters.py` | Blender script that rebuilds both character files from the Poly Pizza GLB | Grok Bot (coach) | MIT (this repo) |
11
+ | `swat-biped-max.fbx` | The SWAT character with **3ds Max Biped bone names** (`Bip001`, `Bip001 Pelvis`, `Bip001 L Thigh`, `Bip001 Head`, `…Nub` bones): FBX 7.4 binary, Y-up, 79 bones (over the 60-bone limit on purpose), 5 takes named like a Max export (`Idle_Rifle`, `Walk`, `Run_Rifle`, `Fire_Rifle`, `Death_KnockDown`) | Built by Grok Bot (coach) with Blender 2.79b and `fbx6/build_fbx61.py` from `swat-maya-zup-cm.fbx` (not made in 3ds Max) | CC0-1.0 |
12
+ | `fbx6/props-max-fbx61-ascii.fbx`, `fbx6/props-max-fbx61-bin.fbx`, `fbx6/colormap.png` | A few Kenney Yard props as **FBX 6.1** (version 6100, the 3ds Max 2006–2010 format), ASCII and binary, inches, texture as a side file. Engine 32 answers *Old FBX 6.x: re-export as FBX 2011+ or GLB* | Blender 2.79b FBX 6.1 exporter (`fbx6/build_fbx61.py`), binary by `fbx6/fbx6_ascii_to_binary.py`; texture from the Kenney Starter Kit FPS | CC0-1.0 |
13
+ | `fbx6/build_fbx61.py`, `fbx6/fbx6_ascii_to_binary.py` | Build scripts for the files above | Grok Bot (coach) | MIT (this repo) |
14
+ | `setup-yard-swat.json` | Example Muse Engine setup (Phase 32): Kenney Yard FBX as the level, SWAT FBX as the enemies, *Knocked Out* picked as the death clip. Load it with Tab › Setup › Load setup… or drop it on the game view | Grok Bot (coach) | CC0-1.0 |
15
+ | `muse-engine-32-testpack-cc0.zip` | This whole pack in one download: the model files above (including `swat-biped-max.fbx` and `fbx6/`), `setup-yard-swat.json` and this licence file | Grok Bot (coach) | CC0-1.0 (contents as listed above) |
16
+
17
+ Kenney Starter Kit FPS: https://github.com/KenneyNL/Starter-Kit-FPS (commit 185fd23, March 2026). Its README says: "Assets included in this package (2D sprites, 3D models and sound effects) are CC0 licensed" (https://creativecommons.org/publicdomain/zero/1.0/). The kit's *code* is MIT; no code from it is used here.
18
+ Quaternius released the Ultimate Modular Men Pack (February 2022) as "Free to use in any project, even commercially! (CC0)" (Patreon post https://www.patreon.com/quaternius/posts/ultimate-modular-62873637; pack page https://quaternius.com/packs/ultimatemodularcharacters.html). Poly Pizza lists the pack as "Licence: Public Domain (CC0)" and the SWAT model as "Licence: CC0 1.0", Animated (checked 27 Sep 2026).
19
+ Credit is not required under CC0, but thanks go to **Kenney (www.kenney.nl)** and **Quaternius (quaternius.com)**.
20
+
21
+
22
+ No Autodesk sample files and no Mixamo content are used anywhere in this project.
assets/testpack/build_characters.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # [e31 coach] Builds the Phase 31 test characters from Quaternius "SWAT" (Ultimate Modular Men Pack, CC0 1.0) in Blender 4.2 (headless).
2
+ # Source: https://poly.pizza/m/Btfn3G5Xv4 (GLB https://static.poly.pizza/713f6535-f4f3-4367-a4c6-ced126ae0936.glb)
3
+ # Outputs:
4
+ # swat-gltf.glb glTF: metres, Y-up, 24 fps, game-style clip names ("Rig|IDLE_RIFLE", "Rig|Jog_Fwd", ...)
5
+ # swat-maya-zup-cm.fbx FBX: centimetres, Z-up, 30 fps bake, Autodesk/Mixamo-style: bones namespaced "Character1:Hips",
6
+ # several takes in one file ("Rifle Idle", "Walking", ...), death deliberately named "Knocked Out"
7
+ # (not auto-mapped -> exercised through the panel clip picker).
8
+ import bpy, sys, os
9
+ args = sys.argv[sys.argv.index('--') + 1:]
10
+ SRC, OUT = args[0], args[1]
11
+ bpy.ops.wm.read_factory_settings(use_empty=True)
12
+ bpy.ops.import_scene.gltf(filepath=SRC)
13
+ arm = next(o for o in bpy.data.objects if o.type == 'ARMATURE')
14
+ for o in list(bpy.data.objects): # the glTF importer's bone-display icosphere (not part of the asset)
15
+ if o.type == 'MESH' and o.parent is None: bpy.data.objects.remove(o, do_unlink=True)
16
+ KEEP = { # source action stem -> (GLB name, FBX take name)
17
+ 'Idle_Gun': ('Rig|IDLE_RIFLE', 'Rifle Idle'),
18
+ 'Idle_Neutral': ('Rig|idle_relaxed', 'Neutral Idle'),
19
+ 'Walk': ('Rig|Walk_Forward', 'Walking'),
20
+ 'Run': ('Rig|Jog_Fwd', 'Rifle Run'),
21
+ 'Run_Back': ('Rig|Jog_Back', 'Run Backwards'),
22
+ 'Run_Left': ('Rig|Jog_Left', 'Strafe Left'),
23
+ 'Gun_Shoot': ('Rig|FireWeapon', 'Firing Rifle'),
24
+ 'Run_Shoot': ('Rig|Jog_Fire', 'Run And Shoot'),
25
+ 'Death': ('Rig|Die_Forward', 'Knocked Out'),
26
+ 'HitRecieve': ('Rig|HitReact', 'Hit Reaction'),
27
+ 'Wave': ('Rig|Wave', 'Waving'),
28
+ }
29
+ acts = {}
30
+ for a in list(bpy.data.actions):
31
+ stem = a.name.split('|', 1)[-1].replace('_CharacterArmature', '')
32
+ if stem in KEEP: acts[stem] = a; a.use_fake_user = True
33
+ else: bpy.data.actions.remove(a)
34
+ assert len(acts) == len(KEEP), sorted(acts)
35
+ arm.animation_data_create()
36
+ def push_all(names):
37
+ ad = arm.animation_data
38
+ for t in list(ad.nla_tracks): ad.nla_tracks.remove(t)
39
+ ad.action = None
40
+ for stem, a in acts.items(): a.name = names[stem]
41
+ os.makedirs(OUT, exist_ok=True)
42
+ # ---- GLB (metres, Y-up, 24 fps) ----
43
+ push_all({k: v[0] for k, v in KEEP.items()})
44
+ bpy.context.scene.render.fps = 24
45
+ bpy.ops.export_scene.gltf(filepath=os.path.join(OUT, 'swat-gltf.glb'), export_format='GLB', export_yup=True,
46
+ export_animations=True, export_animation_mode='ACTIONS', export_force_sampling=True,
47
+ export_skins=True, export_all_influences=False)
48
+ print('GLB_DONE')
49
+ # ---- FBX (cm, Z-up, 30 fps, Autodesk-style names) ----
50
+ push_all({k: v[1] for k, v in KEEP.items()})
51
+ NS = 'Character1:'
52
+ old = [b.name for b in arm.data.bones]
53
+ for a in acts.values(): # rewrite fcurve paths for every take (not only the active one)
54
+ for fc in a.fcurves:
55
+ for n in old:
56
+ p = 'pose.bones["%s"]' % n
57
+ if fc.data_path.startswith(p): fc.data_path = fc.data_path.replace(p, 'pose.bones["%s%s"]' % (NS, n), 1); break
58
+ if fc.group and not fc.group.name.startswith(NS) and fc.group.name in old: fc.group.name = NS + fc.group.name
59
+ for b in arm.data.bones: b.name = NS + b.name # vertex groups follow the rename
60
+ for o in bpy.data.objects:
61
+ if o.type == 'MESH':
62
+ for vg in o.vertex_groups:
63
+ if vg.name in old: vg.name = NS + vg.name
64
+ o.name = NS + o.name.replace('Swat_', '') + '_Geo'
65
+ arm.name = 'Character1:Reference'
66
+ f = 30.0 / 24.0 # 24 fps source keys re-timed onto a 30 fps bake (same durations)
67
+ for a in acts.values():
68
+ for fc in a.fcurves:
69
+ for k in fc.keyframe_points:
70
+ k.co.x *= f; k.handle_left.x *= f; k.handle_right.x *= f
71
+ bpy.context.scene.render.fps = 30
72
+ bpy.context.scene.unit_settings.system = 'METRIC'
73
+ bpy.context.scene.unit_settings.scale_length = 0.01 # 1 Blender unit = 1 cm
74
+ arm.scale = tuple(v * 100 for v in arm.scale) # Autodesk-typical: rig in cm (the source rig already carries a x100 root scale)
75
+ bpy.ops.export_scene.fbx(filepath=os.path.join(OUT, 'swat-maya-zup-cm.fbx'), axis_up='Z', axis_forward='Y',
76
+ apply_unit_scale=True, apply_scale_options='FBX_SCALE_UNITS', global_scale=1.0, bake_space_transform=False,
77
+ object_types={'ARMATURE', 'MESH'}, use_armature_deform_only=False, add_leaf_bones=True,
78
+ bake_anim=True, bake_anim_use_all_actions=True, bake_anim_use_nla_strips=False, bake_anim_step=1.0,
79
+ bake_anim_simplify_factor=0.0, bake_anim_force_startend_keying=True,
80
+ path_mode='COPY', embed_textures=True)
81
+ print('FBX_DONE', len(arm.data.bones), 'bones', len(acts), 'takes')
assets/testpack/build_yard.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # [e30 coach] Builds the Phase 30 test scene "Kenney Yard" from Kenney Starter Kit FPS models (CC0) in Blender 4.2 (headless).
2
+ # Outputs: kenney-yard.glb (glTF: metres, Y-up) and kenney-yard-zup-cm.fbx (FBX: centimetres, Z-up, embedded texture)
3
+ import bpy, math, sys, os
4
+ M = os.path.join(os.environ.get('KENNEY_FPS_MODELS', 'Starter-Kit-FPS/models'), '') # [e32] clone https://github.com/KenneyNL/Starter-Kit-FPS (models are CC0)
5
+ OUT = sys.argv[sys.argv.index('--') + 1]
6
+ bpy.ops.wm.read_factory_settings(use_empty=True)
7
+ src = {}
8
+ def load(name):
9
+ before = set(bpy.data.objects)
10
+ bpy.ops.import_scene.gltf(filepath=M + name + '.glb')
11
+ new = [o for o in bpy.data.objects if o not in before and o.type == 'MESH']
12
+ o = new[0]
13
+ for x in new[1:]: pass
14
+ o.name = 'SRC_' + name; o.hide_render = True
15
+ src[name] = o
16
+ for n in ['platform-large-grass', 'platform', 'wall-high', 'wall-low', 'grass']: load(n)
17
+ col = bpy.data.collections.new('Yard'); bpy.context.scene.collection.children.link(col)
18
+ count = {}
19
+ def put(name, x, y, z=0.0, rz=0.0, label=None):
20
+ s = src[name]; o = bpy.data.objects.new((label or name) + '_%d' % count.setdefault(name, 0), s.data)
21
+ count[name] += 1
22
+ o.location = (x, y, z); o.rotation_euler = (0, 0, math.radians(rz)); col.objects.link(o); return o
23
+ # ground: 4x4 large grass tiles (5.2 m), top surface at z=0.5
24
+ for i in range(4):
25
+ for j in range(4):
26
+ put('platform-large-grass', -7.8 + i * 5.2, -7.8 + j * 5.2, 0.0)
27
+ # perimeter wall-high (1.5 m wide) along the four edges, standing on the ground
28
+ edge = 10.1
29
+ k = 0
30
+ x = -9.6
31
+ while x <= 9.7:
32
+ put('wall-high', x, -edge, 0.5, 0); put('wall-high', x, edge, 0.5, 180)
33
+ put('wall-high', -edge, x, 0.5, 90); put('wall-high', edge, x, 0.5, -90)
34
+ x += 1.5
35
+ # stairs: platforms stacked, each rise 0.5 m (<= engine step 0.55)
36
+ for s_, (px, py) in enumerate([(4.0, 2.0), (4.0, -0.2), (4.0, -2.4)]):
37
+ for h in range(s_ + 1):
38
+ put('platform', px, py, 0.5 + h * 0.5)
39
+ # raised deck at the top of the stairs (top at 2.0 m)
40
+ for (px, py) in [(6.2, -2.4), (6.2, -4.6), (4.0, -4.6)]:
41
+ for h in range(3):
42
+ put('platform', px, py, 0.5 + h * 0.5)
43
+ # low walls (0.8 m: mantle height) and a high wall maze piece
44
+ put('wall-low', -3.0, 3.0, 0.5, 0); put('wall-low', -5.2, 3.0, 0.5, 0)
45
+ put('wall-high', -3.0, -3.0, 0.5, 90); put('wall-high', -3.0, -4.5, 0.5, 90); put('wall-high', -3.0, -6.0, 0.5, 90)
46
+ for (gx, gy) in [(-6, 6), (-1, 7), (2, 5), (7, 7), (-7, -1), (1, -7)]:
47
+ put('grass', gx, gy, 0.5)
48
+ for o in list(src.values()): bpy.data.objects.remove(o, do_unlink=True)
49
+ os.makedirs(OUT, exist_ok=True)
50
+ # GLB: metres, +Y up (glTF convention)
51
+ bpy.ops.export_scene.gltf(filepath=os.path.join(OUT, 'kenney-yard.glb'), export_format='GLB', export_yup=True, export_apply=True)
52
+ # FBX "Autodesk-style": centimetres + Z-up (3ds Max / Maya Z-up workflow), texture embedded
53
+ bpy.context.scene.unit_settings.system = 'METRIC'
54
+ bpy.context.scene.unit_settings.scale_length = 0.01 # 1 Blender unit = 1 cm
55
+ for o in col.objects:
56
+ o.location = (o.location[0] * 100, o.location[1] * 100, o.location[2] * 100)
57
+ o.scale = (100, 100, 100)
58
+ spawn = bpy.data.objects.new('PlayerStart', None); spawn.location = (-600, 600, 60); col.objects.link(spawn)
59
+ bpy.ops.export_scene.fbx(filepath=os.path.join(OUT, 'kenney-yard-zup-cm.fbx'), axis_up='Z', axis_forward='Y',
60
+ apply_unit_scale=True, apply_scale_options='FBX_SCALE_UNITS', global_scale=1.0, bake_space_transform=False,
61
+ object_types={'MESH', 'EMPTY'}, path_mode='COPY', embed_textures=True, use_mesh_modifiers=True)
62
+ print('YARD_DONE', len(col.objects), 'objects')
assets/testpack/kenney-yard-zup-cm.fbx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d63996d10efa30dd0d4fe44ab0af3e8f22b7b1b54693bca889c781ce4c474bd0
3
+ size 133484
assets/testpack/kenney-yard.glb ADDED
Binary file (74.5 kB). View file
 
assets/testpack/muse-engine-32-testpack-cc0.zip ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0d9e925e452c340530a3779d5cb5c5f48012c9c1953ed94e3944d7b6a8a7ad0e
3
+ size 2660409
assets/testpack/setup-yard-swat.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "kind": "muse-engine-setup",
3
+ "version": 1,
4
+ "engine": "e32-rc-1",
5
+ "savedAt": "2026-09-27T05:00:00.000Z",
6
+ "look": "A",
7
+ "config": {
8
+ "importDog": true,
9
+ "stripRootMotion": true
10
+ },
11
+ "scene": {
12
+ "name": "kenney-yard-zup-cm.fbx",
13
+ "source": "url",
14
+ "url": "assets/testpack/kenney-yard-zup-cm.fbx",
15
+ "asLevel": true,
16
+ "units": "auto",
17
+ "up": "auto"
18
+ },
19
+ "character": {
20
+ "name": "swat-maya-zup-cm.fbx",
21
+ "source": "url",
22
+ "url": "assets/testpack/swat-maya-zup-cm.fbx",
23
+ "units": "auto",
24
+ "up": "auto",
25
+ "facing": "+z",
26
+ "clipPicks": {
27
+ "death": "Character1:Reference|Knocked Out"
28
+ }
29
+ }
30
+ }
assets/testpack/swat-biped-max.fbx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:61621dc5287f7f71435a28b113f70376024a4b0260a950ec84188e849dc3bbbb
3
+ size 2831036
assets/testpack/swat-gltf.glb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bdf5bdd234d0e7450e470130570b8a23fd3bfd3636cf1d7212186d966f425e20
3
+ size 1420392
assets/testpack/swat-maya-zup-cm.fbx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ac503490ba7b465ea69729af8581e33b4f964550e57d256aee60636477d3ed60
3
+ size 5900428