Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 立体视图,使VR和AR混合_Swift_Augmented Reality_Arkit_Virtual Reality_Arscnview - Fatal编程技术网

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上,我们可以找到很多有两张相同图片的视频。。这是一个非常大的开始!天哪,这正是我要找的!我是新来的