COSC-3P93-Project/Step 2/include/types.h

127 lines
4.9 KiB
C
Raw Normal View History

2022-10-18 00:44:49 -04:00
/*
* Created by Brett Terpstra 6920201 on 18/10/22.
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*/
#ifndef STEP_2_TYPES_H
#define STEP_2_TYPES_H
#include <math/vectors.h>
#include <math/colliders.h>
2022-10-18 23:11:51 -04:00
#include <utility>
2022-10-18 00:44:49 -04:00
// there were some files which needed access to these types
// but including them from world.h would've resulted in circular includes,
// so I moved them here.
namespace Raytracing {
2022-10-18 23:11:51 -04:00
2022-10-18 00:44:49 -04:00
struct HitData {
// all the other values only matter if this is true
bool hit{false};
// the hit point on the object
2022-10-18 23:11:51 -04:00
Vec4 hitPoint{};
2022-10-18 00:44:49 -04:00
// the normal of that hit point
2022-10-18 23:11:51 -04:00
Vec4 normal{};
2022-10-18 00:44:49 -04:00
// the length of the vector from its origin in its direction.
PRECISION_TYPE length{0};
};
struct ScatterResults {
// returns true to recast the ray with the provided ray
bool scattered;
// the new ray to be cast if scattered
Ray newRay;
// the color of the material
2022-10-18 23:11:51 -04:00
Vec4 attenuationColor;
};
// triangle type for model loading
struct Triangle {
public:
Vec4 vertex1, vertex2, vertex3;
bool hasNormals = false;
Vec4 normal1, normal2, normal3;
Vec4 uv1, uv2, uv3;
AABB aabb;
Triangle(const Vec4& v1, const Vec4& v2, const Vec4& v3): vertex1(v1), vertex2(v2), vertex3(v3) {}
Triangle(const Vec4& v1, const Vec4& v2, const Vec4& v3,
const Vec4& n1, const Vec4& n2, const Vec4& n3): vertex1(v1), vertex2(v2), vertex3(v3),
hasNormals(true), normal1(n1), normal2(n2), normal3(n3) {}
Triangle(const Vec4& v1, const Vec4& v2, const Vec4& v3,
const Vec4& uv1, const Vec4& uv2, const Vec4& uv3,
const Vec4& n1, const Vec4& n2, const Vec4& n3): vertex1(v1), vertex2(v2), vertex3(v3),
uv1(uv1), uv2(uv2), uv3(uv3),
hasNormals(true), normal1(n1), normal2(n2), normal3(n3) {}
// slow method, not really required as all normals should be equal
[[nodiscard]] Vec4 findClosestNormal(const Vec4& point) const {
// no need to sqrt as exact distance doesn't matter
auto n1Dist = (point - normal1).lengthSquared();
auto n2Dist = (point - normal2).lengthSquared();
auto n3Dist = (point - normal3).lengthSquared();
return (n1Dist < n2Dist && n1Dist < n3Dist) ? normal1 : (n2Dist < n3Dist ? normal2 : normal3);
}
};
// face type for model loading
struct face {
int v1, v2, v3;
int uv1, uv2, uv3;
int n1, n2, n3;
2022-10-18 00:44:49 -04:00
};
class Material {
private:
// most materials will need an albedo
2022-10-18 23:11:51 -04:00
Vec4 baseColor;
2022-10-18 00:44:49 -04:00
public:
2022-10-18 23:11:51 -04:00
explicit Material(const Vec4& baseColor): baseColor(baseColor) {}
2022-10-18 00:44:49 -04:00
// returns true if the ray was scattered along with the scattered ray, otherwise will return false with empty ray.
// the returned vec4 is the attenuation color
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const = 0;
2022-10-18 23:11:51 -04:00
[[nodiscard]] Vec4 getBaseColor() const { return baseColor; }
virtual ~Material() = default;
2022-10-18 00:44:49 -04:00
};
class Object {
protected:
AABB aabb;
2022-10-18 23:11:51 -04:00
Vec4 position;
Material* material;
2022-10-18 00:44:49 -04:00
public:
2022-10-18 23:11:51 -04:00
Object(Material* material, const Vec4& position): material(material), position(position), aabb({}) {};
2022-10-18 00:44:49 -04:00
// return true if the ray intersects with this object, only between min and max
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const = 0;
[[nodiscard]] Material* getMaterial() const { return material; }
2022-10-18 23:11:51 -04:00
virtual Object* clone() = 0;
virtual AABB& getAABB() { return aabb; }
virtual void setAABB(const AABB& ab) { this->aabb = ab; }
[[nodiscard]] Vec4 getPosition() const { return position; }
2022-10-18 00:44:49 -04:00
virtual ~Object() = default;
};
2022-10-18 23:11:51 -04:00
// used for using an object, mostly BVH
class EmptyObject : public Object {
protected:
public:
Triangle& tri;
EmptyObject(const Vec4& position, const AABB& a, Triangle& tri): Object(nullptr, position), tri(tri) {this->aabb = a;};
// unused
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const {
wlog << "Warning! A empty object has made its way into the raycaster!\n";
return {};
}
virtual Object* clone(){return new EmptyObject(position, aabb, tri);}
};
2022-10-18 00:44:49 -04:00
}
#endif //STEP_2_TYPES_H