У меня проблемы с ротацией ARKit. Я создаю узел My3DPlayer:SCNNode
, который содержит videoNode:SKVideoNode
. Проблема, которую я испытываю, заключается в том, что она делает случайные вращения (броски). Он не создает никаких проблем с подачей и поворотом, однако он будет поворачиваться в случайном направлении, каждый раз, когда я открываю приложение. Я бы хотел, чтобы ориентация была прямо над якорем, который я использую. У меня правильный размер, который мне нравится, но я немного запутался в повороте.
import UIKit
import ARKit
import AVKit
class My3DPlayer: SCNNode {
var player:AVPlayer!
init(geometry: SCNGeometry?) {
super.init()
self.geometry = geometry
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
convenience init(anchor: ARImageAnchor, currentFrame:ARFrame) {
self.init(geometry: nil)
self.createPlayer(anchor, currentFrame)
}
//Returns a 3d Player of a set size
private func createPlayer(_ anchor:ARImageAnchor, _ frame:ARFrame) {
let physicalSize = anchor.referenceImage.physicalSize
print("Init Player W/ physicalSize: \(physicalSize)")
//Create video
let path = Bundle.main.path(forResource: "Bear", ofType: "mov")
let asset = AVAsset(url: URL(fileURLWithPath: path!))
let track = asset.tracks(withMediaType: AVMediaType.video).first!
let playerItem = AVPlayerItem(asset: asset)
self.player = AVPlayer(playerItem: playerItem)
var videoSize = track.naturalSize.applying(track.preferredTransform)
videoSize = CGSize(width: abs(videoSize.width), height: abs(videoSize.height))
print("Init Video W/ size: \(videoSize)")
//Do something when video ended
NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying(note:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
//Add observer to determine when Player is ready
player.addObserver(self, forKeyPath: "status", options: [], context: nil)
//Create video Node
let videoNode = SKVideoNode(avPlayer: player)
//Create 2d scene to put 2d player on - SKScene
let scene = SKScene(size: videoSize)
videoNode.position = CGPoint(x: videoSize.width/2, y: videoSize.height/2)
videoNode.size = scene.size
//To adjust to landscape and portrait weird af
videoNode.zRotation = CGFloat(-Double.pi)*90/180
print(videoNode.zRotation * 180/CGFloat(Double.pi))
let width = videoNode.size.width
videoNode.size.width = videoNode.size.height
videoNode.size.height = width
//Add videoNode to scene
scene.addChild(videoNode)
//Get ratio difference from physicalsize and video size
let widthRatio = Float(physicalSize.width)/Float(videoSize.width)
let heightRatio = Float(physicalSize.height)/Float(videoSize.height)
let finalRatio = [widthRatio, heightRatio].min()!
//Create a Plane (SCNPlane) to put the SKScene on
let plane = SCNPlane(width: videoSize.width, height: videoSize.height)
plane.firstMaterial?.diffuse.contents = scene
plane.firstMaterial?.isDoubleSided = true
//Set Self.geometry = plane
self.geometry = plane
//Show Node
self.transform = SCNMatrix4(anchor.transform)
let appearanceAction = SCNAction.scale(to: CGFloat(finalRatio), duration: 0.4)
appearanceAction.timingMode = .easeOut
//Set initial scale to 0 then use action to scale up
self.scale = SCNVector3Make(0, 0, 0)
self.runAction(appearanceAction)
//This rotates it to lay down
self.eulerAngles = SCNVector3(Double.pi*90/180, 0, 0)
}
}
Вот как я ссылаюсь на изображение (мне нужно удалить реальное изображение, которое я использую для создания изображения AR, поскольку оно является моей привязанностью. Это был самый удобный и легко доступный объект для игры).
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let imageAnchor = anchor as? ARImageAnchor else {
return
}
guard let currentFrame = self.sceneView.session.currentFrame else {
return
}
DispatchQueue.main.async {
self.videoPlayer3D = My3DPlayer(anchor: imageAnchor, currentFrame: currentFrame)
self.sceneView.scene.rootNode.addChildNode(self.videoPlayer3D)
}
}
Вот несколько примеров, однако, иногда они полностью горизонтальны по сравнению с вертикальными. Это кажется случайным.