From 1d28fd3d74826e6a25c7b1a6c05bc5e665195857 Mon Sep 17 00:00:00 2001 From: Jun Tanaka Date: Sun, 1 Oct 2017 23:23:09 +0900 Subject: [PATCH 1/3] Add PanoramaView.isDeviceMotionEnabled --- Sources/PanoramaView.swift | 63 ++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/Sources/PanoramaView.swift b/Sources/PanoramaView.swift index b2e1ab2..a7684b6 100644 --- a/Sources/PanoramaView.swift +++ b/Sources/PanoramaView.swift @@ -9,6 +9,11 @@ import UIKit import SceneKit +fileprivate struct RenderProperties { + var isDeviceMotionEnabled: Bool = true + weak var sceneRendererDelegate: SCNSceneRendererDelegate? +} + public final class PanoramaView: UIView, SceneLoadable { #if (arch(arm) || arch(arm64)) && os(iOS) public let device: MTLDevice @@ -25,7 +30,23 @@ public final class PanoramaView: UIView, SceneLoadable { } } - public weak var sceneRendererDelegate: SCNSceneRendererDelegate? + public weak var sceneRendererDelegate: SCNSceneRendererDelegate? { + get { + return self.renderProperties.sceneRendererDelegate + } + set { + self.updateRenderProperties { $0.sceneRendererDelegate = newValue } + } + } + + public var isDeviceMotionEnabled: Bool { + get { + return self.renderProperties.isDeviceMotionEnabled + } + set { + self.updateRenderProperties { $0.isDeviceMotionEnabled = newValue } + } + } public lazy var orientationNode: OrientationNode = { let node = OrientationNode() @@ -63,6 +84,14 @@ public final class PanoramaView: UIView, SceneLoadable { return InterfaceOrientationUpdater(orientationNode: self.orientationNode) }() + fileprivate var renderProperties: RenderProperties { + return renderPropertiesQueue.sync { _renderProperties } + } + + private var _renderProperties = RenderProperties() + + private let renderPropertiesQueue = DispatchQueue(label: "com.eje-c.MetalScope.PanoramaView.renderPropertiesQueue") + #if (arch(arm) || arch(arm64)) && os(iOS) public init(frame: CGRect, device: MTLDevice) { self.device = device @@ -98,6 +127,12 @@ public final class PanoramaView: UIView, SceneLoadable { interfaceOrientationUpdater.updateInterfaceOrientation() } } + + private func updateRenderProperties(_ action: @escaping (_ properties: inout RenderProperties) -> Void) { + renderPropertiesQueue.async(flags: .barrier) { [unowned self] in + action(&self._renderProperties) + } + } } extension PanoramaView: ImageLoadable {} @@ -167,22 +202,24 @@ extension PanoramaView: OrientationIndicatorDataSource { extension PanoramaView: SCNSceneRendererDelegate { public func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) { - var disableActions = false + if isDeviceMotionEnabled { + var disableActions = false - if let provider = orientationNode.deviceOrientationProvider, provider.shouldWaitDeviceOrientation(atTime: time) { - provider.waitDeviceOrientation(atTime: time) - disableActions = true - } + if let provider = orientationNode.deviceOrientationProvider, provider.shouldWaitDeviceOrientation(atTime: time) { + provider.waitDeviceOrientation(atTime: time) + disableActions = true + } - SCNTransaction.lock() - SCNTransaction.begin() - SCNTransaction.animationDuration = 1 / 15 - SCNTransaction.disableActions = disableActions + SCNTransaction.lock() + SCNTransaction.begin() + SCNTransaction.animationDuration = 1 / 15 + SCNTransaction.disableActions = disableActions - orientationNode.updateDeviceOrientation(atTime: time) + orientationNode.updateDeviceOrientation(atTime: time) - SCNTransaction.commit() - SCNTransaction.unlock() + SCNTransaction.commit() + SCNTransaction.unlock() + } sceneRendererDelegate?.renderer?(renderer, updateAtTime: time) } From 55f641f1b1f16f89faeb96febca9573fe127d613 Mon Sep 17 00:00:00 2001 From: Jun Tanaka Date: Sun, 1 Oct 2017 23:23:41 +0900 Subject: [PATCH 2/3] Make PanoramaPanGestureManager public --- Sources/PanoramaPanGestureManager.swift | 31 ++++++++++++++++--------- Sources/PanoramaView.swift | 14 +++++------ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/Sources/PanoramaPanGestureManager.swift b/Sources/PanoramaPanGestureManager.swift index bac2792..44d4119 100644 --- a/Sources/PanoramaPanGestureManager.swift +++ b/Sources/PanoramaPanGestureManager.swift @@ -10,18 +10,25 @@ import UIKit import UIKit.UIGestureRecognizerSubclass import SceneKit -final class PanoramaPanGestureManager { - let rotationNode: SCNNode +public final class PanoramaPanGestureManager { + public var isEnabled: Bool { + get { + return self.gestureRecognizer.isEnabled + } + set { + self.gestureRecognizer.isEnabled = newValue + } + } - var allowsVerticalRotation = true - var minimumVerticalRotationAngle: Float? - var maximumVerticalRotationAngle: Float? + public var allowsVerticalRotation = true + public var minimumVerticalRotationAngle: Float? + public var maximumVerticalRotationAngle: Float? - var allowsHorizontalRotation = true - var minimumHorizontalRotationAngle: Float? - var maximumHorizontalRotationAngle: Float? + public var allowsHorizontalRotation = true + public var minimumHorizontalRotationAngle: Float? + public var maximumHorizontalRotationAngle: Float? - lazy var gestureRecognizer: UIPanGestureRecognizer = { + internal lazy var gestureRecognizer: UIPanGestureRecognizer = { let recognizer = AdvancedPanGestureRecognizer() recognizer.addTarget(self, action: #selector(handlePanGesture(_:))) recognizer.earlyTouchEventHandler = { [weak self] in @@ -33,11 +40,13 @@ final class PanoramaPanGestureManager { private var referenceAngles: SCNVector3? - init(rotationNode: SCNNode) { + private let rotationNode: SCNNode + + internal init(rotationNode: SCNNode) { self.rotationNode = rotationNode } - @objc func handlePanGesture(_ sender: UIPanGestureRecognizer) { + @objc fileprivate func handlePanGesture(_ sender: UIPanGestureRecognizer) { guard let view = sender.view else { return } diff --git a/Sources/PanoramaView.swift b/Sources/PanoramaView.swift index a7684b6..dc8645a 100644 --- a/Sources/PanoramaView.swift +++ b/Sources/PanoramaView.swift @@ -48,6 +48,13 @@ public final class PanoramaView: UIView, SceneLoadable { } } + public lazy var panGestureManager: PanoramaPanGestureManager = { + let manager = PanoramaPanGestureManager(rotationNode: self.orientationNode.userRotationNode) + manager.minimumVerticalRotationAngle = -60 / 180 * .pi + manager.maximumVerticalRotationAngle = 60 / 180 * .pi + return manager + }() + public lazy var orientationNode: OrientationNode = { let node = OrientationNode() let mask = CategoryBitMask.all.subtracting(.rightEye) @@ -73,13 +80,6 @@ public final class PanoramaView: UIView, SceneLoadable { return view }() - fileprivate lazy var panGestureManager: PanoramaPanGestureManager = { - let manager = PanoramaPanGestureManager(rotationNode: self.orientationNode.userRotationNode) - manager.minimumVerticalRotationAngle = -60 / 180 * .pi - manager.maximumVerticalRotationAngle = 60 / 180 * .pi - return manager - }() - fileprivate lazy var interfaceOrientationUpdater: InterfaceOrientationUpdater = { return InterfaceOrientationUpdater(orientationNode: self.orientationNode) }() From 2e81690c75346ad75576bb5400c466a35cecf54d Mon Sep 17 00:00:00 2001 From: Jun Tanaka Date: Sun, 1 Oct 2017 23:23:55 +0900 Subject: [PATCH 3/3] Add PanoramaView.isPanGestureEnabled --- Sources/PanoramaView.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Sources/PanoramaView.swift b/Sources/PanoramaView.swift index dc8645a..a064c99 100644 --- a/Sources/PanoramaView.swift +++ b/Sources/PanoramaView.swift @@ -48,6 +48,15 @@ public final class PanoramaView: UIView, SceneLoadable { } } + public var isPanGestureEnabled: Bool { + get { + return self.panGestureManager.isEnabled + } + set { + self.panGestureManager.isEnabled = newValue + } + } + public lazy var panGestureManager: PanoramaPanGestureManager = { let manager = PanoramaPanGestureManager(rotationNode: self.orientationNode.userRotationNode) manager.minimumVerticalRotationAngle = -60 / 180 * .pi