diff --git a/FinalProject/model.cpp b/FinalProject/model.cpp index 1809c28..e1db286 100644 --- a/FinalProject/model.cpp +++ b/FinalProject/model.cpp @@ -34,6 +34,8 @@ void Model::loadModel(std::string path) { processNode(scene->mRootNode, scene); _status = LOADED; Logger::info("Model loaded"); + // 仅检查一次即可 + //check_boundary(); } void Model::processNode(aiNode* node, const aiScene* scene) { @@ -65,9 +67,16 @@ Mesh Model::processMesh(aiMesh* mesh, const aiScene* scene) { glm::vec3 vertexBitangent = glm::vec3(0.0f); // Process vertex positions - vertexPosition.x = mesh->mVertices[i].x; - vertexPosition.y = mesh->mVertices[i].y; - vertexPosition.z = mesh->mVertices[i].z; + //使用循环避免代码重复,如果可行的话,可以在此循环中确定法向量等信息 + for (int j = 0; j < 3; j++) { + vertexPosition[j] = mesh->mVertices[i][j]; + _left_down_back[j] = _left_down_back[j] < vertexPosition[j] ? _left_down_back[j] : vertexPosition[j]; + _right_up_front[j] = _right_up_front[j] > vertexPosition[j] ? _right_up_front[j] : vertexPosition[j]; + } + + //vertexPosition.x = mesh->mVertices[i].x; + //vertexPosition.y = mesh->mVertices[i].y; + //vertexPosition.z = mesh->mVertices[i].z; // Process vertex normals if (mesh->mNormals) { @@ -177,3 +186,19 @@ void Model::render(const ShaderProgram& shader) const { _meshes[i].render(shader); } } + +void Model::check_boundary() { + for (int i = 0; i < _meshes.size(); i++) { + for (int j = 0; j < _meshes[i].vertices().size();j++) { + // 0,1,2 for x,y,z + for (int k = 0; k < 3; k++) { + _left_down_back[k] = _left_down_back[k] < _meshes[i].vertices()[j]._position[k] ? + _left_down_back[k] : _meshes[i].vertices()[j]._position[k]; + + _right_up_front[k] = _right_up_front[k] > _meshes[i].vertices()[j]._position[k] ? + _right_up_front[k] : _meshes[i].vertices()[j]._position[k]; + } + } + } + +} \ No newline at end of file diff --git a/FinalProject/model.h b/FinalProject/model.h index 2e319d2..7f3df3a 100644 --- a/FinalProject/model.h +++ b/FinalProject/model.h @@ -8,7 +8,7 @@ #include "mesh.h" #include "shader.h" - +#include class Model { public: enum MODELSTATUS { LOADING, LOADED, ERR }; @@ -19,6 +19,11 @@ private: std::string _directory; MODELSTATUS _status = LOADING; + // smallest point + glm::vec3 _left_down_back = glm::vec3(3e36f, 3e36f, 3e36f); + // largest point + glm::vec3 _right_up_front = -_left_down_back; + public: Model(std::string path); ~Model(); @@ -26,12 +31,31 @@ public: public: inline MODELSTATUS status() const { return _status; } + + // maybe we can check if boundary has not been set yet + // Do remember to ensure you have called check_boundary + inline glm::vec3 get_upper_bound() { + return _right_up_front; + } + + // Do remember to ensure you have called check_boundary + inline glm::vec3 get_lower_bound() { + return _left_down_back; + } + private: void loadModel(std::string path); void processNode(aiNode* node, const aiScene* scene); Mesh processMesh(aiMesh* mesh, const aiScene* scene); std::vector loadMaterialTextures(aiMaterial* mat, aiTextureType type, TextureType textureType); + // Since these are loacl position, this function should be called just once. + void check_boundary(); public: void render(const ShaderProgram& shader) const; + + + + // maybe we can encapsure a function to get both upper and lower bound? + }; \ No newline at end of file diff --git a/FinalProject/renderable.cpp b/FinalProject/renderable.cpp index 86463a1..16eb8a2 100644 --- a/FinalProject/renderable.cpp +++ b/FinalProject/renderable.cpp @@ -2,6 +2,8 @@ #include "renderable.h" +// 极值点一定在model包围盒的顶点处取到 + Renderable::Renderable(Model* model) : _model(model) {} Renderable::Renderable(Model* model, glm::vec3 position) : _model(model), _position(position) {} @@ -36,3 +38,22 @@ void Renderable::render(ShaderProgram shader) { // Render _model->render(shader); } + +// check here to get global boundary +// must check before get boundary +void Renderable::check_boundary() { + std::vector temp = {_model->get_upper_bound(),_model->get_lower_bound()}; + _lower_bound = glm::vec3(3e36, 3e36, 3e36); + _upper_bound = -_lower_bound; + auto model = this->modelMatrix();// 变换矩阵 + // 位运算 从000到111的每一种组合 + for (int i = 0; i < 8; i++) { + //遍历每一个顶点 + glm::vec4 vx = glm::vec4(temp[(i & 4) >> 2][0], temp[(i & 2)>>1][1], temp[i & 1][2], 1.0f); + auto vex = model * vx; // 经过变化之后的点的坐标 + for (int j = 0; j < 3; j++) { + _lower_bound[j] = _lower_bound[j] < vex[j] ? _lower_bound[j] : vex[j]; + _upper_bound[j] = _upper_bound[j] > vex[j] ? _upper_bound[j] : vex[j]; + } + } +} \ No newline at end of file diff --git a/FinalProject/renderable.h b/FinalProject/renderable.h index 7e5912a..1ae9fe3 100644 --- a/FinalProject/renderable.h +++ b/FinalProject/renderable.h @@ -12,6 +12,9 @@ private: glm::vec3 _position = glm::vec3(0.0f); glm::mat4 _rotation = glm::mat4(1.0f); glm::vec3 _scale = glm::vec3(1.0f); + // 下面是与坐标轴平行的顶点 + glm::vec3 _lower_bound; + glm::vec3 _upper_bound; public: Renderable(Model* model); @@ -27,14 +30,28 @@ public: inline glm::mat4 modelMatrix() const; + inline glm::vec3 get_upper_boundary()const; + inline glm::vec3 get_lower_boundary()const; + public: void render(ShaderProgram shader); + // check here to get global boundary + void check_boundary(); }; inline glm::mat4 Renderable::modelMatrix() const { glm::mat4 model = glm::mat4(1.0f); model = glm::translate(model, _position); - model = model * _rotation; + // 左乘与右乘应该是不一样的,但是这里的表现相同 + //model = model * _rotation; + model = _rotation * model; model = glm::scale(model, _scale); return model; } + +inline glm::vec3 Renderable::get_lower_boundary()const { + return _lower_bound; +} +inline glm::vec3 Renderable::get_upper_boundary()const { + return _upper_bound; +} \ No newline at end of file diff --git a/FinalProject/sceneviewer.cpp b/FinalProject/sceneviewer.cpp index 2ddb15f..6f60c35 100644 --- a/FinalProject/sceneviewer.cpp +++ b/FinalProject/sceneviewer.cpp @@ -65,12 +65,14 @@ void SceneViewer::initializeGL() { vertexShader.dispose(); fragmentShader.dispose(); - Model* backpackModel = new Model("E:\\Repositories\\CollegeProjects\\CGAssignments\\FinalProject\\Models\\backpack\\backpack.obj"); + Model* backpackModel = new Model("D:/code/ComputerGraphic/SceneEditor/obj/nanosuit/nanosuit.obj"); Logger::info("Model loaded"); Renderable backpack(backpackModel); _objects.push_back(backpack); + _camera.setPosition(glm::vec3(0.0f, 0.0f, 5.0f)); + } void SceneViewer::resizeGL(int w, int h) {