CS 419v/519v -- Winter Quarter 2023

Project #2

100 Points

Due: January 28

Keytime Animation of an OBJ Object with Vulkan and GLM


This page was last updated: January 18, 2023


Requirements

The objective of Project #2 is to load an OBJ file and perform a keytime animation with it.

  1. Using the supplied vkuLoadObjFile( ) function, load an OBJ files (your choice).

  2. Animate it using the supplied Keytimes animation C++ class.

  3. Use GLM for the rigid-body animation transformations. Click here to get to the GLM Primer.

  4. Files:
    vkuloadObjFile.h
    vkuLoadObjFile.cpp
    vkuKeytime.h
    vkuKeytime.cpp
    Sample2019-P2.zip

  5. Do a keytime animation on your chosen OBJ object. There needs to be at least 8 key-value pairs, with at least 6 separate quantities animated. Of those 6 animated quantities, at least one must be a position, one must be a rotation, and one must be a scale factor. The rest can be whatever you want. You can animate more quantities than 6 if you want.

  6. The object to be animated is your choice of any 3D OBJ geometry. It must have well-thought-out polygon-work in it to be able to tell that it is rotating (a really smooth sphere is not a good choice). Being a 3D object, each keytime position is defined by some number of parameters: (x, y, z, thetax, thetay, thetaz, scalex, scaley, scalez, r, g, b, shininess, etc.), each defined at specific moments in time.

  7. Be sure to look at your choice of OBJ file (OBJ files can be text-edited.) Be sure there are lines beginning with vn and vt. That tells you that this OBJ file contains normal vector values, for lighting, and texture coordinates, for texturing.

  8. The (x, y, z, thetax, thetay, thetaz, scalex, scaley, scalez, r, g, b, shininess, etc.) values for each keytime are your choice and should be pre-defined in the program.

  9. Animate your object by smoothly interpolating your quantities between the keytimes. Use the smooth interpolation Keytimes C++ class that we discussed. For your convenience, the class methods are re-covered below.

Including the Needed Files

In the sample.cpp file, put these lines after the MyBuffer struct has been defined:


#include "vkuLoadObjFile.h"
#include "vkuKeytime.h"
Put these lines at the end of the sample.cpp file:

#include "vkuLoadObjFile.cpp"
#include "vkuKeytime.cpp"

Loading an OBJ File into a Vertex Data Buffer


MyBuffer MyVertexDataBuffer;		// global -- already in the sample program

. . .

// this goes in InitGraphics( ):
MyVertexDataBuffer = VkuLoadObjFile((char *)"cow.obj");

// comment out or delete these lines:
//Init05MyVertexDataBuffer(  sizeof(VertexData), &MyVertexDataBuffer );
//Fill05DataBuffer( MyVertexDataBuffer,                 (void *) VertexData );

//Init05MyVertexDataBuffer(  sizeof(JustVertexData), &MyJustVertexDataBuffer );
//Fill05DataBuffer( MyJustVertexDataBuffer,               (void *) JustVertexData );

//Init05MyIndexDataBuffer(  sizeof(JustIndexData), &MyJustIndexDataBuffer );
//Fill05DataBuffer( MyJustIndexDataBuffer,                (void *) JustIndexData );

Smooth Interpolation:

The smooth interpolation technique that you will be using employs a piecewise cubic curve. Normally this type of curve requires you to enter slopes. But, rather than you having to specify the slopes, this technique makes a reasonable approximation of them based on the surrounding keytime information.

The methods for the Keytimes class are:

void    AddTimeValue( float time, float value );
float   GetFirstTime( );
float   GetLastTime( );
int     GetNumKeytimes( );
float   GetValue( float time );
void    PrintTimeValues( );

Set the values like this:

// global variables:
Keytimes Xpos, Ypos, Zpos;
Keytimes ThetaX, ThetaY, ThetaZ;
Keytimes ScaleXYZ;		// i used uniform scaling, you don't have to

	. . .

// at the bottom of InitGraphics( ):
ScaleXYZ.AddTimeValue( 0.f,  1.f);
ScaleXYZ.AddTimeValue( 7.5f, 0.25f);
ScaleXYZ.AddTimeValue(15.f,  1.f);
ScaleXYZ.AddTimeValue(22.5f, 2.f);
ScaleXYZ.AddTimeValue(30.f,  1.f);

ThetaX.AddTimeValue(0.0f, 0.0f);
ThetaX.AddTimeValue(5.f, glm::radians(720.f));
ThetaX.AddTimeValue(10.f, glm::radians(0.f));
ThetaX.AddTimeValue(20.f, glm::radians(-720.f));
ThetaX.AddTimeValue(30.f, glm::radians(0.f));

ThetaY.AddTimeValue(0.0f, 0.0f);
ThetaY.AddTimeValue(30.f, glm::radians(10.f*360.f+180.f));

	. . .

To Animate:

Right now, in your sample code, the global variable Time just keeps increasing. But, it would be better to get Time to repeat. So, consider doing something like this:


#define MAXSECONDS	30.

. . .

Time = glfwGetTime( );			// this is already in main( )
Time = fmod( Time, MAXSECONDS );	// add this

The C fmod( ) function divides Time by MAXSECONDS and give you back the remainder of that division. Thus, Time will always be between 0. and MAXSECONDS.

At the fmod'ed Time, sample the GetValue( ) method for each variable. Using GLM calls, produce a glm::mat4 from that and pass it over as the uObjectModel for the object you are about to draw, something like this. Put this at the end of the UpdateScene( ) function.


float time = (float)Time;
Object.uModel = glm::mat4(1.);          // identity
Object.uModel = glm::rotate(Object.uModel, ThetaX.GetValue(time), glm::vec3(1.f, 0.f, 0.f));
Object.uModel = glm::rotate(Object.uModel, ThetaY.GetValue(time), glm::vec3(0.f, 1.f, 0.f));
Object.uModel = glm::scale(Object.uModel, glm::vec3(ScaleXYZ.GetValue(time)));

Object.uNormal = glm::mat4(glm::inverseTranspose(glm::mat3(Scene.uSceneOrient*Object.uModel)));
Object.uColor = glm::vec4( 1.f, 0.2f, 0.2f, 1.f );
Object.uShininess = 32.f;

Fill05DataBuffer( MyObjectUniformBuffer, (void *) &Object );
In your video, somehow demonstrate that this all works.

Keyboard Keys

'l' (ell)Toggle lighting on and off
'm'Toggle display mode (textures vs. colors)
'p'Pause/resume the animation
'r'Toggle allowing the mouse to rotate and scale the animating scene
Esc, 'q'Exit the program

Feel free to add more keyboard inputs to control more aspects of the display if you want.

Turn-in:

Use Teach to turn in your:

  1. All source files: .cpp, .vert, .frag -- you can zip these together if you'd like.
  2. A one-page PDF with a title, your name, your email address, nice screen shots from your program, and the link to the Kaltura video demonstrating that your project does what the requirements ask for. If you can, I'd like you to narrate your video so that you can tell me what you did.
  3. Turn the PDF in as a separate file. Don't put it in the .zip!

Grading:

FeaturePoints
An OBJ object displays, but doesn't animate40
At least 6 quantities are animated30
Each quantity has at least 8 key-times30
Potential Total100