日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

VR+全景播放器+头控讲解-06

發(fā)布時(shí)間:2024/3/26 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VR+全景播放器+头控讲解-06 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

VR+全景播放器+頭控講解-01-知識儲(chǔ)備
VR+全景播放器+頭控講解-02-創(chuàng)建球體
VR+全景播放器+頭控講解-03-渲染視頻
VR+全景播放器+頭控講解-04-滑動(dòng)手勢
VR+全景播放器+頭控講解-05-伸縮畫面
VR+全景播放器+頭控講解-06-頭控實(shí)現(xiàn)
VR+全景播放器+頭控講解-07-分屏技術(shù)

學(xué)習(xí)目標(biāo)

掌握頭控部分布局
如何檢測頭控按鈕被選中
如何實(shí)現(xiàn)懸停動(dòng)畫

在UIView上面布局我們可以使用UIButton UIView UIImageView等,但是是在3D場景中,我們不能使用UIView,我們要使用平面幾何當(dāng)視圖使用,下面具體介紹一下

分析

243FA4BB-FAC5-4A93-A9DF-C3A1F447F010.png

提示幾點(diǎn)

  • 頭控根節(jié)點(diǎn)可以放在根節(jié)點(diǎn)上中心或者球體中心都是可以的,但是考慮到后期我們要進(jìn)行視頻濾波,所以最好放到場景節(jié)點(diǎn)上
  • 低頭菜單出現(xiàn),抬頭菜單消失,這個(gè)要根據(jù)重力感應(yīng)在X軸旋轉(zhuǎn)決定的
  • 當(dāng)抬頭時(shí)菜單總是出現(xiàn)在下方,一旦出現(xiàn)不會(huì)跟隨照相機(jī)轉(zhuǎn)動(dòng),當(dāng)重力感應(yīng)變化時(shí),我們讓頭控節(jié)點(diǎn)的繞著y軸旋轉(zhuǎn)
  • 實(shí)現(xiàn)步驟

    第一步.創(chuàng)建菜單節(jié)點(diǎn)

    +(SCNNode*)createBackgroundNode{/// 創(chuàng)建一個(gè)背景色SCNNode* bgNode = [SCNNode node];bgNode.position = SCNVector3Make(0, CONTROL_DISTANCE/2, -CONTROL_DISTANCE);bgNode.geometry.firstMaterial.cullMode = SCNCullModeBack;bgNode.rotation = SCNVector4Make(1, 0, 0, atan(1/2.0));return bgNode;} +(SCNNode*)createShadowNode{SCNNode *shadowNode = [SCNNode node];shadowNode.geometry= [SCNPlane planeWithWidth:MENU_MAX_LENGTH height:BUTTON_WIDHT+BUTTON_WIDHT/2.0];shadowNode.geometry.firstMaterial.diffuse.contents = BACKGROUND_MENU_SHOW_NAME;shadowNode.position = SCNVector3Make(0, 0, 0);shadowNode.geometry.firstMaterial.cullMode = SCNCullModeBack;return shadowNode; }+(SCNNode*)createPlayNode{SCNNode* playNode = [SCNNode node];playNode.geometry = [SCNPlane planeWithWidth:BUTTON_WIDHT*0.8 height:BUTTON_WIDHT*0.8];playNode.geometry.firstMaterial.diffuse.contents = ICON_PLAY_NAME;playNode.position = SCNVector3Make(-20, 0, 2);playNode.geometry.firstMaterial.cullMode = SCNCullModeBack;return playNode; } +(SCNNode*)createPreviousNode{/// 第六步-創(chuàng)建播放上一個(gè)視頻的節(jié)點(diǎn)SCNNode* previousNode = [SCNNode node];previousNode.geometry = [SCNPlane planeWithWidth:BUTTON_WIDHT*0.8 height:BUTTON_WIDHT*0.8];previousNode.geometry.firstMaterial.diffuse.contents = ICON_PREVIOUS_NAME;previousNode.position = SCNVector3Make(-60, 0, 2);previousNode.geometry.firstMaterial.cullMode = SCNCullModeBack;return previousNode; } +(SCNNode*)createAfterNode{SCNNode *nextNode = [SCNNode node];nextNode.geometry = [SCNPlane planeWithWidth:BUTTON_WIDHT*0.8 height:BUTTON_WIDHT*0.8];nextNode.geometry.firstMaterial.diffuse.contents = ICON_AFTER_NAME;nextNode.position = SCNVector3Make(20, 0, 2);nextNode.geometry.firstMaterial.cullMode = SCNCullModeBack;return nextNode; } +(SCNNode*)createMoreNode{SCNNode* moreNode = [SCNNode node];moreNode.geometry = [SCNPlane planeWithWidth:BUTTON_WIDHT*0.8 height:BUTTON_WIDHT*0.8];moreNode.geometry.firstMaterial.diffuse.contents = ICON_MENU_HIDDEN_NAME;moreNode.position = SCNVector3Make(60, 0, 2);moreNode.geometry.firstMaterial.cullMode = SCNCullModeBack;return moreNode; } +(SCNNode*)createHighVoiceNode{SCNNode* voiceHighNode = [SCNNode node];voiceHighNode.geometry = [SCNPlane planeWithWidth:BUTTON_WIDHT*0.8 height:BUTTON_WIDHT*0.8];voiceHighNode.geometry.firstMaterial.diffuse.contents = ICON_VOICE_HIGH_NAME;voiceHighNode.geometry.firstMaterial.cullMode = SCNCullModeBack;return voiceHighNode; } +(SCNNode*)createLowVoiceNode{SCNNode* voiceLowNode = [SCNNode node];voiceLowNode.geometry = [SCNPlane planeWithWidth:BUTTON_WIDHT*0.8 height:BUTTON_WIDHT*0.8];voiceLowNode.geometry.firstMaterial.diffuse.contents = ICON_VOICE_LOW_NAME;voiceLowNode.geometry.firstMaterial.cullMode = SCNCullModeBack;return voiceLowNode; }

    創(chuàng)建的方法基本一致,調(diào)節(jié)一下位置即可!

    第二步 添加到先把功能按鈕節(jié)點(diǎn)添加到頭控背景節(jié)點(diǎn)上,然后將背景節(jié)點(diǎn)添加到頭控根節(jié)點(diǎn)上去

    [self.scene.rootNode addChildNode:self.controlNode]; [self.controlNode addChildNode:self.bgNode]; [self.bgNode addChildNode:self.shadowNode]; [self.bgNode addChildNode:self.playOrPauseNode]; [self.bgNode addChildNode:self.proviousNode]; [self.bgNode addChildNode:self.AfterNode]; [self.bgNode addChildNode:self.showMoreNode]; [self.bgNode addChildNode:self.lowVoiceNode]; [self.bgNode addChildNode:self.highVoiceNode]; [self.scene.rootNode addChildNode:self.eyeNode];

    第三步 添加點(diǎn)控節(jié)點(diǎn),將其放在添加到照相機(jī)節(jié)點(diǎn)上去,這樣照相機(jī)轉(zhuǎn)動(dòng)的時(shí)候,它就能跟著轉(zhuǎn)動(dòng),效果就是一直在屏幕中央

    [self.eyeNode addChildNode:self.dotNode];

    第四步 抬頭小時(shí)低頭出現(xiàn)

    -(void)controlEyeNodeInVR:(SCNVector3)vector{ // 向上抬頭 并且local if ( vector.x>0.8 &&self.bgNode.hidden==false){self.bgNode.hidden = true;self.dotNode.hidden = true; }else if ( vector.x<0.8 &&self.bgNode.hidden){self.bgNode.hidden = false;self.dotNode.hidden = false;SCNVector3 eulerAngles = self.controlNode.eulerAngles;// eulerAngles.y = -vector.z;eulerAngles.z = vector.z;self.controlNode.eulerAngles = eulerAngles;} }

    第五步 如何檢測點(diǎn)控射線和頭控按鈕相交
    思路:

    先將按鈕轉(zhuǎn)換到照相機(jī)節(jié)點(diǎn)上,點(diǎn)控射線是否和按鈕區(qū)域相交,就是相當(dāng)于頭控坐標(biāo) x在范圍 [-button.width/2,button.width/2]內(nèi), y在 [-button.height/2.button.heigth/2.0]內(nèi)

    /// 下面就舉一個(gè)例子,其它的都是類似的 SCNVector3 proviousPosition = [self.bgNode convertPosition:self.proviousNode.position toNode:self.self.eyeNode]; if (proviousPosition.x > -BUTTON_WIDHT/2 && proviousPosition.x < BUTTON_WIDHT/2 && proviousPosition.y > -BUTTON_WIDHT/2 && proviousPosition.y < BUTTON_WIDHT/2 ){if (!self.controlDotIn.inPreviousNode&&!self.proviousNode.hidden){// 第一次進(jìn)入 還沒有離開// 開始執(zhí)行懸停動(dòng)畫[self startAnimation];}_controlDotIn.inPreviousNode = YES;return; }else if(_controlDotIn.inPreviousNode){// 檢測到離開按鈕return; }

    懸停動(dòng)畫的實(shí)現(xiàn)

    第一步 創(chuàng)建動(dòng)畫行為

    -(void)createAnimation{ /// 創(chuàng)建動(dòng)畫節(jié)點(diǎn) self.animationNode = [SCNNode node]; self.animationNode.geometry = [SCNPlane planeWithWidth:CONTROL_DISTANCE/5.0 height:CONTROL_DISTANCE/5.0]; self.animationNode.hidden = true;// 控制點(diǎn)上增加動(dòng)畫節(jié)點(diǎn) [self.dotNode addChildNode:self.animationNode]; __weak XJRenderView* weakSelf = self; self.animationAction = [SCNAction customActionWithDuration:3 actionBlock:^(SCNNode * _Nonnull node, CGFloat elapsedTime) {int time = (int) (elapsedTime *(weakSelf.gif.count-1)/3.0);node.geometry.firstMaterial.diffuse.contents = weakSelf.gif[time];if(time == weakSelf.gif.count-1){[weakSelf animationDidStop];} }]; } -(NSArray *)gif{if(!_gif){NSMutableArray *gif= [NSMutableArray arrayWithCapacity:GIF_LENGTH];for(int i = 0 ; i< GIF_LENGTH ;i++){NSString *name = [NSString stringWithFormat:GIF_PREFIX_NAME_FORMAT,i];[gif addObject:name];}_gif = gif;}return _gif; }

    第二步 在執(zhí)行的節(jié)點(diǎn)上執(zhí)行動(dòng)畫行為

    -(void)startAnimation{[self.animationNode runAction:self.animationAction]; }

    本節(jié)講解完畢
    SceneKit 中文教程

    總結(jié)

    以上是生活随笔為你收集整理的VR+全景播放器+头控讲解-06的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。