Each simple object on top of the table can be a shape created with GoblinXNA.Graphics.Geometry. (e.g., cube, cylinder, sphere, cone, or torus). Alternatively, you are welcome to create a simple object “from scratch” out of polygons that you define yourself. The table and chairs should be loaded as model objects (.fbx file, or .x file) using the GoblinXNA.Graphics.ModelLoader class. Models of a table and a chair are available for download at our CourseWorks site, although you are welcome to use different models. You can search for the second chair online (links to sites with free 3D models are provided on the TA page).
Each simple object must be a different color (or texture). The table should be placed within the room anywhere that you see fit. The chairs should initially be placed around the table, facing inward towards the table. The simple objects should rest on top of the table. You can use any .fbx or .x files created by you or by someone else (please provide credit). Note that texture mapping is not supported for the simple 3D objects found in GoblinXNA.Graphics.Geometry.
Only one object should be in the selected state at a time. You should also have some way to deselect the currently selected object without selecting another object.
|Figure 1: Table should be able to translate parallel to the main axes of the floor.||Figure 2: Each chair should be able to rotate around the table's up-axis.||Figure 3: Each chair should be able to rotate around its own up-axis.|
The table object should be associated with the following translation transformation: The object must be able to translate parallel to the main axes of the floor (left/right and forward/backward, but not up/down), but should only translate parallel to one of those axes at a time (Figure 1). Using the object's control panel, the user should be able to select the axis to which the translation should be parallel and the translation speed and direction (positive or negative). Selecting a different axis should cause the object to begin translating parallel to that axis with the current speed and direction, starting from the object's position at the time at which the new axis is selected. (That is, the object should not reset to its starting position when a new axis is selected.) Starting and stopping the action should not reset the object to its initial position, either. However, there should be some way to reset the object to its initial position.
Translating the table should cause the chairs and the simple objects on top of the table to translate by the same amount. In other words, the table must be the parent object of the chairs and the simple objects; consequently, any transformation applied to the table will affect its children.
To avoid losing sight of your table, you are welcome to implement bounds on how far the table can deviate from its original starting position.
The chair objects should be associated with the following rotation transformation: Each object must be able to rotate around (a) the table's up-axis (Figure 2) and (b) its own up-axis (Figure 3), but should only rotate about one of those axes at a time. Another way to think about these rotations is: a chair should be able to (a) orbit around the table and (b) rotate in place. Using the object's control panel, the user should be able to select which of the two axes the rotation should be around and the rotational speed and direction (counterclockwise or clockwise). Selecting a different axis should cause the object to begin rotating about that axis with the current speed and direction, starting from the object's orientation around both of the axes at the time at which the new axis is selected. (That is, the object should not reset to its starting orientation when a new axis is selected.) Starting and stopping the action should not reset the object to its initial orientation, either. However, there should be some way to reset the object to its initial orientation.
The simple objects should be associated with the following scaling transformation: The object must be able to scale along each of a set of three orthogonal axes, but should only scale along one of those axes at a time. Scaling should occur around some point on the table top. Using the object's control panel, the user should be able to select the axis along which scaling should occur and scaling speed and direction (larger or smaller). Selecting a different axis should cause the object to begin scaling along that axis with the current speed and direction, starting from the object's scale at the time at which the new axis is selected. (That is, the object should not reset to its starting scale when a new axis is selected.) Starting and stopping the action should not reset it to its initial scale, either. However, there should be some way to reset the object to its initial scale.
Which set of axes to use is up to you: they may be those of the table, or those of the object. To avoid having your object get too big or small to see (or inverting, due to a negative scale factor), you are welcome to implement bounds on how large or small the object can be scaled along any axis. Note: This transformation involves anisotropic (i.e., non-uniform) scaling. Please see the comment about this in the Hints.
Your camera should be controllable by the user at all times. It should be able to translate parallel to the main axes of the floor (Think of the camera as being mounted on a dolly constrained to move left/right and forward/backward, but not up/down). The user should also be able to rotate the camera around an axis perpendicular to the floor, and to change the camera's pitch by rotating it around an axis that is parallel to the floor and perpendicular to the direction in which the camera is pointing. (These two rotational degrees of freedom are typical of what a physical video tripod would support.) The user interface you create for controlling the camera should constrain the range along which it can translate and the amount by which it can pitch, so that it can rotate < 90° up and < 90° down.
Before starting this assignment, please look at the Goblin XNA Tutorials, which can be found in your <GoblinXNA>/tutorials folder (where <GoblinXNA> is the full installation path for your GoblinXNA installation). Also, please read the user's manual located in the <GoblinXNA>/doc folder, and the documentation for the parts of the Goblin XNA API that you use.
Please pay attention to Jakob Nielsen's 10 Usability Heuristics. Your grade will be based in part on how well your assignment follows them. For example, consider the first heuristic: "Visibility of system status: The system should always keep users informed about what is going on, through appropriate feedback within reasonable time." An example of this would be having your application give appropriate feedback (e.g., a label or changing color) to indicate which object is selected.
A "key" to doing this assignment well is to think carefully about how you structure your scene graph. Which nodes should you use and how should they be arranged relative to each other? How should the transformations that you apply to your objects be composed to achieve the required effects?
Remember that lights are required in the scene graph in order to view your scene.
Objects that are outside the bounds established by the camera’s near and far clipping planes will not be visible. If you can't see an object, check to see whether it has been properly added to the scene graph, whether it's within the camera frustum (taking into accounts the near and far clipping planes), and whether it might be occluded by some other object.
A note about the model files. Some of the model files may have a scale that is larger than you would normally expect. When using the models in your scene graph, you may need to apply a scale transform to bring them down to a more manageable size. Tutorial 2 shows an example of how this is done.
If you find any bugs in Goblin XNA, for a quick response, please contact your TA (email@example.com) directly or post your problem on our discussion board in Courseworks.
And now a few (OK, more than a few) words about scaling. Recall that an object's surface normals are important in computing how the object is lit. When an object is rotated, its surface normals need to be rotated the same way. When an object is uniformly scaled, its surface normals do not need to be scaled, but if they are scaled the same way as the object's vertices, each normal will still point in the correct direction. In contrast, the scaling transformation required for this assignment involves anisotropic (i.e., non-uniform) scale. When an object is scaled anisotropically, its surface normals must also be transformed; however, the necessary transform is not the transform used for the object's vertices.
As a simple example, consider a polygon in the y = −x plane, which makes an angle of 45° with the −x axis. Its surface normal, [1 1 0 0], which is perpendicular to the polygon, makes an angle of 45° with the +x axis. If that object is scaled anisotropically such that Sx = 2 and Sy = Sz = 1, it will be stretched so that it now lies in the y =−2x plane, making an angle of < 45° with the −x axis. However, scaling the surface normal by the same transformation yields [2 1 0 0], which makes an angle of < 45° with the +x axis, and thus is no longer perpendicular to the polygon! That's just plain wrong, and will result in incorrect lighting.
In general, the correct transformation for an object's surface normals turns out to be the inverse transpose of the transformation applied to the object's vertices. Note that in the case of rotation, the inverse transpose of the transformation is equal to the transformation itself. However, for scale, which is expressed along the main diagonal, the inverse transpose is, appropriately, just the inverse. Now, here’s one practical reason why this is worth knowing: while the BasicEffect shader provided in XNA Game Studio 4.0 does this correctly, the Basic Effect shader used up until XNA Game Studio 3.1 did not. In particular, it did not handle anisotropic scaling. While your work in this course, done on top of XNA Game Studio 4.0, will be fine, please note that anything done with Goblin XNA 3.x, will have this problem.
You are welcome to provide additional functionality beyond what is specified in the assignment. But, please get the assignment working to spec first.
Your submission should include all of your code, any .x or .fbx files, your Visual Studio project files, and an executable copy of your program. Your submission should also include a README file with the following information:
Please compress all files in your submission into a single archive file named [UNI]_assn1.zip[.tar|.gz|.rar] where UNI is your Columbia UNI. Remember to include all of the items listed above.
Please verify that you can run your executable code by first extracting a copy of this archive to a location on your computer outside the directory tree where you did your development and then running your executable without any references to your development tree.
Submission will be done through CourseWorks. Here are the steps:
Please try to submit before the deadline, since CourseWorks can sometimes become busy and slow.
Remember, you can only use a single late day on this assignment, so start early! And, have fun!