From ce3834ec4f8e132642cd534dda2cd257d1e625d5 Mon Sep 17 00:00:00 2001
From: gbrochar 
Date: Sat, 28 Nov 2020 12:44:52 +0100
Subject: [PATCH] added cache, fix circle size instances bug
---
 src/client/draw.ts     |  2 +-
 src/client/init.ts     | 26 +++++++++++++++++------
 src/client/main.ts     |  9 ++++----
 src/client/matrix.ts   | 15 +++----------
 src/client/objutils.ts | 48 ++++++++++++++++++++++++++++++------------
 src/client/uijquery.ts | 47 +++++++++++++++++++++++++++++++----------
 views/index.ejs        |  2 +-
 7 files changed, 101 insertions(+), 48 deletions(-)
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 @@