How to Remove All Nodes from a Scenekit Scene

How can I remove all nodes from a scenekit scene?

Try this (assuming you are using Swift):

rootNode.enumerateChildNodes { (node, stop) in
node.removeFromParentNode()
}

Works for me.

How can I remove specific nodes from a scenekit scene?

You should name your nodes then you can use the name to filter them out.

sceneView.scene.rootNode.childNodes.filter({ $0.name == "yourName" }).forEach({ $0.removeFromParentNode() })

How to Remove all Nodes

I think the function you need is this:

self.augmentedRealityView.scene.rootNode.enumerateChildNodes { (existingNode, _) in
existingNode.removeFromParentNode()
}

In the example self.augmentedRealityView refers to the variable:

var augmentedRealityView: ARSCNView!

remove nodes from scene after use ARSCNView

I think the issue here is that your are not actually removing the SCNNodes you have added to hierarchy.

Although you are removing the nodes from what I assume is an array of SCNNodes by calling: nodes.removeAll(), you first need to actually remove them from the scene hierarchy.

So what you need to do is call the following function on any node you wish to remove:

removeFromParentNode()

Which simply:

Removes the node from its parent’s array of child nodes.

As such you would do something like this which first removes the nodes from the hierarchy, and then removes them from the array:

for nodeAdded in nodesArray{
nodeAdded.removeFromParentNode()
}

nodesArray.removeAll()

So based on the code provided you could do the following:

if nodes.count > 2 {

for nodeAdded in nodes{
nodeAdded.removeFromParentNode()
}

nodes.removeAll()

}

For future reference, if you want to remove all SCNNodes from you hierarchy you can also call:

self.augmentedRealityView.scene.rootNode.enumerateChildNodes { (existingNode, _) in
existingNode.removeFromParentNode()
}

Whereby self.augmentedRealityView refers to the variable:

var augmentedRealityView: ARSCNView!

Here is a very basic working example based on (and modified from) the code you have provided:

/// Places A Marker Node At The Desired Tap Point
///
/// - Parameter sender: UITapGestureRecognizer
@objc func handleTap(_ sender: UITapGestureRecognizer) {

//1. Get The Current Tap Location
let currentTapLocation = sender.location(in: sceneView)

//2. Check We Have Hit A Feature Point
guard let hitTestResult = self.augmentedRealityView.hitTest(currentTapLocation, types: .featurePoint).first else { return }

//3. Get The World Position From The HitTest Result
let worldPosition = positionFromMatrix(hitTestResult.worldTransform)

//4. Create A Marker Node
createSphereNodeAt(worldPosition)

//5. If We Have Two Nodes Then Measure The Distance
if let distance = distanceBetweenNodes(){
print("Distance == \(distance)")
}

}

/// Creates A Marker Node
///
/// - Parameter position: SCNVector3
func createSphereNodeAt(_ position: SCNVector3){

//1. If We Have More Than 2 Nodes Remove Them All From The Array & Hierachy
if nodes.count >= 2{

nodes.forEach { (nodeToRemove) in
nodeToRemove.removeFromParentNode()
}

nodes.removeAll()
}

//2. Create A Marker Node With An SCNSphereGeometry & Add It To The Scene
let markerNode = SCNNode()
let markerGeometry = SCNSphere(radius: 0.01)
markerGeometry.firstMaterial?.diffuse.contents = UIColor.cyan
markerNode.geometry = markerGeometry
markerNode.position = position
sceneView.scene.rootNode.addChildNode(markerNode)

//3. Add It To The Nodes Array
nodes.append(markerNode)
}

/// Converts A matrix_float4x4 To An SCNVector3
///
/// - Parameter matrix: matrix_float4x4
/// - Returns: SCNVector3
func positionFromMatrix(_ matrix: matrix_float4x4) -> SCNVector3{

return SCNVector3(matrix.columns.3.x, matrix.columns.3.y, matrix.columns.3.z)

}

/// Calculates The Distance Between 2 Nodes
///
/// - Returns: Float?
func distanceBetweenNodes() -> Float? {

guard let firstNode = nodes.first, let endNode = nodes.last else { return nil }
let startPoint = GLKVector3Make(firstNode.position.x, firstNode.position.y, firstNode.position.z)
let endPoint = GLKVector3Make(endNode.position.x, endNode.position.y, endNode.position.z)
let distance = GLKVector3Distance(startPoint, endPoint)
return distance
}

For an example of a measuringApp which might help your development you can look here: ARKit Measuring Example

Hope it helps...

How do you remove a node?

The function is applied just like on a view or a layer:

thisNode.removeFromParentNode()

How to delete a specific node in an ARKit sceneView

Instead of trying to find the focus square, I'm actually trying to find my other custom node class:

sceneView.scene.rootNode.enumerateChildNodes { (node, stop) in
if node is TranslationNode {
node.removeFromParentNode()
}
}

This works fine.

How to remove all nodes with a specific name spritekit

It depends on how you created the spaceships. If you made them all with the same name maybe you can try:

self.enumerateChildNodesWithName("spaceShip"){

spaceShip.removeFromParent()
}
//or try
for child in self.children{

if child.name == "spaceShip"{
child.removeFromParent
}
}

removing all geometry from SceneKit, or modifying it on the fly

I haven't used SceneKit yet but, from the documentation, it would seem that you can find nodes by name by calling:

SCNScene.rootNode.childNodeWithName( name, recursively: true) 

or just iterate through childNodes recursively yourself.

Depending on the complexity of the nodes hierarchy, it may be tricky to implement insertions and deletions but, once you found the nodes you're looking for, that's just plumbing (prune and graft tree manipulations and such).



Related Topics



Leave a reply



Submit