Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Primitives.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "Primitives.h"
271 changes: 176 additions & 95 deletions Primitives.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
#pragma once
#ifndef STB_IMAGE_IMPLEMENTATION
#define STBI_MSC_SECURE_CRT
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#endif
#include<Eigen/Eigen>
#include <numeric>
#include "Types.h"
Expand All @@ -29,7 +24,9 @@ class Primitive {
std::vector<Color> vertex_colors;
std::vector<TriangleVerts> triangle_verts;

void (*surface_shade)(VertexShaderPayload& pi) = nullptr;
void (*geometric_shader)(GeometricShaderPayload& p) = nullptr;
void (*surface_shader)(FragmentShaderPayload& p) = nullptr;
std::shared_ptr<Texture> texture;

void setup_vectors(int l) {
world_points.resize(l);
Expand Down Expand Up @@ -79,7 +76,7 @@ class Primitive {


virtual void get_bounding_cube() = 0;
virtual Eigen::Vector4f get_3D_coordinates(float u_n, float v_n) = 0;
virtual void get_3D_coordinates(float u_n, float v_n, Eigen::Vector4f& pos, Eigen::Vector4f& norm) = 0;


int get_dice_factor(int width, int height) {
Expand Down Expand Up @@ -109,6 +106,15 @@ class Primitive {
bb_top_y = screen_y;
}

// clamp to left edge
bb_left_x = std::max(bb_left_x, 0.0f);
//clamp to right edge
bb_right_x = std::min(bb_right_x, (float)width);
//clamp to bottom edge
bb_bottom_y = std::max(bb_bottom_y, 0.0f);
//clamp to top edge
bb_top_y = std::min(bb_top_y, (float)height);

//if it will be on the screen, how many pixels will it take up?
int xFactor = (bb_right_x - bb_left_x) * MICROPOLYGONS_PER_PIXEL;
int yFactor = (bb_top_y - bb_bottom_y) * MICROPOLYGONS_PER_PIXEL;
Expand All @@ -130,11 +136,10 @@ class Primitive {
float u_n = (float)u / ((float)grid_width - 1);
float v_n = (float)v / ((float)grid_height - 1);

Eigen::Vector4f position = get_3D_coordinates(u_n, v_n);
position.w() = 0.0f;
Eigen::Vector4f normal = position.normalized();
normal.w() = 1.0f;
position.w() = 1.0f;
Eigen::Vector4f position;
Eigen::Vector4f normal;

get_3D_coordinates(u_n, v_n, position, normal);

points[i] = position;
normals[i] = normal;
Expand Down Expand Up @@ -183,51 +188,21 @@ class Primitive {

}

void shade() {
//texture_map();
//apply_checker_shade();
for (int i = 0; i < points.size(); ++i) {
UVTuple tup = get_uv(i);
auto u = (float)tup.u / (float)(dice_factor - 1);
auto v = (float)tup.v / (float)(dice_factor - 1);

/*Point p;
p.u = u;
p.v = v;
p.c = vertex_colors[i];

surface_shade(p);
vertex_colors[i] = p.c;*/
}
}


void texture_map() {
int x, y, n;
unsigned char* data = stbi_load("textures\\earth_2.jpg", &x, &y, &n, 0);

for (int i = 0; i < points.size(); ++i) {
UVTuple p = get_uv(i);
auto u = (float)p.u / (float)(dice_factor - 1);
auto v = (float)p.v / (float)(dice_factor - 1);

int img_x = u * (x);
int img_y = v * (y);

img_x = img_x % x;
img_y = img_y % y;
void sh() {
if (geometric_shader == nullptr)
return;

// we want image processing to start from top left corner
// instead of bottom left corner. So flipping x and y in index value
int id = (img_y * x + img_x)*3;
uint8_t r = data[id];
uint8_t g = data[id + 1];
uint8_t b = data[id + 2];
GeometricShaderPayload p;
p.dice_factor = dice_factor;
p.normals = normals;
p.points = points;
p.triangle_verts = triangle_verts;

vertex_colors[i] = Color(r, g, b);
}
geometric_shader(p);

stbi_image_free(data);
normals = p.normals;
points = p.points;
triangle_verts = p.triangle_verts;
}


Expand Down Expand Up @@ -263,18 +238,18 @@ class Sphere : public Primitive {
b_cube_vertices[7] = Eigen::Vector4f(-1 * radius, radius, -1 * radius, 1.0f);
}

virtual Eigen::Vector4f get_3D_coordinates(float u_n, float v_n) {
Eigen::Vector4f position;
virtual void get_3D_coordinates(float u_n, float v_n, Eigen::Vector4f& position, Eigen::Vector4f& normal) {

float phi = phimin + v_n * (phimax - phimin);
float theta = u_n * thetamax;

position.x() = radius * std::cos(theta) * std::cos(phi);
position.y() = radius * std::sin(theta) * std::cos(phi);
position.z() = radius * std::sin(phi);
position.w() = 1.0f;

return position;
position.w() = 0.0f;
normal = position.normalized();
position.w() = 1.0f;
}
};

Expand Down Expand Up @@ -304,15 +279,19 @@ class Cylinder : public Primitive {
b_cube_vertices[7] = Eigen::Vector4f(radius, -1 * radius, zmax, 1.0f);
}

virtual Eigen::Vector4f get_3D_coordinates(float u_n, float v_n) {
Eigen::Vector4f position;
virtual void get_3D_coordinates(float u_n, float v_n, Eigen::Vector4f& position, Eigen::Vector4f& normal) {

float theta = u_n * thetamax;
position.x() = radius * cos(theta);
position.y() = radius * sin(theta);
position.z() = zmin + v_n * (zmax - zmin);
position.w() = 1.0f;

return position;
normal.x() = position.x();
normal.y() = position.y();
normal.z() = 0.0f;
normal.w() = 0.0f;
normal.normalize();
}

};
Expand Down Expand Up @@ -349,8 +328,7 @@ class Torus : public Primitive {
}


virtual Eigen::Vector4f get_3D_coordinates(float u_n, float v_n) {
Eigen::Vector4f position;
virtual void get_3D_coordinates(float u_n, float v_n, Eigen::Vector4f& position, Eigen::Vector4f& normal) {

float phi = phi_min + v_n * (phi_max - phi_min);
float theta = u_n * theta_max;
Expand All @@ -361,53 +339,68 @@ class Torus : public Primitive {
position.z() = minor_r * std::sin(phi);
position.w() = 1.0f;

return position;
Eigen::Vector4f t(major_r * std::cos(theta), major_r * std::sin(theta), 0.0f, 0.0f);
normal = (position - t).normalized();

}

};


class Patch : public Primitive {
class Cone : public Primitive {
public:
std::vector<Eigen::Vector3f> control_points;
float height, radius;
float thetamax;


Patch(std::vector<Eigen::Vector3f> cp, float scale) {
this->control_points = cp;
for (int i = 0; i < control_points.size(); ++i)
control_points[i] *= scale;
Cone(float height, float radius, float tmax) {
this->radius = radius;
this->height = height;
this->thetamax = tmax * PI / 180.0f;
}

virtual void get_bounding_cube() {
b_cube_vertices[0] = Eigen::Vector4f(radius, radius, 0.0f, 1.0f);
b_cube_vertices[1] = Eigen::Vector4f(-1 * radius, radius, 0.0f, 1.0f);
b_cube_vertices[2] = Eigen::Vector4f(-1 * radius, -1 * radius, 0.0f, 1.0f);
b_cube_vertices[3] = Eigen::Vector4f(radius, -1 * radius, 0.0f, 1.0f);

b_cube_vertices[4] = Eigen::Vector4f(radius, radius, height, 1.0f);
b_cube_vertices[5] = Eigen::Vector4f(-1 * radius, radius, height, 1.0f);
b_cube_vertices[6] = Eigen::Vector4f(-1 * radius, -1 * radius, height, 1.0f);
b_cube_vertices[7] = Eigen::Vector4f(radius, -1 * radius, height, 1.0f);
}

Eigen::Vector3f eval_curve(Eigen::Vector3f cp[4], float t) {
virtual void get_3D_coordinates(float u_n, float v_n, Eigen::Vector4f& position, Eigen::Vector4f& normal) {

Eigen::Vector3f P01 = (1 - t) * cp[0] + t * cp[1];
Eigen::Vector3f P12 = (1 - t) * cp[1] + t * cp[2];
Eigen::Vector3f P23 = (1 - t) * cp[2] + t * cp[3];
float theta = u_n * thetamax;

Eigen::Vector3f a = (1 - t) * P01 + t * P12;
Eigen::Vector3f b = (1 - t) * P12 + t * P23;
position.x() = radius * (1 - v_n) * std::cos(theta);
position.y() = radius * (1 - v_n) * std::sin(theta);
position.z() = v_n * height;
position.w() = 1.0f;

return ((1 - t) * a) + (t * b);
//vector from center to position
Eigen::Vector4f V(position.x(), position.y(), 0.0f, 1.0f);
V.normalize();
normal.x() = V.x() * height / radius;
normal.y() = V.y() * height / radius;
normal.z() = radius / height;
normal.w() = 0.0f;
normal.normalize();

}
};

Eigen::Vector3f eval_surface(float u, float v) {

Eigen::Vector3f ucurve_cp[4];
for (int i = 0; i < 4; ++i) {
// select 4 points for a curve
Eigen::Vector3f curve[4];
int k = i * 4;
curve[0] = control_points[k];
curve[1] = control_points[k + 1];
curve[2] = control_points[k + 2];
curve[3] = control_points[k + 3];
ucurve_cp[i] = eval_curve(curve, u);
}
class Patch : public Primitive {
public:
std::vector<Eigen::Vector3f> control_points;

auto z = eval_curve(ucurve_cp, v);
return z;

Patch(std::vector<Eigen::Vector3f> cp, float scale) {
this->control_points = cp;
for (int i = 0; i < control_points.size(); ++i)
control_points[i] *= scale;
}

virtual void get_bounding_cube() {
Expand All @@ -419,7 +412,7 @@ class Patch : public Primitive {

for (int i = 0; i < 16; ++i) {
auto p = control_points[i];

if (p.x() < l.x())
l.x() = p.x();

Expand Down Expand Up @@ -459,8 +452,96 @@ class Patch : public Primitive {
b_cube_vertices[7] = Eigen::Vector4f(h.x(), h.y(), h.z(), 1.0f);
}

virtual Eigen::Vector4f get_3D_coordinates(float u_n, float v_n) {
inline Eigen::Vector3f eval_curve(Eigen::Vector3f cp[4], float t) {

Eigen::Vector3f P01 = (1 - t) * cp[0] + t * cp[1];
Eigen::Vector3f P12 = (1 - t) * cp[1] + t * cp[2];
Eigen::Vector3f P23 = (1 - t) * cp[2] + t * cp[3];

Eigen::Vector3f a = (1 - t) * P01 + t * P12;
Eigen::Vector3f b = (1 - t) * P12 + t * P23;

return ((1 - t) * a) + (t * b);

}

Eigen::Vector3f eval_surface(float u, float v) {

Eigen::Vector3f ucurve_cp[4];
for (int i = 0; i < 4; ++i) {
// select 4 points for a curve
Eigen::Vector3f curve[4];
int k = i * 4;
curve[0] = control_points[k];
curve[1] = control_points[k + 1];
curve[2] = control_points[k + 2];
curve[3] = control_points[k + 3];
ucurve_cp[i] = eval_curve(curve, u);
}

auto z = eval_curve(ucurve_cp, v);
return z;
}

Eigen::Vector3f dU(float u, float v) {

Eigen::Vector3f P[4];
Eigen::Vector3f v_curve[4];
for (int i = 0; i < 4; ++i) {
P[0] = control_points[i];
P[1] = control_points[4 + i];
P[2] = control_points[8 + i];
P[3] = control_points[12 + i];
v_curve[i] = eval_curve(P, v);
}

return -3 * (1 - u) * (1 - u) * v_curve[0] +
(3 * (1 - u) * (1 - u) - 6 * u * (1 - u)) * v_curve[1] +
(6 * u * (1 - u) - 3 * u * u) * v_curve[2] +
3 * u * u * v_curve[3];
}

Eigen::Vector3f dV(float u, float v)
{
Eigen::Vector3f u_curve[4];
for (int i = 0; i < 4; ++i) {

Eigen::Vector3f curve[4];
int k = i * 4;
curve[0] = control_points[k];
curve[1] = control_points[k + 1];
curve[2] = control_points[k + 2];
curve[3] = control_points[k + 3];
u_curve[i] = eval_curve(curve, u);

}

return -3 * (1 - v) * (1 - v) * u_curve[0] +
(3 * (1 - v) * (1 - v) - 6 * v * (1 - v)) * u_curve[1] +
(6 * v * (1 - v) - 3 * v * v) * u_curve[2] +
3 * v * v * u_curve[3];
}

virtual void get_3D_coordinates(float u_n, float v_n, Eigen::Vector4f& position, Eigen::Vector4f& normal) {
Eigen::Vector3f p = eval_surface(u_n, v_n);
return Eigen::Vector4f(p.x(), p.y(), p.z(), 1.0f);
position.x() = p.x();
position.y() = p.y();
position.z() = p.z();
position.w() = 1.0f;

Eigen::Vector3f dU_vec = dU(u_n, v_n);
Eigen::Vector3f dV_vec = dV(u_n, v_n);
Eigen::Vector3f n = dU_vec.cross(dV_vec);
normal.x() = n.x();
normal.y() = n.y();
normal.z() = n.z();
normal.w() = 0.0f;


/*normal.x() = p.x();
normal.y() = p.y();
normal.z() = p.z();
normal.w() = 0.0f;
normal.normalize();*/
}
};
Loading