In this assignment, you will learn and implement the mathematics behind matrix operations and utilize those functions to transform 3D geometric primitives. You will implement four simple programs to render and transform 3D geometric primitives using JS and HTML5 canvas.
Obtaining the base code
The base code for this class is provided as a git repository. git is a version control system that allows you to keep track of changes in your code over time, collaborate with other people, track down bugs and more. git is the most widely used version control system today, and this is a good opportunity to learn it if you haven't already.
In this class, you will use git to obtain new and updated versions of the base code. During assignments, you will edit your own local copy of the base code. If we hand out new assignments or add improvements to the base code, git allows you to obtain the updated code and merge it with your local copy without losing your changes.
git is a versatile tool and allows you to achieve more than just obtaining new code from us. If you want to know more, a few external resources we can recommend are try git, git-the simple guide, the git immersion tutorial, github's cheat sheet, and the extensive free Pro Git ebook.
Before proceeding to the rest of this section, you need to install git. Please see the first chapter of the git book to find installation instructions for your system.
Cloning the repository
The base code for this class is available on the departmental gitlab server. If you do not already have an account, you will need to create one using either your @dartmouth.edu or @cs.dartmouth.edu email address. If you have trouble accessing the code, please contact one of the TAs.
Cloning using the command line
If you are familiar with using the command line on your system, you can easily obtain the base code that way. Navigate to the directory you want to download the base code to, then enter the command
$ git clone https://gitlab.cs.dartmouth.edu/cs77-fa17/assignment1_basecode.git
Cloning using SourceTree
On Windows and Mac OS X, Source Tree is a convenient visual front-end to Git. We particularly recommend this tool if you've never used Git before. After proceeding through the installation, use Clone/New to add the base code repository for this class.
Before you start, open
firstname-lastname-report.html in your browser. This html file will be both your report and your submitted assignment. The tasks will be rendered in the page.
Check the developer console of your browser for any error messages (check the x-hour slides for how to open the console).
Note: If there are any compatibility issues with your browser/platform, let us know as soon as possible
Task 1: Simple Projection (0.5pt)
In this task, you will finish the implementation of a basic wireframe rasterizer to render the edges of a sphere and a cube. The renderer is given to you with an orthographic projection already implemented, and you will only need to change the orthographic projection to a simple perspective projection.
If you've implemented this task correctly, you will get an image like the one shown below.
Take a look at
Fill in the missing part of
WireframeMesh.prototype.render. This method already contains an implementation of a wireframe renderer, all you have to do is implement the perspective projection. You can do this by simply dividing the x and y components by the z coordinate before rendering the edges.
Task 2: Matrix Operations (3.0pt)
In this task you will implement basic matrix operations and simple transforms. This task builds on Task 1; make sure you have implemented the first task. The end result of this task should be three animating shapes. There should be a cube translating in a circle on the left, a cube shrinking and growing in the center, and a sphere rotating on the right side of the screen.
If you've implemented this task correctly, you will get an image like the one shown below. Once you implement rotations you will be able to rotate your screen as if you were looking up and down by clicking and dragging the mouse up and down.
Take a look at matrix.js.
SimpleMatrix.translate. This method should return a translation matrix.
SimpleMatrix.scale. This method should return a scale matrix.
SimpleMatrix.rotate. This method should return a rotation matrix. NOTE:: The input angle is in degrees. You must convert it to radians.
SimpleMatrix.multiplyVector. This method should return the result of multiplying a 4x4 matrix and a 4 vector. The input to this method is a 3x1 vector. You can simply extend this vector to a 4 vector by adding a 1 as the fourth component. Your method can either return a 4 vector or a 3 vector because in this assignment you will be ignoring the 4th component of the resulting vector.
Take a look at
clear. This function should render a white rectangle the size of the canvas.
WireframeMesh_Two.prototype.render. This method should be almost identical to the render function you completed for Task 1, however, this method has an additional parameter. You are passed a transform matrix which you should apply to the points before you apply your projection. This will require you to use
Task2.prototype.render. The render method is almost fully implemented except it is missing the calculations necessary to create the transforms for the meshes. You have been provided with all of the matrices for the individual transforms for each mesh, it is your job to calculate the transforms for each mesh.
The scale mesh needs to first be scaled by its animation (
scaleAnim), then rotated by the
The trans mesh needs to first be moved to its initial position (
transPos), then translated by its animation (
transAnim), then rotated by the
The rot mesh needs to first be rotated by its animation (
rotAnim), then translated to its position (
rotPos), then rotated by the
Task 3: Similarity Transforms (1.0pt)
Take a look at
task3.js. Fill in the missing function
rotateAroundAxisAtPoint. This function takes an axis (array of 3 floats), an angle and a point (array of 3 floats).
Your function should return a transformation matrix that rotates around the given axis at the given point by the given angle. Rotating at the given point means that the point itself will stay unchanged by the transformation matrix, and that all other points will rotate around the point if transformed by the matrix.
Hint: You will need a combination of two translation matrices and a rotation matrix to solve this task. Check the book or the slides on geometric transformations if you're no longer sure how to do this.
If you've implemented this task correctly, you will get an image like this. One cube will rotate around the y axis (above) and one cube will rotate around the -x axis (left) about the sphere on the right. One cube will rotate around the -y axis (below) and one cube will rotate around the x axis (right) about the sphere on the left. If you click and drag the mouse up or down, the camera should rotate around the animating shapes.
Task 4: Hierarchical Transforms (1.5pt)
In this task you will implement a hierarchical transform to make a skeleton move. The skeleton is given by a series of bones that are connected with each other. A bone counts as connected to another bone when it has a non-null parent.
If you've implemented the task correctly, you will get an image like this. You will be able to manipulate the skeleton with the sliders below it. If you modify the hip rotation, the whole skeleton should turn; if you modify the hip angle, the whole leg should move; if you modify the knee angle, only the lower part of the leg should move; if you modify the ankle angle, only the foot should move. If you click and drag the mouse up or down, the camera should rotate around the skeleton.
Take a look at
task4.js and implement the missing functions
computePoseMatrix should compute the pose matrix of the bone. This matrix contains the rotation and translation of the bone, but does not contain scaling. The pose matrix should translate by
this.position and rotate the bone at
this.jointAngle. Re-use the function you implemented in the last task.
To make the skeleton move properly, you should implement the hierarchical transform. If the bone has a parent, you should retrieve the parent's pose matrix and apply it to the pose matrix of the current bone.
computeModelMatrix should return the model matrix of the bone. It should take the pose matrix and apply the bone scaling on top.
Fill in the calculation for the bone transform in Task4.prototype.render. Hint: you will need to use your
computeModelMatrix and the given view matrix.
What to submit
You should submit a zip file containing the entire folder for this assignment (including all js files, html files and the
resources folder). Rename
firstname-lastname-report.html to contain your name. Fill in the report with any problems encountered and comments about the assignment.
Note that we will grade the assignments in person. You will still need to come to office hours for grading. However, you should also submit the zip file by the due date through Canvas.