/**
     * vertexチャンクの読み込み
     *
     * @param num チャンクにあるデータ数
     * @param br 読み込みストリーム
     * @param scale モデルの倍率
     * @return 頂点配列
     * @throws Exception
     */
    private KGLPoint[] readVertex(int num, multiInput br, float scale) throws Exception {
      KGLPoint[] ret = null;
      String line = null;
      String[] s;
      int cnt;
      ret = new KGLPoint[num];
      cnt = 0;
      try {
        while ((line = br.readLine()) != null) {
          if (line.length() <= 0) continue;
          line = line.trim();
          if (line.equals("}")) break;
          s = line.split(" ", 3);
          ret[cnt] =
              KGLPoint.createXYZ(
                  Float.parseFloat(s[0]) * scale,
                  Float.parseFloat(s[1]) * scale,
                  Float.parseFloat(s[2]) * scale);
          cnt++;
        }
      } catch (Exception e) {
        Log.e("KGLMetaseq", "MQOファイル フォーマットエラー(Object>vertex)[" + line + "]");
        throw e;
      }

      if (cnt != num) return null;
      return ret;
    }
 /**
  * 法線を求める
  *
  * @param V 頂点配列
  * @param A 頂点の位置
  * @param B 頂点の位置
  * @param C 頂点の位置
  * @return 法線ベクトル
  */
 protected KGLPoint calcNormal(KGLPoint[] V, int A, int B, int C) {
   KGLPoint ret = null;
   KGLPoint BA = null;
   KGLPoint BC = null;
   // ベクトルB->A
   BA = KGLPoint.vector(V[B], V[A]);
   // ベクトルB->C
   BC = KGLPoint.vector(V[B], V[C]);
   // 法線の計算
   ret =
       KGLPoint.createXYZ(
           BA.Y() * BC.Z() - BA.Z() * BC.Y(),
           BA.Z() * BC.X() - BA.X() * BC.Z(),
           BA.X() * BC.Y() - BA.Y() * BC.X());
   ret.normalize(); // 正規化
   return ret;
 }
 /**
  * 頂点法線を求める
  *
  * @param mqoObj 読み込んだMQOデータ
  * @return 頂点法線
  */
 protected KGLPoint[] vNormal(objects mqoObj) {
   KGLPoint[] ret = null;
   KGLPoint sn = null;
   // 頂点に接している面の法線を頂点法線に足し込んでいく
   ret = new KGLPoint[mqoObj.vertex.length];
   for (int f = 0; f < mqoObj.face.length; f++) {
     sn = calcNormal(mqoObj.vertex, mqoObj.face[f].V[0], mqoObj.face[f].V[1], mqoObj.face[f].V[2]);
     if (sn == null) continue;
     for (int i = 0; i < 3; i++) {
       if (ret[mqoObj.face[f].V[i]] == null) {
         ret[mqoObj.face[f].V[i]] = KGLPoint.createXYZ(0, 0, 0);
       }
       ret[mqoObj.face[f].V[i]].add(sn);
     }
   }
   // 正規化(長さを求めて、ソレで割って0~1の値にする!)
   for (int v = 0; v < ret.length; v++) {
     if (ret[v] == null) continue;
     ret[v].normalize();
   }
   return ret;
 }