美文网首页iOS AR入门
ARKit太阳系图谱

ARKit太阳系图谱

作者: 高阿呆 | 来源:发表于2018-01-22 19:13 被阅读59次

先看一下效果,太阳自转,地球绕着太阳转,月球绕着地球转,在项目开始时一定要在plist文件中添加对系统相机访问键值对,否则会崩溃


WechatIMG1.png

下面直接上代码.(OC)
/// 创建sceneView
@property (nonatomic, strong) ARSCNView *arSCNView;
/// 创建会话
@property (nonatomic, strong) ARSession *arSession;
/// 创建追踪(摄像头位置改变之后可以进行位置追踪)
@property (nonatomic, strong) ARConfiguration *arConfiguration;
/// 创建太阳节点
@property (nonatomic, strong) SCNNode *sunNode;
/// 创建地球节点
@property (nonatomic, strong) SCNNode *earthNode;
/// 创建月亮节点
@property (nonatomic, strong) SCNNode *moonNode;
/// 创建地月节点
@property (nonatomic, strong) SCNNode *earthGroupNode;

  1. // 添加ARSCNView到View上(不要忘记懒加载创建arSCNView)
  • (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.arSCNView];
    }

  • (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // 创建追踪,因ARConfiguration是个基类不能直接初始化,所以要用他的子类
    /*
    API文档已经给出提示
    ARConfiguration is an abstract class; you do not create or work with instances of this class.
    To run an AR session, create an instance of the concrete
    */
    ARWorldTrackingConfiguration *trackingCongiguration = [[ARWorldTrackingConfiguration alloc] init];
    self.arConfiguration = trackingCongiguration;
    // 自适应灯光,(室内到室外,画面比较柔和)
    self.arConfiguration.lightEstimationEnabled = YES;
    // 加载配置
    [self.arSession runWithConfiguration:self.arConfiguration];
    }

2.运行程序就可以看到如下空白画面


WechatIMG2.jpeg

pragma mark ========== 初始化节点 ==========

  • (void)initNode {
    self.sunNode = [[SCNNode alloc] init];
    self.earthNode = [[SCNNode alloc] init];
    self.moonNode = [[SCNNode alloc] init];
    self.earthGroupNode = [SCNNode node];

    self.sunNode.geometry = [SCNSphere sphereWithRadius:3.0];
    self.earthNode.geometry = [SCNSphere sphereWithRadius:1.0];
    self.moonNode.geometry = [SCNSphere sphereWithRadius:0.5];

    self.sunNode.geometry.firstMaterial.multiply.contents = @"sun.jpg";
    self.sunNode.geometry.firstMaterial.diffuse.contents = @"sun.jpg";
    // 强度
    self.sunNode.geometry.firstMaterial.multiply.intensity = 0.5;
    // 光照不变
    self.sunNode.geometry.firstMaterial.lightingModelName = SCNLightingModelConstant;
    // diffuse 扩散到 contents 全局
    self.earthNode.geometry.firstMaterial.diffuse.contents = @"earth-diffuse-mini.jpg";
    // emission 光、热等的)发射,散发;喷射;发行
    self.earthNode.geometry.firstMaterial.emission.contents = @"earth-emissive-mini.jpg";
    // specular 镜子的;会反射的;镜子一般的
    self.earthNode.geometry.firstMaterial.specular.contents = @"earth-specular-mini.jpg";
    // 光泽
    self.earthNode.geometry.firstMaterial.shininess = 0.1;
    // 反射多少光出去
    self.earthNode.geometry.firstMaterial.specular.intensity = 0.5;

    self.moonNode.geometry.firstMaterial.diffuse.contents = @"moon.jpg";

    // 重复渲染(可以试一下不添加这几句代码看下效果)从上到下,从左到右重复渲染
    /*
    SCNWrapMode是个枚举值有时间大家试一下,看一下效果

    SCNWrapModeClamp
    SCNWrapModeRepeat
    SCNWrapModeClampToBorder
    SCNWrapModeMirror
    */

    self.sunNode.geometry.firstMaterial.multiply.wrapS =
    self.sunNode.geometry.firstMaterial.diffuse.wrapS =
    self.sunNode.geometry.firstMaterial.multiply.wrapT =
    self.sunNode.geometry.firstMaterial.diffuse.wrapT = SCNWrapModeRepeat;

    // 确定节点位置
    self.sunNode.position = SCNVector3Make(0, 5, -30);
    self.earthNode.position = SCNVector3Make(0, 0, 0);
    self.moonNode.position = SCNVector3Make(2, 0, 0);
    self.earthGroupNode.position = SCNVector3Make(8, 0, 0);

    // 添加节点
    [self.arSCNView.scene.rootNode addChildNode:self.sunNode];

    [self.earthGroupNode addChildNode:self.earthNode];
    [self addSunNodeAnimation];
    [self rotationNode];
    }

pragma mark ========== 添加动画 ==========

// 太阳自转

  • (void)addSunNodeAnimation {
    CABasicAnimation *sunBasicAnimation = [CABasicAnimation animationWithKeyPath:@"contentsTransform"];
    // 转一次的时间
    sunBasicAnimation.duration = 10.0;
    // 重复次数
    sunBasicAnimation.repeatCount = FLT_MAX;
    sunBasicAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DConcat(CATransform3DMakeTranslation(0, 0, 0), CATransform3DMakeScale(1, 1, 1))];
    sunBasicAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DConcat(CATransform3DMakeTranslation(0, 0, 0), CATransform3DMakeScale(3, 3, 3))];
    [self.sunNode.geometry.firstMaterial.diffuse addAnimation:sunBasicAnimation forKey:@"sun animation"];
    }

// 公转

  • (void)rotationNode {
    [self.earthNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:1 z:0 duration:1]]];

    SCNNode *moonRotationNode = [SCNNode node];
    [moonRotationNode addChildNode:self.moonNode];

    CABasicAnimation *moonBasicAnimation = [CABasicAnimation animationWithKeyPath:@"rotation"];
    moonBasicAnimation.duration = 1.5;
    moonBasicAnimation.repeatCount = FLT_MAX;
    moonBasicAnimation.toValue = [NSValue valueWithSCNVector4:SCNVector4Make(0, 1, 0, M_PI * 2)];
    [self.moonNode addAnimation:moonBasicAnimation forKey:@"moon rotation"];

    CABasicAnimation *moonRotationAnimation = [CABasicAnimation animationWithKeyPath:@"rotation"];
    moonRotationAnimation.duration = 1;
    moonRotationAnimation.repeatCount = FLT_MAX;
    moonRotationAnimation.toValue = [NSValue valueWithSCNVector4:SCNVector4Make(0, 1, 0, M_PI * 2)];
    [moonRotationNode addAnimation:moonRotationAnimation forKey:@"moon rotation"];

    [self.earthGroupNode addChildNode:moonRotationNode];

    // 地球绕着太阳转
    SCNNode *earthSunRotationNode = [SCNNode node];
    [self.sunNode addChildNode:earthSunRotationNode];
    [earthSunRotationNode addChildNode:_earthGroupNode];

    // 月亮绕着地球转
    moonBasicAnimation = [CABasicAnimation animationWithKeyPath:@"rotation"];
    moonBasicAnimation.duration = 5;
    moonBasicAnimation.repeatCount = FLT_MAX;
    moonBasicAnimation.toValue = [NSValue valueWithSCNVector4:SCNVector4Make(0, 1, 0, M_PI * 2)];
    [earthSunRotationNode addAnimation:moonBasicAnimation forKey:@"earth rotation around sun"];
    }

pragma mark ========== 懒加载 ==========

  • (ARSCNView *)arSCNView {
    if (!_arSCNView) {
    _arSCNView = [[ARSCNView alloc] initWithFrame:self.view.bounds];
    _arSCNView.delegate = self;
    _arSCNView.session = self.arSession;
    // 灯光自适应
    _arSCNView.automaticallyUpdatesLighting = YES;

      [self initNode];
    

    }
    return _arSCNView;
    }

  • (ARSession *)arSession {
    if (!_arSession) {
    _arSession = [[ARSession alloc] init];
    }
    return _arSession;
    }

// 运行一下,看一下效果.是不是很炫.大家可以尝试着做一个七大行星的图谱.

相关文章

  • ARKit太阳系图谱

    先看一下效果,太阳自转,地球绕着太阳转,月球绕着地球转,在项目开始时一定要在plist文件中添加对系统相机访问键值...

  • 自己看的github

    1.ARKit 太阳系 2.仿网易新闻

  • ARkit连载二之太阳系

    在上一节中简单介绍ARKit及其所依赖的SceneKit,但是还有好多API中的东西没有介绍,详情可查看http:...

  • ARKit如何将太阳系装进iPhone(一)

    转载请注明原作者 第二篇文章链接:如何用ARKit把太阳系装在你的iPhone中(二) 关注AR/VR也有一段...

  • 8月iOS Library Top5 ---2017.08

    1.ARKit-CoreLacation ARKit-CoreLacation将ARKit和CoreLocatio...

  • ARKit Work Shop Demo

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

  • ARKit -- 基础概念

    参考内容 直击苹果 ARKit 技术 到底有多强?苹果的增强现实框架:ARKit ARKit文档翻译之ARKit简介

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

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

  • 苹果 ARKit 初探

    苹果 ARKit 初探 苹果 ARKit 初探

  • ARKit入门

    分享收藏关于ARKit的文章集 适合新手入门学习ARKit从入门到精通(1)-ARKit初体验ARKit从入门到精...

网友评论

    本文标题:ARKit太阳系图谱

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