Обновлено
Я проверял это. Ваша модель имеет неправильный начальный масштаб. Это в метрах!
Width = 786
метров Height = 676
метров Depth = 456
метров
Используйте следующие значения, чтобы уменьшить модель:
let scene = SCNScene(named: "art.scnassets/Cube.scn")!
let modelNode: SCNNode? = scene.rootNode.childNode(withName: "_material_1",
recursively: true)
let scale: Float = 0.002 // 500 times smaller
modelNode?.scale = SCNVector3(scale, scale, scale)
... и вернуть вашу модель вдоль оси Z:
modelNode?.position.z = 0
Вот почему ваша модель застревает впереди. камеры - это связано с тем, что вы поместили модель в 800 метрах от начала координат. Таким образом, вы не могли смотреть на него при правильном параллаксе.
Попробуйте следующий код, чтобы разместить вашу модель в ожидаемой позиции теста удара:
@objc func tap(gesture: UITapGestureRecognizer) {
let touch: CGPoint = gesture.location(in: sceneView)
let result: [ARHitTestResult] = sceneView.hitTest(touch,
types: .existingPlaneUsingExtent)
guard let hitTest: ARHitTestResult = result.first
else { return }
self.loadModel(hitTest)
}
Затем создайте содержимое для метода loadModel(:_)
:
func loadModel(_ result: ARHitTestResult) {
let scene = SCNScene(named: "art.scnassets/myScene.scn")!
let node: SCNNode? = scene.rootNode.childNode(withName: "model",
recursively: true)
node?.position = SCNVector3(result.worldTransform.columns.3.x,
result.worldTransform.columns.3.y,
result.worldTransform.columns.3.z)
// Please consider that ARKit's and SceneKit's scenes are in Meters
node?.scale = SCNVector3(0.5, 2.0, 0.5)
self.sceneView.scene.rootNode.addChildNode(node!)
}
И затем введите #selector
с помощью метода @ obj c tap
:
override func viewDidLoad() {
super.viewDidLoad()
let gestureRecognizer = UITapGestureRecognizer(target: self,
action: #selector(tap))
self.sceneView.addGestureRecognizer(gestureRecognizer)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let config = ARWorldTrackingConfiguration()
config.planeDetection = .horizontal
self.sceneView.session.run(config)
}
И мне кажется, что вы используете неправильное преобразование, потому что оно находится в последнем столбце матрицы преобразования 4x4:
┌ ┐
| 1 0 0 tx |
| 0 1 0 ty |
| 0 0 1 tz |
| 0 0 0 1 |
└ ┘
1. проверьте, где находится точка вращения вашей 3D-модели? Если точка вращения вашей модели смещена по осям + Z, то она всегда стоит перед вашей камерой .
2. Убедитесь, что масштаб вашей модели не в десятках или сотнях метров .
Решение для шкалы:
Если Вы хотите, чтобы узел с масштабом по умолчанию (1,0) поместил ваш modelNode
с scale=0.002
в родительский узел с scale=1.0
:
let scene = SCNScene(named: "art.scnassets/Cube.scn")!
let modelNode: SCNNode? = scene.rootNode.childNode(withName: "_material_1",
recursively: true)
let scale: Float = 0.002 // 500 times smaller
modelNode?.scale = SCNVector3(scale, scale, scale)
let defaultScaleNode = SCNNode()
defaultScaleNode.addChildNode(modelNode!)
defaultScaleNode.scale = SCNVector3(1.0, 1.0, 1.0)