What results does showStatistics throw me in scenekit? - swift

I don't have much experience in scenekit, I'm actually working in project in a using scenekit, I'm creating sceneView and adding configurations for my project, but I don't know what's the 'showsStatistics' propiety meaning
var sceneView: SCNView!
var scena = SCNScene()
var nodeInitial = SCNNode()
var arrayNodes = [SCNNode] ()
override func viewDidLoad() {
super.viewDidLoad()
nodeInitial = SCNScene(named: "art.scnassets/world.dae")!
for node in nodeInitial.rootNode.ChildNodes as [SCNNode] {
arrayNode.append(node)
}
scene.rootNode.addChildNode(arrayNode.last!)
sceneView.scene = scene
sceneView.allowsCameraControl = true
sceneView.showsStatistics = true
}
The results throw at me:
The part of left I understand that it makes reference to model propieties, but the part of right I don't know and every time I add elements it increases values and when I delete all the nodes it also increases

Related

Multiple ARSCNViews with different nodes in one screen

I want to show two different 3D objects in two different ARSCNViews.
With this question it's allowed to show the two ARSCNViews, but it is basically cloned one view to another.
I want to display different objects in each view.
Do you have any idea?
Yes, it's possible. You can create two ARSCNViews with different models, or even a RealityKit view and an ARKit view. However, in both cases you have to use the same running ARSession. It is not possible to run two different sessions in parallel.
import ARKit
class ViewController: UIViewController {
#IBOutlet var sceneView: ARSCNView!
#IBOutlet var sceneViewTwo: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
sceneViewTwo.session = sceneView.session
let scene = SCNScene(named: "art.scnassets/ship.scn")!
sceneView.scene = scene
let sceneTwo = SCNScene()
sceneViewTwo.scene = sceneTwo
let sphere = SCNNode(geometry: SCNSphere(radius: 0.1))
sphere.position.z = -1.0
sceneViewTwo.scene.rootNode.addChildNode(sphere)
let config = ARWorldTrackingConfiguration()
sceneView.session.run(config)
}
}

Anchoring Multiple Scenes in RealityKit

While loading multiple scenes (from reality composer) into arView, the scenes is not anchored in the same space.
In this example, scene1 is loaded when the app starts. After the button is pressed, the scene2 is added into the scene. In both the scenes, the models are placed at the origin and are expected to overlap with scene2 is added into the view. However, the position of scene1 and scene2 is different when they are added into the arView.
import UIKit
import RealityKit
class ViewController: UIViewController {
#IBOutlet var arView: ARView!
#IBOutlet weak var button: UIButton!
var scene1: Experience.Scene1!
var scene2: Experience.Scene2!
override func viewDidLoad() {
super.viewDidLoad()
// Load the "Box" scene from the "Experience" Reality File
scene1 = try! Experience.loadScene1()
scene2 = try! Experience.loadScene2()
// Add the box anchor to the scene
arView.scene.addAnchor(scene1)
}
#IBAction func buttonPressed(_ sender: Any) {
arView.scene.addAnchor(scene2)
}
}
Note: This issues does not happen when both the scenes are added simultaneously.
How to make sure that both the scenes are anchored at the same ARAnchor?
Use the following approach:
let scene01 = try! Cube.loadCube()
let scene02 = try! Ball.loadSphere()
let cubeEntity: Entity = scene01.steelCube!.children[0]
let ballEntity: Entity = scene02.glassBall!.children[0]
// var cubeComponent: ModelComponent = cubeEntity.components[ModelComponent].self!
// var ballComponent: ModelComponent = ballEntity.components[ModelComponent].self!
let anchor = AnchorEntity()
anchor.addChild(cubeEntity)
anchor.addChild(ballEntity)
// scene01.steelCube!.components.set(cubeComponent)
// scene02.glassBall!.components.set(ballComponent)
arView.scene.anchors.append(anchor)

Video Stabilization in ARKit / ARSCNView

I record videos using ARKit & ReplayKit.
I realised that the camera/video stream is pretty shaky when using ARKit/ARSCNView.
Is there a way to use a Stabilization Mode that is available for example in AVCaptureConnection to capture a video stream : -> activeVideoStabilizationMode
Is there something similar in ARKit ?
Here is some example code, pretty basic arkit setup:
#IBOutlet var sceneView: ARSCNView!
let scene = SCNScene()
func setupScene() {
sceneView.delegate = self
sceneView.session.delegate = self
sceneView.autoenablesDefaultLighting = true
// Set the scene to the view
sceneView.scene = scene
}
func resetTracking() {
// Create a session configuration
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = .horizontal
// Run the view's session
sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
}

How to keep running the same ARWorldTrackingConfiguration

I would like to create two 3D objects on the AR scene according to the value of the string provided. The default value of the string is "1" and after that, I will jump to another ViewController and change the string value to "2" and then back to the ARViewController.
I would like to ask how can I keep the existing node and world origin of the AR scene remain unchanged when I move to another ViewController and then come back to ARViewController? It seems that every time when I come back to the AR scene, it will do the world tracking again and remove my existing node and world origin.I can only display the latest 3D object by string value "2". The 3D object created by string "1" is being removed.
Here is the code for the AR ViewController:
class ARViewController: UIViewController {
public var object = Connector()
#IBOutlet weak var ARScene: ARSCNView!
public let configuration = ARWorldTrackingConfiguration()
override func viewDidLoad() {
super.viewDidLoad()
self.ARScene.session.run(configuration)
}
override func viewDidAppear(_ animated: Bool) {
if object.stringbeingpassed == "1"{
self.addNode(newposition: SCNVector3(0,0,0))
}else{
self.addNode(newposition: SCNVector3(0.1,0.1,0.1))
}
}
func addNode(newposition:SCNVector3){
let ball = SCNNode()
ball.geometry = SCNSphere(radius: 0.02)
ball.position = newposition
self.ARScene.scene.rootNode.addChildNode(ball)
let action = SCNAction.rotateBy(x: 0, y:CGFloat(360.degreesToRadians), z: 0, duration: 4)
let forever = SCNAction.repeatForever(action)
ball.runAction(forever)
}

SceneKit -– How to get animations for a .dae model?

Ok, I am working with ARKit and SceneKit here and I am having trouble looking at the other questions dealing with just SceneKit trying to have a model in .dae format and load in various animations to have that model run - now that we're in iOS11 seems that some solutions don't work.
Here is how I get my model - from a base .dae scene where no animations are applied. I am importing these with Maya -
var modelScene = SCNScene(named: "art.scnassets/ryderFinal3.dae")!
if let d = modelScene.rootNode.childNodes.first {
theDude.node = d
theDude.setupNode()
}
Then in Dude class:
func setupNode() {
node.scale = SCNVector3(x: modifier, y: modifier, z: modifier)
center(node: node)
}
the scaling and centering of axes is needing because my model was just not at the origin. That worked. Then now with a different scene called "Idle.dae" I try to load in an animation to later run on the model:
func animationFromSceneNamed(path: String) -> CAAnimation? {
let scene = SCNScene(named: path)
var animation:CAAnimation?
scene?.rootNode.enumerateChildNodes({ child, stop in
if let animKey = child.animationKeys.first {
animation = child.animation(forKey: animKey)
stop.pointee = true
}
})
return animation
}
I was going to do this for all my animations scenes that I import into Xcode and store all the animations in
var animations = [CAAnimation]()
First Xcode says animation(forKey: is deprecated and This does not work it seems to (from what I can tell) de-center and de-scale my model back to the huge size it was. It screws up its position because I expect making the model move in an animation, for example, would make the instantiated model in my game snap to that same position.
and other attempts cause crashes. I am very new to scene kit and trying to get a grip on how to properly animate a .dae model that I instantiate anywhere in the scene -
How in iOS11 does one load in an array of animations to apply to their SCNNode?
How do you make it so those animations are run on the model WHEREVER THE MODEL IS (not snapping it to some other position)?
At first I should confirm that CoreAnimation framework and some of its methods like animation(forKey:) instance method are really deprecated in iOS and macOS. But some parts of CoreAnimation framework are now implemented into SceneKit and other modules. In iOS 11+ and macOS 10.13+ you can use SCNAnimation class:
let animation = CAAnimation(scnAnimation: SCNAnimation)
and here SCNAnimation class has three useful initializers:
SCNAnimation(caAnimation: CAAnimation)
SCNAnimation(contentsOf: URL)
SCNAnimation(named: String)
In addition I should add that you can use not only animations baked in .dae file format, but also in .abc, .scn and .usdz.
Also, you can use SCNSceneSource class (iOS 8+ and macOS 10.8+) to examine the contents of a SCNScene file or to selectively extract certain elements of a scene without keeping the entire scene and all the assets it contains.
Here's how a code with implemented SCNSceneSource might look like:
#IBOutlet var sceneView: ARSCNView!
var animations = [String: CAAnimation]()
var idle: Bool = true
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
let scene = SCNScene()
sceneView.scene = scene
loadMultipleAnimations()
}
func loadMultipleAnimations() {
let idleScene = SCNScene(named: "art.scnassets/model.dae")!
let node = SCNNode()
for child in idleScene.rootNode.childNodes {
node.addChildNode(child)
}
node.position = SCNVector3(0, 0, -5)
node.scale = SCNVector3(0.45, 0.45, 0.45)
sceneView.scene.rootNode.addChildNode(node)
loadAnimation(withKey: "walking",
sceneName: "art.scnassets/walk_straight",
animationIdentifier: "walk_version02")
}
...
func loadAnimation(withKey: String, sceneName: String, animationIdentifier: String) {
let sceneURL = Bundle.main.url(forResource: sceneName, withExtension: "dae")
let sceneSource = SCNSceneSource(url: sceneURL!, options: nil)
if let animationObj = sceneSource?.entryWithIdentifier(animationIdentifier,
withClass: CAAnimation.self) {
animationObj.repeatCount = 1
animationObj.fadeInDuration = CGFloat(1)
animationObj.fadeOutDuration = CGFloat(0.5)
animations[withKey] = animationObj
}
}
...
func playAnimation(key: String) {
sceneView.scene.rootNode.addAnimation(animations[key]!, forKey: key)
}