LeapSpace.cs
4.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/******************************************************************************
* Copyright (C) Leap Motion, Inc. 2011-2017. *
* Leap Motion proprietary and confidential. *
* *
* Use subject to the terms of the Leap Motion SDK Agreement available at *
* https://developer.leapmotion.com/sdk_agreement, or another agreement *
* between Leap Motion and you, your company or other organization. *
******************************************************************************/
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;
using Leap.Unity.Query;
namespace Leap.Unity.Space {
public abstract class LeapSpace : LeapSpaceAnchor {
private static List<LeapSpace> _enabledSpaces = new List<LeapSpace>();
public static List<LeapSpace> allEnabled {
get {
#if UNITY_EDITOR
//if we are in the editor, don't bother with enable/disable lifecycle
//just use FindObjectsOfType!
if (!Application.isPlaying) {
FindObjectsOfType<LeapSpace>().Query().Where(c => c.enabled).FillList(_enabledSpaces);
}
#endif
return _enabledSpaces;
}
}
private List<LeapSpaceAnchor> _anchors = new List<LeapSpaceAnchor>();
protected override void OnEnable() {
base.OnEnable();
_enabledSpaces.Add(this);
RebuildHierarchy();
RecalculateTransformers();
}
protected override void OnDisable() {
base.OnDisable();
_enabledSpaces.Remove(this);
for (int i = 0; i < _anchors.Count; i++) {
_anchors[i].space = null;
_anchors[i].transformer = null;
}
}
/// <summary>
/// Returns all active anchors in depth-first pre-order
/// </summary>
public List<LeapSpaceAnchor> anchors {
get {
return _anchors;
}
}
/// <summary>
/// Call to traverse the entire hierarchy and rebuild the relationship
/// between anchors. Call this whenever any of the following happens:
/// - An anchor is created
/// - An anchor is enabled / disabled
/// - An enabled anchor is destroyed
/// - The relative position in the hierarchy of any two anchors changes.
/// </summary>
public void RebuildHierarchy() {
Assert.IsTrue(enabled, "Should never call RebuildHierarchy on a disabled space.");
_anchors.Clear();
rebuildHierarchyRecursively(transform);
Assert.IsTrue(_anchors.Count > 0, "There should always be at least a single anchor (this one).");
Assert.AreEqual(_anchors[0], this, "A space should always be the first element in the anchor list.");
}
/// <summary>
/// Call to update all transformers in the space. Call this whenever any
/// anchor or parent of an anchor changes it's transform.
/// </summary>
public void RecalculateTransformers() {
Assert.IsTrue(enabled, "Should never call RecalculateTransformers on a disabled space.");
transformer = CosntructBaseTransformer();
//Depth-first pre-order ensures that a parent already has it's transformer up-to-date
//by the time a direct child needs to be updated.
for (int i = 1; i < _anchors.Count; i++) {
var anchor = _anchors[i];
var parent = anchor.parent;
Assert.IsNotNull(anchor, "Make sure to call RebuildHierarchy before RecalculateTransformers if you delete an anchor.");
Assert.IsTrue(anchor.enabled, "Make sure to all RebuildHierarchy before RecalculateTransformers if you disable an anchor.");
UpdateTransformer(anchor.transformer, parent.transformer);
}
}
/// <summary>
/// Get a hash of all features in this space. This is useful if you want to know
/// if anything has changed about the settings of this space.
/// </summary>
public abstract Hash GetSettingHash();
protected abstract ITransformer CosntructBaseTransformer();
protected abstract ITransformer ConstructTransformer(LeapSpaceAnchor anchor);
protected abstract void UpdateTransformer(ITransformer transformer, ITransformer parent);
private void rebuildHierarchyRecursively(Transform root) {
var anchor = root.GetComponent<LeapSpaceAnchor>();
if (anchor != null && anchor.enabled) {
anchor.space = this;
anchor.RecalculateParentAnchor();
anchor.transformer = ConstructTransformer(anchor);
_anchors.Add(anchor);
}
int childCount = root.childCount;
for (int i = 0; i < childCount; i++) {
rebuildHierarchyRecursively(root.GetChild(i));
}
}
}
}