Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Destroy out of range scene entities #2808

Draft
wants to merge 2 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,27 +1,12 @@
using DCL.CharacterCamera;
using ECS.Prioritization.Components;
using System;
using Unity.Burst;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
using static Utility.ParcelMathHelper;

namespace ECS.Prioritization
{
public static class ScenesPartitioningUtils
{
public struct PartitionData
{
public bool IsDirty;
public byte Bucket;
public bool IsBehind;
public bool OutOfRange;
public float RawSqrDistance;
}

public static bool TryUpdateCameraTransformOnChanged(PartitionDiscreteDataBase partitionDiscreteData, in CameraComponent cameraComponent,
float sqrPositionTolerance, float angleTolerance)
{
Expand All @@ -43,103 +28,5 @@ public static bool TryUpdateCameraTransformOnChanged(PartitionDiscreteDataBase p

return partitionDiscreteData.IsDirty;
}

public struct ParcelCornersData : IDisposable
{
public NativeArray<ParcelCorners> Corners;

public ParcelCornersData(in NativeArray<ParcelCorners> corners)
{
Corners = corners;
}

public void Dispose()
{
Corners.Dispose();
}
}

[BurstCompile]
public struct ScenePartitionParallelJob : IJobParallelFor
{
public float3 CameraPosition;
public float3 CameraForward;
public float UnloadingSqrDistance;
[ReadOnly] public NativeArray<int> SqrDistanceBuckets;
[ReadOnly] public UnsafeList<ParcelCornersData> ParcelCorners;
private NativeArray<PartitionData> partitions;

public ScenePartitionParallelJob(NativeArray<PartitionData> partitions)
{
this.partitions = partitions;
ParcelCorners = default(UnsafeList<ParcelCornersData>);
CameraPosition = default;
CameraForward = default;
SqrDistanceBuckets = default(NativeArray<int>);
UnloadingSqrDistance = default;
}

public void Execute(int index)
{
ParcelCornersData corners = ParcelCorners[index];
PartitionData partition = partitions[index];
byte bucket = partition.Bucket;
bool isBehind = partition.IsBehind;

// Find the closest scene parcel
// The Y component can be safely ignored as all plots are allocated on one plane

// Is Behind must be calculated for each parcel the scene contains
partition.IsBehind = true;

float minSqrMagnitude = float.MaxValue;

for (var i = 0; i < corners.Corners.Length; i++)
{
void ProcessCorners(float3 corner, ref PartitionData partitionData, ref float3 position, ref float3 forward)
{
Vector3 vectorToCamera = corner - position;
vectorToCamera.y = 0; // ignore Y
float sqr = vectorToCamera.sqrMagnitude;

if (sqr < minSqrMagnitude)
minSqrMagnitude = sqr;

// partition is not behind if at least one corner is not behind
if (partitionData.IsBehind)
partitionData.IsBehind = Vector3.Dot(forward, vectorToCamera) < 0;
}

ParcelCorners corners1 = corners.Corners[i];
ProcessCorners(corners1.minXZ, ref partition, ref CameraPosition, ref CameraForward);
ProcessCorners(corners1.minXmaxZ, ref partition, ref CameraPosition, ref CameraForward);
ProcessCorners(corners1.maxXminZ, ref partition, ref CameraPosition, ref CameraForward);
ProcessCorners(corners1.maxXZ, ref partition, ref CameraPosition, ref CameraForward);
}

// Find the bucket
byte bucketIndex;

for (bucketIndex = 0; bucketIndex < SqrDistanceBuckets.Length; bucketIndex++)
{
if (minSqrMagnitude < SqrDistanceBuckets[bucketIndex])
break;
}

partition.Bucket = bucketIndex;

// Is behind is a dot product
// mind that taking cosines is not cheap
// the same scene is counted as InFront
// If the bucket exceeds the maximum bucket array, we need to mark partition as dirty since we are out of range
partition.IsDirty = partition.Bucket != bucket || partition.IsBehind != isBehind || bucketIndex == SqrDistanceBuckets.Length || partition.RawSqrDistance == -1;
partition.OutOfRange = minSqrMagnitude > UnloadingSqrDistance;

if (partition.IsDirty)
partition.RawSqrDistance = minSqrMagnitude;

partitions[index] = partition;
}
}
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,24 @@ public struct SceneDefinitionComponent
{
public SceneEntityDefinition Definition { get; }
public IReadOnlyList<Vector2Int> Parcels { get; }
public IReadOnlyList<ParcelMathHelper.ParcelCorners> ParcelsCorners { get; }
public IpfsPath IpfsPath { get; }
public bool IsEmpty { get; }
public bool IsSDK7 { get; }
public ParcelMathHelper.SceneGeometry SceneGeometry { get; }
public bool IsPortableExperience { get; }

public int InternalJobIndex { get; set; }

public SceneDefinitionComponent(
SceneEntityDefinition definition,
IReadOnlyList<Vector2Int> parcels,
IReadOnlyList<ParcelMathHelper.ParcelCorners> parcelsCorners,
ParcelMathHelper.SceneGeometry sceneGeometry,
IpfsPath ipfsPath, bool isEmpty, bool isSDK7, bool isPortableExperience)
{
Definition = definition;
Parcels = parcels;
ParcelsCorners = parcelsCorners;
IpfsPath = ipfsPath;
IsEmpty = isEmpty;
IsSDK7 = isSDK7;
SceneGeometry = sceneGeometry;
InternalJobIndex = -1;
IsPortableExperience = isPortableExperience;
}
}
Expand All @@ -56,8 +50,6 @@ public static class SceneDefinitionComponentFactory
minZ: -PORTABLE_EXPERIENCE_MAX_VALUES,
maxZ: PORTABLE_EXPERIENCE_MAX_VALUES),
PORTABLE_EXPERIENCE_MAX_HEIGHT);
//PX don't care about parcel corners as they work on all the map.
private static readonly IReadOnlyList<ParcelMathHelper.ParcelCorners> PORTABLE_EXPERIENCES_PARCEL_CORNERS = new List<ParcelMathHelper.ParcelCorners>();

public static SceneDefinitionComponent CreateFromDefinition(SceneEntityDefinition definition, IpfsPath ipfsPath, bool isPortableExperience = false) =>
isPortableExperience ?
Expand All @@ -68,7 +60,6 @@ private static SceneDefinitionComponent CreatePortableExperienceSceneDefinitionC
new (
definition,
parcels: definition.metadata.scene.DecodedParcels,
PORTABLE_EXPERIENCES_PARCEL_CORNERS,
PORTABLE_EXPERIENCES_SCENE_GEOMETRY,
ipfsPath,
isEmpty: false,
Expand Down Expand Up @@ -112,13 +103,12 @@ private static SceneDefinitionComponent CreateSceneDefinitionComponent(
bool isSDK7,
bool isPortableExperience)
{
var parcelCorners = parcels.Select(ParcelMathHelper.CalculateCorners).ToList();
ParcelMathHelper.SceneGeometry sceneGeometry = ParcelMathHelper.CreateSceneGeometry(parcelCorners, definition.metadata.scene.DecodedBase);
ParcelMathHelper.SceneGeometry sceneGeometry = ParcelMathHelper.CreateSceneGeometry(parcels,
definition.metadata.scene.DecodedBase);

return new SceneDefinitionComponent(
definition,
parcels,
parcelCorners,
sceneGeometry,
ipfsPath,
isEmpty,
Expand Down
Loading