问题
I have a fixed laser beam SCNNode and a detecting sphere SCNNode attached in front of a camera.
How to detect penetration without physical interaction? I have not found any clue..
EDIT: - as suggested below by maxxFrazer I implemented physical interaction and I'm able to register collision IF my laser beam is .static and detector moved by camera set .kinematic.
回答1:
If you need to detect a penetration without physical interaction use trackedRaycast
instance method working in iOS 13+:
func trackedRaycast(_ query: ARRaycastQuery,
updateHandler: @escaping ([ARRaycastResult]) -> Void) -> ARTrackedRaycast?
trackedRaycast(_:updateHandler:)
repeats a ray-cast query over time to notify you of updated surfaces in the physical environment.
Here's how it looks like:
import ARKit
let query = arView.raycastQuery(from: screenCenter,
allowing: .estimatedPlane, // also specifies nonplanar geo
alignment: .any)
let raycast = session.trackedRaycast(query) { results in
if let result = results.first {
object.transform = result.transform
}
}
raycast.stop()
Rememmber that trackedRaycast
instance method repeatedly hits surfaces, so you have to stop it if you don't need it anymore.
However, if you need a convex raycast, use a RealityKit's instance method that also works in iOS 13+ and i's called raycast(origin:direction:query:mask:relativeTo:)
.
func raycast(origin: SIMD3<Float>,
direction: SIMD3<Float>,
query: CollisionCastQueryType,
mask: CollisionGroup,
relativeTo: Entity) -> [CollisionCastHit]
This instance method performs a convex ray cast against all the geometry in the scene for a ray of a given origin, direction, and length.
import RealityKit
let startPosition: SIMD3<Float> = [7,7,7]
let endPosition: SIMD3<Float> = [-10,18,5]
let query: CollisionCastQueryType = .all
let mask: CollisionGroup = .all
let raycasts: [CollisionCastHit] = arView.scene.raycast(from: startPosition,
to: endPosition,
query: query,
mask: mask,
relativeTo: nil)
guard let rayCast: CollisionCastHit = raycasts.first
else {
return
}
回答2:
It looks like you want to use a SceneKit solution, not RealityKit. And also want to find when two actual nodes intersect rather than a hitTest or raycast? If so, I've attempted to explain how to set that up below…
First add a physicsBody to the SCNNode, along with a categoryBitMask + contactTestBitMask. These two are basically saying what category your SCNNode body is, and what categories it can collide with.
You then also need to set up your SCNScene.physicsWorld.contactDelegate to an object which conforms to SCNPhysicsContactDelegate, this is so you can use the physicsWorld callbacks found here.
There's another question on stack overflow which may help in making this work for you:
Detecting collisions in SceneKit issue
来源:https://stackoverflow.com/questions/62393887/how-to-detect-penetration-without-physical-interaction-in-arkit