Неправильное положение камеры при воспроизведении видео на 360 градусов с использованием SceneKit и CoreMotion
Я играю с 360-градусным видеоплеером, используя SpriteKit, SceneKit и CoreMotion. Плеер пока работает, но видео всегда немного увеличено. Похоже, что положение камеры не в (0,0,0), но как-то не так на оси Z. К сожалению, я не нашел способа это отрегулировать. Чтобы воспроизвести поведение, просто коснитесь экрана во время воспроизведения видео и ущипните его. Это позволяет управлять камерой с помощью жестов, двойное нажатие возвращает управление камерой с помощью устройства.
import UIKit
import SceneKit
import CoreMotion
import SpriteKit
import AVFoundation
class Video360VC: UIViewController {
let motionManager = CMMotionManager()
let cameraNode = SCNNode()
@IBOutlet weak var sceneView: SCNView!
@IBAction func exitBtnClicked(_ sender: Any) {
performSegueToReturnBack()
}
func createSphereNode(material: AnyObject?) -> SCNNode {
let sphere = SCNSphere(radius: 20.0)
sphere.firstMaterial!.isDoubleSided = true
sphere.firstMaterial!.diffuse.contents = material
let sphereNode = SCNNode(geometry: sphere)
sphereNode.position = SCNVector3Make(0,0,0)
sphereNode.rotation = SCNVector4Make(1, 0, 0, Float.pi)
return sphereNode
}
func configureScene(node sphereNode: SCNNode) {
// Set the scene
let scene = SCNScene()
sceneView.scene = scene
sceneView.showsStatistics = true
sceneView.allowsCameraControl = true
// Camera, ...
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3Make(0, 0, 0)
scene.rootNode.addChildNode(sphereNode)
scene.rootNode.addChildNode(cameraNode)
}
func startCameraTracking() {
motionManager.deviceMotionUpdateInterval = 1.0 / 60.0
motionManager.startDeviceMotionUpdates(to: OperationQueue.main) {
[weak self](data: CMDeviceMotion?, error: Error?) in
guard let data = data else { return }
let attitude: CMAttitude = data.attitude
self?.cameraNode.eulerAngles = SCNVector3Make(- Float(attitude.roll + Double.pi/2), Float(attitude.yaw), -Float(attitude.pitch))
}
}
override func viewDidLoad() {
super.viewDidLoad()
guard let fileURL = Bundle.main.url(forResource: "360Test2", withExtension: "mp4") else {
print("Video File not found")
return
}
let player = AVPlayer(url: fileURL)
let videoNode = SKVideoNode(avPlayer: player)
let size = CGSize(width: 1280, height: 720)
videoNode.size = size
videoNode.position = CGPoint(x: size.width/2, y: size.height/2)
let spriteScene = SKScene(size: size)
spriteScene.scaleMode = .resizeFill
spriteScene.addChild(videoNode)
let sphereNode = createSphereNode(material:spriteScene)
configureScene(node: sphereNode)
guard motionManager.isDeviceMotionAvailable else {
fatalError("Device motion is not available")
}
startCameraTracking()
player.play()
}
override func viewWillAppear(_ animated: Bool) {
self.sceneView.play(self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Я использовал это видео для тестирования, которое также можно скачать здесь. Большое спасибо!
1 ответ
Из того, что я могу понять из вашего объяснения, это то, что у вас есть проблема с так называемой Field of View
, Это может выглядеть как камера zoomed
но на самом деле это не так. Посмотрите на настройки FOV в вашей камере попробуйте настройки, как 90 градусов.