RealityKit – How to add motion to a loaded ModelEntity from USDZ file?
Add to your code .generateCollisionShapes(recursive:)
instance method for every participant (entity) that not only creates collision's shapes but also allows you to simulate physics.
import SwiftUI
import RealityKit
struct ARViewContainer: UIViewRepresentable {
let boxx = ModelEntity(mesh: .generateBox(size: 0.5))
let ball = ModelEntity(mesh: .generateSphere(radius: 0.25))
let anchor = AnchorEntity()
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
// BALL
ball.physicsBody = .init()
ball.physicsMotion = .init()
ball.physicsMotion?.linearVelocity = [10,0,0]
ball.position.x = -3
ball.generateCollisionShapes(recursive: true)
anchor.addChild(ball)
// BOX
boxx.physicsBody = .init()
boxx.physicsMotion = .init()
boxx.physicsMotion?.linearVelocity = [0,2,0]
boxx.generateCollisionShapes(recursive: true)
anchor.addChild(boxx)
// Anchor
anchor.position.z = -3
arView.scene.addAnchor(anchor)
return arView
}
func updateUIView(_ uiView: ARView, context: Context) { }
}
...
struct ContentView : View {
var body: some View {
return ARViewContainer().edgesIgnoringSafeArea(.all)
}
}
For more details, read THIS post.
RealityComposer – Glitch with Hide all on Scene Start
Try this to prevent a glimpse...
import UIKit
import RealityKit
class ViewController: UIViewController {
@IBOutlet var arView: ARView!
var box: ModelEntity!
override func viewDidLoad() {
super.viewDidLoad()
let scene = try! Experience.loadScene()
self.box = scene.cube!.children[0] as? ModelEntity
self.box.isEnabled = false
arView.scene.anchors.append(scene)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.box.isEnabled = true
}
}
}
In such a scenario glitching occurs only for sphere. Box object works fine.
How to Add Material to ModelEntity programatically in RealityKit?
Updated: June 14, 2022
RealityKit materials
There are 6 types of materials in RealityKit 2.0 and RealityFoundation at the moment:
- SimpleMaterial
- UnlitMaterial
- OcclusionMaterial (read this post to find out how to setup SceneKit occlusion shader)
- VideoMaterial (look at this post to find out how to setup it)
- PhysicallyBasedMaterial
- CustomMaterial
To apply these materials use the following logic:
import Cocoa
import RealityKit
class ViewController: NSViewController {
@IBOutlet var arView: ARView!
override func awakeFromNib() {
let box = try! Experience.loadBox()
var simpleMat = SimpleMaterial()
simpleMat.color = .init(tint: .blue, texture: nil)
simpleMat.metallic = .init(floatLiteral: 0.7)
simpleMat.roughness = .init(floatLiteral: 0.2)
var pbr = PhysicallyBasedMaterial()
pbr.baseColor = .init(tint: .green, texture: nil)
let mesh: MeshResource = .generateBox(width: 0.5,
height: 0.5,
depth: 0.5,
cornerRadius: 0.02,
splitFaces: true)
let boxComponent = ModelComponent(mesh: mesh,
materials: [simpleMat, pbr])
box.steelBox?.children[0].components.set(boxComponent)
box.steelBox?.orientation = Transform(pitch: .pi/4,
yaw: .pi/4,
roll: 0).rotation
arView.scene.anchors.append(box)
}
}
Read this post to find out how to load a texture for RealityKit's shaders.
How to create RealityKit's shaders similar to SceneKit's shaders
We know that in SceneKit there are 5 different shading models, so we can use RealityKit's SimpleMaterial
, PhysicallyBasedMaterial
and UnlitMaterial
to generate all these five shaders that we've been accustomed to.
Let's see how it looks like:
SCNMaterial.LightingModel.blinn – SimpleMaterial(color: . gray,
roughness: .float(0.5),
isMetallic: false)
SCNMaterial.LightingModel.lambert – SimpleMaterial(color: . gray,
roughness: .float(1.0),
isMetallic: false)
SCNMaterial.LightingModel.phong – SimpleMaterial(color: . gray,
roughness: .float(0.0),
isMetallic: false)
SCNMaterial.LightingModel.physicallyBased – PhysicallyBasedMaterial()
// all three shaders (`.constant`, `UnlitMaterial` and `VideoMaterial `)
// don't depend on lighting
SCNMaterial.LightingModel.constant – UnlitMaterial(color: .gray)
– VideoMaterial(avPlayer: avPlayer)
Within RealityKit, how can I make the world without friction?
Apply a new Physics Material
to your model entity.
For this use generate(friction:restitution:)
type method:
static func generate(friction: Float = 0,
restitution: Float = 0) -> PhysicsMaterialResource
where
/* the coefficient of friction is in the range [0, infinity] */
/* and the coefficient of restitution is in the range [0, 1] */
Here's a code:
arView.environment.background = .color(.darkGray)
let mesh = MeshResource.generateSphere(radius: 0.5)
let material = SimpleMaterial()
let model = ModelEntity(mesh: mesh,
materials: [material]) as (ModelEntity & HasPhysics)
let physicsResource: PhysicsMaterialResource = .generate(friction: 0,
restitution: 0)
model.components[PhysicsBodyComponent] = PhysicsBodyComponent(
shapes: [.generateSphere(radius: 0.51)],
mass: 20, // in kilograms
material: physicsResource,
mode: .dynamic)
model.generateCollisionShapes(recursive: true)
let anchor = AnchorEntity()
anchor.addChild(model)
arView.scene.anchors.append(anchor)
P.S. Due to some imperfectness of physics engine in RealityKit, I suppose there's no possibility to create an eternal bouncing. Seemingly next RealityKit's update will fix physics engine imperfectness.
Related Topics
How to Compare Two Dates (Nsdate) in Swift 3 and Get The Days Between Them
Notification in Swift Returning Userinfo in Dictionary
Tableview Image Content Selection Color
Uibutton Action Is Not Triggered After Constraint Layouts Changed
Why Is Inceptionv3 Machine Learning Model Not Recognized on My Project
Extend All Number Types in Swift
Nstextfield Non-System-Font Content Clipped When Usessinglelinemode Is True
Swift Override Static Method Compile Error
"This Class Is Not Key Value Coding-Compliant" Using Coreimage
Access Class Property from Instance
Location Access Request in iOS 11
Convert Time String into Date Swift
Swift: How to Add a Class Method in 'string" Extension
iOS 12 Wkwebview Not Working with Redirects
Bridgetoobjectivec Not Available on Swift Beta 5