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!
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 } }
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.
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.
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. |-(
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
Reply to SCNGeometry and .copy()
as an attempted work-around I created a global array of mySCNGeometry.copy() which should have allowed the materials to be changed independently as stated in the Developer Documentation. They are in fact all the same geometry whereas changing any one "copy" changes them all.
Dec ’24
Reply to SCNGeometry and .copy()
OK, I have just learned that objc methods can be called with Swift. Most examples are of custom functions or methods. How can I call the existing objc version of .copy() since Swift's doesn't work? Thanks fyi: I could never grasp objc and stopped programming during that period. Please be generous with example code.
Dec ’24
Reply to SCNGeometry and .copy()
curiously, when I use .copy() on an SCNGeometry the geometry?.geometrySourceChannels, geometry?.elements, and geometry?.materials are all == to the original but the test whether the geometries themselves are equal returns false. How can a copy not equal its original? Idk what else to test for "as missing" from the copy() .
Dec ’24