in my new ARKit app the user can place objects on the detected plane. The plane is detected just fine and when the user touches the plane, a new node (a SCNBox) is created and dropped on the plane. This step works just fine.
However, I would like that the newly generated box (a more complex model later) is dropped at the exact center of the model.
Here is my code:
fileprivate func pasteModel(hitResult: ARHitTestResult)
{
guard let model = self.model else { return }
// Get the tapped plane.
if let anchor = hitResult.anchor
{
if let plane = self.planes[anchor.identifier]
{
// Get the dimensions of the model.
let widthModel = CGFloat(0.20)
let lengthModel = CGFloat(0.20)
let box = SCNBox(width: widthModel, height: widthModel, length: widthModel, chamferRadius: 0.0)
box.firstMaterial = SCNMaterial()
box.firstMaterial?.diffuse.contents = UIColor.cyan
let node = SCNNode(geometry: box)
plane.addChildNode(node)
// Get the dimensions of the tapped plane.
let width = plane.width
let length = plane.length
// Calculate the scale (i.e. how much bigger the model is). Keep the ratio, so use the bigger side.
let scaleWidth = widthModel / width
let scaleHeight = lengthModel / length
let scale: Float = Float(1.0 / max(scaleWidth, scaleHeight))
node.scale = SCNVector3Make(scale, scale, scale)
node.position = plane.position
// Check how much the model is away from the center point.
let centerPlane = self.getCenter(ofNode: plane)
let centerNode = self.getCenter(ofNode: node)
let distanceX = centerPlane.x - centerPlane.z
let distanceZ = centerNode.x - centerNode.z
let translation = SCNVector3Make(distanceX, self.MODEL_OFFSET, distanceZ)
node.localTranslate(by: translation)
// After the model has been scaled and positoned properly, the physics body is added.
node.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.dynamic, shape: nil)
node.physicsBody?.mass = self.MODEL_MASS
node.physicsBody?.angularVelocityFactor = SCNVector3Zero // Prevent model rotation.
}
}
}
fileprivate func getCenter(ofNode node: SCNNode) -> SCNVector3
{
let widthNode = node.boundingBox.max.x - node.boundingBox.min.x
let lengthNode = node.boundingBox.max.z - node.boundingBox.min.z
let centerNode = SCNVector3Make(node.position.x + Float(widthNode / 2), node.position.y, node.position.z + Float(lengthNode / 2))
return centerNode
}
Here is a short overview of my approach:
- Get the plane detected by ARKit.
- Create a cube and scale it to the dimensions of the plane - the bigger side is used for scaling.
- Get the center point of both the plane and the cube.
- Translate the cube so the center points align.
Unfortunately the model is not centered. Where is my error?