SceneKit: повысить производительность функции hitTest в SceneView?
Наша сцена имеет всего около 20 узлов. Приведенный ниже код позволяет пользователю выполнять панорамирование, выполняя проверку попадания на каждом панораме. Цель состоит в том, чтобы выделить блоки, когда пользователь перемещается по экрану.
Тем не менее, это заметно вялый на iPhone 5S. Это не детерминистично, но случается достаточно часто, чтобы вызывать раздражение (каждые 5-10 сковородок).
Мы рассмотрели использование hitTestWithSegment
так как вы можете жестко ограничить диапазон для тестирования, но считаете, что это должно быть медленнее, потому что вы должны сначала вычислить две точки, необходимые для функции.
Кроме того, SCNHitTestClipToZRangeKey
вариант для hitTest
должен обеспечить сопоставимый прирост производительности путем ужесточения диапазона попаданий без необходимости вычисления двух дополнительных точек.
Любые предложения по ускорению работы hitTest
?
func sceneViewPannedOneFinger(sender: UIPanGestureRecognizer) {
// Get pan distance & convert to radians
let translation = sender.translationInView(sender.view!)
var xRadians = GLKMathDegreesToRadians(Float(translation.x))
var yRadians = GLKMathDegreesToRadians(Float(translation.y))
// Get x & y radians
xRadians = (xRadians / 4) + curXRadians
yRadians = (yRadians / 4) + curYRadians
// Limit yRadians to prevent rotating 360 degrees vertically
yRadians = max(Float(-M_PI_2), min(Float(M_PI_2), yRadians))
// Set rotation values to avoid Gimbal Lock
cameraNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: yRadians)
userNode.rotation = SCNVector4(x: 0, y: 1, z: 0, w: xRadians)
// Save value for next rotation
if sender.state == UIGestureRecognizerState.Ended {
curXRadians = xRadians
curYRadians = yRadians
}
// Set preview block
setPreviewBlock(sender)
}
private func setPreviewBlock(recognizer: UIGestureRecognizer) {
let point = recognizer.locationInView(sceneView)
let options = [SCNHitTestRootNodeKey: sceneView.scene!.rootNode, SCNHitTestClipToZRangeKey: 15, SCNHitTestSortResultsKey: true]
let hits = sceneView.hitTest(point, options: options)
print(hits.first?.worldCoordinates)
}