首先創(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