Стерео ARSCNview для создания смешивания VR и AR - swift


1

Я хочу создать смесь virtual reality и augmented reality. Цель состоит в том, что у меня есть стереокамера (для каждого глаза).

Я попытался поместить два ARSCNView в viewCotnroller но кажется, что ARKit одновременно поддерживает только одну ARWorldTrackingSessionConfiguration. Как я могу это сделать?

Я исследовал, чтобы скопировать графическое представление представления в прошлое это на другое представление, но его невозможно найти. Пожалуйста, помогите мне найти решение.

Я нашел эту ссылку, может быть, она может рассказать нам: ARKit с несколькими пользователями

Вот пример моей проблемы:

https://www.youtube.com/watch?v=d6LOqNnYm5s

PS: прежде чем в отличие от моего поста, прокомментируйте почему!

Источник
  •  32
  •  4
  • 9 мар 2020 2020-03-09 15:56:13

4 ответа

0

Objective-C версия ханского кода github, сценарные создания, созданные программно, с положениями 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;
    });

}
1

Для этого воспользуйтесь следующим кодом:

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()
    }
}

И не забудьте активировать свойства .isPlaying экземпляра для обоих ARSCNViews.

enter image description here

  • 9 мар 2020 2020-03-09 15:56:15
3

В документации ARSession говорится, что ARSession является общим объектом.

Для каждого AR-проекта, созданного с помощью ARKit, требуется один объект ARSession. Если вы используете объект ARSCNView или ARSKView, чтобы легко создавать визуальную часть вашего опыта AR, объект view включает экземпляр ARSession. Если вы создаете собственный рендерер для контента AR, вам необходимо создать экземпляр и сохранить объект ARSession самостоятельно.

Так что в этом последнем предложении есть ключ. Вместо двух экземпляров ARSCNView используйте SCNView и разделите одно ARSession между ними.

Я ожидаю, что это распространенный прецедент, поэтому стоит подать заявку на получение радиолокационной информации.

Как это сделать прямо сейчас?

В сеансе (singleton) есть только один делегат. Вам нужно два разных экземпляра делегата: по одному для каждого представления. Вы можете решить это с помощью объекта, который отправляет сообщения делегатов каждому представлению; разрешима, но немного дополнительной работы.

Там также проблема, связанная с необходимостью использования двух слегка разных камер, по одному для каждого глаза, для стереовидения. ARKit использует одну камеру, размещенную на устройстве устройства iOS, поэтому вам придется это путать.

Затем вам приходится иметь дело с различными искажениями ствола для каждого глаза.

Это, для меня, добавляет к написанию моего собственного пользовательского объекта для перехвата сообщений делегатов ARKit, преобразования координат в то, что я вижу из двух разных камер, и управления двумя отдельными SCNView (не ARSCNViews). Или, возможно, используйте один ARSCNView (один глаз), перехватите его обновления кадра и передайте эти кадры в SCNView (другой глаз).

Загрузите радар, опубликуйте номер, и я обману его.

3

Следующий код в основном является тем, что сказал Хэл. Ранее я написал несколько строк на github, которые могли бы помочь вам начать работу. (Простой код, без искажений ствола, без регулировки для узкого FOV - пока).

По сути, мы соединяем одну и ту же сцену со вторым ARSCNView (поэтому оба ARSCNView видят одну и ту же сцену). Не нужно заставлять ARWorldTrackingSessionConfiguration работать с двумя ARSCNView. Затем мы компенсируем его pointOfView, чтобы он позиционировался как 2-й глаз.

https://github.com/hanleyweng/iOS-Stereoscopic-ARKit-Template

  • 9 мар 2020 2020-03-09 15:56:14