# CS184 AS2: Interactive Polygon Modify and Morph

DUE DATE: Friday February 4th, 11:00pm

## Aim

In this assignment you will build a computer graphics visual effect - a simple linear morph between models. You will construct the software to create this morph by building on the previous assignment. You will also be exposed to several concepts in computer graphics as you explore this assignment:
• Picking objects with the mouse while accounting for inaccuracies in the user's movements.
• Calculating rectangular axis-aligned bounding boxes as approximations to objects.
• Linearly interpolating points to create polygons.
• Interfacing with parsers to read in OBJ data.
• Creating animations.
• Calculating viewport transformations to allow window resizing while maintaining the original aspect ratio of the active viewport.

## User Interaction

Your program will take the path to an OBJ file as a command line argument. Upon opening, the polygon in this OBJ file will be displayed as a set of connected lines. The user can move each vertex by using the left mouse button to click and drag vertices. The original polygon will still be displayed with less opacity, while the modified polygon will be displayed with full opacity. Thus, the user will immediately see a bight polygon as imported from the OBJ file, and as the user moved vertices, a shadow of the original polygon will be revealed. Once the user is happy with his modifications, he will be able to use the right mouse button to morph the original polygon into the new polygon as he drags the mouse from the left to the right of the window, and export an animation of the morph.

## Terminology and Conventions

Linear Interpolation: The mathematical technique for constricting new data points within the range of a discrete set of known points using a linear polynomial. In this assignment, that translates to moving along a straight line between two coordinates, where the first coordinate it as `x = 0.0` and the second coordinate is at `x = 1.0`.
Cel Animation: A traditional form of animation where frames are hand drawn on consecutive semi-translucent sheets, allowing the artist to see the previous frame, and draw the new frame relatively to the first.

## Minimum Specifications

Write a program called `morph` that accomplishes at least the following:
1. Takes a single command line argument for the path to an OBJ file: `morph polygon.obj`
2. On launch, opens a 600px by 600px OpenGL window.
3. Draw a crosshair at the current location of the mouse pointer in the window.
4. Importing OBJ file
1. Using the provided OBJ parser, your program will import the OBJ file exported by Assignment 1
5. Picking and Cel Animation
1. On pressing left mouse down close to a vertex, you will select the vertex.
2. Dragging the selected vertex will update the new position of the vertex to match the distance traveled by the mouse. (You should not see the selected vertex "snapping to" the mouse position). In other words, the offset between the vertex and mouse positions should be maintained.
3. The modified polygon will be drawn in 100% white. The original unmodified polygon will remain on screen as well in a darker shade of white, imitating the cel animation techniques used by traditional animators.
6. Bounding Boxes
1. A rectangular axis-aligned bounding box will be dynamically calculated for the (modified) polygon. This bounding box should also be dynamically calculated during the morph. Thus, the bounding box should AT ALL TIMES bound the modified polygon exactly. This allows for a level of abstraction in handling polygon data.
2. The bounding box will be drawn in green.
3. The bounding box need only consist of the coordinates `(x_min, x_max)` and `(y_min, y_max)`.
7. Morphing and Linear Interpolation
1. On holding down the right mouse button, the vertices of the polygon will be interpolated between its original and its modified state.
2. The interpolation will be linear between start and end positions for each vertex.
3. The current amount of interpolation between start and finish will be determined by the distance the mouse cursor is from the left to the right side of the window. Thus, a right mouse down in the center of the window along the horizontal axis will display a polygon with vertices at positions exactly in the middle between its original and modified position.
4. The interpolation will be dynamic, thus dragging the mouse across the screen horizontally will display the polygon being morphed as the mouse moves.
5. On release of the right mouse button, the program should return to its "editing" mode, displaying the modified and original polygon as described in the Picking section of this instructions.
8. Viewport Transformation and Window Resizing
1. The initial window will display a 1:1 aspect ratio viewport of the polygon.
2. The window will allow arbitrary resizing.
3. The window will allow for an arbitrary aspect ratio, inside which you will draw the largest possible viewport with a 1:1 (square) aspect ratio. Thus the viewport will retain its aspect ratio even as the window takes an arbitrary size.
9. Export animation and OBJ File
1. On pressing s your program will save `polygon2.obj` to the current working directory. This will contain an OBJ description of the new polygon.
2. On pressing a your program will export 100 BMP files consisting of a 3.3 second (30 frames per second) animation of the polygon morphing between the original (0) and modified (1) position. Thus, 100 steps of interpolation will be taken to create the BMP files.
3. Not part of the code: You will use imagemagick to convert this set of BMPs to an animated GIF for submission purposes and for your website.

### Extra Credit Ideas

In approximate order from easiest to hardest.
• User-controlled zooming.
• On screen display - Use OpenGL to show the coordinates of vertices as you drag them around.
• Multi-Selection - allow the user to select multiple vertices and move them together.

### Creating animated GIFs from a series of Bitmap images

We recommend using ImageMagick to create your animated GIFs. ImageMagick is free software, and you can find the source and binary distributions here. Once you have installed ImageMagick and exported a set of BMPs, you can create an animated gif using the `convert` utility of ImageMagick:

`convert -delay 1x30 -loop 0 frame*.bmp animation.gif`

## Submission

To submit this project, all of the following needs to be done by the deadline:
• Submit using the submit as2 command on the INST machines:
1. A copy of your code, including the whole framework, that compiles on the platform you developed on.
3. ONE animated GIFs of morphs you created, called `morph.gif`. Put reasonable effort into this morph. A square into a rectangle is NOT what we are looking for. A fish into a fowl, a reptile into a bird, an ape into a human (this one's tricky!) or something far more creative is desirable.
4. TWO OBJ files corresponding to the animation, called `polygon1.obj` and `polygon2.obj`.
• Put on your class instructional website:
1. A separate page for this assignment.
3. Linked with each animation, the corresponding OBJ files that created this animation.
Windows Users: The grader should ONLY have to open your .sln file and press F5 to build and run your solution.
*Nix Users: The grader should ONLY have to run make with the appropriate makefile to build your project. Thus, for Mac and Linux `make` and for solaris `gmake`.

Note: The submit program retains the directory structure of what you send it. Thus, we recommend making a new directory for your assignment on the server, cd'ing into that directory, copying the whole framework with your code into this directory, and running `yes | submit as2` to easily submit the whole project to us.

## Framework

See the Framework page here. Use version 2 of the framework.

## Implementation Tips

See the Red Book (The OpenGL Programming Guide) and the Blue Book (The OpenGL Reference Manual). Glut function calls can be found here. OpenGL is responsible for all the actual drawing, while GLUT is responsible for managing the window that appears on your screen.

READ the code given in `main.cpp`! It already contains templates of some incredibly useful OpenGL functions. It demonstrates the basic layout, and how to create classes. Also, refer to assignment 1, and reuse code as necessary rather than starting from scratch. We filled out most of the framework to include what you had to do for AS1, so feel free to just use that.

### Picking

From lecture and discussion section you know of at least three ways to do picking:
• Search through data structures checking coordinates.
• Picking through Painting - using OpenGL's buffers to find a position according to its color
• Viewport - positioning a small viewport at the mouse cursor's location and seeing whether there's vertices that are not clipped by this viewport.
Since OpenGL's methods are slightly more verbose that what we would prefer, we suggest that you implement picking by searching through your data structure of vertices, finding which (if any) vertex is within x distance of the mouse location. Make this x around 5 pixels.

### OBJ* Files and Parsing

For this class we are creating a superset of the OBJ file format called OBJ* to support the storing of hierarchical data. See our specification page here. For this project you need only knowledge of standard OBJ files.

Read our implementation to see how to use the simple parser included in the framework for this assignment. The Polygon class has a parser built into a constructor. Calling `Polygon(string filename)` will create a polygon class with all the vertices of the first face found in the obj file.