Skip to content

Commit 2175817

Browse files
committed
feat(pipeline): refine master pipeline logic for rigging and animation handling
Enhance the master pipeline to respect the manifest's rigging requirements, ensuring that only rows designated for rigging and animation are processed accordingly. This update introduces checks for rigging and animation profiles, improving the orchestration of asset processing and maintaining compatibility with existing workflows. Additionally, the logic for handling rigging and animation flags has been streamlined for clarity and efficiency.
1 parent 5b4a41d commit 2175817

2 files changed

Lines changed: 14 additions & 3 deletions

File tree

AGENTS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ VibeGame has its own CI workflow in `VibeGame/.github/workflows/` (Bun + TypeScr
380380

381381
- Terreno em exemplos VibeGame pode parecer voxel/escadinha; amostragem de altura/normal com um único ponto tende a falhar — estratégias multi-amostra ou suavização costumam ser necessárias para alinhar props ao chão. Problemas de árvores a flutuar ou enterrar foram atribuídos em grande parte a pivô/origem do GLB no centro do mesh em vez da base; o utilizador espera que a pipeline Text3D/GameAssets posicione a origem na base por omissão, com pivô ao centro só quando explicitamente adequado ao tipo de asset. No recipe `<Terrain>`, muitos campos do componente `Terrain` são configuráveis por atributos XML em kebab-case (defaults do plugin); `collision-resolution` (32/64/128) é aplicado ao `TerrainLOD`/`three-terrain-lod` sem ser sobrescrito pela `resolution` da malha do chunk.
382382
- O comando `gameassets mesh reorigin-feet` repõe a origem de GLBs estáticos nos pés/base; modelos rigged com animação podem precisar de correção de orientação de root (ex. rotação) antes de centrar o pivô — não aplicar só `reorigin-feet` sem validar o resultado.
383+
- O **rigged GLB** tem de herdar a origem/pivô e a orientação do LOD0 (mesh centrada em X/Z, y=0 na sola dos pés, em pé na vertical correta) e o esqueleto tem de estar alinhado e dentro da malha — não rotacionado, não deslocado em Y para fora do mesh. Helpers de debug (ex. icosphere em 0,0,0, eixos visuais) NÃO devem ficar no GLB final exportado pela stage de rig.
383384
- Text3D / Hunyuan3D (marching cubes): saídas costumam ter paredes grossas/duplas e rachas minúsculas; no repair convém merge/manifold e fechar só buracos muito pequenos antes de watertight, para solidificar a caixa sem tratar a abertura grande da base (ex. crate após remover pedestal) como defeito a tapar em bloco. Em `text3d generate`, o `prepare_mesh_topology` aplica por defeito: merge vertices (digits_vertex=5), non-manifold repair (pymeshlab), weld por distância (0.01% diagonal), Taubin smoothing (3 iterações, preserva volume) e isotropic remeshing adaptativo (3 iterações, targetlen=1% diagonal). O CLI tem `simplify-textured` (decimar GLB preservando textura/UV via PyMeshLab quando há material; sem textura cai em decimação quadric clássica) e `align-plus-z` (usa `align_largest_plus_z_face_normal_to_ground` com guarda `--min-height-ratio` para evitar “dobrar” humanoides quando a heurística falha).
384385
- O comando `vibegame run` foi concebido para rebuild/atualização da engine face a exemplos que usam `file:vibegame`; em Windows podem ocorrer falhas de cópia/cache (`ENOENT` no pacote `vibegame`) e é preciso alvo/cwd coerente com a raiz da engine ou exemplo com `dev` ligado à engine.
385386
- Skymap2D e equirect/PMREM: o modelo HF Flux-LoRA-Equirectangular-v3 devolve imagens em resolução errada (1024×768 em vez do pedido 2048×1024) e com os polos ao centro vertical em vez das bordas; Skymap2D `generator.py` faz auto-resize e shift vertical de 50% para corrigir. O `PMREMGenerator` do Three.js ignora `texture.offset`/`repeat` no shader interno — para ajustar UV de texturas equirect antes de `fromEquirectangular()` é necessário manipular o bitmap a nível de píxeis (canvas). Convenção equirect Three.js: `u = atan(dir.z, dir.x)`, `v = asin(dir.y)` — centro da imagem = horizonte, topo = zénite, fundo = nadir. Texturas equirect em **retrato** (altura > largura) ou com eixos trocados podem mapear o azimute ao eixo vertical do bitmap e produzir artefactos tipo «pilares» no céu; convém normalizar para panorama 2:1 em paisagem antes do PMREM quando isso ocorrer.
@@ -394,7 +395,7 @@ VibeGame has its own CI workflow in `VibeGame/.github/workflows/` (Bun + TypeScr
394395

395396
- **Arquitetura de responsabilidades — mesh operations**: O **Text3D** é o único dono de operações de mesh (LOD, collision, simplify, remesh, remesh-textured, `topology-fix`, `bake-master`). O GameAssets NÃO deve conter código de mesh — apenas orquestra subprocessos `text3d`. Não usar `bpy` nem `trimesh` diretamente no GameAssets (o legado `bpy_simplify.py` foi removido). O `text3d lod` preserva armatures/animations — não é necessário um caminho separado para LOD rigged. Transferência de weights rigged HI → LODs é responsabilidade do `rigging3d transfer-weights` (não do Text3D).
396397

397-
- **Master pipeline (`gameassets batch`, agora default)**: DAG canónico em `GameAssets/src/gameassets/pipeline.py` (`run_master_pipeline`) com stages numeradas: (1) `text3d generate` (shape cru), (2) `text3d topology-fix` (clean, inclui `--export-origin feet|center|none` e `--fill-holes-sides N`), (3) paint, (4) `text3d bake-master` (LOD0 com bake de normais + KTX2/meshopt opcionais a partir do high-poly clean), (5–7) LOD1/LOD2/collision, (8) `rigging3d transfer-weights --source HI --target LOD0 --target LOD1 ...`, (9) animate por LOD, (10) `gamedev-lab check glb --category ...`. Intermediários (`shape`, `painted`, `rigged_hi`, `clean`, `normal_map`) são movidos para `_intermediate/` no fim — o `resume` do batch tem de procurar nesses caminhos para não regenerar do zero quando os intermediários já foram arquivados. `GameProfile` tem `master_pipeline`, `master_validate`, `master_bake_normais`; `--legacy-pipeline` força o pipeline antigo. Flag `text3d generate --no-topology-fix` mantém o Stage 1 cru. A correção de orientação/origem Hunyuan3D → OpenGL (rotação que põe o modelo de pé) tem de ser propagada por **todas** as stages; regressão típica é o mesh aparecer "de barriga para cima" já a partir do `_shape`.
398+
- **Master pipeline (`gameassets batch`, agora default)**: DAG canónico em `GameAssets/src/gameassets/pipeline.py` (`run_master_pipeline`) com stages numeradas: (1) `text3d generate` (shape cru), (2) `text3d topology-fix` (clean, inclui `--export-origin feet|center|none` e `--fill-holes-sides N`), (3) paint, (4) `text3d bake-master` (LOD0 com bake de normais + KTX2/meshopt opcionais a partir do high-poly clean), (5–7) LOD1/LOD2/collision, (8) `rigging3d transfer-weights --source HI --target LOD0 --target LOD1 ...`, (9) animate por LOD, (10) `gamedev-lab check glb --category ...`. Intermediários (`shape`, `painted`, `rigged_hi`, `clean`, `normal_map`) são movidos para `_intermediate/` no fim — o `resume` do batch tem de procurar nesses caminhos (ou, melhor ainda, escrever os intermediários diretamente em `_intermediate/` desde o início) para não regenerar do zero quando os intermediários já foram arquivados. `GameProfile` tem `master_pipeline`, `master_validate`, `master_bake_normais`; `--legacy-pipeline` força o pipeline antigo. Flag `text3d generate --no-topology-fix` mantém o Stage 1 cru. A correção de orientação/origem Hunyuan3D → OpenGL (rotação que põe o modelo de pé) tem de ser propagada por **todas** as stages; regressão típica é o mesh aparecer "de barriga para cima" já a partir do `_shape`.
398399

399400
- **Validação GLB — `gamedev-lab check glb`**: usa `GameDevLab/src/gamedev_lab/glb_meta.py` (parser binário do GLB sem `bpy`) para extrair `attributes_present`, `extensions_used`, `texture_mime_types`, `v_per_tri`, `world_bounds_y_min`. Aceita `--category <lod0|lod1|lod2|rigged|collision>` (regras YAML em `GameAssets/src/gameassets/data/rules/*.yaml`) e `--no-bpy-inspect` para correr sem Blender. Regras suportam `mesh_totals.v_per_tri`, `attributes_required`, `texture_format`, `compression`, `origin.y_min`, `face_count.max_per_category`.
400401

GameAssets/src/gameassets/pipeline.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,16 @@ def _post_text3d_mesh_extras(
626626
bake_normals = bool(getattr(profile, "master_bake_normals", False))
627627

628628
if use_master_pipeline:
629+
# Filtragem por-row: respeita ``manifest.pipeline`` (ex.: ``wooden_crate``
630+
# com ``pipeline: [3d, paint, lod, collision]`` não deve correr rig).
631+
# O caminho legacy fazia isto dentro de ``_rigging3d_pipeline_failed``
632+
# via ``_row_wants_rig``; o master pipeline tem de o aplicar aqui.
633+
row_wants_rig = _row_wants_rig(row, has_rigging_profile)
634+
row_wants_animate = _row_wants_animate(row, with_rig, has_rigging_profile)
635+
effective_with_rig = with_rig and row_wants_rig and (rigging3d_bin is not None)
636+
effective_with_animate = (
637+
with_animate and row_wants_animate and (animator3d_bin is not None)
638+
)
629639
mres = run_master_pipeline(
630640
profile,
631641
row,
@@ -634,8 +644,8 @@ def _post_text3d_mesh_extras(
634644
child_env=child_env,
635645
with_lod=with_lod,
636646
with_collision=with_collision,
637-
with_rig=with_rig and (rigging3d_bin is not None),
638-
with_animate=with_animate and (animator3d_bin is not None),
647+
with_rig=effective_with_rig,
648+
with_animate=effective_with_animate,
639649
with_validate=with_validate,
640650
bake_normals=bake_normals,
641651
on_progress_line=on_progress_line,

0 commit comments

Comments
 (0)