| | 1 | | using System.Collections.Generic; |
| | 2 | | using System.Linq; |
| | 3 | | using DCL.Helpers; |
| | 4 | | using DCL.Models; |
| | 5 | | using UnityEngine; |
| | 6 | |
|
| | 7 | | namespace DCL.Controllers |
| | 8 | | { |
| | 9 | | public class SceneBoundsFeedbackStyle_RedBox : ISceneBoundsFeedbackStyle |
| | 10 | | { |
| | 11 | | class InvalidMeshInfo |
| | 12 | | { |
| 22 | 13 | | public List<GameObject> wireframeObjects = new List<GameObject>(); |
| | 14 | | public MeshesInfo meshesInfo; |
| | 15 | | public System.Action OnResetAll; |
| | 16 | |
|
| 66 | 17 | | public InvalidMeshInfo(MeshesInfo meshesInfo) { this.meshesInfo = meshesInfo; } |
| | 18 | |
|
| | 19 | | public void ResetAll() |
| | 20 | | { |
| 22 | 21 | | if (meshesInfo.meshRootGameObject == null) |
| 0 | 22 | | return; |
| | 23 | |
|
| 22 | 24 | | int count = wireframeObjects.Count; |
| | 25 | |
|
| 136 | 26 | | for (int i = 0; i < count; i++) |
| | 27 | | { |
| 46 | 28 | | Utils.SafeDestroy(wireframeObjects[i]); |
| | 29 | | } |
| | 30 | |
|
| 22 | 31 | | OnResetAll?.Invoke(); |
| 0 | 32 | | } |
| | 33 | | } |
| | 34 | |
|
| | 35 | | const string WIREFRAME_PREFAB_NAME = "Prefabs/WireframeCubeMesh"; |
| | 36 | |
|
| | 37 | | private Dictionary<GameObject, InvalidMeshInfo> invalidMeshesInfo; |
| | 38 | | private HashSet<Bounds> invalidObjects; |
| | 39 | |
|
| 26 | 40 | | public SceneBoundsFeedbackStyle_RedBox() |
| | 41 | | { |
| 26 | 42 | | invalidMeshesInfo = new Dictionary<GameObject, InvalidMeshInfo>(); |
| 26 | 43 | | invalidObjects = new HashSet<Bounds>(); |
| 26 | 44 | | } |
| | 45 | |
|
| | 46 | | public void ApplyFeedback(MeshesInfo meshesInfo, bool isInsideBoundaries) |
| | 47 | | { |
| 82 | 48 | | if (isInsideBoundaries) |
| 35 | 49 | | RemoveInvalidMeshEffect(meshesInfo); |
| | 50 | | else |
| 47 | 51 | | AddInvalidMeshEffect(meshesInfo); |
| 47 | 52 | | } |
| | 53 | |
|
| | 54 | | public void CleanFeedback() |
| | 55 | | { |
| 0 | 56 | | IEnumerable<MeshesInfo> distinctMeshesInfo = invalidMeshesInfo.Values.Select(x => x.meshesInfo).Distinct(); |
| | 57 | |
|
| 0 | 58 | | foreach (var info in distinctMeshesInfo) |
| | 59 | | { |
| 0 | 60 | | RemoveInvalidMeshEffect(info); |
| | 61 | | } |
| | 62 | |
|
| 0 | 63 | | invalidMeshesInfo.Clear(); |
| 0 | 64 | | invalidObjects.Clear(); |
| 0 | 65 | | } |
| | 66 | |
|
| | 67 | | void RemoveInvalidMeshEffect(MeshesInfo meshesInfo) |
| | 68 | | { |
| 35 | 69 | | if (meshesInfo == null) |
| 0 | 70 | | return; |
| | 71 | |
|
| 35 | 72 | | if (!invalidMeshesInfo.ContainsKey(meshesInfo.innerGameObject)) |
| 13 | 73 | | return; |
| | 74 | |
|
| 22 | 75 | | PoolableObject poolableObject = PoolManager.i.GetPoolable(meshesInfo.meshRootGameObject); |
| | 76 | |
|
| 22 | 77 | | if (poolableObject != null) |
| 0 | 78 | | poolableObject.OnRelease -= invalidMeshesInfo[meshesInfo.innerGameObject].ResetAll; |
| | 79 | |
|
| 22 | 80 | | var renderers = meshesInfo.renderers; |
| | 81 | |
|
| 22 | 82 | | if (renderers != null) |
| | 83 | | { |
| 98 | 84 | | for (int i = 0; i < renderers.Length; i++) |
| | 85 | | { |
| 27 | 86 | | Bounds target = renderers[i].bounds; |
| | 87 | |
|
| 27 | 88 | | if (invalidObjects.Contains(target)) |
| 21 | 89 | | invalidObjects.Remove(target); |
| | 90 | | } |
| | 91 | | } |
| | 92 | |
|
| 100 | 93 | | foreach (Collider collider in meshesInfo.colliders) |
| | 94 | | { |
| 28 | 95 | | Bounds target = collider.bounds; |
| | 96 | |
|
| 28 | 97 | | if (invalidObjects.Contains(target)) |
| 6 | 98 | | invalidObjects.Remove(target); |
| | 99 | | } |
| | 100 | |
|
| 22 | 101 | | invalidMeshesInfo[meshesInfo.innerGameObject].ResetAll(); |
| 22 | 102 | | invalidMeshesInfo.Remove(meshesInfo.innerGameObject); |
| 22 | 103 | | } |
| | 104 | |
|
| | 105 | | void AddInvalidMeshEffect(MeshesInfo meshesInfo) |
| | 106 | | { |
| 47 | 107 | | if (meshesInfo == null) |
| 0 | 108 | | return; |
| | 109 | |
|
| 47 | 110 | | if (invalidMeshesInfo.ContainsKey(meshesInfo.innerGameObject)) |
| 25 | 111 | | return; |
| | 112 | |
|
| 22 | 113 | | InvalidMeshInfo invalidMeshInfo = new InvalidMeshInfo(meshesInfo); |
| 22 | 114 | | PoolableObject poolableObject = PoolManager.i.GetPoolable(meshesInfo.meshRootGameObject); |
| | 115 | |
|
| 22 | 116 | | if (poolableObject != null) |
| | 117 | | { |
| 0 | 118 | | poolableObject.OnRelease -= invalidMeshInfo.ResetAll; |
| 0 | 119 | | poolableObject.OnRelease += invalidMeshInfo.ResetAll; |
| | 120 | | } |
| | 121 | |
|
| | 122 | | // Apply invalid effect |
| 22 | 123 | | Renderer[] entityRenderers = meshesInfo.renderers; |
| | 124 | |
|
| 98 | 125 | | for (int i = 0; i < entityRenderers.Length; i++) |
| | 126 | | { |
| 27 | 127 | | Bounds target = entityRenderers[i].bounds; |
| | 128 | |
|
| 27 | 129 | | if (invalidObjects.Contains(target)) |
| | 130 | | continue; |
| | 131 | |
|
| 25 | 132 | | var box = PutBoxAroundObject(target, meshesInfo.innerGameObject.transform); |
| | 133 | |
|
| 25 | 134 | | invalidMeshInfo.wireframeObjects.Add(box); |
| 25 | 135 | | invalidObjects.Add(target); |
| | 136 | | } |
| | 137 | |
|
| 100 | 138 | | foreach (Collider collider in meshesInfo.colliders) |
| | 139 | | { |
| 28 | 140 | | Bounds target = collider.bounds; |
| | 141 | |
|
| 28 | 142 | | if (invalidObjects.Contains(target)) |
| | 143 | | continue; |
| | 144 | |
|
| 21 | 145 | | var box = PutBoxAroundObject(target, meshesInfo.innerGameObject.transform); |
| | 146 | |
|
| 21 | 147 | | invalidMeshInfo.wireframeObjects.Add(box); |
| 21 | 148 | | invalidObjects.Add(target); |
| | 149 | | } |
| | 150 | |
|
| 22 | 151 | | invalidMeshesInfo.Add(meshesInfo.innerGameObject, invalidMeshInfo); |
| 22 | 152 | | } |
| | 153 | |
|
| | 154 | | private GameObject PutBoxAroundObject(Bounds target, Transform parent) |
| | 155 | | { |
| | 156 | | // Wireframe that shows the boundaries to the dev (We don't use the GameObject.Instantiate(prefab, parent) |
| | 157 | | // overload because we need to set the position and scale before parenting, to deal with scaled objects) |
| 46 | 158 | | GameObject wireframeObject = Object.Instantiate(Resources.Load<GameObject>(WIREFRAME_PREFAB_NAME)); |
| 46 | 159 | | wireframeObject.transform.position = target.center; |
| 46 | 160 | | wireframeObject.transform.localScale = target.size * 1.01f; |
| 46 | 161 | | wireframeObject.transform.SetParent(parent); |
| 46 | 162 | | return wireframeObject; |
| | 163 | | } |
| | 164 | | public List<Material> GetOriginalMaterials(MeshesInfo meshesInfo) |
| | 165 | | { |
| 0 | 166 | | return meshesInfo.renderers.SelectMany((x) => x.sharedMaterials).ToList(); |
| | 167 | | } |
| | 168 | | } |
| | 169 | | } |