Текстура комнаты отображается не полностью, когда я перемещаю SCNCamera вокруг SCNBox внутри виртуальной комнаты с помощью SceneKit

#swift #scenekit

#swift #scenekit

Вопрос:

Я попытался создать виртуальную комнату с помощью SceneKit и поместить в нее поле. Также я создал отдельный узел с камерой под названием ‘cameraOrbitNode’ (камера расположена между стеной комнаты и коробкой). Основная цель — переместить ‘cameraOrbitNode’ вокруг окна внутри комнаты. Я реализовал это с помощью распознавателя жестов панорамирования.

импорт UIKit импорт SceneKit

перечисление WallType { case left case right case top case bottom case forward case back }

класс ViewController: UIViewController {

 //MARK: - Outlets
@IBOutlet fileprivate weak var sceneView: SCNView!

//MARK: - Properties
fileprivate let roomLength: CGFloat = 12
fileprivate let cubeLength: CGFloat = 1
fileprivate var cameraOrbitNode: SCNNode?
fileprivate let panModifier: CGFloat = 100

//MARK: - Life cycle
override func viewDidLoad() {
    super.viewDidLoad()

    setupSceneView()
    setupRoom()
    setupCameraOrbitNode()
    setupGestures()
}

func setupSceneView() {
    sceneView.scene = SCNScene()
    sceneView.autoenablesDefaultLighting = true
}

func setupRoom() {
    let roomNode = SCNNode()
    roomNode.position = SCNVector3(0, 0, 0)
    for wallType in Array<WallType>([.left, .right, .top, .bottom, .forward, .back]) {
        roomNode.addChildNode(getWallNodeWith(wallType: wallType))
    }
    roomNode.addChildNode(getCubeNode())
    sceneView.scene?.rootNode.addChildNode(roomNode)
}

func getWallNodeWith(wallType: WallType) -> SCNNode {
    let wallGeometrySize = getWallSize()
    let wallGeometry = SCNPlane(width: wallGeometrySize.width, height: wallGeometrySize.height)
    wallGeometry.firstMaterial?.diffuse.contents = UIColor.darkGray
    let wallNode = SCNNode(geometry: wallGeometry)
    wallNode.position = getWallPositionWith(wallType: wallType)
    wallNode.eulerAngles = getWallEulerAnglesWith(wallType: wallType)
    return wallNode
}

func getWallSize() -> CGSize {
    return CGSize(width: roomLength, height: roomLength)
}

func getWallPositionWith(wallType: WallType) -> SCNVector3 {
    switch wallType {
    case .left:
        return SCNVector3(-roomLength / 2, 0, 0)
    case .right:
        return SCNVector3(roomLength / 2, 0, 0)
    case .forward:
        return SCNVector3(0, 0, -roomLength / 2)
    case .back:
        return SCNVector3(0, 0, roomLength / 2)
    case .top:
        return SCNVector3(0, roomLength / 2, 0)
    case .bottom:
        return SCNVector3(0, -roomLength / 2, 0)
    }
}

func getWallEulerAnglesWith(wallType: WallType) -> SCNVector3 {
    switch wallType {
    case .left, .right:
        return SCNVector3(0, CGFloat.pi / 2, 0)
    case .forward, .back:
        return SCNVector3(0, 0, 0)
    case .top, .bottom:
        return SCNVector3(CGFloat.pi / 2, 0, 0)
    }
}

func getCubeNode() -> SCNNode {
    let cubeGeometry = SCNBox(width: cubeLength, height: cubeLength, length: cubeLength, chamferRadius: 0)
    cubeGeometry.firstMaterial?.diffuse.contents = UIColor.blue
    let cubeNode = SCNNode(geometry: cubeGeometry)
    cubeNode.position = SCNVector3(0, 0, 0)
    return cubeNode
}

func setupCameraOrbitNode() {
    let camera = SCNCamera()
    camera.zNear = 0
    camera.zFar = Double(roomLength)
    let cameraNode = SCNNode()
    cameraNode.position = SCNVector3(0, 0, (roomLength   cubeLength) / 4)
    cameraNode.camera = camera
    cameraOrbitNode = SCNNode()
    guard let cameraOrbitNode = cameraOrbitNode else { return }

    cameraOrbitNode.addChildNode(cameraNode)
    cameraOrbitNode.position = SCNVector3(0, 0, 0)
    sceneView.scene?.rootNode.addChildNode(cameraOrbitNode)
}

@objc func actionPan(gesture: UIPanGestureRecognizer) {
    let translation = gesture.velocity(in: gesture.view)
    cameraOrbitNode?.eulerAngles.y -= Float(translation.x/CGFloat(panModifier)) * .pi / 180
    cameraOrbitNode?.eulerAngles.x -= Float(translation.y/CGFloat(panModifier)) * .pi / 180
}

func setupGestures() {
    sceneView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(actionPan(gesture:))))
}
  

}

Но в некоторых случаях вы можете видеть прозрачные стены комнаты (в основном текстура комнаты отображается не полностью, когда я перемещаю камеру вокруг коробки). Я менял некоторые свойства камеры (zNear, zFar), но ничего не помогло. Пожалуйста, посмотрите ссылки на изображения, прикрепленные ниже. Большое спасибо за любую помощь. https://www.dropbox.com/s/ihxjrsgjfzidoff/IMG_0187.PNG?dl=0
https://www.dropbox.com/s/wd23xepcir3wggk/IMG_0188.PNG?dl=0

Ответ №1:

установите значение isDoubleSdided в true

 node.geometry?.firstMaterial?.isDoubleSided = true