[swift] scenekit / Panジェスチャーでdaeモデルを拡大・縮小

daeモデルから作成したSCNNodeをパンジェスチャーで拡大縮小するコードは以下の通り。

scaleでモデルの見た目の大きさは変化させることができるが、物理情報(Physicalbody)の大きさはscaleを変えただけでは変化させられないため、パンジェスチャー終了時に「SCNPhysicsShape.Option.scale」で物理情報(Physicalbody)の大きさも同じ大きさに変更する。

パンジェスチャーの都度に物理情報(Physicalbody)を変更すると、かなりガタつくので、終了時に変更している。

    var targetedNode = SCNNode()
    let gun = "art.scnassets/Handgun_dae.dae"
    let y:Float = 8
    var currentScale = SCNVector3()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        //sceneの基本設定は省略.......

        //daeモデルからscnNodeを作成
        targetedNode = createObject(position: SCNVector3Make(-1.5, y, 0), restitution: 0.1, filepath: gun)

        //パンジェスチャーの作成
        let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch))

        //パンジェスチャーのアタッチ
        scnView.addGestureRecognizer(pinchGesture)

    }

    @objc
    func handlePinch(_ gesture: UIPinchGestureRecognizer) {

            let scale = Float(gesture.scale)
            let object = targetedNode
            
            switch gesture.state{

            //パンジェスチャーの都度    
            case .changed:

                //ノードのスケールを拡大・縮小
                object.scale = SCNVector3(currentScale.x*scale, currentScale.y*scale, currentScale.z*scale)
               
            //パンジェスチャーの終了 
            case .ended , .cancelled:

                //ノードの物理情報を拡大・縮小
                let aModelShape = SCNPhysicsShape(node: object, options: [
                    SCNPhysicsShape.Option.scale: NSValue(scnVector3: SCNVector3(x: currentScale.x*scale, y: currentScale.y*scale, z: currentScale.z*scale))
                    ])

                //拡大・縮小した物理情報をノードにアタッチ
                object.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.dynamic, shape: aModelShape)
                
                //位置情報を現在の位置に修正
                object.position = object.presentation.position

            default:
                NSLog("not action")
            }
    }

    //daeモデルを生成(詳しい詳細は別記事にて解説)
    func createObject(position:SCNVector3, restitution:CGFloat,filepath:String) -> SCNNode {
        let scene = SCNScene(named: filepath)
        let node: SCNNode = scene!.rootNode.childNodes[0]
        let aModelShape = SCNPhysicsShape(node: node, options: nil)
        let physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil)
        physicsBody.restitution = restitution
        node.physicsBody = physicsBody
        node.position = position
        node.name = "object"
        
        return node
    }

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です