Overview
-----
You will create a tree data structure wherein each node contains a
transformation matrix, and child nodes inherit the transformations of their
parent nodes. During this process you will reinforce your knowledge of C++
pointers and polymorphism as well as linear algebra transformation sequences.
Supplied Code
---------
Click here to access
the homework's Github repository.
We will provide you with a basic Qt GUI that consists of only a window with a
widget to render 2D scenes using OpenGL. You are free to organize your code and
classes however you like as long as they adhere to the requirements outlined
below. Additionally, we have provided a robust library of linear algebra functions
called GLM (OpenGL Mathematics) to use for your transformation needs. The
library you wrote for homework 1 was designed to be very similar in format to
the classes and functions provided by GLM, but there are some differences in
inputs to the transformation matrix functions GLM provides.
You can find the
documentation for GLM here.
When your project runs successfully, you should see the scene below.
You can toggle the grid off and on by pressing the `G` key on your keyboard.

We have also recorded a video showcasing the functionality expected from your homework
implementation:
Conceptual Questions (10 points, Due Friday, September 13 at 11:59 PM)
-------------
Before you begin the programming portion of this homework assignment, read and answer the following conceptual questions. Your answers should be submitted to Canvas.
* (3 pts) In C++, what is a virtual function and how does it relate to object
polymorphism? Say I have a class `Base` and a class `Derived` that inherits from
`Base`. Both classes implement a __non__-virtual function called `func()`. If `func()` is
invoked by dereferencing a `Base*` that actually points to an
instance of `Derived`, which implementation of `func()` will be called, and why?
* (2 pts) In `polygon.cpp` there is a constructor for the `Polygon` class that
takes in a number of sides to construct a regular, convex polygon. There is a
section of this constructor's body that sets up "indices" to construct triangles
out of the polygon's perimeter vertices. Please draw how these triangles would
be formed for a regular convex pentagon (five-sided polygon), and label each
vertex with its index number. You may draw your image on a piece of paper and
take a photograph, or create it in some sort of image editing software. Your
drawing need not be perfect, just make sure it's understandable. In the
end, please submit your drawing as a `.png` image.
* (5 pts) If I want to write a function that builds my entire scene graph and
returns its root node, what should the return type of the function be?
Additionally, where in memory should I instantiate the nodes of my scene graph?
Why should I instantiate my nodes in this portion of memory?
Help Log (5 points)
-------
Maintain a log of all help you receive and resources you use. Make sure the date and time, the names of everyone you work with or get help from, and every URL you use, except as noted in the collaboration policy. Also briefly log your question, bug or the topic you were looking up/discussing. Ideally, you should also the answer to your question or solution to your bug. This will help you learn and provide a useful reference for future assignments and exams. This also helps us know if there is a topic that people are finding difficult.
If you did not use external resources or otherwise receive help, please submit a help log that states you did not receive external help.
You may submit your help log as an ASCII (plain) text file or as a PDF. Refer to the Policies section of the course web site for more specifications.
Code Requirements (85 points, Due Wednesday, September 18 at 11:59 PM)
-------
### A helpful header file ###
We have provided you `smartpointerhelp.h`, which contains some preprocessor definitions to make it easier for you to write out smart pointer syntax. Please make use of these abbreviations as you implement the classes described below.
### Node classes (25 points) ###
A scene graph is a node-based tree data structure used to organize geometry in
computer graphics. We have provided you with `node.h` inside the `scene` folder.
You will create a basic `Node` class which should support the
following features:
* A set of `unique_ptr`s to the node's children. We recommend using `std::vector`s to
store the pointers, since they act as dynamically resizeable arrays.
* A raw, C-style pointer to one instance of `Polygon2D`. As noted later in the writeup,
this `Polygon2D` will be stored on the stack, so smart pointers are not relevant. Note
that a `Node` does not have to point to `Polygon2D`, so a reference is also not applicable,
as they cannot have a value of `nullptr`.
* The color with which to draw the `Polygon2D` pointed to by the node, if
applicable. This should be stored as a Red Green Blue (RGB) value in a `vec3` with elements in the range [0,1].
You will use this to temporarily override the color attribute of the `Polygon2D`
pointed to by this node. This enables you to draw the same basic `Polygon2D` with
differing transformations and colors without having to create a duplicate, as
demonstrated in the example scene drawing code in `MyGL::paintGL`.
* A __purely virtual__ function that computes and returns a 3x3 homogeneous
matrix representing the transformation in the node.
* A QString to represent a name for the node. This will be used later on when
you create a GUI to display your scene graph nodes.
* A function that adds a given `unique_ptr` as a child to this node.
You'll have to make use of `std::move` to make this work. Additionally,
to make scene graph construction easier for you, this function should
return a `Node&` that refers directly to the `Node` that is pointed
to by the `unique_ptr` passed into the function. This will allow
you to modify that heap-based `Node` from within your scene graph construction
function without worrying about `std::move`-ing unique pointers around.
* A function that allows the user to modify the color stored in this node.
Additionally, you will create the following classes that inherit from the basic
`Node` class:
* `TranslateNode`, which stores two floating point numbers: one that represents
its translation in the X direction, and one that represents its translation in
the Y direction.
* `RotateNode`, which stores one floating point number which represents the
magnitude of its rotation in degrees.
* `ScaleNode`, which stores two floating point numbers: one that represents
its scale in the X direction, and one that represents its scale in
the Y direction.
All three subclasses should implement the purely virtual function you declared
in your `Node` class that computes and returns a 3x3 transformation matrix.
Additionally, make sure you remember to use initializer lists in your
constructors and to make your destructors `virtual`. Make sure your
`Node` subclass constructors invoke a `Node` constructor for good style,
in addition to instantiating the unique member variables of each subclass.
### Scene graph construction (25 points) ###
Add a member variable to `MyGL` that represents the root node of your scene
graph. You should make it a unique pointer to a generic `Node`.
Then, write a function that you invoke from within `MyGL::initializeGL`
that constructs your entire scene graph and returns its root node, which you
will store in `MyGL`'s member variable. Any `Polygon2D` that your scene graph
points to should be stored in `MyGL` rather than on the heap. Furthermore,
you may re-use base geometry to draw the same shape with different
transformations by having two different `Node`s point to that shape instance.
Within your scene graph construction function, you will build a scene graph
that forms a humanoid puppet. This puppet must have the following features:
* At least two limbs that each have two segments, e.g. upper arm and forearm.
Each arm segment must pivot about one of its ends, such that if both segments
are rotated the limb curls as an arm or leg would.
* A head or head-analogue that pivots about its base. You may choose to include
a neck if you wish.
* A torso that serves as the "root" of all body transformations. In other words,
any transformations you apply to the torso should apply to the rest of the
character's body.
### Scene graph traversal (10 points) ###
Implement a function that takes in a pointer to a `Node` and a `mat3`, and which traverses
your scene graph and draws any existing `Polygon2D`s at each `Node` using
the sequence of transformation matrices that have been concatenated thus
far, following the example in the lecture slides. You should invoke this
function from `MyGL::paintGL`. Note that because `Node`s store their children
in a vector of `unique_ptr`s, you will have to do one of two things to read them:
* Use a foreach loop to the effect of `for(const uPtr& n : node->children)`.
This enables you to read the children without transferring ownership to `traverse`
because you're not creating a second `unique_ptr`, just a reference to one.
* Use the smart pointer `get()` function to grab a raw pointer to each child,
achieving a similar effect to the code above as this also does not create a
second `unique_ptr`.
We strongly recommend the first option since it precludes the possibility of freeing
memory owned by a smart pointer by invoking `delete` on a raw pointer.
### Qt GUI (25 points) ###
The following elements have been provided in your GUI in order to facilitate interactive alteration
of your nodes' transformation values. You can edit the GUI that appears when
you run your program by opening `Forms/forms/mainwindow.ui` in Qt Creator:
* A Tree Widget used to display your scene graph nodes. See the explanation
in the next paragraph for more information.
* A set of five Spin Boxes that enable the user to edit the translation,
rotation, and scale of a given node.
* A button that, when clicked, sets the geometry pointer of the currently
selected node to be `MyGL`'s `m_geomSquare` if that node does not already have
geometry.
* Three buttons that each allow the user to add a new node as a child of the
currently selected node, with one button for each type of node (translate,
rotate, and scale).
__Important Note:__ None of the provided GUI elements have been set up to
actually implement their required functionality. While you can alter the
numbers inside the spin boxes, for example, they will not yet alter anything.
You must add `slots` to `MyGL` and connect them to the `signals` emitted by these
GUI elements by invoking the `connect` function in `MainWindow`. You can refer to
the provided calls to `connect` in `mainwindow.cpp` to see how to set up further calls.
In order for your Tree Widget to display your nodes, you will have to add the
following functionality to your node class:
* Have your node class inherit from the `QTreeWidgetItem` class (this has been done for you).
* In the function you wrote to add a node as a child to another node,
invoke `QTreeWidgetItem::addChild`, with the child node as the input.
Note that this function takes in a `QTreeWidgetItem*`, and recall that
`Node` inherits from `QTreeWidgetItem`. Also recall that you can get a
raw C-style pointer to the address owned by a smart pointer via the
`get()` function.
* In the body of your node's constructor(s), invoke `setText` on your node's name. This
will allow the name to show up in the tree widget. `setText` is a member function
of the `QTreeWidgetItem` class that gives it a display name in a `QTreeWidget`.
* Just after you invoke your scene graph building function in `MyGL`, have
`MyGL` emit its signal `sig_sendRootNode` with the root node of your scene graph
as its argument. This signal is connected to a slot in `MainWindow` that adds
the given `QTreeWidgetItem` as a "top-level item" to the `QTreeWidget` in the GUI.
In other words, it adds the item as a root node in the GUI.
You can find a guide to editing Qt GUIs under the Resources tab of the web site.
Coding Style (10 points)
----------
To help you write better C++ code, we will score each of your homework assignments on
three different style elements, which will change from week to week. For this assignment, make sure you:
- Implement a copy constructor, assignment operator, and (appropriately virtual) destructor for any classes you author
- Only declare member functions/variables as public when they __need__ to be public. Everything else should be private
or protected.
- Never use the `new` or `delete` keywords anywhere in your program.
Extra Credit (20 points maximum)
-------------------------------
Include a readme.txt file in your repository that lists which extra credit
features you implemented and how to display them.
### Artistically interesting scene (5 - 10 pts) ###
Go beyond the basic requirements for your puppet and add detail to your scene.
Give your character a face, props, clothing, etc. Have fun with it! The more
detail, the more points!
### Polished GUI (5 - 10 pts) ###
Connect signals and slots in your GUI such that when a particular type of
node is selected in your tree widget, only the transformation adjustment widgets
that are compatible with that node are "active". For additional points, alter
the visual style of your GUI with Qt style sheets so it looks more professional
and less "default Windows/OSX user interface".
### Support concave polygons (15 pts) ###
Modify the constructor of `Polygon2D` that takes in a list of vertices such that
its triangulation process works on both concave and convex polygons. You
may have to add additional vertices to the polygon to make this work.
Submission
--------
Upload a .zip of your code to Canvas, and add a comment to your submission with a
link to your Github repository. Make sure you have correctly committed all of your files!