ARKit实战:如何实现任意门

作者: 皮皮Warrior | 来源:发表于2017-09-22 16:20 被阅读1384次

ARKit实战:如何实现任意门

相关

到底有多强?苹果的增强现实框架:ARKit
ARKit进阶:物理世界
ARKit进阶:材质

技术

任意门特效的实现,主要用到了关于纹理、材质、光照的相关知识,掌握起来并不困难。
如果对相关知识不熟悉,可以看一下上面的文章。

github

如果对工程感兴趣,可以在github上找到源码。欢迎star, fork。
github地址:ARKit_trans-dimensional-room

效果

Demo视频合集
Demo视频合集有两段任意门视频,可以看看效果,分别是:pet_find_transDeminalRoom,
ARKit trans-dimensional room。

cover

目标

我们的目标是要实现一个独立的隐藏空间,这个空间只有一个门留给用户展示,当用户走进去时,可以看到内部的细节。

思路

先构建一个封闭的空间,再用透明材质将它包裹起来,当用户进入这个空间后,可以将背景换成全景的图片,当用户走出时,将背景换回摄像头数据。

实现

实现分三部分:
1 . 处理ARKit检测到的平面
用于提示可以用于交互的平面,后期模拟物理世界也要用到。

- (void)renderer:(id<SCNSceneRenderer>)renderer didAddNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor{
    if ([anchor isKindOfClass:[ARPlaneAnchor class]] && !_stopDetectPlanes){
        NSLog(@"detected plane");
        [self addPlanesWithAnchor:(ARPlaneAnchor*)anchor forNode:node];
        [self postInfomation:@"touch ground to place room"];
    }
}
- (void)renderer:(id<SCNSceneRenderer>)renderer didUpdateNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor{
    if ([anchor isKindOfClass:[ARPlaneAnchor class]]){
        NSLog(@"updated plane");
        [self updatePlanesForAnchor:(ARPlaneAnchor*)anchor];
    }
}
- (void)renderer:(id<SCNSceneRenderer>)renderer didRemoveNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor{
    if ([anchor isKindOfClass:[ARPlaneAnchor class]]){
        NSLog(@"removed plane");
        [self removePlaneForAnchor:(ARPlaneAnchor*)anchor];
    }
}

2 . 放置transDimenRoom
对于隐藏空间,抽象成两个类来表达:transDimenRoomtransDimenStruct
后者用于提供一些平板等基础结构,前者将这些结构拼成一个房间,留一个门框出来让用户能够看见里面。
当需要放置任意门时,就用+transDimenRoomAtPosition:方法创建一个transDimenRoom,当用户走进去时,用-hideWalls:隐藏四周的墙壁,切换成全景背景。

@interface transDimenRoom : SCNNode
@property (nonatomic, strong) SCNNode *walls;

+(instancetype)transDimenRoomAtPosition:(SCNVector3)position;
//TODO:check  if user in room
-(BOOL)checkIfInRoom:(SCNVector3)position;

-(void)hideWalls:(BOOL)hidden;
@end

3 . 检测到用户走进房间
目前为了简单起见,是判断用户与房间中心的距离,当距离小于1时,就认为用户进入了房间。
这里的逻辑以后会收归到transDimenRoom中。

- (void)renderer:(id<SCNSceneRenderer>)renderer updateAtTime:(NSTimeInterval)time{
    if (_room.presentationNode) {
        
        SCNVector3 position = self.sceneView.pointOfView.presentationNode.worldPosition;
        
        SCNVector3 roomCenter = _room.walls.worldPosition;
        
        CGFloat distance = GLKVector3Length(GLKVector3Make(position.x - roomCenter.x, 0, position.z - roomCenter.z));
        
        if (distance < 1){
            NSLog(@"In room");
            [self handleUserInRoom:YES];
            return;
        }
        
        [self handleUserInRoom:NO];
        
    }
}

展望

工程大致提供了让用户从真实世界进入虚拟空间的力能,目前功能还有一些问题需要改进:

  1. 进入房间后,用skyBox代替背景,会看不到门后的真实世界,考虑用shader去渲染门的内容
  2. 判断用户进入房间的方法比较粗糙

相关文章

  • 到底有多强?苹果的增强现实框架:ARKit

    相关 ARKit进阶:物理世界ARKit进阶:材质ARKit实战:如何实现任意门 写在前面 其实准备ARKit已经...

  • ARKit实战:如何实现任意门

    ARKit实战:如何实现任意门 相关 到底有多强?苹果的增强现实框架:ARKitARKit进阶:物理世界ARKit...

  • ARKit进阶:材质

    相关 到底有多强?苹果的增强现实框架:ARKitARKit进阶:物理世界ARKit实战:如何实现任意门 Scene...

  • ARKit进阶:物理世界

    相关 到底有多强?苹果的增强现实框架:ARKitARKit进阶:材质ARKit实战:如何实现任意门 写在前面 AR...

  • ARKit 学习礼记

    ARKit demo传送门 持续优化更新中... ARKit 简介 增强现实技术(Augmented Realit...

  • ARkit 实战教程(Xcode开发)

    ARkit 实战教程(Xcode开发) ARKit 最近在开发圈实在是火,ios 开发者可以快速的进行增强现实的开...

  • Golang 学习笔记十二 实例pool

    摘自Go语言实战第7章 本章会介绍pool包。这个包用于展示如何使用有缓冲的通道实现资源池,来管理可以在任意数量的...

  • 基于ARKit的iOS无限屏实现,还原锤子发布会效果

    基于ARKit的iOS无限屏实现,还原锤子发布会效果 基于ARKit的iOS无限屏实现,还原锤子发布会效果

  • 任意门

    我想,在那个高潮中眠去 爱,紧抱,两个人交换最后一口空气 濒临崩溃的人,平静的像石块击碎湖镜 我渴望朦胧而闪亮 像...

  • 任意门

    小时候,常常羡慕野比大雄有一个叫哆啦A梦的朋友,遇到困难的时候,不开心的时候,它总能拿出各种各样的道具帮大雄解决困...

网友评论

  • b95f0ca6ca78:厉害:+1:🏻。功能实现就很厉害了。一直想学习。
  • JACK_岩:厉害,自己研究的吗,有什么资料可以参考的?
    皮皮Warrior:主要是自学,看苹果和github上的demo,其实代码不难的

本文标题:ARKit实战:如何实现任意门

本文链接:https://www.haomeiwen.com/subject/aqpfextx.html