@@ -343,6 +343,14 @@ class gz::sim::systems::PhysicsPrivate
343
343
// / \param[in] _world The world to disable it for.
344
344
public: void DisableContactSurfaceCustomization (const Entity &_world);
345
345
346
+ // / \brief Update the AxisAlignedBox for link entities.
347
+ // / \param[in] _ecm The entity component manager.
348
+ public: void UpdateLinksBoundingBoxes (EntityComponentManager &_ecm);
349
+
350
+ // / \brief Update the AxisAlignedBox for model entities.
351
+ // / \param[in] _ecm The entity component manager.
352
+ public: void UpdateModelsBoundingBoxes (EntityComponentManager &_ecm);
353
+
346
354
// / \brief Cache the top-level model for each entity.
347
355
// / The key is an entity and the value is its top level model.
348
356
public: std::unordered_map<Entity, Entity> topLevelModelMap;
@@ -555,12 +563,18 @@ class gz::sim::systems::PhysicsPrivate
555
563
556
564
557
565
// ////////////////////////////////////////////////
558
- // Bounding box
566
+ // Model Bounding box
559
567
// / \brief Feature list for model bounding box.
560
- public: struct BoundingBoxFeatureList : physics::FeatureList<
568
+ public: struct ModelBoundingBoxFeatureList : physics::FeatureList<
561
569
MinimumFeatureList,
562
570
physics::GetModelBoundingBox>{};
563
571
572
+ // ////////////////////////////////////////////////
573
+ // Link Bounding box
574
+ // / \brief Feature list for model bounding box.
575
+ public: struct LinkBoundingBoxFeatureList : physics::FeatureList<
576
+ MinimumFeatureList,
577
+ physics::GetLinkBoundingBox>{};
564
578
565
579
// ////////////////////////////////////////////////
566
580
// Joint velocity command
@@ -680,7 +694,7 @@ class gz::sim::systems::PhysicsPrivate
680
694
physics::Model,
681
695
MinimumFeatureList,
682
696
JointFeatureList,
683
- BoundingBoxFeatureList ,
697
+ ModelBoundingBoxFeatureList ,
684
698
NestedModelFeatureList,
685
699
ConstructSdfLinkFeatureList,
686
700
ConstructSdfJointFeatureList>;
@@ -697,7 +711,8 @@ class gz::sim::systems::PhysicsPrivate
697
711
CollisionFeatureList,
698
712
HeightmapFeatureList,
699
713
LinkForceFeatureList,
700
- MeshFeatureList>;
714
+ MeshFeatureList,
715
+ LinkBoundingBoxFeatureList>;
701
716
702
717
// / \brief A map between link entity ids in the ECM to Link Entities in
703
718
// / gz-physics.
@@ -2853,46 +2868,8 @@ void PhysicsPrivate::UpdatePhysics(EntityComponentManager &_ecm)
2853
2868
});
2854
2869
2855
2870
// Populate bounding box info
2856
- // Only compute bounding box if component exists to avoid unnecessary
2857
- // computations
2858
- _ecm.Each <components::Model, components::AxisAlignedBox>(
2859
- [&](const Entity &_entity, const components::Model *,
2860
- components::AxisAlignedBox *_bbox)
2861
- {
2862
- if (!this ->entityModelMap .HasEntity (_entity))
2863
- {
2864
- gzwarn << " Failed to find model [" << _entity << " ]." << std::endl;
2865
- return true ;
2866
- }
2867
-
2868
- auto bbModel =
2869
- this ->entityModelMap .EntityCast <BoundingBoxFeatureList>(_entity);
2870
-
2871
- if (!bbModel)
2872
- {
2873
- static bool informed{false };
2874
- if (!informed)
2875
- {
2876
- gzdbg << " Attempting to get a bounding box, but the physics "
2877
- << " engine doesn't support feature "
2878
- << " [GetModelBoundingBox]. Bounding box won't be populated."
2879
- << std::endl;
2880
- informed = true ;
2881
- }
2882
-
2883
- // Break Each call since no AxisAlignedBox'es can be processed
2884
- return false ;
2885
- }
2886
-
2887
- math::AxisAlignedBox bbox =
2888
- math::eigen3::convert (bbModel->GetAxisAlignedBoundingBox ());
2889
- auto state = _bbox->SetData (bbox, this ->axisAlignedBoxEql ) ?
2890
- ComponentState::PeriodicChange :
2891
- ComponentState::NoChange;
2892
- _ecm.SetChanged (_entity, components::AxisAlignedBox::typeId, state);
2893
-
2894
- return true ;
2895
- });
2871
+ this ->UpdateLinksBoundingBoxes (_ecm);
2872
+ this ->UpdateModelsBoundingBoxes (_ecm);
2896
2873
} // NOLINT readability/fn_size
2897
2874
// TODO (azeey) Reduce size of function and remove the NOLINT above
2898
2875
@@ -4371,6 +4348,107 @@ void PhysicsPrivate::DisableContactSurfaceCustomization(const Entity &_world)
4371
4348
<< _world << " ]" << std::endl;
4372
4349
}
4373
4350
4351
+ // ////////////////////////////////////////////////
4352
+ void PhysicsPrivate::UpdateLinksBoundingBoxes (EntityComponentManager &_ecm)
4353
+ {
4354
+ // Only compute bounding box if component exists to avoid unnecessary
4355
+ // computation for links.
4356
+ _ecm.Each <components::Link, components::AxisAlignedBox>(
4357
+ [&](const Entity &_entity, const components::Link *,
4358
+ components::AxisAlignedBox *_bbox)
4359
+ {
4360
+ auto linkPhys = this ->entityLinkMap .Get (_entity);
4361
+ if (!linkPhys)
4362
+ {
4363
+ gzwarn << " Failed to find link [" << _entity << " ]." << std::endl;
4364
+ return true ;
4365
+ }
4366
+
4367
+ auto bbLink = this ->entityLinkMap .EntityCast <
4368
+ LinkBoundingBoxFeatureList>(_entity);
4369
+
4370
+ // Bounding box expressed in the link frame
4371
+ math::AxisAlignedBox bbox;
4372
+
4373
+ if (bbLink)
4374
+ {
4375
+ bbox = math::eigen3::convert (
4376
+ bbLink->GetAxisAlignedBoundingBox (linkPhys->GetFrameID ()));
4377
+ }
4378
+ else
4379
+ {
4380
+ static bool informed{false };
4381
+ if (!informed)
4382
+ {
4383
+ gzdbg << " Attempting to get a bounding box, but the physics "
4384
+ << " engine doesn't support feature "
4385
+ << " [GetLinkBoundingBox]. Link bounding boxes will be "
4386
+ << " computed from their collision shapes based on their"
4387
+ << " geometry properties in SDF." << std::endl;
4388
+ informed = true ;
4389
+ }
4390
+
4391
+ // Fallback to SDF API to get the link AABB from its collision shapes.
4392
+ // If the link has no collision shapes, the AABB will be invalid.
4393
+ bbox = gz::sim::Link (_entity).ComputeAxisAlignedBox (_ecm).value_or (
4394
+ math::AxisAlignedBox ());
4395
+ }
4396
+
4397
+ auto state = _bbox->SetData (bbox, this ->axisAlignedBoxEql ) ?
4398
+ ComponentState::PeriodicChange :
4399
+ ComponentState::NoChange;
4400
+ _ecm.SetChanged (_entity, components::AxisAlignedBox::typeId, state);
4401
+
4402
+ return true ;
4403
+ });
4404
+ }
4405
+
4406
+ // ////////////////////////////////////////////////
4407
+ void PhysicsPrivate::UpdateModelsBoundingBoxes (EntityComponentManager &_ecm)
4408
+ {
4409
+ // Only compute bounding box if component exists to avoid unnecessary
4410
+ // computation for models.
4411
+ _ecm.Each <components::Model, components::AxisAlignedBox>(
4412
+ [&](const Entity &_entity, const components::Model *,
4413
+ components::AxisAlignedBox *_bbox)
4414
+ {
4415
+ if (!this ->entityModelMap .HasEntity (_entity))
4416
+ {
4417
+ gzwarn << " Failed to find model [" << _entity << " ]." << std::endl;
4418
+ return true ;
4419
+ }
4420
+
4421
+ auto bbModel = this ->entityModelMap .EntityCast <
4422
+ ModelBoundingBoxFeatureList>(_entity);
4423
+
4424
+ if (!bbModel)
4425
+ {
4426
+ static bool informed{false };
4427
+ if (!informed)
4428
+ {
4429
+ gzdbg << " Attempting to get a bounding box, but the physics "
4430
+ << " engine doesn't support feature "
4431
+ << " [GetModelBoundingBox]. Bounding box won't be populated."
4432
+ << std::endl;
4433
+ informed = true ;
4434
+ }
4435
+
4436
+ // Break Each call since no AxisAlignedBox'es can be processed
4437
+ return false ;
4438
+ }
4439
+
4440
+ // Bounding box expressed in the world frame
4441
+ math::AxisAlignedBox bbox =
4442
+ math::eigen3::convert (bbModel->GetAxisAlignedBoundingBox ());
4443
+ auto state = _bbox->SetData (bbox, this ->axisAlignedBoxEql ) ?
4444
+ ComponentState::PeriodicChange :
4445
+ ComponentState::NoChange;
4446
+ _ecm.SetChanged (_entity, components::AxisAlignedBox::typeId, state);
4447
+
4448
+ return true ;
4449
+ });
4450
+ }
4451
+
4374
4452
GZ_ADD_PLUGIN (Physics,
4375
4453
System,
4376
4454
Physics::ISystemConfigure,
0 commit comments