Skip to content
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

Mesh joining for unstable Bullet collision compounds. #317

Merged
merged 47 commits into from
Dec 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7f28c46
Store mesh bounding boxes computed during load.
aclegg3 Sep 20, 2019
428b155
Add bounding boxes to drawables on object instancing.
aclegg3 Sep 23, 2019
e385e1d
Fixed bounding box rendering option
aclegg3 Sep 23, 2019
4ce03d2
Moved primitive initialization into loadScene
aclegg3 Sep 23, 2019
fb5bfb7
Cleanup unused includes
aclegg3 Sep 23, 2019
3fa94e6
Bounding box and drawable node moved to RigidBody. Added BB display t…
aclegg3 Sep 24, 2019
3796ca7
Merge remote-tracking branch 'origin/master' into loaded-mesh-boundin…
aclegg3 Sep 24, 2019
579d463
Enable directory loading and global filepaths in object lib loader fr…
aclegg3 Sep 25, 2019
453ca46
BB moved to SceneNode level with recursive hierarchy construction.
aclegg3 Sep 26, 2019
fec7e4a
Merge branch 'improve_object_lib_loading' into loaded-mesh-bounding-b…
aclegg3 Sep 26, 2019
998291a
Debugging stuff, bounding box draw adjusted and working.
aclegg3 Sep 27, 2019
74004e6
Merge remote-tracking branch 'origin/master' into loaded-mesh-boundin…
aclegg3 Oct 1, 2019
3f8e21a
Docs and cleanup
aclegg3 Oct 1, 2019
7bc7aee
Removed wayfair from default config
aclegg3 Oct 1, 2019
27d71ee
Merge remote-tracking branch 'origin/master' into loaded-mesh-boundin…
aclegg3 Oct 1, 2019
2bb8618
Link Magnum::Primitives to assets
aclegg3 Oct 1, 2019
bbf7c42
Cleaned debugging output. Added BB toggle demo to Viewer.cpp 'B' key.
aclegg3 Oct 7, 2019
807743d
Use dynamic_cast isntead of static_cast
aclegg3 Oct 9, 2019
b0dd67f
Changed toggleBBDraw to setObjectBBDraw with boolean input. Modified …
aclegg3 Oct 9, 2019
864f37a
Addressed review comments
aclegg3 Oct 11, 2019
74e3e26
revert change to default object library
aclegg3 Oct 11, 2019
1515f48
Hierarchy building, copying, addComponenet usage, scenes and objects …
aclegg3 Oct 15, 2019
1b08397
Enable Magnum BulletIntegration DebugDraw in viewer.
aclegg3 Oct 15, 2019
4a57df4
Merge remote-tracking branch 'origin/bullet-debug-draw' into mesh_tra…
aclegg3 Oct 15, 2019
e6ec869
Cleanup debugging calls
aclegg3 Oct 15, 2019
4d77389
Merge remote-tracking branch 'origin/master' into store-mesh-transfor…
aclegg3 Oct 16, 2019
045b6e5
Merge remote-tracking branch 'origin/master' into loaded-mesh-boundin…
aclegg3 Oct 16, 2019
fe3e410
Made bounding boxes protected members and added getters/setters.
aclegg3 Oct 16, 2019
828a65c
Converted if to CHECK to throw exception instead of failing silently.
aclegg3 Oct 16, 2019
4a375a3
Building bullet compound collision object from hierarchies of convexi…
aclegg3 Oct 16, 2019
618a116
Merge remote-tracking branch 'origin/master' into bullet-collision-fr…
aclegg3 Oct 16, 2019
e9ceb54
Cleanup
aclegg3 Oct 16, 2019
be137f7
Merge remote-tracking branch 'origin/master' into loaded-mesh-boundin…
aclegg3 Oct 17, 2019
31c450b
Merge branch 'loaded-mesh-bounding-boxes' into bounding-box-com-shift
aclegg3 Oct 17, 2019
9d0442b
Bounding box shift for Bullet compound shapes and testing code
aclegg3 Oct 17, 2019
62c5364
Remove testing code. Cleanup old mesh shifting code. Added Bool DataT…
aclegg3 Oct 17, 2019
fc4b847
Added join mesh default for stable collision behavior.
aclegg3 Oct 22, 2019
6756f2d
Added physics object parser option for collision mesh joining
aclegg3 Oct 22, 2019
2957adf
Merge remote-tracking branch 'origin/master' into bounding-box-com-shift
aclegg3 Oct 22, 2019
d9bdff0
revert changes to default physics library paths
aclegg3 Oct 22, 2019
4a4b36c
Merge remote-tracking branch 'origin/master' into bounding-box-com-shift
aclegg3 Nov 1, 2019
52bf926
undo join code reverted with merge
aclegg3 Nov 1, 2019
ee0968d
revert change to default objects
aclegg3 Nov 1, 2019
26a602e
Merge remote-tracking branch 'origin/master' into bounding-box-com-shift
aclegg3 Dec 9, 2019
cfd3c64
Added physics C++ test for mesh joining. Added docs. Added small test…
aclegg3 Dec 10, 2019
d619dd7
addressed comment
aclegg3 Dec 10, 2019
cf919e9
removed unnecessary copy constructor
aclegg3 Dec 10, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added data/test_assets/objects/nested_box.glb
Binary file not shown.
4 changes: 4 additions & 0 deletions data/test_assets/objects/nested_box.phys_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"render mesh": "nested_box.glb",
"join collision meshes": false
}
Binary file added data/test_assets/scenes/plane.glb
Binary file not shown.
6 changes: 6 additions & 0 deletions src/esp/assets/Attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,12 @@ PhysicsObjectAttributes::PhysicsObjectAttributes() {
setString("originHandle", "");
setString("renderMeshHandle", "");
setString("collisionMeshHandle", "");
setBool("useBoundingBoxForCollision",
false); // if true, override other options and TODO: use bounding box
// as collision object
setBool("joinCollisionMeshes",
true); // if true, join all meshes into one collision convex instead
// of building a compound
}

PhysicsSceneAttributes::PhysicsSceneAttributes() {
Expand Down
12 changes: 0 additions & 12 deletions src/esp/assets/MeshMetaData.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,6 @@ struct MeshTransformNode {
materialIDLocal = ID_UNDEFINED;
componentID = ID_UNDEFINED;
};

//! copy constructor which duplicates the @ref MeshTransformNode tree of which
//! val is the root.
MeshTransformNode(const MeshTransformNode& val) {
componentID = val.componentID;
meshIDLocal = val.meshIDLocal;
materialIDLocal = val.materialIDLocal;
T_parent_local = Magnum::Matrix4(val.T_parent_local);
for (auto& child : val.children) {
children.push_back(MeshTransformNode(child));
}
}
};
aclegg3 marked this conversation as resolved.
Show resolved Hide resolved

// for each scene (mesh file),
Expand Down
156 changes: 92 additions & 64 deletions src/esp/assets/ResourceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ bool ResourceManager::loadScene(
PhysicsManagerAttributes physicsManagerAttributes =
loadPhysicsConfig(physicsFilename);
physicsManagerLibrary_[physicsFilename] = physicsManagerAttributes;

return loadScene(info, _physicsManager, physicsManagerAttributes, parent,
drawables);
}
Expand Down Expand Up @@ -233,6 +232,8 @@ bool ResourceManager::loadScene(

PhysicsManagerAttributes ResourceManager::loadPhysicsConfig(
std::string physicsFilename) {
CHECK(Cr::Utility::Directory::exists(physicsFilename));

// Load the global scene config JSON here
io::JsonDocument scenePhysicsConfig = io::parseJsonFile(physicsFilename);
// In-memory representation of scene meta data
Expand Down Expand Up @@ -390,6 +391,80 @@ PhysicsObjectAttributes& ResourceManager::getPhysicsObjectAttributes(
return physicsObjectLibrary_[objectName];
}

int ResourceManager::loadObject(PhysicsObjectAttributes& objectTemplate,
const std::string objectTemplateHandle) {
CHECK(physicsObjectLibrary_.count(objectTemplateHandle) == 0);
CHECK(objectTemplate.existsAs(STRING, "renderMeshHandle"));

// load/check_for render and collision mesh metadata
//! Get render mesh names
std::string renderMeshFilename = objectTemplate.getString("renderMeshHandle");
std::string collisionMeshFilename = "";

if (objectTemplate.existsAs(STRING, "collisionMeshHandle")) {
collisionMeshFilename = objectTemplate.getString("collisionMeshHandle");
}

bool renderMeshSuccess = false;
bool collisionMeshSuccess = false;
AssetInfo renderMeshinfo;
AssetInfo collisionMeshinfo;

//! Load rendering mesh
if (!renderMeshFilename.empty()) {
renderMeshinfo = assets::AssetInfo::fromPath(renderMeshFilename);
renderMeshSuccess = loadGeneralMeshData(renderMeshinfo);
if (!renderMeshSuccess) {
LOG(ERROR) << "Failed to load a physical object's render mesh: "
<< objectTemplateHandle << ", " << renderMeshFilename;
}
}
//! Load collision mesh
if (!collisionMeshFilename.empty()) {
collisionMeshinfo = assets::AssetInfo::fromPath(collisionMeshFilename);
collisionMeshSuccess = loadGeneralMeshData(collisionMeshinfo);
if (!collisionMeshSuccess) {
LOG(ERROR) << "Failed to load a physical object's collision mesh: "
<< objectTemplateHandle << ", " << collisionMeshFilename;
}
}

if (!renderMeshSuccess && !collisionMeshSuccess) {
// we only allow objects with SOME mesh file. Failing
// both loads or having no mesh will cancel the load.
LOG(ERROR) << "Failed to load a physical object: no meshes...: "
<< objectTemplateHandle;
return ID_UNDEFINED;
}

// handle one missing mesh
if (!renderMeshSuccess)
objectTemplate.setString("renderMeshHandle", collisionMeshFilename);
if (!collisionMeshSuccess)
objectTemplate.setString("collisionMeshHandle", renderMeshFilename);

// cache metaData, collision mesh Group
physicsObjectLibrary_.emplace(objectTemplateHandle, objectTemplate);
MeshMetaData& meshMetaData =
resourceDict_.at(objectTemplate.getString("collisionMeshHandle"));

int start = meshMetaData.meshIndex.first;
int end = meshMetaData.meshIndex.second;
//! Gather mesh components for meshGroup data
std::vector<CollisionMeshData> meshGroup;
for (int mesh_i = start; mesh_i <= end; mesh_i++) {
GltfMeshData* gltfMeshData =
dynamic_cast<GltfMeshData*>(meshes_[mesh_i].get());
CollisionMeshData& meshData = gltfMeshData->getCollisionMeshData();
meshGroup.push_back(meshData);
}
collisionMeshGroups_.emplace(objectTemplateHandle, meshGroup);
physicsObjectConfigList_.push_back(objectTemplateHandle);

int objectID = physicsObjectConfigList_.size() - 1;
return objectID;
}

// load object from config filename
int ResourceManager::loadObject(const std::string& objPhysConfigFilename) {
// check for duplicate load
Expand Down Expand Up @@ -500,8 +575,19 @@ int ResourceManager::loadObject(const std::string& objPhysConfigFilename) {
}
}

// 3. load/check_for render and collision mesh metadata
//! Get render mesh names
//! Get collision configuration options if specified
if (objPhysicsConfig.HasMember("join collision meshes")) {
if (objPhysicsConfig["join collision meshes"].IsBool()) {
physicsObjectAttributes.setBool(
"joinCollisionMeshes",
objPhysicsConfig["join collision meshes"].GetBool());
} else {
LOG(ERROR)
<< " Invalid value in object physics config - join collision meshes";
}
}

// 4. parse render and collision mesh filepaths
std::string renderMeshFilename = "";
std::string collisionMeshFilename = "";

Expand All @@ -523,70 +609,12 @@ int ResourceManager::loadObject(const std::string& objPhysConfigFilename) {
}
}

bool renderMeshSuccess = false;
bool collisionMeshSuccess = false;
AssetInfo renderMeshinfo;
AssetInfo collisionMeshinfo;

//! Load rendering mesh
if (!renderMeshFilename.empty()) {
renderMeshinfo = assets::AssetInfo::fromPath(renderMeshFilename);
renderMeshSuccess = loadGeneralMeshData(renderMeshinfo);
if (!renderMeshSuccess) {
LOG(ERROR) << "Failed to load a physical object's render mesh: "
<< objPhysConfigFilename << ", " << renderMeshFilename;
}
}
//! Load collision mesh
if (!collisionMeshFilename.empty()) {
collisionMeshinfo = assets::AssetInfo::fromPath(collisionMeshFilename);
collisionMeshSuccess = loadGeneralMeshData(collisionMeshinfo);
if (!collisionMeshSuccess) {
LOG(ERROR) << "Failed to load a physical object's collision mesh: "
<< objPhysConfigFilename << ", " << collisionMeshFilename;
}
}

if (!renderMeshSuccess && !collisionMeshSuccess) {
// we only allow objects with SOME mesh file. Failing
// both loads or having no mesh will cancel the load.
LOG(ERROR) << "Failed to load a physical object: no meshes...: "
<< objPhysConfigFilename;
return ID_UNDEFINED;
}

physicsObjectAttributes.setString("renderMeshHandle", renderMeshFilename);
physicsObjectAttributes.setString("collisionMeshHandle",
collisionMeshFilename);

// handle one missing mesh
if (!renderMeshSuccess)
physicsObjectAttributes.setString("renderMeshHandle",
collisionMeshFilename);
if (!collisionMeshSuccess)
physicsObjectAttributes.setString("collisionMeshHandle",
renderMeshFilename);

// 5. cache metaData, collision mesh Group
physicsObjectLibrary_.emplace(objPhysConfigFilename, physicsObjectAttributes);
MeshMetaData& meshMetaData = resourceDict_.at(
physicsObjectAttributes.getString("collisionMeshHandle"));

int start = meshMetaData.meshIndex.first;
int end = meshMetaData.meshIndex.second;
//! Gather mesh components for meshGroup data
std::vector<CollisionMeshData> meshGroup;
for (int mesh_i = start; mesh_i <= end; mesh_i++) {
GltfMeshData* gltfMeshData =
dynamic_cast<GltfMeshData*>(meshes_[mesh_i].get());
CollisionMeshData& meshData = gltfMeshData->getCollisionMeshData();
meshGroup.push_back(meshData);
}
collisionMeshGroups_.emplace(objPhysConfigFilename, meshGroup);
physicsObjectConfigList_.push_back(objPhysConfigFilename);

int objectID = physicsObjectConfigList_.size() - 1;
return objectID;
// 5. load the parsed file into the library
return loadObject(physicsObjectAttributes, objPhysConfigFilename);
}

const std::vector<assets::CollisionMeshData>& ResourceManager::getCollisionMesh(
Expand Down Expand Up @@ -1101,7 +1129,7 @@ void ResourceManager::loadTextures(Importer& importer, MeshMetaData* metaData) {
void ResourceManager::addComponent(const MeshMetaData& metaData,
scene::SceneNode& parent,
DrawableGroup* drawables,
MeshTransformNode& meshTransformNode) {
const MeshTransformNode& meshTransformNode) {
// Add the object to the scene and set its transformation
scene::SceneNode& node = parent.createChild();
node.MagnumObject::setTransformation(meshTransformNode.T_parent_local);
Expand Down
43 changes: 36 additions & 7 deletions src/esp/assets/ResourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,21 +100,50 @@ class ResourceManager {
DrawableGroup* drawables = nullptr,
std::string physicsFilename = "data/default.phys_scene_config.json");

// load a PhysicsSceneMetaData object from a config file
/**
* @brief Load and parse a physics world config file and generates a @ref
* PhysicsManagerAttributes object.
* @param physicsFilename The config file.
* @return The resulting @ref PhysicsManagerAttributes object.
*/
PhysicsManagerAttributes loadPhysicsConfig(
std::string physicsFilename = "data/default.phys_scene_config.json");

//! Load Object data and store internally
//! Does not instantiate (physics & drawable)
//! Return index in physicsObjectList_
/**
* @brief Load the drawable for an object from the @ref physicsObjectLibrary_
* into the scene graph. Attempts to load and parse the referenced object
* template file into the @ref physicsObjectLibrary_ if not already present.
* @param objPhysConfigFilename The string key for the object template in the
* @ref physicsObjectLibrary_.
* @param parent The parent @ref scene::SceneNode for the object.
* @param drawables The @ref DrawableGroup for the object drawable.
* @return the object's index in @ref physicsObjectList_
*/
int loadObject(const std::string& objPhysConfigFilename,
scene::SceneNode* parent,
DrawableGroup* drawables);

// load an object into the physicsObjectLibrary_ from a physics properties
// filename
/**
* @brief Load and parse a physics object template config file and generates a
* @ref PhysicsObjectAttributes object, adding it to the @ref
* physicsObjectLibrary_.
* @param objPhysConfigFilename The config file.
* @return The index in the @ref physicsObjectLibrary_ of the resulting @ref
* PhysicsObjectAttributes object.
*/
int loadObject(const std::string& objPhysConfigFilename);

/**
* @brief Add a @ref PhysicsObjectAttributes object to the @ref
* physicsObjectLibrary_. Can modify template values based on results of load.
* @param objectTemplateHandle The key for referencing the template in the
* @ref physicsObjectLibrary_.
* @param objectTemplate The object template.
* @return The index in the @ref physicsObjectLibrary_ of object template.
*/
int loadObject(PhysicsObjectAttributes& objectTemplate,
const std::string objectTemplateHandle);

//======== Accessor functions ========
const std::vector<assets::CollisionMeshData>& getCollisionMesh(
const std::string configFile);
Expand Down Expand Up @@ -161,7 +190,7 @@ class ResourceManager {
void addComponent(const MeshMetaData& metaData,
scene::SceneNode& parent,
DrawableGroup* drawables,
MeshTransformNode& meshTransformNode);
const MeshTransformNode& meshTransformNode);

//! Load textures from importer into assets, and update metaData
void loadTextures(Importer& importer, MeshMetaData* metaData);
Expand Down
5 changes: 5 additions & 0 deletions src/esp/physics/PhysicsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ int PhysicsManager::checkActiveObjects() {
return numActive;
}

bool PhysicsManager::isActive(const int physObjectID) const {
assertIDValidity(physObjectID);
return existingObjects_.at(physObjectID)->isActive();
}

void PhysicsManager::applyForce(const int physObjectID,
const Magnum::Vector3& force,
const Magnum::Vector3& relPos) {
Expand Down
Loading