Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <cstdlib>
- #include <fstream>
- #include <sstream>
- #define STB_IMAGE_IMPLEMENTATION
- #include "stb_image.h"
- #define STBI_MSC_SECURE_CRT
- #define STB_IMAGE_WRITE_IMPLEMENTATION
- #include "stb_image_write.h"
- using namespace std;
- struct Vector3
- {
- float x, y, z;
- Vector3() { x = y = z = 0; }
- Vector3(float x, float y, float z) : x(x), y(y), z(z) {}
- inline Vector3& operator=(const Vector3& v)
- {
- x = v.x;
- y = v.y;
- z = v.z;
- return *this;
- }
- inline bool operator==(const Vector3& v)
- {
- return (x == v.x && y == v.y && z == v.z);
- }
- inline Vector3 operator+(const Vector3& v)
- {
- return Vector3(x + v.x, y + v.y, z + v.z);
- }
- inline Vector3 operator-(const Vector3& v)
- {
- return Vector3(x - v.x, y - v.y, z - v.z);
- }
- inline float dot(const Vector3& v)
- {
- return (x * v.x) + (y * v.y) + (z * v.z);
- }
- inline Vector3 scalarMultiply(float scalar)
- {
- return Vector3(x * scalar, y * scalar, z * scalar);
- }
- inline Vector3 crossProduct(const Vector3& v)
- {
- return Vector3(y*v.z - z * v.y, z*v.x - x * v.z, x*v.y - y * v.x);
- }
- inline float magnitude()
- {
- return sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- }
- inline Vector3 normalize()
- {
- Vector3 n = *this;
- return n.scalarMultiply(1 / n.magnitude());
- }
- inline string intToString()
- {
- return "<" + to_string((int)x) + " " + to_string((int)y) + " " + to_string((int)z) + ">" + " ";
- }
- inline string floatToString()
- {
- return "<" + to_string((float)x) + " " + to_string((float)y) + " " + to_string((float)z) + ">" + " ";
- }
- };
- struct Color
- {
- uint8_t r, g, b;
- Color() { r = g = b = 0; }
- Color(uint8_t r, uint8_t g, uint8_t b) : r(r), g(g), b(b) {}
- };
- struct Ray
- {
- Vector3 origin, direction;
- Ray() : origin(Vector3()), direction(Vector3(0, 0, 1)) {}
- Ray(Vector3 origin, Vector3 direction) : origin(origin), direction(direction) {}
- };
- struct Plane
- {
- Vector3 normal;
- float distance;
- Vector3 point;
- Color color;
- Plane(Vector3 normal, float distance, Color color) :normal(normal), distance(distance), color(color) {}
- bool intersected(Ray &ray, float &t)
- {
- Vector3 n = normal.normalize();
- t = -(ray.origin.dot(n) + distance) / (ray.direction.normalize().dot(n));
- if (t <= 0)
- {
- return false;
- }
- else
- {
- return true;
- }
- }
- };
- struct OBB
- {
- Vector3 u;
- Vector3 v;
- Vector3 w;
- Vector3 center;
- Color color;
- Vector3 sideDirecitons[3] = { u, v, w };
- float halfLengths[3];
- OBB(Vector3 u, Vector3 v, Vector3 w, Vector3 center, Color color) :u(u), v(v), w(w), center(center), color(color)
- {
- for(int i = 0; i < 3; i++)
- {
- sideDirecitons[i] = sideDirecitons[i].normalize();
- cout << sideDirecitons[i].intToString();
- }
- for(int i = 0; i < 3; i++)
- {
- halfLengths[i] = (center - sideDirecitons[i]).magnitude();
- }
- };
- bool intersected(Ray &ray, float &t)
- {
- float tMin = -INFINITY;
- float tMax = INFINITY;
- Vector3 p = center - ray.origin;
- for (int i = 0; i < 3; i++)
- {
- float e = sideDirecitons[i].dot(p);
- float f = sideDirecitons[i].dot(ray.direction);
- if(abs(f) > FLT_EPSILON)
- {
- float t1 = (e + halfLengths[i]) / f;
- float t2 = (e - halfLengths[i]) / f;
- if(t1 > t2)
- {
- swap(t1, t2);
- }
- if (t1 > tMin)
- {
- tMin = t1;
- }
- if (t2 < tMax)
- {
- tMax = t2;
- }
- if (tMin > tMax)
- {
- return false;
- }
- if (tMax < 0)
- {
- return false;
- }
- }
- else if (-e - halfLengths[i] > 0 || -e + halfLengths[i] < 0)
- {
- return false;
- }
- }
- if (tMin > 0)
- {
- return true;
- }
- else
- {
- return true;
- }
- }
- };
- struct Triangle
- {
- Vector3 a, b, c;
- Color color;
- Triangle(Vector3 a, Vector3 b, Vector3 c, Color color) : a(a), b(b), c(c), color(color) {};
- bool intersected(Ray &ray, float &t, float &u, float &v)
- {
- Vector3 ba = b - a;
- Vector3 ca = c - a;
- Vector3 q = ray.direction.crossProduct(ca);
- float det = ba.dot(q);
- if (det > -FLT_EPSILON && det < FLT_EPSILON)
- {
- return false;
- }
- else
- {
- float f = 1 / det;
- Vector3 s = ray.origin - a;
- float u = f * (s.dot(q));
- if (u < 0.0f)
- {
- return false;
- }
- Vector3 r = s.crossProduct(ba);
- float v = f * (ray.direction.dot(r));
- if (v < 0.0f || u + v > 1.0f)
- {
- return false;
- }
- t = f * (ca.dot(r));
- return true;
- }
- }
- };
- struct Sphere
- {
- Vector3 center;
- float radius;
- Color color;
- Sphere(Vector3 center, float radius, Color color) : center(center), radius(radius), color(color) {}
- bool intersected(Ray &ray, float &t)
- {
- Vector3 d = ray.direction.normalize();
- Vector3 oc = ray.origin - center;
- float b = d.dot(oc);
- float c = (oc).dot(oc) - pow(radius, 2);
- float discriminant = pow(b, 2) - c;
- if (discriminant < 0)
- {
- return false;
- }
- else
- {
- discriminant = sqrt(discriminant);
- float t1 = -b - discriminant;
- float t2 = -b + discriminant;
- t = (t1 < t2) ? t1 : t2;
- return true;
- }
- }
- };
- void setPixel(uint8_t* imgPtr, int width, int nrOfChannels, int x, int y, Color &color)
- {
- int index = (y * width + x) * nrOfChannels;
- imgPtr[index] = color.r;
- imgPtr[index + 1] = color.g;
- imgPtr[index + 2] = color.b;
- }
- int main()
- {
- const int width = 256;
- const int height = 256;
- const int nrOfChannels = 3;
- Sphere sphere(Vector3(width / 2, height / 2, 50), 50, Color(0, 255, 255));
- Plane plane(Vector3(0, 0, -1), 1, Color(0, 0, 255));
- Triangle triangle(Vector3(20, 20, 0), Vector3(100, 100, 0), Vector3(150, 50, 0), Color(255, 0, 0));
- OBB obb(Vector3(1, 0, 0), Vector3(0, 1, 0), Vector3(0, 0, 1), Vector3(20,20,5), Color(0, 255, 0));
- uint8_t* imageData = new uint8_t[width*height * nrOfChannels];
- int index = 0;
- for (int j = 0; j < height; j++)
- {
- for (int i = 0; i < width; i++)
- {
- Color gray(100, 100, 100);
- setPixel(imageData, width, nrOfChannels, i, j, gray);
- }
- }
- for (int j = 0; j < height; j++)
- {
- for (int i = 0; i < width; i++)
- {
- float t, u, v = 0;
- float nearest;
- Ray ray(Vector3(i, j, 0), Vector3(0, 0, 1));
- if (plane.intersected(ray, t))
- {
- setPixel(imageData, width, nrOfChannels, i, j, plane.color);
- }
- if (sphere.intersected(ray, t))
- {
- setPixel(imageData, width, nrOfChannels, i, j, sphere.color);
- }
- if (triangle.intersected(ray, t, u, v))
- {
- setPixel(imageData, width, nrOfChannels, i, j, triangle.color);
- }
- if(obb.intersected(ray,t))
- {
- setPixel(imageData, width, nrOfChannels, i, j, obb.color);
- }
- }
- }
- cout << "done" << endl;
- stbi_write_png("bruh.png", width, height, nrOfChannels, imageData, width * nrOfChannels);
- delete[] imageData;
- getchar();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement