Skip to content

Commit

Permalink
add and remove voxels, rotate camera
Browse files Browse the repository at this point in the history
  • Loading branch information
meeees committed Jan 2, 2020
1 parent cc76233 commit a9a4a32
Show file tree
Hide file tree
Showing 6 changed files with 284 additions and 13 deletions.
18 changes: 18 additions & 0 deletions webgl/helpers.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,22 @@ export function calcNormalMatrix(modelView)
mat4.invert(normalMatrix, modelView);
mat4.transpose(normalMatrix, normalMatrix);
return normalMatrix;
}

export function rgbaToArray(val)
{
return [
(val & 0xff) / 255.0,
(val >> 8 & 0xff) / 255.0,
(val >> 16 & 0xff) / 255.0,
(val >> 24 & 0xff) / 255.0,
];
}

export function arrayToRGBA(arr)
{
return Math.round(arr[0]) |
(Math.round(arr[1]) << 8) |
(Math.round(arr[2]) << 16) |
(Math.round(arr[3]) << 24);
}
4 changes: 4 additions & 0 deletions webgl/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@
import {run} from './webgl.mjs';
run();
</script>
<p>Click to add voxels</p>
<p>Hold alt and click to remove voxels</p>
<p>Scroll to zoom</p>
<p>Press middle mouse and drag to rotate</p>
</body>
</html>
56 changes: 56 additions & 0 deletions webgl/input.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
class InputManager {

static mouseX = 0;
static mouseY = 0;
static middleDown;
static initialize(canvas, addCallback, removeCallback, cameraCallback, zoomCallback)
{
InputManager.mouseX = 0;
InputManager.mouseY = 0;
canvas.addEventListener('mousemove', function(evt) {
var mousePos = InputManager.getMousePos(canvas, evt);
InputManager.mouseX = mousePos.x;
InputManager.mouseY = mousePos.y;
if(InputManager.middleDown)
{
cameraCallback(evt.movementX, evt.movementY);
}
//console.log(mousePos);
});
canvas.addEventListener('mousedown', function(evt) {
if(evt.button == 0)
{
if(evt.altKey)
{
removeCallback();
}
else
{
addCallback();
}
}
else if(evt.button == 1){
InputManager.middleDown = true;
}
});
canvas.addEventListener('mouseup', function(evt) {
if(evt.button == 1)
{
InputManager.middleDown = false;
}
});
canvas.addEventListener('wheel', function(evt) {
zoomCallback(evt.deltaY);
})
}

static getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: rect.height - (evt.clientY - rect.top)
};
}
}

export {InputManager}
7 changes: 6 additions & 1 deletion webgl/shaders.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ const vertShader = `#version 300 es
in vec4 aVertexPosition;
in vec3 aVertexNormal;
in vec2 aTextureCoord;
in vec4 aFaceColor;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
uniform mat4 uNormalMatrix;
out highp vec3 vLighting;
out highp vec2 vTextureCoord;
out highp vec4 vFaceColor;
void main() {
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
Expand All @@ -23,6 +25,7 @@ const vertShader = `#version 300 es
highp float directional = max(dot(transformedNormal.xyz, directionalVector), 0.0);
vLighting = ambientLight + (directionalLightColor * directional);
vTextureCoord = aTextureCoord;
vFaceColor = aFaceColor;
}
`;

Expand All @@ -31,6 +34,7 @@ const fragShader = `#version 300 es
in highp vec3 vLighting;
in highp vec2 vTextureCoord;
in highp vec4 vFaceColor;
uniform sampler2D uSampler;
Expand All @@ -39,7 +43,7 @@ const fragShader = `#version 300 es
void main() {
color = texture(uSampler, vTextureCoord) * vec4(vLighting, 1.0);
collision = texture(uSampler, vTextureCoord);
collision = vFaceColor;
}
`;

Expand Down Expand Up @@ -73,6 +77,7 @@ export function initPrograms(gl) {
vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
vertexTextureCoord: gl.getAttribLocation(shaderProgram, 'aTextureCoord'),
vertexNormal: gl.getAttribLocation(shaderProgram, 'aVertexNormal'),
faceColor: gl.getAttribLocation(shaderProgram, 'aFaceColor'),
},
uniformLocations: {
projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'),
Expand Down
89 changes: 86 additions & 3 deletions webgl/voxels.mjs
Original file line number Diff line number Diff line change
@@ -1,21 +1,78 @@
import {bindFloatBuffer, makeColorTexture, calcModelView, calcNormalMatrix} from './helpers.mjs';
import {bindFloatBuffer, makeColorTexture,
calcModelView, calcNormalMatrix,
rgbaToArray, arrayToRGBA}
from './helpers.mjs';

var voxelCount = 0;

class Voxel {

constructor(gl, x, y, z, col) {
static voxelMap = {}
// maps to the block in front of the indexed face
// front, back, top, bottom, right, left
static faceMappings = [[0, 0, 1], [0, 0, -1], [0, 1, 0], [0, -1, 0], [1, 0, 0], [-1, 0, 0]];

// optionally be a ghost voxel, will stop the voxel from being put into the map for collision
constructor(gl, x, y, z, col, ghost=false) {
this.pos = [x, y, z];
this.texture = makeColorTexture(gl, new Uint8Array(col));
this.ghost = ghost;
if(!this.ghost)
{
this.voxelIndex = voxelCount;
Voxel.voxelMap[this.voxelIndex] = this;
voxelCount += 1;

const baseCol = 1 + this.voxelIndex * 6;
const faceCols = [baseCol, baseCol + 1, baseCol + 2, baseCol + 3, baseCol + 4, baseCol + 5];
var faceColArray = [];
for(var i = 0; i < faceCols.length; i++)
{
var val = rgbaToArray(faceCols[i]);
val[3] = 1.0;
faceColArray = faceColArray.concat(val, val, val, val);
}
}
else
{
this.voxelIndex = -1;
const baseCol = 1;
const faceCols = [baseCol, baseCol + 1, baseCol + 2, baseCol + 3, baseCol + 4, baseCol + 5];
var faceColArray = [];
for(var i = 0; i < faceCols.length; i++)
{
var val = rgbaToArray(faceCols[i]);
val[3] = 0.0;
faceColArray = faceColArray.concat(val, val, val, val);
}
}


const faceColBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, faceColBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(faceColArray), gl.STATIC_DRAW);
this.faceColors = faceColBuffer;
}

drawVoxel(gl, programInfo)
{
const modelViewMatrix = calcModelView(this.pos, [0, 0, 0]);
var modelViewMatrix;
// shrink ghost view a little so it doesn't clip
if(!this.ghost)
{
modelViewMatrix = calcModelView(this.pos, [0, 0, 0]);
}
else
{
modelViewMatrix = calcModelView(this.pos, [0, 0, 0], [0.9, 0.9, 0.9]);
}
const normalMatrix = calcNormalMatrix(modelViewMatrix);

gl.uniformMatrix4fv(programInfo.uniformLocations.modelViewMatrix, false, modelViewMatrix);
gl.uniformMatrix4fv(programInfo.uniformLocations.normalMatrix, false, normalMatrix);
gl.bindTexture(gl.TEXTURE_2D, this.texture);

bindFloatBuffer(gl, this.faceColors, programInfo.attribLocations.faceColor, 4);
{
const offset = 0;
const vertexCount = 36;
Expand All @@ -24,6 +81,12 @@ class Voxel {
}

}

destroyVoxel()
{
delete Voxel.voxelMap[this.voxelIndex];
}

static setupVoxelDrawing(gl, programInfo, projectionMatrix, buffers)
{
gl.useProgram(programInfo.program);
Expand Down Expand Up @@ -161,6 +224,26 @@ class Voxel {
textureCoord: textureBuffer,
};
}

static getVoxelByCol(rgba)
{
// zero out the alpha channel
rgba[3] = 0;
const val = arrayToRGBA(rgba) - 1;
if(val == -1)
{
return null;
}
const index = Math.trunc(val / 6);
const face = val % 6;
const voxel = Voxel.voxelMap[index];
const targeted = Voxel.faceMappings[face];
return {
voxel: voxel,
face: face,
targetedSpace: [voxel.pos[0] + targeted[0], voxel.pos[1] + targeted[1], voxel.pos[2] + targeted[2]],
}
}
}

export {Voxel}
Loading

0 comments on commit a9a4a32

Please sign in to comment.