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