国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

J2MEMobile3D入門教程系列文章之二

2019-11-18 16:05:06
字體:
來源:轉載
供稿:網友

  在這里我首先感謝大家對上一篇文章J2ME Mobile 3D入門教程系列文章之一的支持,也正是有了大家的支持,我決定把我的Mobile3D學習過程拿出來和大家共享,希望大家能一起來討論Mobile3D。
  
  在上一次的教程中我為您詳細的介紹了,在Moble3D中通過及時運算建立3D圖形,并且對從*.m3g文件中導入模型做了一個簡單的介紹,這次我想在這里通過*.m3g文件的使用簡單的介紹一下Mobile3D對動畫的控制,以及對模型的一些操作。
  
  首先我來簡單的說一下m3g文件的建立,這個其實很簡單,你只需要選擇一種你所熟悉的3D圖形制作軟件,并安裝對應的插件即可,在這里我使用的軟件是Maya和3DS MAX,插件使用的是H3T EXPort Plugin,該插件有maya和3ds max的,同時還需要下載一個軟件M3G Tools kit。
  
  這些都可以從Sony EriCSSon的網站上找到連接。插件的安裝應該都沒問題吧。插件安裝完成后,就可以建立模型、設置材質帖圖、設置攝影機、設置關鍵幀等等了,最后只要輸出成H3T文件即可。然后再打開M3G Tools kit將h3t文件輸出成m3g文件就可以了。在使用m3g文件之前最好用M3G Tools kit瀏覽一下該文件,為的是記錄對應的信息,例如userid和該場景的樹狀結構等信息,這些都是非常重要的。如果你這樣做了,你會發現這樣導出的m3g文件中camera并沒有在world樹下,而是和world樹是平級的。
  
  其實上一篇文章中我也說過,camera和渲染信息可以不被放在world樹下,但是所有的模型信息必須被放到樹下。當我們看m3g文件的時候比較重要的是看清楚world節點所在的位置,以及需要我們操作的模型的userid。
  
  準備工作差不多了,現在來看Mobile3D吧,在上一文章中我說過m3g文件使用通過javax.microedition.m3g.Loader.load(String url)載入的,而且該方法返回的是javax.microedition.m3g.Object3D的數組,也許有人要問既然world是根節點,那么為什么不直接返回一個World呢?
  
  剛才讓大家看m3g文件的結構的時候就已經說明了攝影機和動畫設定等等并沒有被放到World為節點的書中,而是和World節點同級的。而World節點是場景的根節點才對。那么我們如何才正確的取出World節點呢?方法有兩個:
  
  1、遍歷該Object3D數組,并比較每個元素的userid如果正式World節點的useid將該元素取出。
  
  2、遍歷該Object3D數組,并比較每個元素是不是World類的實例,那么既然World節點是場景的根節點,那么在該Object3D數組中也應該只有一個World類的實例對象。
  
  第一個方法比較簡單,我在這里只給出第二個方法的片斷代碼。(其實是一樣的)
  
  PRivate void loadWorld(){
  System.out.println("now loading...");
  try{
  buffer=Loader.load("/img/TmpMicroFile.m3g");
  for(int i=0;i  if(buffer[i] instanceof World){
  world=(World)buffer[i];
  return ;
  }
  }
  }catch(Exception e){
  buffer=null;
  System.out.println("thorw a exception when loading");
  e.printStackTrace();
  }
  }
  
  然后我們設置攝影機,不同的是,這次我們從World中獲得攝影機信息,獲取后我們可以對其進行一些基本的設置這里不細說了。下面著重的說一下動畫的部分。
  
  在我們導入這個m3g文件時候我們其實已經有了動畫的信息了,并且這些動畫信息有可能是很復雜的,我測試了連桿兩軸的運動可以沒問題,從一些資料上看到的IK反向運動也沒有問題。也許你已經著急了,怎么還不說如何控制動畫的播放呢?
  簡單的說World.animate()來更新動畫信息,這個方法需要傳進去一個int類型的參數,當你第一次調用該方法的時候,系統會記錄下這個數值,后面每次調用的時候都會和這個數值相比較,然后系統替我們計算出動畫更新到什么位置,同時該方法會返回一個int類型的參數,這個參數表示的下一次更新的一個建議的數值(是以毫秒為單位的)。
  
  我們這時就可以讓調用這個方法的線程休眠這個時間,以便下以次更新動畫數據。這里也許你會有疑問,我的動畫明明只有幾十幀,可是這里卻反復的播放;這雖然是個好消息,但在有很多情況播放的長度、什么時候播放,都需要我們自己來控制怎么辦?
  
  這時候我們就需要用到javax.microedition.m3g.AnimationController類了,其實每個動畫中的每個可以動的模型都有自己的AnimationController對象,和模型動畫一樣我們可以通過World.find(int controllerID)來獲得,在該類中我們可以通過setActiveInterval(int activeTime,int unactiveTime)來設定動畫在該系統中播放的起始和重點時間,另外通過setPosition(int startTime,int endTime)方法控制這個動畫需要播放哪一段落。
  
  很抱歉有關兩個方法的時候在這次教程實例中我并沒有使用,不過如果您想了解關于這兩個方法的使用,我建議你看看WTK2.2的那個Demo3D中袋鼠的例子,那里面寫的挺詳細的。這里呢我給出動畫和繪制的代碼片斷吧。
  
  protected void paint(Graphics g) {
  
  startTime= System.currentTimeMillis() - worldStartTime;
  validity= world.animate((int)startTime);
  perFrameTime=(int)System.currentTimeMillis();
  
  g.setColor(0x00);
  g.fillRect(0,0,getWidth(), getHeight());
  
  g.setClip(0,0,getWidth(),getHeight());
  g3d.bindTarget(g,true,Graphics3D.DITHERGraphics3D.TRUE_COLOR);
  g3d.setViewport(0,0,getWidth(),getHeight());
  
  g3d.render(world);
  
  g3d.releaseTarget();
  
  framePor=(int)1000/((int)System.currentTimeMillis()-perFrameTime);
  
  System.out.println("3D demo frame/sn:"+framePor);
  
  if(validity < 1)
  { // The validity too small; allow a minimum of 1ms.
  validity = 1;
  }
  
  if(validity == 0x7fffffff)
  { // The validity is infinite; scehdule a refresh in 1 second.
  validity=1000;
  }
  
  }
  
  public void run() {
  while(isRun){
  repaint();
  try{
  Thread.sleep(validity);
  }catch(Exception e){}
  }
  }
  
  這里如果你不喜歡使用線程的話,你可以換成Timer。個人喜好問題吧,我對線程比較熟悉,所以這里我使用的是線程。
  
  動畫似乎我現在也只理解到這些,全部和大家共享出來了。下面我想說一說Transformable類中的幾個方法。首先來介紹一下Transformable類吧。Transformable類是很重要的一個類,Node就是它的子類,知道它的重要性了吧。
  
  Transformable中有四個方法是今天我要簡單說一下的postRotate(float, float, float, float)放是和物體的旋轉有關系的在Mobile3D中默認所有的物體的旋轉軸都在自身的中心,所以對物體進行旋轉操作的話,一定是自轉,而不是繞某個點、或某個軸公轉,這一點一定要弄清楚。也許這樣說有些抽象那么我換個說法,就是這里的旋轉只改變物體的朝向,并不改變物體的位置。
  
  這下明白了吧,也許有人要問“這不正是我們需要的嗎?為什么要強調呢?”原因其實是這樣的,在有的3D引擎中,旋轉是以原點為基礎的。也就是說如果需要做自轉運動,就必須做移動、再旋轉、再移動這樣的操作,其實這樣做的好處是可以方便點的運算,因為點不存在自轉的概念。而我們的Mobile3D在某種程度上說是不可以對點操作的,所以它的最小單位是Mesh,那么它如何實現自轉呢?來看個矩陣你就明白了
  
  90,0,0,0
  0,0,0,0
  0,0,1,0
  0,0,0,0
  
  這個矩陣表示的當前的模型在Y軸上有90度的旋轉。現在我們回頭來看看postRotate(float a, float x, float y, float z)方法,其中有4個參數,第一個就是這次需要旋轉的角度,后三個其實一個這次旋轉的軸,是通過一個向量來表示的,postRotate方法就是在原來的朝向上繼續進行新的旋轉,如果用數學公式來表示的話就是使用原有的矩陣乘以
  
  a,0,0,0
  0,x,0,0
  0,0,y,0
  0,0,0,z
  
  這個矩陣就是新的方向矩陣。這個方法如果從數學角度聽起來很難理解的話,你只要記住四個參數第一個是這次旋轉的角度,后三個確定旋轉軸。
  同postRotate方法類似的是setOrientation(float a, float x, float y, float z)。不同的是這次不再是旋轉了而是直接設置到這個朝向。
  
  說過旋轉再來看看移動,這個似乎就簡單很多了translate(float x, float y, float z)這個就是指按照指定的向量平移;setTranslation(float x, float y, float z)這個更簡單了,直接移動到指定的位置。
  
  其實還有一個方法scale(float sx, float sy, float sz)是用來進行縮放的,同樣還有setScale(float sx, float sy, float sz)直接設置比例尺,這個六個方法是對物體進行直接的操作的,非常有用,尤其是前四個,在編寫游戲的時候會經常用到,而后兩個使用的頻率似乎少一些,因為很多時候我們都是直接對攝像機的距離進行操作的(除非有特殊需要)。下面我給出個使用前四方法的舉例吧。
  
  public void keyPressed(int keycode){
  float[] camerTra;
  float x;
  float z;
  switch(keycode){
  case GameCanvas.DOWN:
  break;
  case GameCanvas.UP:
  break;
  case 52:
  dir=dir-2;
  System.out.println(dir);
  x=(float)(3*Math.sin((dir * 3.14159f)

(出處:http://m.survivalescaperooms.com)



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 收藏| 井研县| 涟水县| 长子县| 伊春市| 南雄市| 普洱| 广河县| 蓬莱市| 合水县| 赤峰市| 宁国市| 嘉义市| 日土县| 朔州市| 岳普湖县| 宁明县| 屯门区| 顺义区| 敦煌市| 鄂温| 抚顺县| 峨眉山市| 岳池县| 监利县| 崇仁县| 甘南县| 济阳县| 仪征市| 兴仁县| 大悟县| 明水县| 桃园县| 天等县| 泾阳县| 勃利县| 蓬安县| 体育| 琼结县| 塔河县| 丰顺县|