Post

Replies

Boosts

Views

Activity

Reply to SceneView selective draw since concurrency
Oh my Word guys, the solution was as simple as can be but what a challenge. The line above: precessionNode.simdTransform = float4x4([Float(0.5.squareRoot()),Float(0.5.squareRoot()),0,0], [-Float(0.5.squareRoot()),Float(0.5.squareRoot()),0,0],[0,0,1,0],[0,0,0,0]) needed to be: precessionNode.simdTransform = float4x4([Float(0.5.squareRoot()),Float(0.5.squareRoot()),0,0], [-Float(0.5.squareRoot()),Float(0.5.squareRoot()),0,0],[0,0,1,0],[0,0,0,1]) How it got corrupted idk. One little character!
Topic: Graphics & Games SubTopic: SceneKit Tags:
Feb ’25
Reply to SceneView selective draw since concurrency
OK, took a while. Here is a greatly reduced bit of code that should, but does not show my nodes. // ContentView.swift // SendToForum // // Created on 1/25/25. // import SwiftUI import SceneKit struct ContentView: View { @State private var fs_cv = "2" private let scene = makeAScene() private struct box: Identifiable { let radius: Int let position: [simd_float3] var id: String { String(radius) } } private let boxFlake:[box] = [ box(radius: 0, position: [ simd_float3(0, 0, 0)]), box(radius: 1, position: [ simd_float3(0, 1, 0), simd_float3(0, -1, 0), simd_float3(1, 0, 0), simd_float3(-1, 0, 0) ]), box(radius: 2, position: [ simd_float3(0, 2, 0), simd_float3(0, -2, 0), simd_float3(2, 0, 0), simd_float3(-2, 0, 0) ]), box(radius: 3, position: [ simd_float3(3, 3, 0), simd_float3(3, -3, 0), simd_float3(-3, 3, 0), simd_float3(-3, -3, 0) ]) ] var body: some View { ZStack(alignment: .topTrailing) { SceneView(scene: scene, options: [.autoenablesDefaultLighting, .allowsCameraControl, .rendersContinuously]) Picker("" , selection: self.$fs_cv) { let boxFlakeList: [String] = ["0","1","2","3"] ForEach( boxFlakeList, id: \.self ) { Num in Text(Num) } }.fixedSize() .onChange(of: fs_cv, { let selected_boxFlake:[box] = boxFlake.dropLast( 3 - (fs_cv as NSString).integerValue ) redraw_animate_scene(boxFlake: selected_boxFlake) } // .onChange(of: fs_cv ) // .onChange } } // var body: some View private func redraw_animate_scene(boxFlake: [box]) { for box in boxFlake { for position in box.position { position.pNode(drawIntoNode: scene.rootNode.childNode(withName: "Spin", recursively: true)!, radius: String(box.radius)) } } animate(node: scene.rootNode) } // func redraw_animate_scene() } // struct ContentView: View func makeAScene() -> SCNScene { let precessionNode = SCNNode() let SpinNode = SCNNode() precessionNode.name = "precession" precessionNode.simdPosition = SIMD3<Float>(0,0,0) precessionNode.simdTransform = float4x4([Float(0.5.squareRoot()),Float(0.5.squareRoot()),0,0], [-Float(0.5.squareRoot()),Float(0.5.squareRoot()),0,0],[0,0,1,0],[0,0,0,0]) SpinNode.name = "Spin" SpinNode.simdPosition = SIMD3<Float>(0, 0, 0) let newScene = SCNScene() newScene.rootNode.addChildNode(precessionNode) newScene.rootNode.childNode(withName: "precession", recursively: true)?.addChildNode(SpinNode) // newScene.fogDensityExponent = 0.0 newScene.background.contents = NSColor.black newScene.rootNode.camera = SCNCamera() newScene.rootNode.camera?.usesOrthographicProjection = true // @abstract Determines whether the receiver uses an orthographic projection or not. Defaults to NO. INVISIBLE WITHOUT IT! newScene.rootNode.camera?.orthographicScale = 20 // the bigger the number the smaller the image Without specifying 20 view is too close to nucleus Defaults to 1. newScene.rootNode.camera?.zNear = -20 // The default value is 1.0 newScene.rootNode.camera?.zFar = 100 // The default value is 100.0 // newScene.rootNode.camera?.fieldOfView = 45 // defaults to 60 degrees // newScene.rootNode.camera?.automaticallyAdjustsZRange = true newScene.rootNode.camera?.automaticallyAdjustsZRange = false /* @discussion When set to YES, the near and far planes are automatically set to fit the bounding box of the entire scene at render time. */ return newScene } extension simd_float3 { func pNode(drawIntoNode: SCNNode, radius: String) { let myBox = SCNBox(width: 0.5, height: 0.5, length: 0.5, chamferRadius: 0.1) let newNode = SCNNode(geometry: myBox) newNode.name = "box_\(radius)" newNode.simdPosition = self newNode.scale = SCNVector3(x: 1.0, y: 1.0, z: 1.0) newNode.isHidden = false newNode.opacity = 1.0 // "A value of 0 means 100% transparency, while a value of 1 means 100% opacity." assignMaterials(newNode) drawIntoNode.addChildNode(newNode) } } func animate(node: SCNNode) { let precession_action = SCNAction.rotate(by: CGFloat(Double.pi*2), around: SCNVector3Make(0, 1, 0), duration: 79.17) let Spin_action = SCNAction.rotate(by: CGFloat(Double.pi*2), around: SCNVector3Make(0, 1, 0), duration: 4) let boxSpin_action = SCNAction.rotate(by: -CGFloat(Double.pi*2), around: SCNVector3Make(0, 1, 0), duration: 0.5) var childNodeList:[SCNNode] = node.childNodes(passingTest: { (anyNode, stop) -> Bool in anyNode.name == "precession" } ) for kids in childNodeList { if !kids.hasActions { kids.runAction(SCNAction.repeatForever(precession_action)) } } childNodeList = node.childNodes(passingTest: { (anyNode, stop) -> Bool in anyNode.name == "Spin" } ) for kids in childNodeList { if !kids.hasActions { kids.runAction(SCNAction.repeatForever(Spin_action)) } } childNodeList = node.childNodes(passingTest: { (anyNode, stop) -> Bool in anyNode.name!.hasPrefix("box") } ) for kids in childNodeList { if !kids.hasActions { kids.runAction(SCNAction.repeatForever(boxSpin_action)) } } } func assignMaterials( node: SCNNode) { _ for (index,_) in zip((node.geometry?.elements.indices)!, node.geometry!.elements) { // see enumerated() for zero based e.g., Array() and ContiguousArray() only else zip(_:_:) node.geometry?.materials[index].diffuse.contents = NSColor.red } }
Topic: Graphics & Games SubTopic: SceneKit Tags:
Jan ’25
Reply to SceneView selective draw since concurrency
Let's start with my scene, some of the oldest code and I was just starting coding after many years. internal func makeAScene() -> SCNScene { let firstNode = SCNNode() let secondNode = SCNNode() firstNode.name = “firstNode” firstNode.simdPosition = SIMD3<Float>(0,0,0) firstNode.simdTransform = float4x4([Float(0.5.squareRoot()),Float(0.5.squareRoot()),0,0],[-Float(0.5.squareRoot()),Float(0.5.squareRoot()),0,0],[0,0,1,0],[0,0,0,0]) secondNode.name = “secondNode” secondNode.simdPosition = SIMD3<Float>(0,0,0) let newScene = SCNScene() newScene.rootNode.addChildNode(firstNode) newScene.rootNode.childNode(withName: “firstNode”, recursively: true)?.addChoildNode(secondNode) newScene.background.contents = NSColor.black newScene.rootNode.camera = SCNCamera() newScene.rootNode.camera?.usesOrthographicProjection = true newScene.rootNode.camera?.orthographicScale = 20 newScene.rootNode.camera?.zNear = -20 newScene.rootNode.camera?.zFar = 100 newScene.rootNode.camera?.automaticallyAdjustsZRange = false return newScene } .zNear bothers me because the default is 1 (not a negative number) but doesn't show otherwise. .zFar defaults to 100. The SceneView is the first view listed within a ZStack{} and is therefore under much Text() and Pickers() etc. The figure constructed by the many elements and drawn in the scene are no wider nor deeper than 10 units in scale. The center of the figure is @ (0,0,0) of the scene's coordinate system.
Topic: Graphics & Games SubTopic: SceneKit Tags:
Jan ’25
Reply to SceneView selective draw since concurrency
Oh, I almost forgot to cite a potentially important clue. To a view in ContentView I had attached .onChange(of: scene.rootNode.childNode(withName: "parent-to-few-or-many", recursively: true).childNodes { flushAllChildNodes-reloadFileDescibingChildNodes-reDrawChildNodes } which had the effect of constantly and alternatively blanking the scene and flashing the desired "fewer" nodes. Proving the childNodes are recognized by SceneKit in the proper position, scale etc. before getting wiped by unknown code. Before you ask, I had also disabled all calls to my own code that removes childNodes just in case poor coding was calling it somewhere. No luck, the fewer were not displayed any the many had subsequent childNodes added for a real mess.
Topic: Graphics & Games SubTopic: SceneKit Tags:
Jan ’25
Reply to SceneView selective draw since concurrency
Thanks for replying Greg The only thing I hadn't tried in TN3124 was logging .boundingBox, which proved consistent whether few or many nodes. I even tried setting the box (for every childNode) larger to no effect. The parentNode has nil boundingBox. In playing with the camera options, if .usesOrthographicProjection is false, no nodes appear whether few or many. The default is false per documentation. Yet OP is otherwise not necessary nor desired for my app. Again, since the common code creates all nodes into a common scene with common camera etc. the only difference I can see is the time required to delete the previous nodes, load-from-file the pattern for the nodes to be drawn. Many nodes take more time than fewer. Yet again, .rendersContinuously is set. |-(
Topic: Graphics & Games SubTopic: SceneKit Tags:
Jan ’25
Reply to you don't have permission to view it
OK, if that wasn't odd enough... as a work around I made a Data.dataset folder in the apps assets and copied-in a few files to read. Only, they also say "you don't have permission to view it" referring to Assets.xcassets! Yes, this folder was drag-n-dropped from the old project into this new project. Yet if I create a new folder in the project and copy the data into it, I have no permissions as well. No permissions within my own project, anywhere! Hmm. Security gone awry.
Dec ’24