diff --git a/src/client/draw.ts b/src/client/draw.ts index 39931aa..cccb880 100644 --- a/src/client/draw.ts +++ b/src/client/draw.ts @@ -54,7 +54,7 @@ export function drawScene(gl: any, programInfo.uniformLocations.normalModelMatrix, false, normalModelMatrix[i]); - const vertexCount = params.length; + const vertexCount = params.len; const type = gl.UNSIGNED_SHORT; const offset = 0; gl.drawElements(gl.TRIANGLES, vertexCount, type, offset); diff --git a/src/client/init.ts b/src/client/init.ts index 6751995..4ecf8c1 100644 --- a/src/client/init.ts +++ b/src/client/init.ts @@ -1,4 +1,5 @@ import $ from 'jquery'; +import {fetchObj, loadObj} from './objutils'; /** * Initialize the parameters @@ -10,12 +11,7 @@ export function initParams(context: any) { parseFloat($('#distancefine').val()), circleSize: parseFloat($('#circlesize').val()), fov: parseFloat($('#fov').val()), - length: 0, - avg: { - x: 0, - y: 0, - z: 0, - }, + len: 0, range: 0, rot: { x: parseFloat($('#rotx').val()), @@ -45,6 +41,24 @@ export function initParams(context: any) { }; } +/** + * Initialize the cache with an object + * @param {any} context the program context + */ +export async function initCache(context: any) { + const racerData = await fetchObj('/static/objs/racer.obj'); + const racerObj = loadObj(racerData); + context.cache = { + fox: null, + mecha: null, + racer: racerObj, + sphere: null, + teapot: null, + }; + context.params.len = racerObj.indices.length; + context.params.range = racerObj.range; +} + /** * Set the program info * @param {any} context the program context diff --git a/src/client/main.ts b/src/client/main.ts index 4897c97..67f39c0 100644 --- a/src/client/main.ts +++ b/src/client/main.ts @@ -1,11 +1,11 @@ import vsSource from './shaders/shader.vert'; import texture from './shaders/texture.frag'; -import {fetchObj, updateObj} from './objutils'; +import {loadObjBuffers} from './objutils'; import {initShaderProgram} from './shaders'; import {loadTexture} from './texture'; import {drawScene} from './draw'; -import {initParams, setProgramInfo} from './init'; +import {initCache, initParams, setProgramInfo} from './init'; import {uiUpdateParams, uiUpdateTexture, @@ -29,6 +29,7 @@ async function main() { shaderProgram: null, fragmentShader: null, vertexShader: null, + cache: null, }; const canvas: any = document.querySelector('#glCanvas')!; context.gl = canvas.getContext('webgl2'); @@ -40,9 +41,9 @@ async function main() { support it.

`); } - const data = await fetchObj('/static/objs/racer.obj'); initParams(context); - updateObj(context, data, true); + await initCache(context); + loadObjBuffers(context, context.cache.racer); initShaderProgram(context, vsSource, texture); setProgramInfo(context); context.texture = loadTexture(context.gl, '/static/textures/racer.png'); diff --git a/src/client/matrix.ts b/src/client/matrix.ts index 6b658d5..7ca1e61 100644 --- a/src/client/matrix.ts +++ b/src/client/matrix.ts @@ -38,7 +38,6 @@ export function initMatrices(gl: any, params: any) { viewMatrix, viewMatrix, [0.0, 0.0, -params.distance]); - const normalModelMatrix = []; const modelMatrix = []; for (let i = 0; i < params.instanceNumber; i++) { @@ -58,14 +57,6 @@ export function initMatrices(gl: any, params: any) { mat4.rotateY(normalModelMatrixTemplate, normalModelMatrixTemplate, params.squareRotation); - mat4.translate( - viewMatrix, - viewMatrix, - [ - params.circleSize * Math.cos(params.squareRotation), - params.circleSize * Math.sin(params.squareRotation), - 0, - ]); if (i % 3 == 1) { addx = Math.floor(i / 9 + 1) * params.range * 1.5; } else if (i % 3 == 2) { @@ -79,9 +70,9 @@ export function initMatrices(gl: any, params: any) { mat4.translate(modelMatrixTemplate, modelMatrixTemplate, [ - -params.avg.x + addx, - -params.avg.y + addy, - -params.avg.z, + params.circleSize * Math.cos(params.squareRotation) + addx, + params.circleSize * Math.sin(params.squareRotation) + addy, + 0, ]); normalModelMatrix.push(normalModelMatrixTemplate); modelMatrix.push(modelMatrixTemplate); diff --git a/src/client/objutils.ts b/src/client/objutils.ts index f16bde7..ffd1a0e 100644 --- a/src/client/objutils.ts +++ b/src/client/objutils.ts @@ -16,20 +16,31 @@ export async function fetchObj(url: string) { /** * Pushes a new obj file to the gl buffer * @param {any} context the program context - * @param {string} data the obj file to push - * @param {boolean} firstCall is it first object updated ? + * @param {any} obj the obj file to push */ -export function updateObj( +export function loadObjBuffers( context: any, - data: string, - firstCall: boolean = false) { + obj: any) { + if (context.buffers != null) { + deleteBuffers(context.gl, context.buffers); + } + context.buffers = initBuffers(context.gl, + obj.positions, obj.indices, obj.normals, obj.uvs); +} + +/** + * Load a new obj file to the cache + * @param {string} data the obj file to push + * @return {any} the obj file loaded + */ +export function loadObj( + data: string) { const [ positions, normals, uvs, indices, ] = convert(data); - context.params.length = indices.length; let x = 0; let y = 0; let z = 0; @@ -63,12 +74,23 @@ export function updateObj( z += positions[i]; } } - context.params.range = Math.max(maxx - minx, maxy - miny, maxz - minz); - context.params.avg.x = x / (positions.length / 3); - context.params.avg.y = y / (positions.length / 3); - context.params.avg.z = z / (positions.length / 3); - if (!firstCall) { - deleteBuffers(context.gl, context.buffers); + const avgx = x / (positions.length / 3); + const avgy = y / (positions.length / 3); + const avgz = z / (positions.length / 3); + for (let i = 0; i < positions.length; i++) { + if (i % 3 == 0) { + positions[i] -= avgx; + } else if (i % 3 == 1) { + positions[i] -= avgy; + } else { + positions[i] -= avgz; + } } - context.buffers = initBuffers(context.gl, positions, indices, normals, uvs); + return { + positions: positions, + indices: indices, + normals: normals, + uvs: uvs, + range: Math.max(maxx - minx, maxy - miny, maxz - minz), + }; } diff --git a/src/client/uijquery.ts b/src/client/uijquery.ts index c308845..f581a52 100644 --- a/src/client/uijquery.ts +++ b/src/client/uijquery.ts @@ -1,6 +1,6 @@ import $ from 'jquery'; import {loadTexture} from './texture'; -import {fetchObj, updateObj} from './objutils'; +import {fetchObj, loadObj, loadObjBuffers} from './objutils'; import {changeFragmentShader} from './shaders'; import vsSource from './shaders/shader.vert'; @@ -84,24 +84,49 @@ export function uiUpdateTexture(context: any) { */ export function uiUpdateObject(context: any) { $('#o_sphere').on('click', async function() { - const data = await fetchObj('/static/objs/sphere.obj'); - updateObj(context, data); + if (context.cache.sphere == null) { + const data = await fetchObj('/static/objs/sphere.obj'); + context.cache.sphere = loadObj(data); + } + loadObjBuffers(context, context.cache.sphere); + context.params.len = context.cache.sphere.indices.length; + context.params.range = context.cache.sphere.range; }); $('#o_teapot').on('click', async function() { - const data = await fetchObj('/static/objs/teapot.obj'); - updateObj(context, data); + if (context.cache.teapot == null) { + const data = await fetchObj('/static/objs/teapot.obj'); + context.cache.teapot = loadObj(data); + } + loadObjBuffers(context, context.cache.teapot); + context.params.len = context.cache.teapot.indices.length; + context.params.range = context.cache.teapot.range; }); $('#o_fox').on('click', async function() { - const data = await fetchObj('/static/objs/fox.obj'); - updateObj(context, data); + if (context.cache.fox == null) { + const data = await fetchObj('/static/objs/fox.obj'); + context.cache.fox = loadObj(data); + } + loadObjBuffers(context, context.cache.fox); + context.params.len = context.cache.fox.indices.length; + context.params.range = context.cache.fox.range; }); $('#o_mecha').on('click', async function() { - const data = await fetchObj('/static/objs/mecha.obj'); - updateObj(context, data); + if (context.cache.mecha == null) { + const data = await fetchObj('/static/objs/mecha.obj'); + context.cache.mecha = loadObj(data); + } + loadObjBuffers(context, context.cache.mecha); + context.params.len = context.cache.mecha.indices.length; + context.params.range = context.cache.mecha.range; }); $('#o_racer').on('click', async function() { - const data = await fetchObj('/static/objs/racer.obj'); - updateObj(context, data); + if (context.cache.racer == null) { + const data = await fetchObj('/static/objs/racer.obj'); + context.cache.racer = loadObj(data); + } + loadObjBuffers(context, context.cache.racer); + context.params.len = context.cache.racer.indices.length; + context.params.range = context.cache.racer.range; }); } diff --git a/views/index.ejs b/views/index.ejs index bcfe8d7..c412f16 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -36,7 +36,7 @@
Change circle size:
- +
Change fov: