SceneKit加CoreMotion实现全景图浏览

SceneKit是iOS中的一个简单的3D引擎,有了他,我们可以将一些简单的3D功能直接通过OC来实现,而不需要借助Unity3D这类游戏引擎了。下面我们就用SceneKit来实现一个简单的全景图浏览功能。

图形学扫盲:首先有一个3D的场景,然后场景里面有各种3D的模型,有灯光,最后,通过摄像机,将3D的场景映射到一个2D的平面上显示出来,这是基础。

通过这个我们可以想到全景图最简单的一个实现方案,那就是,一个球体,然后将摄像机放置在球体的球心处,然后将一个全景图的资源以贴图的形式放置在球体上,再设置球体为单面。这样,我们通过摄像机就能看到图像了,转动摄像机,就是看到的全景图的不同部分。下面上代码。

    //创建场景
    SCNView *scnView = [[SCNView alloc] initWithFrame:self.view.bounds];
    scnView.scene = [SCNScene new];
    [self.view addSubview:scnView];
    
    //添加相机节点
    SCNCamera *camera = [SCNCamera new];
    camera.automaticallyAdjustsZRange = YES;
    SCNNode *cameraNode = [SCNNode new];
    cameraNode.camera = camera;
    cameraNode.position = SCNVector3Make(0, 0, 0);
    [scnView.scene.rootNode addChildNode:cameraNode];
    
    //添加一个球体
    SCNNode *panoramaNode = [SCNNode new];
    panoramaNode.geometry = [SCNSphere sphereWithRadius:150];
    panoramaNode.geometry.firstMaterial.cullMode = SCNCullModeFront;
    panoramaNode.geometry.firstMaterial.doubleSided = NO;
    panoramaNode.position = SCNVector3Make(0, 0, 0);
    [scnView.scene.rootNode addChildNode:panoramaNode];
    panoramaNode.geometry.firstMaterial.diffuse.contents = [UIImage imageNamed:@"日本.jpg"];

这样我们就创建了一个全景图展示的功能。但是由于摄像机角度是固定的,我们无法查看各个方向。有两种办法,一种是通过手指在屏幕上滑动来改变摄像机的角度,这种办法比较简单。第二种是比较酷一点的,读取手机陀螺仪的信息来改变摄像机的方向,这样用户只要拿着手机转动,就能浏览全景图了,有点VR的味道。下面是代码。

@interface ViewController ()
{
    CMMotionManager *_motionManager;
}

motionManager需要是类的一个成员哟,如果直接在方法里面写,是会被释放掉的。

_motionManager = [[CMMotionManager alloc] init];
//设置信息更新评率,显然60FPS就很奢侈了
    _motionManager.deviceMotionUpdateInterval = 1/60.0;
    NSOperationQueue *queue = [NSOperationQueue new];
    [_motionManager startDeviceMotionUpdatesToQueue:queue withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {
        cameraNode.orientation = [self orientationFromCMQuaternion:motion.attitude.quaternion];
    }];

用陀螺的信息时需要经过一个转换,而且最好使用陀螺里面读取到的设备姿态信息,即“attitude”,使用GLKit中四维数转化的方法可以将CoreMotion中的数据转化至SceneKit中,以下是转换的方法

- (SCNQuaternion)orientationFromCMQuaternion:(CMQuaternion)q
{
    GLKQuaternion gq1 = GLKQuaternionMakeWithAngleAndAxis(GLKMathDegreesToRadians(-90), 1, 0, 0);
    GLKQuaternion gq2 = GLKQuaternionMake(q.x, q.y, q.z, q.w);
    GLKQuaternion qp  = GLKQuaternionMultiply(gq1, gq2);
    
    return SCNVector4Make(qp.x, qp.y, qp.z, qp.w);
}

记得引用一下GLKit库。

代码在这里:https://download.youkuaiyun.com/download/a690993211/10623300

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值