-
Notifications
You must be signed in to change notification settings - Fork 0
/
RealityObject.cs
194 lines (158 loc) · 5.5 KB
/
RealityObject.cs
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
//
// Cuboid (http://github.com/arjonagelhout/cuboid)
// Copyright (c) 2023 Arjo Nagelhout
//
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cuboid.Models;
using Cuboid.Utils;
using UnityEngine.EventSystems;
using Cuboid.Input;
using Newtonsoft.Json;
namespace Cuboid
{
/// <summary>
/// There are two options:
///
/// 1. If at least one object in the selection prefers proportional scaling,
/// it should use proportional scaling
/// 2. If at least one object doesn't prefer proportional scaling,
/// it shouldn't use proportional scaling.
/// </summary>
public interface IPrefersProportionalScaling
{
}
[Serializable]
public abstract class RealityObjectData
{
/// <summary>
/// Guid, access object
/// </summary>
public Guid Guid;
/// <summary>
/// Object Name (multiple objects can have the same name)
/// </summary>
[RuntimeSerializedPropertyString]
public BindingWithoutNew<string> Name = new();
/// <summary>
///
/// </summary>
public Binding<TransformData> Transform;
[NonSerialized]
public Binding<bool> Selected = new();
public abstract IEnumerator InstantiateAsync(Action<RealityObject> completed);
}
/// <summary>
/// Abstract class that any object can inherit from that should be able to be
/// instantiated in the scene, and controlled in the scene hierarchy, transform.
///
/// These are MonoBehaviour instances inside the scene
/// </summary>
public abstract class RealityObject : MonoBehaviour
{
private Action<TransformData> _onTransformDataChanged = null;
private Action<bool> _onSelectedChanged = null;
private float k_MinimumBoundsExtentsSqrMagnitude = 0.0001f;
private RealityObjectData _realityObjectData = null;
/// <summary>
/// The data that contains all transform data, the guid of the object etc.
/// </summary>
public RealityObjectData RealityObjectData
{
get => _realityObjectData;
set
{
Unregister();
_realityObjectData = value;
SetupColliders();
Register();
}
}
protected virtual void Start()
{
}
private void SetupColliders()
{
bool hasValidColliders = false;
// 1. First determine whether the asset already has any collider active on it,
// if so, don’t try to add a new collider
Collider[] existingColliders = GetComponentsInChildren<Collider>();
foreach (Collider collider in existingColliders)
{
// make sure the bounds are not zero
if (collider.bounds.extents.sqrMagnitude > k_MinimumBoundsExtentsSqrMagnitude)
{
hasValidColliders = true;
}
}
if (hasValidColliders) { return; }
// 2. If there is no collider active, try to create a mesh collider for all
// mesh renderers, however, for this the Mesh should have been set to
// Read / write enabled on asset bundle build
MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
foreach (MeshFilter meshFilter in meshFilters)
{
bool readable = meshFilter.sharedMesh.isReadable;
if (readable)
{
// readable, so add the new mesh collider.
MeshCollider newMeshCollider = meshFilter.gameObject.AddComponent<MeshCollider>();
newMeshCollider.sharedMesh = meshFilter.sharedMesh;
}
else
{
// not readable, so make a box collider around the mesh.
BoxCollider newBoxCollider = meshFilter.gameObject.AddComponent<BoxCollider>();
}
}
}
private void OnSelectedChanged(bool selected)
{
gameObject.SetLayerRecursively(selected ? Layers.Selected : Layers.Default);
}
protected virtual void OnTransformDataChanged(TransformData transformData)
{
transform.SetFromTransformData(transformData);
}
#region Action registration
private void OnEnable()
{
Register();
}
private void OnDestroy()
{
Unregister();
}
private void OnDisable()
{
Unregister();
}
protected virtual void Register()
{
if (_onTransformDataChanged == null)
{
_onTransformDataChanged = OnTransformDataChanged;
}
if (_onSelectedChanged == null)
{
_onSelectedChanged = OnSelectedChanged;
}
if (_realityObjectData != null)
{
_realityObjectData.Transform.Register(_onTransformDataChanged);
_realityObjectData.Selected.Register(_onSelectedChanged);
}
}
protected virtual void Unregister()
{
if (_realityObjectData != null)
{
_realityObjectData.Transform.Unregister(_onTransformDataChanged);
_realityObjectData.Selected.Unregister(_onSelectedChanged);
}
}
#endregion
}
}