[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
This commit is contained in:
Linloir 2022-12-18 16:10:22 +08:00
parent 2977890457
commit 10a78360ec
No known key found for this signature in database
GPG Key ID: 58EEB209A0F2C366
2 changed files with 33 additions and 44 deletions

View File

@ -13,11 +13,12 @@ Model::~Model() {
// TODO: Maybe delete all meshes?
}
Model::Model(std::vector<Mesh>&& meshes, std::vector<Texture>&& textures, std::string directory) {
Model::Model(std::vector<Mesh>&& meshes, std::vector<Texture>&& 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;
}

View File

@ -2,13 +2,16 @@
#include <vector>
#include <string>
#include <limits>
#include <Assimp/Importer.hpp>
#include <Assimp/scene.h>
#include <Assimp/postprocess.h>
#include "mesh.h"
#include "shader.h"
#include <limits>
#include "boundary.h"
#include "hitrecord.h"
class Model {
public:
enum MODELSTATUS { LOADING, LOADED, ERR };
@ -18,46 +21,33 @@ private:
std::vector<Texture> _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<Mesh>&& meshes, std::vector<Texture>&& textures, std::string directory);
Model(std::vector<Mesh>&& meshes, std::vector<Texture>&& 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<Mesh>& 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<Texture> 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)
};