-
Notifications
You must be signed in to change notification settings - Fork 419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[culling] Compute absolute AABB (NOT the existing local AABB) for each mesh component of the static scene (ptex, mp3d ONLY) #400
Conversation
Code is ready to be reviewed. Thanks. |
@msb: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/esp/assets/ResourceManager.h
Outdated
// | ||
// -) ptex mesh: | ||
// meshID is the index of the submesh corresponding to the drawable; | ||
std::vector<std::pair<std::reference_wrapper<esp::gfx::Drawable>, uint32_t>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This vector is concerning. Are we sure that we won't try to access the drawable after it gets deleted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a valid concern. However, it is unlikely to happen.
This variable so far is used as a "temporary" variable that is to collect drawables, and meshIDs at the loading stage. After that, it will not be used any more.
It is needed in multiple functions, so that I put it here as a member variable to avoid passing it as a function parameter.
I think solution is easy:
What I can do to address your concern is to clear this vector after its job is completed in loading stage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the drawable being used in anyway besides getting access to the node? If so, why not store a reference to the scene node? The scene node and drawable should have very similar lifetimes so it should be equally safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, good suggestion. In terms of functionality, both methods are the same. But I read my code, and what you suggested can potentially lead to simpler code. So why not? Let me try to change it.
These 2 AABBs are different. |
src/esp/assets/ResourceManager.h
Outdated
// | ||
// -) ptex mesh: | ||
// meshID is the index of the submesh corresponding to the drawable; | ||
std::vector<std::pair<std::reference_wrapper<esp::gfx::Drawable>, uint32_t>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a valid concern. However, it is unlikely to happen.
This variable so far is used as a "temporary" variable that is to collect drawables, and meshIDs at the loading stage. After that, it will not be used any more.
It is needed in multiple functions, so that I put it here as a member variable to avoid passing it as a function parameter.
I think solution is easy:
What I can do to address your concern is to clear this vector after its job is completed in loading stage.
Note: |
The correctness of the computed absolute AABBs was tested in the branch called "culling":
|
Agreed, we'd need to compute an OBB in the first place. Then that can be either converted to an AABB or transformed and converted to an AABB. |
src/esp/assets/ResourceManager.h
Outdated
// | ||
// -) ptex mesh: | ||
// meshID is the index of the submesh corresponding to the drawable; | ||
std::vector<std::pair<std::reference_wrapper<esp::gfx::Drawable>, uint32_t>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, good suggestion. In terms of functionality, both methods are the same. But I read my code, and what you suggested can potentially lead to simpler code. So why not? Let me try to change it.
This PR is ready to be reviewed. |
src/esp/assets/ResourceManager.cpp
Outdated
drawables}; | ||
|
||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) | ||
gfx::PTexMeshDrawable* d = new gfx::PTexMeshDrawable{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this can just be new gfx::PTexMeshDrawable{node, *ptexShader, *pTexMeshData, jSubmesh, drawables};
again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, right. Good catch. It was needed before as I stored drawables in previous commits. (Now I store the scene node).
src/esp/assets/ResourceManager.cpp
Outdated
|
||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) | ||
gfx::PrimitiveIDDrawable* d = | ||
new gfx::PrimitiveIDDrawable{node, *shader, mesh, group}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change can be undone.
src/esp/assets/ResourceManager.cpp
Outdated
objectId, color); | ||
|
||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) | ||
gfx::GenericDrawable* d = new gfx::GenericDrawable{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, minor comments. I understand the desire for precise bounding boxes for the single static scene given worst case approximation.
Would be curious to know the difference between the approximate and precise bounding boxes computed over the Gibson or Replica datasets.
src/esp/assets/ResourceManager.cpp
Outdated
@@ -65,6 +69,13 @@ namespace assets { | |||
bool ResourceManager::loadScene(const AssetInfo& info, | |||
scene::SceneNode* parent, /* = nullptr */ | |||
DrawableGroup* drawables /* = nullptr */) { | |||
// we only compute absolute AABB for evey mesh component when loading ptex |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: every
src/esp/assets/ResourceManager.h
Outdated
*/ | ||
void computeGeneralMeshAbsoluteAABBs(); | ||
|
||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/**
src/esp/assets/ResourceManager.h
Outdated
// this helper vector contains information of the drawables on which we will | ||
// compute the absolute AABB | ||
// | ||
// pair: <Drawable's scene node, meshID> | ||
// | ||
// -) non-ptex mesh: | ||
// meshID is the global index into meshes_. | ||
// meshes_[meshID] is the BaseMesh corresponding to the drawable; | ||
// | ||
// -) ptex mesh: | ||
// meshID is the index of the submesh corresponding to the drawable; | ||
std::vector< | ||
std::pair<std::reference_wrapper<esp::scene::SceneNode>, uint32_t>> | ||
staticDrawableInfo_; | ||
bool computeAbsoluteAABBs_ = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reformat the comments for docs? 😃
@aclegg3 :
Good question. To answer it, I need to do experiment to collect data and compare the culling rate. To compute the absolute AABB instead of approximation, better accuracy is indeed a purpose. However, there is another even more important reason -- save computation. Because, culling test can only be done when frustum and the bounding box are in the same space (e.g., world, camera, or model space). And to make the test efficient, the bounding box must be a AABB. If we use the existing "local" AABB in the scene node (developed by you), we will have to transform the frustum by a constant transformation matrix from clip space to model space (because the bounding box is a AABB only in the model space). That means we need to compute the "mvp" for every object in every frame. But with the absolute AABB, we only need to compute "vp" once for all objects in every frame. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a test.
src/esp/assets/ResourceManager.cpp
Outdated
} | ||
|
||
void ResourceManager::createDrawable( | ||
const ShaderType shaderType, | ||
Magnum::GL::Mesh& mesh, | ||
scene::SceneNode& node, | ||
Corrade::Containers::Optional<uint32_t> meshID, /* = NullOpt */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We seem to be over-loading createDrawable with a lot o responsiblities. Not sure if the code might be simpler if it the new functionality were added to addMeshToDrawables instead.
src/esp/assets/ResourceManager.h
Outdated
* -) ptex mesh: | ||
* meshID is the index of the submesh corresponding to the drawable; | ||
*/ | ||
std::vector< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use a proper struct instead of a pair since this is used in such a large scope.
It also seems like this should really be a local variable instead of a member for this.
Synced up with @msbaines offline. His comments on data and code structures, tests makes a lot of sense. I really appreciated it. Will change accordingly. |
Ready for another round review while I am writing the unit tests. |
Codecov Report
@@ Coverage Diff @@
## master #400 +/- ##
=========================================
Coverage ? 57.46%
=========================================
Files ? 160
Lines ? 6983
Branches ? 84
=========================================
Hits ? 4013
Misses ? 2970
Partials ? 0
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One suggestion.
src/esp/assets/ResourceManager.cpp
Outdated
@@ -649,6 +687,113 @@ Magnum::Range3D ResourceManager::computeMeshBB(BaseMesh* meshDataGL) { | |||
return Magnum::Range3D{ | |||
Magnum::Math::minmax<Magnum::Vector3>(meshData.positions)}; | |||
} | |||
void ResourceManager::computePTexMeshAbsoluteAABBs(BaseMesh& baseMesh) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, it makes sense to #ifdef
the function definition itself instead of the implementation. If we aren't building with ptex, then we can assume this method should/will never be called, so there shouldn't be any code that requires this blank implementation right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to me. Will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still #ifdef'ing the implementation and not the whole function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually cannot add #ifdef
to the entire function definition since it would cause the CI test failure. When compiling js, it complained undefined symbols.
If you look at the other functions, e.g., loadPTexMeshData
, we did the same thing, namely, adding the conditionals on the body, not the entire definition. So the function is just empty.
I guess I will just leave it like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you also need to #ifdef
it in the header file.
Dear reviewers, Just added the test as requested. |
src/esp/assets/ResourceManager.cpp
Outdated
@@ -649,6 +687,113 @@ Magnum::Range3D ResourceManager::computeMeshBB(BaseMesh* meshDataGL) { | |||
return Magnum::Range3D{ | |||
Magnum::Math::minmax<Magnum::Vector3>(meshData.positions)}; | |||
} | |||
void ResourceManager::computePTexMeshAbsoluteAABBs(BaseMesh& baseMesh) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still #ifdef'ing the implementation and not the whole function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for the record, I don't have any comments/requests regarding this code, everything seems in order. 👍 for using mesh tools and batch functions to calculate transformed vertex AABBs.
docs: remove :ref: as a default role.
…h mesh component of the static scene (ptex, mp3d ONLY) (facebookresearch#400) * working in progress * Done: -) compute the absTransform; -) staticDrawables_; TODO: absPositions * DONE: abs aabb for MP3D TODO: abs aabb for ptex * DONE: abs aabb ptex * fix typo, modify comments * minor * minor * try to address Erik's concern * change the pair in staticDrwableInfo_ from <drawable, meshID> to <sceneNode, meshID> * minor * minor * minor * minor * address CI errors * partially address Mandeep's concern. * minor * using reference directly instead of reference wrapper. Make life a little bit simpler * adding tests (in progress) * correct the path * minor * added tests * address reviewer's concern. * minor * address reviewer's concern
Motivation and Context
Each mesh component corresponds to a static drawable. Static drawables have fixed absolute transformations during the runtime. Repeat computation is not necessary;
absolute AABB will be used in the frustum culling process;
more details: [DO NOT accept][Experiment only] Some quick, hacky tests on frustum culling #380
Existing issue: #390
How Has This Been Tested
local
Types of changes
Checklist