Perspective camera RealityKit - swift

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.

Related

ARKit – How to track iPhone camera location during ARSession?

I'm very new to Xcode, so any and all help would be a godsend. I'm trying to write an app that saves the positional and rotational data from an iPhone at a set interval and saves it to a file. Right now, I'm not sure where to look when it comes to getting that data.
CoreMotion seems to not be enough so I'm using ARKit. I have a sceneView where I can see the origin and the feature points, but again, I'm stuck when it comes to where or even if the camera's position is tracked.
You can retrieve ARCamera's position and rotation via Transform Matrix (simd_float4x4). This data is contained inside every ARFrame of a running ARSession (for selfie or rear camera).
let sceneView = ARSCNView(frame: .zero)
sceneView.delegate = self
let frame: ARFrame = sceneView.session.currentFrame!
let cameraPosition: simd_float4 = frame.camera.transform.columns.3
let cameraRotation: simd_float3 = frame.camera.eulerAngles
The best place for these lines is SceneKit's renderer(_:didUpdate:for:) instance method. Take into consideration, that ARCamera transform values coming from IMU sensors are specially filtered.

Is inverse kinematics possible without additional reference objects?

I was looking at this tutorial: https://docs.unity3d.com/Manual/InverseKinematics.html
In that tutorial, they change the body position of hands, head etc, by setting a target object to hold or look at.
In this project: https://hackaday.com/2016/01/23/amazing-imu-based-motion-capture-suit-turns-you-into-a-cartoon/
The guy access the blender api, and directly sets the transform of several bones.
Is it possible to do the same in Unity ? I do not need any assistance with getting data from sensors etc. I'm just looking for information on what is the equivalent API in unity to directly set the orientation of specific body parts of a skeleton at runtime.
You are probably looking for SkinnedMeshRenderer.
When you import a model from some 3d soft, such as blender, it will have SkinnedMeshRenderer component.
What you would want too check out is SkinnedMeshRenderer.bones, which get you the array of bones (as an array of Transform) used to control its pose. You can modify its elements, thus affecting the pose. So you can do stuff like this:
var bones = this.GetComponent<SkinnedMeshRenderer>().bones;
bones[0].localRotation = bones[0].localRotation * Quaternion.Euler(0f, 45f, 0f);
Just play around with it, it is the best way to see.
For more advanced manipulations, you can also set your own array of bones and specify their weights, with SetBlendShapeWeight / GetBlendShapeWeight, but this is probably more than what you need.

Giving physics to tiles of SKTileMapNode in Xcode 8

I am learning Swift, and as a project I am working on a tile based 2D game similar to super mario where my character will walk and jump on tiles.
The latest version of Xcode and Sprite Kit give the ability to create a Tile Map directly in Xcode.
In the presentation of the new Xcode and Sprite kit, the guy demonstrates a game similar to what i am working on.
https://developer.apple.com/videos/play/wwdc2016/610/ (around the 20th minute).
He mentions giving Tiles user data properties which i did, and in code we search through all the tiles which have that user data and give them some physics properties so that the character can collide or interact with them (in my case, my character not falling or walking through the tiles).
so basically, the idea is giving those tiles a physics Body, but this can't be done using SKphysicsBody. So there must be another way, and since i am new to Swift i am missing it.
if anyone knows this, i would very much appreciate the help.
If the question is unclear let me know because i am also new to stack overflow.
Apple staff member Bobjt says here that "the right approach" is to add user data to your SKTileDefinition objects and use that to identify and add physics bodies to your tiles.
So you would add a user data value to a tile definition either programmatically or in the editor, like so:
Then in code you would check each tile definition to see if it has the user data value. If so, then you need to calculate the tile's position and add a physics body on a new node, parenting it to your tile map. Here is the code for this which Bobjt referred to as "the correct approach":
self.tileMap = self.childNode(withName: "Tile Map") as? SKTileMapNode
guard let tileMap = self.tileMap else { fatalError("Missing tile map for the level") }
let tileSize = tileMap.tileSize
let halfWidth = CGFloat(tileMap.numberOfColumns) / 2.0 * tileSize.width
let halfHeight = CGFloat(tileMap.numberOfRows) / 2.0 * tileSize.height
for col in 0..<tileMap.numberOfColumns {
for row in 0..<tileMap.numberOfRows {
let tileDefinition = tileMap.tileDefinition(atColumn: col, row: row)
let isEdgeTile = tileDefinition?.userData?["edgeTile"] as? Bool
if (isEdgeTile ?? false) {
let x = CGFloat(col) * tileSize.width - halfWidth
let y = CGFloat(row) * tileSize.height - halfHeight
let rect = CGRect(x: 0, y: 0, width: tileSize.width, height: tileSize.height)
let tileNode = SKShapeNode(rect: rect)
tileNode.position = CGPoint(x: x, y: y)
tileNode.physicsBody = SKPhysicsBody.init(rectangleOf: tileSize, center: CGPoint(x: tileSize.width / 2.0, y: tileSize.height / 2.0))
tileNode.physicsBody?.isDynamic = false
tileNode.physicsBody?.collisionBitMask = playerCollisionMask | wallCollisionMask
tileNode.physicsBody?.categoryBitMask = wallCollisionMask
tileMap.addChild(tileNode)
}
}
}
Personally, I think this approach is too fussy. I'm going to try a different approach in my game and if it works I'll post it here. What I'd really like is for Apple to enhance the tile map API so that we can add physics bodies directly to individual tiles. Maybe in the process they could optimize the engine so that physics bodies on individual tiles would be automatically merged to form larger, more optimal shapes in order to improve system performance.
Update: I filed a request with Apple about this issue, for whatever good might come of it.
I'm not sure there's a surefire way to do this yet... but here's two ways to think about how to try apply physics to a tilemap.
Option 1: Apply SKNodes to each positions of each tile on your map, and apply an appropriate physicsbody to that SKNode based on the content and state of that tile.
Option 2: Use the position information of each tile to add an array of physicsbodies to the SKTileMapNode, and position each of them accordingly.
I'm imagining a gravity down, Mario style platformer, with this kind of terrain in need of physics bodies for the ground:
Lifted transcript from Apple's WWDC about tiles and physics:
And you'll note that I'm colliding with the tiles here.
And I achieve this by leveraging custom user data that we can put on
each of our tiles.
Here, I'll show you in our tile set.
Select one of the variants here.
And you can see that we have some user data over here.
And I just have a value called edgeTile which is a Boolean, and I set
to 1.
So, in code, I'm going through the tile map in our platform demo here,
and I'm looking for all of these edge tiles.
And whenever I find one, I create some physics data to allow the
player to collide with it.
And since it is just in our tile map here, say I wanted to get over
this large wall here.
When I run the game, you'll see that my guy can't actually jump high
enough to get over it.
And he really wants to because that red button over there looks really
tempting.
I really want to push that thing.
So, since we're just generating our physics data from our tiles and
our user data, all we can do is just going here and erase these tiles
and build and run our game again.
The tiles are now gone and we can now move through there.
And we didn't have to change code or anything.
We just used the data that we pulled from the tile map to set up our
tile.
It's that simple.
Makes it sound very simple, but takes a far greater mind than mine to figure out what is being done, and how it's being done.
Alternatively, you can apply a line sweep algorithm to the tiles you want to give a SKPhysicsBody.
You can do this in four steps;
Iterate through the position of the tiles in your SKTileMap.
Find the tiles that are adjacent to one another.
For each group of adjacent tiles, collect:
a down-left corner coordinate and
an up-right corner coordinate.
Draw a square, and move on to the next group of tiles until you run out of tile coordinates.
Screenshot without visuals for comparison
Screenshot without visuals showing the physicsbodies
See my answer in a similar post on how to implement this.
I spent two days trying different ideas but could find nothing better than what I posted in my other answer. As mentioned there, it is the way recommended by an Apple staff member and as far as I know it's the most efficient way to have SpriteKit automatically add physics bodies to all your tiles. I've tested it and it works. (Although I'm still holding my breath for Apple to add a straightfoward way of putting physics bodies on tiles).
But there are other considerations. If you are having performance issues because there are too many physics bodies in your scene, you might want to try one of these other approaches. However, they are both more time-consuming than the approach described above. The only reason that may justify using one of these more labor-intensive approaches is if you need to reduce the number of physics bodies in your scene due to performance issues. Otherwise, I think the "automatic" approach mentioned above is the best option we have.
So I won't go into detail here because I think the automatic option is the best. These are just ideas for alternate approaches if your game needs to be extra stingy with system resources.
Alternate Approach #1 - Use Fewer Physics Bodies
Create your tile map in the editor. Then keep working in the editor to drag Color Sprites (SKSpriteNodes) over parts of your map that need a physics body. Shape the nodes to make the largest rectangle possible for areas that need physics bodies. This works best for for large, flat surfaces like walls, floors, ceilings, platforms, crates, etc. It's tedious but you end up with far fewer physics bodies in your simulation than if you had used the automatic approach mentioned above.
Alternate Approach #2 - Use No Physics Bodies
This idea would probably require even more work, but you could potentially avoid using physics bodies altogether. First, create your tile map in the editor. Analyze your map to identify which tiles mark a barrier, beyond which the player should not cross. Assign a user data identifier to that type of tile. You would need different categories of identifiers for different types of barriers, and you may also need to design your artwork to fit this approach.
Once your barrier tiles are sufficiently identified, write code which checks the user data value for the tile currently occupied by the player sprite and restrict the sprite's movement accordingly. For example, if the player enters a title that marks an upper boundary, your movement code would not allow the player sprite to move up. Likewise, if the player enters a tile that marks the leftmost boundary, your movement code will not let the player travel left.

Q: How do I move objects down the y axis as my player moves up?

Creating a game like Doodle Jump where my player is constantly being moved up by bouncing off of obstacles. Ive tried every trick in the book but nothing seems to be working/doing exactly what I want. Can anyone give me some tips?
iOS 9 introduced the Camera Node. Use SKCameraNode, which is a subclass of SKNode, and can be translated and rotated in same way.
So, instead of moving all of your background elements in the opposite direction of your hero/player, you can simply attach your scene's camera node to your hero/player and the rest is taken care of.
PS. You can also do cool stuff like scaling the camera size.
EDIT.
Happy to include an example.
First, make a camera constant in your scene.
import SpriteKit
class myFirstScene: SKScene {
let myCamera: SKCameraNode = SKCameraNode()
...
}
Then in your didMoveToView() function, assign the scene's built-in camera variable to the camera constant we made earlier.
override func didMoveToView( view: SKView ) {
camera = myCamera
...
}
Now, there are a few different ways to "attach" your camera to your hero/player. The first is to attach your camera node to your hero.
hero.addChild( myCamera )
I don't even know if it works that easily because my game uses something different, a simpler version is below.
update(){
camera!.zRotation = hero.zRotation
camera!.position = hero.position
}

How to make an object on the screen rotates , in swift

I am creating an Iphone game in Xcode using swift , and there is a ball i want it to keep constantly rotating , i think i need to do it with the update method , but how could i do it , and if there another way with out using the update method please let me know
You could use an SKAction (take a look at the documentation; you'll see SKActions have a variety of uses). For a rotation you could do:
// The angle is measured in radians and the duration is measured in seconds.
let rotateAction = SKAction.rotateByAngle(1, duration: 1)
To make the action run forever you can use another SKAction:
let repeatAction = SKAction.repeatActionForever(rotateAction)
Finally, you need to make your node (ball) run the action:
ball.runAction(repeatAction)
Take a look at the SKNode documentation for other methods you can use to run an SKAction.
Also, I'm assuming you're new to Sprite Kit, so I'd recommend you take a look at The Sprite Kit Programming Guide.