From cb72a4105a40159d8427812eb2c9717dd3e88fba Mon Sep 17 00:00:00 2001
From: "geoffrey.menetrey" <geoffrey.menetrey@etu.hesge.ch>
Date: Thu, 17 Dec 2020 15:58:28 +0100
Subject: [PATCH] =?UTF-8?q?d=C3=A9tection=20du=20click=20sur=20le=20sablie?=
 =?UTF-8?q?r,=20fonctionne=20mal=20avec=20la=20lumi=C3=A8re=20ponctuelle?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lab3.zip                | Bin 0 -> 41317 bytes
 lab4/lib/cuon-matrix.js | 741 ++++++++++++++++++++++++++++++++++++++++
 lab4/src/lab4.html      |   5 +
 lab4/src/lab4.js        | 511 ++++++++++++++++++++++++++-
 4 files changed, 1247 insertions(+), 10 deletions(-)
 create mode 100644 lab3.zip
 create mode 100644 lab4/lib/cuon-matrix.js

diff --git a/lab3.zip b/lab3.zip
new file mode 100644
index 0000000000000000000000000000000000000000..04bcfd0df37de238a57ffdf2ccc2a415a10b826c
GIT binary patch
literal 41317
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

literal 0
HcmV?d00001

diff --git a/lab4/lib/cuon-matrix.js b/lab4/lib/cuon-matrix.js
new file mode 100644
index 0000000..ded82a7
--- /dev/null
+++ b/lab4/lib/cuon-matrix.js
@@ -0,0 +1,741 @@
+// cuon-matrix.js (c) 2012 kanda and matsuda
+/** 
+ * This is a class treating 4x4 matrix.
+ * This class contains the function that is equivalent to OpenGL matrix stack.
+ * The matrix after conversion is calculated by multiplying a conversion matrix from the right.
+ * The matrix is replaced by the calculated result.
+ */
+
+/**
+ * Constructor of Matrix4
+ * If opt_src is specified, new matrix is initialized by opt_src.
+ * Otherwise, new matrix is initialized by identity matrix.
+ * @param opt_src source matrix(option)
+ */
+var Matrix4 = function(opt_src) {
+  var i, s, d;
+  if (opt_src && typeof opt_src === 'object' && opt_src.hasOwnProperty('elements')) {
+    s = opt_src.elements;
+    d = new Float32Array(16);
+    for (i = 0; i < 16; ++i) {
+      d[i] = s[i];
+    }
+    this.elements = d;
+  } else {
+    this.elements = new Float32Array([1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]);
+  }
+};
+
+/**
+ * Set the identity matrix.
+ * @return this
+ */
+Matrix4.prototype.setIdentity = function() {
+  var e = this.elements;
+  e[0] = 1;   e[4] = 0;   e[8]  = 0;   e[12] = 0;
+  e[1] = 0;   e[5] = 1;   e[9]  = 0;   e[13] = 0;
+  e[2] = 0;   e[6] = 0;   e[10] = 1;   e[14] = 0;
+  e[3] = 0;   e[7] = 0;   e[11] = 0;   e[15] = 1;
+  return this;
+};
+
+/**
+ * Copy matrix.
+ * @param src source matrix
+ * @return this
+ */
+Matrix4.prototype.set = function(src) {
+  var i, s, d;
+
+  s = src.elements;
+  d = this.elements;
+
+  if (s === d) {
+    return;
+  }
+    
+  for (i = 0; i < 16; ++i) {
+    d[i] = s[i];
+  }
+
+  return this;
+};
+
+/**
+ * Multiply the matrix from the right.
+ * @param other The multiply matrix
+ * @return this
+ */
+Matrix4.prototype.concat = function(other) {
+  var i, e, a, b, ai0, ai1, ai2, ai3;
+  
+  // Calculate e = a * b
+  e = this.elements;
+  a = this.elements;
+  b = other.elements;
+  
+  // If e equals b, copy b to temporary matrix.
+  if (e === b) {
+    b = new Float32Array(16);
+    for (i = 0; i < 16; ++i) {
+      b[i] = e[i];
+    }
+  }
+  
+  for (i = 0; i < 4; i++) {
+    ai0=a[i];  ai1=a[i+4];  ai2=a[i+8];  ai3=a[i+12];
+    e[i]    = ai0 * b[0]  + ai1 * b[1]  + ai2 * b[2]  + ai3 * b[3];
+    e[i+4]  = ai0 * b[4]  + ai1 * b[5]  + ai2 * b[6]  + ai3 * b[7];
+    e[i+8]  = ai0 * b[8]  + ai1 * b[9]  + ai2 * b[10] + ai3 * b[11];
+    e[i+12] = ai0 * b[12] + ai1 * b[13] + ai2 * b[14] + ai3 * b[15];
+  }
+  
+  return this;
+};
+Matrix4.prototype.multiply = Matrix4.prototype.concat;
+
+/**
+ * Multiply the three-dimensional vector.
+ * @param pos  The multiply vector
+ * @return The result of multiplication(Float32Array)
+ */
+Matrix4.prototype.multiplyVector3 = function(pos) {
+  var e = this.elements;
+  var p = pos.elements;
+  var v = new Vector3();
+  var result = v.elements;
+
+  result[0] = p[0] * e[0] + p[1] * e[4] + p[2] * e[ 8] + e[12];
+  result[1] = p[0] * e[1] + p[1] * e[5] + p[2] * e[ 9] + e[13];
+  result[2] = p[0] * e[2] + p[1] * e[6] + p[2] * e[10] + e[14];
+
+  return v;
+};
+
+/**
+ * Multiply the four-dimensional vector.
+ * @param pos  The multiply vector
+ * @return The result of multiplication(Float32Array)
+ */
+Matrix4.prototype.multiplyVector4 = function(pos) {
+  var e = this.elements;
+  var p = pos.elements;
+  var v = new Vector4();
+  var result = v.elements;
+
+  result[0] = p[0] * e[0] + p[1] * e[4] + p[2] * e[ 8] + p[3] * e[12];
+  result[1] = p[0] * e[1] + p[1] * e[5] + p[2] * e[ 9] + p[3] * e[13];
+  result[2] = p[0] * e[2] + p[1] * e[6] + p[2] * e[10] + p[3] * e[14];
+  result[3] = p[0] * e[3] + p[1] * e[7] + p[2] * e[11] + p[3] * e[15];
+
+  return v;
+};
+
+/**
+ * Transpose the matrix.
+ * @return this
+ */
+Matrix4.prototype.transpose = function() {
+  var e, t;
+
+  e = this.elements;
+
+  t = e[ 1];  e[ 1] = e[ 4];  e[ 4] = t;
+  t = e[ 2];  e[ 2] = e[ 8];  e[ 8] = t;
+  t = e[ 3];  e[ 3] = e[12];  e[12] = t;
+  t = e[ 6];  e[ 6] = e[ 9];  e[ 9] = t;
+  t = e[ 7];  e[ 7] = e[13];  e[13] = t;
+  t = e[11];  e[11] = e[14];  e[14] = t;
+
+  return this;
+};
+
+/**
+ * Calculate the inverse matrix of specified matrix, and set to this.
+ * @param other The source matrix
+ * @return this
+ */
+Matrix4.prototype.setInverseOf = function(other) {
+  var i, s, d, inv, det;
+
+  s = other.elements;
+  d = this.elements;
+  inv = new Float32Array(16);
+
+  inv[0]  =   s[5]*s[10]*s[15] - s[5] *s[11]*s[14] - s[9] *s[6]*s[15]
+            + s[9]*s[7] *s[14] + s[13]*s[6] *s[11] - s[13]*s[7]*s[10];
+  inv[4]  = - s[4]*s[10]*s[15] + s[4] *s[11]*s[14] + s[8] *s[6]*s[15]
+            - s[8]*s[7] *s[14] - s[12]*s[6] *s[11] + s[12]*s[7]*s[10];
+  inv[8]  =   s[4]*s[9] *s[15] - s[4] *s[11]*s[13] - s[8] *s[5]*s[15]
+            + s[8]*s[7] *s[13] + s[12]*s[5] *s[11] - s[12]*s[7]*s[9];
+  inv[12] = - s[4]*s[9] *s[14] + s[4] *s[10]*s[13] + s[8] *s[5]*s[14]
+            - s[8]*s[6] *s[13] - s[12]*s[5] *s[10] + s[12]*s[6]*s[9];
+
+  inv[1]  = - s[1]*s[10]*s[15] + s[1] *s[11]*s[14] + s[9] *s[2]*s[15]
+            - s[9]*s[3] *s[14] - s[13]*s[2] *s[11] + s[13]*s[3]*s[10];
+  inv[5]  =   s[0]*s[10]*s[15] - s[0] *s[11]*s[14] - s[8] *s[2]*s[15]
+            + s[8]*s[3] *s[14] + s[12]*s[2] *s[11] - s[12]*s[3]*s[10];
+  inv[9]  = - s[0]*s[9] *s[15] + s[0] *s[11]*s[13] + s[8] *s[1]*s[15]
+            - s[8]*s[3] *s[13] - s[12]*s[1] *s[11] + s[12]*s[3]*s[9];
+  inv[13] =   s[0]*s[9] *s[14] - s[0] *s[10]*s[13] - s[8] *s[1]*s[14]
+            + s[8]*s[2] *s[13] + s[12]*s[1] *s[10] - s[12]*s[2]*s[9];
+
+  inv[2]  =   s[1]*s[6]*s[15] - s[1] *s[7]*s[14] - s[5] *s[2]*s[15]
+            + s[5]*s[3]*s[14] + s[13]*s[2]*s[7]  - s[13]*s[3]*s[6];
+  inv[6]  = - s[0]*s[6]*s[15] + s[0] *s[7]*s[14] + s[4] *s[2]*s[15]
+            - s[4]*s[3]*s[14] - s[12]*s[2]*s[7]  + s[12]*s[3]*s[6];
+  inv[10] =   s[0]*s[5]*s[15] - s[0] *s[7]*s[13] - s[4] *s[1]*s[15]
+            + s[4]*s[3]*s[13] + s[12]*s[1]*s[7]  - s[12]*s[3]*s[5];
+  inv[14] = - s[0]*s[5]*s[14] + s[0] *s[6]*s[13] + s[4] *s[1]*s[14]
+            - s[4]*s[2]*s[13] - s[12]*s[1]*s[6]  + s[12]*s[2]*s[5];
+
+  inv[3]  = - s[1]*s[6]*s[11] + s[1]*s[7]*s[10] + s[5]*s[2]*s[11]
+            - s[5]*s[3]*s[10] - s[9]*s[2]*s[7]  + s[9]*s[3]*s[6];
+  inv[7]  =   s[0]*s[6]*s[11] - s[0]*s[7]*s[10] - s[4]*s[2]*s[11]
+            + s[4]*s[3]*s[10] + s[8]*s[2]*s[7]  - s[8]*s[3]*s[6];
+  inv[11] = - s[0]*s[5]*s[11] + s[0]*s[7]*s[9]  + s[4]*s[1]*s[11]
+            - s[4]*s[3]*s[9]  - s[8]*s[1]*s[7]  + s[8]*s[3]*s[5];
+  inv[15] =   s[0]*s[5]*s[10] - s[0]*s[6]*s[9]  - s[4]*s[1]*s[10]
+            + s[4]*s[2]*s[9]  + s[8]*s[1]*s[6]  - s[8]*s[2]*s[5];
+
+  det = s[0]*inv[0] + s[1]*inv[4] + s[2]*inv[8] + s[3]*inv[12];
+  if (det === 0) {
+    return this;
+  }
+
+  det = 1 / det;
+  for (i = 0; i < 16; i++) {
+    d[i] = inv[i] * det;
+  }
+
+  return this;
+};
+
+/**
+ * Calculate the inverse matrix of this, and set to this.
+ * @return this
+ */
+Matrix4.prototype.invert = function() {
+  return this.setInverseOf(this);
+};
+
+/**
+ * Set the orthographic projection matrix.
+ * @param left The coordinate of the left of clipping plane.
+ * @param right The coordinate of the right of clipping plane.
+ * @param bottom The coordinate of the bottom of clipping plane.
+ * @param top The coordinate of the top top clipping plane.
+ * @param near The distances to the nearer depth clipping plane. This value is minus if the plane is to be behind the viewer.
+ * @param far The distances to the farther depth clipping plane. This value is minus if the plane is to be behind the viewer.
+ * @return this
+ */
+Matrix4.prototype.setOrtho = function(left, right, bottom, top, near, far) {
+  var e, rw, rh, rd;
+
+  if (left === right || bottom === top || near === far) {
+    throw 'null frustum';
+  }
+
+  rw = 1 / (right - left);
+  rh = 1 / (top - bottom);
+  rd = 1 / (far - near);
+
+  e = this.elements;
+
+  e[0]  = 2 * rw;
+  e[1]  = 0;
+  e[2]  = 0;
+  e[3]  = 0;
+
+  e[4]  = 0;
+  e[5]  = 2 * rh;
+  e[6]  = 0;
+  e[7]  = 0;
+
+  e[8]  = 0;
+  e[9]  = 0;
+  e[10] = -2 * rd;
+  e[11] = 0;
+
+  e[12] = -(right + left) * rw;
+  e[13] = -(top + bottom) * rh;
+  e[14] = -(far + near) * rd;
+  e[15] = 1;
+
+  return this;
+};
+
+/**
+ * Multiply the orthographic projection matrix from the right.
+ * @param left The coordinate of the left of clipping plane.
+ * @param right The coordinate of the right of clipping plane.
+ * @param bottom The coordinate of the bottom of clipping plane.
+ * @param top The coordinate of the top top clipping plane.
+ * @param near The distances to the nearer depth clipping plane. This value is minus if the plane is to be behind the viewer.
+ * @param far The distances to the farther depth clipping plane. This value is minus if the plane is to be behind the viewer.
+ * @return this
+ */
+Matrix4.prototype.ortho = function(left, right, bottom, top, near, far) {
+  return this.concat(new Matrix4().setOrtho(left, right, bottom, top, near, far));
+};
+
+/**
+ * Set the perspective projection matrix.
+ * @param left The coordinate of the left of clipping plane.
+ * @param right The coordinate of the right of clipping plane.
+ * @param bottom The coordinate of the bottom of clipping plane.
+ * @param top The coordinate of the top top clipping plane.
+ * @param near The distances to the nearer depth clipping plane. This value must be plus value.
+ * @param far The distances to the farther depth clipping plane. This value must be plus value.
+ * @return this
+ */
+Matrix4.prototype.setFrustum = function(left, right, bottom, top, near, far) {
+  var e, rw, rh, rd;
+
+  if (left === right || top === bottom || near === far) {
+    throw 'null frustum';
+  }
+  if (near <= 0) {
+    throw 'near <= 0';
+  }
+  if (far <= 0) {
+    throw 'far <= 0';
+  }
+
+  rw = 1 / (right - left);
+  rh = 1 / (top - bottom);
+  rd = 1 / (far - near);
+
+  e = this.elements;
+
+  e[ 0] = 2 * near * rw;
+  e[ 1] = 0;
+  e[ 2] = 0;
+  e[ 3] = 0;
+
+  e[ 4] = 0;
+  e[ 5] = 2 * near * rh;
+  e[ 6] = 0;
+  e[ 7] = 0;
+
+  e[ 8] = (right + left) * rw;
+  e[ 9] = (top + bottom) * rh;
+  e[10] = -(far + near) * rd;
+  e[11] = -1;
+
+  e[12] = 0;
+  e[13] = 0;
+  e[14] = -2 * near * far * rd;
+  e[15] = 0;
+
+  return this;
+};
+
+/**
+ * Multiply the perspective projection matrix from the right.
+ * @param left The coordinate of the left of clipping plane.
+ * @param right The coordinate of the right of clipping plane.
+ * @param bottom The coordinate of the bottom of clipping plane.
+ * @param top The coordinate of the top top clipping plane.
+ * @param near The distances to the nearer depth clipping plane. This value must be plus value.
+ * @param far The distances to the farther depth clipping plane. This value must be plus value.
+ * @return this
+ */
+Matrix4.prototype.frustum = function(left, right, bottom, top, near, far) {
+  return this.concat(new Matrix4().setFrustum(left, right, bottom, top, near, far));
+};
+
+/**
+ * Set the perspective projection matrix by fovy and aspect.
+ * @param fovy The angle between the upper and lower sides of the frustum.
+ * @param aspect The aspect ratio of the frustum. (width/height)
+ * @param near The distances to the nearer depth clipping plane. This value must be plus value.
+ * @param far The distances to the farther depth clipping plane. This value must be plus value.
+ * @return this
+ */
+Matrix4.prototype.setPerspective = function(fovy, aspect, near, far) {
+  var e, rd, s, ct;
+
+  if (near === far || aspect === 0) {
+    throw 'null frustum';
+  }
+  if (near <= 0) {
+    throw 'near <= 0';
+  }
+  if (far <= 0) {
+    throw 'far <= 0';
+  }
+
+  fovy = Math.PI * fovy / 180 / 2;
+  s = Math.sin(fovy);
+  if (s === 0) {
+    throw 'null frustum';
+  }
+
+  rd = 1 / (far - near);
+  ct = Math.cos(fovy) / s;
+
+  e = this.elements;
+
+  e[0]  = ct / aspect;
+  e[1]  = 0;
+  e[2]  = 0;
+  e[3]  = 0;
+
+  e[4]  = 0;
+  e[5]  = ct;
+  e[6]  = 0;
+  e[7]  = 0;
+
+  e[8]  = 0;
+  e[9]  = 0;
+  e[10] = -(far + near) * rd;
+  e[11] = -1;
+
+  e[12] = 0;
+  e[13] = 0;
+  e[14] = -2 * near * far * rd;
+  e[15] = 0;
+
+  return this;
+};
+
+/**
+ * Multiply the perspective projection matrix from the right.
+ * @param fovy The angle between the upper and lower sides of the frustum.
+ * @param aspect The aspect ratio of the frustum. (width/height)
+ * @param near The distances to the nearer depth clipping plane. This value must be plus value.
+ * @param far The distances to the farther depth clipping plane. This value must be plus value.
+ * @return this
+ */
+Matrix4.prototype.perspective = function(fovy, aspect, near, far) {
+  return this.concat(new Matrix4().setPerspective(fovy, aspect, near, far));
+};
+
+/**
+ * Set the matrix for scaling.
+ * @param x The scale factor along the X axis
+ * @param y The scale factor along the Y axis
+ * @param z The scale factor along the Z axis
+ * @return this
+ */
+Matrix4.prototype.setScale = function(x, y, z) {
+  var e = this.elements;
+  e[0] = x;  e[4] = 0;  e[8]  = 0;  e[12] = 0;
+  e[1] = 0;  e[5] = y;  e[9]  = 0;  e[13] = 0;
+  e[2] = 0;  e[6] = 0;  e[10] = z;  e[14] = 0;
+  e[3] = 0;  e[7] = 0;  e[11] = 0;  e[15] = 1;
+  return this;
+};
+
+/**
+ * Multiply the matrix for scaling from the right.
+ * @param x The scale factor along the X axis
+ * @param y The scale factor along the Y axis
+ * @param z The scale factor along the Z axis
+ * @return this
+ */
+Matrix4.prototype.scale = function(x, y, z) {
+  var e = this.elements;
+  e[0] *= x;  e[4] *= y;  e[8]  *= z;
+  e[1] *= x;  e[5] *= y;  e[9]  *= z;
+  e[2] *= x;  e[6] *= y;  e[10] *= z;
+  e[3] *= x;  e[7] *= y;  e[11] *= z;
+  return this;
+};
+
+/**
+ * Set the matrix for translation.
+ * @param x The X value of a translation.
+ * @param y The Y value of a translation.
+ * @param z The Z value of a translation.
+ * @return this
+ */
+Matrix4.prototype.setTranslate = function(x, y, z) {
+  var e = this.elements;
+  e[0] = 1;  e[4] = 0;  e[8]  = 0;  e[12] = x;
+  e[1] = 0;  e[5] = 1;  e[9]  = 0;  e[13] = y;
+  e[2] = 0;  e[6] = 0;  e[10] = 1;  e[14] = z;
+  e[3] = 0;  e[7] = 0;  e[11] = 0;  e[15] = 1;
+  return this;
+};
+
+/**
+ * Multiply the matrix for translation from the right.
+ * @param x The X value of a translation.
+ * @param y The Y value of a translation.
+ * @param z The Z value of a translation.
+ * @return this
+ */
+Matrix4.prototype.translate = function(x, y, z) {
+  var e = this.elements;
+  e[12] += e[0] * x + e[4] * y + e[8]  * z;
+  e[13] += e[1] * x + e[5] * y + e[9]  * z;
+  e[14] += e[2] * x + e[6] * y + e[10] * z;
+  e[15] += e[3] * x + e[7] * y + e[11] * z;
+  return this;
+};
+
+/**
+ * Set the matrix for rotation.
+ * The vector of rotation axis may not be normalized.
+ * @param angle The angle of rotation (degrees)
+ * @param x The X coordinate of vector of rotation axis.
+ * @param y The Y coordinate of vector of rotation axis.
+ * @param z The Z coordinate of vector of rotation axis.
+ * @return this
+ */
+Matrix4.prototype.setRotate = function(angle, x, y, z) {
+  var e, s, c, len, rlen, nc, xy, yz, zx, xs, ys, zs;
+
+  angle = Math.PI * angle / 180;
+  e = this.elements;
+
+  s = Math.sin(angle);
+  c = Math.cos(angle);
+
+  if (0 !== x && 0 === y && 0 === z) {
+    // Rotation around X axis
+    if (x < 0) {
+      s = -s;
+    }
+    e[0] = 1;  e[4] = 0;  e[ 8] = 0;  e[12] = 0;
+    e[1] = 0;  e[5] = c;  e[ 9] =-s;  e[13] = 0;
+    e[2] = 0;  e[6] = s;  e[10] = c;  e[14] = 0;
+    e[3] = 0;  e[7] = 0;  e[11] = 0;  e[15] = 1;
+  } else if (0 === x && 0 !== y && 0 === z) {
+    // Rotation around Y axis
+    if (y < 0) {
+      s = -s;
+    }
+    e[0] = c;  e[4] = 0;  e[ 8] = s;  e[12] = 0;
+    e[1] = 0;  e[5] = 1;  e[ 9] = 0;  e[13] = 0;
+    e[2] =-s;  e[6] = 0;  e[10] = c;  e[14] = 0;
+    e[3] = 0;  e[7] = 0;  e[11] = 0;  e[15] = 1;
+  } else if (0 === x && 0 === y && 0 !== z) {
+    // Rotation around Z axis
+    if (z < 0) {
+      s = -s;
+    }
+    e[0] = c;  e[4] =-s;  e[ 8] = 0;  e[12] = 0;
+    e[1] = s;  e[5] = c;  e[ 9] = 0;  e[13] = 0;
+    e[2] = 0;  e[6] = 0;  e[10] = 1;  e[14] = 0;
+    e[3] = 0;  e[7] = 0;  e[11] = 0;  e[15] = 1;
+  } else {
+    // Rotation around another axis
+    len = Math.sqrt(x*x + y*y + z*z);
+    if (len !== 1) {
+      rlen = 1 / len;
+      x *= rlen;
+      y *= rlen;
+      z *= rlen;
+    }
+    nc = 1 - c;
+    xy = x * y;
+    yz = y * z;
+    zx = z * x;
+    xs = x * s;
+    ys = y * s;
+    zs = z * s;
+
+    e[ 0] = x*x*nc +  c;
+    e[ 1] = xy *nc + zs;
+    e[ 2] = zx *nc - ys;
+    e[ 3] = 0;
+
+    e[ 4] = xy *nc - zs;
+    e[ 5] = y*y*nc +  c;
+    e[ 6] = yz *nc + xs;
+    e[ 7] = 0;
+
+    e[ 8] = zx *nc + ys;
+    e[ 9] = yz *nc - xs;
+    e[10] = z*z*nc +  c;
+    e[11] = 0;
+
+    e[12] = 0;
+    e[13] = 0;
+    e[14] = 0;
+    e[15] = 1;
+  }
+
+  return this;
+};
+
+/**
+ * Multiply the matrix for rotation from the right.
+ * The vector of rotation axis may not be normalized.
+ * @param angle The angle of rotation (degrees)
+ * @param x The X coordinate of vector of rotation axis.
+ * @param y The Y coordinate of vector of rotation axis.
+ * @param z The Z coordinate of vector of rotation axis.
+ * @return this
+ */
+Matrix4.prototype.rotate = function(angle, x, y, z) {
+  return this.concat(new Matrix4().setRotate(angle, x, y, z));
+};
+
+/**
+ * Set the viewing matrix.
+ * @param eyeX, eyeY, eyeZ The position of the eye point.
+ * @param centerX, centerY, centerZ The position of the reference point.
+ * @param upX, upY, upZ The direction of the up vector.
+ * @return this
+ */
+Matrix4.prototype.setLookAt = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) {
+  var e, fx, fy, fz, rlf, sx, sy, sz, rls, ux, uy, uz;
+
+  fx = centerX - eyeX;
+  fy = centerY - eyeY;
+  fz = centerZ - eyeZ;
+
+  // Normalize f.
+  rlf = 1 / Math.sqrt(fx*fx + fy*fy + fz*fz);
+  fx *= rlf;
+  fy *= rlf;
+  fz *= rlf;
+
+  // Calculate cross product of f and up.
+  sx = fy * upZ - fz * upY;
+  sy = fz * upX - fx * upZ;
+  sz = fx * upY - fy * upX;
+
+  // Normalize s.
+  rls = 1 / Math.sqrt(sx*sx + sy*sy + sz*sz);
+  sx *= rls;
+  sy *= rls;
+  sz *= rls;
+
+  // Calculate cross product of s and f.
+  ux = sy * fz - sz * fy;
+  uy = sz * fx - sx * fz;
+  uz = sx * fy - sy * fx;
+
+  // Set to this.
+  e = this.elements;
+  e[0] = sx;
+  e[1] = ux;
+  e[2] = -fx;
+  e[3] = 0;
+
+  e[4] = sy;
+  e[5] = uy;
+  e[6] = -fy;
+  e[7] = 0;
+
+  e[8] = sz;
+  e[9] = uz;
+  e[10] = -fz;
+  e[11] = 0;
+
+  e[12] = 0;
+  e[13] = 0;
+  e[14] = 0;
+  e[15] = 1;
+
+  // Translate.
+  return this.translate(-eyeX, -eyeY, -eyeZ);
+};
+
+/**
+ * Multiply the viewing matrix from the right.
+ * @param eyeX, eyeY, eyeZ The position of the eye point.
+ * @param centerX, centerY, centerZ The position of the reference point.
+ * @param upX, upY, upZ The direction of the up vector.
+ * @return this
+ */
+Matrix4.prototype.lookAt = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) {
+  return this.concat(new Matrix4().setLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ));
+};
+
+/**
+ * Multiply the matrix for project vertex to plane from the right.
+ * @param plane The array[A, B, C, D] of the equation of plane "Ax + By + Cz + D = 0".
+ * @param light The array which stored coordinates of the light. if light[3]=0, treated as parallel light.
+ * @return this
+ */
+Matrix4.prototype.dropShadow = function(plane, light) {
+  var mat = new Matrix4();
+  var e = mat.elements;
+
+  var dot = plane[0] * light[0] + plane[1] * light[1] + plane[2] * light[2] + plane[3] * light[3];
+
+  e[ 0] = dot - light[0] * plane[0];
+  e[ 1] =     - light[1] * plane[0];
+  e[ 2] =     - light[2] * plane[0];
+  e[ 3] =     - light[3] * plane[0];
+
+  e[ 4] =     - light[0] * plane[1];
+  e[ 5] = dot - light[1] * plane[1];
+  e[ 6] =     - light[2] * plane[1];
+  e[ 7] =     - light[3] * plane[1];
+
+  e[ 8] =     - light[0] * plane[2];
+  e[ 9] =     - light[1] * plane[2];
+  e[10] = dot - light[2] * plane[2];
+  e[11] =     - light[3] * plane[2];
+
+  e[12] =     - light[0] * plane[3];
+  e[13] =     - light[1] * plane[3];
+  e[14] =     - light[2] * plane[3];
+  e[15] = dot - light[3] * plane[3];
+
+  return this.concat(mat);
+}
+
+/**
+ * Multiply the matrix for project vertex to plane from the right.(Projected by parallel light.)
+ * @param normX, normY, normZ The normal vector of the plane.(Not necessary to be normalized.)
+ * @param planeX, planeY, planeZ The coordinate of arbitrary points on a plane.
+ * @param lightX, lightY, lightZ The vector of the direction of light.(Not necessary to be normalized.)
+ * @return this
+ */
+Matrix4.prototype.dropShadowDirectionally = function(normX, normY, normZ, planeX, planeY, planeZ, lightX, lightY, lightZ) {
+  var a = planeX * normX + planeY * normY + planeZ * normZ;
+  return this.dropShadow([normX, normY, normZ, -a], [lightX, lightY, lightZ, 0]);
+};
+
+/**
+ * Constructor of Vector3
+ * If opt_src is specified, new vector is initialized by opt_src.
+ * @param opt_src source vector(option)
+ */
+var Vector3 = function(opt_src) {
+  var v = new Float32Array(3);
+  if (opt_src && typeof opt_src === 'object') {
+    v[0] = opt_src[0]; v[1] = opt_src[1]; v[2] = opt_src[2];
+  } 
+  this.elements = v;
+}
+
+/**
+  * Normalize.
+  * @return this
+  */
+Vector3.prototype.normalize = function() {
+  var v = this.elements;
+  var c = v[0], d = v[1], e = v[2], g = Math.sqrt(c*c+d*d+e*e);
+  if(g){
+    if(g == 1)
+        return this;
+   } else {
+     v[0] = 0; v[1] = 0; v[2] = 0;
+     return this;
+   }
+   g = 1/g;
+   v[0] = c*g; v[1] = d*g; v[2] = e*g;
+   return this;
+};
+
+/**
+ * Constructor of Vector4
+ * If opt_src is specified, new vector is initialized by opt_src.
+ * @param opt_src source vector(option)
+ */
+var Vector4 = function(opt_src) {
+  var v = new Float32Array(4);
+  if (opt_src && typeof opt_src === 'object') {
+    v[0] = opt_src[0]; v[1] = opt_src[1]; v[2] = opt_src[2]; v[3] = opt_src[3];
+  } 
+  this.elements = v;
+}
\ No newline at end of file
diff --git a/lab4/src/lab4.html b/lab4/src/lab4.html
index 2bb37bc..6bf6d90 100644
--- a/lab4/src/lab4.html
+++ b/lab4/src/lab4.html
@@ -8,9 +8,14 @@
 <canvas width="400" height="600" id="my-canvas">
   Please use a browser that supports "canvas"
 </canvas>
+<div id="which_light">lumière directionnelle</div>
+<div id="lightx">light x : </div>
+<div id="lighty">light y : </div>
+<div id="lightz">light z : </div>
 <script src="../lib/webgl-utils.js"></script>
 <script src="../lib/webgl-debug.js"></script>
 <script src="../lib/cuon-utils.js"></script>
+<script src="../lib/cuon-matrix.js"></script>
 <script src="lab4.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/lab4/src/lab4.js b/lab4/src/lab4.js
index 105a227..2e15fdd 100644
--- a/lab4/src/lab4.js
+++ b/lab4/src/lab4.js
@@ -1,18 +1,509 @@
+var eyeX = 0.0;
+var eyeY = 3.0;
+var eyeZ = 15.0;
+
+var xLightDir = 0.0;
+var yLightDir = 0.0;
+var zLightDir = 7.0;
+
+var canvas;
+var gl;
+// Model matrix
+var u_MvpMatrix;
+var u_NormalMatrix;
+
+// light color
+var u_LightColor;
+
+// diffuse light direction
+var u_LightDirection;
+
+// ambient light components
+var u_ModelMatrix;
+var u_LightPosition;
+var u_AmbientLight;
+
+// click variable
+var u_Clicked;
+
+which_light = true;
+
+document.onkeydown = checkKey;
+function checkKey(e) {
+  switch (e.key) {
+
+    // camera
+    case 'w':
+      eyeY += 1
+      break;
+    case 's':
+      eyeY -= 1
+      break;
+    case 'a':
+      eyeX -= 1
+      break;
+    case 'd':
+      eyeX += 1
+      break;
+    case 'e':
+      eyeZ += 1
+      break;
+    case 'q':
+      eyeZ -= 1
+      break;
+
+    // light
+    case 'ArrowUp':
+      zLightDir -= 0.1
+      break;
+    case 'ArrowDown':
+      zLightDir += 0.1;
+      break;
+    case 'ArrowLeft':
+      xLightDir -= 0.1;
+      break;
+    case 'ArrowRight':
+      xLightDir += 0.1
+      break;
+    case 'o': // up
+      yLightDir += 0.1
+      break;
+    case 'p': // down
+      yLightDir -= 0.1
+      break;
+
+    // choose light
+    case 'c':
+      which_light = !which_light
+      initElements();
+  }
+};
+
 // Vertex shader program
-const VSHADER_SOURCE =
-  '\n' +
-  // TODO: Implement your vertex shader code here
-  '\n';
+var VSHADER_SOURCE_DIRECTIONAL = 
+  'attribute vec4 a_Position;\n' + 
+  'attribute vec4 a_Color;\n' + 
+  'attribute vec4 a_Normal;\n' +        // Normal
+
+  'uniform mat4 u_MvpMatrix;\n' +
+  'uniform mat4 u_NormalMatrix;\n' +
+  
+  'uniform vec3 u_LightColor;\n' +     // Light color
+  'uniform vec3 u_LightDirection;\n' + // Light direction (in the world coordinate, normalized)
+
+  'varying vec4 v_Color;\n' +
+
+  'uniform bool u_Clicked;\n' +
+
+  'void main() {\n' +
+  '  gl_Position = u_MvpMatrix * a_Position;\n' +
+  '  vec4 normal = u_NormalMatrix * a_Normal;\n' +
+  '  float nDotL = max(dot(u_LightDirection, normalize(normal.xyz)), 0.0);\n' +
+  '  vec3 diffuse = u_LightColor * a_Color.rgb * nDotL;\n' +
+
+  '  if (u_Clicked) {\n' + //  Draw in red if mouse is pressed
+  '    v_Color = vec4(1.0, 0.0, 0.0, 1.0);\n' +
+  '  } else {\n' +
+  '  v_Color = vec4(diffuse, a_Color.a);\n' +
+  '  }\n' +
+  '}\n';
 
 // Fragment shader program
-const FSHADER_SOURCE =
-  '\n' +
-  // TODO: Implement your fragment shader code here
-  '\n';
+var FSHADER_SOURCE_DIRECTIONAL = 
+  
+  'precision mediump float;\n' +
+
+  'varying vec4 v_Color;\n' +
+
+  'void main() {\n' +
+  '  gl_FragColor = v_Color;\n' +
+  '}\n';
+
+var VSHADER_SOURCE_PONCTUAL =
+  'attribute vec4 a_Position;\n' +
+  'attribute vec4 a_Color;\n' +
+  'attribute vec4 a_Normal;\n' +
+
+  'uniform mat4 u_MvpMatrix;\n' +
+  'uniform mat4 u_ModelMatrix;\n' +   
+  'uniform mat4 u_NormalMatrix;\n' + 
+
+  'uniform vec3 u_AmbientLight;\n' + 
+
+  'varying vec3 normal;\n' + 
+  'varying vec4 vertexPosition;\n' + 
+  'varying vec3 ambient;\n' + 
+
+  'varying vec4 v_Color;\n' +
+
+  'uniform bool u_Clicked;\n' +
+
+  'void main() {\n' +
+  '  gl_Position = u_MvpMatrix * a_Position;\n' +
+  '  normal = normalize(vec3(u_NormalMatrix * a_Normal));\n' +
+  '  vertexPosition = u_ModelMatrix * a_Position;\n' +
+
+  '  ambient = u_AmbientLight * a_Color.xyz;\n' +
+
+  '  if (u_Clicked) {\n' + //  Draw in red if mouse is pressed
+  '    v_Color = vec4(1.0, 0.0, 0.0, 1.0);\n' +
+  '  } else {\n' +
+  '    v_Color = a_Color;\n' +
+  '  }\n' +
+  '}\n';
+
+var FSHADER_SOURCE_PONCTUAL =
+  'precision mediump float;\n' +
+
+  'uniform vec3 u_LightColor;\n' +     
+  'uniform vec3 u_LightPosition;\n' +  
+
+  'varying vec4 v_Color;\n' +
+  'varying vec3 normal;\n' + 
+  'varying vec4 vertexPosition;\n' + 
+  'varying vec3 ambient;\n' +
+
+  'void main() {\n' +
+
+  '  vec3 lightDirection = normalize(u_LightPosition - vec3(vertexPosition));\n' +
+  '  float nDotL = max(dot(normal, lightDirection), 0.0);\n' +
+  '  vec3 diffuse = u_LightColor * v_Color.rgb * nDotL;\n' +
+
+  '  gl_FragColor = vec4(diffuse + ambient, v_Color.a);\n' +
+  '}\n';
+
+function initElements(){
+  // Initialize shaders
+  vh_source = VSHADER_SOURCE_DIRECTIONAL;
+  fh_source = FSHADER_SOURCE_DIRECTIONAL;
+  if (!which_light){
+    vh_source = VSHADER_SOURCE_PONCTUAL;
+    fh_source = FSHADER_SOURCE_PONCTUAL;
+  }
+  if (!initShaders(gl, vh_source, fh_source)) {
+    console.log('Failed to intialize shaders.');
+    return;
+  }
+
+  // clear canva
+  gl.clearColor(0, 0, 0, 1);
+  gl.enable(gl.DEPTH_TEST);
+  gl.depthFunc(gl.LEQUAL);
+
+  // Get the storage location of u_MvpMatrix
+  u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
+  if (!u_MvpMatrix) { 
+    console.log('Failed to get the storage locations of u_MvpMatrix');
+    return -1;
+  }
+
+  u_LightColor = gl.getUniformLocation(gl.program, 'u_LightColor');
+  if (!u_LightColor) { 
+    console.log('Failed to get the storage locations of u_LightColor');
+    return -1;
+  }
+
+  u_NormalMatrix = gl.getUniformLocation(gl.program, 'u_NormalMatrix');
+  if (!u_NormalMatrix) { 
+    console.log('Failed to get the storage locations of u_NormalMatrix');
+    return -1;
+  }
+
+  u_Clicked  = gl.getUniformLocation(gl.program, 'u_Clicked');
+  if (!u_Clicked) { 
+    console.log('Failed to get the storage locations of u_Clicked');
+    return -1;
+  }
+
+  if (which_light){ // directionnal light
+    u_LightDirection = gl.getUniformLocation(gl.program, 'u_LightDirection');
+    if (!u_LightDirection) { 
+      console.log('Failed to get the storage locations of u_LightDirection');
+      return -1;
+    }
+  }else { // ponctual light
+    u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
+    if (!u_ModelMatrix) { 
+      console.log('Failed to get the storage locations of u_ModelMatrix');
+      return -1;
+    }
+
+    u_LightPosition = gl.getUniformLocation(gl.program, 'u_LightPosition');
+    if (!u_LightPosition) { 
+      console.log('Failed to get the storage locations of u_LightPosition');
+      return -1;
+    }
+
+    u_AmbientLight = gl.getUniformLocation(gl.program, 'u_AmbientLight');
+    if (!u_AmbientLight) { 
+      console.log('Failed to get the storage locations of u_AmbientLight');
+      return -1;
+    }
+  }
+
+  gl.uniform1i(u_Clicked, 0); // Pass false to u_Clicked
+}
 
 function main() {
+
   // Retrieve <canvas> element
-  const canvas = document.getElementById('my-canvas');
+  canvas = document.getElementById('my-canvas');
+
+  // Get the rendering context for WebGL
+  gl = getWebGLContext(canvas);
+  if (!gl) {
+    console.log('Failed to get the rendering context for WebGL');
+    return;
+  }
+
+  initElements();
+
+  canvas.onmousedown = function(ev) {   // Mouse is pressed
+    var x = ev.clientX, y = ev.clientY;
+    var rect = ev.target.getBoundingClientRect();
+    if (rect.left <= x && x < rect.right && rect.top <= y && y < rect.bottom) {
+
+      var vpMatrix = new Matrix4();   // View projection matrix
+      // Calculate the view projection matrix
+      vpMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
+      vpMatrix.lookAt(eyeX, eyeY, eyeZ, 0, 0, 0, 0, 1, 0);
+      var modelMatrix = new Matrix4();  // Model matrix
+
+      // If pressed position is inside <canvas>, check if it is above object
+      var x_in_canvas = x - rect.left, y_in_canvas = rect.bottom - y;
+      var picked = check(gl, x_in_canvas, y_in_canvas, u_Clicked, vpMatrix, u_MvpMatrix, u_ModelMatrix, u_NormalMatrix, modelMatrix);
+      if (picked) alert('The Hourglass was selected');
+    }
+  }
+
+  setInterval(onTimerTick, 10);
+}
+
+function onTimerTick() {
+
+  var light = "lumière directionnelle"
+  if (!which_light){
+    light = "lumière ponctuelle"
+  }
+  document.getElementById('which_light').innerHTML = light;
+  document.getElementById('lightx').innerHTML = "light x : " + xLightDir;
+  document.getElementById('lighty').innerHTML = "light y : " + yLightDir;
+  document.getElementById('lightz').innerHTML = "light z : " + zLightDir;
+
+  vpMatrix = new Matrix4();   // View projection matrix
+  // Calculate the view projection matrix
+  vpMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
+  vpMatrix.lookAt(eyeX, eyeY, eyeZ, 0, 0, 0, 0, 1, 0);
+
+  gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);
+  if (which_light){ // diffuse light
+    var lightDirection = new Vector3([xLightDir, yLightDir, zLightDir]);
+    lightDirection.normalize();     // Normalize
+    gl.uniform3fv(u_LightDirection, lightDirection.elements);
+  }else { // ambient light
+    // Set the light direction (in the world coordinate)
+    gl.uniform3f(u_LightPosition, xLightDir, yLightDir, zLightDir);
+    // Set the ambient light
+    gl.uniform3f(u_AmbientLight, 0.3, 0.3, 0.3);
+  }
+
+  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+  var modelMatrix = new Matrix4();  // Model matrix
+
+  /*modelMatrix.rotate(xAngle, 1, 0, 0);
+  modelMatrix.rotate(yAngle, 0, 1, 0);*/
+
+  drawHourglass(gl, vpMatrix, u_MvpMatrix, u_ModelMatrix, u_NormalMatrix, modelMatrix)
+  //drawSquares(gl, canvas, u_MvpMatrix)
+  drawBase(gl, vpMatrix, u_MvpMatrix, u_ModelMatrix, u_NormalMatrix, modelMatrix)
+}
+
+function drawHourglass(gl, vpMatrix, u_MvpMatrix, u_ModelMatrix, u_NormalMatrix, modelMatrix){
+  // Write the positions of trapezes vertices to a vertex shader
+  var n = initVertexBufferHourglass(gl);
+  if (n < 0) {
+    console.log('Failed to set the positions of the vertices');
+    return;
+  }
+
+  var mvpMatrix = new Matrix4();    // Model view projection matrix
+  var normalMatrix = new Matrix4(); // Transformation matrix for normals
+
+  // first half of hourglass
+  modelMatrix.translate(0, 0.0, 0);
+  if (!which_light){ gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements); }
+  mvpMatrix.set(vpMatrix).multiply(modelMatrix);
+  gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
+
+  normalMatrix.setInverseOf(modelMatrix);
+  normalMatrix.transpose();
+  gl.uniformMatrix4fv(u_NormalMatrix, false, normalMatrix.elements);
+
+  gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
+
+  // second half of hourglass
+  modelMatrix.translate(0, 1.0, 0);
+  modelMatrix.rotate(180, 0, 0, 1);
+  if (!which_light){ gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements); }
+  mvpMatrix.set(vpMatrix).multiply(modelMatrix);
+  gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
+
+  normalMatrix.rotate(180, 0, 0, 1);
+  normalMatrix.transpose();
+  gl.uniformMatrix4fv(u_NormalMatrix, false, normalMatrix.elements);
+
+  gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
+}
+
+function drawBase(gl, vpMatrix, u_MvpMatrix, u_ModelMatrix, u_NormalMatrix, modelMatrix){
+  // Write the positions of square vertices to a vertex shader
+  var n = initVertexBufferBase(gl);
+  if (n < 0) {
+    console.log('Failed to set the positions of the vertices');
+    return;
+  }
+
+  var mvpMatrix = new Matrix4();    // Model view projection matrix
+  var normalMatrix = new Matrix4(); // Transformation matrix for normals
+
+  modelMatrix.translate(0, 2.01, 0);
+  if (!which_light){ gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements); }
+  mvpMatrix.set(vpMatrix).multiply(modelMatrix);
+  gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
+
+  normalMatrix.setInverseOf(modelMatrix);
+  normalMatrix.transpose();
+  gl.uniformMatrix4fv(u_NormalMatrix, false, normalMatrix.elements);
+
+  gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
+}
+
+function initVertexBufferHourglass(gl){
+
+  const vertices = new Float32Array([
+    -0.25, 0.5,  0.25,  0.25, 0.5,  0.25,  -0.5, -0.5, 0.5,  0.5, -0.5, 0.5,     // front
+    0.25, 0.5,  0.25,  0.25, 0.5, -0.25,  0.5, -0.5, 0.5,  0.5, -0.5, -0.5,      // right
+    0.25, 0.5, -0.25,  -0.25, 0.5, -0.25, 0.5, -0.5, -0.5,  -0.5, -0.5, -0.5,    // back
+   -0.25, 0.5, -0.25,  -0.25, 0.5,  0.25, -0.5, -0.5, -0.5,  -0.5, -0.5, 0.5,    // left
+   -0.25, 0.5,  0.25,  0.25, 0.5,  0.25,  -0.25, 0.5, -0.25,   0.25, 0.5, -0.25, // up
+    -0.5, -0.5,  0.5,  0.5, -0.5, 0.5,  -0.5, -0.5, -0.5,  0.5, -0.5, -0.5       // down
+   ]);  
+
+  const colors = new Float32Array([
+     1.0, 1.0, 0.0,  1.0, 1.0, 0.0,  1.0, 1.0, 0.0,  1.0, 1.0, 0.0,
+     1.0, 1.0, 0.0,  1.0, 1.0, 0.0,  1.0, 1.0, 0.0,  1.0, 1.0, 0.0,
+     1.0, 1.0, 0.0,  1.0, 1.0, 0.0,  1.0, 1.0, 0.0,  1.0, 1.0, 0.0,
+     1.0, 1.0, 0.0,  1.0, 1.0, 0.0,  1.0, 1.0, 0.0,  1.0, 1.0, 0.0,
+     1.0, 1.0, 0.0,  1.0, 1.0, 0.0,  1.0, 1.0, 0.0,  1.0, 1.0, 0.0,
+     1.0, 1.0, 0.0,  1.0, 1.0, 0.0,  1.0, 1.0, 0.0,  1.0, 1.0, 0.0
+   ]);
+
+  const indices = new Uint8Array([
+    0, 1, 2,    1, 2, 3,
+    4, 5, 6,    5, 6, 7,
+    8, 9,10,    9,10,11,
+   12,13,14,   13,14,15,
+   16,17,18,   17,18,19,
+   20,21,22,   21,22,23
+   ]);
+
+  const normals = new Float32Array([
+    0.0, 0.25, 0.25,  0.0, 0.25, 0.25,  0.0, 0.25, 0.25,  0.0, 0.25, 0.25, 
+    0.25, 0.25, 0.0,  0.25, 0.25, 0.0,  0.25, 0.25, 0.0,  0.25, 0.25, 0.0,  
+    0.0, 0.25, -0.25,  0.0, 0.25, -0.25,  0.0, 0.25, -0.25,  0.0, 0.25, -0.25,  
+   -0.25,0.25, 0.0,  -0.25, 0.25, 0.0,  -0.25, 0.25, 0.0,  -0.25, 0.25, 0.0,  
+    0.0, 0.25, 0.0,  0.0, 0.25, 0.0,  0.0, 0.25, 0.0,   0.0, 0.25, 0.0,  
+    0.0, -0.25, 0.0,  0.0, -0.25, 0.0,  0.0, -0.25, 0.0,   0.0, -0.25, 0.0
+   ]);
+
+  initVertexBuffer(gl, vertices, colors, indices, normals)
+  return indices.length; // The number of vertices
+}
+
+function initVertexBufferBase(gl){
+
+  const vertices = new Float32Array([
+    -2.0, -0.50, 2.0,  2.0, -0.50, 2.0,  2.0, -0.50, -2.0,  -2.0, -0.50, -2.0 // square         
+   ]);
+
+  const colors = new Float32Array([
+     1.0, 1.0, 1.0,  1.0, 1.0, 1.0,  1.0, 1.0, 1.0,  1.0, 1.0, 1.0
+   ]);
+
+  const indices = new Uint8Array([
+     0, 1, 2,  0, 2, 3
+   ]);
+
+  const normals = new Float32Array([
+    -2.0, -0.50, 2.0,  2.0, -0.50, 2.0,  2.0, -0.50, -2.0,  -2.0, -0.50, -2.0
+  ]);
+
+  initVertexBuffer(gl, vertices, colors, indices, normals)
+  return indices.length; // The number of vertices
+}
+
+// init vertex buffer with given vertices
+function initVertexBuffer(gl, vertices, colors, indices, normals) {
+
+  const n = indices.length; // The number of vertices
+
+  // Create a buffer object for indexes
+  var indexBuffer = gl.createBuffer();
+  if (!indexBuffer) {
+    console.log('Failed to create the buffer object');
+    return -1;
+  }
+  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
+
+  // set array buffer for vertices
+  setArrayBuffer(gl, vertices, 'a_Position')
+
+  // set array buffer for color
+  setArrayBuffer(gl, colors, 'a_Color')
+
+  // set array buffer for normal
+  setArrayBuffer(gl, normals, 'a_Normal')
+
+  return n;
+}
+
+// set an array in the buffer of given attribute
+function setArrayBuffer(gl, array, attribute){
+
+  // Create a buffer object for vertices / colors
+  var vertexBuffer = gl.createBuffer();
+  if (!vertexBuffer) {
+    console.log('Failed to create the buffer object');
+    return -1;
+  }
+  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
+  gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
+
+  // Set attributes and uniforms
+  var attribute = gl.getAttribLocation(gl.program, attribute);
+  if (attribute < 0) {
+    console.log('Failed to get the storage location of a_Position');
+    return -1;
+  }
+  gl.vertexAttribPointer(attribute, 3, gl.FLOAT, false, 0, 0);
+  gl.enableVertexAttribArray(attribute);
+}
+
+function check(gl, x, y, u_Clicked, vpMatrix, u_MvpMatrix, u_ModelMatrix, u_NormalMatrix, modelMatrix) {
+  var picked = false;
+  gl.uniform1i(u_Clicked, 1);  // Pass true to u_Clicked
+  drawHourglass(gl, vpMatrix, u_MvpMatrix, u_ModelMatrix, u_NormalMatrix, modelMatrix); // Draw cube with red
+  // Read pixel at the clicked position
+  var pixels = new Uint8Array(4); // Array for storing the pixel value
+  gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+
+  if (pixels[0] == 255) // The mouse in on cube if R(pixels[0]) is 255
+    picked = true;
 
-  // TODO: Complete with your code here
+  gl.uniform1i(u_Clicked, 0);  // Pass false to u_Clicked(rewrite the cube)
+  drawHourglass(gl, vpMatrix, u_MvpMatrix, u_ModelMatrix, u_NormalMatrix, modelMatrix); // Draw the cube
+  
+  return picked;
 }
\ No newline at end of file
-- 
GitLab