src/gl/S3GLTriangleIndexData.js
import S3Vector from "../math/S3Vector.js";
import S3GLTriangleIndex from "./S3GLTriangleIndex.js";
import S3GLArray from "./S3GLArray.js";
import S3GLVertex from "./S3GLVertex.js";
/**
* WebGL描画用の三角形インデックス・属性データ格納クラス。
* 三角形ごとの頂点インデックス・UV・法線・接線・従法線などを保持し、
* WebGL(GLSL)用に最適化されたデータ生成やハッシュ作成も担います。
*
* @class
* @module S3
*/
export default class S3GLTriangleIndexData {
/**
* 三角形インデックス情報からGL用データ構造を生成します。
* @param {S3GLTriangleIndex} triangle_index S3GLTriangleIndexなどの三角形インデックス情報
*/
constructor(triangle_index) {
/**
* 各頂点を示すインデックス配列
* @type {number[]}
*/
this.index = triangle_index.index;
/**
* 面が使用するマテリアル番号
* @type {number}
*/
this.materialIndex = triangle_index.materialIndex;
/**
* 各頂点のUV座標(S3Vectorの配列)
* @type {Array<S3Vector>}
*/
this.uv = triangle_index.uv;
/**
* UV情報が有効かどうか
* @type {boolean}
*/
this._isEnabledTexture = triangle_index.uv[0] !== null;
/**
* 面(フェース)単位の属性情報型。
* S3Vector.getTangentVector で計算された面の法線・接線・従法線(すべてS3Vector型またはnull)。
*
* @typedef {Object} S3GLFaceAttribute
* @property {?S3Vector} normal 面の法線ベクトル
* @property {?S3Vector} tangent 面の接線ベクトル
* @property {?S3Vector} binormal 面の従法線ベクトル
*/
/**
* 頂点単位の属性情報型。
* 各頂点(3つ)の法線・接線・従法線(いずれもS3Vector型またはnull)の配列。
*
* @typedef {Object} S3GLVertexAttribute
* @property {Array<?S3Vector>} normal 各頂点の法線ベクトル [0], [1], [2]
* @property {Array<?S3Vector>} tangent 各頂点の接線ベクトル [0], [1], [2]
* @property {Array<?S3Vector>} binormal 各頂点の従法線ベクトル [0], [1], [2]
*/
/**
* 面の法線・接線・従法線
* @type {S3GLFaceAttribute}
*/
this.face = {
normal: null,
tangent: null,
binormal: null
};
/**
* 各頂点(3つ)の法線・接線・従法線の配列
* @type {S3GLVertexAttribute}
*/
this.vertex = {
normal: [null, null, null],
tangent: [null, null, null],
binormal: [null, null, null]
};
}
/**
* この三角形の、指定頂点(number番目)についてWebGL用一意ハッシュ値を生成します。
* 頂点情報・UV・法線などを元にGLバッファのキャッシュや識別に使えます。
* @param {number} number 三角形の頂点番号(0, 1, 2)
* @param {Array<S3GLVertex>} vertexList 全頂点配列
* @returns {string} 頂点+属性を加味したハッシュ文字列
*/
getGLHash(number, vertexList) {
const uvdata = this._isEnabledTexture
? this.uv[number].toString(2) + this.face.binormal.toString(2) + this.face.tangent.toString(2)
: "";
const vertex = vertexList[this.index[number]].getGLHash();
return vertex + this.materialIndex + uvdata + this.vertex.normal[number].toString(3);
}
/**
* 指定頂点のWebGL向け頂点属性データ(GLSL用attribute名に合わせたデータ群)を返します。
* 位置・マテリアル番号・UV・法線・接線・従法線などがGLArray形式で格納されます。
*
* - vertexPosition: 頂点位置(vec3)
* - vertexTextureCoord: UV座標(vec2)
* - vertexMaterialFloat: マテリアル番号(float)
* - vertexNormal: 法線ベクトル(vec3)
* - vertexBinormal: 従法線ベクトル(vec3)
* - vertexTangent: 接線ベクトル(vec3)
*
* @param {number} number 三角形内の何番目の頂点データを取得するか(0, 1, 2)
* @param {Array<S3GLVertex>} vertexList 頂点の配列
* @returns {{[key: string]: S3GLArray}}
*/
getGLData(number, vertexList) {
/**
* @type {{[key: string]: S3GLArray}}
*/
const vertex = {};
const vertexdata_list = vertexList[this.index[number]].getGLData();
for (const key in vertexdata_list) {
vertex[key] = vertexdata_list[key];
}
const uvdata = this._isEnabledTexture ? this.uv[number] : new S3Vector(0.0, 0.0);
vertex.vertexTextureCoord = new S3GLArray(uvdata, 2, S3GLArray.datatype.Float32Array);
vertex.vertexMaterialFloat = new S3GLArray(this.materialIndex, 1, S3GLArray.datatype.Float32Array);
vertex.vertexNormal = new S3GLArray(this.vertex.normal[number], 3, S3GLArray.datatype.Float32Array);
vertex.vertexBinormal = new S3GLArray(this.vertex.binormal[number], 3, S3GLArray.datatype.Float32Array);
vertex.vertexTangent = new S3GLArray(this.vertex.tangent[number], 3, S3GLArray.datatype.Float32Array);
return vertex;
}
}