In tvOS how to actually put an SCNNode in a focus container? Scene nodes now have focus behavior, but how to include in the focus container? - scenekit

You have a scene kit scene in your tvOS app.
As usual the scene kit is part of a normal view controllert.
Nowdays you can in fact do this:
someNode.focusBehavior = .focusable
reference - https://developer.apple.com/documentation/uikit/focus-based_navigation/adding_user-focusable_elements_to_a_tvos_app
As it says, "To make a SceneKit or SpriteKit node focusable, set the focusBehavior property of the node to focusable"
However when you do this, you will simply get a crash:
'Focus item <SCNNode: 0x600003bc5d00> has a parent focus environment of <SCNNode: 0x600003bc3d00> but this environment does not provide a container for focus items.'
You cannot do this or this, they ar read only:
// can't do this -
someNode.parentFocusEnvironment = ...
// can't do this -
someNode.focusItemContainer = ...
I can't seem to set them in a subclass (overriding) and indeed - I'm not sure what they should be set to!!
How do you add scene kit nodes to the focus container of ordinary nodes (say, buttons) in the view controller?

Related

ARKit allowsCameraControl

I'm implementing allowsCameraControl in my ARKit scene via an IBAction that sets self.sceneView.allowsCameraControl = true via a switch, it works great. My switch logic seems fine in the debugger, however when I turn self.sceneView.allowsCameraControl = false - the camera doesn't return back to it's original tracking state. The objects stay stationary in my Scene View. Any clues?
The allowsCameraControl option is defined by ARSCNView's superclass SCNView — which is to say, it's designed for non-AR situations. That it behaves strangely in that view's ARKit subclass is probably a bug (arguably, it shouldn't work at all, since in AR the camera is supposed to always match device movement). You might want to file that bug with Apple.
In the meantime, if you want to switch between AR (user controls camera by moving device) and non-AR (you control camera, or user controls camera via touch gestures) views of the same content, you might experiment with moving your scene between instances of ARSCNView and SCNView.

Render Visual 3D Container on top in Viewport3D

Using Helixtoolkit you have set up a scene (viewport). Added the camera, default lights, grids, etc. You also added a SortingVisual3D where you add various box elements for example. They are rendered as they are placed in the view. Everything fine.
Now I would like to achieve is to create a new container for 3D objects where my moving gizmo would be placed (every object gets one). If I add gizmo to sorting container, it might not be visible (box overlapping gizmo), so I need a separate container which has to be rendered on top of everything.
How to set container (content) to be rendered on top of everything - regardless of its physical location while still keeping it in the correct 3d space when rotating camera. Something like 3dsmax does (example).
Tnx
Ok, found the solution myself. What you want to do is to make an overlay and transform Point3D to Point and place objects there (a canvas for example).

Rotate WPF control or change screen orientation

I have wpf project with one Window (MainWindow). Depending upon the config file it shows one of two UserControl's as Content. It may be a horizontal (1920x1080) control or vertical (1080x1920) control. It's fine with horizontal screen, but when vertical is loaded I would like to do:
1) rotate window/control by 270 degrees
2) change primary screen orientation
I would prefer to just rotate application and don't interact with windows API. I can't change orientation manually, because I have only remote access to this computer.
You can not rotate the Window object itself, as it is positioned by the window management system built in Windows. You can, however, transform (and thus rotate) any FrameworkElement inside the window. This includes, but is not limited to, the Grid, the Button and the TextBox elements.
All you need to do is edit the LayoutTransform property on the element you want to rotate, which is most likely the root element in your window. Set the rotation to 270/-90 degrees and WPF will automatically rotate your UI.
Because you are using the LayoutTransform property, the layout system will also scale you UI correctly. The RenderTransform property causes the control to first be rendered, then be rotated.
YES WE CAN CHANGE SCCREEN ORIENTATION USING
DEVMODE & using System.Runtime.InteropServices;
its bit late to reply but I am replaying for the new ones , if someone com across this article for change screen rotation in C# or VB .
Please use the link given below to get help Mr. Hannes Completely write an article to change screen rotation and luckily its working fine for me (Windows 11) as now of..
https://www.codeguru.com/dotnet/creating-a-screen-rotator-in-net/

Default camera position not changing?

So I am trying to understand how allowsCameraControl really work.
I have a scene and I set the allowsCameraControl = true. When I pan around and the scene rotates, or translates (two fingers...), I don't understand what scene kit really changes for me.
I was expecting the camera node to change position, or rotation. Not the case.
I also logged the position and rotation of the rootNode of the scene...no change.
So just to be clear, in the render delegate called for every frame update, I log the position and rotation of the camera node I set for the scene, I logged the position and rotation of the root node, I also logged te position and rotation of a node I added to the scene. None of these show any change in position and or rotation.
Can anyone explain to me what scene kit changes when the scene rotates or translates using the standard camera controls?
A new camera is indeed created, leaving the original one unchanged. The scene graph is also unchanged. The new camera is not part of the scene graph and can be accessed with
scnView.pointOfView
A new camera is created, leaving the original one unchanged.
If you show the inspector using the showsStatistics property, you'll notice the Point of View changes from the camera you had (even if it is "Untitled") to kSCNFreeViewCameraName.
Sadly there is not much documentation about this behavior but you might be able to find it in the node hierarchy.
Let us know what you find!
Just came across an easy way of detecting the moment when a new camera is switched by SceneKit using KVO.
Swift 5
Declare an observer property in your class:
var povObserver: NSKeyValueObservation?
Then, setup the observer:
povObserver = defaultCameraController.observe(\.pointOfView, options: [.new]) { (cameraController, change) in
if let newPov = cameraController.pointOfView {
// Access new camera here
}
}
When finished you can set povObserver to nil

Why do I need to a localGroup:insert( object ) with the corona director class?

I cant seem to wrap my head around the localGroup:insert command that is necessary when using the director class.
If I create my object with something like:
local btnBegin = display.newImage( "images/btn_begin.png", (display.viewableContentWidth/2)-200, display.contentHeight * .7 )
The image will display perfectly fine in the scene, even if I never do a
localGroup:insert( btnBegin )
I would have thought that the localGroup:insert would be necessary so that all of the components of the scene can be grouped to gether for the display, but isnt that the point of
function new()
at the begining of each scene? In my mind, I see it that creating all of my objects within the function already makes them local to the scene file. What does localGroup:insert accomplish?
As I understand it, you could have a HUD which you add straight to the screen and the localGroup containing your level. Then if you change level, you would only move away the level contained in the localGroup and keep the elements of the HUD you placed straight on the screen.
When you do display.newImage(...) this adds the display object to the main stage. As tomdemuyt has said, this might be useful for a HUD or some other graphics that appear between scenes.
The stage also contains your scene, defined here has localGroup. To add an object to your scene, you should insert it into the localGroup.
This is useful for example, if you have a menu scene containing menu buttons. If you press the "start game" button, when the screen transitions to the next scene all your menu items will be removed appropriately with the menu scene, instead of hanging around on the global stage.
It all comes down to the display hierarchy and how you want to organize it. It makes sense to have sub objects inserted into their appropriate parents:
the stage HAS A menu scene
the menu scene HAS A button
Makes more sense than:
the stage HAS A menu scene
the stage HAS A button

Resources