ARKit技术问询:如何检测相机是否触碰AR物体?
Hey there! Building a Portal-like AR app without Unity sounds fun—let's walk through how to implement camera origin collision detection with haptic feedback step by step:
First off, the camera origin in AR is essentially the user's viewpoint in 3D space. Our goal is to continuously track this 3D coordinate, check if it intersects with any AR objects (like your wall cubes), and trigger haptic feedback the moment a collision happens.
1. Get the Camera's Real-Time 3D Position
All major AR frameworks (ARKit, ARCore, etc.) provide APIs to fetch the camera's world-space position. Here are quick examples for the two main platforms:
- ARCore (Android): Use the camera pose's translation data:
Pose cameraPose = session.getCamera().getPose(); float[] cameraPos = cameraPose.getTranslation(); // cameraPos[0] = x, cameraPos[1] = y, cameraPos[2] = z - ARKit (iOS): Extract the translation from the camera's transform matrix:
guard let cameraTransform = arView.session.currentFrame?.camera.transform else { return } let cameraPos = SIMD3<Float>(cameraTransform.columns.3.x, cameraTransform.columns.3.y, cameraTransform.columns.3.z)
Critical note: Make sure all AR objects in your scene use the same world coordinate system as the camera—this avoids misalignment issues during collision checks.
2. Define Collision Boundaries for AR Objects
For simple objects like wall cubes, use bounding boxes to represent their collision area:
- Axis-Aligned Bounding Box (AABB): The easiest option—store the minimum and maximum x/y/z coordinates of the cube. For example, if your cube is centered at
(0, 1.5, -3)with dimensions(2, 2, 0.1), the min/max would be(-1, 0.5, -3.05)and(1, 2.5, -2.95). - Oriented Bounding Box (OBB): Use this if your cube is rotated (not aligned with world axes). You'll need the cube's center position, size, and rotation matrix to transform the camera position into the cube's local space for checks.
For irregular AR objects, you can combine multiple simple bounding boxes or use convex hulls for better accuracy.
3. Real-Time Collision Detection
Run this check every frame to see if the camera origin intersects with any object's collision boundary:
- AABB Check (for axis-aligned cubes):
boolean isColliding = (cameraPos[0] >= cubeMinX && cameraPos[0] <= cubeMaxX) && (cameraPos[1] >= cubeMinY && cameraPos[1] <= cubeMaxY) && (cameraPos[2] >= cubeMinZ && cameraPos[2] <= cubeMaxZ); - OBB Check: Transform the camera position into the object's local space using inverse rotation, then perform an AABB check on the transformed point.
Pro tip: If a point check feels too sensitive, expand the camera origin into a tiny sphere (e.g., 1cm radius) and check for sphere-box collisions instead—this feels more natural for "touching" in AR.
4. Trigger Haptic Feedback
Once a collision is detected, use platform-specific APIs to trigger vibrations:
- iOS: Use
UIImpactFeedbackGeneratorfor a physical "tap" feel:let impactGenerator = UIImpactFeedbackGenerator(style: .medium) impactGenerator.prepare() // Preload for faster response impactGenerator.impactOccurred() - Android: Use the
Vibratorservice:Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { vibrator.vibrate(VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE)); } else { vibrator.vibrate(200); // Legacy API for older devices }
Avoid spam: Add a cooldown period (e.g., 500ms) so the vibration doesn't fire every frame during a sustained collision. You can track the last feedback time and only trigger it if enough time has passed.
- Spatial Partitioning: If you have lots of AR objects, use a spatial structure like an octree to only check objects near the camera—this reduces unnecessary computations.
- Visual Feedback: Pair haptics with on-screen cues (e.g., a red border around the screen) to make the collision more obvious for users.
- Performance Testing: Run collision checks on a background thread if needed, to avoid dropping AR frame rates.
内容的提问来源于stack exchange,提问作者Santosh

