diff --git a/Controller.cpp b/Controller.cpp index ed2e7d6..d3d07a4 100644 --- a/Controller.cpp +++ b/Controller.cpp @@ -20,6 +20,8 @@ using namespace std; Controller::Controller(istream& scenegraphFile, Model& m,View& v): model(m), view(v) { initScenegraph(scenegraphFile); + view.useRaycast = true; + globalCamera = new StationaryCamera(glm::vec3(0.0, 0.0, 20.0)); globalCamera->LookAt(glm::vec3(0.0,0.0,0.0)); cameras.push_back(globalCamera); diff --git a/View.cpp b/View.cpp index 0eedfa4..e020b64 100644 --- a/View.cpp +++ b/View.cpp @@ -5,6 +5,7 @@ #include "PolygonMesh.h" #include "TextureImage.h" #include "sgraph/LightAccumulator.h" +#include "sgraph/RaycastRenderer.hpp" #include #include #include @@ -96,6 +97,8 @@ void View::init(Callbacks *callbacks, Model& model) deltaTime = 0; renderer = new sgraph::GLScenegraphRenderer(modelview,objects,textureIds,shaderLocations); + raycastRenderer = new sgraph::RaycastRenderer(modelview,objects); + model.getScenegraph()->getRoot()->accept(raycastRenderer); } diff --git a/View.h b/View.h index e4a624e..7e13a71 100644 --- a/View.h +++ b/View.h @@ -2,6 +2,7 @@ #define __VIEW_H__ #include "../include/Light.h" +#include "sgraph/RaycastRenderer.hpp" #ifndef GLFW_INCLUDE_NONE #define GLFW_INCLUDE_NONE #endif @@ -41,6 +42,9 @@ class View bool shouldWindowClose(); void closeWindow(); + bool useRaycast = false; + + private: void initObjects(Model& model); vector getLightPositions(const glm::mat4& transformation); @@ -56,6 +60,7 @@ class View glm::mat4 projection; stack modelview; sgraph::SGNodeVisitor *renderer; + sgraph::RaycastRenderer *raycastRenderer; int frames; double time; double deltaTime; diff --git a/sgraph/RaycastRenderer.hpp b/sgraph/RaycastRenderer.hpp new file mode 100644 index 0000000..9480ff9 --- /dev/null +++ b/sgraph/RaycastRenderer.hpp @@ -0,0 +1,122 @@ +#ifndef _RAYCASTRENDERER_H_ +#define _RAYCASTRENDERER_H_ + +#include "SGNodeVisitor.h" +#include "GroupNode.h" +#include "LeafNode.h" +#include "TransformNode.h" +#include "RotateTransform.h" +#include "ScaleTransform.h" +#include "TranslateTransform.h" +#include +#include +#include +#include "ObjectInstance.h" +#include +#include +#include + +using namespace std; + +namespace sgraph { + /** + * This visitor implements drawing the scene graph using OpenGL + * + */ + class RaycastRenderer: public SGNodeVisitor { + public: + /** + * @brief Construct a new RaycastRenderer object + * + * @param mv a reference to modelview stack that will be used while rendering + * @param os the map of ObjectInstance objects + * @param shaderLocations the shader locations for the program used to render + */ + RaycastRenderer(stack& mv,map& os) + : modelview(mv) + , objects(os) { + for (map::iterator it=objects.begin();it!=objects.end();it++) { + cout << "Mesh with name: "<< it->first << endl; + } + } + + /** + * @brief Recur to the children for drawing + * + * @param groupNode + */ + void visitGroupNode(GroupNode *groupNode) { + for (int i=0;igetChildren().size();i=i+1) { + groupNode->getChildren()[i]->accept(this); + } + } + + /** + * @brief Draw the instance for the leaf, after passing the + * modelview and color to the shader + * + * @param leafNode + */ + void visitLeafNode(LeafNode *leafNode) { + + util::Material mat = leafNode->getMaterial(); + + //send modelview matrix to GPU + glm::mat4 normalmatrix = glm::inverse(glm::transpose((modelview.top()))); + + string name = leafNode->getInstanceOf(); + modelviewMap.emplace(name, modelview.top()); + normalmatrixMap.emplace(name, normalmatrix); + } + + /** + * @brief Multiply the transform to the modelview and recur to child + * + * @param transformNode + */ + void visitTransformNode(TransformNode * transformNode) { + modelview.push(modelview.top()); + modelview.top() = modelview.top() * transformNode->getTransform(); + if (transformNode->getChildren().size()>0) { + transformNode->getChildren()[0]->accept(this); + } + modelview.pop(); + } + + /** + * @brief For this visitor, only the transformation matrix is required. + * Thus there is nothing special to be done for each type of transformation. + * We delegate to visitTransformNode above + * + * @param scaleNode + */ + void visitScaleTransform(ScaleTransform *scaleNode) { + visitTransformNode(scaleNode); + } + + /** + * @brief For this visitor, only the transformation matrix is required. + * Thus there is nothing special to be done for each type of transformation. + * We delegate to visitTransformNode above + * + * @param translateNode + */ + void visitTranslateTransform(TranslateTransform *translateNode) { + visitTransformNode(translateNode); + } + + void visitRotateTransform(RotateTransform *rotateNode) { + visitTransformNode(rotateNode); + } + + private: + stack& modelview; + map objects; + // TODO: map textures; + unordered_map modelviewMap; + unordered_map normalmatrixMap; + + }; +} + +#endif