Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
996 views
in Technique[技术] by (71.8m points)

swift - Reality Composer - Custom Collision Between Entities of Different Scenes

I'm pretty new to RealityKit and ARKit. I have two scenes in Reality Composer, one with a book image anchor and one with a horizontal plane anchor. The first scene with an image anchor has a cube attached to the top of it and the second scene built on a horizontal plane has two rings. All objects have a fixed collision. I'd like to run an animation when the rings and the cube touch. I couldn't find a way to do this in Reality Composer, so I made two attempts within the code to no avail. (I'm printing "collision started" just to test the collision code without the animation) Unfortunately, it didn't work. Would appreciate help on this.

Attempt #1:

func makeUIView(context: Context) -> ARView {

    let arView = ARView(frame: .zero)

    let componentBreakdownAnchor = try! CC.loadComponentBreakdown()

    arView.scene.anchors.append(componentBreakdownAnchor)

    let bookAnchor = try! CC.loadBook()
    arView.scene.anchors.append(bookAnchor)   

    let ringsAnchor = try! CC.loadRings()
    arView.scene.anchors.append(ringsAnchor)

    // Add the componentBreakdown anchor to the scene
    arView.scene.anchors.append(componentBreakdownAnchor)

    let bookAnchor = try! CC.loadBook()
    arView.scene.anchors.append(bookAnchor)    

    let ringsAnchor = try! CC.loadRings()
    arView.scene.anchors.append(ringsAnchor)

    let _ = ringsAnchor.scene?.subscribe(
    to: CollisionEvents.Began.self,
    on: bookAnchor
    ) { event in
      print("collision started")
    }

    return arView
}

Attempt #2

func makeUIView(context: Context) -> ARView {

    let arView = ARView(frame: .zero)

    let componentBreakdownAnchor = try! CC.loadComponentBreakdown()

    arView.scene.anchors.append(componentBreakdownAnchor)

    let bookAnchor = try! CC.loadBook()
    arView.scene.anchors.append(bookAnchor)  

    let ringsAnchor = try! CC.loadRings()
    arView.scene.anchors.append(ringsAnchor)

    // Add the componentBreakdown anchor to the scene
    arView.scene.anchors.append(componentBreakdownAnchor)

    let bookAnchor = try! CC.loadBook()
    arView.scene.anchors.append(bookAnchor)   

    let ringsAnchor = try! CC.loadRings()
    arView.scene.anchors.append(ringsAnchor)

    arView.scene.subscribe(
      to: CollisionEvents.Began.self,
      on: bookAnchor

    ) { event in
      print("collision started")
    }

    return arView
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

RealityKit scene

If you want to use models' collisions made in RealityKit's scene from scratch, at first you need to implement a HasCollision protocol.

Let's see what a developer documentation says about it:

HasCollision protocol is an interface used for ray casting and collision detection.

Here's how your implementation should look like if you generate models in RealityKit:

import Cocoa
import RealityKit

class CustomCollision: Entity, HasModel, HasCollision {

    let color: NSColor = .gray
    let collider: ShapeResource = .generateSphere(radius: 0.5)
    let sphere: MeshResource = .generateSphere(radius: 0.5)

    required init() {
        super.init()

        let material = SimpleMaterial(color: color,
                                 isMetallic: true)

        self.components[ModelComponent] = ModelComponent(mesh: sphere,
                                                    materials: [material])

        self.components[CollisionComponent] = CollisionComponent(shapes: [collider],
                                                                   mode: .trigger,
                                                                 filter: .default)
    }
}

Reality Composer scene

And here's how your code should look like if you use models from Reality Composer:

import UIKit
import RealityKit
import Combine

class ViewController: UIViewController {

    @IBOutlet var arView: ARView!
    var subscriptions: [Cancellable] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        let groundSphere = try! Experience.loadStaticSphere()
        let upperSphere = try! Experience.loadDynamicSphere()

        let gsEntity = groundSphere.children[0].children[0].children[0]
        let usEntity = upperSphere.children[0].children[0].children[0]

        // CollisionComponent exists in case you turn on 
        // "Participates" property in Reality Composer app
        print(gsEntity)   

        let gsComp: CollisionComponent = gsEntity.components[CollisionComponent]!.self
        let usComp: CollisionComponent = usEntity.components[CollisionComponent]!.self

        gsComp.shapes = [.generateBox(size: [0.05, 0.07, 0.05])]
        usComp.shapes = [.generateBox(size: [0.05, 0.05, 0.05])]

        gsEntity.components.set(gsComp)
        usEntity.components.set(usComp)

        let subscription = self.arView.scene.subscribe(to: CollisionEvents.Began.self,
                                                       on: gsEntity) { event in
            print("Balls' collision occured!")
        }
        self.subscriptions.append(subscription)

        arView.scene.anchors.append(upperSphere)
        arView.scene.anchors.append(groundSphere)
    }
}

enter image description here enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...