diff --git a/src/Light.cc b/src/Light.cc index dddb575..07d7c27 100644 --- a/src/Light.cc +++ b/src/Light.cc @@ -7,3 +7,7 @@ void Light::setTransform(const Matrix4f &transform) { void Light::setGridSize(unsigned int gridSize) { this->gridSize = gridSize; } void Light::setUseCenter(bool useCenter) { this->useCenter = useCenter; } + +void PointLight::illumination() const {} + +void AreaLight::illumination() const {} diff --git a/src/Parser.cc b/src/Parser.cc new file mode 100644 index 0000000..69fabb3 --- /dev/null +++ b/src/Parser.cc @@ -0,0 +1,134 @@ +#include "Parser.h" +#include "Geometry.h" +#include "Light.h" + +#include +#include + +using Eigen::Vector3f; +using Eigen::VectorXi; +using std::string; + +// a helper function to get Vector3f +const Vector3f getVector3f(const nlohmann::json &j) { + return Vector3f(j[0].get(), j[1].get(), j[2].get()); +} + +// A helper function to get raysperpixel array +const VectorXi getRpp(const nlohmann::json &j) { + VectorXi rpp(j.size()); + + for (int i = 0; i < j.size(); ++i) { + rpp[i] = j[i].get(); + } + + return rpp; +} + +Scene *Parser::getScene(const nlohmann::json &j) { + string name = j["filename"].get(); + int width = j["size"][0].get(); + int height = j["size"][1].get(); + float fov = j["fov"].get(); + Vector3f lookAt = getVector3f(j["lookat"]); + Vector3f up = getVector3f(j["up"]); + Vector3f center = getVector3f(j["centre"]); + Vector3f ai = getVector3f(j["ai"]); + Vector3f bgc = getVector3f(j["bkc"]); + + Scene *sc = new Scene(name, width, height, fov, center, up, lookAt, ai, bgc); + sc->setAntialiasing(j.value("antialiasing", false)); + sc->setTwoSideRender(j.value("twosiderender", false)); + sc->setGlobalIllum(j.value("globalillum", false)); + if (j.contains("raysperpixel")) + sc->setRaysPerPixel(getRpp(j["raysperpixel"])); + + return sc; +} + +// TODO: Get Matrix4f transform for geometries and lights +const Matrix4f getTransform(const nlohmann::json &j) { return Matrix4f(); } + +Geometry *Parser::getGeometry(const nlohmann::json &j) { + float ka = j["ka"].get(); + float kd = j["kd"].get(); + float ks = j["ks"].get(); + Vector3f ca = getVector3f(j["ac"]); + Vector3f cd = getVector3f(j["dc"]); + Vector3f cs = getVector3f(j["sc"]); + float phong = j["pc"].get(); + + Geometry *g; + + if (j["type"].get().compare("rectangle")) + g = getSphere(j, ka, kd, ks, ca, cd, cs, phong); + else + g = getRectangle(j, ka, kd, ks, ca, cd, cs, phong); + + if (j.contains("transform")) { + g->setTransform(getTransform(j["transform"])); + } + + return g; +} + +// helper function to get four corners of a rectangle +const Matrix getCorners(const nlohmann::json &j) { + Matrix corners; + for (int i = 0; i < 4; ++i) { + corners.col(i) = getVector3f(j["p" + std::to_string(i + 1)]); + } + return corners; +} + +Sphere *Parser::getSphere(const nlohmann::json &j, float ka, float kd, float ks, + const Vector3f &ca, const Vector3f &cd, + const Vector3f &cs, float pc) { + float radius = j["radius"].get(); + Vector3f center = getVector3f(j["centre"]); + + return new Sphere(ka, kd, ks, ca, cd, cs, pc, radius, center); +} + +Rectangle *Parser::getRectangle(const nlohmann::json &j, float ka, float kd, + float ks, const Vector3f &ca, + const Vector3f &cd, const Vector3f &cs, + float pc) { + Matrix corners = getCorners(j); + + return new Rectangle(ka, kd, ks, ca, cd, cs, pc, corners); +} + +Light *Parser::getLight(const nlohmann::json &j) { + Vector3f id = getVector3f(j["id"]); + Vector3f is = getVector3f(j["is"]); + + Light *l; + if (j["type"].get().compare("point")) + l = getAreaLight(j, id, is); + else + l = getPointLight(j, id, is); + + if (j.contains("transform")) { + l->setTransform(getTransform(j["transform"])); + } + + l->setGridSize(j.value("n", 0)); + l->setUseCenter(j.value("usecenter", false)); + + return l; +} + +AreaLight *Parser::getAreaLight(const nlohmann::json &j, const Vector3f &id, + const Vector3f &is) { + Matrix corners = getCorners(j); + + return new AreaLight(id, is, corners); +} + +PointLight *Parser::getPointLight(const nlohmann::json &j, const Vector3f &id, + const Vector3f &is) { + Vector3f center = getVector3f(j["centre"]); + + return new PointLight(id, is, center); +} diff --git a/src/Parser.h b/src/Parser.h index 709f386..f82c63c 100644 --- a/src/Parser.h +++ b/src/Parser.h @@ -1,6 +1,29 @@ #ifndef PARSER_H_ #define PARSER_H_ -class Parser {}; +#include "../external/json.hpp" + +#include "Geometry.h" +#include "Light.h" +#include "Scene.h" + +class Parser { +public: + static Geometry *getGeometry(const nlohmann::json &); + static Light *getLight(const nlohmann::json &); + static Scene *getScene(const nlohmann::json &); + +private: + static PointLight *getPointLight(const nlohmann::json &, const Vector3f &, + const Vector3f &); + static AreaLight *getAreaLight(const nlohmann::json &, const Vector3f &, + const Vector3f &); + static Rectangle *getRectangle(const nlohmann::json &, float, float, float, + const Vector3f &, const Vector3f &, + const Vector3f &, float); + static Sphere *getSphere(const nlohmann::json &, float, float, float, + const Vector3f &, const Vector3f &, const Vector3f &, + float); +}; #endif // !PARSER_H_ diff --git a/src/RayTracer.cc b/src/RayTracer.cc index cf70d8a..2cb39a1 100644 --- a/src/RayTracer.cc +++ b/src/RayTracer.cc @@ -1,6 +1,35 @@ #include "RayTracer.h" #include "../external/simpleppm.h" +#include "Parser.h" -RayTracer::RayTracer(const nlohmann::json &json) : json(json) {} +#include -void RayTracer::run() {} +using std::vector; + +void RayTracer::parse() { + for (auto i = json["output"].begin(); i != json["output"].end(); ++i) + scenes.push_back(Parser::getScene(*i)); + + for (auto i = json["geometry"].begin(); i != json["geometry"].end(); ++i) + geometries.push_back(Parser::getGeometry(*i)); + + for (auto i = json["light"].begin(); i != json["light"].end(); ++i) + lights.push_back(Parser::getLight(*i)); +} + +void RayTracer::render() {} + +void RayTracer::output() { + for (auto scene : scenes) { + int width = scene->getWidth(); + int height = scene->getHeight(); + vector buffer(3 * width * height); + save_ppm(scene->getName(), buffer, width, height); + } +} + +void RayTracer::run() { + parse(); + render(); + output(); +} diff --git a/src/RayTracer.h b/src/RayTracer.h index 0975344..1c18f19 100644 --- a/src/RayTracer.h +++ b/src/RayTracer.h @@ -2,14 +2,26 @@ #define RAY_TRACER_H_ #include "../external/json.hpp" +#include "Geometry.h" +#include "Light.h" +#include "Scene.h" + +#include class RayTracer { public: - RayTracer(const nlohmann::json &); + RayTracer(const nlohmann::json &j) : json(j) {} void run(); private: nlohmann::json json; + std::vector scenes; + std::vector lights; + std::vector geometries; + + void parse(); + void render(); + void output(); }; #endif // !RAY_TRACER_H_ diff --git a/src/Scene.cc b/src/Scene.cc index 5bec7c5..ea22c48 100644 --- a/src/Scene.cc +++ b/src/Scene.cc @@ -1,5 +1,11 @@ #include "Scene.h" +string Scene::getName() { return name; } + +int Scene::getWidth() { return width; } + +int Scene::getHeight() { return height; } + void Scene::setRaysPerPixel(const Eigen::VectorXi &raysPerPixel) { this->raysPerPixel = raysPerPixel; } diff --git a/src/Scene.h b/src/Scene.h index 0411791..74ec55f 100644 --- a/src/Scene.h +++ b/src/Scene.h @@ -32,6 +32,9 @@ private: bool globalIllum = false; public: + string getName(); + int getWidth(); + int getHeight(); void setRaysPerPixel(const Eigen::VectorXi &); void setAntialiasing(bool); void setTwoSideRender(bool);