swift - 对 ARKit SCNNode 应用多次旋转
问题描述
我正在使用一个 AR 应用程序,它使用 Apple 的 Focus Square 来指导用户在垂直和水平表面上的交互。但是,它仅设计用于水平表面。我已经修改了更新正方形旋转的方法以考虑垂直表面。但是,使用他们一次只能执行一次旋转的方法,而为了使正方形正确定位在水平表面上,我需要执行两次旋转(一次用于应用原始偏航校正,一次用于垂直倾斜正方形)。
相关代码如下,但我做的具体改动只是开头和结尾。
// MARK: - Appearence
func update(for position: float3, planeAnchor: ARPlaneAnchor?, camera: ARCamera?) {
lastPosition = position
let thisAlignment = planeAnchor?.alignment ?? .horizontal
if thisAlignment != lastAlignment {
lastAlignment = thisAlignment
print("alignmentChanged")
recentFocusSquarePositions = []
}
if let anchor = planeAnchor {
close(flash: !anchorsOfVisitedPlanes.contains(anchor))
lastPositionOnPlane = position
anchorsOfVisitedPlanes.insert(anchor)
} else {
open()
}
updateTransform(for: position, alignment: thisAlignment, camera: camera)
}
private func updateTransform(for position: float3, alignment: ARPlaneAnchor.Alignment, camera: ARCamera?) {
// add to list of recent positions
recentFocusSquarePositions.append(position)
// remove anything older than the last 8
recentFocusSquarePositions.keepLast(8)
// move to average of recent positions to avoid jitter
if let average = recentFocusSquarePositions.average {
self.simdPosition = average
self.setUniformScale(scaleBasedOnDistance(camera: camera))
}
// Correct y rotation of camera square
if let camera = camera {
let tilt = abs(camera.eulerAngles.x)
let threshold1: Float = .pi / 2 * 0.65
let threshold2: Float = .pi / 2 * 0.75
let yaw = atan2f(camera.transform.columns.0.x, camera.transform.columns.1.x)
var angle: Float = 0
switch tilt {
case 0..<threshold1:
angle = camera.eulerAngles.y
case threshold1..<threshold2:
let relativeInRange = abs((tilt - threshold1) / (threshold2 - threshold1))
let normalizedY = normalize(camera.eulerAngles.y, forMinimalRotationTo: yaw)
angle = normalizedY * (1 - relativeInRange) + yaw * relativeInRange
default:
angle = yaw
}
if alignment == .vertical{
self.rotation = SCNVector4(0, 1, 1, Float.pi)
} else {
self.rotation = SCNVector4(0, 1, 0, angle)
}
}
}
我的目标是最后在对象上执行控制语句中的两个旋转。如果else
删除该语句,则仅应用该旋转并且正方形保持水平。我曾尝试直接使用对变换进行两种修改,SCNMatrix4MakeRotation(_:_:_:_:)
但这会导致正方形无休止地旋转并错误地定位自身。我也尝试调整节点Pivot
,但这导致对象没有可见的变化。
解决方案
推荐阅读
- django - Django - 有没有办法将某些 url 配置为无法从浏览器请求中访问?
- authorization - Blazor - 级联用户名到所有组件
- java - Gradle 自定义类型:默认任务“错误:找不到符号”
- grafana - Grafana 仅针对少数相对时间范围过滤器显示“未找到数据”
- google-app-engine - 应用引擎将静态文件分派到 CDN url
- flutter - 是否有根据时间更新数据库的功能
- ios - 无法将类型“(ViewController)->()->()”的值转换为预期的参数类型“()->()”
- vue.js - 如何向这个 Vue 组件添加组件?
- jquery - Jquery TimePicker 如何将显示小时或分钟的标题更改为其他内容?
- javascript - JS - 重新映射数组并将父元素添加到子数组