aboutsummaryrefslogtreecommitdiff
path: root/src/utils/sceneparser.cpp
diff options
context:
space:
mode:
authorsotech117 <michael_foiani@brown.edu>2023-12-07 16:23:20 -0500
committersotech117 <michael_foiani@brown.edu>2023-12-07 16:23:20 -0500
commitcaa765bff49d54217b75aaf0e7acf4e5392a11e4 (patch)
tree9b92914dfb88b99599e8e60e4512e9e9ea9a25db /src/utils/sceneparser.cpp
parenta9274459443f1d560d7580a162deb581549980cb (diff)
upload base code
Diffstat (limited to 'src/utils/sceneparser.cpp')
-rw-r--r--src/utils/sceneparser.cpp136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/utils/sceneparser.cpp b/src/utils/sceneparser.cpp
new file mode 100644
index 0000000..74c605a
--- /dev/null
+++ b/src/utils/sceneparser.cpp
@@ -0,0 +1,136 @@
+#include "sceneparser.h"
+#include "scenefilereader.h"
+#include <glm/gtx/transform.hpp>
+#include <QImage>
+#include <iostream>
+
+
+/**
+ * @brief Stores the image specified from the input file in this class's
+ * `std::vector<RGBA> m_image`.
+ * @param file: file path to an image
+ * @return True if successfully loads image, False otherwise.
+ */
+TextureData loadTextureFromFile(const QString &file) {
+ QImage myTexture;
+
+ int width; int height;
+ if (!myTexture.load(file)) {
+ std::cout<<"Failed to load in image: " << file.toStdString() << std::endl;
+ return TextureData{0, 0, nullptr};
+ }
+ myTexture = myTexture.convertToFormat(QImage::Format_RGBX8888);
+ width = myTexture.width();
+ height = myTexture.height();
+
+ RGBA* texture = new RGBA[width*height];
+ QByteArray arr = QByteArray::fromRawData((const char*) myTexture.bits(), myTexture.sizeInBytes());
+
+ for (int i = 0; i < arr.size() / 4.f; i++){
+ texture[i] = RGBA{(std::uint8_t) arr[4*i], (std::uint8_t) arr[4*i+1], (std::uint8_t) arr[4*i+2], (std::uint8_t) arr[4*i+3]};
+ }
+
+ return TextureData{width, height, texture};
+}
+
+// helper to handle recursive creation of tree
+void initTree(SceneNode* currentNode, std::vector<RenderShapeData> *shapes, std::vector<SceneLightData> *lights, glm::mat4 currentCTM) {
+ for (auto t : currentNode->transformations) {
+ switch (t->type)
+ {
+ case TransformationType::TRANSFORMATION_TRANSLATE:
+ currentCTM *= glm::translate(glm::vec3(t->translate[0], t->translate[1], t->translate[2]));
+ break;
+ case TransformationType::TRANSFORMATION_SCALE:
+ currentCTM *= glm::scale(glm::vec3(t->scale[0], t->scale[1], t->scale[2]));
+ break;
+ case TransformationType::TRANSFORMATION_ROTATE:
+ currentCTM *= glm::rotate(t->angle, glm::vec3(t->rotate[0], t->rotate[1], t->rotate[2]));
+ break;
+ case TransformationType::TRANSFORMATION_MATRIX:
+ currentCTM *= glm::mat4(t->matrix);
+ break;
+ default:
+ std::cout << "Invalid transformation type" << std::endl;
+ break;
+ }
+ }
+
+
+ for(auto primitive : currentNode->primitives) {
+ primitive->material.textureData = loadTextureFromFile(QString::fromStdString(primitive->material.textureMap.filename));
+ RenderShapeData rsd = {*primitive, currentCTM, glm::inverse(currentCTM)};
+ shapes->push_back(rsd);
+ }
+
+ // add the lights
+ for(auto l : currentNode->lights) {
+ SceneLightData sld{};
+ sld.id = l->id;
+ sld.color = l->color;
+ sld.function = l->function;
+
+ switch (l->type)
+ {
+ case LightType::LIGHT_POINT:
+ sld.type = LightType::LIGHT_POINT;
+ sld.pos = currentCTM * glm::vec4(0.f, 0.f, 0.f, 1.f);
+ sld.dir = glm::vec4(0.0f);
+ break;
+ case LightType::LIGHT_DIRECTIONAL:
+ sld.type = LightType::LIGHT_DIRECTIONAL;
+ sld.pos = glm::vec4(0.0f);
+ sld.dir = glm::vec4(currentCTM * l->dir);
+ break;
+ case LightType::LIGHT_SPOT:
+ sld.type = LightType::LIGHT_SPOT;
+ sld.pos = currentCTM * glm::vec4(0.f, 0.f, 0.f, 1.f);
+ sld.dir = currentCTM * l->dir;
+ sld.penumbra = l->penumbra;
+ sld.angle = l->angle;
+ break;
+ case LightType::LIGHT_AREA:
+ sld.type = LightType::LIGHT_AREA;
+ sld.pos = currentCTM * glm::vec4(0.f, 0.f, 0.f, 1.f);
+ sld.width = l->width;
+ sld.height = l->height;
+ break;
+ default:
+ std::cout << "Invalid light type" << std::endl;
+ continue;
+ }
+
+ lights->push_back(sld);
+ }
+
+ for (auto child : currentNode->children) {
+ initTree(child, shapes, lights, currentCTM);
+ }
+
+}
+
+
+bool SceneParser::parse(std::string filepath, RenderData &renderData) {
+ ScenefileReader fileReader = ScenefileReader(filepath);
+ bool success = fileReader.readJSON();
+ if (!success) {
+ return false;
+ }
+
+ // TODO: Use your Lab 5 code here
+ // Task 5: populate renderData with global data, and camera data;
+ renderData.globalData = fileReader.getGlobalData();
+ renderData.cameraData = fileReader.getCameraData();
+
+ // Task 6: populate renderData's list of primitives and their transforms.
+ // This will involve traversing the scene graph, and we recommend you
+ // create a helper function to do so!
+ SceneNode* root = fileReader.getRootNode();
+ renderData.shapes.clear();
+ renderData.lights.clear();
+ auto currentCTM = glm::mat4(1.0f);
+
+ initTree(root, &renderData.shapes, &renderData.lights, currentCTM);
+
+ return true;
+}