ARkit 實(shí)戰(zhàn)教程(Xcode開發(fā))

ARkit 實(shí)戰(zhàn)教程(Xcode開發(fā))


ARKit 最近在開發(fā)圈實(shí)在是火,ios 開發(fā)者可以快速的進(jìn)行增強(qiáng)現(xiàn)實(shí)的開發(fā)省有,簡(jiǎn)化了許多步驟澜掩,之前了,我們AR醬也出了相應(yīng)的ARKit 系列教程芹敌,今天了算是ARKit 的實(shí)戰(zhàn)教程番外篇痊远,我們實(shí)現(xiàn)一些網(wǎng)上比較流行的一些AR功能。

ps:代碼地址:http://www.arparticles.com/portal.php?mod=view&aid=107

基礎(chǔ):現(xiàn)實(shí)模型

基礎(chǔ)效果演示:

打開Xcode氏捞,新建一個(gè)AR項(xiàng)目

這次我們用SceneKit 來渲染3D內(nèi)容碧聪。

進(jìn)入項(xiàng)目之后會(huì)有個(gè)smaple project,我們可以嘗試著運(yùn)行:

我們使用SceneKit繪制一個(gè)3D立方體液茎。SceneKit有幾個(gè)基本類逞姿,SCNScene是所有3D模型的容器辞嗡。要向場(chǎng)景添加內(nèi)容,你首先創(chuàng)建幾何滞造,幾何可以是復(fù)雜的形狀续室,或簡(jiǎn)單的像球體,多維數(shù)據(jù)集谒养,平面等挺狰。然后,將幾何模型放在在場(chǎng)景節(jié)點(diǎn)中买窟,并將其添加到場(chǎng)景中她渴。然后,SceneKit將遍歷場(chǎng)景圖并呈現(xiàn)內(nèi)容蔑祟。

- (void)viewDidLoad {

[super viewDidLoad];

SCNScene *scene = [SCNScene new];

SCNBox *boxGeometry = [SCNBox

boxWithWidth:0.1

height:0.1

length:0.1

chamferRadius:0.0];

SCNNode *boxNode = [SCNNode nodeWithGeometry:boxGeometry];

boxNode.position = SCNVector3Make(0, 0, -0.5);

[scene.rootNode addChildNode: boxNode];

self.sceneView.scene = scene;

}

ARKit和SceneKit的坐標(biāo)系如下所示:

當(dāng)ARSession啟動(dòng)時(shí)趁耗,計(jì)算出的相機(jī)位置最初設(shè)置為X = 0,Y = 0疆虚,Z = 0苛败。

們可以看到立方體的兩面,我們可以稍后添加一些更高級(jí)的照明径簿,但現(xiàn)在我們可以在SCNScene實(shí)例上設(shè)置autoenablesDefaultLighting :

self.sceneView.autoenablesDefaultLighting = YES;

進(jìn)階:平面檢測(cè)+可視化

效果演示:

在我們開始之前罢屈,將一些調(diào)試信息添加到程序中,即渲染ARKit檢測(cè)到的功能點(diǎn)篇亭,我們可以打開我們的ARSCNView:

self.sceneView.debugOptions =

ARSCNDebugOptionShowWorldOrigin |

ARSCNDebugOptionShowFeaturePoints;

我們來檢測(cè)平面幾何缠捌,在ARKit中,可以通過設(shè)置planeDetection屬性來檢測(cè)水平平面译蒂。此值可以設(shè)置為ARPlaneDetectionHorizontal或ARPlaneDetectionNone曼月。

- (void)renderer:(id )renderer

didAddNode:(SCNNode *)node

forAnchor:(ARAnchor *)anchor {

SCNNode實(shí)例是ARKit創(chuàng)建的一個(gè)SceneKit節(jié)點(diǎn),它具有一些類似于方向和位置的屬性柔昼,然后我們獲得一個(gè)錨實(shí)例哑芹,這將告訴我們使用已找到的特定錨點(diǎn)的更多信息,如大小和中心位置的plane捕透。錨實(shí)例實(shí)際上是一個(gè)ARPlaneAnchor類型聪姿,比如我們可以得到plane的范圍和中心信息。

我們進(jìn)行渲染plane乙嘀,可以在虛擬世界中繪制一個(gè)SceneKit 3D平面末购。為此,我們創(chuàng)建一個(gè)繼承自SCNNode的Plane類虎谢。在構(gòu)造方法中盟榴,我們創(chuàng)建平面并相應(yīng)地調(diào)整它的大小:

self.planeGeometry = [SCNPlane planeWithWidth:anchor.extent.x height:anchor.extent.z];

SCNNode *planeNode = [SCNNode nodeWithGeometry:self.planeGeometry];

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

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

[self addChildNode:planeNode];

現(xiàn)在我們有我們的Plane類嘉冒,回到ARSCNViewDelegate回調(diào)方法中曹货,當(dāng)ARKit找到一個(gè)新的錨點(diǎn)時(shí)咆繁,我們可以創(chuàng)建我們的新plane:

if (![anchor isKindOfClass:[ARPlaneAnchor class]]) {

return;

Plane *plane = [[Plane alloc] initWithAnchor: (ARPlaneAnchor *)anchor];

[node addChildNode:plane];

更新Plane SceneKit,使得我們?cè)谝苿?dòng)時(shí)有更穩(wěn)定的效果顶籽。

didUpdateNode:(SCNNode *)node

// See if this is a plane we are currently rendering

Plane *plane = [self.planes objectForKey:anchor.identifier];

if (plane == nil) {

[plane update:(ARPlaneAnchor *)anchor];

更新plane的寬度和高度玩般。

- (void)update:(ARPlaneAnchor *)anchor {

self.planeGeometry.width = anchor.extent.x;

self.planeGeometry.height = anchor.extent.z;

self.position = SCNVector3Make(anchor.center.x, 0, anchor.center.z);

運(yùn)行,會(huì)發(fā)現(xiàn)如下一些效果礼饱。

添加物理效果

效果預(yù)覽:

在這個(gè)演示中坏为,當(dāng)用戶在屏幕上單擊時(shí),我們執(zhí)行一段代碼镊绪,這個(gè)代碼很簡(jiǎn)單匀伏,ARSCNView包含一個(gè)hitTest方法,可以通過獲得的屏幕坐標(biāo)點(diǎn)蝴韭,從相機(jī)中心通過該點(diǎn)投射一條射線够颠,并返回結(jié)果:

- (void)handleTapFrom: (UITapGestureRecognizer *)recognizer {

CGPoint tapPoint = [recognizer locationInView:self.sceneView];

NSArray *result = [self.sceneView hitTest:tapPoint types:ARHitTestResultTypeExistingPlaneUsingExtent];

if (result.count == 0) {

ARHitTestResult * hitResult = [result firstObject];

[self insertGeometry:hitResult];

通過上述代碼,我們可以得到射線與平面交叉點(diǎn)的世界坐標(biāo)榄鉴,并在該位置放置一些3D模型等等履磨。

- (void)insertGeometry:(ARHitTestResult *)hitResult {

float dimension = 0.1;

SCNBox *cube = [SCNBox boxWithWidth:dimension

height:dimension

length:dimension

chamferRadius:0];

SCNNode *node = [SCNNode nodeWithGeometry:cube];

node.physicsBody = [SCNPhysicsBody

bodyWithType:SCNPhysicsBodyTypeDynamic

shape:nil];

node.physicsBody.mass = 2.0;

node.physicsBody.categoryBitMask = CollisionCategoryCube;

float insertionYOffset = 0.5;

node.position = SCNVector3Make(

hitResult.worldTransform.columns[3].x,

hitResult.worldTransform.columns[3].y + insertionYOffset,

hitResult.worldTransform.columns[3].z

);

[self.sceneView.scene.rootNode addChildNode:node];

[self.boxes addObject:node];

我們給每個(gè)立方體一個(gè)physicsBody,它是SceneKit的物理引擎庆尘。

接下來剃诅,我們實(shí)現(xiàn)停止平面檢測(cè)的功能。用戶用兩個(gè)手指按住屏幕1秒鐘驶忌,那么我們會(huì)隱藏所有的平面并關(guān)閉平面檢測(cè)矛辕。

ARWorldTrackingSessionConfiguration *configuration = (ARWorldTrackingSessionConfiguration *)self.sceneView.session.configuration;

configuration.planeDetection = ARPlaneDetectionNone;

[self.sceneView.session runWithConfiguration:configuration];

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市付魔,隨后出現(xiàn)的幾起案子聊品,更是在濱河造成了極大的恐慌,老刑警劉巖抒抬,帶你破解...
    沈念sama閱讀 221,406評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杨刨,死亡現(xiàn)場(chǎng)離奇詭異晤柄,居然都是意外死亡擦剑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門芥颈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惠勒,“玉大人,你說我怎么就攤上這事爬坑【牢荩” “怎么了?”我有些...
    開封第一講書人閱讀 167,815評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵盾计,是天一觀的道長(zhǎng)售担。 經(jīng)常有香客問我赁遗,道長(zhǎng),這世上最難降的妖魔是什么族铆? 我笑而不...
    開封第一講書人閱讀 59,537評(píng)論 1 296
  • 正文 為了忘掉前任岩四,我火速辦了婚禮,結(jié)果婚禮上哥攘,老公的妹妹穿的比我還像新娘剖煌。我一直安慰自己,他們只是感情好逝淹,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評(píng)論 6 397
  • 文/花漫 我一把揭開白布耕姊。 她就那樣靜靜地躺著,像睡著了一般栅葡。 火紅的嫁衣襯著肌膚如雪茉兰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,184評(píng)論 1 308
  • 那天欣簇,我揣著相機(jī)與錄音邦邦,去河邊找鬼。 笑死醉蚁,一個(gè)胖子當(dāng)著我的面吹牛燃辖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播网棍,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼黔龟,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了滥玷?” 一聲冷哼從身側(cè)響起氏身,我...
    開封第一講書人閱讀 39,668評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惑畴,沒想到半個(gè)月后蛋欣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,212評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡如贷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評(píng)論 3 340
  • 正文 我和宋清朗相戀三年陷虎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杠袱。...
    茶點(diǎn)故事閱讀 40,438評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尚猿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出楣富,到底是詐尸還是另有隱情凿掂,我是刑警寧澤,帶...
    沈念sama閱讀 36,128評(píng)論 5 349
  • 正文 年R本政府宣布纹蝴,位于F島的核電站庄萎,受9級(jí)特大地震影響踪少,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜糠涛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評(píng)論 3 333
  • 文/蒙蒙 一秉馏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脱羡,春花似錦萝究、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至脓规,卻和暖如春栽连,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背侨舆。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工秒紧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人挨下。 一個(gè)月前我還...
    沈念sama閱讀 48,827評(píng)論 3 376
  • 正文 我出身青樓熔恢,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親臭笆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子叙淌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容