使用ARKit将对象放置在平面上时,当对象总数超过一个时,有时对象会固定在相机框架上,并且实际上并未在真实场景中渲染。我猜想这可能是由于某些外部因素造成的,例如照明,feature points,真实世界飞机的质量等。是否有人遇到过这种情况,或者是否知道解决此问题的方法或解决方法?防止这种情况?谢谢!
编辑:这是一些处理对象渲染的代码:
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
DispatchQueue.main.async {
self.virtualObjectInteraction.updateObjectToCurrentTrackingPosition()
self.updateFocusSquare()
}
if objectsViewController != nil {
let planeAnchor = focusSquare.currentPlaneAnchor
objectsViewController?.updateObjectAvailability(for: planeAnchor)
}
// If the object selection menu is open, update availability of items
if objectsViewController != nil {
let planeAnchor = focusSquare.currentPlaneAnchor
objectsViewController?.updateObjectAvailability(for: planeAnchor)
}
// If light estimation is enabled, update the intensity of the directional lights
if let lightEstimate = session.currentFrame?.lightEstimate {
sceneView.updateDirectionalLighting(intensity: lightEstimate.ambientIntensity, queue: updateQueue)
} else {
sceneView.updateDirectionalLighting(intensity: 1000, queue: updateQueue)
}
}
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
updateQueue.async {
for object in self.virtualObjectLoader.loadedObjects {
object.adjustOntoPlaneAnchor(planeAnchor, using: node)
}
}
}
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
updateQueue.async {
if let planeAnchor = anchor as? ARPlaneAnchor {
for object in self.virtualObjectLoader.loadedObjects {
object.adjustOntoPlaneAnchor(planeAnchor, using: node)
}
} else {
if let objectAtAnchor = self.virtualObjectLoader.loadedObjects.first(where: { $0.anchor == anchor }) {
objectAtAnchor.simdPosition = anchor.transform.translation
objectAtAnchor.anchor = anchor
}
}
}
}
func setTransform(_ newTransform: float4x4,
relativeTo cameraTransform: float4x4,
smoothMovement: Bool,
alignment: ARPlaneAnchor.Alignment,
allowAnimation: Bool) {
let cameraWorldPosition = cameraTransform.translation
var positionOffsetFromCamera = newTransform.translation - cameraWorldPosition
if simd_length(positionOffsetFromCamera) > 10 {
positionOffsetFromCamera = simd_normalize(positionOffsetFromCamera)
positionOffsetFromCamera *= 10
}
if smoothMovement {
let hitTestResultDistance = simd_length(positionOffsetFromCamera)
// Add the latest position and keep up to 10 recent distances to smooth with.
recentVirtualObjectDistances.append(hitTestResultDistance)
recentVirtualObjectDistances = Array(recentVirtualObjectDistances.suffix(10))
let averageDistance = recentVirtualObjectDistances.average!
let averagedDistancePosition = simd_normalize(positionOffsetFromCamera) * averageDistance
simdPosition = cameraWorldPosition + averagedDistancePosition
} else {
simdPosition = cameraWorldPosition + positionOffsetFromCamera
}
updateAlignment(to: alignment, transform: newTransform, allowAnimation: allowAnimation)
}
func placeVirtualObject(_ virtualObject: VirtualObject) {
guard let cameraTransform = session.currentFrame?.camera.transform,
let focusSquareAlignment = focusSquare.recentFocusSquareAlignments.last,
focusSquare.state != .initializing else {
return
}
let focusSquareScaleInverse = 1.0 / focusSquare.simdScale.x
let scaleMatrix = float4x4(uniformScale: focusSquareScaleInverse)
let focusSquareTransformWithoutScale = focusSquare.simdWorldTransform * scaleMatrix
virtualObjectInteraction.selectedObject = virtualObject
virtualObject.setTransform(focusSquareTransformWithoutScale,
relativeTo: cameraTransform,
smoothMovement: false,
alignment: focusSquareAlignment,
allowAnimation: false)
updateQueue.async {
self.sceneView.scene.rootNode.addChildNode(virtualObject)
self.sceneView.addOrUpdateAnchor(for: virtualObject)
}
}