An overview of the code you will be using can be found here.
An overview of the .ray
file syntax can be found here.
An overview of the .key
file syntax can be found here.
Sample actor and key-frame files can be found here.
A (Win32) compiled version of the renderer implementing some of the basic features can be found here.
The OpenGL programming Guide is an invaluable resource in assisting with OpenGL implementation. You can find a link to the guide here or here.
main.cpp
file.
SVD
directory. (If you've lost it since assignment 2, you can download it
here).
Matrix4D ParametrizedRayGroup::getInverseMatrix(void){return getMatrix().invert();} Matrix4D ParametrizedRayGroup::getNormalMatrix(void){return getMatrix().invert().transpose();}
In addition to rendering static models, this assignment will allow you to render animated 3D models. The key
to doing this is the class
ParametrizedRayGroup (in Ray/rayGroup.[h/cpp]
).
which represents a transformation node in the scene-graph hierarchy whose value is a function of the time elapsed. At each frame,
the transformation associated with a parametrized scene-graph node is changed, and as a result, OpenGL renders
a new image. More particularly, animation is achieved through the use of the template class
ParameterSamples (in Util/parameterSamples.h
and Util/parameterSamples.todo.inl
). This class:
type
parameter.
The program takes in as a mandatory arguments the input (.ray
) .ray file name. Additionally, you can also pass in the dimensions of the viewing window and the complexity of the tesselation for objects like the sphere, the cylinder, and the cone. It is invoked from the command line with:The% Assignment4 --in in.ray --width w --height h --cplx c --factor matrix/euler/closest/quaternion/log
--factor
specifies how the animations will represent transformations in order to compute the transformations between the key-frame samples.Feel free to add new arguments to deal with the new functionalities you are implementing. Just make sure they are documented.
matrix
: Indicates that transformations are represented by 4x4 matrices. In-between transformations are obtained by blending these matrices.euler
: Indicates that transformations are represented by a triplet of Euler angles and a 3D translation vector. In-between transformations are obtained by blending the Euler angles and translation vectors independently and then using the blend of Euler angles to define the rotational component of the transformation.closest
: Indicates that transformations are represented by a 3x3 rotation matrix and a 3D translation vector. In-between transformations are obtained by blending the rotations and translation vectors independely and then defining the rotational component of the transformation to be the closest rotation to the computed blend of rotations.quaternion
: Indicates that transformations are represented by a unit quaternion describing the rotation and a 3D translation vector. In-between transformations are obtained by blending the quaternions and translation vectors independently, normalizing the blend of quaternions so that it is a unit quaternion, and then transforming the quaternion into the rotational component of the transformation.log
: Indicates that transformatinos are represented by the 3x3 skew-symmetric logarithm of the rotation and a 3D translation vector. In-between transformations are obtained by blending the skew-symmetric matrices and translation vectors independently and then exponentiating the blend of skew-symmetric matrices to obtain the rotational component of the transformation.
The assignment is worth 15 points. The following is a list of features that you may implement. The number in parentheses corresponds to how many points it is worth.
The assignment will be graded out of 15 points. In addition to implementing these features, there are several other ways to get more points:
- (2) The code you receive already parses apart the information in the .key files and makes the appropriate calls in the RayWindow::IdleFunction (in
Ray/rayWindow.[h/cpp]
) to update the values of the parameters. In order to obtain animations, modify the ParameterSamples::setCurrentValue (inUtil/parameterSamples.todo.inl
) method to set the value of ParameterSamples::currentValue by linearly interpolating the samples. You should assume that the value of the interpolation parameter,t
, is always between 0 and 1.
A template function is used forParameterSamples::setCurrentValue
in order to facilitate your work as you progress through this assignment. In order to take advantage of this, implement the code so that the value ofParameterSamples::currentValue
is expressed as a weighted sum of the sample values, using only addition and right-scalar multiplication.- (2) The default factorization of the transformation samples read in from a .key file is as 4x4 matrices. Consequently, even if the samples are rotations, interpolation can introduce unwanted scaling (as in the runner's legs in
Data/act/test.ray
). Modify the code to support parametrization of rotations using Euler angles.
To do this, you will need to implement the code in the constructor Matrix3D::Matrix3D(const Point3D& eulerAngles) (inUtil/geometry.todo.cpp
) which generates a 3x3 rotation matrix from a triplet of Euler angles. Recall that the three Euler angles define a rotation which is the product of a rotation about the x-axes, multiplied on the right by a rotation about the y-axes, multiplied on the right by a rotation about the z-axes.
You will also need to modify the code in ParametrizedEulerAnglesAndTranslation::getMatrix (inRay/rayGroup.todo.cpp
) to combine the rotation matrix obtained from the constructor, with the translation, to obtain the complete 4x4 transformation matrix.
The Euler angles and translation are pointed to by ParametrizedEulerAnglesAndTranslation::value.- (2) Although using Euler angles guarantees that the in-between transformations are rotations, they can result in unwanted artifacts (such as the jiggling of the runner's legs in
Data/act/test.ray
). To fix this problem, implement nearest rotation interpolation/approximation which finds the rotation between two rotations by computing the weighted average of the two rotations (not necessarily itself a rotation) and then finding the closest rotation to that average.
To do this, you will need to implement the code in Matrix3D::closestRotation (inUtil/geometry.todo.cpp
) which returns the rotation closest to the general 3x3 transformation described by theMatrix3D
object. (To help you on your way, the method Matrix3D::SVD has already been provided, giving the SVD decomposition of an arbitrary matrix as the product of a rotation, a diagonal, and another rotation matrix. The Singular Value Decomposition is performed in such a way that the absolute values of the diagonal entries in the diagonal matrix is strictly non-increasing.)
You will also need to modify the code in ParametrizedClosestRotationAndTranslation::getMatrix (inRay/rayGroup.todo.cpp
) to combine the rotation matrix obtained from theMatrix3D::closestRotation
with the translation, to obtain the complete 4x4 transformation matrix.
The matrix and translation are pointed to by ParametrizedClosestRotationAndTranslation::value.- (2) Implement quaternion parametrization of rotations.
To do this, you will need to implement the constructor Matrix3D::Matrix3D(const Quaternion& q) (inUtil/geometry.todo.cpp
) which generates the matrix corresponding to a quaternion. (Keep in mind that the matrix is only a rotation if the quaternion is a unit quaternion.)
You will also need to modify the code in ParametrizedQuaternionAndTranslation::getMatrix (inRay/rayGroup.todo.cpp
) to combine the rotation matrix obtained from the constructor with the translation, to obtain the complete 4x4 transformation matrix.
The quaternion and translation are pointed to by ParametrizedQuaternionAndTranslation::value.- (2) Implement the parametrization of rotations by the 3x3 skew-symmetric logarithm.
To do this, you will need to implement the function Matrix3D::Exp (inUtil/geometry.todo.cpp
) which computes the exponential of a matrix using the firstiter
terms of the Taylor approximation. Keep in mind that the Taylor series for the exponential function is:
exp(X)=1+X+X*X/(2!)+X*X*X/(3!)+...+X**k/(k!)+...
whereX**k
representsX
raised to thek
-th power, andk!
is "k
factorial" --k*(k-1)*(k-2)*...*2*1
.
You will also need to modify the code in ParametrizedRotationLogarithmAndTranslation::getMatrix (inRay/rayGroup.todo.cpp
) to combine the rotation matrix obtained from exponentiation with the translation, to obtain the complete 4x4 transformation matrix.
The logarithm and translation are pointed to by ParametrizedRotationLogarithmAndTranslation::value.- (2) Modify the ParameterSamples::setCurrentValue (in
Util/parameterSamples.todo.inl
) method to set the value ofParameterSamples::currentValue
by using Catmull-Rom interpolation.- (2) Modify the ParameterSamples::setCurrentValue (in
Util/parameterSamples.todo.inl
) method to set the value ofParameterSamples::currentValue
by using uniform cubic B-spline approximation.- (2) Create a .ray file and a .key file describing an interesting animation. Do not use any of the .key files provided with this assignment.
- (1) Implement the ability to sample the keyframe data at constant time intervals and dump the frame buffer to a sequence of files and then create a movie from the individual images.
- (1) Add the ability to parse a list of 3-D control points from a file and generate a camera path spline that the viewpoint flies along.
- (2) Add the ability to composite two motions specified in separate .key files onto the same actor at the same time. Augment the .key files to include a #Start time, and linearly blend between motions for the subsets of joints in both .key files during transition periods. Demonstrate this feature with a hand waving motion composited onto a walking cycle.
- (2) Add the ability to transition and composite motions in separate .key files under interactive user control.
- (1) Modify the OpenGL renderer to allow the user to generate a sequence of video images by taking snapshots of the scene from the same perspective as the
RayCamera
at a user-specified frame-rate.- (1) Modify the OpenGL renderer to allow the user to generate a sequence of video images by ray-tracing a sequence of scenes from the same perspective as the
RayCamera
at a user-specified frame-rate.- (?) Impress us with something we hadn't considered...
- (1) Submitting one or more images for the art contests.
- (1) Submitting one or more videos for the art contests.
- (1) Submitting one or more .ray files for the art contests.
- (1) Submitting one or more .key files for the art contests.
- (2) Winning the regular art contest.
- (2) Winning the video art contest.
- (2) Winning the .ray file art contest.
- (2) Winning the .key file art contest.
It is possible to get more than 15 points. However, after 15 points, each point is divided by 2, and after 17 points, each point is divided by 4. If your raw score is 14, your final score will be 14. If the raw score is 18, you'll get 16.25. For a raw score of 21, you'll get 17.