二、SCNGeometry代碼創建幾何體

感謝小伙伴的到來~~~

(一)前言

上章對ARKit進行了一個簡單介紹

一、ARKit初探索

沒有看過的小伙伴可以點擊了解一下。

本章我會來帶大家了解一下SCNGeometry使用頂點信息創建幾何體

(二) SCNGeometry

1、介紹

在SceneKit中,附加到SCNNode對象的幾何形狀形成場景的可見元素,并且SCNMaterial連接到幾何的對象決定其外觀。

2、創建方法

描述 了解更多
從使用外部3D創作工具創建的場景文件加載 SCNScene、SCNSceneSource
使用和自定義SceneKit的內置原始形狀 SCNPlane、SCNBox、SCNSphere、SCNPyramid、SCNCone、SCNCylinder、SCNCapsule、SCNTube和SCNTorus
從2D文本或Bézier曲線創建3D幾何 SCNText、SCNShape
從頂點數據創建自定義幾何 SCNGeometrySource、 SCNGeometryElement、init(sources:elements:)或是管理形狀數據

本章主要是用 init(sources:elements:)的方法來創建自定義幾何體

3、SCNGeometry init(sources:elements:)

本章我主要使用頂點來創建幾何體。法線和紋理映射坐標將在下章介紹

參數說明

sources 描述幾何及其屬性中的頂點的SCNGeometrySource對象數組。

elements 描述如何連接幾何的頂點的SCNGeometryElement對象數組。

幾何的可見內容來自幾何源的組合,其中包含描述其頂點的數據、幾何元素、描述頂點如何連接以形成曲面的數據。

每個SCNGeometrySource對象描述由源的屬性識別的幾何中的所有頂點的屬性(頂點位置,表面法線矢量,顏色或紋理映射坐標)semantic。要創建自定義幾何,您必須提供至少一個源,用于vertex。通常,您還提供用于照明和陰影的法線和紋理坐標的來源。

頂點,正常和顏色語義的來源必須是唯一的 - 如果sources數組中的多個對象具有相同的語義,則SceneKit僅使用第一個。幾何可能有多個texcoord來源-sources陣列中的紋理坐標源的順序決定了在附加材料時用于屬性的值mappingChannel

每個SCNGeometryElement對象描述幾何源的頂點如何組合成多邊形以創建幾何體的形狀。創建自定義幾何需要至少一個元素。如果數組包含多個elements對象,則它們的順序決定了幾何圖形材料的排列方式有關詳細信息,請參閱materials

4、使用頂點坐標創建線、面和幾何體

(1)線
let indices: [UInt8] = [0, 1]//需要特別注意 [UInt8]可以使用UInt8、UInt16、UInt32,不能使用UInt64,否則什么幾何圖像都繪制不出來,具體原因還在查看
我這里索引都不會很大所以使用的UInt8,請注意變量最大取值范圍
//使用SCNVector3創建頂點索引
let geometrySources = SCNGeometrySource(vertices: [
            SCNVector3(x: 0.1, y: 0.0, z: -0.1),
            SCNVector3(x: 0.1, y: 0.1, z: -0.1),
            ])

//indices:一組索引值,每個索引值都標識幾何源中的一個頂點(連接頂點的順序)
//primitiveType:渲染幾何元素時連接頂點的繪圖方式(SCNGeometryPrimitiveType)
/*
SCNGeometryPrimitiveType:
case triangles
幾何元素的數據是一系列三角形,每個三角形由三個新的頂點描述。
case triangleStrip
幾何元素的數據是一系列三角形,每個三角形由一個新頂點和前三角形的兩個頂點描述。
case line
幾何元素的數據是一系列線段,每個線段由兩個新頂點描述。
case point
幾何元素的數據是一系列未連接的點。
*/
let indices: [UInt8] = [0, 1]
let geometryElement = SCNGeometryElement(indices: indices, primitiveType: .line)

//根據頂點和索引數據 創建幾何形狀
let geometry = SCNGeometry(sources: [geometrySources], elements: [geometryElement])
(2)繪制平面

在介紹代碼之間我們先了解一下關于圖形的一些基本知識

在3D空間中繪制的大部分內容都包含大量三角形,他是具有表面的最小形狀。三點形成一個表面,我們可以用四點形成一個矩形實際上只是兩個三角形。

每個表面都有前面和后面,"前面以逆時針方向指定"。SCNMaterial渲染器默認只渲染前面(isDoubleSided屬性默認NO),這是一個常見的優化,因為后面很多時候是被幾何體中的其他表面遮蔽。

①繪制三角形
逆時針索引頂點
注意:頂點個數n至少要大于3,否則不能繪制任何三角形。
let geometrySources = SCNGeometrySource(vertices: [
            SCNVector3(x:  0.1, y: 0.0, z: -0.1),
            SCNVector3(x:  0.1, y: 0.1, z: -0.1),
            SCNVector3(x: -0.1, y: 0.0, z: -0.1),
            ])
        
let indices: [UInt8] = [0, 1, 2]
        
let geometryElement = SCNGeometryElement(indices: indices, primitiveType: .triangles)
        
let geometry = SCNGeometry(sources: [geometrySources], elements: [geometryElement])

運行代碼會看到一個面向我們的三角形,而從三角形的背面看是透明的

②繪制長方形

我們將使用三角形兩種不同的頂點索引方式來分別拼合一個長方形

case triangles 幾何元素的數據是一系列三角形,每個三角形由三個新的頂點描述。

case triangleStrip
幾何元素的數據是一系列三角形,每個三角形由一個新頂點和前三角形的兩個頂點描述。

A、triangles

以每三個頂點繪制一個三角形。如果頂點的個數n不是3的倍數,那么最后的1個或者2個頂點會被忽略。

let geometrySources = SCNGeometrySource(vertices: [
            SCNVector3(x:  0.1, y: 0.0, z: -0.1),
            SCNVector3(x:  0.1, y: 0.1, z: -0.1),
            SCNVector3(x: -0.1, y: 0.0, z: -0.1),
            SCNVector3(x: -0.1, y: 0.1, z: -0.1),
            ])
//正面向前,逆時針索引每個三角形,三個一組
//0->1->2   2->1->3
let indices: [UInt8] = [0, 1, 2,
                        2, 1, 3]
        
let geometryElement = SCNGeometryElement(indices: indices, primitiveType: .triangles)
        
let geometry = SCNGeometry(sources: [geometrySources], elements: [geometryElement])
A、triangleStrip

構建當前三角形的頂點的連接順序依賴于要和前面已經出現過的2個頂點組成三角形
一般用在"三角帶"上,三角帶是一個三角形列表,其中每個三角形都與前一個三角形共享一邊。下圖顯示了一個三角帶

下圖中,注意到,頂點順序在順時針和逆時針間不斷變換。

三角帶

let geometrySources = SCNGeometrySource(vertices: [
            SCNVector3(x:  0.1, y: 0.0, z: -0.1),
            SCNVector3(x:  0.1, y: 0.1, z: -0.1),
            SCNVector3(x: -0.1, y: 0.0, z: -0.1),
            SCNVector3(x: -0.1, y: 0.1, z: -0.1),
            SCNVector3(x: -0.1, y: 0.0, z: 0.0),
            SCNVector3(x: -0.1, y: 0.1, z: 0.0),
            ])

//0->1->2(逆) 1->2->3(順) 2->3->4(逆) 3->4->5(順)
let indices: [UInt8] = [0, 1, 2,  3,  4,  5]
        
let geometryElement = SCNGeometryElement(indices: indices, primitiveType: .triangleStrip)
        
let geometry = SCNGeometry(sources: [geometrySources], elements: [geometryElement])
結構圖
效果圖

)

(3) 繪制幾何體

繪制立方體其實就是兩個三角形拼接成一個方形面,六個正方形面拼接成閉合的立方體。需要注意的是立方體每個面的正反面。

代碼已經上傳其中已經打好注釋在這里不做過多解釋了: github

曲線

曲面

(三)創建SCN文件 拖拽模型

最后簡單的給大家截圖看一下創建SCN文件拖裝一些模型,然后用SCNScene(named:)加載模型文件


添加
添加模型

本章內容就到這里感謝小伙伴們的到來~
下章我將給大家介紹SCNGeometry曲面的繪制、法線以及紋理映射坐標的內容。我會盡量加快更新速度~~~
代碼已經上傳github

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容