ARKit –如何显示来自放置在SCNPlane上的虚拟SCNCamera的提要? [英] ARKit – How to display the feed from a virtual SCNCamera placed on SCNPlane?

查看:85
本文介绍了ARKit –如何显示来自放置在SCNPlane上的虚拟SCNCamera的提要?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用ARKit和SceneKit在AR空间中放置了一些对象.那很好.现在,我想添加一个附加的摄像机(SCNCamera),该摄像机放置在场景中其他地方,并由一个公共SCNNode定位.它旨在从另一个(固定的)角度向我展示当前场景.

现在,我想在i.Ex上显示此额外的SCNCamera供稿.SCNPlane(作为漫反射的第一材质)-就像电视屏幕一样.当然,我知道它只会显示停留在相机焦点上的SceneKit内容,而不显示ARKit图像的其余部分(当然,这只能由主相机实现).这样简单的彩色背景就可以了.

我看过一些教程,其中描述了如何在ARSpace中的虚拟显示器上播放视频文件,但是我需要从自己当前的场景中获取实时的摄像机提要.

我定义了这个对象:

 让相机= SCNCamera()让cameraNode = SCNNode() 

然后在viewDidLoad中执行此操作:

  camera.usesOrthographicProjection = truecamera.orthographicScale = 9camera.zNear = 0camera.zFar = 100cameraNode.camera =摄影机sceneView.scene.rootNode.addChildNode(cameraNode) 

然后我调用我的设置函数,将虚拟Display放置在我所有AR物品的旁边,同时也放置cameraNode(指向对象在场景中停留的方向)

  cameraNode.position = SCNVector3(initialStartPosition.x,initialStartPosition.y + 0.5,initialStartPosition.z)让cameraPlane = SCNNode(几何形状:SCNPlane(宽度:0.5,高度:0.3))cameraPlane.geometry?.firstMaterial?.diffuse.contents = cameraNode.cameracameraPlane.position = SCNVector3(initialStartPosition.x-1.0,initialStartPosition.y + 0.5,initialStartPosition.z)sceneView.scene.rootNode.addChildNode(cameraPlane) 

所有内容都会编译并加载...显示屏显示在给定位置,但始终保持灰色.我放在场景中的SCNCamera根本什么都没有显示.AR场景中的所有其他东西都运作良好,我只是没有从那台相机得到任何提要.

有没有人使这种情况奏效的方法?

为了更好地可视化,我添加了更多的打印屏幕.

以下显示了根据ARGeo的输入通过SCNCamera的图像.但是它占用了整个屏幕,而不是像我需要的那样在SCNPlane上显示其内容.

下一个打印"屏幕实际上显示了我使用发布的代码得到的当前ARView结果.如您所见,灰色的Display-Plane保持灰色-它什么也没显示.

最后一个打印屏幕是照片蒙太奇,显示了我想要得到的预期结果.

这怎么可能实现?我在这里缺少基本的东西吗?

解决方案

经过研究和睡眠,我得出了以下可行的解决方案(包括一些无法解释的障碍):

目前,附加的SCNCamera供稿尚未链接到SCNPlane上的SCNMaterial,因为这是最初的想法,但我将暂时使用附加的SCNView

在定义中,我添加另一个视图,如下所示:

  let overlayView = SCNView()//(也已通过ARSCNView()测试,没有区别)让相机= SCNCamera()让cameraNode = SCNNode() 

然后,在viewDidLoad中,我像这样设置东西...

  camera.automaticallyAdjustsZRange = truecamera.usesOrthographicProjection = falsecameraNode.camera =摄影机cameraNode.camera?.focalLength = 50sceneView.scene.rootNode.addChildNode(cameraNode)//将节点添加到默认场景overlayView.scene = scene//与sceneView相同的场景overlayView.allowsCameraControl = falseoverlayView.isUserInteractionEnabled = falseoverlayView.pointOfView = cameraNode////将新的SCNView链接到创建的SCNCameraself.view.addSubview(overlayView)//不要忘记添加为子视图//调整视图大小并将其放在底部overlayView.frame = CGRect(x:0,y:0,宽度:self.view.bounds.width * 0.8,高度:self.view.bounds.height * 0.25)overlayView.center = CGPoint(x:self.view.bounds.width * 0.5,y:self.view.bounds.height-175) 

然后,在其他功能中,将包含SCNCamera的节点放置到所需的位置和角度.

 //(示例性)cameraNode.position = initialStartPosition + SCNVector3(x:-0.5,y:0.5,z:-(Float(shiftCurrentDistance * 2.0-2.0)))cameraNode.eulerAngles = SCNVector3(-15.0.degreesToRadians,-15.0.degreesToRadians,0.0) 

结果是屏幕底部的一种窗口(新的SCNView),显示与主sceneView相同的SceneKit内容,通过SCNCamera的透视图及其节点位置进行查看,这非常好

在一个常见的iOS/Swift/ARKit项目中,此构造会产生一些副作用,可能会引起人们的困扰.

1)主要是,新的SCNView从所需的角度显示SceneKit的内容,但背景始终是实际的物理摄像机提要.我仍然无法通过仍然显示所有SceneKit内容来弄清楚如何使背景成为静态颜色.更改新场景的background属性也会影响整个主场景,这实际上是不希望的.

2)听起来可能令人困惑,但是只要包含以下代码(这对于使其工作必不可少):

  overlayView.scene =场景 

整个场景(两个)的动画速度加倍!(为什么?)

我通过添加/更改以下属性来更正此问题,该属性使动画速度的行为几乎恢复为正常状态(默认):

 //在场景设置中添加或更改scene.physicsWorld.speed = 0.5 

3)如果项目中有类似SCNAction.playAudio的动作,则所有效果都将不再播放-只要我不这样做:

  overlayView.scene = nil 

当然,附加的SCNView会停止工作,但其他所有操作都会恢复正常.

I put some objects in AR space using ARKit and SceneKit. That works well. Now I'd like to add an additional camera (SCNCamera) that is placed elsewhere in the scene attached and positioned by a common SCNNode. It is oriented to show me the current scene from an other (fixed) perspective.

Now I'd like to show this additional SCNCamera feed on i.Ex. a SCNPlane (as the diffuse first material) - Like a TV screen. Of course I am aware that it will only display the SceneKit content which stays in the camera focus and not rest of the ARKit image (which is only possible by the main camera of course). A simple colored background then would be fine.

I have seen tutorials that describes, how to play a video file on a virtual display in ARSpace, but I need a realtime camera feed from my own current scene.

I defined this objects:

let camera = SCNCamera()
let cameraNode = SCNNode()

Then in viewDidLoad I do this:

camera.usesOrthographicProjection = true
camera.orthographicScale = 9
camera.zNear = 0
camera.zFar = 100
cameraNode.camera = camera
sceneView.scene.rootNode.addChildNode(cameraNode)

Then I call my setup function to place the virtual Display next to all my AR stuff, position the cameraNode as well (pointing in the direction where objects stay in the scene)

cameraNode.position = SCNVector3(initialStartPosition.x, initialStartPosition.y + 0.5, initialStartPosition.z)

let cameraPlane = SCNNode(geometry: SCNPlane(width: 0.5, height: 0.3))
cameraPlane.geometry?.firstMaterial?.diffuse.contents = cameraNode.camera
cameraPlane.position = SCNVector3(initialStartPosition.x - 1.0, initialStartPosition.y + 0.5, initialStartPosition.z)

sceneView.scene.rootNode.addChildNode(cameraPlane)

Everything compiles and loads... The display shows up at the given position, but it stays entirely gray. Nothing is displayed at all from the SCNCamera I put in the scene. Everything else in the AR scene works well, I just don't get any feed from that camera.

Hay anyone an approach to get this scenario working?

To even better visualize, I add some more print screens.

The following shows the Image trough the SCNCamera according to ARGeo's input. But it takes the whole screen, instead of displaying its contents on a SCNPlane, like I need.

The next Print screen actually shows the current ARView result as I got it using my posted code. As you can see, the gray Display-Plane remains gray - it shows nothing.

The last print screen is a photomontage, showing the expected result, as I'd like to get.

How could this be realized? Am I missing something fundamental here?

解决方案

After some research and sleep, I came to the following, working solution (including some inexplainable obstacles):

Currently, the additional SCNCamera feed is not linked to a SCNMaterial on a SCNPlane, as it was the initial idea, but I will use an additional SCNView (for the moment)

In the definitions I add an other view like so:

let overlayView   = SCNView() // (also tested with ARSCNView(), no difference)
let camera        = SCNCamera()
let cameraNode    = SCNNode()

then, in viewDidLoad, I setup the stuff like so...

camera.automaticallyAdjustsZRange = true
camera.usesOrthographicProjection = false
cameraNode.camera                 = camera
cameraNode.camera?.focalLength    = 50
sceneView.scene.rootNode.addChildNode(cameraNode) // add the node to the default scene

overlayView.scene                    = scene // the same scene as sceneView
overlayView.allowsCameraControl      = false
overlayView.isUserInteractionEnabled = false
overlayView.pointOfView              = cameraNode // this links the new SCNView to the created SCNCamera
self.view.addSubview(overlayView)    // don't forget to add as subview

// Size and place the view on the bottom
overlayView.frame  = CGRect(x: 0, y: 0, width: self.view.bounds.width * 0.8, height: self.view.bounds.height * 0.25)
overlayView.center = CGPoint(x: self.view.bounds.width * 0.5, y: self.view.bounds.height - 175)

then, in some other function, I place the node containing the SCNCamera to my desired position and angle.

// (exemplary)
cameraNode.position = initialStartPosition + SCNVector3(x: -0.5, y: 0.5, z: -(Float(shiftCurrentDistance * 2.0 - 2.0)))          
cameraNode.eulerAngles = SCNVector3(-15.0.degreesToRadians, -15.0.degreesToRadians, 0.0)

The result, is a kind of window (the new SCNView) at the bottom of the screen, displaying the same SceneKit content as in the main sceneView, viewed trough the perspective of the SCNCamera plus its node position, and that very nicely.

In a common iOS/Swift/ARKit project, this construct generates some side effects, that one may struggle into.

1) Mainly, the new SCNView shows SceneKit content from the desired perspective, but the background is always the actual physical camera feed. I could not figure out, how to make the background a static color, by still displaying all the SceneKit content. Changing the new scene's background property affects also the whole main scene, what is actually NOT desired.

2) It might sound confusing, but as soon as the following code get's included (which is essential to make it work):

overlayView.scene = scene

the animation speed of the entire scenes (both) DOUBLES! (Why?)

I got this corrected by adding/changing the following property, which restores the animation speed behavour almost like normal (default):

// add or change this in the scene setup
scene.physicsWorld.speed = 0.5

3) If there are actions like SCNAction.playAudio in the project, all the effects will no longer play - as long as I don't do this:

overlayView.scene = nil

Of course, the additional SCNView stops working but everything else gets gets back to its normal.

这篇关于ARKit –如何显示来自放置在SCNPlane上的虚拟SCNCamera的提要?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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