Ich habe mit SceneKit getestet, also habe ich mich entschieden, eine Virtual Reality Test App zu machen. Ich würde die Daten von der Gerätebewegung erhalten und würde dann die Kamerawinkel basierend auf den Daten ändern. Ich habe auf einem iPhone 6 getestet, also kein Problem. Das Ding wird komisch, wenn ich es auf dem iPhone 5 und einem Freund iPhone 5S, die Kamera wird einige Verzögerung zu drehen, sehr anders als auf iPhone 6, die Instant ist. Die FPS auf Xcode hält auf beiden Geräten rund 60 FPS, ich habe einige Zeittests hinzugefügt und die Bewegungsdaten kommen auf beiden Geräten auf etwa 60 Hz. Ich bin verloren.SceneKit und CoreMotion "lagging" auf dem iPhone 5, aber normal auf dem iPhone 6
Die Basis für den Code ist dieses Projekt: https://github.com/stevenjs/VR-iOS-Experiment
Wenn möglich, würde ich einige Tipps, wie wie man es beheben, bereit, den Code nicht nur & eingefügt sein kopieren. Ich will lernen.
Ich kann es nicht gut erklären, mit Worten, also habe ich einige Videos aufgenommen, Ihnen zu zeigen, was los ist:
iPhone 6: https://www.youtube.com/watch?v=pdyTEwvsR1I
iPhone 5: https://www.youtube.com/watch?v=MlDdKtHkrYo
die Ist hier code:
// Create Scene
var scene = SCNScene()
scnView.scene = scene
//scnView.autoenablesDefaultLighting = true
//Add camera to scene.
let camera = SCNCamera()
camera.xFov = 45
camera.yFov = 45
let camerasNode = SCNNode()
camerasNode.camera = camera
camerasNode.position = SCNVector3(x: 0, y: 0, z: 0)
// The user will be holding their device up (i.e. 90 degrees roll from a flat orientation)
// so roll the camera by -90 degrees to orient the view correctly
// otherwise the object will be created "below" the user
camerasNode.eulerAngles = SCNVector3Make(degreesToRadians(-90.0), 0, 0)
let cameraRollNode = SCNNode()
cameraRollNode.addChildNode(camerasNode)
let cameraPitchNode = SCNNode()
cameraPitchNode.addChildNode(cameraRollNode)
let cameraYawNode = SCNNode()
cameraYawNode.addChildNode(cameraPitchNode)
scene.rootNode.addChildNode(cameraYawNode)
scnView.pointOfView = camerasNode
// Ambient Light
let ambientLight = SCNLight()
ambientLight.type = SCNLightTypeAmbient
ambientLight.color = UIColor(white: 0.1, alpha: 1.0)
let ambientLightNode = SCNNode()
ambientLightNode.light = ambientLight
scene.rootNode.addChildNode(ambientLightNode)
// Omni Light
let diffuseLight = SCNLight()
diffuseLight.type = SCNLightTypeOmni
diffuseLight.color = UIColor(white: 1.0, alpha: 1.0)
let diffuseLightNode = SCNNode()
diffuseLightNode.light = diffuseLight
diffuseLightNode.position = SCNVector3(x: -30, y: 30, z: 50)
scene.rootNode.addChildNode(diffuseLightNode)
let material = SCNMaterial()
material.diffuse.contents = UIColor.redColor()
material.locksAmbientWithDiffuse = true
let material2 = SCNMaterial()
material2.diffuse.contents = UIColor.whiteColor()
material2.locksAmbientWithDiffuse = true
let material3 = SCNMaterial()
material3.diffuse.contents = UIColor.blueColor()
material3.locksAmbientWithDiffuse = true
let material4 = SCNMaterial()
material4.diffuse.contents = UIColor.purpleColor()
material4.locksAmbientWithDiffuse = true
let material5 = SCNMaterial()
material5.diffuse.contents = UIColor.yellowColor()
material5.locksAmbientWithDiffuse = true
let material6 = SCNMaterial()
material6.diffuse.contents = UIColor.orangeColor()
material6.locksAmbientWithDiffuse = true
//Create the box
let baseBox = SCNBox(width: 5, height: 5, length: 5, chamferRadius: 0)
baseBox.materials = [material, material2, material3, material4, material5, material6]
let boxNode = SCNNode(geometry: baseBox)
boxNode.position = SCNVector3(x: 0, y: 3, z: -10)
scene.rootNode.addChildNode(boxNode)
// Respond to user head movement
motionManager = CMMotionManager()
motionManager?.deviceMotionUpdateInterval = 1.0/60.0
motionManager?.startDeviceMotionUpdatesUsingReferenceFrame(CMAttitudeReferenceFrameXArbitraryZVertical,
toQueue: NSOperationQueue.mainQueue(),
withHandler: { (motion: CMDeviceMotion!, error: NSError!) -> Void in
self.counter++
let currentAttitude = motion.attitude
let roll = Float(currentAttitude.roll)
let pitch = Float(currentAttitude.pitch)
let yaw = Float(currentAttitude.yaw)
//only working at 60FPS on iPhone 6... WHY
//according to documentation, SCNVector3 from a node is, (pitch, yaw, node)
cameraRollNode.eulerAngles = SCNVector3Make(0.0, 0.0, -roll)
cameraPitchNode.eulerAngles = SCNVector3Make(pitch, 0.0, 0.0)
cameraYawNode.eulerAngles = SCNVector3Make(0.0, yaw, 0.0)
})
Gute Frage ... weiß nicht ich. Um eine Vermutung zu riskieren, würde ich sagen, dass es etwas mit der Synchronisierung zwischen der Bewegungsaktualisierungswarteschlange und der SCN-Rendering-Schleife zu tun hat. Anstatt diese beiden 60Hz-Prozesse unabhängig voneinander auszuführen und zu versuchen, zwischen ihnen zu kommunizieren, möchten Sie vielleicht die Dinge in einer einzigen 60-Hz-Schleife kombinieren - also nach Bewegungsdaten in der Render-Delegate-Methode Ihrer Szene suchen. (Siehe [die Übersicht im 'CMMotionManager' Dokument] (https://developer.apple.com/library/ios/documentation/CoreMotion/Reference/CMMotionManager_Class/index.html).) – rickster
@rickster Danke! Ich versuche, dies zu implementieren, wie Sie gesagt haben, jetzt ist mein ViewController der Delegat, aber die Delegate-Methode 'render (aRenderer: SCNSceneRenderer, updateAtTime: NSTimeInterval)' wird nur dreimal aufgerufen. Vielleicht weil die Render-Methode das einzige ist, das die Frames aktualisiert? Es ist Art Kurzschluss selbst? –
Yup, als ich 'sceneView.playing = true' am Ende der Methode hinzufügte, zwang dies das Szenen-Kit, das Rendering für immer fortzusetzen, was funktionierte. Ich frage mich, was ist der richtige Weg, dies zu tun? –