2011年6月1日水曜日

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

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

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

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

package com.dividebyzero.KszGameBase;

/**
 * 勝手に作ったFloat型のArrayList
 * ArrayListでも悪くはないけど、オートボクシングがかかって内部でfloat→new Float()がかかってると考えると耐えられないので
 * 作ってみた。効果は不明。
 * @author ksz
 *
 */
class FloatArrayList {
 private int lastIndex;
 private float[] array;
 private static final float[] emptyArray = new float[0];

 public FloatArrayList() {
  this(0);
 }

 public FloatArrayList(int capacity) {
  lastIndex = 0;
  try {
   array = newElementArray(capacity);
  } catch (NegativeArraySizeException e) {
   throw new IllegalArgumentException();
  }
 }

 private float[] newElementArray(int size) {
  if (size == 0) {
   return emptyArray;
  }
  return new float[size];
 }

 public boolean add(float object) {
  if (lastIndex == array.length) { //いっぱいになっちゃった
   int size = size();
   int increment = size / 2;
   if (increment < 12) {
    increment = 12;
   }
   float[] newArray = newElementArray(size + increment);
   if (size > 0) {
    System.arraycopy(array, 0, newArray, 0, size);
    lastIndex = size;
   }
   array = newArray;
  }
  array[lastIndex++] = object;
  return true;
 }

 public float[] toArray() {
  int size = size();
  float[] result = new float[size];
  System.arraycopy(array, 0, result, 0, size);
  return result;
 }

 public float[] getFloatArray() {
  return array;
 }

 public int size() {
  return lastIndex;
 }
}

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

/**
 * Meshを作る前段階のクラス。 必要かどうかよくわかんなくなってきた
 * @author ksz
 *
 */
public class Subset {
 private FloatArrayList vertexList = new FloatArrayList();
 private FloatArrayList uvList = new FloatArrayList();
 private Texture tex;
 private int vCnt, uvCnt;
 public float r, g, b, a, diffuse, ambient;

 public Texture getTex() {
  return tex;
 }

 public int getVCnt() {
  return vCnt;
 }

 public int getUVCnt() {
  return uvCnt;
 }

 /**
  * 頂点を格納していく
  * @param x
  * @param y
  * @param z
  */
 public void addVertex(float x, float y, float z) {
  vertexList.add(x);
  vertexList.add(y);
  vertexList.add(z);
  vCnt++;
 }

 /**
  * UV座標の格納
  * @param u
  * @param v
  */
 public void addUV(float u, float v) {
  uvList.add(u);
  uvList.add(v);
  uvCnt++;
 }

 /**
  * 仕様しているテクスチャのセット
  * @param tex
  */
 public void addTexture(Texture tex) {
  this.tex = tex;
 }

 /**
  * セットされた頂点、UVからVBOを作成して返す
  * @return 作成されたVBO
  */
 public Vbo makeVBO() {
  Vbo retVBO = new Vbo();
  retVBO.makeBuffer(vertexList.getFloatArray(), vertexList.size(), uvList.getFloatArray(), uvList.size());
  retVBO.r = r;
  retVBO.g = g;
  retVBO.b = b;
  retVBO.diffuse = diffuse;
  retVBO.ambient = ambient;

  return retVBO;
 }
}
 

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

0 件のコメント:

コメントを投稿