仿微博全景图 - SceneKit

一、原理部分

1.利用SceneKit 造一个球面
2.将图片铺满球面
3.在球中心放一个相机,也就是我们的眼睛所在,
4.根据手势或者陀螺仪,改变相机视野

仿微博全景图 - SceneKit_第1张图片
大概这样.png
二、代码部分

1.导入 SceneKit框架
SceneKit是一个高性能的渲染游戏引擎,它能够将 3D 模型文件,用很简单的方式渲染出来.

import SceneKit

2.创建SCNView 并加到 view上

let scnView = SCNView()
scnView.frame = view.bounds
//SCNView中scene默认为 nil
scnView.scene = SCNScene()
self.view.addSubview(scnView);

3.添加相机节点

let camera = SCNCamera()
cameraNode.camera = camera
cameraNode.camera?.automaticallyAdjustsZRange = true;
cameraNode.position = SCNVector3Make(0, 0, 0);
scnView.scene?.rootNode.addChildNode(cameraNode);

4.添加图片显示节点

let panoramaNode = SCNNode()
panoramaNode.geometry = SCNSphere(radius: 100);
//剔除外表面
panoramaNode.geometry?.firstMaterial?.cullMode = .front
//只显示一个面
panoramaNode.geometry?.firstMaterial?.isDoubleSided = false
panoramaNode.position = SCNVector3Make(0, 0, 0);
scnView.scene?.rootNode.addChildNode(panoramaNode);

5.显示图片

let image = UIImage(named: "星空")
panoramaNode.geometry?.firstMaterial?.diffuse.contents = image

6.实现滑动旋转

let pan = UIPanGestureRecognizer(target: self, action: #selector(panImage(gesture:)))
scnView.addGestureRecognizer(pan)

根据手指移动距离计算角度,然后旋转相机节点


if gesture.state == .began {
    let currentPoint = gesture .location(in: self.scnView)
    lastPoint_x = currentPoint.x
    lastPoint_y = currentPoint.y
}else{
    let currentPoint = gesture .location(in: self.scnView)
    var distX = currentPoint.x - lastPoint_x
    var distY:CGFloat = currentPoint.y - lastPoint_y
    lastPoint_x = currentPoint.x
    lastPoint_y = currentPoint.y
    distX *= -0.003
    distY *= -0.003
    
    fingerRotationY += distY
    fingerRotationX += distX
    
    var modelMatrix = SCNMatrix4MakeRotation(0, 0, 0, 0)
    modelMatrix = SCNMatrix4Rotate(modelMatrix, Float(fingerRotationX),0, 1, 0);
    modelMatrix = SCNMatrix4Rotate(modelMatrix, Float(fingerRotationY), 1, 0, 0);
    self.cameraNode.pivot = modelMatrix;
}

7.实现图片放大缩小
添加捏合手势

let pinch = UIPinchGestureRecognizer(target: self, action: #selector(pinchGesture(gesture:)))
scnView.addGestureRecognizer(pinch)

手势计算

    @objc func pinchGesture(gesture:UIGestureRecognizer){
        if !gesture.isKind(of: UIPinchGestureRecognizer.self){
            return
        }
        let pinchGesture = gesture as! UIPinchGestureRecognizer
        if pinchGesture.state != .ended && pinchGesture.state != .failed{
            if/* pinchGesture.scale != NAN  && */ pinchGesture.scale != 0.0{
                
                var scale = pinchGesture.scale - 1
                if scale < 0 {
                    scale *= (sScaleMax - sScaleMin)
                }
                    currentScale = scale + prevScale
                    currentScale = validateScale(scale: currentScale)
                    let valScale = validateScale(scale: currentScale)
                    let xFov = 90 * (1-(valScale-1)*0.15)
                    let yFov = 50 * (1-(valScale-1)*0.15)
                    cameraNode.camera?.xFov = Double(xFov)
                    cameraNode.camera?.yFov = Double(yFov)
            }
            }else if pinchGesture.state == .ended{
            prevScale = currentScale
        }
    }
    private func validateScale(scale:CGFloat) -> CGFloat {
        var validateScale = scale
        if scale < sScaleMin {
            validateScale = sScaleMin
        } else if scale > sScaleMax{
            validateScale = sScaleMax
        }
        return validateScale
    }
效果
全景图来自微博 侵删

Demo:https://github.com/SherlockQi/PanoramaImage

你可能感兴趣的:(仿微博全景图 - SceneKit)