@webspatial/platform-visionos 1.0.5 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/web-spatial/JSBCommand.swift +45 -53
- package/web-spatial/SpatialObject.swift +30 -14
- package/web-spatial/WebMsgCommand.swift +52 -50
- package/web-spatial/manager/Dynamic3DManager.swift +10 -12
- package/web-spatial/manager/FileCoordinator.swift +20 -0
- package/web-spatial/manager/WKWebViewManager.swift +9 -1
- package/web-spatial/manifest.swift +4 -1
- package/web-spatial/model/SpatialScene.swift +43 -13
- package/web-spatial/model/Spatialized2DElement.swift +2 -0
- package/web-spatial/model/SpatializedElement.swift +5 -6
- package/web-spatial/model/dynamic3d/SpatialEntity.swift +72 -69
- package/web-spatial/view/Spatialized2DElementView.swift +1 -1
- package/web-spatial/view/SpatializedDynamic3DView.swift +73 -64
- package/web-spatial/view/SpatializedElementView.swift +42 -46
- package/web-spatial/view/SpatializedStatic3DView.swift +2 -0
- package/web-spatial.xcodeproj/project.pbxproj +1 -0
- package/web-spatial.xcodeproj/xcshareddata/xcschemes/web-spatial.xcscheme +2 -2
|
@@ -39,7 +39,7 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
39
39
|
var parent: (any ScrollAbleSpatialElementContainer)?
|
|
40
40
|
|
|
41
41
|
// Enum
|
|
42
|
-
|
|
42
|
+
enum WindowStyle: String, Codable, CaseIterable {
|
|
43
43
|
case window
|
|
44
44
|
case volume
|
|
45
45
|
}
|
|
@@ -51,7 +51,7 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
51
51
|
var setLoadingWindowData = PassthroughSubject<XLoadingViewData, Never>()
|
|
52
52
|
|
|
53
53
|
var url: String = "" // start_url
|
|
54
|
-
|
|
54
|
+
var windowStyle: WindowStyle {
|
|
55
55
|
didSet {
|
|
56
56
|
resetBackgroundMaterialOnWindowStyleChange(windowStyle)
|
|
57
57
|
}
|
|
@@ -116,6 +116,35 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
116
116
|
return true
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
private func handleNavigationCheckCustom(_ url: URL) -> Bool {
|
|
120
|
+
/*
|
|
121
|
+
because full url is webspatial://createSpatialScene?url=xxx
|
|
122
|
+
we need to get the real url.
|
|
123
|
+
we do 2 things:
|
|
124
|
+
|
|
125
|
+
1. let curUrl = parse url
|
|
126
|
+
2. if url is in scope do webviewModel.load(curUrl)
|
|
127
|
+
else open in safari
|
|
128
|
+
*/
|
|
129
|
+
guard let components = URLComponents(string: url.absoluteString),
|
|
130
|
+
let queryItems = components.queryItems
|
|
131
|
+
else {
|
|
132
|
+
print("❌ fail to parse URL")
|
|
133
|
+
return false
|
|
134
|
+
}
|
|
135
|
+
guard let encodedUrl = queryItems.first(where: { $0.name == "url" })?.value,
|
|
136
|
+
let decodedUrl = encodedUrl.removingPercentEncoding
|
|
137
|
+
else {
|
|
138
|
+
return false
|
|
139
|
+
}
|
|
140
|
+
if pwaManager.checkInScope(url: decodedUrl) {
|
|
141
|
+
spatialWebViewModel.load(decodedUrl)
|
|
142
|
+
return false
|
|
143
|
+
}
|
|
144
|
+
UIApplication.shared.open(URL(string: decodedUrl)!, options: [:], completionHandler: nil)
|
|
145
|
+
return false
|
|
146
|
+
}
|
|
147
|
+
|
|
119
148
|
private func handleWindowOpenCustom(_ url: URL) -> WebViewElementInfo? {
|
|
120
149
|
// get config from url
|
|
121
150
|
guard let components = URLComponents(string: url.absoluteString),
|
|
@@ -132,6 +161,11 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
132
161
|
return nil
|
|
133
162
|
}
|
|
134
163
|
|
|
164
|
+
if !pwaManager.checkInScope(url: decodedUrl) {
|
|
165
|
+
UIApplication.shared.open(URL(string: decodedUrl)!, options: [:], completionHandler: nil)
|
|
166
|
+
return nil
|
|
167
|
+
}
|
|
168
|
+
|
|
135
169
|
if let encodedConfig = queryItems.first(where: { $0.name == "config" })?.value,
|
|
136
170
|
let decodedConfig = encodedConfig.removingPercentEncoding
|
|
137
171
|
{
|
|
@@ -190,9 +224,9 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
190
224
|
SpatialApp.Instance.closeWindowGroup(self)
|
|
191
225
|
}
|
|
192
226
|
|
|
193
|
-
|
|
227
|
+
var sceneConfig: SceneOptions?
|
|
194
228
|
|
|
195
|
-
|
|
229
|
+
func moveToState(_ newState: SceneStateKind, _ sceneConfig: SceneOptions?) {
|
|
196
230
|
print(" moveToState \(state) to \(newState) ")
|
|
197
231
|
|
|
198
232
|
let oldState = state
|
|
@@ -214,7 +248,7 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
214
248
|
|
|
215
249
|
} else if oldState == .idle, newState == .visible {
|
|
216
250
|
// SpatialApp opened SpatialScene
|
|
217
|
-
} else if oldState == .idle
|
|
251
|
+
} else if oldState == .idle, newState == .willVisible {
|
|
218
252
|
// window.open with scene config
|
|
219
253
|
SpatialApp.Instance.openWindowGroup(self, sceneConfig!)
|
|
220
254
|
}
|
|
@@ -269,6 +303,8 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
269
303
|
|
|
270
304
|
spatialWebViewModel
|
|
271
305
|
.addNavigationListener(protocal: SpatialApp.Instance.scope, event: handleNavigationCheck)
|
|
306
|
+
spatialWebViewModel
|
|
307
|
+
.addNavigationListener(protocal: "webspatial://createSpatialScene", event: handleNavigationCheckCustom)
|
|
272
308
|
}
|
|
273
309
|
|
|
274
310
|
var width: Double = 0
|
|
@@ -292,7 +328,7 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
292
328
|
])
|
|
293
329
|
}
|
|
294
330
|
|
|
295
|
-
|
|
331
|
+
var didFailLoad = false
|
|
296
332
|
|
|
297
333
|
private func setupWebViewStateListener() {
|
|
298
334
|
spatialWebViewModel.addStateListener(.didStartLoad) {
|
|
@@ -608,9 +644,7 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
608
644
|
if let enableDragEndGesture = command.enableDragEndGesture {
|
|
609
645
|
spatializedElement.enableDragEndGesture = enableDragEndGesture
|
|
610
646
|
}
|
|
611
|
-
|
|
612
|
-
spatializedElement.enableRotateStartGesture = enableRotateStartGesture
|
|
613
|
-
}
|
|
647
|
+
|
|
614
648
|
if let enableRotateGesture = command.enableRotateGesture {
|
|
615
649
|
spatializedElement.enableRotateGesture = enableRotateGesture
|
|
616
650
|
}
|
|
@@ -618,10 +652,6 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
618
652
|
spatializedElement.enableRotateEndGesture = enableRotateEndGesture
|
|
619
653
|
}
|
|
620
654
|
|
|
621
|
-
if let enableMagnifyStartGesture = command.enableMagnifyStartGesture {
|
|
622
|
-
spatializedElement.enableMagnifyStartGesture = enableMagnifyStartGesture
|
|
623
|
-
}
|
|
624
|
-
|
|
625
655
|
if let enableMagnifyGesture = command.enableMagnifyGesture {
|
|
626
656
|
spatializedElement.enableMagnifyGesture = enableMagnifyGesture
|
|
627
657
|
}
|
|
@@ -53,6 +53,8 @@ class Spatialized2DElement: SpatializedElement, ScrollAbleSpatialElementContaine
|
|
|
53
53
|
self._scrollOffset.y = point.y
|
|
54
54
|
}
|
|
55
55
|
spatialWebViewModel.scrollEnabled = false
|
|
56
|
+
|
|
57
|
+
defaultAlignment = .center
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
// Spatialized2DElement can hold a collection of SpatializedElement children
|
|
@@ -26,20 +26,20 @@ class SpatializedElement: SpatialObject {
|
|
|
26
26
|
var enableDragStartGesture: Bool = false
|
|
27
27
|
var enableDragGesture: Bool = false
|
|
28
28
|
var enableDragEndGesture: Bool = false
|
|
29
|
-
var enableRotateStartGesture: Bool = false
|
|
30
29
|
var enableRotateGesture: Bool = false
|
|
31
30
|
var enableRotateEndGesture: Bool = false
|
|
32
|
-
var enableMagnifyStartGesture: Bool = false
|
|
33
31
|
var enableMagnifyGesture: Bool = false
|
|
34
32
|
var enableMagnifyEndGesture: Bool = false
|
|
35
33
|
var enableTapGesture: Bool = false
|
|
36
34
|
|
|
35
|
+
var defaultAlignment: DepthAlignment = .back
|
|
36
|
+
|
|
37
37
|
var enableGesture: Bool {
|
|
38
|
-
return enableDragStartGesture || enableDragGesture || enableDragEndGesture ||
|
|
38
|
+
return enableDragStartGesture || enableDragGesture || enableDragEndGesture || enableRotateGesture || enableRotateEndGesture || enableMagnifyGesture || enableMagnifyEndGesture || enableTapGesture
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
enum CodingKeys: String, CodingKey {
|
|
42
|
-
case clientX, clientY, width, height, depth, backOffset, transform, rotationAnchor, opacity, visible, scrollWithParent, zIndex, parent, enableGesture, enableTapGesture, enableDragGesture, enableDragEndGesture,
|
|
42
|
+
case clientX, clientY, width, height, depth, backOffset, transform, rotationAnchor, opacity, visible, scrollWithParent, zIndex, parent, enableGesture, enableTapGesture, enableDragStartGesture, enableDragGesture, enableDragEndGesture, enableRotateGesture, enableRotateEndGesture, enableMagnifyGesture, enableMagnifyEndGesture
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
override func encode(to encoder: Encoder) throws {
|
|
@@ -60,12 +60,11 @@ class SpatializedElement: SpatialObject {
|
|
|
60
60
|
try container.encode(parent?.id, forKey: .parent)
|
|
61
61
|
try container.encode(enableGesture, forKey: .enableGesture)
|
|
62
62
|
try container.encode(enableTapGesture, forKey: .enableTapGesture)
|
|
63
|
+
try container.encode(enableDragStartGesture, forKey: .enableDragStartGesture)
|
|
63
64
|
try container.encode(enableDragGesture, forKey: .enableDragGesture)
|
|
64
65
|
try container.encode(enableDragEndGesture, forKey: .enableDragEndGesture)
|
|
65
|
-
try container.encode(enableRotateStartGesture, forKey: .enableRotateStartGesture)
|
|
66
66
|
try container.encode(enableRotateGesture, forKey: .enableRotateGesture)
|
|
67
67
|
try container.encode(enableRotateEndGesture, forKey: .enableRotateEndGesture)
|
|
68
|
-
try container.encode(enableMagnifyStartGesture, forKey: .enableMagnifyStartGesture)
|
|
69
68
|
try container.encode(enableMagnifyGesture, forKey: .enableMagnifyGesture)
|
|
70
69
|
try container.encode(enableMagnifyEndGesture, forKey: .enableMagnifyEndGesture)
|
|
71
70
|
}
|
|
@@ -1,118 +1,123 @@
|
|
|
1
|
-
import SwiftUI
|
|
2
1
|
import RealityKit
|
|
2
|
+
import SwiftUI
|
|
3
3
|
|
|
4
4
|
@Observable
|
|
5
5
|
class SpatialEntity: Entity, SpatialObjectProtocol {
|
|
6
6
|
let spatialId: String
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
private var _isDestroyed: Bool = false
|
|
9
9
|
var isDestroyed: Bool {
|
|
10
10
|
return _isDestroyed
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
|
|
13
|
+
var listeners: [String: [(_ object: Any, _ data: Any) -> Void]] = [:]
|
|
14
|
+
|
|
14
15
|
private var _enableTap: Bool = false
|
|
15
16
|
private var _enableRotate: Bool = false
|
|
16
|
-
private var _enableRotateStart: Bool = false
|
|
17
17
|
private var _enableRotateEnd: Bool = false
|
|
18
18
|
private var _enableDrag: Bool = false
|
|
19
19
|
private var _enableDragStart: Bool = false
|
|
20
20
|
private var _enableDragEnd: Bool = false
|
|
21
21
|
private var _enableMagnify: Bool = false
|
|
22
|
-
private var _enableMagnifyStart: Bool = false
|
|
23
22
|
private var _enableMagnifyEnd: Bool = false
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
|
|
24
|
+
var rotation: simd_quatd = .init()
|
|
25
|
+
var spatialChildren: [String: SpatialEntity] = [:]
|
|
26
|
+
var spatialComponents: [String: SpatialComponent] = [:]
|
|
27
|
+
|
|
29
28
|
var enableTap: Bool {
|
|
30
29
|
return _enableTap
|
|
31
30
|
}
|
|
31
|
+
|
|
32
32
|
var enableRotate: Bool {
|
|
33
|
-
return _enableRotate ||
|
|
33
|
+
return _enableRotate || _enableRotateEnd
|
|
34
34
|
}
|
|
35
|
+
|
|
35
36
|
var enableDrag: Bool {
|
|
36
|
-
return _enableDrag || _enableDragStart
|
|
37
|
+
return _enableDrag || _enableDragStart || _enableDragEnd
|
|
37
38
|
}
|
|
39
|
+
|
|
38
40
|
var enableMagnify: Bool {
|
|
39
|
-
return _enableMagnify ||
|
|
41
|
+
return _enableMagnify || _enableMagnifyEnd
|
|
40
42
|
}
|
|
41
|
-
|
|
43
|
+
|
|
42
44
|
var enableRotateEnd: Bool {
|
|
43
45
|
return _enableRotateEnd
|
|
44
46
|
}
|
|
47
|
+
|
|
45
48
|
var enableDragEnd: Bool {
|
|
46
49
|
return _enableDragEnd
|
|
47
50
|
}
|
|
51
|
+
|
|
48
52
|
var enableMagnifyEnd: Bool {
|
|
49
53
|
return _enableMagnifyEnd
|
|
50
54
|
}
|
|
51
|
-
|
|
55
|
+
|
|
52
56
|
var enableInteractive: Bool {
|
|
53
|
-
return enableTap || enableRotate || enableDrag || enableMagnify
|
|
57
|
+
return enableTap || enableRotate || enableDrag || enableMagnify
|
|
54
58
|
}
|
|
55
|
-
|
|
59
|
+
|
|
56
60
|
required init() {
|
|
57
|
-
|
|
61
|
+
spatialId = UUID().uuidString
|
|
58
62
|
super.init()
|
|
59
|
-
SpatialObject.
|
|
63
|
+
SpatialObject.serialQueue.sync {
|
|
64
|
+
SpatialObject.objects[spatialId] = self
|
|
65
|
+
}
|
|
60
66
|
SpatialObjectWeakRefManager.setWeakRef(spatialId, self)
|
|
61
67
|
}
|
|
62
|
-
|
|
63
|
-
init(_ _name:String){
|
|
64
|
-
|
|
68
|
+
|
|
69
|
+
init(_ _name: String) {
|
|
70
|
+
spatialId = UUID().uuidString
|
|
65
71
|
super.init()
|
|
66
|
-
|
|
67
|
-
SpatialObject.
|
|
72
|
+
name = _name
|
|
73
|
+
SpatialObject.serialQueue.sync {
|
|
74
|
+
SpatialObject.objects[spatialId] = self
|
|
75
|
+
}
|
|
68
76
|
SpatialObjectWeakRefManager.setWeakRef(spatialId, self)
|
|
69
77
|
}
|
|
70
|
-
|
|
71
|
-
func addChild(entity:SpatialEntity){
|
|
78
|
+
|
|
79
|
+
func addChild(entity: SpatialEntity) {
|
|
72
80
|
spatialChildren[entity.spatialId] = entity
|
|
73
81
|
super.addChild(entity)
|
|
74
82
|
}
|
|
75
|
-
|
|
76
|
-
func removeChild(id:String){
|
|
77
|
-
if let entity = spatialChildren[id]{
|
|
83
|
+
|
|
84
|
+
func removeChild(id: String) {
|
|
85
|
+
if let entity = spatialChildren[id] {
|
|
78
86
|
super.removeChild(entity)
|
|
79
87
|
spatialChildren.removeValue(forKey: id)
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
88
|
+
} else {
|
|
82
89
|
print("no child found")
|
|
83
90
|
}
|
|
84
91
|
}
|
|
85
|
-
|
|
86
|
-
func removeFromParent(){
|
|
87
|
-
if let parent = parent as? SpatialEntity{
|
|
92
|
+
|
|
93
|
+
func removeFromParent() {
|
|
94
|
+
if let parent = parent as? SpatialEntity {
|
|
88
95
|
parent.removeChild(self)
|
|
89
96
|
}
|
|
90
97
|
}
|
|
91
|
-
|
|
98
|
+
|
|
92
99
|
func addComponent(_ comp: SpatialComponent) {
|
|
93
100
|
spatialComponents[comp.type.rawValue] = comp
|
|
94
101
|
comp.addToEntity(entity: self)
|
|
95
102
|
}
|
|
96
|
-
|
|
103
|
+
|
|
97
104
|
func removeComponent(_ comp: SpatialComponent) {
|
|
98
105
|
if spatialComponents[comp.type.rawValue] != nil {
|
|
99
106
|
comp.removeFromEntity(entity: self)
|
|
100
107
|
spatialComponents.removeValue(forKey: comp.type.rawValue)
|
|
101
108
|
}
|
|
102
109
|
}
|
|
103
|
-
|
|
104
|
-
func updateTransform(_ matrix:[String:Float]){
|
|
110
|
+
|
|
111
|
+
func updateTransform(_ matrix: [String: Float]) {
|
|
105
112
|
transform.matrix = float4x4([matrix["0"]!, matrix["1"]!, matrix["2"]!, matrix["3"]!], [matrix["4"]!, matrix["5"]!, matrix["6"]!, matrix["7"]!], [matrix["8"]!, matrix["9"]!, matrix["10"]!, matrix["11"]!], [matrix["12"]!, matrix["13"]!, matrix["14"]!, matrix["15"]!])
|
|
106
113
|
}
|
|
107
|
-
|
|
108
|
-
func updateGesture(_ type:String, _ isEable:Bool){
|
|
109
|
-
switch WebSpatialGestureType(rawValue: type){
|
|
114
|
+
|
|
115
|
+
func updateGesture(_ type: String, _ isEable: Bool) {
|
|
116
|
+
switch WebSpatialGestureType(rawValue: type) {
|
|
110
117
|
case .spatialtap:
|
|
111
118
|
_enableTap = isEable
|
|
112
119
|
case .spatialrotate:
|
|
113
120
|
_enableRotate = isEable
|
|
114
|
-
case .spatialrotatestart:
|
|
115
|
-
_enableRotateStart = isEable
|
|
116
121
|
case .spatialrotateend:
|
|
117
122
|
_enableRotateEnd = isEable
|
|
118
123
|
case .spatialdrag:
|
|
@@ -123,46 +128,42 @@ class SpatialEntity: Entity, SpatialObjectProtocol {
|
|
|
123
128
|
_enableDragEnd = isEable
|
|
124
129
|
case .spatialmagnify:
|
|
125
130
|
_enableMagnify = isEable
|
|
126
|
-
case .spatialmagnifystart:
|
|
127
|
-
_enableMagnifyStart = isEable
|
|
128
131
|
case .spatialmagnifyend:
|
|
129
132
|
_enableMagnifyEnd = isEable
|
|
130
133
|
default:
|
|
131
134
|
return
|
|
132
135
|
}
|
|
133
|
-
|
|
136
|
+
|
|
134
137
|
if enableInteractive {
|
|
135
|
-
if !components.has(InputTargetComponent.self){
|
|
138
|
+
if !components.has(InputTargetComponent.self) {
|
|
136
139
|
components.set(InputTargetComponent())
|
|
137
140
|
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if components.has(InputTargetComponent.self){
|
|
141
|
+
} else {
|
|
142
|
+
if components.has(InputTargetComponent.self) {
|
|
141
143
|
components.remove(InputTargetComponent.self)
|
|
142
144
|
}
|
|
143
145
|
}
|
|
144
146
|
}
|
|
145
|
-
|
|
146
|
-
static func findNearestParent(entity: Entity) -> SpatialEntity?{
|
|
147
|
-
if let parent = entity.parent as? SpatialEntity{
|
|
147
|
+
|
|
148
|
+
static func findNearestParent(entity: Entity) -> SpatialEntity? {
|
|
149
|
+
if let parent = entity.parent as? SpatialEntity {
|
|
148
150
|
return parent
|
|
149
|
-
}
|
|
150
|
-
else if entity.parent != nil {
|
|
151
|
+
} else if entity.parent != nil {
|
|
151
152
|
return findNearestParent(entity: entity.parent!)
|
|
152
153
|
}
|
|
153
154
|
return nil
|
|
154
155
|
}
|
|
155
|
-
|
|
156
|
+
|
|
156
157
|
func setRotation(_ rotation: simd_quatd) {
|
|
157
158
|
self.rotation = rotation
|
|
158
|
-
|
|
159
|
+
transform.rotation = simd_quatf(ix: Float(rotation.imag.x), iy: Float(rotation.imag.y), iz: Float(rotation.imag.z), r: Float(rotation.real))
|
|
159
160
|
}
|
|
160
|
-
|
|
161
|
+
|
|
161
162
|
// Encodable
|
|
162
163
|
enum CodingKeys: String, CodingKey {
|
|
163
164
|
case id, name, isDestroyed, children, components
|
|
164
165
|
}
|
|
165
|
-
|
|
166
|
+
|
|
166
167
|
func encode(to encoder: any Encoder) throws {
|
|
167
168
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
168
169
|
try container.encode(spatialId, forKey: .id)
|
|
@@ -171,12 +172,12 @@ class SpatialEntity: Entity, SpatialObjectProtocol {
|
|
|
171
172
|
try container.encode(spatialChildren, forKey: .children)
|
|
172
173
|
try container.encode(spatialComponents, forKey: .components)
|
|
173
174
|
}
|
|
174
|
-
|
|
175
|
+
|
|
175
176
|
// Equatable
|
|
176
177
|
static func == (lhs: SpatialEntity, rhs: SpatialEntity) -> Bool {
|
|
177
178
|
return lhs.spatialId == rhs.spatialId
|
|
178
179
|
}
|
|
179
|
-
|
|
180
|
+
|
|
180
181
|
func destroy() {
|
|
181
182
|
if _isDestroyed {
|
|
182
183
|
return
|
|
@@ -187,24 +188,26 @@ class SpatialEntity: Entity, SpatialObjectProtocol {
|
|
|
187
188
|
|
|
188
189
|
emit(event: SpatialObject.Events.Destroyed.rawValue, data: ["object": self])
|
|
189
190
|
listeners = [:]
|
|
190
|
-
SpatialObject.
|
|
191
|
+
SpatialObject.serialQueue.sync {
|
|
192
|
+
SpatialObject.objects.removeValue(forKey: spatialId)
|
|
193
|
+
}
|
|
191
194
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if
|
|
195
|
+
|
|
196
|
+
func onDestroy() {
|
|
197
|
+
if parent != nil {
|
|
195
198
|
removeFromParent()
|
|
196
199
|
}
|
|
197
200
|
components.removeAll()
|
|
198
|
-
|
|
201
|
+
for (id, child) in spatialChildren {
|
|
199
202
|
child.destroy()
|
|
200
203
|
}
|
|
201
204
|
spatialChildren = [:]
|
|
202
|
-
|
|
205
|
+
for (id, components) in spatialComponents {
|
|
203
206
|
components.destroy()
|
|
204
207
|
}
|
|
205
208
|
spatialComponents = [:]
|
|
206
209
|
}
|
|
207
|
-
|
|
210
|
+
|
|
208
211
|
deinit {
|
|
209
212
|
SpatialObjectWeakRefManager.removeWeakRef(spatialId)
|
|
210
213
|
}
|
|
@@ -71,7 +71,7 @@ struct Spatialized2DElementView: View {
|
|
|
71
71
|
private var dragWebGesture: some Gesture {
|
|
72
72
|
DragGesture()
|
|
73
73
|
.onChanged { gesture in
|
|
74
|
-
print("\(spatialized2DElement.name) dragWebGesture")
|
|
74
|
+
// print("\(spatialized2DElement.name) dragWebGesture")
|
|
75
75
|
if spatialized2DElement.scrollPageEnabled {
|
|
76
76
|
if !gestureData.dragStarted {
|
|
77
77
|
gestureData.dragStarted = true
|
|
@@ -7,90 +7,99 @@ struct SpatializedDynamic3DView: View {
|
|
|
7
7
|
@State private var isDrag = false
|
|
8
8
|
@State private var isRotate = false
|
|
9
9
|
@State private var isScale = false
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
private var spatializedDynamic3DElement: SpatializedDynamic3DElement {
|
|
12
12
|
return spatializedElement as! SpatializedDynamic3DElement
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
var spatialTapEvent: some Gesture{
|
|
14
|
+
|
|
15
|
+
var spatialTapEvent: some Gesture {
|
|
16
16
|
SpatialTapGesture(count: 1).targetedToAnyEntity()
|
|
17
|
-
.onEnded{ value in
|
|
18
|
-
if let entity = value.entity as? SpatialEntity{
|
|
17
|
+
.onEnded { value in
|
|
18
|
+
if let entity = value.entity as? SpatialEntity {
|
|
19
19
|
spatialScene.sendWebMsg(entity.spatialId, WebSpatialTapGuestureEvent(detail: WebSpatialTapGuestureEventDetail(location3D: value.location3D)))
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if let spatialEntity = SpatialEntity.findNearestParent(entity: value.entity){
|
|
20
|
+
} else {
|
|
21
|
+
if let spatialEntity = SpatialEntity.findNearestParent(entity: value.entity) {
|
|
23
22
|
spatialScene.sendWebMsg(spatialEntity.spatialId, WebSpatialTapGuestureEvent(detail: WebSpatialTapGuestureEventDetail(location3D: value.location3D)))
|
|
24
23
|
}
|
|
25
24
|
}
|
|
26
|
-
|
|
25
|
+
}
|
|
27
26
|
}
|
|
28
|
-
|
|
29
|
-
var rotate3dEvent: some Gesture{
|
|
30
|
-
RotateGesture3D().targetedToAnyEntity().onChanged{ value in
|
|
31
|
-
|
|
32
|
-
if let entity = value.entity as? SpatialEntity{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
27
|
+
|
|
28
|
+
var rotate3dEvent: some Gesture {
|
|
29
|
+
RotateGesture3D().targetedToAnyEntity().onChanged { value in
|
|
30
|
+
// Always forward rotate gesture events to JS
|
|
31
|
+
if let entity = value.entity as? SpatialEntity {
|
|
32
|
+
let gestureEvent = WebSpatialRotateGuestureEvent(
|
|
33
|
+
detail: .init(
|
|
34
|
+
quaternion: Quaternion(
|
|
35
|
+
x: value.rotation.quaternion.imag.x,
|
|
36
|
+
y: value.rotation.quaternion.imag.y,
|
|
37
|
+
z: value.rotation.quaternion.imag.z,
|
|
38
|
+
w: value.rotation.quaternion.real
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
spatialScene.sendWebMsg(entity.spatialId, gestureEvent)
|
|
43
|
+
}
|
|
44
|
+
}.onEnded { value in
|
|
45
|
+
// Always forward rotate end event to JS
|
|
46
|
+
if let entity = value.entity as? SpatialEntity {
|
|
47
|
+
let gestureEvent = WebSpatialRotateEndGuestureEvent()
|
|
48
|
+
spatialScene.sendWebMsg(entity.spatialId, gestureEvent)
|
|
43
49
|
}
|
|
44
50
|
isRotate = false
|
|
45
|
-
}.onEnded{ value in
|
|
46
|
-
print(value.rotation)
|
|
47
|
-
print("rotate end")
|
|
48
|
-
// isRotate = false
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
|
-
|
|
52
|
-
var magnifyEvent: some Gesture{
|
|
53
|
-
MagnifyGesture().targetedToAnyEntity().onChanged{ value in
|
|
54
|
-
|
|
55
|
-
if let entity = value.entity as? SpatialEntity{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
53
|
+
|
|
54
|
+
var magnifyEvent: some Gesture {
|
|
55
|
+
MagnifyGesture().targetedToAnyEntity().onChanged { value in
|
|
56
|
+
// Always forward magnify gesture events to JS
|
|
57
|
+
if let entity = value.entity as? SpatialEntity {
|
|
58
|
+
let detail = WebSpatialMagnifyGuestureEventDetail(magnification: value.magnification)
|
|
59
|
+
let gestureEvent = WebSpatialMagnifyGuestureEvent(
|
|
60
|
+
detail: detail
|
|
61
|
+
)
|
|
62
|
+
spatialScene.sendWebMsg(entity.spatialId, gestureEvent)
|
|
63
|
+
}
|
|
64
|
+
}.onEnded { value in
|
|
65
|
+
// Always forward magnify end event to JS
|
|
66
|
+
if let entity = value.entity as? SpatialEntity {
|
|
67
|
+
let gestureEvent = WebSpatialMagnifyEndGuestureEvent()
|
|
68
|
+
spatialScene.sendWebMsg(entity.spatialId, gestureEvent)
|
|
66
69
|
}
|
|
67
|
-
|
|
68
|
-
print("scale end")
|
|
69
|
-
// isScale = false
|
|
70
|
+
isScale = false
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
-
var dragEvent: some Gesture{
|
|
74
|
-
DragGesture().targetedToAnyEntity().onChanged{ value in
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
73
|
+
|
|
74
|
+
var dragEvent: some Gesture {
|
|
75
|
+
DragGesture().targetedToAnyEntity().onChanged { value in
|
|
76
|
+
// Always forward drag gesture events to JS
|
|
77
|
+
if let entity = value.entity as? SpatialEntity {
|
|
78
|
+
if !isDrag {
|
|
79
|
+
let startEvent = WebSpatialDragStartGuestureEvent(
|
|
80
|
+
detail: .init(
|
|
81
|
+
startLocation3D: value.startLocation3D
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
spatialScene.sendWebMsg(entity.spatialId, startEvent)
|
|
85
|
+
isDrag = true
|
|
86
|
+
} else {
|
|
87
|
+
let gestureEvent = WebSpatialDragGuestureEvent(
|
|
88
|
+
detail: .init(translation3D: value.translation3D)
|
|
89
|
+
)
|
|
90
|
+
spatialScene.sendWebMsg(entity.spatialId, gestureEvent)
|
|
85
91
|
}
|
|
86
92
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
}.onEnded { value in
|
|
94
|
+
// Always forward drag end event to JS
|
|
95
|
+
if let entity = value.entity as? SpatialEntity {
|
|
96
|
+
let gestureEvent = WebSpatialDragEndGuestureEvent()
|
|
97
|
+
spatialScene.sendWebMsg(entity.spatialId, gestureEvent)
|
|
98
|
+
}
|
|
99
|
+
isDrag = false
|
|
91
100
|
}
|
|
92
101
|
}
|
|
93
|
-
|
|
102
|
+
|
|
94
103
|
var body: some View {
|
|
95
104
|
RealityView(make: { content in
|
|
96
105
|
let rootEntity = spatializedDynamic3DElement.getRoot()
|