wmc/geometry.js
Paul Mathieu 49e814d1bc A few things
- webgl boilerplate
- shader ambiant + diffuse lighting
- fractal perlin noise chunk generation
- super primitive world generation (stone, dirt, grass blocks)
- WASD controls + mouse pointer capture

On the menu:
- collisions
- gravity
- mine & place
- more stuff
2021-12-08 09:24:19 -08:00

127 lines
3.2 KiB
JavaScript

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);
}