ios – Black Background momentary seems on SCNNode

Spread the love


I’m making a primary interactive globe utilizing SceneKit and SCNNodes. My most important SCNNode, the earth node, is meant to be formed as a sphere (with no background). The background added to a scene is a .scnp star constellation. Once I rotate the globe a black background seems on the EarthNode which covers the SCNParticleSystem. This black background does not at all times seem however normally exhibits up when the globe is rotated.

I attempted: sceneView.backgroundColor = .clear however this did not work.

import Basis
import SceneKit
import CoreImage
import SwiftUI
import MapKit

public typealias GenericController = UIViewController
public typealias GenericColor = UIColor
public typealias GenericImage = UIImage

public class GlobeViewController: GenericController {
    //@Binding var showProf: Bool
    var nodePos: CGPoint? = nil
    public var earthNode: SCNNode!
    non-public var sceneView : SCNView!
    non-public var cameraNode: SCNNode!
    non-public var worldMapImage: CGImage {
        guard let picture = UIImage(named: "earth-dark")?.cgImage else {
            fatalError("Not discovered")
        }
        return picture
    }
   

    non-public var dotCount = 50000
    
    public init(earthRadius: Double) {//, showProf: Binding<Bool>
        self.earthRadius = earthRadius
        //self._showProf = showProf
        tremendous.init(nibName: nil, bundle: nil)
    }
    
    public init(earthRadius: Double, dotCount: Int) {//, showProf: Binding<Bool>
        self.earthRadius = earthRadius
        self.dotCount = dotCount
        //self._showProf = showProf
        tremendous.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been carried out")
    }

    public override func touchesBegan(_ touches: Set<UITouch>, with occasion: UIEvent?) {
        guard let contact = touches.first, contact.view == self.sceneView else {
            return
        }

        let touchLocation = contact.location(in: sceneView)
        let hitTestResults = sceneView.hitTest(touchLocation, choices: nil)
        
        let touchLocation3D = sceneView.unprojectPoint(SCNVector3(Float(touchLocation.x), Float(touchLocation.y), 0.0))
        
        print(touchLocation3D)
        
        if let tappedNode = hitTestResults.first?.node {
            print(tappedNode)
            // Deal with the tapped node
            if tappedNode.identify == "NewYorkDot" {
                // That is the New York dot, carry out your motion right here
                print("Tapped on New York! Place: (tappedNode.place)")
            } else if tappedNode.identify == "RegularDot" {
                // Deal with different nodes if wanted
                print("Tapped on an everyday dot. Place: (tappedNode.place)")
            }
        }
    }

    public override func viewDidLoad() {
        tremendous.viewDidLoad()
        setupScene()
        
        setupParticles()
        
        setupCamera()
        setupGlobe()
        
        setupDotGeometry()
    }
    
    non-public func setupScene() {
        let scene = SCNScene()
        sceneView = SCNView(body: view.body)
    
        sceneView.scene = scene
        
//        let tapGesture = UITapGestureRecognizer(goal: self, motion: #selector(handleTap(_:)))
//        sceneView.addGestureRecognizer(tapGesture)

        sceneView.showsStatistics = true
        sceneView.backgroundColor = .clear
        sceneView.allowsCameraControl = true
        sceneView.isUserInteractionEnabled = true
        
        self.view.addSubview(sceneView)
    }
        
    non-public func setupParticles() {
        guard let stars = SCNParticleSystem(named: "StarsParticles.scnp", inDirectory: nil) else { return }
        stars.isLightingEnabled = false
                
        if sceneView != nil {
            sceneView.scene?.rootNode.addParticleSystem(stars)
        }
    }
    
    non-public func setupCamera() {
        self.cameraNode = SCNNode()
        cameraNode.digicam = SCNCamera()
        cameraNode.place = SCNVector3(x: 0, y: 0, z: 5)
        
        sceneView.scene?.rootNode.addChildNode(cameraNode)

    }

    non-public func setupGlobe() {
        self.earthNode = EarthNode(radius: earthRadius, earthColor: earthColor, earthGlow: glowColor, earthReflection: reflectionColor)
        sceneView.scene?.rootNode.addChildNode(earthNode)
    }

    non-public func setupDotGeometry() {
        let textureMap = generateTextureMap(dots: dotCount, sphereRadius: CGFloat(earthRadius))

        let newYork = CLLocationCoordinate2D(latitude: 44.0682, longitude: -121.3153)
        let newYorkDot = closestDotPosition(to: newYork, in: textureMap)

        let dotColor = GenericColor(white: 1, alpha: 1)
        let oceanColor = GenericColor(cgColor: UIColor.systemRed.cgColor)
        let highlightColor = GenericColor(cgColor: UIColor.systemRed.cgColor)
        
        // threshold to find out if the pixel within the earth-dark.jpg represents terrain (0.03 represents rgb(7.65,7.65,7.65), which is sort of black)
        let threshold: CGFloat = 0.03
        
        let dotGeometry = SCNSphere(radius: dotRadius)
        dotGeometry.firstMaterial?.diffuse.contents = dotColor
        dotGeometry.firstMaterial?.lightingModel = SCNMaterial.LightingModel.fixed
        
        let highlightGeometry = SCNSphere(radius: dotRadius)
        highlightGeometry.firstMaterial?.diffuse.contents = highlightColor
        highlightGeometry.firstMaterial?.lightingModel = SCNMaterial.LightingModel.fixed
        
        let oceanGeometry = SCNSphere(radius: dotRadius)
        oceanGeometry.firstMaterial?.diffuse.contents = oceanColor
        oceanGeometry.firstMaterial?.lightingModel = SCNMaterial.LightingModel.fixed
        
        var positions = [SCNVector3]()
        var dotNodes = [SCNNode]()
        
        var highlightedNode: SCNNode? = nil
        
        for i in 0...textureMap.rely - 1 {
            let u = textureMap[i].x
            let v = textureMap[i].y
            
            let pixelColor = self.getPixelColor(x: Int(u), y: Int(v))
            let isHighlight = u == newYorkDot.x && v == newYorkDot.y
            
            if (isHighlight) {
                let dotNode = SCNNode(geometry: highlightGeometry)
                dotNode.identify = "NewYorkDot"
                dotNode.place = textureMap[i].place
                positions.append(dotNode.place)
                dotNodes.append(dotNode)
                
                print("myloc (textureMap[i].place)")
                
                highlightedNode = dotNode
            } else if (pixelColor.crimson < threshold && pixelColor.inexperienced < threshold && pixelColor.blue < threshold) {
                let dotNode = SCNNode(geometry: dotGeometry)
                dotNode.identify = "Different"
                dotNode.place = textureMap[i].place
                positions.append(dotNode.place)
                dotNodes.append(dotNode)
            }
        }
        
        DispatchQueue.most important.async {
            let dotPositions = positions as NSArray
            let dotIndices = NSArray()
            let supply = SCNGeometrySource(vertices: dotPositions as! [SCNVector3])
            let factor = SCNGeometryElement(indices: dotIndices as! [Int32], primitiveType: .level)
            
            let pointCloud = SCNGeometry(sources: [source], components: [element])
            
            let pointCloudNode = SCNNode(geometry: pointCloud)
            for dotNode in dotNodes {
                pointCloudNode.addChildNode(dotNode)
            }
     
            self.sceneView.scene?.rootNode.addChildNode(pointCloudNode)
            
        }
   }
}


typealias GenericControllerRepresentable = UIViewControllerRepresentable

@accessible(iOS 13.0, *)
non-public struct GlobeViewControllerRepresentable: GenericControllerRepresentable {
    var particles: SCNParticleSystem? = nil
    //@Binding public var showProf: Bool

    func makeUIViewController(context: Context) -> GlobeViewController {
        let globeController = GlobeViewController(earthRadius: 1.0)//, showProf: $showProf
        updateGlobeController(globeController)
        return globeController
    }
    
    func updateUIViewController(_ uiViewController: GlobeViewController, context: Context) {
        updateGlobeController(uiViewController)
    }
    
    non-public func updateGlobeController(_ globeController: GlobeViewController) {
        globeController.dotSize = CGFloat(0.005)
              
        globeController.enablesParticles = true
        
        if let particles = particles {
            globeController.particles = particles
        }
    }
}

@accessible(iOS 13.0, *)
public struct GlobeView: View {
    //@Binding public var showProf: Bool
    
    public var physique: some View {
        GlobeViewControllerRepresentable()//showProf: $showProf
    }
} 

Leave a Reply

Your email address will not be published. Required fields are marked *