From 10a78360ec69f2c77081cc4473533327ac485e66 Mon Sep 17 00:00:00 2001 From: Linloir <3145078758@qq.com> Date: Sun, 18 Dec 2022 16:10:22 +0800 Subject: [PATCH] [CORE][CHG] Change Model API - Remove old APIs related to boundary box - Add new APIs for boundary generating - Add APIs for hit test - Add APIs for mesh data fetching --- FinalProject/model.cpp | 47 +++++++++++++++++++++--------------------- FinalProject/model.h | 30 +++++++++------------------ 2 files changed, 33 insertions(+), 44 deletions(-) diff --git a/FinalProject/model.cpp b/FinalProject/model.cpp index 1dd519e..38d073e 100644 --- a/FinalProject/model.cpp +++ b/FinalProject/model.cpp @@ -13,11 +13,12 @@ Model::~Model() { // TODO: Maybe delete all meshes? } -Model::Model(std::vector&& meshes, std::vector&& textures, std::string directory) { +Model::Model(std::vector&& meshes, std::vector&& textures, std::string directory, Boundary boundBox) { _meshes = std::move(meshes); _texturesLoaded = std::move(textures); _directory = directory; _status = LOADED; + _boundBox = boundBox; } void Model::loadModel(std::string path) { @@ -38,10 +39,9 @@ void Model::loadModel(std::string path) { Logger::info("Model read successfully"); Logger::info("Processing model nodes"); processNode(scene->mRootNode, scene); + _status = LOADED; Logger::info("Model loaded"); - // 仅检查一次即可 - //checkBoundary(); } void Model::processNode(aiNode* node, const aiScene* scene) { @@ -72,17 +72,13 @@ Mesh Model::processMesh(aiMesh* mesh, const aiScene* scene) { glm::vec3 vertexTangent = glm::vec3(0.0f); glm::vec3 vertexBitangent = glm::vec3(0.0f); - // Process vertex positions - //使用循环避免代码重复,如果可行的话,可以在此循环中确定法向量等信息 - for (int j = 0; j < 3; j++) { - vertexPosition[j] = mesh->mVertices[i][j]; - _leftBackBottomVex[j] = _leftBackBottomVex[j] < vertexPosition[j] ? _leftBackBottomVex[j] : vertexPosition[j]; - _rightFrontTopVex[j] = _rightFrontTopVex[j] > vertexPosition[j] ? _rightFrontTopVex[j] : vertexPosition[j]; - } + // Process vertex position + vertexPosition.x = mesh->mVertices[i].x; + vertexPosition.y = mesh->mVertices[i].y; + vertexPosition.z = mesh->mVertices[i].z; - //vertexPosition.x = mesh->mVertices[i].x; - //vertexPosition.y = mesh->mVertices[i].y; - //vertexPosition.z = mesh->mVertices[i].z; + // Update boundary box + _boundBox.updateControlPoints(vertexPosition); // Process vertex normals if (mesh->mNormals) { @@ -193,18 +189,21 @@ void Model::render(const ShaderProgram& shader) const { } } -void Model::checkBoundary() { - 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++) { - _leftBackBottomVex[k] = _leftBackBottomVex[k] < _meshes[i].vertices()[j]._position[k] ? - _leftBackBottomVex[k] : _meshes[i].vertices()[j]._position[k]; - - _rightFrontTopVex[k] = _rightFrontTopVex[k] > _meshes[i].vertices()[j]._position[k] ? - _rightFrontTopVex[k] : _meshes[i].vertices()[j]._position[k]; +HitRecord Model::hit(const Ray& ray) const { + // 1. use the aabb method to test whether hit the boundary box + // 2. if hit, use the mesh hit method to test whether hit the mesh + + if (_boundBox.hit(ray)) { + for (unsigned int i = 0; i < _meshes.size(); i++) { + HitRecord hitRecord = _meshes[i].hit(ray); + if (hitRecord.hitted()) { + return hitRecord; } } + return HitRecord(); + } + else { + return HitRecord(); // return a false hit record } } @@ -226,6 +225,6 @@ Model* Model::copyToCurrentContext() const { } // Create new model - Model* newModel = new Model(std::move(newMeshes), std::move(newTextures), _directory); + Model* newModel = new Model(std::move(newMeshes), std::move(newTextures), _directory, _boundBox); return newModel; } diff --git a/FinalProject/model.h b/FinalProject/model.h index 5f7888e..589ea17 100644 --- a/FinalProject/model.h +++ b/FinalProject/model.h @@ -2,13 +2,16 @@ #include #include +#include #include #include #include #include "mesh.h" #include "shader.h" -#include +#include "boundary.h" +#include "hitrecord.h" + class Model { public: enum MODELSTATUS { LOADING, LOADED, ERR }; @@ -18,46 +21,33 @@ private: std::vector _texturesLoaded; std::string _directory; MODELSTATUS _status = LOADING; - - // smallest point - glm::vec3 _leftBackBottomVex = glm::vec3(3e36f, 3e36f, 3e36f); - // largest point - glm::vec3 _rightFrontTopVex = -_leftBackBottomVex; + + Boundary _boundBox; // the model's boundary box, won't change after it's initialized public: Model(std::string path); ~Model(); private: - Model(std::vector&& meshes, std::vector&& textures, std::string directory); + Model(std::vector&& meshes, std::vector&& textures, std::string directory, Boundary boundBox); public: inline MODELSTATUS status() const { return _status; } inline int meshCount() const { return _meshes.size(); } inline int textureCount() const { return _texturesLoaded.size(); } inline std::string directory() const { return _directory; } + inline Boundary boundBox() const { return _boundBox; } + inline const std::vector& meshes() const { return _meshes; } Model* copyToCurrentContext() const; - - // maybe we can check if boundary has not been set yet - // Do remember to ensure you have called checkBoundary - inline glm::vec3 upperBoundVex() { - return _rightFrontTopVex; - } - - // Do remember to ensure you have called checkBoundary - inline glm::vec3 lowerBoundVex() { - return _leftBackBottomVex; - } - 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); - void checkBoundary(); public: void render(const ShaderProgram& shader) const; + HitRecord hit(const Ray& ray) const; // test the hit record of an input array (transformed into local space) }; \ No newline at end of file