ARKit平面检测和可视化无法正常工作

问题描述

我有一个应用程序,我想结合使用React Native,WebView和ARKit。因此,使用此代码,我在彼此之上堆叠了三个视图:

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <SDImageCodersManager.h>
#import <SDWebImageWebPCoder/SDImageWebPCoder.h>
#import <WebKit/WebKit.h>
#import "realnote_app-Swift.h"
#import <ARKit/ARKit.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];
  [theConfiguration.preferences setValue:@"TRUE" forKey:@"allowFileAccessFromFileURLs"];
  [theConfiguration setValue:@"TRUE" forKey:@"allowUniversalAccessFromFileURLs"];
  UrlHandler *urlHandler = [[UrlHandler alloc] init];
  [theConfiguration setURLSchemeHandler:urlHandler  forURLScheme:@"localhost"];
  WKWebView *webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds configuration:theConfiguration];
  webView.opaque = false;
  webView.scrollView.backgroundColor = UIColor.clearColor;
  webView.backgroundColor = UIColor.clearColor;
  

  NSURL *urlpath = [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html" subdirectory:@"html"];
  urlpath = [urlHandler changeURLSchemeWithNewScheme:@"localhost" forURL:urlpath];
  
  NSURLRequest *nsrequest=[NSURLRequest requestWithURL:urlpath];
  [webView loadRequest:nsrequest];
  
  //ARSCNView *arView = [[ARSCNView alloc] initWithFrame:[UIScreen mainScreen].bounds];
  SceneViewRenderer *sceneViewRenderer = [[SceneViewRenderer alloc] init];
  
  
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"realnote_app"
                                            initialProperties:nil];
  rootView.contentView.backgroundColor = UIColor.clearColor;
  

  rootView.backgroundColor = UIColor.clearColor;

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  
  UIView *holderView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
  holderView.backgroundColor = UIColor.clearColor;
  
  rootView.frame = [UIScreen mainScreen].bounds;
  [holderView insertSubview:sceneViewRenderer.view belowSubview:rootView];
  [holderView insertSubview:webView belowSubview:rootView];
  
  [holderView addSubview:rootView];
  
  
  rootViewController.view = holderView;
  self.window.rootViewController = rootViewController;
  
  [self.window makeKeyAndVisible];
  [SDImageCodersManager.sharedManager addCoder:SDImageWebPCoder.sharedCoder];
  
  return YES;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

@end

我的SceneViewRenderer类看起来像这样:

import Foundation
import UIKit
import ARKit

@objc
class SceneViewRenderer: UIViewController,ARSCNViewDelegate {
  
  public var sceneView: ARSCNView!
  
  override func loadView() {
    self.view = ARSCNView(frame: UIScreen.main.bounds)
    sceneView = (self.view as! ARSCNView)
  }
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    configureLighting()
    addTapGestureToSceneView()
    
    
    // Container to hold all of the 3D geometry
    let scene = SCNScene()
    // The 3D cube geometry we want to draw
    let boxGeometry = SCNBox(
        width: 0.1,height: 0.1,length: 0.1,chamferRadius: 0.0)
    // The node that wraps the geometry so we can add it to the scene
    let boxNode = SCNNode(geometry: boxGeometry)
    // Position the box just in front of the camera
    boxNode.position = SCNVector3Make(0,-0.5)
    // rootNode is a special node,it is the starting point of all
    // the items in the 3D scene
    scene.rootNode.addChildNode(boxNode)
    // Set the scene to the view
    sceneView.scene = scene
  }
  
  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    setUpSceneView()
  }
  
  override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    sceneView.session.pause()
  }
  
  func setUpSceneView() {
    let configuration = ARWorldTrackingConfiguration()
    configuration.planeDetection = [.horizontal,.vertical]
    
    sceneView.session.run(configuration)
    
    sceneView.delegate = self
    sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints]
  }
  
  func configureLighting() {
    sceneView.autoenablesDefaultLighting = true
    sceneView.automaticallyUpdatesLighting = true
  }
  
  func addTapGestureToSceneView() {
    let tapGestureRecognizer = UITapGestureRecognizer(target: self,action: #selector(SceneViewRenderer.tapDelegate(withGestureRecognizer:)))
      sceneView.addGestureRecognizer(tapGestureRecognizer)
  }
  
  @objc func tapDelegate(withGestureRecognizer recognizer: UIGestureRecognizer) {
    print("tapped")
  }
  
  @objc func renderer(_ renderer: SCNSceneRenderer,didAdd node: SCNNode,for anchor: ARAnchor) {
    print("Renderer Function")
    // 1
    guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
    
    // 2
    let width = CGFloat(planeAnchor.extent.x)
    let height = CGFloat(planeAnchor.extent.z)
    let plane = SCNPlane(width: width,height: height)
    
    // 3
    plane.materials.first?.diffuse.contents = UIColor.transparentLightBlue
    
    // 4
    let planeNode = SCNNode(geometry: plane)
    
    // 5
    let x = CGFloat(planeAnchor.center.x)
    let y = CGFloat(planeAnchor.center.y)
    let z = CGFloat(planeAnchor.center.z)
    planeNode.position = SCNVector3(x,y,z)
    planeNode.eulerAngles.x = -.pi / 2
    
    // 6
    node.addChildNode(planeNode)
    sceneView.scene.rootNode.addChildNode(planeNode)
  }
  
  
  @objc func renderer(_ renderer: SCNSceneRenderer,didUpdate node: SCNNode,for anchor: ARAnchor) {
    print("Renderer Function")
    // 1
    guard let planeAnchor = anchor as?  ARPlaneAnchor,let planeNode = node.childNodes.first,let plane = planeNode.geometry as? SCNPlane
      else { return }
    
    // 2
    let width = CGFloat(planeAnchor.extent.x)
    let height = CGFloat(planeAnchor.extent.z)
    plane.width = width
    plane.height = height
    
    // 3
    let x = CGFloat(planeAnchor.center.x)
    let y = CGFloat(planeAnchor.center.y)
    let z = CGFloat(planeAnchor.center.z)
    planeNode.position = SCNVector3(x,z)
  }
}

extension float4x4 {
  var translation: float3 {
    let translation = self.columns.3
    return float3(translation.x,translation.y,translation.z)
  }
}

extension UIColor {
  open class var transparentLightBlue: UIColor {
    return UIColor(red: 90/255,green: 200/255,blue: 250/255,alpha: 0.50)
  }
}

我可以看到我的react按钮(它们仅在角落,其余部分是透明的),我还可以看到WebView的内容(一个元素,其余部分也是透明的),并且可以看到立方体我使用ARKit以及ARKit的特征点进行渲染。无效的是可视化飞机。即使我在实现的两个函数中设置了断点,也不会调用这些断点。我犯了什么错误?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...