Swift 立体视图,使VR和AR混合
我想混合使用Swift 立体视图,使VR和AR混合,swift,augmented-reality,arkit,virtual-reality,arscnview,Swift,Augmented Reality,Arkit,Virtual Reality,Arscnview,我想混合使用虚拟现实和增强现实。 目标是我有一个立体相机(每只眼睛) 我试图将两个ARSCNView放在viewcontnroller中,但似乎它同时只启用一个arworldctrackingsessionconfiguration。我该怎么做 我研究了将一个视图的图形表示复制到另一个视图,但找不到。请帮我找到解决办法 我找到了这个链接,也许它能启发我们: 以下是我的问题示例: PS:以前不像我的帖子,评论为什么 表示ARSession是一个共享对象 使用ARKit构建的每个AR体验都需要一
虚拟现实
和增强现实
。
目标是我有一个立体相机(每只眼睛)
我试图将两个ARSCNView
放在viewcontnroller
中,但似乎它同时只启用一个arworldctrackingsessionconfiguration
。我该怎么做
我研究了将一个视图的图形表示复制到另一个视图,但找不到。请帮我找到解决办法
我找到了这个链接,也许它能启发我们:
以下是我的问题示例:
PS:以前不像我的帖子,评论为什么 表示ARSession
是一个共享对象
使用ARKit构建的每个AR体验都需要一个ARSession对象。如果你使用
ARSCNView
或
阿什克维尤
对象要轻松构建AR体验的可视部分,view对象包含一个ARSession实例。如果为AR内容构建自己的渲染器,则需要自己实例化和维护ARSession对象
最后一句话里有个线索。不要使用两个ARSCNView
实例,而是使用SCNView
并在它们之间共享单个ARSession
我认为这是一个常见的使用案例,因此值得申请一个雷达来请求立体声支持
现在怎么做
(单例)会话只有一个委托。您需要两个不同的代理实例,每个视图一个。您可以使用一个对象来解决这个问题,该对象将代理消息发送到每个视图;可以解决,但需要一点额外的工作
还有一个问题是立体视觉需要两个稍微不同的摄像机位置,每只眼睛一个。ARKit使用一个摄像头,放置在iOS设备的位置上,因此您必须对其进行模糊处理
然后你必须为每只眼睛处理不同的桶形失真
对我来说,这等于编写了我自己的自定义对象来截获ARKit委托消息,将坐标转换为我从两个不同摄像头看到的坐标,并管理两个不同的SCNViews(而不是ArscnView)。或者使用一个ARSCNView(一只眼睛),截取其帧更新,并将这些帧传递给SCNView(另一只眼睛)
把雷达存档,把号码贴出来,我会复制它 下面的代码基本上就是哈尔说的。我之前在github上写了几行代码,也许可以帮助您开始。(代码简单,无枪管变形,窄视场无需调整-尚未) 本质上,我们将同一场景连接到第二个ARSCNView(因此两个ARSCNView看到的是同一场景)。无需让ARWorldTrackingSessionConfiguration使用2个ArsCNView。然后,我们偏移它的视角,使其定位为第二只眼睛
韩寒github代码的Objective-C版本,通过编程创建的SceneView,y+z位置未更新-所有韩寒:
-(void)setup{
//left
leftSceneView = [ARSCNView new];
leftSceneView.frame = CGRectMake(0, 0, w, h/2);
leftSceneView.delegate = self;
leftSceneView.autoenablesDefaultLighting = true;
[self.view addSubview:leftSceneView];
//right
rightSceneView = [ARSCNView new];
rightSceneView.frame = CGRectMake(0, h/2, w, h/2);
rightSceneView.playing = true;
rightSceneView.autoenablesDefaultLighting = true;
[self.view addSubview:rightSceneView];
//scene
SCNScene * scene = [SCNScene new];
leftSceneView.scene = scene;
rightSceneView.scene = scene;
//tracking
ARWorldTrackingConfiguration * configuration = [ARWorldTrackingConfiguration new];
configuration.planeDetection = ARPlaneDetectionHorizontal;
[leftSceneView.session runWithConfiguration:configuration];
}
-(void)renderer:(id<SCNSceneRenderer>)renderer updateAtTime:(NSTimeInterval)time {
dispatch_async(dispatch_get_main_queue(), ^{
//update right eye
SCNNode * pov = self->leftSceneView.pointOfView.clone;
SCNQuaternion orientation = pov.orientation;
GLKQuaternion orientationQuaternion = GLKQuaternionMake(orientation.x, orientation.y, orientation.z, orientation.w);
GLKVector3 eyePosition = GLKVector3Make(1, 0, 0);
GLKVector3 rotatedEyePosition = GLKQuaternionRotateVector3(orientationQuaternion, eyePosition);
SCNVector3 rotatedEyePositionSCNV = SCNVector3Make(rotatedEyePosition.x, rotatedEyePosition.y, rotatedEyePosition.z);
float mag = 0.066f;
float rotatedX = pov.position.x + rotatedEyePositionSCNV.x * mag;
float rotatedY = pov.position.y;// + rotatedEyePositionSCNV.y * mag;
float rotatedZ = pov.position.z;// + rotatedEyePositionSCNV.z * mag;
[pov setPosition:SCNVector3Make(rotatedX, rotatedY, rotatedZ)];
self->rightSceneView.pointOfView = pov;
});
}
-(无效)设置{
//左
leftSceneView=[ARSCNView新建];
leftSceneView.frame=CGRectMake(0,0,w,h/2);
leftSceneView.delegate=self;
leftSceneView.autoenablesDefaultLighting=true;
[self.view addSubview:leftSceneView];
//对
rightSceneView=[ARSCNView新建];
rightSceneView.frame=CGRectMake(0,h/2,w,h/2);
rightSceneView.playing=true;
rightSceneView.autoenablesDefaultLighting=true;
[self.view addSubview:rightSceneView];
//场面
SCNScene*场景=[SCNScene新建];
leftSceneView.scene=场景;
rightSceneView.scene=场景;
//追踪
ARWorldTrackingConfiguration*configuration=[ARWorldTrackingConfiguration new];
configuration.planeDetection=ARPlaneDetectionHorizontal;
[leftSceneView.session runWithConfiguration:configuration];
}
-(void)渲染器:(id)渲染器更新时间:(NSTimeInterval)时间{
dispatch\u async(dispatch\u get\u main\u queue()^{
//更新右眼
SCNNode*pov=self->leftSceneView.pointOfView.clone;
scnqueternion方向=pov.方向;
GLKQuaternion方向quaternion=GLKQuaternionMake(方向.x,方向.y,方向.z,方向.w);
GLKVector3眼位=GLKVector3Make(1,0,0);
GLKVector3 rotatedEyePosition=GLKquaternionRotatedEyector3(方向四元数,眼睛位置);
SCInvector3 rotatedEyePositionSCNV=SCInvector3Make(rotatedEyePosition.x,rotatedEyePosition.y,rotatedEyePosition.z);
浮子磁极=0.066f;
浮动旋转x=pov.position.x+旋转Y位置CNV.x*mag;
浮动旋转y=pov.position.y;//+RotatedeyPositionSCNV.y*mag;
浮动旋转z=pov.position.z;//+ROTATEDEYESPOSITIONSCNV.z*mag;
[pov设置位置:SCInvector3Make(旋转X、旋转Y、旋转Z)];
self->rightSceneView.pointOfView=pov;
});
}
要完成此操作,请使用以下代码:
import UIKit
import SceneKit
import ARKit
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet weak var sceneView: ARSCNView!
@IBOutlet weak var sceneView2: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
sceneView.showsStatistics = true
let scene = SCNScene(named: "art.scnassets/ship.scn")!
sceneView.scene = scene
sceneView.isPlaying = true
// SceneView2 Setup
sceneView2.scene = scene
sceneView2.showsStatistics = sceneView.showsStatistics
// Now sceneView2 starts receiving updates
sceneView2.isPlaying = true
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let configuration = ARWorldTrackingConfiguration()
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
sceneView.session.pause()
}
}
不要忘记激活。为两个ARSCNViews
的实例属性进行显示
非常感谢您的完整回答!但是,ARSession不参与SCNView。我终于无法想象如何做到这一点。代理需要包含会话的所有数据,但这是不可能的,因为我们无法访问所有数据。或者我的知识有点贫乏。使用ARSessionDelegate方法之一,可能是会话(session:ARSession,didUpdate frame:ARFrame)
。在那里捕获AR帧,将其传递给自定义调度程序,然后调度程序将其传递给每个SCNView以用作背景。就像我说的,很多工作。而且你的每只眼睛仍然使用相同的相机图像,所以我认为即使你让它工作,它也不会是令人满意的立体效果。好的,谢谢!真的很抱歉,我对这种编程还不熟悉。。现在,我的立体声音响不会是立体声的。在youtube上,我们可以找到很多有两张相同图片的视频。。这是一个非常大的开始!天哪,这正是我要找的!我是新来的