SceneKit自學(xué)之路(2)

第二個(gè)Demo袱耽,沒有用到什么新的東西咒循。算是對(duì)學(xué)習(xí)的東西一個(gè)鞏固吧据途。


該實(shí)例模擬了一個(gè)簡單的天體運(yùn)動(dòng)。大概分了以下幾步來實(shí)現(xiàn)叙甸。

- (void)viewDidLoad {
    [super viewDidLoad];
    //創(chuàng)建場景
    SCNView *universeView = [self makeScene];
    //創(chuàng)建太陽
    SCNNode *sunNode = [self makeSun];
    [universeView.scene.rootNode addChildNode:sunNode];
    //太陽自轉(zhuǎn)
    [self rotation:sunNode];
    //創(chuàng)建地球
    SCNNode *earthNode = [self makeEarth];
    //地球自轉(zhuǎn)
    [self rotation:earthNode];
    //地球公轉(zhuǎn)
    [sunNode addChildNode:earthNode];
    //添加月亮
    SCNNode *moonNode = [self makeMoon];
    //月亮自轉(zhuǎn)
    [self rotation:moonNode];
    //月亮公轉(zhuǎn)
    [earthNode addChildNode:moonNode];
}
1颖医、創(chuàng)建場景

在創(chuàng)建場景時(shí),我把除天體以外的SCNView裆蒸、SCNScene熔萧、SCNNode都放在了這初始化。方便流程了理解僚祷。

#pragma mark - 初始化Scene
-(SCNView *)makeScene {
    //創(chuàng)建SCNView
    SCNView *universeView = [[SCNView alloc]initWithFrame:self.view.frame];
    [self.view addSubview:universeView];
    [universeView setBackgroundColor:[UIColor lightGrayColor]];
    //創(chuàng)建SCNScene
    SCNScene *scene = [SCNScene new];
    universeView.scene = scene;
    //創(chuàng)建cameraNode(用于調(diào)整鏡頭佛致,必須添加camera,否則添加的node總是會(huì)適應(yīng)scene的大小辙谜,無法觀測(cè)調(diào)整大小效果)
    SCNNode *cameraNode = [SCNNode node];
    cameraNode.camera = [SCNCamera camera];
    [scene.rootNode addChildNode:cameraNode];
    cameraNode.position = SCNVector3Make(0, 0,250);
    cameraNode.camera.zFar = 2000;
    return universeView;
}

在這里需要強(qiáng)調(diào)的是camera這個(gè)Node非常重要俺榆,要實(shí)現(xiàn)一個(gè)完整的功能,幾乎必不可少装哆。所以接下來的一篇罐脊,我將單獨(dú)專門研究camera定嗓。

2、創(chuàng)建太陽

在上一篇的HelloWorld中萍桌,我發(fā)現(xiàn)SCNText這個(gè)幾何圖形有些特殊宵溅,如果是其他幾何圖形SCNSphereSCNBox等上炎,在沿Y軸旋轉(zhuǎn)時(shí)恃逻,都是圍著中心旋轉(zhuǎn)。但是SCNText是圍著左邊旋轉(zhuǎn)反症。
分析后發(fā)現(xiàn)其他的幾何圖形辛块,他們的坐標(biāo)軸都是在自己的中心,但是SCNText是在自己的左下角铅碍。設(shè)置alignmentMode都沒用润绵。那如何讓SCNText實(shí)現(xiàn)圍著中心旋轉(zhuǎn)呢?
搜索引擎了兩天沒有得到結(jié)果胞谈。我最終采用的方法是類似html的div方式尘盼。把SCNText用其他的幾何圖形包一層,然后讓包裹它的幾何圖形旋轉(zhuǎn)烦绳。需要注意的地方是我們需要將SCNText放在parentNode的中心卿捎。
我封裝了這個(gè)一個(gè)方法

- (void)recenterText:(SCNNode *)node {
    SCNText *sceneText = (SCNText *)node.geometry;
    SCNVector3 min = SCNVector3Zero;
    SCNVector3 max = SCNVector3Zero;
    [sceneText getBoundingBoxMin:&min max:&max];
    sceneText.alignmentMode = kCAAlignmentCenter;
    CGFloat textHeight = max.y - min.y;
    CGFloat textWidth = max.x - min.x;
    SCNVector3 position = SCNVector3Make(-textWidth/2 , -textHeight/3*2 , 0);
    node.position = position;
}

上面的position的y值,我認(rèn)為應(yīng)該是-textHeight/2就行了径密,但是實(shí)際效果卻偏高了一點(diǎn)午阵,目測(cè)調(diào)整為-textHeight/3*2,原因還沒想通享扔。

#pragma mark - 初始化Sun
-(SCNNode *)makeSun {
    //創(chuàng)建太陽
    SCNNode *sunNode = [SCNNode new];
    SCNSphere *sphere = [SCNSphere sphereWithRadius:40];
    sphere.firstMaterial.diffuse.contents = [UIColor colorWithRed:1.0 green:0 blue:0 alpha:0.8];
    sunNode.geometry = sphere;
    //把太陽設(shè)置為發(fā)光源
    sunNode.geometry.firstMaterial.lightingModelName = SCNLightingModelConstant;
    SCNNode *omniLightNode = [SCNNode node];
    omniLightNode.light = [SCNLight light];
    omniLightNode.light.type = SCNLightTypeOmni;
    omniLightNode.light.color = [UIColor whiteColor];
    [sunNode addChildNode:omniLightNode];
    //給他一個(gè)Title
    SCNNode *textNode = [SCNNode new];
    SCNText *text = [SCNText textWithString:@"太陽" extrusionDepth:2];
    text.font = [UIFont systemFontOfSize:32];
    text.firstMaterial.diffuse.contents = [UIColor whiteColor];
    textNode.geometry = text;
    [sunNode addChildNode:textNode];
    [self recenterText:textNode];
    return sunNode;
}

我沒有素材底桂,就用顏色+文字表達(dá)了。給幾何圖形設(shè)置顏色的方法是text.firstMaterial.diffuse.contents = [UIColor redColor];也可以設(shè)置firstMateri.almultiply.contents等惧眠,了解更多可以查看一下SCNMaterial類籽懦。我沒計(jì)劃深入了解貼圖,所以這里先跳過氛魁。

3暮顺、太陽自轉(zhuǎn)
#pragma mark - 自轉(zhuǎn)
-(void)rotation:(SCNNode *)node {
    SCNAction *customAction = [SCNAction rotateByX:0 y:1 z:0 duration:1];
    SCNAction *repeatAction = [SCNAction repeatActionForever:customAction];
    [node runAction:repeatAction];
}
4、初始化地球/月亮

地球和月亮的初始化方法和自轉(zhuǎn)方法與太陽大同小異秀存。

5捶码、地球/月亮公轉(zhuǎn)

實(shí)際上每個(gè)天體的旋轉(zhuǎn)速度都是不一樣的,在Demo中我們忽略這些或链。
地球是圍著太陽旋轉(zhuǎn)的宙项,我們直接把earthNode加入sunNode的子節(jié)點(diǎn),earthNode就跟著sunNode一起旋轉(zhuǎn)了株扛。

[sunNode addChildNode:earthNode];

假如要實(shí)現(xiàn)公轉(zhuǎn)速度與太陽自轉(zhuǎn)速度不相等尤筐,只需要再加一個(gè)公轉(zhuǎn)速度的節(jié)點(diǎn)汇荐,并將地球節(jié)點(diǎn)設(shè)為它的子節(jié)點(diǎn)就好了。
還要注意地球與太陽的位置

earthNode.position = SCNVector3Make(120, 0, 0);

這個(gè)position就是node的坐標(biāo)原點(diǎn)相對(duì)parentNode坐標(biāo)原點(diǎn)的位置盆繁。


代碼寫得比較冗余(實(shí)際上除了注釋也就幾十行代碼)掀淘,可以按照代碼規(guī)范優(yōu)化。但是目前是以學(xué)習(xí)為主油昂,所以盡量把所有的流程都寫出來革娄,方便理解。

效果圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冕碟,一起剝皮案震驚了整個(gè)濱河市拦惋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌安寺,老刑警劉巖厕妖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異挑庶,居然都是意外死亡言秸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門迎捺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來举畸,“玉大人,你說我怎么就攤上這事凳枝〕冢” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵岖瑰,是天一觀的道長叛买。 經(jīng)常有香客問我,道長锭环,這世上最難降的妖魔是什么聪全? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任泊藕,我火速辦了婚禮辅辩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘娃圆。我一直安慰自己玫锋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布讼呢。 她就那樣靜靜地躺著撩鹿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪悦屏。 梳的紋絲不亂的頭發(fā)上节沦,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天键思,我揣著相機(jī)與錄音,去河邊找鬼甫贯。 笑死吼鳞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的叫搁。 我是一名探鬼主播赔桌,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼渴逻!你這毒婦竟也來了疾党?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤惨奕,失蹤者是張志新(化名)和其女友劉穎雪位,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體墓贿,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡茧泪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了聋袋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片队伟。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖幽勒,靈堂內(nèi)的尸體忽然破棺而出嗜侮,到底是詐尸還是另有隱情,我是刑警寧澤啥容,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布锈颗,位于F島的核電站,受9級(jí)特大地震影響咪惠,放射性物質(zhì)發(fā)生泄漏击吱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一遥昧、第九天 我趴在偏房一處隱蔽的房頂上張望覆醇。 院中可真熱鬧,春花似錦炭臭、人聲如沸永脓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽常摧。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間落午,已是汗流浹背谎懦。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留溃斋,地道東北人党瓮。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像盐类,于是被迫代替她去往敵國和親寞奸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

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

  • 本文介紹如何用AR做一個(gè)簡易的太陽系 一在跳、了解太陽系的場景 太陽系是以太陽為中心枪萄,和所有受到太陽的引力約束天體的集...
    Oooh閱讀 1,649評(píng)論 0 0
  • 簡介: 上篇回顧: ARKit初探篇(鏈接)中寫到怎樣開啟一個(gè)AR項(xiàng)目,包括開發(fā)環(huán)境,建立項(xiàng)目,及基礎(chǔ)代碼實(shí)現(xiàn),在...
    a437e8f87a81閱讀 3,548評(píng)論 5 38
  • 今天上午,聽到領(lǐng)導(dǎo)和改試卷老師呵呵大家的培訓(xùn)猫妙,真是收獲滿滿瓷翻。 首先是王校長的講話,非常在理割坠。無規(guī)矩不成方圓齐帚。守時(shí)守...
    wh王浩閱讀 195評(píng)論 0 4
  • 腦子里經(jīng)常會(huì)思緒亂飛对妄,有時(shí)躺在床上,輾轉(zhuǎn)反側(cè)敢朱,腦海里總是浮現(xiàn)出各種畫面剪菱,思考著各種問題,一旦想到好點(diǎn)子或是遇到想不...
    張德祥閱讀 210評(píng)論 1 4
  • 周日,本不用上班蚓哩,卻依然有了個(gè)早起构灸。 今天是中考的最后一天,起床后照例是先奏上一曲鍋碗瓢盆的交響曲岸梨。喜颁,然后再當(dāng)上一...
    不經(jīng)不覺閱讀 235評(píng)論 0 5