2011年6月1日水曜日

AndroidでMetasequoiaのmqoを読み込むコード その3 Subsetクラス

まだまだ続いています。 メタセコファイル読み込み下準備。

頂点配列、UV配列をモデルのファイルから読み込んで管理するために、Subsetクラスを作ってます。
モデルデータをパースする際、頂点数などが先に分かっている場合はいいのですが、それが明記されてないファイル形式も多々あるので、可変長にせざるを得ない。 でも可変長だからといって、単純にArrayListみたいにするとシンタックスシュガーで隠れてはいるけどオートボクシング(裏でラッパークラスへの変換)が行われているはずであってそんなのやってもらっちゃー困る。

ので、FloatArrayListなんつーものも作ってあります。

  1. package com.dividebyzero.KszGameBase;  
  2.   
  3. /** 
  4.  * 勝手に作ったFloat型のArrayList 
  5.  * ArrayList<float>でも悪くはないけど、オートボクシングがかかって内部でfloat→new Float()がかかってると考えると耐えられないので 
  6.  * 作ってみた。効果は不明。 
  7.  * @author ksz 
  8.  * 
  9.  */  
  10. class FloatArrayList {  
  11.  private int lastIndex;  
  12.  private float[] array;  
  13.  private static final float[] emptyArray = new float[0];  
  14.   
  15.  public FloatArrayList() {  
  16.   this(0);  
  17.  }  
  18.   
  19.  public FloatArrayList(int capacity) {  
  20.   lastIndex = 0;  
  21.   try {  
  22.    array = newElementArray(capacity);  
  23.   } catch (NegativeArraySizeException e) {  
  24.    throw new IllegalArgumentException();  
  25.   }  
  26.  }  
  27.   
  28.  private float[] newElementArray(int size) {  
  29.   if (size == 0) {  
  30.    return emptyArray;  
  31.   }  
  32.   return new float[size];  
  33.  }  
  34.   
  35.  public boolean add(float object) {  
  36.   if (lastIndex == array.length) { //いっぱいになっちゃった  
  37.    int size = size();  
  38.    int increment = size / 2;  
  39.    if (increment < 12) {  
  40.     increment = 12;  
  41.    }  
  42.    float[] newArray = newElementArray(size + increment);  
  43.    if (size > 0) {  
  44.     System.arraycopy(array, 0, newArray, 0, size);  
  45.     lastIndex = size;  
  46.    }  
  47.    array = newArray;  
  48.   }  
  49.   array[lastIndex++] = object;  
  50.   return true;  
  51.  }  
  52.   
  53.  public float[] toArray() {  
  54.   int size = size();  
  55.   float[] result = new float[size];  
  56.   System.arraycopy(array, 0, result, 0, size);  
  57.   return result;  
  58.  }  
  59.   
  60.  public float[] getFloatArray() {  
  61.   return array;  
  62.  }  
  63.   
  64.  public int size() {  
  65.   return lastIndex;  
  66.  }  
  67. }  
  68. </float>  

そして、↑を使ってSubsetクラス。
ただデータを貯めこむのと、そこからVBOを作れるだけ。

  1. /** 
  2.  * Meshを作る前段階のクラス。 必要かどうかよくわかんなくなってきた 
  3.  * @author ksz 
  4.  * 
  5.  */  
  6. public class Subset {  
  7.  private FloatArrayList vertexList = new FloatArrayList();  
  8.  private FloatArrayList uvList = new FloatArrayList();  
  9.  private Texture tex;  
  10.  private int vCnt, uvCnt;  
  11.  public float r, g, b, a, diffuse, ambient;  
  12.   
  13.  public Texture getTex() {  
  14.   return tex;  
  15.  }  
  16.   
  17.  public int getVCnt() {  
  18.   return vCnt;  
  19.  }  
  20.   
  21.  public int getUVCnt() {  
  22.   return uvCnt;  
  23.  }  
  24.   
  25.  /** 
  26.   * 頂点を格納していく 
  27.   * @param x 
  28.   * @param y 
  29.   * @param z 
  30.   */  
  31.  public void addVertex(float x, float y, float z) {  
  32.   vertexList.add(x);  
  33.   vertexList.add(y);  
  34.   vertexList.add(z);  
  35.   vCnt++;  
  36.  }  
  37.   
  38.  /** 
  39.   * UV座標の格納 
  40.   * @param u 
  41.   * @param v 
  42.   */  
  43.  public void addUV(float u, float v) {  
  44.   uvList.add(u);  
  45.   uvList.add(v);  
  46.   uvCnt++;  
  47.  }  
  48.   
  49.  /** 
  50.   * 仕様しているテクスチャのセット 
  51.   * @param tex 
  52.   */  
  53.  public void addTexture(Texture tex) {  
  54.   this.tex = tex;  
  55.  }  
  56.   
  57.  /** 
  58.   * セットされた頂点、UVからVBOを作成して返す 
  59.   * @return 作成されたVBO 
  60.   */  
  61.  public Vbo makeVBO() {  
  62.   Vbo retVBO = new Vbo();  
  63.   retVBO.makeBuffer(vertexList.getFloatArray(), vertexList.size(), uvList.getFloatArray(), uvList.size());  
  64.   retVBO.r = r;  
  65.   retVBO.g = g;  
  66.   retVBO.b = b;  
  67.   retVBO.diffuse = diffuse;  
  68.   retVBO.ambient = ambient;  
  69.   
  70.   return retVBO;  
  71.  }  
  72. }  
  73.    

ところどころメンバ変数がpublicなのは単純に面倒だったのと、これを直接いじる人もおらんだろうという想像から。 加えて言うならこれをセッターゲッターにしたときのオーバーヘッドを減らしたかった・・・という欺瞞もありで。

0 件のコメント:

コメントを投稿