SceneKit SCNSceneRendererDelegate-未调用渲染器功能 [英] SceneKit SCNSceneRendererDelegate - renderer function not called

查看:309
本文介绍了SceneKit SCNSceneRendererDelegate-未调用渲染器功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近问了一个问题,答案很明显.我仍在从事同一个项目,并遇到另一个问题.我需要实现每帧逻辑,并且SCNSceneRendererDelegate协议在iOS上工作得很好,但是在OSX上,renderer函数没有触发.我创建了一个小示例项目来说明我的问题.它由情节提要中的场景工具包视图"和ViewController类中的以下代码组成:

I recently asked a question which had a pretty obvious answer. I'm still working on the same project and running into another problem. I need to implement per frame logic and the SCNSceneRendererDelegate protocol worked perfectly fine on iOS, but on OSX, the renderer function is not firing. I have created a little example project to illustrate my problem. It consists of a Scene Kit View in storyboard and following code in the ViewController class:

import Cocoa
import SceneKit

class ViewController: NSViewController, SCNSceneRendererDelegate {

    @IBOutlet weak var sceneView: SCNView!

    let cubeNode = SCNNode()

    override func viewDidLoad() {

        super.viewDidLoad()

        let scene = SCNScene()

        let sphere = SCNSphere(radius: 0.1)
        sphere.firstMaterial!.diffuse.contents = NSColor.yellowColor()
        let sphereNode = SCNNode(geometry: sphere)
        scene.rootNode.addChildNode(sphereNode)

        let cube = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)
        cube.firstMaterial!.diffuse.contents = NSColor.greenColor()
        cubeNode.geometry = cube
        cubeNode.position = SCNVector3(1,0,0)
        scene.rootNode.addChildNode(cubeNode)

        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(2, 1, 2)
        let constraint = SCNLookAtConstraint(target: cubeNode)
        cameraNode.constraints = [constraint]
        scene.rootNode.addChildNode(cameraNode)

        sceneView.scene = scene
        sceneView.backgroundColor = NSColor(red: 0.5, green: 0, blue: 0.3, alpha: 1)
        sceneView.allowsCameraControl = true

        sceneView.delegate = self
        sceneView.playing = true

    }

    func renderer(renderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
        cubeNode.position.x += 0.1
    }
}

我要做的就是基本上在每一帧中移动多维数据集.但是什么也没发生.奇怪的是,当我将sceneView.allowsCameraControl设置为true时,每当我在屏幕上单击或拖动时,都会调用renderer函数(这很有意义,因为它需要根据相机角度更新视图).但是我希望每帧都可以调用它.

All I want is to basically move the cube with every frame. But nothing happens. What is weird is that when I set sceneView.allowsCameraControl to true, the renderer function is called whenever I click or drag on the screen (which makes sense because it needs to update the view based on camera angles). But I would want it to be called every frame.

我没有看到错误或者这是我的Xcode中的错误吗?

Is there an error I don't see or is this a bug in my Xcode?

我已经尝试按照下面答案中的说明进行操作,现在对ViewController使用以下代码:

I have tried following the instructions in the answer below and now have the following code for the ViewController:

import Cocoa
import SceneKit

class ViewController: NSViewController {

    @IBOutlet weak var sceneView: SCNView!
    let scene = MyScene(create: true)

    override func viewDidLoad() {

        super.viewDidLoad()

        sceneView.scene = scene
        sceneView.backgroundColor = NSColor(red: 0.5, green: 0, blue: 0.3, alpha: 1)
        sceneView.allowsCameraControl = true

        sceneView.delegate = scene
        sceneView.playing = true

    }

}

还有一个MyScene类:

And a MyScene class:

import Foundation
import SceneKit

final class MyScene: SCNScene, SCNSceneRendererDelegate {

    let cubeNode = SCNNode()

    convenience init(create: Bool) {
        self.init()

        let sphere = SCNSphere(radius: 0.1)
        sphere.firstMaterial!.diffuse.contents = NSColor.yellowColor()
        let sphereNode = SCNNode(geometry: sphere)
        rootNode.addChildNode(sphereNode)

        let cube = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)
        cube.firstMaterial!.diffuse.contents = NSColor.greenColor()
        cubeNode.geometry = cube
        cubeNode.position = SCNVector3(1,0,0)
        rootNode.addChildNode(cubeNode)

        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(2, 1, 2)
        let constraint = SCNLookAtConstraint(target: cubeNode)
        cameraNode.constraints = [constraint]

        rootNode.addChildNode(cameraNode)
    }

    @objc func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
        cubeNode.position.x += 0.01
    }
}

但是,它仍然无法正常工作.我在做什么错了?

However, it is still not working. What am I doing wrong?

设置sceneView.loops = true可以解决所描述的问题

setting sceneView.loops = true fixes the described problem

推荐答案

我怀疑答案取决于Querent所说的每一帧". Querent可能应该澄清这一点,但是无论如何我都会尝试回答,因为我就是这样.

I suspect the answer hinges on what Querent means by "every frame". Querent should probably clarify this, but I'll try to answer anyway because I'm like that.

最简单的解释可能是无论如何都会渲染的每个帧",但是除非多维数据集旨在用作渲染器的一种活动监视器,否则似乎不太可能是理想的;这似乎也不可能.有更好的方法.

The simplest interpretation is probably "every frame that would render anyway", but that seems unlikely to be what is desired unless the cube is intended as a kind of activity monitor for the renderer, which doesn't seem likely either; there are much better approaches to that.

Querent可能希望在视图的

What Querent may want is to render repeatedly while the view's playing property is YES. If that's the case, then perhaps the answer is as simple as setting the view's loops property to YES. This recently solved a problem for me in which I wanted rendering to occur while a keyboard key was held down. (I had noticed that setting playing to YES would induce a single call to my delegate.)

这篇关于SceneKit SCNSceneRendererDelegate-未调用渲染器功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆