Hierarchical Modeling System
Due Thursday, 30 March 2017
In this assignment you'll implement a hierachical modeling system and learn how to build scene graphs using primitives and matrix transforms.
Tasks
Read the entire assignment before starting. If you don't, bad things will happen.
The Graphics System Specification outlines the functions required for a 2D/3D hierarchical modeling system that allows you to create modules and draw them. You will create a new set of functions for inserting graphics primitives, transforms, and other attributes into an open module. Each function will do approximately the same thing: put an instance of the object, transform, or attribute on the module's list.
As indicated in the graphics spec, the only required visual objects for the modeling system will be points, lines, polylines, and polygons. All of these primitives are described by one or more Point types. The important thing to remember about the insert function for these items is that graphics primitives need to be copied into the module so that the module has a local copy of the points constituting the object. If you do not copy the data into the module, bad things will happen.
The exception to the copy rule is inserting one module into another. In that case, a pointer to the sub-module needs to be stored in the parent. Modules should not be copied when they are inserted into another module. If you make copies of modules, bad things will happen.
The only tricky function to write is the function that actually traverses a Module's list and draws the scene onto the screen. The lecture notes include an algorithm for proper traversal of the scene graph. The most important aspect of the algorithm is how to organize the matrices.
- Within the context of traversing the elements a single module, use a local transformation matrix, the LTM, to hold all of the matrix operations. Left-multiply new matrices onto the LTM. If you right-multiply, bad things will happen.
-
When the Module_draw() function begins, it will be handed two
matrices, the view transformation matrix [VTM] and the Global
Transformation Matrix [GTM]. All points should be left-multiplied by
the LTM, then the GTM and then the VTM before they are drawn on the
screen. Remember that the original points stored in the module should
never be changed. Use temporary points to hold the results of
transforming the original points. If you modify the points stored in a
module, bad things will happen.
Pscreen = VTM * GTM * LTM * Porg
-
When the function Module_draw() gets called recursively, the GTM argument
handed to the function should be the product of the GTM and the local LTM.
GTMpass = GTM * LTM
You do not want to change the GTM within the current level of the Module_draw() function. If you change the GTM, bad things will happen.
- The Module_draw() also gets called with a DrawState structure that holds the current drawing state (e.g. color, shading parameters, and other information). You want to pass a duplicate copy of the DrawState structure into the child module so that any changes within the child module do not change the current DrawState. If you do not pass along a copy of the DrawState, bad things will happen.
-
The Module_draw() function will also take a Lighting
argument. However, for this assignment you should pass in NULL for the
Lighting pointer. You can define the Lighting structure as follows.
If you try and implement lighting on this assignment, you're just
silly.
typedef { int nLights; } Lighting;
Required Images
-
Use the first test program to test out your
system. It does not require any 3D functions module functions. The
list of functions required is given at the top of the C file. Get
those functions working first, before going on to anything else.
My system prints out the vtm, the element type, and the point and line locations it is drawing from within Module_draw. here is my printout.
Get this required picture done first before writing any more of the module functions. It will help you debug your basic module system.
- The second required picture is an image of a blue cube outline, made using your module_cube function.
- The third required image is a scene that contains a model with at least 3 layers of modules, where each higher module contains at least 3 instances of a lower module. For example, create a spaceship model, then a formation of 3 spaceships, then a scene with 3 formations. At the scene level, have each formation doing something different. You can put four or five things in your groups. Three is just the minimum. This is your required creative image. If you are working with a partner, you each need to make your own scene. (Oh, and this is a great scene in which to do animations).
-
The last required image is based on this test
code, which produces the image below.
Extensions
- Use the modeling commands creatively to develop (very) complex scenes.
- Create animated sequences and build an animated GIF.
- Enable ellipse and circle drawing with general transformations (hint, use polygons).
- Add Module_PopMatrix and Module_PushMatrix commands to store and restore transformation matrices as part of the module traversal process.
- Write routines for reading in lines or polygons from a file so you can create complex polygons using a text editor.
- Write routines that let you read in and write out modules from a human-editable file so you can create stuff off-line.
- Allow the use of run-time parameters in your structures. In other words, you would have to be able to specify when you build a structure that some of the parameters are not fixed, but should be gotten from the user when they execute a Module_draw() command. Then, your Module_draw function would include, not only a pointer to the structure, but also a pointer to the run-time parameter values. If you do something like this, it allows you to execute animations without having to recreate your structures for each frame. (tricky, but doable, and there are clever hacks)
Writeup
Make a wiki page and give it the label cs351s17project6. Put up your required and portfolio images along with brief descriptions and relevant information.
Handin
Put your code on the handin server in a project 6 directory in your Private folder.
Spring 2017