ARKit捕捉平面

首先創(chuàng)建項(xiàng)目

然后重新創(chuàng)建了一個(gè)Controller叫THARKitController(隨便取的)

下面開始導(dǎo)入ARKit庫

#import <ARKit/ARKit.h>

導(dǎo)入ARKit庫并不夠,還需要導(dǎo)入3D框架#import <SceneKit/SceneKit.h> 用來創(chuàng)建加載模型的對(duì)象

想要顯示AR效果需要3個(gè)對(duì)象

ARSCNView:用于展示3D效果的視圖

ARWorldTrackingConfiguration:(會(huì)話追蹤配置)的作用是跟蹤設(shè)備的方向和位置,以及檢測(cè)設(shè)備攝像頭看到的現(xiàn)實(shí)世界的表面。它的內(nèi)部實(shí)現(xiàn)了一系列非常龐大的算法計(jì)算以及調(diào)用了你的iPhone必要的傳感器來檢測(cè)手機(jī)的移動(dòng)及旋轉(zhuǎn)甚至是翻滾。我們無需關(guān)心內(nèi)部實(shí)現(xiàn),ARKit框架幫助我們封裝的非常完美,只需調(diào)用一兩個(gè)屬性即可。

SCNScene:用來加載3D模型的類,這里我使用它的節(jié)點(diǎn)(SCNNode)來加入視圖中

SCNNode:從創(chuàng)建的模型類中取得節(jié)點(diǎn),節(jié)點(diǎn)不是一個(gè),而是多個(gè)節(jié)點(diǎn)拼裝出來的,主要是能控制其大小和位置信息

1.創(chuàng)建ARSCNView

ARSCNView *arScnView = ?[[ARSCNView alloc] initWithFrame:self.view.bounds];?

arScnView.showsStatistics = YES;// 加載FPS等調(diào)試信息

arScnView.debugOptions = ARSCNDebugOptionShowWorldOrigin|ARSCNDebugOptionShowFeaturePoints;// 渲染 ARKit 報(bào)告的世界原點(diǎn)以及渲染 ARKit 檢測(cè)到的特征點(diǎn)

[self.view addSubview:arScnView];// 把AR視圖添加在viewController上

2.創(chuàng)建ARWorldTrackingConfiguration并啟動(dòng)AR會(huì)話

ARWorldTrackingConfiguration *arSessionConfiguration = ?[[ARWorldTrackingConfiguration alloc] init];?

arSessionConfiguration.planeDetection = ARPlaneDetectionHorizontal;// 設(shè)置追蹤方向(追蹤平面)

[arScnView.session runWithConfiguration:arSessionConfiguration];// 開啟AR會(huì)話(此時(shí)相機(jī)開始工作)

顯示AR開始工作了,但是我們想檢測(cè)平面,需要實(shí)現(xiàn)ARSCNView的代理方法

首先設(shè)置代理

arScnView.delegate = self;

然后實(shí)現(xiàn)代理方法

- (void)renderer:(id <SCNSceneRenderer>)renderer didAddNode:(SCNNode*)node forAnchor:(ARAnchor*)anchor;

當(dāng)設(shè)備捕捉到平面的時(shí)候就會(huì)調(diào)用該方法,其中anchor就是捕捉到的平面信息

我們創(chuàng)建網(wǎng)格平面來顯示檢測(cè)到的平面是什么樣的

首先用ARAnchor的子類來接收位置信息

ARPlaneAnchor*planeAnchor = (ARPlaneAnchor*)anchor;

然后創(chuàng)建一個(gè)平面并設(shè)置其大小為檢測(cè)出來的大小

SCNPlane*plane = [SCNPlane planeWithWidth:planeAnchor.extent.x height:planeAnchor.extent.z];

創(chuàng)建一個(gè)網(wǎng)格并賦值給這個(gè)平面

SCNMaterial*material = [[SCNMaterial alloc]init];

material.lightingModelName=SCNLightingModelPhysicallyBased;

material.diffuse.contents = ?[UIImageimageNamed:@"tron_grid"];

plane.materials= [NSMutableArray arrayWithObjects:material,nil];

創(chuàng)建一個(gè)基于3D物體模型的節(jié)點(diǎn),并把這個(gè)平面放上去

SCNNode*planeNode = [SCNNode nodeWithGeometry:plane];

設(shè)置節(jié)點(diǎn)的位置為捕捉到的平地的錨點(diǎn)的中心位置SceneKit框架中節(jié)點(diǎn)的位置position是一個(gè)基于3D坐標(biāo)系的矢量坐標(biāo)SCNVector3Make

planeNode.position=SCNVector3Make(planeAnchor.center.x,0, planeAnchor.center.z);

planeNode.transform=SCNMatrix4MakeRotation((-(float)M_PI/2.0),1.0,0.0,0.0);

把這個(gè)3D模型的節(jié)點(diǎn)放在映射到 anchor 的節(jié)點(diǎn)上

[node addChildNode:planeNode];

更新平面

我們添加一個(gè)全局屬性可變的字典,用于記錄我們添加的網(wǎng)格3D模型

[_plane ssetObject:planeNode forKey:anchor.identifier];

然后在代理方法

- (void)renderer:(id)renderer didUpdateNode:(SCNNode*)node forAnchor:(ARAnchor*)anchor;

中取出模型并更新大小個(gè)位置

SCNNode*plane = [_planes objectForKey:anchor.identifier];

if(plane ==nil) {

return;

}

修改大小

((SCNPlane*)plane.geometry).width= (float)planeAnchor.extent.x;

((SCNPlane*)plane.geometry).height= (float)planeAnchor.extent.z;

修改位置

plane.position=SCNVector3Make(planeAnchor.center.x,0, planeAnchor.center.z);

最后跑起來看看

最后貼上原文地址:http://www.cocoachina.com/ios/20170713/19856.html?utm_source=tuicool&utm_medium=referral

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容