refactor(render): delete the packed dispatcher
This commit is contained in:
parent
8d8aa715ee
commit
73ba1d3c32
7 changed files with 115 additions and 1659 deletions
|
|
@ -2,6 +2,7 @@ using System.Numerics;
|
|||
using AcDream.App.Rendering.Scene;
|
||||
using AcDream.App.Rendering.Selection;
|
||||
using AcDream.App.Rendering.Walk;
|
||||
using AcDream.Core.Lighting;
|
||||
using AcDream.Core.Meshing;
|
||||
using AcDream.Core.World;
|
||||
using DatReaderWriter.Enums;
|
||||
|
|
@ -166,7 +167,7 @@ public sealed partial class WbDrawDispatcher
|
|||
/// Classifies one static entity for the walk populator: resolves its clip
|
||||
/// slot / light set / selection lighting exactly as
|
||||
/// <c>ClassifyPackedEntity</c> does (via the shared
|
||||
/// <see cref="ResolveSlotForFrame"/> / <c>ResolvePackedLightSet</c>
|
||||
/// <see cref="ResolveSlotForFrame"/> / <c>ResolveWalkLightSet</c>
|
||||
/// helpers), walks its Setup parts or single mesh (mirroring
|
||||
/// <c>ClassifyPackedEntity</c>'s own shape), and appends one
|
||||
/// <see cref="WalkClassifiedBatch"/> per surviving batch to
|
||||
|
|
@ -204,7 +205,7 @@ public sealed partial class WbDrawDispatcher
|
|||
if (culled)
|
||||
return;
|
||||
|
||||
ResolvePackedLightSet(in entity, out InstanceLightSet lights, out bool indoor);
|
||||
ResolveWalkLightSet(in entity, out InstanceLightSet lights, out bool indoor);
|
||||
Vector2 selectionLighting =
|
||||
_selectionLighting?.TryGetLighting(
|
||||
entity.ServerGuid, entity.LocalEntityId, out RetailSelectionLighting lighting) == true
|
||||
|
|
@ -261,7 +262,7 @@ public sealed partial class WbDrawDispatcher
|
|||
}
|
||||
|
||||
float opacity = liveDynamic
|
||||
? PackedPartOpacity(
|
||||
? WalkPartOpacity(
|
||||
entity.ServerGuid,
|
||||
entity.LocalEntityId,
|
||||
(uint)setupPartIndex)
|
||||
|
|
@ -298,7 +299,7 @@ public sealed partial class WbDrawDispatcher
|
|||
else
|
||||
{
|
||||
float opacity = liveDynamic
|
||||
? PackedPartOpacity(
|
||||
? WalkPartOpacity(
|
||||
entity.ServerGuid,
|
||||
entity.LocalEntityId,
|
||||
(uint)partIndex)
|
||||
|
|
@ -330,6 +331,110 @@ public sealed partial class WbDrawDispatcher
|
|||
}
|
||||
}
|
||||
|
||||
private float WalkPartOpacity(
|
||||
uint serverGuid,
|
||||
uint localEntityId,
|
||||
uint setupPartIndex)
|
||||
{
|
||||
float opacity = EntityOpacity(serverGuid);
|
||||
if (opacity <= 0f)
|
||||
return 0f;
|
||||
if (!_translucencyFades.TryGetCurrentValue(
|
||||
localEntityId,
|
||||
setupPartIndex,
|
||||
out float translucency))
|
||||
{
|
||||
return opacity;
|
||||
}
|
||||
|
||||
return translucency >= 1f
|
||||
? 0f
|
||||
: opacity * (1f - translucency);
|
||||
}
|
||||
|
||||
private void ResolveWalkLightSet(
|
||||
in RenderInstanceCandidate entity,
|
||||
out InstanceLightSet lights,
|
||||
out bool indoor)
|
||||
{
|
||||
indoor = IndoorObjectReceivesTorches(entity.ParentCell);
|
||||
lights = InstanceLightSet.Disabled;
|
||||
IReadOnlyList<LightSource>? snapshot = _pointSnapshot;
|
||||
if (!indoor || snapshot is null || snapshot.Count == 0)
|
||||
return;
|
||||
|
||||
Vector3 center =
|
||||
(entity.Bounds.Minimum + entity.Bounds.Maximum) * 0.5f;
|
||||
float radius =
|
||||
(entity.Bounds.Maximum - entity.Bounds.Minimum)
|
||||
.Length() * 0.5f;
|
||||
Span<int> selected =
|
||||
stackalloc int[LightManager.MaxLightsPerObject];
|
||||
selected.Fill(-1);
|
||||
LightManager.SelectForObject(
|
||||
snapshot,
|
||||
center,
|
||||
radius,
|
||||
selected);
|
||||
lights = InstanceLightSet.From(selected);
|
||||
}
|
||||
|
||||
private static bool PartVisibleInLookInTurn(
|
||||
IWalkLookInViewSource? lookInViews,
|
||||
int routeIndex,
|
||||
uint cellId,
|
||||
in RenderInstanceCandidate entity,
|
||||
int partIndex,
|
||||
uint gfxObjId,
|
||||
ObjectRenderData renderData,
|
||||
Matrix4x4 localToWorld)
|
||||
{
|
||||
if (lookInViews is null)
|
||||
return true;
|
||||
if (renderData.SelectionSphere is not { Radius: > 0f } sphere)
|
||||
return true;
|
||||
|
||||
return LookInDrawingSphereVisible(
|
||||
lookInViews,
|
||||
routeIndex,
|
||||
sphere,
|
||||
localToWorld,
|
||||
out _,
|
||||
out _);
|
||||
}
|
||||
|
||||
internal static bool LookInDrawingSphereVisible(
|
||||
IWalkLookInViewSource lookInViews,
|
||||
int routeIndex,
|
||||
DatReaderWriter.Types.Sphere sphere,
|
||||
Matrix4x4 localToWorld,
|
||||
out Vector3 center,
|
||||
out float radius)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(lookInViews);
|
||||
ArgumentNullException.ThrowIfNull(sphere);
|
||||
|
||||
center = Vector3.Transform(sphere.Origin, localToWorld);
|
||||
float scaleX = new Vector3(
|
||||
localToWorld.M11,
|
||||
localToWorld.M12,
|
||||
localToWorld.M13).Length();
|
||||
float scaleY = new Vector3(
|
||||
localToWorld.M21,
|
||||
localToWorld.M22,
|
||||
localToWorld.M23).Length();
|
||||
float scaleZ = new Vector3(
|
||||
localToWorld.M31,
|
||||
localToWorld.M32,
|
||||
localToWorld.M33).Length();
|
||||
radius = sphere.Radius
|
||||
* MathF.Max(scaleX, MathF.Max(scaleY, scaleZ));
|
||||
return lookInViews.SphereVisibleInLookInTurn(
|
||||
routeIndex,
|
||||
in center,
|
||||
radius);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Walks one resolved mesh's batches through <see cref="TryClassifyBatch"/>
|
||||
/// and appends every surviving one to <paramref name="sink"/> at
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue