import * as se3 from './se3'; /** Makes a square with constant z = 0. * * Face is oriented towards z+. */ function makeSquare() { const vertices = [ // triangle 0 0.5, 0.5 , 0.0, -0.5, 0.5, 0.0, -0.5, -0.5, 0.0, // triangle 1 0.5, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0, ]; // normals toward z+ const normals = [].concat(...Array(6).fill([0.0, 0.0, 1.0])); const textures = [ 0.99, 0.99, 0.01, 0.99, 0.01, 0.01, 0.99, 0.99, 0.01, 0.01, 0.99, 0.01, ]; return { vertices, normals, textures, }; } function makeZFace(normal, texture, transform) { const textMul = 0.0625; const textOff = texture.map(x => x * textMul); const vertices = []; const textures = []; const sq = makeSquare(); for (let i = 0; i < 6; i++) { vertices.push( se3.product( transform, sq.vertices.slice(3 * i, 3 * (i + 1)).concat([1.0]) ).slice(0, 3)); textures.push(sq.textures.slice(2 * i, 2 * (i + 1)).map((v, j) => textMul * v + textOff[j])); } const normals = [].concat(...Array(6).fill(normal)); return { vertices: [].concat(...vertices), normals, textures: [].concat(...textures), }; } export function makeFace(which, texture, centerPos) { const rot = { '-x': se3.roty(-Math.PI / 2), '+x': se3.roty(Math.PI / 2), '-y': se3.rotx(Math.PI / 2), '+y': se3.rotx(-Math.PI / 2), '-z': se3.roty(Math.PI), '+z': se3.identity(), }[which]; const normal = { '+x': [1.0, 0.0, 0.0], '-x': [-1.0, 0.0, 0.0], '+y': [0.0, 1.0, 0.0], '-y': [0.0, -1.0, 0.0], '+z': [0.0, 0.0, 1.0], '-z': [0.0, 0.0, -1.0], }[which]; const tf = se3.product(se3.translation(...centerPos), rot); return makeZFace(normal, texture, tf); } export function makeBuffersFromFraces(gl, faces) { vertices = [].concat(...faces.map(f => f.vertices)); normals = [].concat(...faces.map(f => f.normals)); textures = [].concat(...faces.map(f => f.textures)); const vertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); const normalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW); const textureBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textures), gl.STATIC_DRAW); return { vertexBuffer, normalBuffer, textureBuffer, numVertices: vertices.length / 3, }; } export function makeGrassCube(gl) { faces = [ makeFace('+y', [0, 15], [0.0, 0.5, 0.0]), makeFace('-y', [2, 15], [0.0, -0.5, 0.0]), makeFace('-x', [1, 15], [-0.5, 0.0, 0.0]), makeFace('+x', [1, 15], [0.5, 0.0, 0.0]), makeFace('-z', [1, 15], [0.0, 0.0, -0.5]), makeFace('+z', [1, 15], [0.0, 0.0, 0.5]), ]; return makeBuffersFromFraces(gl, faces); }