-
Notifications
You must be signed in to change notification settings - Fork 619
Add dedicated gravity for global world -1 #3724
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
base: main
Are you sure you want to change the base?
Changes from all commits
36c5d75
f41fc92
b809688
04e0d20
62b56bb
ded6b63
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1277,7 +1277,13 @@ def __init__(self, device: Devicelike | None = None): | |
| self.up_axis: int = 2 | ||
| """Up axis: 0 for x, 1 for y, 2 for z.""" | ||
| self.gravity: wp.array[wp.vec3] | None = None | ||
| """Per-world gravity vectors [m/s²], shape [world_count, 3], dtype :class:`vec3`.""" | ||
| """Local-world and global gravity vectors [m/s²], dtype :class:`vec3`. | ||
|
|
||
| Models with explicit local worlds have shape [world_count + 1], where | ||
| the final element is the gravity for global world ``-1``. Legacy | ||
| implicit single-world models have shape [1], shared by world ``0`` | ||
| and global world ``-1``. | ||
| """ | ||
|
|
||
| self.constraint_mimic_joint0: wp.array[wp.int32] | None = None | ||
| """Follower joint index (``joint0 = coef0 + coef1 * joint1``), shape [constraint_mimic_count], int.""" | ||
|
|
@@ -1964,31 +1970,41 @@ def set_gravity( | |
| Set gravity for runtime modification. | ||
|
|
||
| Args: | ||
| gravity: Gravity vector (3,) or per-world array (world_count, 3). | ||
| world: If provided, set gravity only for this world. | ||
| gravity: A single gravity vector [m/s²], one vector per local world, or one | ||
| vector per local world plus a final global vector. A single vector | ||
| updates every local world and the global world. Local-world-only | ||
| inputs preserve a distinct global gravity entry. | ||
| world: If provided, set gravity only for this world. Use ``-1`` for the | ||
| global world. | ||
|
|
||
| Note: | ||
| Call ``solver.notify_model_changed(ModelFlags.MODEL_PROPERTIES)`` after. | ||
|
|
||
| Global entities (particles/bodies not assigned to a specific world) use | ||
| gravity from world 0. | ||
| """ | ||
| gravity_np = np.asarray(gravity, dtype=np.float32) | ||
|
|
||
| if world is not None: | ||
| if gravity_np.shape != (3,): | ||
| raise ValueError("Expected single gravity vector (3,) when world is specified") | ||
| if world < 0 or world >= self.world_count: | ||
| raise IndexError(f"world {world} out of range [0, {self.world_count})") | ||
| if world < -1 or world >= self.world_count: | ||
| raise IndexError(f"world {world} out of range; expected -1 or [0, {self.world_count})") | ||
| current = self.gravity.numpy() | ||
| current[world] = gravity_np | ||
| self.gravity.assign(current) | ||
| elif gravity_np.ndim == 1: | ||
| if gravity_np.shape != (3,): | ||
| raise ValueError(f"Expected gravity with shape (3,), got {gravity_np.shape}") | ||
| self.gravity.fill_(gravity_np) | ||
| else: | ||
| if len(gravity_np) != self.world_count: | ||
| raise ValueError(f"Expected {self.world_count} gravity vectors, got {len(gravity_np)}") | ||
| self.gravity.assign(gravity_np) | ||
| local_shape = (self.world_count, 3) | ||
| full_shape = (self.gravity.shape[0], 3) | ||
| if gravity_np.shape == full_shape: | ||
| self.gravity.assign(gravity_np) | ||
| elif gravity_np.shape == local_shape: | ||
| current = self.gravity.numpy() | ||
| current[: self.world_count] = gravity_np | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P1] Legacy gravity updates no longer affect global-only entities
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. Implicit single-world models keep the legacy one-entry |
||
| self.gravity.assign(current) | ||
| else: | ||
| raise ValueError(f"Expected gravity with shape {local_shape} or {full_shape}, got {gravity_np.shape}") | ||
|
|
||
| def _init_collision_pipeline(self, enable_rigid_soft_full_surface_contact: bool = 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.
[P1] Kamino maps global entities to world 0
ModelKamino.from_newton()rewrites every-1world index to0wheneverworld_count == 1, including models containing both global and world-0 entities. With global gravity-2and world-0 gravity-5, constructing Kamino changedbody_worldfrom[-1, 0]to[0, 0]; one step produced Z velocities[-0.5, -0.5]instead of[-0.2, -0.5].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.
Fixed. Kamino now uses a conversion-only world mapping and leaves
model.body_worldunchanged. Global bodies keep world-1and use global gravity.