How to add an image to an ARSCNScene in Swift? - swift

I stumbled upon a roadblock with the development of a Swift playground I'm developing. I want to add an image to my ARSCNScene (ARKit + SceneKit). Not as a background, but as an actual node with positions and all. Does anyone know whether this is possible? I couldn't find anything online. Thanks!

You can easily add UIImage as diffuse material to your SCNPlane. Example:
let image = UIImage(named: "yourImageName")
let node = SCNNode(geometry: SCNPlane(width: 1, height: 1))
node.geometry?.firstMaterial?.diffuse.contents = image
Further, you can modify your node as you like. I hope it helped!

I think I found a solution too for this problem since im having the same issue
Write:
node.geometry?.firstmaterial?.diffuse.contents = #imageLiteral(resourceName: “yourimagename”)
Note that you have to add the image inside the assets first (as an image set of course)

Related

Perspective camera RealityKit

I created a RealityKit project which loads objects (usdz files). Using the LiDAR is really great for occlusion and be able to see the real world mesh.
I would like to use something found in the Apple's documentation : Perspective Camera. If I well understood this could be compare as a third person camera.
I created a dedicated button in my arView which, when called, execute the code following :
let cameraEntity = PerspectiveCamera()
cameraEntity.camera.far = 10
cameraEntity.camera.fieldOfViewInDegrees = 60
cameraEntity.camera.near = 0.01
let cameraAnchor = AnchorEntity(world: .zero)
cameraAnchor.children.append(cameraEntity)
self.arView.scene.anchors.append(cameraAnchor)
When is code is called the the become black.... I do not understand how to place the camera to see the scanned mesh.
If someone has an idea ? Thanks in advance!
It depends where the USDZ you're looking at is located. I think the default will mean the camera is located at the origin looking in the direction of [0, 0, -1].
You could change this using the Entity.look(at:from:upVector:relativeTo:) method. Making sure that your from: parameter is far enough from the centre of your USDZ object.

SceneKit shader modifiers

I'm writing a 3D space game using SceneKit and I'm pretty happy with it so far, but I'm starting to hit some limitations and would like some advice.
I have a sphere which represents a star that sits on a point light, and I'd like to add some effects to this to make it look more realistic. I think I should use the sphere's shaderModifiers to do this, but I'm not sure which modifiers I should be looking at i.e. to achieve a lens flare effect. Infact if anyone can give me a clear explanation of the differences between: ShaderModifiers, SCNProgram and SCNTechnique that would be great!
I'd like to draw a 1px circle to represent an orbit. I've tried using a cylinder that is really thin, but this results in some visual artefacts (the ring seems to have gaps at larger distances and break up). Any ideas how I can do this and maintain a nice smooth circle?
The shortest way to have a flare effect for SceneKit models is to use a CoreImage framework's capabilities.
For making a visible orbit use a regular PNG-image technique with premultiplied alpha channel (RGBxA). Look at this link to find out how a png image with orbits looks like (save a file). And if you wanna automatically orient a plane toward a camera use a constraint.
And here's a code:
let orbitsOnPlane = SCNPlane(width: 10, height: 10)
let material = SCNMaterial()
material.diffuse.contents = UIImage(named:"overlayOrbits.png")
orbitsOnPlane.materials = [material]
let orbitNode = SCNNode()
orbitNode.geometry = orbitsOnPlane
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
let constraint = SCNLookAtConstraint(target: orbitNode)
cameraNode.constraints = [constraint]

Create SKSpriteNode with an Asset Programmatically

I'm attempting to programmatically create an SKSpriteNode and give it a texture that is in my Assets.xcassets folder. I figured this would be a basic procedure, but I seem to be having a lot of troubles.
For a reference, here is my asset catalog with the ground asset I'm trying to set to a SKSpriteNode:
Here's the code to make the sprite node:
sprite.texture = SKTexture(image: UIImage(named: spriteName)!)
sprite.anchorPoint = CGPoint(x: 0, y: 1)
sprite.position = CGPoint(x: 0, y: 0)
referenceNode.addChild(sprite)
The variable "spriteName" in the first line is having the String "ground" passed into it. However, when I load the game, the ground is missing. Just to make sure the nodes were actually there, I commented out the texture code and just gave them size and a visible color. This worked out so I know the problem is definitely in the asset reference, not in the code logic.
Any point in the right direction would be greatly appreciated. If more information is needed, please do ask as specifically as possible :)
Thanks,
Matthew
EDIT:
My original question may have been a bit too complicated. To rephrase in simpler terms:
I have an asset in my asset library called ground. However, when I set the texture of a SKSpriteNode using this code...
sprite.texture = SKTexture(image: UIImage(named: "ground")!)
the texture doesn't show up in app. My question: how do I properly reference the image in my asset library?
It seems like you need to explicitly set the size too:
sprite.texture = SKTexture(imageNamed: "myImage1")
sprite.size = sprite.texture!.size()
..or you can specify the image in init:
let sprite = SKSpriteNode(imageNamed: "myImage1")

How to scale/position nodes Swift SpriteKit? Custom View?

I'm working on a game but can't figure out the right way to scale/ position everything. I have a universal app and when I switch from device to device the nodes aren't in the right place everytime. I'm using AspectFill because it sizes my nodes the the right way for each device. The problem is the positioning. I don't know if I'm right in making the conclusion that I need to figure out how to make the view the same size as the screen so that it changes for each device and then positions and scales everything properly, but this is what I've been trying to figure out. I've been trying many different things online and looking at things like how to make a custom view. I've tried to make a rectangle that ha constraints to fill the screen and then setting that rectangle to equal the UIView or SKView. I've tried many different things and looked at many things online but they are either confusing and I don't know if I'm trying them right or they don't pertain to my situation. This is causing a lot of confusion for me and I was hoping someone could help with this issue. I think the issue is that I need to make a custom view that relates to the size of the screen. I don't know if this is possible or what I should be going after. It would be great if someone could clear this up for me.
To keep my games universal I make all my nodes sizes and positions dependant on SKScene size
Instead of using hardcoded numbers try using proportions from your SKScene size. For example:
Instead of writing this:
node.position = CGPointMake(100, 100)
Write somthing like this:
node.position = CGPointMake(world.frame.size.width / 32 * 16, world.frame.size.height / 18 * 9)
world - SKNode of exactly same size as your SKScene
Same for sizes
let blackSquare = SKSpriteNode(texture: nil, color: UIColor.blackColor(), size: CGSizeMake(world.frame.size.width / 32, world.frame.size.width / 32))
Also GameViewController should look something like this:
override func viewDidLoad() {
super.viewDidLoad()
// Configure the view
let skView = view as! SKView
skView.multipleTouchEnabled = false
// Create and configure the scene
let scene = GameScene(size: skView.bounds.size)
scene.scaleMode = .AspectFill
scene.size = skView.bounds.size
skView.presentScene(scene);
}
Was this helpfull?

SKPhysicsBody uses only part of SKTexture

I'm using an SKTexture with an image and set the SKPhysicsBody. Like that:
var moleTexture = SKTexture(imageNamed: "moleTop1")
leftPlayer = SKSpriteNode(texture: moleTexture)
leftPlayer.physicsBody = SKPhysicsBody(texture: moleTexture, size: leftPlayer.texture!.size())
Now after I start my game, I noticed that the physicsBody is set wrong. I've activated the showPhysics property and my image looks like that:
As you see, the only thing which is used by SKPhysicsBody is the little part on the middle left(blue border).
How can I change that so that the whole image will be used?
That looks interesting. I believe it will only create an outline (or one shape) and it appears to be starting from the left and because there are no other pixels near enough it calls it done.
I wonder if you get a different result if those pixels are touching. I would try and validate that first. If that is the case you may have to change the texture or use a different variation of the texture for the physical body.
I hope that helps =)