*In which you will add to your growing library of code an abstraction for 4x4 transformation matrices.*

Your first challenge is to create `Vector4`

and `Matrix4`

classes that you will use to perform transformations. Follow these steps to get them working:

In the project, run

`npm install`

.
Define in

`vector.js`

a class named `Vector4`

.
Define a constructor for

`Vector4`

that zeroes out the vector.
Define

`Vector4.get`

, which accepts an index as a parameter and returns the component of the vector specified by the index.
Define

`Vector4.set`

, which accepts an index and a value as parameters. It sets the component specified by the index to the value.
Ensure that

`Vector4`

passes the provided unit tests by running `npm run test-vector`

.
Define in

`matrix.js`

a class named `Matrix4`

.
Define a constructor for

`Matrix4`

that allocates the matrix's elements as a `Float32Array`

with 16 slots. The `Float32Array`

class is part of JavaScript's standard library and handles any conversion required to go from JavaScript's floating-point type (which is a `double`

) to a 4-byte floating point value that the GPU expects. See MDN to learn its interface.
Note that your

`Float32Array`

is a flat 16-element array, but you want to think of it as a 4x4 two-dimensional array. By the conventions of WebGL, the first four elements are the first column of the matrix. The next four are the second column. This ordering is called column major. Add a comment to show a 4x4 column major "map" of the matrix. You should be able to look at the map and figure out at which index of the array you can find an element at a given row and column.
Define

`Matrix4.get`

, which accepts a row and a column as parameters and returns the component of the matrix specified by the row and column.
Define

`Matrix4.set`

, which accepts a row, a column, and a value as parameters. It sets the component specified by the row and column to the value.
Define

`Matrix4.toBuffer`

to return the `Float32Array`

. The `ShaderProgram`

class calls this method when you set a matrix uniform.
Define

`Matrix4.identity`

, which is static. It returns the identity matrix. Multiplying a vector or matrix by the identity matrix is akin to multiplying a scalar number by 1. The identity matrix is essentially a scale matrix in which the scale factors are all 1.
Define

`Matrix4.scale`

, which is static. It accepts three parameters for the x-, y-, and z-factors. It returns a matrix that scales by the given factors.
Define

`Matrix4.translate`

, which is static. It accepts three parameters for the x-, y-, and z-offsets. It returns a matrix that translates by the given offsets.
Define

`Matrix4.rotateX`

, which is static. It accepts a number of degrees. It returns a matrix that rotates around the x-axis by the given number of degrees.
Define

`Matrix4.rotateY`

, which is static. It accepts a number of degrees. It returns a matrix that rotates around the y-axis by the given number of degrees.
Define

`Matrix4.rotateZ`

, which is static. It accepts a number of degrees. It returns a matrix that rotates around the z-axis by the given number of degrees.
Define

`Matrix4.multiplyVector`

. It accepts a `Vector4`

as a parameter. It returns the product of the matrix and vector as a new `Vector4`

.
Define

`Matrix4.multiplyMatrix`

. It accepts a `Matrix4`

as a parameter. It returns the product of this matrix and the parameter matrix as a new `Matrix4`

.
Ensure that all unit tests pass by running

`npm run test`

.
Show your passing tests to your instructor to receive credit.

Your second challenge is to render a scene that renders two instances of an object: one untransformed and one transformed by your matrices. Follow these steps:

Start up a web server and verify that you can see the triangular donut at the center of the viewport.

Modify the vertex shader in

`main.js`

to accept a `mat4`

uniform. Transform the vertex position by this matrix.
Draw the donut once with this matrix set to the identity.

Draw the donut again with this matrix set to a composition of at least two transformations.

Show your functioning application to your instructor to receive credit.