Skip to content

Introduce OrientedBoundingBox - #961

Open
zhx06 wants to merge 1 commit into
mainfrom
zxiao/feature/object_oriented_bbox
Open

Introduce OrientedBoundingBox#961
zhx06 wants to merge 1 commit into
mainfrom
zxiao/feature/object_oriented_bbox

Conversation

@zhx06

@zhx06 zhx06 commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add oriented bounding box support

##Detailed description

  • Replace AABBs with rotation-aware OBBs.
  • Propagate full quaternions through placement and results.
  • Extend mesh collision and cuRobo integration to 3D rotations.

Signed-off-by: zhx06 <zihaox@nvidia.com>
@greptile-apps

greptile-apps Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Introduces rotation-aware oriented bounding boxes throughout placement and collision handling.

  • Replaces axis-aligned bounding-box representations with quaternion-aware OBB geometry.
  • Propagates full 3D rotations through relation solving, placement validation, mesh collision checks, and placement results.
  • Updates ObjectReference scaling and transforms for rotated referenced geometry.
  • Converts OBBs into correctly oriented cuRobo collision cuboids for IK reachability validation.
  • Expands tests and visualization helpers for rotated boxes and poses.

Confidence Score: 5/5

The PR appears safe to merge; no concrete changed-code defect was identified.

The reviewed OBB, solver, validator, mesh-collision, ObjectReference, and cuRobo paths consistently use xyzw quaternions, compose local-to-world rotations in the same order, preserve pose-relative box centers, and keep matching relation losses and validators geometrically aligned.

Important Files Changed

Filename Overview
isaaclab_arena/utils/bounding_box.py Replaces the AABB abstraction with batched quaternion-aware OBB construction, transformation, projection, corner generation, and SAT penetration operations.
isaaclab_arena/assets/object_reference.py Applies parent scaling in the referenced prim’s frame and propagates composed rotations into local bounds, world bounds, and collision meshes.
isaaclab_arena/relations/relation_solver_state.py Carries full candidate rotations through solver state and derives dynamic FaceTo orientations while producing transformed OBBs.
isaaclab_arena/relations/object_placer.py Generates, validates, and applies full quaternion placement orientations instead of yaw-only footprints.
isaaclab_arena/relations/no_overlap_obb.py Replaces axis-aligned overlap loss with OBB penetration computed through separating-axis projections.
isaaclab_arena/relations/placement_validators.py Updates spatial-relation and collision validation to evaluate rotation-aware world bounding boxes.
isaaclab_arena/relations/no_overlap_mesh.py Extends mesh broadphase and frame transformations to full quaternion poses and oriented bounding-box proxies.
isaaclab_arena_curobo/utils/ik_solver_utils.py Builds cuRobo cuboids by composing object poses with intrinsic OBB centers and orientations.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  USD[USD geometry] --> OBB[Local OrientedBoundingBox]
  OBB --> ENV[Per-environment boxes]
  ENV --> STATE[Relation solver state]
  STATE --> LOSS[Relation and overlap losses]
  STATE --> POSE[Full quaternion placement poses]
  POSE --> VALIDATE[Placement validators]
  POSE --> MESH[Warp mesh collision transforms]
  POSE --> CUROBO[cuRobo oriented cuboids]
  VALIDATE --> RESULT[Placement result]
  MESH --> RESULT
  CUROBO --> RESULT
Loading

Reviews (1): Last reviewed commit: "introduce oriented bbox" | Re-trigger Greptile

return manager.get_query_spheres(box_mesh).to(device)


def _bbox_proxy_mesh(bbox: OrientedBoundingBox) -> trimesh.Trimesh | None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Duplicated OBB→box-mesh conversion

This builds a trimesh box from an OBB (extents, quaternion_matrix(np.roll(...)), translate) — the same steps NoOverlapValidator._collision_mesh_or_bbox_proxy runs in placement_validators.py. Could the conversion live once, e.g. as a small OrientedBoundingBox.to_box_mesh() (or a shared helper both call), so the two copies can't drift apart?

from typing import TYPE_CHECKING, ClassVar, cast

from isaaclab_arena.relations.collision_mode import CollisionMode, get_object_collision_mode, object_uses_mesh_collision
from isaaclab_arena.relations.no_overlap_mesh import transform_points_between_frames

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Generic geometry helper imported from the collision module

transform_points_between_frames is a plain quaternion frame transform, but it lives in no_overlap_mesh.py and is pulled in here. Would a shared home (e.g. utils/pose or a small transforms util) fit better, so the validator doesn't reach into the collision-loss module for basic geometry?

radius = torch.bmm(rotation.abs(), self.half_extents.unsqueeze(-1)).squeeze(-1)
return self.center - radius, self.center + radius

def is_axis_aligned(self, atol: float = 1e-5) -> torch.Tensor:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 is_axis_aligned looks unused

The only caller I can find is its own unit test — no production use. Is it needed now, or can it be dropped until something actually uses it?

@arena-review-bot

Copy link
Copy Markdown
Contributor

🤖 Isaac Lab-Arena Review Bot

Summary

This PR replaces the axis-aligned bounding box with a batched OrientedBoundingBox and threads full xyzw rotations through placement, validation, the relation solver, mesh/OBB collision, debug draw, and the cuRobo cuboids. It is a large but cohesive, well-typed refactor: the new type keeps invariants by construction (unit-quat / non-negative half-extent asserts, from_tensors_unchecked fast paths), the per-env vectorization in no_overlap_mesh preserves the old per-pair-mean semantics, and it is backed by substantial test additions (OBB geometry, reference objects, mesh collision, reachability). Overall read: solid, ship-quality once a few small cleanups are considered.

Findings

🔵 Improvement_bbox_proxy_mesh (no_overlap_mesh.py) and _collision_mesh_or_bbox_proxy (placement_validators.py) build the same OBB→trimesh box; factor into one shared helper / OrientedBoundingBox method.
🔵 Improvementtransform_points_between_frames is a generic frame transform living in the collision module but imported by the validators; a shared utils home would read cleaner.
🔵 ImprovementOrientedBoundingBox.is_axis_aligned appears to have no production caller (only its own test).

Notes (non-blocking)

The no-overlap collision loss changes from an overlap-volume product (slope=10000) to SAT min-penetration (new collision_loss_slope=1000), which alters the solver's optimization dynamics for every placement. This looks intentional and better-conditioned (penetration is in metres, dimensionally consistent with the relation losses it now sits 10× above), and it is covered by tests — flagging only so the recalibration is a conscious choice rather than incidental.

Test Coverage

Good. The changed suites cover the new OBB math, rotated reference objects, mesh/OBB collision parity, and reachability-cuboid orientation, including negative/identity-fallback cases. These are pure-Python (non-sim) tests, so the inner/outer run_simulation_app_function pattern is not required here.

Verdict

Ship it (minor cleanups optional).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant