refactor(render): move look-in dynamics onto walk turns

This commit is contained in:
Erik 2026-08-31 03:39:03 +02:00
parent 966836895f
commit f9a80fbc44
9 changed files with 190 additions and 113 deletions

View file

@ -1,6 +1,7 @@
using System.Numerics;
using AcDream.App.Rendering.Scene;
using AcDream.App.Rendering.Selection;
using AcDream.App.Rendering.Walk;
using AcDream.Core.Meshing;
using AcDream.Core.World;
using DatReaderWriter.Enums;
@ -182,13 +183,20 @@ public sealed partial class WbDrawDispatcher
in RenderProjectionRecord projection,
uint tupleLandblockId,
List<WalkClassifiedBatch> batches,
List<WalkClassifiedSelectionPart> selectionParts)
List<WalkClassifiedSelectionPart> selectionParts,
bool liveDynamic = false,
IWalkLookInViewSource? lookInViews = null,
int lookInRouteIndex = -1,
uint lookInCellId = 0)
{
ArgumentNullException.ThrowIfNull(batches);
ArgumentNullException.ThrowIfNull(selectionParts);
RenderInstanceCandidate entity =
RenderInstanceCandidate.FromProjection(in projection, tupleLandblockId);
RenderInstanceCandidate.FromProjection(
in projection,
tupleLandblockId,
animated: liveDynamic);
(uint slot, bool culled) = ResolveSlotForFrame(
_clipRoutingActive, entity.ServerGuid, entity.ParentCell,
@ -217,7 +225,11 @@ public sealed partial class WbDrawDispatcher
MeshRef meshRef = meshRefs[partIndex];
ObjectRenderData? renderData = _meshAdapter.TryGetRenderData(meshRef.GfxObjId);
if (renderData is null)
{
if (_missRequested.Add(meshRef.GfxObjId))
_meshAdapter.EnsureLoaded(meshRef.GfxObjId);
continue;
}
if (renderData.IsSetup && renderData.SetupParts.Count > 0)
{
@ -236,16 +248,42 @@ public sealed partial class WbDrawDispatcher
(ulong gfxObjId, Matrix4x4 partTransform) = renderData.SetupParts[setupPartIndex];
ObjectRenderData? partData = _meshAdapter.TryGetRenderData(gfxObjId);
if (partData is null)
{
if (_missRequested.Add(gfxObjId))
_meshAdapter.EnsureLoaded(gfxObjId);
continue;
}
float opacity = liveDynamic
? PackedPartOpacity(
entity.ServerGuid,
entity.LocalEntityId,
(uint)setupPartIndex)
: 1f;
if (opacity <= 0f)
continue;
Matrix4x4 restPose = partTransform * meshRef.PartTransform;
Matrix4x4 model = restPose * entity.RootWorld;
int selectionPartIndex = unchecked((partIndex << 16) | (setupPartIndex & 0xFFFF));
if (!PartVisibleInLookInTurn(
lookInViews,
lookInRouteIndex,
lookInCellId,
in entity,
selectionPartIndex,
(uint)gfxObjId,
partData,
model))
{
continue;
}
EmitClassifiedBatches(
partData, model, in entity, meshRef, paletteIdentity,
entityHasCutoutSubset, slot, lights, indoor, selectionLighting,
detailCategory, batches);
detailCategory, opacity, batches);
selectionParts.Add(new WalkClassifiedSelectionPart(
entity.ServerGuid, entity.LocalEntityId, selectionPartIndex,
(uint)gfxObjId, model));
@ -253,11 +291,32 @@ public sealed partial class WbDrawDispatcher
}
else
{
float opacity = liveDynamic
? PackedPartOpacity(
entity.ServerGuid,
entity.LocalEntityId,
(uint)partIndex)
: 1f;
if (opacity <= 0f)
continue;
Matrix4x4 model = meshRef.PartTransform * entity.RootWorld;
if (!PartVisibleInLookInTurn(
lookInViews,
lookInRouteIndex,
lookInCellId,
in entity,
partIndex,
(uint)meshRef.GfxObjId,
renderData,
model))
{
continue;
}
EmitClassifiedBatches(
renderData, model, in entity, meshRef, paletteIdentity,
entityHasCutoutSubsetOverride: null, slot, lights, indoor,
selectionLighting, detailCategory, batches);
selectionLighting, detailCategory, opacity, batches);
selectionParts.Add(new WalkClassifiedSelectionPart(
entity.ServerGuid, entity.LocalEntityId, partIndex,
(uint)meshRef.GfxObjId, model));
@ -283,6 +342,7 @@ public sealed partial class WbDrawDispatcher
bool indoor,
Vector2 selectionLighting,
uint detailCategory,
float opacity,
List<WalkClassifiedBatch> sink)
{
bool entityHasCutoutSubset = entityHasCutoutSubsetOverride ?? renderData.HasCutoutSubset;
@ -290,13 +350,13 @@ public sealed partial class WbDrawDispatcher
{
bool survives = TryClassifyBatch(
renderData, batchIdx, in entity, meshRef, paletteIdentity,
opacityMultiplier: 1.0f, entityHasCutoutSubset,
opacityMultiplier: opacity, entityHasCutoutSubset,
out GroupKey key, out _);
if (!survives)
continue;
sink.Add(new WalkClassifiedBatch(
key, model, slot, lights, indoor ? 1u : 0u, Alpha: 1f,
key, model, slot, lights, indoor ? 1u : 0u, Alpha: opacity,
selectionLighting, detailCategory, IsOpaque: IsOpaque(key.Translucency),
LocalSortCenter: renderData.SortCenter));
}