This assignment will be creating a 90\'s style screen saver. You must create a c
ID: 3821485 • Letter: T
Question
This assignment will be creating a 90's style screen saver. You must create a complex shape that has 10 faces (at least) You will then create (spawn) these shapes at random locations with z being as far away from the camera as possible. The shapes will steadily move forward (toward the camera). Each shape will rotate at a different random rate around the x, y, z axis Once the object goes past the camera it will be deleted. Create a slider input that will change the creation rate of the objects. Create another slider input that will affect the overall rotation speed of the objects Challenge - After finishing the above requirements watch the video I posted and figure out how to create a projection matrix so the objects appear to be in normal perspective. (Smaller the farther away they are) Moving toward the camera Rotating randomly over 3 axis Slider bar for creation rate Slider bar for rotation rate Getting the perspective view on the camera.Explanation / Answer
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include "geometry.h"
#include "vertexdata.h"
void setProjectionMatrix(const float &angleOfView, const float &near, const float &far, Matrix44f &M)
{
// do some work here
float scale = 1 / tan(angleOfView * 0.5 * M_PI / 180);
M[0][0] = scale;
M[1][1] = scale;
M[2][2] = -far / (far - near);
M[3][2] = -far * near / (far - near);
M[2][3] = -1;
M[3][3] = 0;
}
void multPointMatrix(const Vec3f &in, Vec3f &out, const Matrix44f &M)
{
//out = in * Mproj;
out.x = in.x * M[0][0] + in.y * M[1][0] + in.z * M[2][0] + /* in.z = 1 */ M[3][0];
out.y = in.x * M[0][1] + in.y * M[1][1] + in.z * M[2][1] + /* in.z = 1 */ M[3][1];
out.z = in.x * M[0][2] + in.y * M[1][2] + in.z * M[2][2] + /* in.z = 1 */ M[3][2];
float w = in.x * M[0][3] + in.y * M[1][3] + in.z * M[2][3] + /* in.z = 1 */ M[3][3];
// normalize if w is different than 1 (convert from homogeneous to Cartesian coordinates)
if (w != 1) {
out.x /= w;
out.y /= w;
out.z /= w;
}
}
int main(int argc, char **argv)
{
uint32_t imageWidth = 512, imageHeight = 512;
Matrix44f Mproj;
Matrix44f worldToCamera;
worldToCamera[3][1] = -10;
worldToCamera[3][2] = -20; setProjectionMatrix(angleOfView, near, far, Mproj);
unsigned char *buffer = new unsigned char[imageWidth * imageHeight];
memset(buffer, 0x0, imageWidth * imageHeight);
float angleOfView = 90;
float near = 0.1;
float far = 100;
for (uint32_t i = 0; i < numVertices; ++i) {
Vec3f vertCamera, projectedVert;
multPointMatrix(vertices[i], vertCamera, worldToCamera);
multPointMatrix(vertCamera, projectedVert, Mproj);
if (projectedVert.x < -1 || projectedVert.x > 1 || projectedVert.y < -1 || projectedVert.y > 1) continue;
// convert to raster space and mark the position of the vertex in the image with a simple dot
uint32_t x = std::min(imageWidth - 1, (uint32_t)((projectedVert.x + 1) * 0.5 * imageWidth));
uint32_t y = std::min(imageHeight - 1, (uint32_t)((1 - (projectedVert.y + 1) * 0.5) * imageHeight));
buffer[y * imageWidth + x] = 255;
//std::cerr << "here sometmes" << std::endl;
}
// export to image
std::ofstream ofs;
ofs.open("./out.ppm");
ofs << "P5 " << imageWidth << " " << imageHeight << " 255 ";
ofs.write((char*)buffer, imageWidth * imageHeight);
ofs.close();
delete [] buffer;
return 0;
}