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