SceneKit. How to create box with rounded edges and with different radiuses?

Viewed 25

I've started learning SceneKit. And I've tried SCNBox. And it has chamferRadius. But the radius is applied for all the edges. But I want to achieve something similar to the one on the screenshot belowenter image description here

1 Answers

You can do this by extruding a UIBezierPath:

    // rounded rect bezier path
    let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: 1.0, height: 1.0), cornerRadius: 0.1)
    
    path.flatness = 0
    
    // extrude the path
    let shape = SCNShape(path: path, extrusionDepth: 0.05)
    
    let mat = SCNMaterial()
    mat.diffuse.contents = UIColor(white: 0.9, alpha: 1.0)
    shape.materials = [mat]
    
    let shapeNode = SCNNode(geometry: shape)

Result:

enter image description here

Here's a full example (note: I have only glanced at SceneKit, so I used this tutorial as a starting point Introduction to SceneKit):

import UIKit
import SceneKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let sceneView = SCNView(frame: self.view.frame)
        self.view.addSubview(sceneView)

        let scene = SCNScene()
        sceneView.scene = scene
        
        let camera = SCNCamera()
        let cameraNode = SCNNode()
        cameraNode.camera = camera
        cameraNode.position = SCNVector3(x: 3.0, y: 2.0, z: 1.5)
        
        let ambientLight = SCNLight()
        ambientLight.type = .ambient
        ambientLight.color = UIColor(white: 0.9, alpha: 1.0)
        cameraNode.light = ambientLight

        let light = SCNLight()
        light.type = SCNLight.LightType.spot
        light.spotInnerAngle = 30.0
        light.spotOuterAngle = 80.0
        light.castsShadow = true
        let lightNode = SCNNode()
        lightNode.light = light
        lightNode.position = SCNVector3(x: 1.5, y: 1.5, z: 1.5)

        
        // rounded rect bezier path
        let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: 1.0, height: 1.0), cornerRadius: 0.1)
        
        path.flatness = 0
        
        // extrude the path
        let shape = SCNShape(path: path, extrusionDepth: 0.05)
        
        let mat = SCNMaterial()
        mat.diffuse.contents = UIColor(white: 0.9, alpha: 1.0)
        shape.materials = [mat]
        
        let shapeNode = SCNNode(geometry: shape)
        
        
        let planeGeometry = SCNPlane(width: 50.0, height: 50.0)
        let planeNode = SCNNode(geometry: planeGeometry)
        planeNode.eulerAngles = SCNVector3(x: GLKMathDegreesToRadians(-90), y: 0, z: 0)
        planeNode.position = SCNVector3(x: 0, y: 0.0, z: 0)

        let floorMaterial = SCNMaterial()
        floorMaterial.diffuse.contents = UIColor.lightGray
        planeGeometry.materials = [floorMaterial]
        
        scene.rootNode.addChildNode(lightNode)
        scene.rootNode.addChildNode(cameraNode)
        scene.rootNode.addChildNode(shapeNode)
        scene.rootNode.addChildNode(planeNode)
        
        let constraint = SCNLookAtConstraint(target: shapeNode)
        constraint.isGimbalLockEnabled = true
        cameraNode.constraints = [constraint]
        lightNode.constraints = [constraint]

    }


}
Related