AnimSkin can now write CPU-skinning results back to the render mesh so skeletal animation actually plays from scripts:
- capture bind normals at fromModel and skin them per pose (updateSkinnedNormals / getSkinnedNormals, cofactor inverse-transpose + normalize)
- packed getSkinnedPositions() array getter, matching AnimLattice's script pattern
- one-call applyToMesh(gfx, mesh, pose): skin positions+normals then in-place gpu.updateMeshVertices
- Renderable3D.getMesh() script binding so createRenderable meshes are reachable
- Mesh::gpuVertexCount so getVertexCount() is correct for non-morph meshes (both backends)
- tests: packed positions == skinPositionsTo, normals follow pose and stay unit length, applyToMesh render test with in-place updates
- docs: animation/graphics user guides + design spec
Completes the PBR surface-parameter layer: mesh3d.frag now blends normal / roughness / metallic / emissive (in addition to albedo) from the DecalLayer before lighting; decals are drawn as grouped instanced draws (112B per-instance SSBO, alpha-over non-premultiplied layer, per-decal uvRect/atlas + channel strengths + blend mode API); DecalManager gains frustum + distance culling and setUvRect/setTextures/setBlend; new headless readback readDecalLayerToImageData validates the pass without a swapchain. Fixes two Vulkan validation violations found by the layer (missing vertex/index binds on instanced draws, blend attachmentCount).
Phase 3 of the surface fluid simulation:
- Bingham yield stress in the CPU solver and integrate kernel: effective
viscosity grows as local shear rate drops, so mud piles up and freezes
instead of spreading like water.
- FluidSurfaceRenderer: screen-space fluid rendering pipeline (splat depth+
thickness with atomic min/add, bilateral depth smoothing, view-space normal
reconstruction from depth gradients, water/mud shading), mirrored 1:1 in
FluidSsfKernels.h and driven through the gpgpu compute queue with a CPU
fallback and PPM debug output.
- Script API: Fluids.newSurfaceRenderer + FluidSurface (render/setCamera/
setMode/writePpm).
- Design + usage spec under docs/dev/specs.
- Tests: yield-stress freeze, SSF single-particle depth/normal/thickness,
water-vs-mud shading, GPU SSF pipeline with PPM artifact (17 fluids cases).
Add §17b–§17d API detail tables to docs/dev/测试覆盖.md for map, rpg and
building (all rows now '已展开'), backed by a fresh audit of the existing
70+ map cases, 28 rpg cases and 15 building cases.
Fill the audit gaps with two compact accessor tests:
- map.path.accessorRoundTrips: diagonal, blockEmpty, cellCost getter,
unblockGid/clearBlockedGids, invalidateCache, setBlocked/isWalkable.
- map.fov.accessorRoundTrips: cornerPeek, eyeOffset, cliffBlock,
verticalRange, perceptionRadiusScale, revealerPosition3/perception,
revealer count and unknown-id behavior.
Local win32-debug: map/map_fov/map_path bundles pass.
The blocking-wake path was already covered by event.workerPushWakesWait;
add the queued-message fast path (wait returns immediately). Update
docs/dev/测试覆盖.md §9: wait marked 已覆盖.
Fill the last thread-module API gaps: blocking demand() and cross-thread
postMain() into the Event queue (same-thread, empty-name throw, worker
thread). 46/46 thread bundle cases pass locally on win32-debug. Update
docs/dev/测试覆盖.md: thread row to '已展开' with a full API detail table.