#if (UNITY_EDITOR) using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.Linq; namespace ECE { // Can't figure out how to do platform dependant compilation with attributes, and I have quite a headache, so... // there's just two copies of the class here. all so that the warning isn't displayed when going from prefab mode to play mode /// /// Not actually a compute shader. Just uses a regular shader with a structured buffer. /// "In regular graphics shaders the compute buffer support requires minimum shader model 4.5." /// #if (UNITY_2018_3_OR_NEWER) [System.Serializable, ExecuteAlways] public class EasyColliderCompute : MonoBehaviour { #region preference values private EasyColliderPreferences ECEPreferences { get { return EasyColliderPreferences.Preferences; } } public Color SelectedColor { get { return ECEPreferences.SelectedVertColour; } } public Color HoveredColor { get { return ECEPreferences.HoverVertColour; } } public Color OverlapColor { get { return ECEPreferences.OverlapSelectedVertColour; } } public Color DisplayAllColor { get { return ECEPreferences.DisplayVerticesColour; } } public float DefaultScale { get { return ECEPreferences.DefaultScale; } } public float CommonScale { get { return ECEPreferences.CommonScalingMultiplier; } } public float HoveredScale { get { return ECEPreferences.HoveredScaleMult; } } public float SelectedScale { get { return ECEPreferences.SelectedScaleMult; } } public float DisplayAllScale { get { return ECEPreferences.DisplayAllScaleMult; } } public float OverlapScale { get { return ECEPreferences.OverlapScaleMult; } } public bool DisplayAllVertices { get { return ECEPreferences.DisplayAllVertices; } } #endregion // shader to create materials from public Shader GeometryShader; // hovered material for use with hovered buffer, color, and size. [SerializeField] Material _HoveredMaterial; [SerializeField] Material _SelectedMaterial; [SerializeField] Material _OverlapMaterial; [SerializeField] Material _DisplayAllMaterial; // bools to use to check if the buffer is valid (not empty), and if they are valid, to render the vertices/geometry [SerializeField] private bool _ValidOverlapBuffer = true; [SerializeField] private bool _ValidSelectedBuffer = true; [SerializeField] private bool _ValidHoverBuffer = true; [SerializeField] private bool _ValidDisplayAllBuffer = true; /// /// Calculated density values. /// public float DensityScale = 0.0f; // Lists of points to be used in buffers. [HideInInspector] private List _SelectedWorldPoints = new List(); [HideInInspector] private HashSet _SelectedWorldPointsSet = new HashSet(); [HideInInspector] private List _OverlappedPoints = new List(); [HideInInspector] private List _HoveredPoints = new List(); [HideInInspector] private List _DisplayAllPoints = new List(); public int SelectedPointCount { get { try { return _SelectedBuffer != null ? _SelectedWorldPoints.Count : 0; } catch { return 0; } } } public int HoveredPointCount { get { try { return (_HoveredBuffer != null && _OverlapBuffer != null) ? _HoveredPoints.Count + _OverlappedPoints.Count : 0; } catch { return 0; } } } public int DisplayPointCount { get { try { return (_DisplayAllBuffer != null) ? _DisplayAllPoints.Count : 0; } catch { return 0; } } } // Compute buffers [SerializeField] ComputeBuffer _SelectedBuffer; [SerializeField] ComputeBuffer _HoveredBuffer; [SerializeField] ComputeBuffer _OverlapBuffer; [SerializeField] ComputeBuffer _DisplayAllBuffer; /// /// Called when the current editor scene is saved. /// /// void OnSceneSaved(UnityEngine.SceneManagement.Scene scene) { SetSelectedBuffer(); SetDisplayAllBuffer(); } void Start() { if (EditorApplication.isPlaying) { Destroy(this); } } void OnEnable() { // we need to recreate the selected and display buffer when the scene is saved so they are displayed correctly. UnityEditor.SceneManagement.EditorSceneManager.sceneSaved += OnSceneSaved; // find the geometry shader if (GeometryShader == null) { string[] ecp = AssetDatabase.FindAssets("EasyColliderShader t:Shader"); if (ecp.Length > 0) { string assetPath = AssetDatabase.GUIDToAssetPath(ecp[0]); GeometryShader = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Shader)) as Shader; } if (GeometryShader == null) { Debug.LogError("EasyColliderEditor was unable to find the shader needed for displaying vertices. If you deleted it because your system does not support it, be sure to set Render Vertex Method to Gizmos in preferences."); DestroyImmediate(this); } } // create materials _OverlapMaterial = new Material(GeometryShader); _HoveredMaterial = new Material(GeometryShader); _SelectedMaterial = new Material(GeometryShader); _DisplayAllMaterial = new Material(GeometryShader); // create buffers if (_DisplayAllBuffer == null) { _ValidDisplayAllBuffer = false; _DisplayAllBuffer = new ComputeBuffer(1, 12); } if (_HoveredBuffer == null) { _ValidHoverBuffer = false; _HoveredBuffer = new ComputeBuffer(1, 12); } if (_SelectedBuffer == null) { _ValidSelectedBuffer = false; _SelectedBuffer = new ComputeBuffer(1, 12); } if (_OverlapBuffer == null) { _ValidOverlapBuffer = false; _OverlapBuffer = new ComputeBuffer(1, 12); } } float GetScale() { float scale = DefaultScale * CommonScale; if (scale <= 0.0f) { scale = ECEPreferences.DefaultScale; } return scale; } void OnRenderObject() { float size = GetScale(); // only need to re-update the selected buffer due to undo/redo operations. if (!_ValidSelectedBuffer && _SelectedWorldPoints.Count > 0) { UpdateSelectedBuffer(_SelectedWorldPoints); } #if (UNITY_2018_1_OR_NEWER) if (DisplayAllVertices && _DisplayAllBuffer != null && _ValidDisplayAllBuffer && _DisplayAllBuffer.IsValid()) #else if (DisplayAllVertices && _DisplayAllBuffer != null && _ValidDisplayAllBuffer) #endif { _DisplayAllMaterial.SetColor("_Color", DisplayAllColor); _DisplayAllMaterial.SetFloat("_Size", size * DisplayAllScale); _DisplayAllMaterial.SetBuffer("worldPositions", _DisplayAllBuffer); _DisplayAllMaterial.SetPass(0); #if (UNITY_2019_1_OR_NEWER) Graphics.DrawProceduralNow(MeshTopology.Points, _DisplayAllBuffer.count); #else Graphics.DrawProcedural(MeshTopology.Points, _DisplayAllBuffer.count); #endif //TODO: customizable / enablable wireframe drawing for the points. // GL.wireframe = true; // _DisplayAllMaterial.SetColor("_Color", Color.black); // _DisplayAllMaterial.SetPass(0); // Graphics.DrawProcedural(MeshTopology.Points, _DisplayAllBuffer.count); // GL.wireframe = false; } #if (UNITY_2018_1_OR_NEWER) if (_SelectedBuffer == null || !_SelectedBuffer.IsValid() || _SelectedBuffer.count != _SelectedWorldPoints.Count) { SetSelectedBuffer(); } if (_SelectedBuffer != null && _ValidSelectedBuffer && _SelectedBuffer.IsValid()) #else if (_SelectedBuffer != null && _ValidSelectedBuffer) #endif { _SelectedMaterial.SetColor("_Color", SelectedColor); _SelectedMaterial.SetFloat("_Size", size * SelectedScale); _SelectedMaterial.SetBuffer("worldPositions", _SelectedBuffer); _SelectedMaterial.SetPass(0); #if (UNITY_2019_1_OR_NEWER) Graphics.DrawProceduralNow(MeshTopology.Points, _SelectedBuffer.count); #else Graphics.DrawProcedural(MeshTopology.Points, _SelectedBuffer.count); #endif } #if (UNITY_2018_1_OR_NEWER) if (_HoveredBuffer != null && _ValidHoverBuffer && _HoveredBuffer.IsValid()) #else if (_HoveredBuffer != null && _ValidHoverBuffer) #endif { _HoveredMaterial.SetColor("_Color", HoveredColor); _HoveredMaterial.SetFloat("_Size", size * HoveredScale); _HoveredMaterial.SetPass(0); #if (UNITY_2019_1_OR_NEWER) Graphics.DrawProceduralNow(MeshTopology.Points, _HoveredBuffer.count); #else Graphics.DrawProcedural(MeshTopology.Points, _HoveredBuffer.count); #endif } #if (UNITY_2018_1_OR_NEWER) if (_OverlapBuffer != null && _ValidOverlapBuffer && _OverlapBuffer.IsValid()) #else if (_OverlapBuffer != null && _ValidOverlapBuffer) #endif { _OverlapMaterial.SetColor("_Color", OverlapColor); // scale overlap to be always larger than currently selected so they are always visible. _OverlapMaterial.SetFloat("_Size", size * OverlapScale); _OverlapMaterial.SetPass(0); // draw the topology as points. the squares are drawn in the shader by triangles from the points passed in through the overlap buffer when it is updated. #if (UNITY_2019_1_OR_NEWER) Graphics.DrawProceduralNow(MeshTopology.Points, _OverlapBuffer.count); #else Graphics.DrawProcedural(MeshTopology.Points, _OverlapBuffer.count); #endif } } /// /// Updates the selected world points buffer. /// /// New list of world points public void UpdateSelectedBuffer(List worldPoints) { _SelectedWorldPointsSet.Clear(); _SelectedWorldPoints = worldPoints; _SelectedWorldPointsSet.UnionWith(worldPoints); worldPoints.ForEach(point => _SelectedWorldPointsSet.Add(point)); SetSelectedBuffer(); } /// /// Clears the current selected buffer and resets it from _SelectedWorldPoints /// private void SetSelectedBuffer() { if (_SelectedBuffer != null) { _SelectedBuffer.Release(); } if (_SelectedWorldPoints.Count > 0) { _SelectedBuffer = new ComputeBuffer(_SelectedWorldPoints.Count, 12); _SelectedBuffer.SetData(_SelectedWorldPoints.ToArray()); _ValidSelectedBuffer = true; } else { _SelectedBuffer = new ComputeBuffer(1, 12); _SelectedBuffer.SetCounterValue(0); _ValidSelectedBuffer = false; } if (_SelectedBuffer != null && _SelectedMaterial != null) { _SelectedMaterial.SetBuffer("worldPositions", _SelectedBuffer); } else { _SelectedBuffer.Release(); } } /// /// Updates both the overlap and hovered buffer /// /// All vertices highlighted for possible selection public void UpdateOverlapHoveredBuffer(HashSet worldPoints) { _OverlappedPoints.Clear(); _HoveredPoints.Clear(); foreach (Vector3 p in _SelectedWorldPoints) { if (worldPoints.Contains(p)) { _OverlappedPoints.Add(p); } } foreach (Vector3 p in worldPoints) { if (!_SelectedWorldPointsSet.Contains(p)) { _HoveredPoints.Add(p); } } if (_OverlapBuffer != null) { _OverlapBuffer.Release(); } if (_OverlappedPoints.Count > 0) { _OverlapBuffer = new ComputeBuffer(_OverlappedPoints.Count, 12); // _OverlapBuffer.SetData(_OverlappedPoints); _OverlapBuffer.SetData(_OverlappedPoints.ToArray()); _ValidOverlapBuffer = true; } else { _OverlapBuffer = new ComputeBuffer(1, 12); _OverlapBuffer.SetCounterValue(0); _ValidOverlapBuffer = false; } if (_OverlapMaterial != null) { _OverlapMaterial.SetBuffer("worldPositions", _OverlapBuffer); } else { _OverlapBuffer.Release(); } if (_HoveredBuffer != null) { _HoveredBuffer.Release(); } if (_HoveredPoints.Count > 0) { _HoveredBuffer = new ComputeBuffer(_HoveredPoints.Count, 12); // _HoveredBuffer.SetData(_HoveredPoints); _HoveredBuffer.SetData(_HoveredPoints.ToArray()); _ValidHoverBuffer = true; } else { _HoveredBuffer = new ComputeBuffer(1, 12); _HoveredBuffer.SetCounterValue(0); _ValidHoverBuffer = false; } if (_HoveredMaterial != null) { _HoveredMaterial.SetBuffer("worldPositions", _HoveredBuffer); } else { _HoveredBuffer.Dispose(); } } public void SetDisplayAllBuffer(HashSet worldPoints) { _DisplayAllPoints.Clear(); _DisplayAllPoints = worldPoints.ToList(); SetDisplayAllBuffer(); } /// /// Clears the current display all buffer and updates it using _DisplayAllPoints /// private void SetDisplayAllBuffer() { if (_DisplayAllBuffer != null) { _DisplayAllBuffer.Release(); } if (_DisplayAllPoints.Count > 0) { _DisplayAllBuffer = new ComputeBuffer(_DisplayAllPoints.Count, 12); _DisplayAllBuffer.SetData(_DisplayAllPoints.ToArray()); _ValidDisplayAllBuffer = true; } else { _DisplayAllBuffer = new ComputeBuffer(1, 12); _DisplayAllBuffer.SetCounterValue(0); _ValidDisplayAllBuffer = false; } if (_DisplayAllBuffer != null && _DisplayAllMaterial != null) { _DisplayAllMaterial.SetBuffer("worldPositions", _DisplayAllBuffer); } else { _DisplayAllBuffer.Release(); } } void OnDestroy() { if (_HoveredBuffer != null) { _HoveredBuffer.Release(); } if (_SelectedBuffer != null) { _SelectedBuffer.Release(); } if (_OverlapBuffer != null) { _OverlapBuffer.Release(); } if (_DisplayAllBuffer != null) { _DisplayAllBuffer.Release(); } } void OnDisable() { if (_HoveredBuffer != null) { _HoveredBuffer.Release(); } if (_SelectedBuffer != null) { _SelectedBuffer.Release(); } if (_OverlapBuffer != null) { _OverlapBuffer.Release(); } if (_DisplayAllBuffer != null) { _DisplayAllBuffer.Release(); } // Unregister from the scene save delegate UnityEditor.SceneManagement.EditorSceneManager.sceneSaved -= OnSceneSaved; } } #else [System.Serializable, ExecuteInEditMode] public class EasyColliderCompute : MonoBehaviour { #region preference values private EasyColliderPreferences ECEPreferences { get { return EasyColliderPreferences.Preferences; } } public Color SelectedColor { get { return ECEPreferences.SelectedVertColour; } } public Color HoveredColor { get { return ECEPreferences.HoverVertColour; } } public Color OverlapColor { get { return ECEPreferences.OverlapSelectedVertColour; } } public Color DisplayAllColor { get { return ECEPreferences.DisplayVerticesColour; } } public float DefaultScale { get { return ECEPreferences.DefaultScale; } } public float CommonScale { get { return ECEPreferences.CommonScalingMultiplier; } } public float HoveredScale { get { return ECEPreferences.HoveredScaleMult; } } public float SelectedScale { get { return ECEPreferences.SelectedScaleMult; } } public float DisplayAllScale { get { return ECEPreferences.DisplayAllScaleMult; } } public float OverlapScale { get { return ECEPreferences.OverlapScaleMult; } } public bool DisplayAllVertices { get { return ECEPreferences.DisplayAllVertices; } } #endregion // shader to create materials from public Shader GeometryShader; // hovered material for use with hovered buffer, color, and size. [SerializeField] Material _HoveredMaterial; [SerializeField] Material _SelectedMaterial; [SerializeField] Material _OverlapMaterial; [SerializeField] Material _DisplayAllMaterial; // bools to use to check if the buffer is valid (not empty), and if they are valid, to render the vertices/geometry [SerializeField] private bool _ValidOverlapBuffer = true; [SerializeField] private bool _ValidSelectedBuffer = true; [SerializeField] private bool _ValidHoverBuffer = true; [SerializeField] private bool _ValidDisplayAllBuffer = true; /// /// Calculated density values. /// public float DensityScale = 0.0f; // Lists of points to be used in buffers. [HideInInspector] private List _SelectedWorldPoints = new List(); [HideInInspector] private HashSet _SelectedWorldPointsSet = new HashSet(); [HideInInspector] private List _OverlappedPoints = new List(); [HideInInspector] private List _HoveredPoints = new List(); [HideInInspector] private List _DisplayAllPoints = new List(); public int SelectedPointCount { get { try { return _SelectedBuffer != null ? _SelectedWorldPoints.Count : 0; } catch { return 0; } } } public int HoveredPointCount { get { try { return (_HoveredBuffer != null && _OverlapBuffer != null) ? (_HoveredPoints.Count + _OverlappedPoints.Count) : 0; } catch { return 0; } } } public int DisplayPointCount { get { try { return (_DisplayAllBuffer != null) ? _DisplayAllPoints.Count : 0; } catch { return 0; } } } // Compute buffers [SerializeField] ComputeBuffer _SelectedBuffer; [SerializeField] ComputeBuffer _HoveredBuffer; [SerializeField] ComputeBuffer _OverlapBuffer; [SerializeField] ComputeBuffer _DisplayAllBuffer; /// /// Called when the current editor scene is saved. /// /// void OnSceneSaved(UnityEngine.SceneManagement.Scene scene) { SetSelectedBuffer(); SetDisplayAllBuffer(); } void Start() { if (EditorApplication.isPlaying) { Destroy(this); } } void OnEnable() { // we need to recreate the selected and display buffer when the scene is saved so they are displayed correctly. UnityEditor.SceneManagement.EditorSceneManager.sceneSaved += OnSceneSaved; // find the geometry shader if (GeometryShader == null) { string[] ecp = AssetDatabase.FindAssets("EasyColliderShader t:Shader"); if (ecp.Length > 0) { string assetPath = AssetDatabase.GUIDToAssetPath(ecp[0]); GeometryShader = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Shader)) as Shader; } if (GeometryShader == null) { Debug.LogError("EasyColliderEditor was unable to find the shader needed for displaying vertices. If you deleted it because your system does not support it, be sure to set Render Vertex Method to Gizmos in preferences."); DestroyImmediate(this); } } // create materials _OverlapMaterial = new Material(GeometryShader); _HoveredMaterial = new Material(GeometryShader); _SelectedMaterial = new Material(GeometryShader); _DisplayAllMaterial = new Material(GeometryShader); // create buffers if (_DisplayAllBuffer == null) { _ValidDisplayAllBuffer = false; _DisplayAllBuffer = new ComputeBuffer(1, 12); } if (_HoveredBuffer == null) { _ValidHoverBuffer = false; _HoveredBuffer = new ComputeBuffer(1, 12); } if (_SelectedBuffer == null) { _ValidSelectedBuffer = false; _SelectedBuffer = new ComputeBuffer(1, 12); } if (_OverlapBuffer == null) { _ValidOverlapBuffer = false; _OverlapBuffer = new ComputeBuffer(1, 12); } } float GetScale() { float scale = DefaultScale * CommonScale; if (scale <= 0.0f) { scale = ECEPreferences.DefaultScale; } return scale; } void OnRenderObject() { float size = GetScale(); // only need to re-update the selected buffer due to undo/redo operations. if (!_ValidSelectedBuffer && _SelectedWorldPoints.Count > 0) { UpdateSelectedBuffer(_SelectedWorldPoints); } #if (UNITY_2018_1_OR_NEWER) if (DisplayAllVertices && _DisplayAllBuffer != null && _ValidDisplayAllBuffer && _DisplayAllBuffer.IsValid()) #else if (DisplayAllVertices && _DisplayAllBuffer != null && _ValidDisplayAllBuffer) #endif { _DisplayAllMaterial.SetColor("_Color", DisplayAllColor); _DisplayAllMaterial.SetFloat("_Size", size * DisplayAllScale); _DisplayAllMaterial.SetBuffer("worldPositions", _DisplayAllBuffer); _DisplayAllMaterial.SetPass(0); #if (UNITY_2019_1_OR_NEWER) Graphics.DrawProceduralNow(MeshTopology.Points, _DisplayAllBuffer.count); #else Graphics.DrawProcedural(MeshTopology.Points, _DisplayAllBuffer.count); #endif //TODO: customizable / enablable wireframe drawing for the points. // GL.wireframe = true; // _DisplayAllMaterial.SetColor("_Color", Color.black); // _DisplayAllMaterial.SetPass(0); // Graphics.DrawProcedural(MeshTopology.Points, _DisplayAllBuffer.count); // GL.wireframe = false; } #if (UNITY_2018_1_OR_NEWER) if (_SelectedBuffer != null && _ValidSelectedBuffer && _SelectedBuffer.IsValid()) #else if (_SelectedBuffer != null && _ValidSelectedBuffer) #endif { _SelectedMaterial.SetColor("_Color", SelectedColor); _SelectedMaterial.SetFloat("_Size", size * SelectedScale); _SelectedMaterial.SetBuffer("worldPositions", _SelectedBuffer); _SelectedMaterial.SetPass(0); #if (UNITY_2019_1_OR_NEWER) Graphics.DrawProceduralNow(MeshTopology.Points, _SelectedBuffer.count); #else // because for some reason using vhacd with vertices selected, but not the use selected vertices toggle, // causes the selected buffer to be lost. Tried to record an undo and full object undo, but that didn't do anything. // but try/catch/finally works. try { Graphics.DrawProcedural(MeshTopology.Points, _SelectedBuffer.count); } catch { SetSelectedBuffer(); } finally { Graphics.DrawProcedural(MeshTopology.Points, _SelectedBuffer.count); } #endif } #if (UNITY_2018_1_OR_NEWER) if (_HoveredBuffer != null && _ValidHoverBuffer && _HoveredBuffer.IsValid()) #else if (_HoveredBuffer != null && _ValidHoverBuffer) #endif { _HoveredMaterial.SetColor("_Color", HoveredColor); _HoveredMaterial.SetFloat("_Size", size * HoveredScale); _HoveredMaterial.SetPass(0); #if (UNITY_2019_1_OR_NEWER) Graphics.DrawProceduralNow(MeshTopology.Points, _HoveredBuffer.count); #else Graphics.DrawProcedural(MeshTopology.Points, _HoveredBuffer.count); #endif } #if (UNITY_2018_1_OR_NEWER) if (_OverlapBuffer != null && _OverlapBuffer.IsValid()) #else if (_OverlapBuffer != null && _ValidOverlapBuffer) #endif { _OverlapMaterial.SetColor("_Color", OverlapColor); // scale overlap to be always larger than currently selected so they are always visible. _OverlapMaterial.SetFloat("_Size", size * OverlapScale); _OverlapMaterial.SetPass(0); // draw the topology as points. the squares are drawn in the shader by triangles from the points passed in through the overlap buffer when it is updated. #if (UNITY_2019_1_OR_NEWER) Graphics.DrawProceduralNow(MeshTopology.Points, _OverlapBuffer.count); #else Graphics.DrawProcedural(MeshTopology.Points, _OverlapBuffer.count); #endif } } /// /// Updates the selected world points buffer. /// /// New list of world points public void UpdateSelectedBuffer(List worldPoints) { _SelectedWorldPointsSet.Clear(); _SelectedWorldPoints = worldPoints; _SelectedWorldPointsSet.UnionWith(worldPoints); worldPoints.ForEach(point => _SelectedWorldPointsSet.Add(point)); SetSelectedBuffer(); } /// /// Clears the current selected buffer and resets it from _SelectedWorldPoints /// private void SetSelectedBuffer() { if (_SelectedBuffer != null) { _SelectedBuffer.Release(); } if (_SelectedWorldPoints.Count > 0) { _SelectedBuffer = new ComputeBuffer(_SelectedWorldPoints.Count, 12); _SelectedBuffer.SetData(_SelectedWorldPoints.ToArray()); _ValidSelectedBuffer = true; } else { _SelectedBuffer = new ComputeBuffer(1, 12); _SelectedBuffer.SetCounterValue(0); _ValidSelectedBuffer = false; } if (_SelectedBuffer != null && _SelectedMaterial != null) { _SelectedMaterial.SetBuffer("worldPositions", _SelectedBuffer); } else { _SelectedBuffer.Release(); } } /// /// Updates both the overlap and hovered buffer /// /// All vertices highlighted for possible selection public void UpdateOverlapHoveredBuffer(HashSet worldPoints) { _OverlappedPoints.Clear(); _HoveredPoints.Clear(); foreach (Vector3 p in _SelectedWorldPoints) { if (worldPoints.Contains(p)) { _OverlappedPoints.Add(p); } } foreach (Vector3 p in worldPoints) { if (!_SelectedWorldPointsSet.Contains(p)) { _HoveredPoints.Add(p); } } if (_OverlapBuffer != null) { _OverlapBuffer.Release(); } if (_OverlappedPoints.Count > 0) { _OverlapBuffer = new ComputeBuffer(_OverlappedPoints.Count, 12); // _OverlapBuffer.SetData(_OverlappedPoints); _OverlapBuffer.SetData(_OverlappedPoints.ToArray()); _ValidOverlapBuffer = true; } else { _OverlapBuffer = new ComputeBuffer(1, 12); _OverlapBuffer.SetCounterValue(0); _ValidOverlapBuffer = false; } if (_OverlapMaterial != null) { _OverlapMaterial.SetBuffer("worldPositions", _OverlapBuffer); } else { _OverlapBuffer.Release(); } if (_HoveredBuffer != null) { _HoveredBuffer.Release(); } if (_HoveredPoints.Count > 0) { _HoveredBuffer = new ComputeBuffer(_HoveredPoints.Count, 12); // _HoveredBuffer.SetData(_HoveredPoints); _HoveredBuffer.SetData(_HoveredPoints.ToArray()); _ValidHoverBuffer = true; } else { _HoveredBuffer = new ComputeBuffer(1, 12); _HoveredBuffer.SetCounterValue(0); _ValidHoverBuffer = false; } if (_HoveredMaterial != null) { _HoveredMaterial.SetBuffer("worldPositions", _HoveredBuffer); } else { _HoveredBuffer.Dispose(); } } public void SetDisplayAllBuffer(HashSet worldPoints) { _DisplayAllPoints.Clear(); _DisplayAllPoints = worldPoints.ToList(); SetDisplayAllBuffer(); } /// /// Clears the current display all buffer and updates it using _DisplayAllPoints /// private void SetDisplayAllBuffer() { if (_DisplayAllBuffer != null) { _DisplayAllBuffer.Release(); } if (_DisplayAllPoints.Count > 0) { _DisplayAllBuffer = new ComputeBuffer(_DisplayAllPoints.Count, 12); _DisplayAllBuffer.SetData(_DisplayAllPoints.ToArray()); _ValidDisplayAllBuffer = true; } else { _DisplayAllBuffer = new ComputeBuffer(1, 12); _DisplayAllBuffer.SetCounterValue(0); _ValidDisplayAllBuffer = false; } if (_DisplayAllBuffer != null && _DisplayAllMaterial != null) { _DisplayAllMaterial.SetBuffer("worldPositions", _DisplayAllBuffer); } else { _DisplayAllBuffer.Release(); } } void OnDestroy() { if (_HoveredBuffer != null) { _HoveredBuffer.Release(); } if (_SelectedBuffer != null) { _SelectedBuffer.Release(); } if (_OverlapBuffer != null) { _OverlapBuffer.Release(); } if (_DisplayAllBuffer != null) { _DisplayAllBuffer.Release(); } } void OnDisable() { if (_HoveredBuffer != null) { _HoveredBuffer.Release(); } if (_SelectedBuffer != null) { _SelectedBuffer.Release(); } if (_OverlapBuffer != null) { _OverlapBuffer.Release(); } if (_DisplayAllBuffer != null) { _DisplayAllBuffer.Release(); } // Unregister from the scene save delegate UnityEditor.SceneManagement.EditorSceneManager.sceneSaved -= OnSceneSaved; } } #endif } #endif