iOS 3D 之 SceneKit框架Demo分析

Scene Kit 是Apple 向 OS X 開發者們提供的 Cocoa 下的 3D 渲染框架。  node

Scene Kit 創建在 OpenGL 的基礎上,包含了如光照、模型、材質、攝像機等高級引擎特性,這些組件都是面向對象的,你能夠用熟悉的 Objective-C 或 Swift 語言來編寫代碼。假如你用過 OpenGL 最先的版本,那時尚未 shader,只能苦逼的使用各類底層受限制的 API 開發。而 Scene Kit 就行了不少,對於大多數需求 (甚至像動態陰影等高級特性),使用它提供的上層 API 來配置,就已經足夠了。xcode

建立一個項目:app

 

 

 

在demo中比通常的文件多了一個scnasssets文件夾,這個是存放3d模型的文件夾,打開能夠看到.scn後綴的文件,這個就是xcode識別的模型文件後綴的一種框架

 

 

    // create a new scene
    //建立一個場景scene
    SCNScene *scene = [SCNScene sceneNamed:@"art.scnassets/ship.scn"];
    
    //實例化SCNcene,場景自己並不可見,須要添加在SceneView的場景上
    //建立並添加一個相冊到scene
    //這段代碼是用來建立並配置攝像機。攝像機處於的位置即視角所看的位置。  注意這裏建立攝像機是建立了一個SCNNode,賦值了node的屬性。這裏須要瞭解一下node的做用。在SceneKit中,node即節點是很是關鍵的部分。node自己一樣是不可見的,它的做用是節點化各個部件。好比一輛車,車身和方向盤都是模型,能夠把方向盤的node添加在車身模型的node上,這樣在車移動的時候,車模型的子node也會一塊兒移動。車身各部件之間的相對位置是不變的。這樣能夠大大節省工做量。在渲染場景的時候,sceneKit會遍歷全部的子node,cameraNode設置了屬性camera,並把本身添加在了scene的rootNode上纔會在scene顯示的時候起做用
    
    // create and add a camera to the scene
    SCNNode *cameraNode = [SCNNode node];
    cameraNode.camera = [SCNCamera camera];
    [scene.rootNode addChildNode:cameraNode];
    
    //設置camera
    // place the camera
    cameraNode.position = SCNVector3Make(0, 0, 15);
    
    //代碼用來建立並配置燈光效果。在3d成像中,燈光是很重要的一個環節。燈光和陰影可讓物體更有質感。light的type有四種,你們能夠嘗試。
    //建立light到scene
    // create and add a light to the scene
    SCNNode *lightNode = [SCNNode node];
    lightNode.light = [SCNLight light];
    lightNode.light.type = SCNLightTypeOmni;
    lightNode.position = SCNVector3Make(0, 10, 10);
    [scene.rootNode addChildNode:lightNode];
    
    
    // create and add an ambient light to the scene
    SCNNode *ambientLightNode = [SCNNode node];
    ambientLightNode.light = [SCNLight light];
    ambientLightNode.light.type = SCNLightTypeAmbient;
    ambientLightNode.light.color = [UIColor darkGrayColor];
    [scene.rootNode addChildNode:ambientLightNode];
    
    
    //獲得飛機模型。注意這個方法recursively:(BOOL)的意思爲是否在子node中查詢。node是樹形結構,會返回第一個遇到的@「ship」node。
    // retrieve the ship node
    SCNNode *ship = [scene.rootNode childNodeWithName:@"ship" recursively:YES];
    
    
    //讓飛機繞y軸飛行。這裏的動畫是SCNAction,封裝性和使用方法與UIVIew的二維動畫相似,至關便捷。
    // animate the 3d object
    [ship runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
    
    //獲得用於展現的SCNView,並配置scnView的scene。
    // retrieve the SCNView
    SCNView *scnView = (SCNView *)self.view;
    
    // set the scene to the view
    scnView.scene = scene;
    
    
    //設置容許用戶控制攝像機,顯示狀態,(fps等)通常是在開發中用做調試的
    
    // allows the user to manipulate the camera
    scnView.allowsCameraControl = YES;
        
    // show statistics such as fps and timing information
    scnView.showsStatistics = YES;
    
    // configure the view
    scnView.backgroundColor = [UIColor blackColor];
    
    //添加手勢
    // add a tap gesture recognizer
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    NSMutableArray *gestureRecognizers = [NSMutableArray array];
    [gestureRecognizers addObject:tapGesture];
    [gestureRecognizers addObjectsFromArray:scnView.gestureRecognizers];
    scnView.gestureRecognizers = gestureRecognizers;
    //這就是官方demo的基本內容。實現了一個模型的顯示和動畫。告訴了咱們模型想變爲可見,須要攝像機模擬視角,燈光和周圍燈光展現,添加在根node中。

 

- (void) handleTap:(UIGestureRecognizer*)gestureRecognize
{
    //去到SCNView
    // retrieve the SCNView
    SCNView *scnView = (SCNView *)self.view;
    
    //找到對應的node
    // check what nodes are tapped
    CGPoint p = [gestureRecognize locationInView:scnView];
    NSArray *hitResults = [scnView hitTest:p options:nil];
    
    // check that we clicked on at least one object
    if([hitResults count] > 0){
        // retrieved the first clicked object
        SCNHitTestResult *result = [hitResults objectAtIndex:0];
        
        // get its material
        SCNMaterial *material = result.node.geometry.firstMaterial;
        
        // highlight it
        [SCNTransaction begin];
        [SCNTransaction setAnimationDuration:0.5];
        
        // on completion - unhighlight
        [SCNTransaction setCompletionBlock:^{
            [SCNTransaction begin];
            [SCNTransaction setAnimationDuration:0.5];
            
            material.emission.contents = [UIColor blackColor];
            
            [SCNTransaction commit];
        }];
        
        material.emission.contents = [UIColor redColor];
        
        [SCNTransaction commit];
    }
}
相關文章
相關標籤/搜索