Tanoda
LeapGraphicRenderer.cs
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) Ultraleap, Inc. 2011-2020. *
3 * *
4 * Use subject to the terms of the Apache License 2.0 available at *
5 * http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
6 * between Ultraleap and you, your company or other organization. *
7 ******************************************************************************/
8
9using System;
10using System.Collections.Generic;
11using UnityEngine;
12using Leap.Unity.Space;
13using Leap.Unity.Query;
15
17
18 [ExecuteInEditMode]
19 public partial class LeapGraphicRenderer : MonoBehaviour, ISerializationCallbackReceiver {
20 public const string FEATURE_PREFIX = "GRAPHIC_RENDERER_";
21 public const string PROPERTY_PREFIX = "_GraphicRenderer";
22
23 public const string FEATURE_MOVEMENT_TRANSLATION = FEATURE_PREFIX + "MOVEMENT_TRANSLATION";
24 public const string FEATURE_MOVEMENT_FULL = FEATURE_PREFIX + "MOVEMENT_FULL";
25
26 #region INSPECTOR FIELDS
27 [SerializeField]
28 private LeapSpace _space;
29 private bool _lastSpaceWasNull = true;
30
31 [SerializeField]
32 private List<LeapGraphicGroup> _groups = new List<LeapGraphicGroup>();
33 #endregion
34
35 #region PUBLIC RUNTIME API
36
41 get {
42 return _space;
43 }
44 }
45
51 public List<LeapGraphicGroup> groups {
52 get {
53 return _groups;
54 }
55 }
56
61 public LeapGraphicGroup FindGroup(string name) {
62 return _groups.Query().FirstOrDefault(g => g.name == name);
63 }
64
77 public bool TryAddGraphic(LeapGraphic graphic) {
78 LeapGraphicGroup targetGroup = null;
79
80 //First just try to attach to a group that is its favorite
81 foreach (var group in groups) {
82 if (group.name == graphic.favoriteGroupName) {
83 if (group.TryAddGraphic(graphic)) {
84 return true;
85 }
86 }
87 }
88
89 //Then try to attatch to a group that is of the preferred type
90 //Choose the preferred group with the least graphics
91 Type preferredType = graphic.preferredRendererType;
92 if (preferredType != null) {
93 foreach (var group in groups) {
94 Type rendererType = group.renderingMethod.GetType();
95 if (preferredType == rendererType ||
96 rendererType.IsSubclassOf(preferredType)) {
97 if (targetGroup == null || group.toBeAttachedCount < targetGroup.toBeAttachedCount) {
98 targetGroup = group;
99 }
100 }
101 }
102 }
103
104 if (targetGroup != null && targetGroup.TryAddGraphic(graphic)) {
105 return true;
106 }
107
108 //If we failed, just try to attach to any group that will take us
109 foreach (var group in groups) {
110 if (group.renderingMethod.IsValidGraphic(graphic)) {
111 if (targetGroup == null || group.toBeAttachedCount < targetGroup.toBeAttachedCount) {
112 targetGroup = group;
113 }
114 }
115 }
116
117 if (targetGroup != null && targetGroup.TryAddGraphic(graphic)) {
118 return true;
119 }
120
121 //Unable to find any group that would accept the graphic :(
122 return false;
123 }
124
125 #endregion
126
127 #region UNITY CALLBACKS
128 private void OnValidate() {
129#if UNITY_EDITOR
130 if (!InternalUtility.IsPrefab(this)) {
131 if (!Application.isPlaying) {
132 editor.ScheduleRebuild();
133 }
134 editor.OnValidate();
135 }
136#endif
137 }
138
139 private void OnDestroy() {
140#if UNITY_EDITOR
141 editor.OnDestroy();
142#endif
143 }
144
145 private void OnEnable() {
146#if UNITY_EDITOR
147 Vector2[] uv = null;
148 foreach (var group in _groups) {
149 foreach (var feature in group.features) {
150 LeapSpriteFeature spriteFeature = feature as LeapSpriteFeature;
151 if (spriteFeature != null) {
152 foreach (var data in spriteFeature.featureData) {
153 uv = data.sprite.uv;
154 }
155 }
156 }
157 }
158
159 UnityEditor.Undo.undoRedoPerformed -= onUndoRedoPerformed;
160 UnityEditor.Undo.undoRedoPerformed += onUndoRedoPerformed;
161#endif
162
163 if (Application.isPlaying) {
164 if (_space != null) {
165 _space.RebuildHierarchy();
167 _lastSpaceWasNull = false;
168 }
169
170 foreach (var group in _groups) {
171 group.OnEnable();
172 }
173 }
174 }
175
176 private void OnDisable() {
177 if (Application.isPlaying) {
178 foreach (var group in _groups) {
179 group.OnDisable();
180 }
181 }
182
183#if UNITY_EDITOR
184 UnityEditor.Undo.undoRedoPerformed += onUndoRedoPerformed;
185#endif
186 }
187
188 private void LateUpdate() {
189#if UNITY_EDITOR
190 //No updates for prefabs!
191 if (InternalUtility.IsPrefab(this)) {
192 return;
193 }
194
195 if (!Application.isPlaying) {
196 editor.DoLateUpdateEditor();
197 } else
198#endif
199 {
200 doLateUpdateRuntime();
201 }
202 }
203 #endregion
204
205 #region PRIVATE IMPLEMENTATION
206
207 private LeapGraphicRenderer() {
208#if UNITY_EDITOR
209 editor = new EditorApi(this);
210#endif
211 }
212
213 private void doLateUpdateRuntime() {
214 // Validate the attached space to support it changing at runtime.
216
217 if (_space != null) {
218 //TODO, optimize this! Don't do it every frame for the whole thing!
219 using (new ProfilerSample("Refresh space data")) {
221 }
222 }
223
224 foreach (var group in _groups) {
225 group.UpdateRenderer();
226 }
227 }
228
230 var origSpace = _space;
231
232 var spaces = Pool<List<LeapSpace>>.Spawn();
233 spaces.Clear();
234 try {
235 GetComponents<LeapSpace>(spaces);
236 _space = spaces.Query().FirstOrDefault(s => s.enabled);
237 }
238 finally {
239 spaces.Clear();
240 Pool<List<LeapSpace>>.Recycle(spaces);
241 }
242
243 // Support Undo/Redo with runtime space changes in-editor
244 bool didUndoRedo = false;
245 #if UNITY_EDITOR
246 if (_didUndoRedoThisFrame) {
247 didUndoRedo = true;
248 _didUndoRedoThisFrame = false;
249 }
250 #endif
251
252 if (Application.isPlaying
253 && (origSpace != _space
254 || (_space == null && !_lastSpaceWasNull))
255 || didUndoRedo
256 ) {
257 onRuntimeSpaceChanged();
258 }
259
260 _lastSpaceWasNull = _space == null;
261 }
262
263#if UNITY_EDITOR
264 private bool _didUndoRedoThisFrame = false;
265
266 private void onUndoRedoPerformed() {
267 _didUndoRedoThisFrame = true;
268 }
269#endif
270
271 private void onRuntimeSpaceChanged() {
272 // The space was modified, so refresh a bunch of things..
273
274 if (_space != null) {
275 _space.RebuildHierarchy();
277 }
278
279 // Need to update material keywords appropriately.
280 // This involves re-preparing materials, which happens OnEnable,
281 // so we'll "power-cycle" the whole renderer for simplicity's sake.
282 OnDisable();
283 OnEnable();
284
285
286 foreach (var group in _groups) {
287 group.RefreshGraphicAnchors();
288 }
289 }
290
291 public void OnBeforeSerialize() { }
292
293 public void OnAfterDeserialize() {
294 foreach (var group in _groups) {
295 (group as ILeapInternalGraphicGroup).renderer = this;
296 }
297 }
298 #endregion
299 }
300}
LeapRenderingMethod renderingMethod
Gets the rendering method used for this group. This can only be changed at edit time using either the...
bool TryAddGraphic(LeapGraphic graphic)
Tries to add the given graphic to any group attached to this graphic. First, it will try to be attach...
LeapGraphicGroup FindGroup(string name)
Searches the group list for a group with the given name. If there is no group with the given name,...
LeapSpace space
Returns the leap space that is currently attached to this graphic renderer.
List< LeapGraphicGroup > groups
Returns a list of all graphic groups contained withinin this renderer. This getter returns a regular ...
void RecalculateTransformers()
Call to update all transformers in the space. Call this whenever any anchor or parent of an anchor ch...
Definition: LeapSpace.cs:85
void RebuildHierarchy()
Call to traverse the entire hierarchy and rebuild the relationship between anchors....
Definition: LeapSpace.cs:71