[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
}