我不知道怎么切入這個ARKit的主題,也不想胡亂吹一套,AR是一個什么技術(shù),反正我明白一件事情,那就是Apple 做AR最牛逼的公司給收購了! 他為啥收購? 好了 不BB了,本人對AR也比較感興趣。!通過學(xué)習(xí),Apple 官方的IPA,結(jié)合大牛的博客。(其中過程還是比較痛苦的。)
一:首先建議下。。
ARKit不能理解,如果你是純做iOS的這個正常。
但是還有一個SceneKit,這個就有點!你懂的。!還有我有點基礎(chǔ),一路看過來都可以理解,但是關(guān)于換算這塊。!還是很多不懂的,后續(xù)會繼續(xù)學(xué)習(xí)!
二:先說個他是怎么樣在iOS上運行AR的。!
首先要A9 的芯片,就是說要6S以上的手機。。!才能運行。。!我拿的是7pulse。
ARKit重要包含的class
ARSession 他負(fù)責(zé)調(diào)接顯示,和數(shù)據(jù)的傳輸(他是中介)
在iOS框架中,凡是帶session或者context后綴的,這種類一般自己不干活,作用一般都是兩個:1.管理其他類,幫助他們搭建溝通橋梁,好處就是解耦 2.負(fù)責(zé)幫助我們管理復(fù)雜環(huán)境下的內(nèi)存
context與session不同之處是:一般與硬件打交道,例如攝像頭捕捉ARSession,網(wǎng)卡的調(diào)用NSURLSession等使用的都是session后綴。沒有硬件參與,一般用context,如繪圖上下文,自定義轉(zhuǎn)場上下文等
1.你對象提供接收視頻圖像捕獲和跟蹤信息,或?qū)挔顟B(tài)的變化,代理是捕獲視頻流的。。(方法可以實現(xiàn)接收視頻幀圖像捕獲和跟蹤狀態(tài)的AR會話。) var
self.arsession.delegate = self;
2.暫停 func
[self.arsession pause];
3.支持多線程的 var
self.arsession.delegateQueue ;
4.翻譯為當(dāng)前幀,我對這個ARframe還不是很了解 先不做回答。。?。??? var
ARFrame *frame = self.arsession.currentFrame;
5.這個函數(shù)還真不知道什么意思。 。
[self.arsession runWithConfiguration:self.arsessionconfiguration options:(nil)];
6.運行追蹤者! func
[self.arsession runWithConfiguration:self.arsessionconfiguration];
7.增加刪除錨點,func
ARAnchor *ar = [[ARAnchor alloc]initWithTransform:matrix_sub];
[self.arsession addAnchor:ar ];
[self.arsession removeAnchor:ar];
重點需要理解的。。!
?ARSession搭建溝通橋梁的參與者主要有兩個ARWorldTrackingSessionConfiguration與ARFrame
*/
與他配合的是ARSessionConfiguration 這個追蹤類,功能是非常強大的。。!
RWorldTrackingSessionConfiguration(會話追蹤配置)的作用是跟蹤設(shè)備的方向和位置,以及檢測設(shè)備攝像頭看到的現(xiàn)實世界的表面。它的內(nèi)部實現(xiàn)了一系列非常龐大的算法計算以及調(diào)用了你的iPhone必要的傳感器來檢測手機的移動及旋轉(zhuǎn)甚至是翻滾
該類只支持A9芯片之后的機型,也就是iPhone6s之后的機型
當(dāng)ARWorldTrackingSessionConfiguration計算出相機在3D世界中的位置時,它本身并不持有這個位置數(shù)據(jù),而是將其計算出的位置數(shù)據(jù)交給ARSession去管理(與前面說的session管理內(nèi)存相呼應(yīng)),而相機的位置數(shù)據(jù)對應(yīng)的類就是ARFrame
--ARSessionConfiguration--父類
ARSessionConfiguration *arsessionconfiguration = [[ARSessionConfiguration alloc]init];
1.是否支持A9芯片 ,AR
@property(class, nonatomic, readonly) BOOL isSupported;
//這是一個類方法
BOOL b = ARSessionConfiguration.isSupported;
2.會話的對其方式,這里的對其指的是3D世界的坐標(biāo)。
arsessionconfiguration.worldAlignment = ARWorldAlignmentGravity;
num : ARWorldAlignmentGravity 相機位置 vector (0, -1, 0)
ARWorldAlignmentGravityAndHeading 相機位置及方向. vector (0, -1, 0)
ARWorldAlignmentCamera 相機方向
3.是否需要燈光
arsessionconfiguration.lightEstimationEnabled = YES;
--ARWorldTrackingSessionConfiguration--
只有兩個選項,第一個不偵查!第二個偵查地形。!
self.arsessionconfiguration.planeDetection = 1;
/
以上基本上搭建好了,ARKit這邊了,!但是還有;
但是要使用的話還得會幾個工具類!
/
ARFrame
ARFrame *frame = [ARFrame alloc];
ARFrame主要是追蹤相機當(dāng)前的狀態(tài),這個狀態(tài)不僅僅只是位置,還有圖像幀及時間等參數(shù)
1.時間戳.
float time = frame.timestamp;
2.緩沖區(qū)圖像幀
CVPixelBufferRef ref = frame.capturedImage;
3.相機(表示這個ARFrame是哪一個相機的,iPhone7plus有兩個攝像機)
ARCamera *camera = frame.camera;
4. 返回當(dāng)前相機捕捉到的錨點數(shù)據(jù)(當(dāng)一個3D虛擬模型加入到ARKit中時,錨點值得就是這個模型在AR中的位置)
NSArray *anchorsarr = frame.anchors;
5.燈光,詳情可見本章節(jié)ARLightEstimate類介紹(指的是燈光強度 一般是0-2000,系統(tǒng)默認(rèn)1000)
ARLightEstimate *light = frame.lightEstimate;
6.特征點(應(yīng)該是捕捉平地或者人臉的,比較蘋果有自帶的人臉識別功能)
ARPointCloud *point = frame.rawFeaturePoints;
7.根據(jù)2D坐標(biāo)點搜索3D模型,這個方法通常用于,當(dāng)我們在手機屏幕點擊某一個點的時候,可以捕捉到這一個點所在的3D模型的位置,至于為什么是一個數(shù)組非常好理解。手機屏幕一個是長方形,這是一個二維空間。而相機捕捉到的是一個由這個二維空間射出去的長方體,我們點擊屏幕一個點可以理解為在這個長方體的邊緣射出一條線,這一條線上可能會有多個3D物體模型
point:2D坐標(biāo)點(手機屏幕某一點)
ARHitTestResultType:捕捉類型 點還是面
(NSArray<ARHitTestResult *> *):追蹤結(jié)果數(shù)組
CGPoint pin = CGPointMake(10, 10);
NSArray *arr = [frame hitTest:pin types:ARHitTestResultTypeFeaturePoint];
跟ARSCnview一樣的
8.相機窗口的的坐標(biāo)變換(可用于相機橫豎屏的旋轉(zhuǎn)適配)
CGSize sizi = CGSizeMake(100, 100);
[frame displayTransformWithViewportSize:sizi orientation:UIDeviceOrientationUnknown];
*/
/*
--ARAnchor--
錨點,
1. 標(biāo)識符
NSString *NSuuid = anchor.identifier ;
2. 錨點的旋轉(zhuǎn)變換矩陣,定義了錨點的旋轉(zhuǎn)、位置、縮放。是一個4x4的矩陣
matrix_float4x4 mat = anchor.transform;
3. 構(gòu)造方法,一般我們無需構(gòu)造。因為添加一個3D物體時ARKit會有代理告知我們物體的錨點
matrix_float4x4 a ;
ARAnchor *anchor = [[ARAnchor alloc]initWithTransform:a];
*/
/*
ARHitTestResult *hittestresult = [ARHitTestResult alloc];
1.捕捉類型是一個枚舉類型
hittestresult.type;
點.
ARHitTestResultTypeFeaturePoint
水平面 y為0.
ARHitTestResultTypeEstimatedHorizontalPlane
已結(jié)存在的平面.
ARHitTestResultTypeExistingPlane
已結(jié)存在的錨點和平面.
ARHitTestResultTypeExistingPlaneUsingExtent
2. 3D虛擬物體與相機的距離(單位:米)
float distance = hittestresult.distance;
3.自身坐標(biāo)
matrix_float4x4 local = hittestresult.localTransform;
4.世界坐標(biāo)
matrix_float4x4 word = hittestresult.worldTransform;
5.錨點
ARAnchor *anchor = hittestresult.anchor;
*/
接下來是ARSession;
/*
--ARSCNView--
非常重要的一個類,他是一個支持3D的AR場景和2D的AR場景,ARSCNView是3D的AR場景視圖
1.您提供協(xié)調(diào)同步的對象視圖的基于“增大化現(xiàn)實”技術(shù)與SceneKit場景信息內(nèi)容。
self.sceneView.delegate = self; var
2.添加會話
self.sceneView.session = self.arsession;
3.添加3D場景
self.sceneView.scene = scnscen;
4.是否自動適應(yīng)燈光
self.sceneView.autoenablesDefaultLighting = YES;
5.返回對應(yīng)節(jié)點的錨點,節(jié)點是一個3D虛擬物體,它的坐標(biāo)是虛擬場景中的坐標(biāo),而錨點ARAnchor是ARKit中現(xiàn)實世界的坐標(biāo)。
ARAnchor *anchor = [self.sceneView anchorForNode:scnscen];
6.上對于
self.sceneView nodeForAnchor:<#(nonnull ARAnchor *)#>
7.
根據(jù)2D坐標(biāo)點搜索3D模型,這個方法通常用于,當(dāng)我們在手機屏幕點擊某一個點的時候,可以捕捉到這一個點所在的3D模型的位置,至于為什么是一個數(shù)組非常好理解。手機屏幕一個是長方形,這是一個二維空間。而相機捕捉到的是一個由這個二維空間射出去的長方體,我們點擊屏幕一個點可以理解為在這個長方體的邊緣射出一條線,這一條線上可能會有多個3D物體模型
point:2D坐標(biāo)點(手機屏幕某一點)
ARHitTestResultType:捕捉類型 點還是面
(NSArray<ARHitTestResult *> *):追蹤結(jié)果數(shù)組
數(shù)組的結(jié)果排序是由近到遠(yuǎn)
ARHitTestResult 這兩個東西比較難,!目前我不理解???
ARHitTestResultType 這是一個枚舉
CGPoint pin = CGPointMake(10, 10);
NSArray *arr = [self.sceneView hitTest:pin types:ARHitTestResultTypeFeaturePoint];
*/
pragma mark --SCNScene--
/*
--SCNScene--
場景內(nèi)!這包括游戲的任何東西。。!AIP已經(jīng)寫好了。!
這個類場景類,用來讀取相對場景。!
具體的方法可以在API 中查看。。!
2. 上面已經(jīng)說了,!ARSCRView是繼承SCNView的。。!
SCRView就是用來顯示場景的。。。
3. 在手機中是右手坐標(biāo)系。
3.1其中場景中的負(fù)責(zé)顯示的SCNView,最底層的就是SCN節(jié)點。。(相對于各種組件)
3.2 (在這里你想想場景里基本的包括的東西!需要顯示出來還差什么,已經(jīng)有transform 了),這個還提供 了一個類,渲染類!
4。 渲染這塊包括 五塊
SCNSceneRenderer
SCNSceneRendererDelegate
SCNLayer
SCNRenderer
SCNHitTestResult
5.在這個場景框架里,該有的都有!接下來就是相機類了,!到這里就有點奇怪了。。!
(不是還有一個ARCameras么?)
SCRCameras 一組相機屬性可以被附加到一個節(jié)點提供一個角度顯示現(xiàn)場。(官網(wǎng)上說的)
ARCaneras 攝像機的位置和成像特征信息捕獲視頻幀的AR會話。
SCRCameras 這個是用來編輯相機位置的。。!
ARCaneras 負(fù)責(zé)顯示在手機屏幕上的。。?。ㄟ@是我對他的理解)
6. 燈光類! SCNlight
7. class SCNMaterial 材質(zhì)球
7.1 class SCNMaterialProperty
8.Geometry 幾何類嗎、,一個三維形狀(也稱為一個模型或網(wǎng)格),可以顯示在一個場景中,附加材料定義其外觀。
9.Animation and Constraints 動畫類
10.物理類,Physics Simulation
11.Particle Systems 粒子系統(tǒng)
12.Audio 音頻
13.Renderer Customization 渲染器定制
14.Scene Asset Import 場景的資源導(dǎo)入
15.JavaScript 使SceneKit類和全局常量用于指定JavaScript上下文。
*/
ARSCNViewDelegate
// Override to create and configure nodes for anchors added to the view's session.
-
(SCNNode *)renderer:(id<SCNSceneRenderer>)renderer nodeForAnchor:(ARAnchor *)anchor {
SCNNode *node = [SCNNode new];// Add geometry to the node..., 當(dāng)添加節(jié)點是會調(diào)用,我們可以通過這個代理方法得知我們添加一個虛擬物體到AR場景下的錨點(AR現(xiàn)實世界中的坐標(biāo))
return node;
}
/**
將要刷新節(jié)點
*/
- (void)renderer:(id <SCNSceneRenderer>)renderer didAddNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor{
}
/**
將要刷新節(jié)點
*/
- (void)renderer:(id <SCNSceneRenderer>)renderer willUpdateNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor{
}
/**
已經(jīng)刷新節(jié)點
*/
- (void)renderer:(id <SCNSceneRenderer>)renderer didUpdateNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor{
}
/**
移除節(jié)點
*/
- (void)renderer:(id <SCNSceneRenderer>)renderer didRemoveNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor{
}
//系統(tǒng)提供一下!
- (void)session:(ARSession *)session didFailWithError:(NSError *)error {
// Present an error message to the user,向用戶顯示一條錯誤消息
}
- (void)sessionWasInterrupted:(ARSession *)session {
// Inform the user that the session has been interrupted, for example, by presenting an overlay,/ /通知用戶會話已經(jīng)中斷,例如,通過提供一個覆蓋
}
- (void)sessionInterruptionEnded:(ARSession *)session {
// Reset tracking and/or remove existing anchors if consistent tracking is required
//重置跟蹤和/或刪除現(xiàn)有的定位是否需要持續(xù)跟蹤
}
ARSessionDelegate 代理
pragma mark - ARSessionDelegate
/**
這就是所謂的新框架時已更新。
會話正在運行的會話。
幀的幀更新。
每一幀都在調(diào)
*/
- (void)session:(ARSession *)session didUpdateFrame:(ARFrame *)frame{
// if (self.planeNode) {
// //positon 位置 ,matrix_float4x4 這個類不知道是什么意思!
// self.planeNode.position = SCNVector3Make(frame.camera.transform.columns[3].x, frame.camera.transform.columns[3].y, frame.camera.transform.columns[3].z);
//// NSLog(@"x = %f y = %f z = %f",frame.camera.transform.columns[2].x,frame.camera.transform.columns[2].y,frame.camera.transform.columns[2].z);
//
// }
}
/**
This is called when new anchors are added to the session.
這叫做當(dāng)新的錨被添加到會話
@param session The session being run.會話正在運行的會話
@param anchors An array of added anchors.錨的數(shù)組添加錨點
*/
- (void)session:(ARSession )session didAddAnchors:(NSArray<ARAnchor>*)anchors{
}
在這里寫的是第一次學(xué)習(xí)的比較,也是直接寫在Xcode上的。。!
希望以后一起學(xué)習(xí)。。!雙手奉上QQ 有問題一起解決。。!
345996501 !