将SCNNode或UIView添加到SCNView的中心,以便检测其他SCNNode
Add SCNNode or UIView to the center of SCNView in order to detect other SCNNodes
我正在尝试将 UIView 居中放置在 SCNView 的中心,以便检测场景中其他添加的 SCNTorus 节点。
我在 sceneView 的中心添加了一个视图,如下所示
var focusPoint: CGPoint {
return CGPoint(
x: sceneView.bounds.size.width / 2,
y: sceneView.bounds.size.height - (sceneView.bounds.size.height / 1.618))
}
然后我尝试了两种方法:
1 -
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
DispatchQueue.main.async { [weak self] in
guard let strongSelf = self else { return }
if !strongSelf.inEditMode { return }
for node in strongSelf.selectionRingsNodes {
let projectedPoint = renderer.projectPoint(node.position)
let projectedCGPoint = CGPoint(x: CGFloat(projectedPoint.x), y: CGFloat(projectedPoint.y))
let distance = projectedCGPoint.distance(to: strongSelf.focusPoint)
if distance < 20 {
print(node.name)
}
}
}
}
2 -
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
DispatchQueue.main.async { [weak self] in
guard let strongSelf = self else { return }
if !strongSelf.inEditMode { return }
for node in strongSelf.selectionRingsNodes {
let (min, max) = node.boundingBox
let projectedMinPoint = renderer.projectPoint(min)
let projectedMinCGPoint = CGPoint(x: CGFloat(projectedMinPoint.x), y: CGFloat(projectedMinPoint.y))
let projectedMaxPoint = renderer.projectPoint(max)
let projectedMaxCGPoint = CGPoint(x: CGFloat(projectedMaxPoint.x), y: CGFloat(projectedMaxPoint.y))
let minX = CGFloat(projectedMinCGPoint.x)
let maxX = CGFloat(projectedMaxCGPoint.x)
let minY = CGFloat(projectedMinCGPoint.y)
let maxY = CGFloat(projectedMaxCGPoint.y)
let nodeRect = CGRect(x: minX, y: minY, width: maxX - minX, height: maxY - minY)
if nodeRect.contains(strongSelf.focusPoint) {
print(node.name)
}
}
}
}
这两种方法return结果错误,距离很大,x和y很大。
终于找到解决方案了!
原来我应该把位置转换成场景的世界坐标space,用这个方法convertPosition(SCNVector3,to:)
这里是完整的代码:
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
DispatchQueue.main.async { [weak self] in
guard let strongSelf = self else { return }
if !strongSelf.inEditMode { return }
for node in strongSelf.selectionRingsNodes {
let position = node.convertPosition(SCNVector3Zero, to: nil)
let projectedPoint = renderer.projectPoint(position)
let projectedCGPoint = CGPoint(x: CGFloat(projectedPoint.x), y: CGFloat(projectedPoint.y))
let distance = projectedCGPoint.distance(to: strongSelf.focusPoint)
if distance < 50 {
strongSelf.showToast(message: node.getTopMostParentNode().name!, font: .systemFont(ofSize: 30))
}
}
}
}
我正在尝试将 UIView 居中放置在 SCNView 的中心,以便检测场景中其他添加的 SCNTorus 节点。
我在 sceneView 的中心添加了一个视图,如下所示
var focusPoint: CGPoint {
return CGPoint(
x: sceneView.bounds.size.width / 2,
y: sceneView.bounds.size.height - (sceneView.bounds.size.height / 1.618))
}
然后我尝试了两种方法:
1 -
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
DispatchQueue.main.async { [weak self] in
guard let strongSelf = self else { return }
if !strongSelf.inEditMode { return }
for node in strongSelf.selectionRingsNodes {
let projectedPoint = renderer.projectPoint(node.position)
let projectedCGPoint = CGPoint(x: CGFloat(projectedPoint.x), y: CGFloat(projectedPoint.y))
let distance = projectedCGPoint.distance(to: strongSelf.focusPoint)
if distance < 20 {
print(node.name)
}
}
}
}
2 -
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
DispatchQueue.main.async { [weak self] in
guard let strongSelf = self else { return }
if !strongSelf.inEditMode { return }
for node in strongSelf.selectionRingsNodes {
let (min, max) = node.boundingBox
let projectedMinPoint = renderer.projectPoint(min)
let projectedMinCGPoint = CGPoint(x: CGFloat(projectedMinPoint.x), y: CGFloat(projectedMinPoint.y))
let projectedMaxPoint = renderer.projectPoint(max)
let projectedMaxCGPoint = CGPoint(x: CGFloat(projectedMaxPoint.x), y: CGFloat(projectedMaxPoint.y))
let minX = CGFloat(projectedMinCGPoint.x)
let maxX = CGFloat(projectedMaxCGPoint.x)
let minY = CGFloat(projectedMinCGPoint.y)
let maxY = CGFloat(projectedMaxCGPoint.y)
let nodeRect = CGRect(x: minX, y: minY, width: maxX - minX, height: maxY - minY)
if nodeRect.contains(strongSelf.focusPoint) {
print(node.name)
}
}
}
}
这两种方法return结果错误,距离很大,x和y很大。
终于找到解决方案了!
原来我应该把位置转换成场景的世界坐标space,用这个方法convertPosition(SCNVector3,to:)
这里是完整的代码:
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
DispatchQueue.main.async { [weak self] in
guard let strongSelf = self else { return }
if !strongSelf.inEditMode { return }
for node in strongSelf.selectionRingsNodes {
let position = node.convertPosition(SCNVector3Zero, to: nil)
let projectedPoint = renderer.projectPoint(position)
let projectedCGPoint = CGPoint(x: CGFloat(projectedPoint.x), y: CGFloat(projectedPoint.y))
let distance = projectedCGPoint.distance(to: strongSelf.focusPoint)
if distance < 50 {
strongSelf.showToast(message: node.getTopMostParentNode().name!, font: .systemFont(ofSize: 30))
}
}
}
}