forked from mirror/ObjToSchematic
Added buffer.js
This commit is contained in:
parent
7aa6e82f3d
commit
a348ba4e23
143
src/buffer.js
Normal file
143
src/buffer.js
Normal file
@ -0,0 +1,143 @@
|
||||
const twgl = require('twgl.js');
|
||||
|
||||
class SegmentedBuffer {
|
||||
|
||||
constructor(bufferSize, attributes) {
|
||||
this._bufferSize = bufferSize;
|
||||
this._completeBuffers = [];
|
||||
|
||||
this._compiled = false;
|
||||
this.compiledBuffers = [];
|
||||
|
||||
this._attributes = {};
|
||||
for (const attr of attributes) {
|
||||
this._attributes[attr.name] = {
|
||||
numComponents: attr.numComponents
|
||||
};
|
||||
}
|
||||
|
||||
this._insertIndex = 0;
|
||||
this._maxIndex = 0;
|
||||
|
||||
this._getNewBuffer();
|
||||
}
|
||||
|
||||
_getNewBuffer() {
|
||||
this._buffer = {
|
||||
indices: {
|
||||
numComponents: 1,
|
||||
data: new Uint16Array(this._bufferSize),
|
||||
}
|
||||
};
|
||||
for (const attr in this._attributes) {
|
||||
this._buffer[attr] = {
|
||||
numComponents: this._attributes[attr].numComponents,
|
||||
data: new Float32Array(this._bufferSize * this._attributes[attr].numComponents)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
_cycle() {
|
||||
|
||||
this._completeBuffers.push({
|
||||
buffer: this._buffer,
|
||||
numElements: this._insertIndex,
|
||||
});
|
||||
this._getNewBuffer();
|
||||
this._maxIndex = 0;
|
||||
this._insertIndex = 0;
|
||||
}
|
||||
|
||||
_willOverflow(data) {
|
||||
// Check for indices Uint16 overflow
|
||||
const dataMaxIndex = Math.max(...data.indices);
|
||||
let willOverflow = (this._maxIndex + dataMaxIndex) > 65535;
|
||||
if ((this._maxIndex + dataMaxIndex) > 65535) {
|
||||
console.log("index overflow");
|
||||
}
|
||||
|
||||
const sizeAdding = data.indices.length;
|
||||
willOverflow |= (this._insertIndex + sizeAdding > this._bufferSize);
|
||||
if (this._insertIndex + sizeAdding > this._bufferSize) {
|
||||
console.log("length overflow");
|
||||
}
|
||||
|
||||
if (sizeAdding > this._bufferSize) {
|
||||
throw "Data length too large, add in chunks smaller than buffer size";
|
||||
}
|
||||
|
||||
return willOverflow;
|
||||
}
|
||||
|
||||
_checkDataMatchesAttributes(data) {
|
||||
if (!('indices'in data)) {
|
||||
throw `Given data does not have indices data`;
|
||||
}
|
||||
const setsRequired = Math.max(...data.indices) + 1;
|
||||
for (const attr in this._attributes) {
|
||||
if (!(attr in data)) {
|
||||
throw `Given data does not have ${attr} data`;
|
||||
}
|
||||
if (data[attr].length % this._attributes[attr].numComponents != 0) {
|
||||
throw `Not enough/too much ${attr} data given`;
|
||||
}
|
||||
const numSets = data[attr].length / this._attributes[attr].numComponents;
|
||||
if (numSets != setsRequired) {
|
||||
//throw `Number of indices does not match number of ${attr} components given`;
|
||||
throw `Expected ${setsRequired * this._attributes[attr].numComponents} values for ${attr}, got ${data[attr].length}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_addDataToAttribute(attr, attr_data) {
|
||||
const indexOffset = this._insertIndex * this._attributes[attr].numComponents;
|
||||
for (let i = 0; i < attr_data.length; ++i) {
|
||||
this._buffer[attr].data[i + indexOffset] = attr_data[i];
|
||||
}
|
||||
}
|
||||
|
||||
add(data) {
|
||||
this._checkDataMatchesAttributes(data);
|
||||
|
||||
if (this._willOverflow(data)) {
|
||||
this._cycle();
|
||||
}
|
||||
|
||||
if (this._compiled) {
|
||||
throw "Buffer already compiled, cannot add more data";
|
||||
}
|
||||
|
||||
for (let i = 0; i < data.indices.length; ++i) {
|
||||
this._buffer.indices.data[i + this._insertIndex] = data.indices[i] + this._maxIndex;
|
||||
}
|
||||
//this._insertIndex += data.indices.length;
|
||||
const dataMaxIndex = Math.max(...data.indices);
|
||||
this._maxIndex += 1 + dataMaxIndex;
|
||||
|
||||
for (const attr in this._attributes) {
|
||||
this._addDataToAttribute(attr, data[attr]);
|
||||
}
|
||||
this._insertIndex += data.indices.length;
|
||||
}
|
||||
|
||||
compile(gl) {
|
||||
if (this._compiled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._cycle();
|
||||
|
||||
this.compiledBuffers = new Array(this._completeBuffers.length);
|
||||
for (let i = 0; i < this._completeBuffers.length; ++i) {
|
||||
this.compiledBuffers[i] = {
|
||||
buffer: twgl.createBufferInfoFromArrays(gl, this._completeBuffers[i].buffer),
|
||||
numElements: this._completeBuffers[i].numElements
|
||||
};
|
||||
}
|
||||
|
||||
this._compiled = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports.SegmentedBuffer = SegmentedBuffer;
|
@ -7,9 +7,16 @@ const { Schematic } = require('./src/schematic.js');
|
||||
const dialog = require('electron').remote.dialog;
|
||||
|
||||
const voxelSize = document.querySelector("#voxelInput").value;
|
||||
let renderer = new Renderer(voxelSize);
|
||||
const voxelManager = new VoxelManager(voxelSize);
|
||||
let renderer = new Renderer(30, new Vector3(0.1, 0.1, 0.1));
|
||||
|
||||
const mesh = new Mesh('./resources/suzanne.obj');
|
||||
|
||||
renderer.setDebug(true);
|
||||
renderer.registerMesh(mesh);
|
||||
renderer.compile();
|
||||
|
||||
|
||||
const voxelManager = new VoxelManager(voxelSize);
|
||||
const canvas = document.querySelector("#c");
|
||||
|
||||
let loadedMesh = null;
|
||||
@ -172,8 +179,7 @@ $(document).resize(function() {
|
||||
});
|
||||
|
||||
function render(time) {
|
||||
renderer.begin();
|
||||
renderer.end();
|
||||
renderer.draw();
|
||||
|
||||
requestAnimationFrame(render);
|
||||
}
|
||||
|
92
src/geometry.js
Normal file
92
src/geometry.js
Normal file
@ -0,0 +1,92 @@
|
||||
const twgl = require('twgl.js');
|
||||
const { Vector3 } = require('./vector.js');
|
||||
|
||||
const default_cube = twgl.primitives.createCubeVertices(1.0);
|
||||
|
||||
class GeometryTemplates {
|
||||
|
||||
static getTriangleBufferData(triangle, debug) {
|
||||
const a = triangle.v0;
|
||||
const b = triangle.v1;
|
||||
const c = triangle.v2;
|
||||
const n = triangle.normal;
|
||||
|
||||
if (debug) {
|
||||
return {
|
||||
position: [
|
||||
a.x, a.y, a.z,
|
||||
b.x, b.y, b.z,
|
||||
c.x, c.y, c.z,
|
||||
],
|
||||
indices: [
|
||||
0, 1,
|
||||
1, 2,
|
||||
2, 0
|
||||
]
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
position: [
|
||||
a.x, a.y, a.z,
|
||||
b.x, b.y, b.z,
|
||||
c.x, c.y, c.z,
|
||||
],
|
||||
normal: [
|
||||
n.x, n.y, n.z,
|
||||
n.x, n.y, n.z,
|
||||
n.x, n.y, n.z
|
||||
],
|
||||
indices: [
|
||||
0, 1, 2
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static getBoxBufferData(centre, size, debug) {
|
||||
const a = Vector3.sub(centre, Vector3.mulScalar(size, 0.5));
|
||||
const b = Vector3.add(centre, Vector3.mulScalar(size, 0.5));
|
||||
|
||||
if (debug) {
|
||||
return {
|
||||
position: [
|
||||
a.x, a.y, a.z,
|
||||
b.x, a.y, a.z,
|
||||
b.x, b.y, a.z,
|
||||
a.x, b.y, a.z,
|
||||
a.x, a.y, b.z,
|
||||
b.x, a.y, b.z,
|
||||
b.x, b.y, b.z,
|
||||
a.x, b.y, b.z
|
||||
],
|
||||
indices: [
|
||||
0, 1, 1, 2, 2, 3, 3, 0,
|
||||
4, 5, 5, 6, 6, 7, 7, 4,
|
||||
0, 4, 1, 5, 2, 6, 3, 7
|
||||
]
|
||||
};
|
||||
} else {
|
||||
|
||||
let cube = {
|
||||
position: new Float32Array(72),
|
||||
normal: new Float32Array(72),
|
||||
indices: new Float32Array(72)
|
||||
};
|
||||
|
||||
cube.position.set(default_cube.position);
|
||||
cube.normal.set(default_cube.normal);
|
||||
cube.indices.set(default_cube.indices);
|
||||
|
||||
for (let i = 0; i < 72; i += 3) {
|
||||
cube.position[i + 0] = (cube.position[i + 0] * size.x) + centre.x;
|
||||
cube.position[i + 1] = (cube.position[i + 1] * size.y) + centre.y;
|
||||
cube.position[i + 2] = (cube.position[i + 2] * size.z) + centre.z;
|
||||
}
|
||||
|
||||
return cube;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports.GeometryTemplates = GeometryTemplates;
|
34
src/math.js
34
src/math.js
@ -1,32 +1,16 @@
|
||||
// Not apart of rendering, SIMD optimisation not necessary
|
||||
const { Vector3 } = require('./vector.js');
|
||||
|
||||
/*
|
||||
function roundTo(value, base) {
|
||||
return Math.round(value / base) * base;
|
||||
/**
|
||||
* Retrieve the array key corresponding to the largest element in the array.
|
||||
*
|
||||
* @param {Array.<number>} array Input array
|
||||
* @return {number} Index of array element with largest value
|
||||
*/
|
||||
function argMax(array) {
|
||||
return array.map((x, i) => [x, i]).reduce((r, a) => (a[0] > r[0] ? a : r))[1];
|
||||
}
|
||||
|
||||
function floorTo(value, base) {
|
||||
return Math.floor(value / base) * base;
|
||||
}
|
||||
|
||||
function ceilTo(value, base) {
|
||||
return Math.ceil(value / base) * base;
|
||||
}
|
||||
|
||||
function fastDotXAxis(vec) {
|
||||
return vec[0];
|
||||
}
|
||||
|
||||
function fastDotYAxis(vec) {
|
||||
return vec[1];
|
||||
}
|
||||
|
||||
function fastDotZAxis(vec) {
|
||||
return vec[2];
|
||||
}
|
||||
*/
|
||||
|
||||
function fastCrossXAxis(vec) {
|
||||
return new Vector3(0.0, -vec.z, vec.y);
|
||||
}
|
||||
@ -65,4 +49,6 @@ module.exports.xAxis = new Vector3(1.0, 0.0, 0.0);
|
||||
module.exports.yAxis = new Vector3(0.0, 1.0, 0.0);
|
||||
module.exports.zAxis = new Vector3(0.0, 0.0, 1.0);
|
||||
|
||||
module.exports.argMax = argMax;
|
||||
|
||||
//module.exports.roundVector3To = roundVector3To;
|
468
src/renderer.js
468
src/renderer.js
@ -4,53 +4,133 @@ const { Vector3 } = require('./vector.js');
|
||||
const { ArcballCamera } = require('./camera.js');
|
||||
const mouseManager = require('./mouse.js');
|
||||
const shaderManager = require('./shaders.js');
|
||||
const { SegmentedBuffer } = require('./buffer.js');
|
||||
const { GeometryTemplates } = require('./geometry.js');
|
||||
|
||||
class Renderer {
|
||||
|
||||
constructor(voxelSize) {
|
||||
this._gl = document.querySelector("#c").getContext("webgl");
|
||||
|
||||
this._fov = 30;
|
||||
this._backgroundColour = new Vector3(0.1, 0.1, 0.1);
|
||||
constructor(fov, backgroundColour) {
|
||||
this._backgroundColour = backgroundColour;
|
||||
this._strokeColour = new Vector3(1.0, 1.0, 1.0);
|
||||
|
||||
this._camera = new ArcballCamera(this._fov, this._gl.canvas.clientWidth / this._gl.canvas.clientHeight, 0.5, 100.0);
|
||||
|
||||
this._gl = document.querySelector("#c").getContext("webgl");
|
||||
this._camera = new ArcballCamera(fov, this._gl.canvas.clientWidth / this._gl.canvas.clientHeight, 0.5, 100.0);
|
||||
|
||||
this._registerEvents();
|
||||
|
||||
this._debugRegister = this._getEmptyDebugRegister();
|
||||
this._register = this._getEmptyRegister();
|
||||
this._debugRegister = new SegmentedBuffer(2048, [{name: 'position', numComponents: 3}, {name: 'colour', numComponents: 3}]);
|
||||
this._register = new SegmentedBuffer(2048, [{name: 'position', numComponents: 3}, {name: 'normal', numComponents: 3}]);
|
||||
|
||||
this._filledDebugRegisters = [];
|
||||
this._filledRegisters = [];
|
||||
|
||||
this._registerBuffers = [];
|
||||
this._debugRegisterBuffers = [];
|
||||
|
||||
this._debugMaxIndex = 0;
|
||||
this._maxIndex = 0;
|
||||
|
||||
this._voxelSize = voxelSize;
|
||||
this._voxelSizeVector = new Vector3(voxelSize, voxelSize, voxelSize);
|
||||
this._cube = twgl.primitives.createCubeVertices(1.0);
|
||||
|
||||
this._registersOpen = true;
|
||||
this._debug = false;
|
||||
this._compiled = false;
|
||||
}
|
||||
|
||||
_getEmptyDebugRegister() {
|
||||
return {
|
||||
position: {numComponents: 3, data: []},
|
||||
colour: {numComponents: 3, data: []},
|
||||
indices: {numComponents: 3, data: []}
|
||||
};
|
||||
|
||||
compile() {
|
||||
this._debugRegister.compile(this._gl);
|
||||
this._register.compile(this._gl);
|
||||
this._compiled = true;
|
||||
}
|
||||
|
||||
_getEmptyRegister() {
|
||||
return {
|
||||
position: {numComponents: 3, data: []},
|
||||
normal: {numComponents: 3, data: []},
|
||||
indices: {numComponents: 3, data: []},
|
||||
setStroke(colour) {
|
||||
this._strokeColour = colour;
|
||||
}
|
||||
|
||||
setDebug(debug) {
|
||||
this._debug = debug;
|
||||
}
|
||||
|
||||
draw() {
|
||||
if (!this._compiled) {
|
||||
this.compile();
|
||||
return;
|
||||
}
|
||||
|
||||
this._setupScene();
|
||||
|
||||
this._drawDebugRegisters();
|
||||
this._drawRegisters();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
_drawDebugRegisters() {
|
||||
const debugUniforms = {
|
||||
u_worldViewProjection: this._camera.getWorldViewProjection(),
|
||||
};
|
||||
|
||||
for (const buffer of this._debugRegister.compiledBuffers) {
|
||||
this._drawBuffer(this._gl.LINES, buffer, shaderManager.debugProgram, debugUniforms);
|
||||
}
|
||||
}
|
||||
|
||||
_drawRegisters() {
|
||||
const uniforms = {
|
||||
u_lightWorldPos: this._camera.getCameraPosition(0.0, 0.0),
|
||||
u_worldViewProjection: this._camera.getWorldViewProjection(),
|
||||
u_worldInverseTranspose: this._camera.getWorldInverseTranspose()
|
||||
};
|
||||
|
||||
for (const buffer of this._register.compiledBuffers) {
|
||||
this._drawBuffer(this._gl.TRIANGLES, buffer, shaderManager.shadedProgram, uniforms);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
registerBox(centre, size) {
|
||||
const data = GeometryTemplates.getBoxBufferData(centre, size, this._debug);
|
||||
this._registerData(data);
|
||||
}
|
||||
|
||||
registerTriangle(triangle) {
|
||||
const data = GeometryTemplates.getTriangleBufferData(triangle, this._debug);
|
||||
this._registerData(data);
|
||||
}
|
||||
|
||||
registerMesh(mesh) {
|
||||
for (const triangle of mesh.triangles) {
|
||||
this.registerTriangle(triangle);
|
||||
}
|
||||
}
|
||||
|
||||
registerVoxelMesh(voxelManager) {
|
||||
const mesh = voxelManager.buildMesh();
|
||||
for (const box of mesh) {
|
||||
this.registerBox(box.centre, box.size, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
_registerData(data) {
|
||||
if (this._debug) {
|
||||
const numVertices = data.position.length / 3;
|
||||
data.colour = [].concat(...new Array(numVertices).fill(this._strokeColour.toArray()));
|
||||
this._debugRegister.add(data);
|
||||
} else {
|
||||
this._register.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
_setupScene() {
|
||||
twgl.resizeCanvasToDisplaySize(this._gl.canvas);
|
||||
this._gl.viewport(0, 0, this._gl.canvas.width, this._gl.canvas.height);
|
||||
this._camera.aspect = this._gl.canvas.width / this._gl.canvas.height;
|
||||
//this._gl.blendFuncSeparate(this._gl.SRC_ALPHA, this._gl.ONE_MINUS_SRC_ALPHA, this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
this._gl.enable(this._gl.DEPTH_TEST);
|
||||
this._gl.enable(this._gl.CULL_FACE);
|
||||
//this._gl.enable(this._gl.BLEND);
|
||||
this._gl.clearColor(this._backgroundColour.x, this._backgroundColour.y, this._backgroundColour.z, 1);
|
||||
this._gl.clear(this._gl.COLOR_BUFFER_BIT | this._gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
this._camera.updateCameraPosition();
|
||||
}
|
||||
|
||||
_registerEvents() {
|
||||
@ -72,331 +152,13 @@ class Renderer {
|
||||
});
|
||||
}
|
||||
|
||||
begin() {
|
||||
twgl.resizeCanvasToDisplaySize(this._gl.canvas);
|
||||
this._gl.viewport(0, 0, this._gl.canvas.width, this._gl.canvas.height);
|
||||
this._camera.aspect = this._gl.canvas.width / this._gl.canvas.height;
|
||||
this._gl.blendFuncSeparate(this._gl.SRC_ALPHA, this._gl.ONE_MINUS_SRC_ALPHA, this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
this._gl.enable(this._gl.DEPTH_TEST);
|
||||
this._gl.enable(this._gl.CULL_FACE);
|
||||
//this._gl.enable(this._gl.BLEND);
|
||||
this._gl.clearColor(this._backgroundColour.x, this._backgroundColour.y, this._backgroundColour.z, 1);
|
||||
this._gl.clear(this._gl.COLOR_BUFFER_BIT | this._gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
this._camera.updateCameraPosition();
|
||||
}
|
||||
|
||||
compileRegister() {
|
||||
this._cycleRegister();
|
||||
this._cycleDebugRegister();
|
||||
|
||||
//console.log(this._debug);
|
||||
|
||||
for (const register of this._filledRegisters) {
|
||||
this._registerBuffers.push(twgl.createBufferInfoFromArrays(this._gl, register));
|
||||
}
|
||||
for (const debugRegister of this._filledDebugRegisters) {
|
||||
this._debugRegisterBuffers.push(twgl.createBufferInfoFromArrays(this._gl, debugRegister));
|
||||
}
|
||||
//this._debugRegisterBuffer = twgl.createBufferInfoFromArrays(this._gl, this._debugRegister);
|
||||
//this._registerBuffer = twgl.createBufferInfoFromArrays(this._gl, this._register);
|
||||
this._registersOpen = false;
|
||||
}
|
||||
|
||||
setStroke(colour) {
|
||||
this._strokeColour = colour;
|
||||
}
|
||||
|
||||
end() {
|
||||
if (this._registersOpen) {
|
||||
//console.error("Trying to draw register objects before register is closed. Call compileRegister() first.");
|
||||
return;
|
||||
}
|
||||
|
||||
this._drawDebugRegisters();
|
||||
this._drawRegisters();
|
||||
}
|
||||
|
||||
clear() {
|
||||
//console.log("clearing");
|
||||
|
||||
this._debugRegister = this._getEmptyDebugRegister();
|
||||
this._register = this._getEmptyRegister();
|
||||
|
||||
this._filledDebugRegisters = [];
|
||||
this._filledRegisters = [];
|
||||
|
||||
this._registerBuffers = [];
|
||||
this._debugRegisterBuffers = [];
|
||||
|
||||
this._debugMaxIndex = 0;
|
||||
this._maxIndex = 0;
|
||||
|
||||
this._registersOpen = true;
|
||||
}
|
||||
|
||||
setVoxelSize(voxelSize) {
|
||||
this._voxelSize = voxelSize;
|
||||
this._voxelSizeVector = new Vector3(voxelSize, voxelSize, voxelSize);
|
||||
}
|
||||
|
||||
_drawDebugRegisters() {
|
||||
const uniforms = {
|
||||
u_worldViewProjection: this._camera.getWorldViewProjection()
|
||||
};
|
||||
|
||||
for (const debugBuffer of this._debugRegisterBuffers) {
|
||||
this._drawBuffer(this._gl.LINES, debugBuffer, shaderManager.debugProgram, uniforms);
|
||||
}
|
||||
}
|
||||
|
||||
_drawRegisters() {
|
||||
const uniforms = {
|
||||
u_lightWorldPos: this._camera.getCameraPosition(0.0, 0.0),
|
||||
//u_lightWorldPos: new Vector3(4, 2, 1).normalise().toArray(),
|
||||
u_worldViewProjection: this._camera.getWorldViewProjection(),
|
||||
u_worldInverseTranspose: this._camera.getWorldInverseTranspose()
|
||||
};
|
||||
|
||||
for (const buffer of this._registerBuffers) {
|
||||
this._drawBuffer(this._gl.TRIANGLES, buffer, shaderManager.shadedProgram, uniforms);
|
||||
}
|
||||
}
|
||||
|
||||
_drawBuffer(drawMode, buffer, shader, uniforms) {
|
||||
this._gl.useProgram(shader.program);
|
||||
twgl.setBuffersAndAttributes(this._gl, shader, buffer);
|
||||
twgl.setBuffersAndAttributes(this._gl, shader, buffer.buffer);
|
||||
twgl.setUniforms(shader, uniforms);
|
||||
this._gl.drawElements(drawMode, buffer.numElements, this._gl.UNSIGNED_SHORT, 0);
|
||||
}
|
||||
|
||||
_getBoxData(centre, size, debug) {
|
||||
const a = Vector3.sub(centre, Vector3.mulScalar(size, 0.5));
|
||||
const b = Vector3.add(centre, Vector3.mulScalar(size, 0.5));
|
||||
|
||||
if (debug) {
|
||||
return {
|
||||
position: [
|
||||
a.x, a.y, a.z,
|
||||
b.x, a.y, a.z,
|
||||
b.x, b.y, a.z,
|
||||
a.x, b.y, a.z,
|
||||
a.x, a.y, b.z,
|
||||
b.x, a.y, b.z,
|
||||
b.x, b.y, b.z,
|
||||
a.x, b.y, b.z
|
||||
],
|
||||
indices: [
|
||||
0, 1, 1, 2, 2, 3, 3, 0,
|
||||
4, 5, 5, 6, 6, 7, 7, 4,
|
||||
0, 4, 1, 5, 2, 6, 3, 7
|
||||
]
|
||||
};
|
||||
} else {
|
||||
|
||||
let cube = {
|
||||
position: new Float32Array(72),
|
||||
normal: new Float32Array(72),
|
||||
indices: new Float32Array(72)
|
||||
};
|
||||
|
||||
cube.position.set(this._cube.position);
|
||||
cube.normal.set(this._cube.normal);
|
||||
cube.indices.set(this._cube.indices);
|
||||
|
||||
for (let i = 0; i < 72; i += 3) {
|
||||
cube.position[i + 0] = (cube.position[i + 0] * size.x) + centre.x;
|
||||
cube.position[i + 1] = (cube.position[i + 1] * size.y) + centre.y;
|
||||
cube.position[i + 2] = (cube.position[i + 2] * size.z) + centre.z;
|
||||
}
|
||||
|
||||
return cube;
|
||||
}
|
||||
}
|
||||
|
||||
_getTriangleData(triangle, debug) {
|
||||
|
||||
const a = triangle.v0;
|
||||
const b = triangle.v1;
|
||||
const c = triangle.v2;
|
||||
const n = triangle.normal;
|
||||
|
||||
if (debug) {
|
||||
return {
|
||||
position: [
|
||||
a.x, a.y, a.z,
|
||||
b.x, b.y, b.z,
|
||||
c.x, c.y, c.z,
|
||||
],
|
||||
indices: [
|
||||
0, 1,
|
||||
1, 2,
|
||||
2, 0
|
||||
]
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
position: [
|
||||
a.x, a.y, a.z,
|
||||
b.x, b.y, b.z,
|
||||
c.x, c.y, c.z,
|
||||
],
|
||||
normal: [
|
||||
n.x, n.y, n.z,
|
||||
n.x, n.y, n.z,
|
||||
n.x, n.y, n.z
|
||||
],
|
||||
indices: [
|
||||
0, 1, 2
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Use when immediate drawing
|
||||
drawBox(centre, size) {
|
||||
const data = this._getBoxData(centre, size);
|
||||
this._drawData(data);
|
||||
}
|
||||
|
||||
// Use when immediate drawing
|
||||
drawTriangle(a, b, c) {
|
||||
const data = this._getTriangleData(a, b, c);
|
||||
this._drawData(data);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// Use when drawing the same thing each frame
|
||||
registerBox(centre, size, debug) {
|
||||
const data = this._getBoxData(centre, size, debug);
|
||||
//console.log(data);
|
||||
this._addDataToRegister(data, debug);
|
||||
}
|
||||
|
||||
// Use when drawing the same triangle each frame
|
||||
/*
|
||||
registerTriangle(a, b, c) {
|
||||
const data = this._getTriangleData(a, b, c);
|
||||
this._addDataToRegister(data);
|
||||
}*/
|
||||
|
||||
registerMesh(mesh) {
|
||||
for (const triangle of mesh.triangles) {
|
||||
this.registerTriangle(triangle, false);
|
||||
}
|
||||
}
|
||||
|
||||
registerVoxelMesh(voxelManager, useMeshing) {
|
||||
if (useMeshing) {
|
||||
const mesh = voxelManager.buildMesh();
|
||||
for (const box of mesh) {
|
||||
this.registerBox(box.centre, box.size, false);
|
||||
}
|
||||
} else {
|
||||
for (const voxel of voxelManager.voxels) {
|
||||
this.registerVoxel(voxel, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerTriangle(triangle, debug) {
|
||||
const data = this._getTriangleData(triangle, debug);
|
||||
this._addDataToRegister(data, debug);
|
||||
}
|
||||
|
||||
registerVoxel(centre, debug) {
|
||||
const data = this._getBoxData(centre, this._voxelSizeVector, debug);
|
||||
this._addDataToRegister(data, debug);
|
||||
}
|
||||
|
||||
registerVoxels(voxelCentres, debug) {
|
||||
/*
|
||||
for (let i = 0; i < voxelCentres.length; ++i) {
|
||||
console.log(i / voxelCentres.length);
|
||||
this.registerVoxel(voxelCentres[i], debug);
|
||||
}
|
||||
*/
|
||||
for (const voxelCentre of voxelCentres) {
|
||||
this.registerVoxel(voxelCentre, debug);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_cycleDebugRegister() {
|
||||
this._filledDebugRegisters.push(this._debugRegister);
|
||||
this._debugRegister = this._getEmptyDebugRegister();
|
||||
//this._debugMaxIndex = 0;
|
||||
}
|
||||
|
||||
_cycleRegister() {
|
||||
this._filledRegisters.push(this._register);
|
||||
this._register = this._getEmptyRegister();
|
||||
//this._maxIndex = 0;
|
||||
//console.log("Cycling Registers");
|
||||
}
|
||||
|
||||
_willDataOverflowBuffer(data) {
|
||||
|
||||
}
|
||||
|
||||
_addDataToRegister(data, debug) {
|
||||
if (!this._registersOpen) {
|
||||
console.error("Trying to register object when register is closed. Register before calling compileRegister()");
|
||||
return;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
let newMaxIndex = this._debugMaxIndex + 1 + Math.max(...data.indices);
|
||||
if (newMaxIndex >= 65535) {
|
||||
this._cycleDebugRegister();
|
||||
newMaxIndex = 0;
|
||||
}
|
||||
|
||||
this._debugRegister.position.data.push(...data.position);
|
||||
this._debugRegister.indices.data.push(...data.indices.map(x => x + this._debugMaxIndex));
|
||||
|
||||
const numVertices = data.position.length / 3;
|
||||
const vertexColours = [].concat(...new Array(numVertices).fill(this._strokeColour.toArray()));
|
||||
this._debugRegister.colour.data.push(...vertexColours);
|
||||
|
||||
this._debugMaxIndex = newMaxIndex;
|
||||
} else {
|
||||
let newMaxIndex = this._maxIndex + 1 + Math.max(...data.indices);
|
||||
if (newMaxIndex >= 65535) {
|
||||
this._cycleRegister();
|
||||
newMaxIndex = 0;
|
||||
}
|
||||
|
||||
this._register.position.data.push(...data.position);
|
||||
this._register.normal.data.push(...data.normal);
|
||||
this._register.indices.data.push(...data.indices.map(x => x + this._maxIndex));
|
||||
|
||||
this._maxIndex = newMaxIndex;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
_drawData(data) {
|
||||
const buffer = twgl.createBufferInfoFromArrays(this._gl, data);
|
||||
|
||||
const uniforms = {
|
||||
u_fillColour: this._strokeColour.toArray(),
|
||||
u_worldViewProjection: this._camera.getWorldViewProjection()
|
||||
};
|
||||
|
||||
const shader = shaderManager.unshadedProgram;
|
||||
this._gl.useProgram(shader.program);
|
||||
twgl.setBuffersAndAttributes(this._gl, shader, buffer);
|
||||
twgl.setUniforms(shader, uniforms);
|
||||
this._gl.drawElements(this._gl.LINES, buffer.numElements, this._gl.UNSIGNED_SHORT, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
module.exports.Renderer = Renderer;
|
Loading…
Reference in New Issue
Block a user