fix(render): clip walk content to authored portal views
This commit is contained in:
parent
90eba0ec3c
commit
11e68aad82
10 changed files with 408 additions and 78 deletions
|
|
@ -274,23 +274,15 @@ public sealed partial class WbDrawDispatcher
|
|||
Matrix4x4 model = restPose * entity.RootWorld;
|
||||
int selectionPartIndex = unchecked((partIndex << 16) | (setupPartIndex & 0xFFFF));
|
||||
|
||||
if (!PartVisibleInLookInTurn(
|
||||
lookInViews,
|
||||
lookInRouteIndex,
|
||||
lookInCellId,
|
||||
in entity,
|
||||
selectionPartIndex,
|
||||
(uint)gfxObjId,
|
||||
partData,
|
||||
model))
|
||||
{
|
||||
IReadOnlyList<uint>? partClipSlots = ResolvePartClipSlots(
|
||||
lookInViews, lookInRouteIndex, partData, model);
|
||||
if (partClipSlots is { Count: 0 })
|
||||
continue;
|
||||
}
|
||||
|
||||
EmitClassifiedBatches(
|
||||
partData, model, in entity, meshRef, paletteIdentity,
|
||||
entityHasCutoutSubset, slot, lights, indoor, selectionLighting,
|
||||
detailCategory, opacity, batches);
|
||||
detailCategory, opacity, partClipSlots, batches);
|
||||
selectionParts.Add(new WalkClassifiedSelectionPart(
|
||||
entity.ServerGuid, entity.LocalEntityId, selectionPartIndex,
|
||||
(uint)gfxObjId, model));
|
||||
|
|
@ -308,22 +300,14 @@ public sealed partial class WbDrawDispatcher
|
|||
continue;
|
||||
|
||||
Matrix4x4 model = meshRef.PartTransform * entity.RootWorld;
|
||||
if (!PartVisibleInLookInTurn(
|
||||
lookInViews,
|
||||
lookInRouteIndex,
|
||||
lookInCellId,
|
||||
in entity,
|
||||
partIndex,
|
||||
(uint)meshRef.GfxObjId,
|
||||
renderData,
|
||||
model))
|
||||
{
|
||||
IReadOnlyList<uint>? partClipSlots = ResolvePartClipSlots(
|
||||
lookInViews, lookInRouteIndex, renderData, model);
|
||||
if (partClipSlots is { Count: 0 })
|
||||
continue;
|
||||
}
|
||||
EmitClassifiedBatches(
|
||||
renderData, model, in entity, meshRef, paletteIdentity,
|
||||
entityHasCutoutSubsetOverride: null, slot, lights, indoor,
|
||||
selectionLighting, detailCategory, opacity, batches);
|
||||
selectionLighting, detailCategory, opacity, partClipSlots, batches);
|
||||
selectionParts.Add(new WalkClassifiedSelectionPart(
|
||||
entity.ServerGuid, entity.LocalEntityId, partIndex,
|
||||
(uint)meshRef.GfxObjId, model));
|
||||
|
|
@ -379,28 +363,29 @@ public sealed partial class WbDrawDispatcher
|
|||
lights = InstanceLightSet.From(selected);
|
||||
}
|
||||
|
||||
private static bool PartVisibleInLookInTurn(
|
||||
private static IReadOnlyList<uint>? ResolvePartClipSlots(
|
||||
IWalkLookInViewSource? lookInViews,
|
||||
int routeIndex,
|
||||
uint cellId,
|
||||
in RenderInstanceCandidate entity,
|
||||
int partIndex,
|
||||
uint gfxObjId,
|
||||
ObjectRenderData renderData,
|
||||
Matrix4x4 localToWorld)
|
||||
{
|
||||
if (lookInViews is null)
|
||||
return true;
|
||||
return null;
|
||||
if (renderData.SelectionSphere is not { Radius: > 0f } sphere)
|
||||
return true;
|
||||
{
|
||||
return lookInViews.VisibleClipSlotsInLookInTurn(
|
||||
routeIndex,
|
||||
Vector3.Zero,
|
||||
radius: 0f,
|
||||
testSphere: false);
|
||||
}
|
||||
|
||||
return LookInDrawingSphereVisible(
|
||||
lookInViews,
|
||||
TransformDrawingSphere(sphere, localToWorld, out Vector3 center, out float radius);
|
||||
return lookInViews.VisibleClipSlotsInLookInTurn(
|
||||
routeIndex,
|
||||
sphere,
|
||||
localToWorld,
|
||||
out _,
|
||||
out _);
|
||||
in center,
|
||||
radius,
|
||||
testSphere: true);
|
||||
}
|
||||
|
||||
internal static bool LookInDrawingSphereVisible(
|
||||
|
|
@ -414,6 +399,19 @@ public sealed partial class WbDrawDispatcher
|
|||
ArgumentNullException.ThrowIfNull(lookInViews);
|
||||
ArgumentNullException.ThrowIfNull(sphere);
|
||||
|
||||
TransformDrawingSphere(sphere, localToWorld, out center, out radius);
|
||||
return lookInViews.SphereVisibleInLookInTurn(
|
||||
routeIndex,
|
||||
in center,
|
||||
radius);
|
||||
}
|
||||
|
||||
private static void TransformDrawingSphere(
|
||||
DatReaderWriter.Types.Sphere sphere,
|
||||
Matrix4x4 localToWorld,
|
||||
out Vector3 center,
|
||||
out float radius)
|
||||
{
|
||||
center = Vector3.Transform(sphere.Origin, localToWorld);
|
||||
float scaleX = new Vector3(
|
||||
localToWorld.M11,
|
||||
|
|
@ -429,10 +427,6 @@ public sealed partial class WbDrawDispatcher
|
|||
localToWorld.M33).Length();
|
||||
radius = sphere.Radius
|
||||
* MathF.Max(scaleX, MathF.Max(scaleY, scaleZ));
|
||||
return lookInViews.SphereVisibleInLookInTurn(
|
||||
routeIndex,
|
||||
in center,
|
||||
radius);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -454,6 +448,7 @@ public sealed partial class WbDrawDispatcher
|
|||
Vector2 selectionLighting,
|
||||
uint detailCategory,
|
||||
float opacity,
|
||||
IReadOnlyList<uint>? clipSlots,
|
||||
List<WalkClassifiedBatch> sink)
|
||||
{
|
||||
bool entityHasCutoutSubset = entityHasCutoutSubsetOverride ?? renderData.HasCutoutSubset;
|
||||
|
|
@ -466,10 +461,23 @@ public sealed partial class WbDrawDispatcher
|
|||
if (!survives)
|
||||
continue;
|
||||
|
||||
sink.Add(new WalkClassifiedBatch(
|
||||
key, model, slot, lights, indoor ? 1u : 0u, Alpha: opacity,
|
||||
selectionLighting, detailCategory, IsOpaque: IsOpaque(key.Translucency),
|
||||
LocalSortCenter: renderData.SortCenter));
|
||||
if (clipSlots is null)
|
||||
{
|
||||
sink.Add(new WalkClassifiedBatch(
|
||||
key, model, slot, lights, indoor ? 1u : 0u, Alpha: opacity,
|
||||
selectionLighting, detailCategory, IsOpaque: IsOpaque(key.Translucency),
|
||||
LocalSortCenter: renderData.SortCenter));
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int clipIndex = 0; clipIndex < clipSlots.Count; clipIndex++)
|
||||
{
|
||||
sink.Add(new WalkClassifiedBatch(
|
||||
key, model, clipSlots[clipIndex], lights, indoor ? 1u : 0u,
|
||||
Alpha: opacity, selectionLighting, detailCategory,
|
||||
IsOpaque: IsOpaque(key.Translucency),
|
||||
LocalSortCenter: renderData.SortCenter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue