¿Qué hace polywright-finish?
Una malla está terminada cuando pasa la verificación de su destino, se ve correcta en un render e importa con el tamaño y la orientación adecuados. Volver al centro: ../polywright/SKILL.md. Detalles de motores: references/engines.md. Cómo crear y finalizar para un motor, paso a paso: references/roblox.md, references/unity.md, references/web-threejs.md. Mallas que se doblan, sombrean y texturizan bien: references/topology.md.
Paso 1: medir, luego decidir
pw.py inspect <archivo> y pw.py check <archivo> --target <t> --real-size-m X. Los fallos indican qué hacer:
demasiados triángulos, sin UVs, demasiados materiales, tamaño incorrecto, bordes abiertos, y para juegos, web y AR, caras
volteadas o apiladas y densidad de UV desigual (inspect --topology; caras volteadas: convert --fix-winding). Renderiza
antes y después de cada paso destructivo (pw.py render).
Paso 2: escala, orientación, pivote
- Tamaño real en metros:
pw.py convert entrada salida --size-m X --ground --center(lado más largo a X; usa una dimensión conocida para formas irregulares). Una puerta mide 2.0 a 2.1 m, un asiento de silla 0.45 m, una mesa 0.75 m, una persona 1.7 a 1.8 m. - Pivote en el centro inferior para accesorios, en la bisagra para puertas, en el eje para ruedas, en la empuñadura para armas.
- Ejes: Blender +Z arriba y el frente mira -Y; glTF +Y arriba y el frente mira +Z; Unreal +Z arriba en centímetros; Unity +Y arriba, sistema zurdo; Roblox +Y arriba, 1 stud = 0.28 m. Prueba una exportación con un cubo de 1 m y una flecha de orientación si tienes dudas.
Paso 3: geometría para el destino
| Necesidad | Haz |
|---|---|
| Menos triángulos, accesorio estático | pw.py convert --max-tris N (la decimación por colapso conserva la silueta); LODs con pw.py lods (aproximadamente la mitad por nivel) |
| Menos triángulos, malla que se dobla | no uses decimación: fusiona bucles donde no se doble nada, mantén los bucles alrededor de las articulaciones (references/topology.md) |
| Cuádruples limpios para deformación o esculpido | remallado voxel primero (lo cierra), luego QuadriFlow (receta en polywright-blender), Instant Meshes, Quad Remesher (de pago), o un remallado cuádruple alojado; personajes: a mano |
| Malla generada (densa, grumosa, bordes suaves) | accesorio estático: decima y vuelve a hornear; héroe o animado: retopología y vuelve a hornear; o regenera con mejores referencias |
| Muchas partes que deberían ser una | --join; para un sólido, pw.py union |
| Colisión | una caja, cápsula o casco convexo por parte; prefijo Unreal UCX_; Roblox CollisionFidelity Box o Hull; nunca uses la malla de render para objetos en movimiento |
Paso 4: UVs y texturas
- UVs:
pw.py convert --uv(Proyecto UV Inteligente) para accesorios; un segundo conjunto sin superposición para lightmaps horneados (receta); densidad de texel consistente en todo un kit; hojas de recorte y atlas para reducir materiales y llamadas de dibujo. - Hornea desde la malla densa a la baja: normal, AO, color (receta
bake-high-to-low). La retopología destruye los UVs, por lo que siempre debes volver a hornear. - PBR metal-rough: metalness 0 o 1, roughness define el aspecto, albedo nunca negro o blanco puro; glTF empaqueta oclusión, roughness, metalness en R, G, B (ORM).
- Mapas de normales: OpenGL (Y+) para Blender, Unity, Godot, glTF, three.js, Roblox; DirectX (Y-) para Unreal. Corrige un desajuste invirtiendo el canal verde. Texturas en potencias de dos; 1024 a 2044 por material para web y AR.
Paso 5: rig (cuando se mueve)
Entrada en pose A, malla manifold limpia. UniRig (MIT, local, 8 GB) o Tripo, Meshy, AccuRIG alojados (pesos humanoides más limpios), Mixamo (humanoides, mejor documentación de retarget). Una comparación de 2026 encontró que el pivote de cadera de Meshy estaba 5 a 15 cm desviado (pies deslizantes) y AccuRIG importa una vez a escala 0.01: verifica escala y pivote después del rigging. Roblox: como máximo 4 influencias de hueso por vértice, raíz en el origen. Un rig de Rigify exporta muchos más huesos que su conjunto deformante (278 de 706 solo con deformación activada): para juegos, construye un esqueleto solo deformante o usa las rutas anteriores.
Clips de animación: inicia y termina cada clip en una de unas pocas poses centrales compartidas para que los clips se encadenen sin transición; el primer fotograma de un bucle es igual al último; decide movimiento de raíz o en el lugar por clip y anótalo; mantén los clips aditivos (apuntar, mirar, inclinarse) como acciones separadas sobre una pose base (Gregory, Game Engine Architecture 2e (2014), sec. 11.6).
Paso 6: exportar y verificar
pw.py convert escribe GLB, FBX, OBJ, USD/USDZ, STL. Por destino:
| Destino | Exportar | Luego |
|---|---|---|
| game-roblox | FBX, OBJ o GLB por MeshPart, menos de 20k triángulos, un material | check --target game-roblox; roblox-agent lo coloca |
| game-unity | GLB (glTFast) o FBX --fbx-bake-axes | prueba de importación en el proyecto (unity-agent) |
| game-unreal | FBX o GLB; Nanite para mallas densas opacas | verificación de escala al importar |
| web-threejs | GLB, luego gltf-transform optimize entrada.glb salida.glb --compress meshopt --texture-compress ktx2 --join-named false | gltf_validator; verificación de página (threewright) |
| ar-usdz | convert entrada.glb salida.usdz | usdchecker --arkit cuando usd-core está instalado |
| video-blockout | GLB o .blend a escala real, además de mesas giratorias y pases de profundidad/normal (recetas) | entrega al plugin de video (cinewright) |
| commerce-gltf | GLB, tamaño real, origen centro inferior, solo triángulos | check --target commerce-gltf |
Suavizado por ángulo es un modificador de Geometry Nodes en Blender 4.1 y posteriores: exporta con los modificadores aplicados, o los
bordes duros aparecerán suavizados (glTF, FBX y OBJ por igual, verificado en 5.2.1). Registra cada salida: pw.py manifest <dir> --add-output out/<archivo> --target <t> --inspect.
Mantenimiento
Unidad perenne, nivel moderate. Compañeros: RESEARCH.md, CHANGELOG.md,
LEARNINGS.md, TESTS.md con evals/evals.json, MAINTENANCE.md,
estado en evergreen.json. Lee evergreen.json en cada uso; actualízalo cuando corresponda.