diff --git a/Editor/ObjectWindow.cpp b/Editor/ObjectWindow.cpp index 5efe2058c..3959b6724 100644 --- a/Editor/ObjectWindow.cpp +++ b/Editor/ObjectWindow.cpp @@ -580,7 +580,7 @@ void ObjectWindow::Create(EditorComponent* editor) AddWidget(&lineardampingSlider); angulardampingSlider.Create(0, 1, 0, 100000, "Angular Damping: "); - angulardampingSlider.SetTooltip("Set the mass amount for the physics engine."); + angulardampingSlider.SetTooltip("Set the angular damping amount for the physics engine."); angulardampingSlider.SetSize(XMFLOAT2(100, hei)); angulardampingSlider.SetPos(XMFLOAT2(x, y += step)); angulardampingSlider.OnSlide([&](wi::gui::EventArgs args) { @@ -592,6 +592,24 @@ void ObjectWindow::Create(EditorComponent* editor) }); AddWidget(&angulardampingSlider); + physicsMeshLODSlider.Create(0, 6, 0, 6, "Physics Mesh LOD: "); + physicsMeshLODSlider.SetTooltip("Specify which LOD to use for triangle mesh physics."); + physicsMeshLODSlider.SetSize(XMFLOAT2(100, hei)); + physicsMeshLODSlider.SetPos(XMFLOAT2(x, y += step)); + physicsMeshLODSlider.OnSlide([&](wi::gui::EventArgs args) { + RigidBodyPhysicsComponent* physicscomponent = wi::scene::GetScene().rigidbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + if (physicscomponent->mesh_lod != uint32_t(args.iValue)) + { + physicscomponent->physicsobject = nullptr; // will be recreated automatically + physicscomponent->mesh_lod = uint32_t(args.iValue); + } + physicscomponent->mesh_lod = uint32_t(args.iValue); + } + }); + AddWidget(&physicsMeshLODSlider); + kinematicCheckBox.Create("Kinematic: "); kinematicCheckBox.SetTooltip("Toggle kinematic behaviour."); kinematicCheckBox.SetSize(XMFLOAT2(hei, hei)); @@ -864,6 +882,7 @@ void ObjectWindow::SetEntity(Entity entity) restitutionSlider.SetEnabled(true); lineardampingSlider.SetEnabled(true); angulardampingSlider.SetEnabled(true); + physicsMeshLODSlider.SetEnabled(true); if (physicsComponent != nullptr) { @@ -872,6 +891,7 @@ void ObjectWindow::SetEntity(Entity entity) restitutionSlider.SetValue(physicsComponent->restitution); lineardampingSlider.SetValue(physicsComponent->damping_linear); angulardampingSlider.SetValue(physicsComponent->damping_angular); + physicsMeshLODSlider.SetValue(float(physicsComponent->mesh_lod)); kinematicCheckBox.SetCheck(physicsComponent->IsKinematic()); disabledeactivationCheckBox.SetCheck(physicsComponent->IsDisableDeactivation()); diff --git a/Editor/ObjectWindow.h b/Editor/ObjectWindow.h index 55c87a518..32c2e9ee0 100644 --- a/Editor/ObjectWindow.h +++ b/Editor/ObjectWindow.h @@ -32,6 +32,7 @@ public: wi::gui::Slider restitutionSlider; wi::gui::Slider lineardampingSlider; wi::gui::Slider angulardampingSlider; + wi::gui::Slider physicsMeshLODSlider; wi::gui::CheckBox disabledeactivationCheckBox; wi::gui::CheckBox kinematicCheckBox; diff --git a/WickedEngine/wiPhysics_Bullet.cpp b/WickedEngine/wiPhysics_Bullet.cpp index 7d6dc872f..3040257c7 100644 --- a/WickedEngine/wiPhysics_Bullet.cpp +++ b/WickedEngine/wiPhysics_Bullet.cpp @@ -140,22 +140,26 @@ namespace wi::physics case RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH: if(mesh != nullptr) { - int totalVerts = (int)mesh->vertex_positions.size(); int totalTriangles = 0; + int* indices = nullptr; uint32_t first_subset = 0; uint32_t last_subset = 0; - mesh->GetLODSubsetRange(0, first_subset, last_subset); + mesh->GetLODSubsetRange(physicscomponent.mesh_lod, first_subset, last_subset); for (uint32_t subsetIndex = first_subset; subsetIndex < last_subset; ++subsetIndex) { const MeshComponent::MeshSubset& subset = mesh->subsets[subsetIndex]; + if (indices == nullptr) + { + indices = (int*)(mesh->indices.data() + subset.indexOffset); + } totalTriangles += int(subset.indexCount / 3); } btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray( totalTriangles, - (int*)mesh->indices.data(), + indices, 3 * sizeof(int), - totalVerts, + int(mesh->vertex_positions.size()), (btScalar*)mesh->vertex_positions.data(), sizeof(XMFLOAT3) ); @@ -253,22 +257,28 @@ namespace wi::physics btVerts[i * 3 + 2] = btScalar(position.z); } - const int iCount = (int)mesh.indices.size(); - const int tCount = iCount / 3; - wi::vector btInd(iCount); - for (int i = 0; i < iCount; ++i) + wi::vector btInd; + btInd.reserve(mesh.indices.size()); + uint32_t first_subset = 0; + uint32_t last_subset = 0; + mesh.GetLODSubsetRange(0, first_subset, last_subset); + for (uint32_t subsetIndex = first_subset; subsetIndex < last_subset; ++subsetIndex) { - uint32_t ind = mesh.indices[i]; - uint32_t mappedIndex = physicscomponent.graphicsToPhysicsVertexMapping[ind]; - btInd[i] = (int)mappedIndex; + const MeshComponent::MeshSubset& subset = mesh.subsets[subsetIndex]; + const uint32_t* indices = mesh.indices.data() + subset.indexOffset; + for (uint32_t i = 0; i < subset.indexCount; ++i) + { + btInd.push_back((int)physicscomponent.graphicsToPhysicsVertexMapping[indices[i]]); + } } + // This function uses new to allocate btSoftbody internally: btSoftBody* softbody = btSoftBodyHelpers::CreateFromTriMesh( - dynamicsWorld.getWorldInfo() - , btVerts.data() - , btInd.data() - , tCount - , false + dynamicsWorld.getWorldInfo(), + btVerts.data(), + btInd.data(), + int(btInd.size() / 3), + false ); if (softbody) diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h index 463d2e14d..1044ddb69 100644 --- a/WickedEngine/wiScene.h +++ b/WickedEngine/wiScene.h @@ -757,8 +757,13 @@ namespace wi::scene float height = 1; } capsule; + // This will force LOD level for rigid body if it is a TRIANGLE_MESH shape: + // The geometry for LOD level will be taken from MeshComponent. + // The physics object will need to be recreated for it to take effect. + uint32_t mesh_lod = 0; + // Non-serialized attributes: - void* physicsobject = nullptr; + void* physicsobject = nullptr; // You can set to null to recreate the physics object the next time phsyics system will be running. inline void SetDisableDeactivation(bool value) { if (value) { _flags |= DISABLE_DEACTIVATION; } else { _flags &= ~DISABLE_DEACTIVATION; } } inline void SetKinematic(bool value) { if (value) { _flags |= KINEMATIC; } else { _flags &= ~KINEMATIC; } } diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index b6e097854..136a16092 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 70; // minor bug fixes, alterations, refactors, updates - const int revision = 5; + const int revision = 6; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);