feat: Support 6 light types (point, sun, direction, spot, rect, mesh)#361
Open
yuecideng wants to merge 13 commits into
Open
feat: Support 6 light types (point, sun, direction, spot, rect, mesh)#361yuecideng wants to merge 13 commits into
yuecideng wants to merge 13 commits into
Conversation
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Add optional fields for sun, direction, spot, rect, and mesh light types. Change default intensity to 30.0 and default radius to 10.0. All new fields have defaults — existing point-light code works unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
Add set_direction, set_spot_angle, set_rect_wh, set_mesh, and enable_shadow methods with runtime type validation. Update reset() to apply only properties relevant to the light type. Guard set_local_pose for direction-type lights (no position). Co-Authored-By: Claude <noreply@anthropic.com>
Adds a length-1 broadcast branch so that (1,) tensors for inner/outer spot angles and width/height are applied to all targeted env_ids. Co-Authored-By: Claude <noreply@anthropic.com>
Add _LIGHT_TYPE_MAP mapping string type names to dexsim LightType enum. Add validation warnings for mesh (no path) and rect (zero dimensions). Unknown light types now log the list of supported types. Co-Authored-By: Claude <noreply@anthropic.com>
Cover creation, type validation, broadcasting, from_dict, and backward compatibility for point lights. Also fix logger.warning() -> logger.log_warning() in sim_manager.py and light.py (logger.warning() did not exist). Co-Authored-By: Claude <noreply@anthropic.com>
logger.log_error raises RuntimeError, not ValueError. Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR expands EmbodiChain’s simulation lighting pipeline from point-only lights to six dexsim-backed light types by extending the configuration surface (LightCfg), adding type-specific runtime setters on the batched Light object, and updating SimulationManager.add_light to map the new type strings to dexsim’s LightType.
Changes:
- Extend
LightCfgwith a 6-valuelight_typeliteral plus type-specific fields (direction/spot/rect/mesh and sun-reserved fields) and updated defaults (intensity/radius). - Add new
Lightsetters (set_direction,set_spot_angle,set_rect_wh,set_mesh,enable_shadow) and updatereset()to apply only relevant properties per light type. - Update
SimulationManager.add_lightwith a centralized type map and add new tests + internal design/spec docs.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
embodichain/lab/sim/cfg.py |
Expands LightCfg to cover six light types and adds type-specific fields/defaults. |
embodichain/lab/sim/objects/light.py |
Adds type-specific setters and updates reset() to apply per-type properties (including shadow). |
embodichain/lab/sim/sim_manager.py |
Introduces _LIGHT_TYPE_MAP and updates add_light() to support all six dexsim light types plus validation warnings. |
tests/sim/objects/test_light.py |
Adds a new test class covering creation, validation, and broadcasting across all six types. |
docs/superpowers/specs/2026-07-05-light-types-design.md |
Adds an internal design spec for the light type expansion. |
docs/superpowers/plans/2026-07-05-light-types-plan.md |
Adds an internal implementation plan for the feature. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+885
to
+888
| mesh_path: str = "" | ||
| """Asset path for mesh-based emissive lights. Only used when ``light_type="mesh"``. | ||
| The actual mesh assignment is done via :meth:`Light.set_mesh` which accepts a | ||
| :class:`dexsim.models.MeshObject`. This field stores the path for reference.""" |
Comment on lines
+105
to
+114
| | Method | Tensor Shape | Broadcast Pattern | Applies To | | ||
| |---|---|---|---| | ||
| | `set_direction(directions, env_ids=None)` | (3,) or (M, 3) | `_apply_vector3` | sun, direction, spot, rect, mesh | | ||
| | `set_spot_angle(inner, outer, env_ids=None)` | scalar each | `_apply_scalar` × 2 | spot | | ||
| | `set_angular_radius(radii, env_ids=None)` | scalar or (M,) | `_apply_scalar` | sun | | ||
| | `set_halo_size(sizes, env_ids=None)` | scalar or (M,) | `_apply_scalar` | sun | | ||
| | `set_halo_falloff(falloffs, env_ids=None)` | scalar or (M,) | `_apply_scalar` | sun | | ||
| | `set_rect_size(widths, heights, env_ids=None)` | scalar each | `_apply_scalar` × 2 | rect | | ||
| | `set_mesh_path(path, env_ids=None)` | `str` | single string, no tensor | mesh | | ||
| | `enable_shadow(flags, env_ids=None)` | scalar or (M,) | `_apply_scalar` | all | |
Comment on lines
+385
to
+392
| cfg_dict = { | ||
| "light_type": "point", | ||
| "color": [0.1, 0.1, 0.1], | ||
| "radius": 10.0, | ||
| "position": [0.0, 0.0, 2.0], | ||
| "uid": "point_compat", | ||
| } | ||
| light = self.sim.add_light(cfg=LightCfg.from_dict(cfg_dict)) |
Comment on lines
870
to
+874
| logger.log_error( | ||
| f"Unsupported light type: {light_type}. Supported types: point." | ||
| f"Unsupported light type: '{light_type_str}'. " | ||
| f"Supported types: {supported}." | ||
| ) | ||
| return None |
Comment on lines
+718
to
+722
| uid="global_light", | ||
| light_type="direction", | ||
| intensity=8.0, | ||
| direction=(0.0, 0, -1.0), | ||
| color=(1.0, 0.95, 0.85), |
| base_color_texture=color_texture, | ||
| roughness_texture=roughness_texture, | ||
| roughness=0.7, | ||
| roughness=0.9, |
| | Type | Category | Key Properties | | ||
| |---|---|---| | ||
| | `point` | Parametric | position, falloff (radius) | | ||
| | `sun` | Parametric | position, direction, angular_radius, halo_size, halo_falloff | |
Comment on lines
+135
to
+137
| - **point:** color, intensity, radius, init_pos, shadow | ||
| - **sun:** color, intensity, init_pos, direction, angular_radius, halo_size, halo_falloff, shadow | ||
| - **direction:** color, intensity, direction, shadow |
Comment on lines
+109
to
+113
| | `set_angular_radius(radii, env_ids=None)` | scalar or (M,) | `_apply_scalar` | sun | | ||
| | `set_halo_size(sizes, env_ids=None)` | scalar or (M,) | `_apply_scalar` | sun | | ||
| | `set_halo_falloff(falloffs, env_ids=None)` | scalar or (M,) | `_apply_scalar` | sun | | ||
| | `set_rect_size(widths, heights, env_ids=None)` | scalar each | `_apply_scalar` × 2 | rect | | ||
| | `set_mesh_path(path, env_ids=None)` | `str` | single string, no tensor | mesh | |
Comment on lines
+812
to
+814
| - ``"mesh"``: Per-environment mesh-based emissive light. Requires a | ||
| :class:`~dexsim.models.MeshObject` via :meth:`~Light.set_mesh` | ||
| (not tensor-batched). Created as a batched light. |
Comment on lines
+895
to
+897
| """Asset path for mesh-based emissive lights. Only used when ``light_type="mesh"``. | ||
| The actual mesh assignment is done via :meth:`Light.set_mesh` which accepts a | ||
| :class:`dexsim.models.MeshObject`. This field stores the path for reference.""" |
Comment on lines
+586
to
+590
| .. attention:: | ||
| For global lights (:attr:`is_global` is True), ``env_ids`` is | ||
| normalized to ``None`` because there is only one instance. | ||
| Passing per-environment indices is silently ignored. | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR expands EmbodiChain light support from a single
pointtype to all 6 light types exposed by the dexsim rendering backend.Changes
LightCfg: Expandedlight_typeliteral to"point" | "sun" | "direction" | "spot" | "rect" | "mesh"with type-specific optional fields (direction, spot angles, rect dimensions, mesh path, shadow toggle, sun angular radius)Lightclass: Addedset_direction,set_spot_angle,set_rect_wh,set_mesh,enable_shadowsetters with runtime type validation and tensor broadcastingSimulationManager.add_light: Maps all 6 light type strings to dexsimLightTypeenum values with validation warningsintensity50.0→30.0,radius1e2→10.0Architecture
Two-tier design: 5 parametric types (point, sun, direction, spot, rect) get full tensor batching via
_apply_vector3/_apply_scalarpatterns. Mesh lights are asset-based — string-set-only, not tensor-batched.Behavior changes to note
reset()now appliesenable_shadowfor all light types (previously only applied color/intensity/falloff/position)set_local_posewarns and no-ops fordirectionlight type (infinite distance, direction only)angular_radius,halo_size,halo_falloff) are config fields only — Python bindings not yet availableBackward compatibility
All existing point-light code works unchanged. New fields have defaults.
Type of change
Checklist
black .command to format the code base.