-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathPartitionGlobalAssetEntitiesSystem.cs
More file actions
120 lines (104 loc) · 4.96 KB
/
Copy pathPartitionGlobalAssetEntitiesSystem.cs
File metadata and controls
120 lines (104 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
using Arch.Core;
using Arch.System;
using Arch.SystemGroups;
using Arch.SystemGroups.DefaultSystemGroups;
using DCL.Character.Components;
using DCL.ECSComponents;
using DCL.Optimization.Pools;
using DCL.Profiles;
using ECS.Abstract;
using ECS.Prioritization;
using ECS.Prioritization.Components;
using ECS.Unity.Systems;
using UnityEngine;
namespace DCL.Systems
{
/// <summary>
/// Similar to <see cref="PartitionAssetEntitiesSystem" /> but partitions components for
/// qualified entities that exist in the global world.
/// </summary>
[UpdateInGroup(typeof(InitializationSystemGroup))]
public partial class PartitionGlobalAssetEntitiesSystem : BaseUnityLoopSystem
{
private readonly IReadOnlyCameraSamplingData cameraSamplingData;
private readonly IPartitionSettings partitionSettings;
private readonly IComponentPool<PartitionComponent> partitionComponentPool;
internal PartitionGlobalAssetEntitiesSystem(World world, IComponentPool<PartitionComponent> partitionComponentPool,
IPartitionSettings settings, IReadOnlyCameraSamplingData cameraSamplingData) : base(world)
{
this.partitionComponentPool = partitionComponentPool;
partitionSettings = settings;
this.cameraSamplingData = cameraSamplingData;
}
protected override void Update(float t)
{
// First re-partition if player position or rotation is changed
// if is true then re-partition if Transform.isDirty
Vector3 cameraPosition = cameraSamplingData.Position;
Vector3 cameraForward = cameraSamplingData.Forward;
if (cameraSamplingData.IsDirty)
{
// Repartition everything
RePartitionExistingEntityQuery(World, cameraPosition, cameraForward);
}
else
{
RepartitionDirtyPlayersQuery(World, cameraPosition, cameraForward);
ResetDirtyQuery(World);
}
// Then partition all entities that are not partitioned yet
PartitionNewEntityQuery(World, cameraPosition, cameraForward);
}
[Query]
[Any(typeof(PBAvatarShape), typeof(Profile))]
private void ResetDirty(ref PartitionComponent partitionComponent)
{
partitionComponent.IsDirty = false;
}
[Query]
[Any(typeof(PBAvatarShape), typeof(Profile))]
[None(typeof(PartitionComponent))]
private void PartitionNewEntity([Data] Vector3 cameraPosition, [Data] Vector3 cameraForward, in Entity entity,
ref CharacterTransform transformComponent)
{
PartitionComponent partitionComponent = partitionComponentPool.Get();
RePartition(cameraPosition, cameraForward, transformComponent.Transform.position,
ref transformComponent, ref partitionComponent);
partitionComponent.IsDirty = true;
World.Add(entity, partitionComponent);
}
[Query]
[Any(typeof(PBAvatarShape), typeof(Profile))]
[None(typeof(PlayerComponent))]
private void RePartitionExistingEntity([Data] Vector3 cameraPosition, [Data] Vector3 cameraForward,
ref CharacterTransform transformComponent, ref PartitionComponent partitionComponent)
{
RePartition(cameraPosition, cameraForward, transformComponent.Transform.position,
ref transformComponent, ref partitionComponent);
}
[Query]
[Any(typeof(PBAvatarShape), typeof(Profile))]
[None(typeof(PlayerComponent))]
private void RepartitionDirtyPlayers([Data] Vector3 cameraPosition, [Data] Vector3 cameraForward,
ref CharacterTransform transformComponent, ref PartitionComponent partitionComponent)
{
if (!transformComponent.IsDirty) return;
RePartition(cameraPosition, cameraForward, transformComponent.Transform.position,
ref transformComponent, ref partitionComponent);
}
private void RePartition(Vector3 cameraTransform, Vector3 cameraForward, Vector3 entityPosition,
ref CharacterTransform transformComponent, ref PartitionComponent partitionComponent)
{
// TODO pure math logic can be jobified for much better performance
byte bucket = partitionComponent.Bucket;
bool isBehind = partitionComponent.IsBehind;
// check if fast path should be used
Vector3 vectorToCamera = entityPosition - cameraTransform;
float sqrDistance = Vector3.SqrMagnitude(vectorToCamera);
PartitionAssetEntitiesSystem.ResolvePartitionFromDistance(partitionSettings, cameraForward, partitionComponent,
sqrDistance, vectorToCamera);
partitionComponent.IsDirty = bucket != partitionComponent.Bucket || isBehind != partitionComponent.IsBehind;
transformComponent.ClearDirty();
}
}
}