miniworld-maze 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of miniworld-maze might be problematic. Click here for more details.
- miniworld_maze/__init__.py +37 -0
- miniworld_maze/core/__init__.py +8 -0
- miniworld_maze/core/constants.py +130 -0
- miniworld_maze/core/miniworld_gymnasium/README.md +1 -0
- miniworld_maze/core/miniworld_gymnasium/__init__.py +4 -0
- miniworld_maze/core/miniworld_gymnasium/base_env.py +52 -0
- miniworld_maze/core/miniworld_gymnasium/entities/__init__.py +7 -0
- miniworld_maze/core/miniworld_gymnasium/entities/agent.py +117 -0
- miniworld_maze/core/miniworld_gymnasium/entities/base_entity.py +135 -0
- miniworld_maze/core/miniworld_gymnasium/entities/objects.py +116 -0
- miniworld_maze/core/miniworld_gymnasium/entity_manager.py +358 -0
- miniworld_maze/core/miniworld_gymnasium/envs/__init__.py +3 -0
- miniworld_maze/core/miniworld_gymnasium/math.py +83 -0
- miniworld_maze/core/miniworld_gymnasium/objmesh.py +294 -0
- miniworld_maze/core/miniworld_gymnasium/occlusion_queries.py +97 -0
- miniworld_maze/core/miniworld_gymnasium/opengl.py +21 -0
- miniworld_maze/core/miniworld_gymnasium/params.py +128 -0
- miniworld_maze/core/miniworld_gymnasium/random.py +105 -0
- miniworld_maze/core/miniworld_gymnasium/rendering/__init__.py +7 -0
- miniworld_maze/core/miniworld_gymnasium/rendering/drawing.py +77 -0
- miniworld_maze/core/miniworld_gymnasium/rendering/framebuffer.py +260 -0
- miniworld_maze/core/miniworld_gymnasium/rendering/texture.py +101 -0
- miniworld_maze/core/miniworld_gymnasium/rendering_engine.py +293 -0
- miniworld_maze/core/miniworld_gymnasium/room.py +330 -0
- miniworld_maze/core/miniworld_gymnasium/texture_utils.py +64 -0
- miniworld_maze/core/miniworld_gymnasium/textures/airduct_grate_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/asphalt_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/beanpaste_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/beige_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/black_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/blueberry_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/brick_wall_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/cardboard_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/cardboard_2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/cardboard_3.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/cardboard_4.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/ceiling_tile_noborder_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/ceiling_tiles_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/cinder_blocks_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/cobaltgreen_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/concrete_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/concrete_2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/concrete_3.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/concrete_4.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/concrete_tiles_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/copperred_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/crimson_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/door_doom_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/door_doom_2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/door_garage_red.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/door_garage_white.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/door_steel_brown.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/door_steel_grey.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/door_steel_red.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/drywall_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/floor_tiles_bw_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/floor_tiles_white.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/grass_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/grass_2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/lava_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/lava_2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/lemongrass_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/lightbeige_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/lightcobaltgreen_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/lightgray_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/lightnavyblue_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/lightskyblue_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/lime_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/logo_mila_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/magenta_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/marble_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/marble_2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/metal_grill_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/metal_grill_2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/morningglory_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/navyblue_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/oakbrown_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/orange_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/orchid_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/picket_fence_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/adelaide_hanscom1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/adelaide_hanscom1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/alessandro_allori1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/alessandro_allori1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/alessandro_allori2.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/alessandro_allori2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/alexandre_cabanel1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/alexandre_cabanel1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/alexei_harlamov1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/alexei_harlamov1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/alexey_petrovich_antropov1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/alexey_petrovich_antropov1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/alice_pike_barney1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/alice_pike_barney1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/aman_theodor1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/aman_theodor1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/antonello_messina1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/antonello_messina1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/antonio_herrera_toro1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/antonio_herrera_toro1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/benjamin-constant1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/benjamin-constant1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/benoist_marie-guillemine1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/benoist_marie-guillemine1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/bouguereau_william-adolphe1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/bouguereau_william-adolphe1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/byron1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/byron1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/carl_fredric_breda1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/carl_fredric_breda1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/carl_fredric_breda2.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/carl_fredric_breda2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/cramacj_lucas1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/cramacj_lucas1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/cranach_lucas2.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/cranach_lucas2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/cristobal_rojas1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/cristobal_rojas1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/delacroix_eugene_ferdinand_victor1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/delacroix_eugene_ferdinand_victor1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/domenikos_theotokopoulos1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/domenikos_theotokopoulos1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/edmund_blair_leighton1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/edmund_blair_leighton1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/edmund_blair_leighton2.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/edmund_blair_leighton2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/edwin_longsden_long1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/edwin_longsden_long1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/falero_luis_ricardo1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/falero_luis_ricardo1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/felix_bonfils1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/felix_bonfils1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/francesco_hayez1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/francesco_hayez1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/francisco_goya_lucientes1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/francisco_goya_lucientes1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/francisco_goya_lucientes2.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/francisco_goya_lucientes2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/francisco_zurbaran1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/francisco_zurbaran1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/franz_von_defregger1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/franz_von_defregger1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/franz_von_defregger2.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/franz_von_defregger2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/franz_von_defregger3.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/franz_von_defregger3.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/frederic_westin1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/frederic_westin1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/frederic_yates1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/frederic_yates1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/frederick_leighton1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/frederick_leighton1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/gaston_bussiere1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/gaston_bussiere1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/george_henry_hall1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/george_henry_hall1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/giovanni_battista_tiepolo1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/giovanni_battista_tiepolo1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/giovanni_bellini1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/giovanni_bellini1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/hans_holbein1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/hans_holbein1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/hayez_francesco1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/hayez_francesco1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/henryk_siemiradzki1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/henryk_siemiradzki1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/ilja_jefimowitsch_repin1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/ilja_jefimowitsch_repin1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/james_carrol_beckwith1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/james_carrol_beckwith1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-baptiste-camille_corot1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-baptiste-camille_corot1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-baptiste-camille_corot2.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-baptiste-camille_corot2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome2.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome3.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome3.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome4.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome4.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/john_william_godward1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/john_william_godward1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/john_william_godward2.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/john_william_godward2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/john_william_godward3.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/john_william_godward3.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/julije_klovic1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/julije_klovic1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/juriaen_streek1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/juriaen_streek1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/kiprenskij_orest_adamovic1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/kiprenskij_orest_adamovic1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/konstantin_makovsky1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/konstantin_makovsky1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/lefebvre_jules_joseph1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/lefebvre_jules_joseph1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/leon-francois_comerre1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/leon-francois_comerre1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/leopold_loffler1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/leopold_loffler1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/lewis_john_frederick1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/lewis_john_frederick1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/madrazo_garreta_raimundo1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/madrazo_garreta_raimundo1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/marie_bashkirtseff1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/marie_bashkirtseff1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/moritz_kellerhoven1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/moritz_kellerhoven1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/nathaniel_jocelyn1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/nathaniel_jocelyn1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/nikolai_alexandrowitsch_jaroschenko1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/nikolai_alexandrowitsch_jaroschenko1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/nils_johan_olsson_blommer1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/nils_johan_olsson_blommer1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/paolo_veronese1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/paolo_veronese1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/parmigianino1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/parmigianino1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/paul_cesar_helleu1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/paul_cesar_helleu1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/regnault_henri1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/regnault_henri1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/richard_bergh1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/richard_bergh1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/richard_bergh2.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/richard_bergh2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/robert_dampier1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/robert_dampier1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/robert_lefevre1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/robert_lefevre1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/robert_leopold1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/robert_leopold1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/sichel_nathanael1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/sichel_nathanael1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/svetoslav_roerich1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/svetoslav_roerich1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/velazquez_diego1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/velazquez_diego1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/viktor_vasnetsov1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/viktor_vasnetsov1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/william-adolphe_bouguereau1.license +2 -0
- miniworld_maze/core/miniworld_gymnasium/textures/portraits/william-adolphe_bouguereau1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/realblueberry_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/redbean_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/rock_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/seablue_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/silver_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/skyblue_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/slime_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/stucco_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/sunnyyellow_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/turquoise_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/violet_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/water_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/water_2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/water_3.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/white_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/wood_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/wood_2.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/textures/wood_planks_1.png +0 -0
- miniworld_maze/core/miniworld_gymnasium/unified_env.py +1364 -0
- miniworld_maze/core/miniworld_gymnasium/utils.py +37 -0
- miniworld_maze/core/miniworld_gymnasium/wrappers.py +2 -0
- miniworld_maze/core/observation_types.py +32 -0
- miniworld_maze/environments/__init__.py +16 -0
- miniworld_maze/environments/base_grid_rooms.py +204 -0
- miniworld_maze/environments/factory.py +155 -0
- miniworld_maze/environments/nine_rooms.py +74 -0
- miniworld_maze/environments/spiral_nine_rooms.py +70 -0
- miniworld_maze/environments/twenty_five_rooms.py +122 -0
- miniworld_maze/tools/__init__.py +5 -0
- miniworld_maze/tools/generate_observations.py +199 -0
- miniworld_maze/wrappers/__init__.py +5 -0
- miniworld_maze/wrappers/image_transforms.py +40 -0
- miniworld_maze-1.0.0.dist-info/METADATA +108 -0
- miniworld_maze-1.0.0.dist-info/RECORD +280 -0
- miniworld_maze-1.0.0.dist-info/WHEEL +4 -0
- miniworld_maze-1.0.0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"""OBJ mesh loading and rendering utilities for MiniWorld environments."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import pyglet
|
|
7
|
+
|
|
8
|
+
from .opengl import *
|
|
9
|
+
from .utils import *
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ObjMesh:
|
|
13
|
+
"""
|
|
14
|
+
Load and render OBJ model files for 3D entity meshes.
|
|
15
|
+
|
|
16
|
+
Provides functionality to load Wavefront OBJ files, parse vertices and faces,
|
|
17
|
+
and render them using OpenGL. Includes mesh caching for performance.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
# Loaded mesh files, indexed by mesh file path
|
|
21
|
+
cache = {}
|
|
22
|
+
|
|
23
|
+
@classmethod
|
|
24
|
+
def get(self, mesh_name):
|
|
25
|
+
"""
|
|
26
|
+
Load a mesh or used a cached version
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# Assemble the absolute path to the mesh file
|
|
30
|
+
file_path = get_file_path("meshes", mesh_name, "obj")
|
|
31
|
+
|
|
32
|
+
if file_path in self.cache:
|
|
33
|
+
return self.cache[file_path]
|
|
34
|
+
|
|
35
|
+
mesh = ObjMesh(file_path)
|
|
36
|
+
self.cache[file_path] = mesh
|
|
37
|
+
|
|
38
|
+
return mesh
|
|
39
|
+
|
|
40
|
+
def __init__(self, file_path):
|
|
41
|
+
"""
|
|
42
|
+
Load an OBJ model file
|
|
43
|
+
|
|
44
|
+
Limitations:
|
|
45
|
+
- only one object/group
|
|
46
|
+
- only triangle faces
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
# OBJ file format:
|
|
50
|
+
# #Comments
|
|
51
|
+
# mtllib file_name
|
|
52
|
+
# o object_name
|
|
53
|
+
# v x y z
|
|
54
|
+
# vt u v
|
|
55
|
+
# vn x y z
|
|
56
|
+
# usemtl mtl_name
|
|
57
|
+
# f v0/t0/n0 v1/t1/n1 v2/t2/n2
|
|
58
|
+
|
|
59
|
+
# print('Loading mesh "%s"' % file_path)
|
|
60
|
+
|
|
61
|
+
# Attempt to load the materials library
|
|
62
|
+
materials = self._load_mtl(file_path)
|
|
63
|
+
mesh_file = open(file_path, "r")
|
|
64
|
+
|
|
65
|
+
verts = []
|
|
66
|
+
texs = []
|
|
67
|
+
normals = []
|
|
68
|
+
faces = []
|
|
69
|
+
|
|
70
|
+
cur_mtl = ""
|
|
71
|
+
|
|
72
|
+
# For each line of the input file
|
|
73
|
+
for line in mesh_file:
|
|
74
|
+
line = line.rstrip(" \r\n")
|
|
75
|
+
|
|
76
|
+
# Skip comments
|
|
77
|
+
if line.startswith("#") or line == "":
|
|
78
|
+
continue
|
|
79
|
+
|
|
80
|
+
tokens = line.split(" ")
|
|
81
|
+
tokens = map(lambda t: t.strip(" "), tokens)
|
|
82
|
+
tokens = list(filter(lambda t: t != "", tokens))
|
|
83
|
+
|
|
84
|
+
prefix = tokens[0]
|
|
85
|
+
tokens = tokens[1:]
|
|
86
|
+
|
|
87
|
+
if prefix == "v":
|
|
88
|
+
vert = list(map(lambda v: float(v), tokens))
|
|
89
|
+
verts.append(vert)
|
|
90
|
+
|
|
91
|
+
if prefix == "vt":
|
|
92
|
+
tc = list(map(lambda v: float(v), tokens))
|
|
93
|
+
texs.append(tc)
|
|
94
|
+
|
|
95
|
+
if prefix == "vn":
|
|
96
|
+
normal = list(map(lambda v: float(v), tokens))
|
|
97
|
+
normals.append(normal)
|
|
98
|
+
|
|
99
|
+
if prefix == "usemtl":
|
|
100
|
+
mtl_name = tokens[0]
|
|
101
|
+
if mtl_name in materials:
|
|
102
|
+
cur_mtl = mtl_name
|
|
103
|
+
else:
|
|
104
|
+
cur_mtl = ""
|
|
105
|
+
|
|
106
|
+
if prefix == "f":
|
|
107
|
+
assert len(tokens) == 3, "only triangle faces are supported"
|
|
108
|
+
|
|
109
|
+
face = []
|
|
110
|
+
for token in tokens:
|
|
111
|
+
indices = filter(lambda t: t != "", token.split("/"))
|
|
112
|
+
indices = list(map(lambda idx: int(idx), indices))
|
|
113
|
+
assert len(indices) == 2 or len(indices) == 3
|
|
114
|
+
face.append(indices)
|
|
115
|
+
|
|
116
|
+
faces.append([face, cur_mtl])
|
|
117
|
+
|
|
118
|
+
# Sort the faces by material name
|
|
119
|
+
faces.sort(key=lambda f: f[1])
|
|
120
|
+
|
|
121
|
+
# Compute the start and end faces for each chunk in the model
|
|
122
|
+
cur_mtl = None
|
|
123
|
+
chunks = []
|
|
124
|
+
for idx, face in enumerate(faces):
|
|
125
|
+
face, mtl_name = face
|
|
126
|
+
if mtl_name != cur_mtl:
|
|
127
|
+
if len(chunks) > 0:
|
|
128
|
+
chunks[-1]["end_idx"] = idx
|
|
129
|
+
chunks.append(
|
|
130
|
+
{"mtl": materials[mtl_name], "start_idx": idx, "end_idx": None}
|
|
131
|
+
)
|
|
132
|
+
cur_mtl = mtl_name
|
|
133
|
+
chunks[-1]["end_idx"] = len(faces)
|
|
134
|
+
|
|
135
|
+
num_faces = len(faces)
|
|
136
|
+
# print('num verts=%d' % len(verts))
|
|
137
|
+
# print('num faces=%d' % num_faces)
|
|
138
|
+
# print('num chunks=%d' % len(chunks))
|
|
139
|
+
|
|
140
|
+
# Create numpy arrays to store the vertex data
|
|
141
|
+
list_verts = np.zeros(shape=(num_faces, 3, 3), dtype=np.float32)
|
|
142
|
+
list_norms = np.zeros(shape=(num_faces, 3, 3), dtype=np.float32)
|
|
143
|
+
list_texcs = np.zeros(shape=(num_faces, 3, 2), dtype=np.float32)
|
|
144
|
+
list_color = np.zeros(shape=(num_faces, 3, 3), dtype=np.float32)
|
|
145
|
+
|
|
146
|
+
# For each triangle
|
|
147
|
+
for f_idx, face in enumerate(faces):
|
|
148
|
+
face, mtl_name = face
|
|
149
|
+
|
|
150
|
+
# Get the color for this face
|
|
151
|
+
f_mtl = materials[mtl_name]
|
|
152
|
+
f_color = f_mtl["Kd"] if f_mtl else np.array((1, 1, 1))
|
|
153
|
+
|
|
154
|
+
# For each tuple of indices
|
|
155
|
+
for l_idx, indices in enumerate(face):
|
|
156
|
+
# Note: OBJ uses 1-based indexing
|
|
157
|
+
# and texture coordinates are optional
|
|
158
|
+
if len(indices) == 3:
|
|
159
|
+
v_idx, t_idx, n_idx = indices
|
|
160
|
+
vert = verts[v_idx - 1]
|
|
161
|
+
texc = texs[t_idx - 1]
|
|
162
|
+
normal = normals[n_idx - 1]
|
|
163
|
+
else:
|
|
164
|
+
v_idx, n_idx = indices
|
|
165
|
+
vert = verts[v_idx - 1]
|
|
166
|
+
normal = normals[n_idx - 1]
|
|
167
|
+
texc = [0, 0]
|
|
168
|
+
|
|
169
|
+
list_verts[f_idx, l_idx, :] = vert
|
|
170
|
+
list_texcs[f_idx, l_idx, :] = texc
|
|
171
|
+
list_norms[f_idx, l_idx, :] = normal
|
|
172
|
+
list_color[f_idx, l_idx, :] = f_color
|
|
173
|
+
|
|
174
|
+
# Re-center the object so that the base is at y=0
|
|
175
|
+
# and the object is centered in x and z
|
|
176
|
+
min_coords = list_verts.min(axis=0).min(axis=0)
|
|
177
|
+
max_coords = list_verts.max(axis=0).min(axis=0)
|
|
178
|
+
mean_coords = (min_coords + max_coords) / 2
|
|
179
|
+
min_y = min_coords[1]
|
|
180
|
+
mean_x = mean_coords[0]
|
|
181
|
+
mean_z = mean_coords[2]
|
|
182
|
+
list_verts[:, :, 1] -= min_y
|
|
183
|
+
list_verts[:, :, 0] -= mean_x
|
|
184
|
+
list_verts[:, :, 2] -= mean_z
|
|
185
|
+
|
|
186
|
+
# Recompute the object extents after centering
|
|
187
|
+
self.min_coords = list_verts.min(axis=0).min(axis=0)
|
|
188
|
+
self.max_coords = list_verts.max(axis=0).max(axis=0)
|
|
189
|
+
|
|
190
|
+
# Vertex lists, one per chunk
|
|
191
|
+
self.vlists = []
|
|
192
|
+
|
|
193
|
+
# Textures, one per chunk
|
|
194
|
+
self.textures = []
|
|
195
|
+
|
|
196
|
+
# For each chunk
|
|
197
|
+
for chunk in chunks:
|
|
198
|
+
start_idx = chunk["start_idx"]
|
|
199
|
+
end_idx = chunk["end_idx"]
|
|
200
|
+
num_faces_chunk = end_idx - start_idx
|
|
201
|
+
|
|
202
|
+
# Create a vertex list to be used for rendering
|
|
203
|
+
vlist = pyglet.graphics.vertex_list(
|
|
204
|
+
3 * num_faces_chunk,
|
|
205
|
+
("v3f", list_verts[start_idx:end_idx, :, :].reshape(-1)),
|
|
206
|
+
("t2f", list_texcs[start_idx:end_idx, :, :].reshape(-1)),
|
|
207
|
+
("n3f", list_norms[start_idx:end_idx, :, :].reshape(-1)),
|
|
208
|
+
("c3f", list_color[start_idx:end_idx, :, :].reshape(-1)),
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
mtl = chunk["mtl"]
|
|
212
|
+
if "map_Kd" in mtl:
|
|
213
|
+
texture = Texture.load(mtl["map_Kd"])
|
|
214
|
+
else:
|
|
215
|
+
texture = None
|
|
216
|
+
|
|
217
|
+
self.vlists.append(vlist)
|
|
218
|
+
self.textures.append(texture)
|
|
219
|
+
|
|
220
|
+
def _load_mtl(self, model_file):
|
|
221
|
+
model_dir, file_name = os.path.split(model_file)
|
|
222
|
+
|
|
223
|
+
# Create a default material for the model
|
|
224
|
+
default_mtl = {
|
|
225
|
+
"Kd": np.array([1, 1, 1]),
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
# Determine the default texture path for the default material
|
|
229
|
+
tex_name = file_name.split(".")[0]
|
|
230
|
+
tex_path = get_file_path("meshes", tex_name, "png")
|
|
231
|
+
if os.path.exists(tex_path):
|
|
232
|
+
default_mtl["map_Kd"] = tex_path
|
|
233
|
+
|
|
234
|
+
materials = {"": default_mtl}
|
|
235
|
+
|
|
236
|
+
mtl_path = model_file.split(".")[0] + ".mtl"
|
|
237
|
+
|
|
238
|
+
if not os.path.exists(mtl_path):
|
|
239
|
+
return materials
|
|
240
|
+
|
|
241
|
+
# print('Loading materials from "%s"' % mtl_path)
|
|
242
|
+
|
|
243
|
+
mtl_file = open(mtl_path, "r")
|
|
244
|
+
|
|
245
|
+
cur_mtl = None
|
|
246
|
+
|
|
247
|
+
# For each line of the input file
|
|
248
|
+
for line in mtl_file:
|
|
249
|
+
line = line.rstrip(" \r\n")
|
|
250
|
+
|
|
251
|
+
# Skip comments
|
|
252
|
+
if line.startswith("#") or line == "":
|
|
253
|
+
continue
|
|
254
|
+
|
|
255
|
+
tokens = line.split(" ")
|
|
256
|
+
tokens = map(lambda t: t.strip(" "), tokens)
|
|
257
|
+
tokens = list(filter(lambda t: t != "", tokens))
|
|
258
|
+
|
|
259
|
+
prefix = tokens[0]
|
|
260
|
+
tokens = tokens[1:]
|
|
261
|
+
|
|
262
|
+
if prefix == "newmtl":
|
|
263
|
+
cur_mtl = {}
|
|
264
|
+
materials[tokens[0]] = cur_mtl
|
|
265
|
+
|
|
266
|
+
# Diffuse color
|
|
267
|
+
if prefix == "Kd":
|
|
268
|
+
vals = list(map(lambda v: float(v), tokens))
|
|
269
|
+
vals = np.array(vals)
|
|
270
|
+
cur_mtl["Kd"] = vals
|
|
271
|
+
|
|
272
|
+
# Texture file name
|
|
273
|
+
if prefix == "map_Kd":
|
|
274
|
+
tex_file = tokens[-1]
|
|
275
|
+
tex_file = os.path.join(model_dir, tex_file)
|
|
276
|
+
cur_mtl["map_Kd"] = tex_file
|
|
277
|
+
|
|
278
|
+
mtl_file.close()
|
|
279
|
+
|
|
280
|
+
return materials
|
|
281
|
+
|
|
282
|
+
def render(self):
|
|
283
|
+
for idx, vlist in enumerate(self.vlists):
|
|
284
|
+
texture = self.textures[idx]
|
|
285
|
+
|
|
286
|
+
if texture:
|
|
287
|
+
glEnable(GL_TEXTURE_2D)
|
|
288
|
+
glBindTexture(texture.target, texture.id)
|
|
289
|
+
else:
|
|
290
|
+
glDisable(GL_TEXTURE_2D)
|
|
291
|
+
|
|
292
|
+
vlist.draw(GL_TRIANGLES)
|
|
293
|
+
|
|
294
|
+
glDisable(GL_TEXTURE_2D)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""OpenGL occlusion query utilities for MiniWorld environments."""
|
|
2
|
+
|
|
3
|
+
from typing import List, Set
|
|
4
|
+
|
|
5
|
+
from pyglet.gl import *
|
|
6
|
+
|
|
7
|
+
from .entities import Entity
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class OcclusionQueryManager:
|
|
11
|
+
"""
|
|
12
|
+
Manages OpenGL occlusion queries for entity visibility detection.
|
|
13
|
+
|
|
14
|
+
This class handles the lifecycle of OpenGL occlusion queries, providing
|
|
15
|
+
a clean interface for determining which entities are visible to the agent.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, entities: List[Entity]):
|
|
19
|
+
"""
|
|
20
|
+
Initialize occlusion query manager.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
entities: List of entities to test for visibility
|
|
24
|
+
"""
|
|
25
|
+
self.entities = entities
|
|
26
|
+
self.num_entities = len(entities)
|
|
27
|
+
|
|
28
|
+
# Allocate OpenGL query IDs
|
|
29
|
+
self.query_ids = (GLuint * self.num_entities)()
|
|
30
|
+
glGenQueries(self.num_entities, self.query_ids)
|
|
31
|
+
|
|
32
|
+
def begin_query(self, entity_index: int) -> None:
|
|
33
|
+
"""
|
|
34
|
+
Begin occlusion query for specific entity.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
entity_index: Index of entity in the entities list
|
|
38
|
+
"""
|
|
39
|
+
if entity_index >= self.num_entities:
|
|
40
|
+
raise IndexError(f"Entity index {entity_index} out of range")
|
|
41
|
+
|
|
42
|
+
glBeginQuery(GL_ANY_SAMPLES_PASSED, self.query_ids[entity_index])
|
|
43
|
+
|
|
44
|
+
def end_query(self) -> None:
|
|
45
|
+
"""End the current occlusion query."""
|
|
46
|
+
glEndQuery(GL_ANY_SAMPLES_PASSED)
|
|
47
|
+
|
|
48
|
+
def get_query_result(self, entity_index: int) -> bool:
|
|
49
|
+
"""
|
|
50
|
+
Get the result of an occlusion query.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
entity_index: Index of entity in the entities list
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
True if entity is visible (any samples passed), False otherwise
|
|
57
|
+
"""
|
|
58
|
+
if entity_index >= self.num_entities:
|
|
59
|
+
raise IndexError(f"Entity index {entity_index} out of range")
|
|
60
|
+
|
|
61
|
+
visible = (GLuint * 1)(1)
|
|
62
|
+
glGetQueryObjectuiv(self.query_ids[entity_index], GL_QUERY_RESULT, visible)
|
|
63
|
+
return visible[0] != 0
|
|
64
|
+
|
|
65
|
+
def get_visible_entities(self, agent: Entity) -> Set[Entity]:
|
|
66
|
+
"""
|
|
67
|
+
Get all entities that are visible (excluding the agent).
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
agent: The agent entity to exclude from results
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Set of visible entities
|
|
74
|
+
"""
|
|
75
|
+
visible_entities = set()
|
|
76
|
+
|
|
77
|
+
for entity_index, entity in enumerate(self.entities):
|
|
78
|
+
if entity is agent:
|
|
79
|
+
continue
|
|
80
|
+
|
|
81
|
+
if self.get_query_result(entity_index):
|
|
82
|
+
visible_entities.add(entity)
|
|
83
|
+
|
|
84
|
+
return visible_entities
|
|
85
|
+
|
|
86
|
+
def cleanup(self) -> None:
|
|
87
|
+
"""Clean up OpenGL resources."""
|
|
88
|
+
if hasattr(self, "query_ids"):
|
|
89
|
+
glDeleteQueries(self.num_entities, self.query_ids)
|
|
90
|
+
|
|
91
|
+
def __enter__(self):
|
|
92
|
+
"""Context manager entry."""
|
|
93
|
+
return self
|
|
94
|
+
|
|
95
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
96
|
+
"""Context manager exit with automatic cleanup."""
|
|
97
|
+
self.cleanup()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""OpenGL utilities for MiniWorld environments.
|
|
2
|
+
|
|
3
|
+
This module now imports from the refactored rendering modules for better organization.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
import pyglet
|
|
9
|
+
|
|
10
|
+
# Solution to https://github.com/maximecb/gym-miniworld/issues/24
|
|
11
|
+
# until pyglet support egl officially
|
|
12
|
+
if os.environ.get("PYOPENGL_PLATFORM", None) == "egl":
|
|
13
|
+
pyglet.options["headless"] = True
|
|
14
|
+
|
|
15
|
+
from pyglet.gl import *
|
|
16
|
+
|
|
17
|
+
# Import all classes and functions from the refactored modules
|
|
18
|
+
from .rendering import FrameBuffer, Texture, drawAxes, drawBox
|
|
19
|
+
|
|
20
|
+
# Export everything for backward compatibility
|
|
21
|
+
__all__ = ["Texture", "FrameBuffer", "drawAxes", "drawBox"]
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
from collections import namedtuple
|
|
2
|
+
from copy import deepcopy
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
# Simulation parameter, with domain randomization range
|
|
7
|
+
# The default value is used when domain randomization is disabled
|
|
8
|
+
DomainParam = namedtuple("Domainparam", ["default", "min", "max", "type"])
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DomainParams:
|
|
12
|
+
"""
|
|
13
|
+
Set of simulation parameters
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self):
|
|
17
|
+
# Dictionary of parameters, indexed by name
|
|
18
|
+
self.params = {}
|
|
19
|
+
|
|
20
|
+
def copy(self):
|
|
21
|
+
return deepcopy(self)
|
|
22
|
+
|
|
23
|
+
def no_random(self):
|
|
24
|
+
"""
|
|
25
|
+
Make a copy in which randomization is disabled for all parameters
|
|
26
|
+
This is useful to then selectively enable randomization on a
|
|
27
|
+
limited subset of the parameters.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
copy = self.copy()
|
|
31
|
+
|
|
32
|
+
for name, p in copy.params.items():
|
|
33
|
+
copy.params[name] = DomainParam(p.default, p.default, p.default, p.type)
|
|
34
|
+
|
|
35
|
+
return copy
|
|
36
|
+
|
|
37
|
+
def set(self, name, default, min=None, max=None, type="float"):
|
|
38
|
+
"""
|
|
39
|
+
Register/modify a named parameter
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
if isinstance(default, list):
|
|
43
|
+
default = np.array(default)
|
|
44
|
+
if isinstance(min, list):
|
|
45
|
+
min = np.array(min)
|
|
46
|
+
if isinstance(max, list):
|
|
47
|
+
max = np.array(max)
|
|
48
|
+
|
|
49
|
+
if min is None:
|
|
50
|
+
min = default
|
|
51
|
+
if max is None:
|
|
52
|
+
max = default
|
|
53
|
+
|
|
54
|
+
if isinstance(default, np.ndarray):
|
|
55
|
+
assert max.shape == default.shape
|
|
56
|
+
assert min.shape == max.shape
|
|
57
|
+
assert np.all(np.greater_equal(max, default))
|
|
58
|
+
assert np.all(np.greater_equal(default, min))
|
|
59
|
+
|
|
60
|
+
if type == "float":
|
|
61
|
+
default = default.astype("float")
|
|
62
|
+
min = min.astype("float")
|
|
63
|
+
max = max.astype("float")
|
|
64
|
+
else:
|
|
65
|
+
assert max >= default
|
|
66
|
+
assert default >= min
|
|
67
|
+
|
|
68
|
+
# Validation when modifying existing parameters
|
|
69
|
+
if name in self.params:
|
|
70
|
+
p = self.params[name]
|
|
71
|
+
assert type == p.type
|
|
72
|
+
if isinstance(p.default, np.ndarray):
|
|
73
|
+
assert default.shape == p.default.shape
|
|
74
|
+
|
|
75
|
+
self.params[name] = DomainParam(default, min, max, type)
|
|
76
|
+
|
|
77
|
+
def get_max(self, name):
|
|
78
|
+
assert name in self.params, name
|
|
79
|
+
p = self.params[name]
|
|
80
|
+
return p.max
|
|
81
|
+
|
|
82
|
+
def sample(self, rng, name):
|
|
83
|
+
"""
|
|
84
|
+
Sample a single parameter
|
|
85
|
+
Note: when rng is None, the default value is returned, which
|
|
86
|
+
has the effect of turning off domain randomization
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
assert name in self.params, name
|
|
90
|
+
p = self.params[name]
|
|
91
|
+
|
|
92
|
+
if rng is None:
|
|
93
|
+
return p.default
|
|
94
|
+
|
|
95
|
+
if p.type == "float":
|
|
96
|
+
return rng.float(p.min, p.max)
|
|
97
|
+
elif p.type == "int":
|
|
98
|
+
return rng.int(p.min, p.max + 1)
|
|
99
|
+
|
|
100
|
+
assert False
|
|
101
|
+
|
|
102
|
+
def sample_many(self, rng, target_obj, param_names):
|
|
103
|
+
"""
|
|
104
|
+
Sample a list of parameters
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
for name in param_names:
|
|
108
|
+
setattr(target_obj, name, self.sample(rng, name))
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# Default simulation parameters
|
|
112
|
+
DEFAULT_PARAMS = DomainParams()
|
|
113
|
+
DEFAULT_PARAMS.set("black", [0.00, 0.00, 0.00], [0.00, 0.00, 0.00], [0.00, 0.00, 0.00])
|
|
114
|
+
DEFAULT_PARAMS.set("sky_color", [0.25, 0.82, 1], [0.1, 0.1, 0.1], [1.0, 1.0, 1.0])
|
|
115
|
+
DEFAULT_PARAMS.set("light_pos", [0, 2.5, 0], [-40, 2.5, -40], [40, 5, 40])
|
|
116
|
+
DEFAULT_PARAMS.set("light_color", [0.7, 0.7, 0.7], [0.45, 0.45, 0.45], [0.8, 0.8, 0.8])
|
|
117
|
+
DEFAULT_PARAMS.set(
|
|
118
|
+
"light_ambient", [0.45, 0.45, 0.45], [0.35, 0.35, 0.35], [0.55, 0.55, 0.55]
|
|
119
|
+
)
|
|
120
|
+
DEFAULT_PARAMS.set("obj_color_bias", [0, 0, 0], [-0.2, -0.2, -0.2], [0.2, 0.2, 0.2])
|
|
121
|
+
DEFAULT_PARAMS.set("forward_step", 0.15, 0.12, 0.17)
|
|
122
|
+
DEFAULT_PARAMS.set("forward_drift", 0, -0.05, 0.05)
|
|
123
|
+
DEFAULT_PARAMS.set("turn_step", 15, 10, 20)
|
|
124
|
+
DEFAULT_PARAMS.set("bot_radius", 0.4, 0.38, 0.42)
|
|
125
|
+
DEFAULT_PARAMS.set("cam_pitch", 0, -5, 5)
|
|
126
|
+
DEFAULT_PARAMS.set("cam_fov_y", 60, 55, 65)
|
|
127
|
+
DEFAULT_PARAMS.set("cam_height", 1.5, 1.45, 1.55)
|
|
128
|
+
DEFAULT_PARAMS.set("cam_fwd_disp", 0, -0.05, 0.10)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Random number generation utilities for MiniWorld environments."""
|
|
2
|
+
|
|
3
|
+
from gymnasium.utils import seeding
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class RandGen:
|
|
7
|
+
"""
|
|
8
|
+
Thread-safe random value generator for environment simulation.
|
|
9
|
+
|
|
10
|
+
Provides consistent random number generation across different runs
|
|
11
|
+
when seeded properly, which is essential for reproducible experiments.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, seed=None):
|
|
15
|
+
"""Initialize random generator with optional seed."""
|
|
16
|
+
self.np_random, _ = seeding.np_random(seed)
|
|
17
|
+
|
|
18
|
+
def random_int(self, low, high):
|
|
19
|
+
"""
|
|
20
|
+
Generate random integer in the range [low, high).
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
low: Lower bound (inclusive)
|
|
24
|
+
high: Upper bound (exclusive)
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
Random integer in specified range
|
|
28
|
+
"""
|
|
29
|
+
return self.np_random.integers(low, high)
|
|
30
|
+
|
|
31
|
+
def random_float(self, low, high, shape=None):
|
|
32
|
+
"""
|
|
33
|
+
Generate random float(s) in the range [low, high).
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
low: Lower bound (inclusive)
|
|
37
|
+
high: Upper bound (exclusive)
|
|
38
|
+
shape: Optional shape for array output
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
Random float or array of floats in specified range
|
|
42
|
+
"""
|
|
43
|
+
return self.np_random.uniform(low, high, size=shape)
|
|
44
|
+
|
|
45
|
+
def random_bool(self):
|
|
46
|
+
"""
|
|
47
|
+
Generate random boolean value with 50/50 probability.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
Random boolean (True or False)
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
return self.np_random.integers(0, 2) == 0
|
|
54
|
+
|
|
55
|
+
def choice(self, iterable, probs=None):
|
|
56
|
+
"""
|
|
57
|
+
Pick a random element in a list
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
lst = list(iterable)
|
|
61
|
+
idx = self.np_random.choice(len(lst), p=probs)
|
|
62
|
+
return lst[idx]
|
|
63
|
+
|
|
64
|
+
def random_color(self):
|
|
65
|
+
"""
|
|
66
|
+
Pick a random color name
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
from .entities.base_entity import COLOR_NAMES
|
|
70
|
+
|
|
71
|
+
return self.choice(COLOR_NAMES)
|
|
72
|
+
|
|
73
|
+
def subset(self, iterable, num_elems):
|
|
74
|
+
"""
|
|
75
|
+
Sample a random subset of distinct elements of a list
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
lst = list(iterable)
|
|
79
|
+
assert num_elems <= len(lst)
|
|
80
|
+
|
|
81
|
+
out = []
|
|
82
|
+
|
|
83
|
+
while len(out) < num_elems:
|
|
84
|
+
elem = self.choice(lst)
|
|
85
|
+
lst.remove(elem)
|
|
86
|
+
out.append(elem)
|
|
87
|
+
|
|
88
|
+
return out
|
|
89
|
+
|
|
90
|
+
# Backward compatibility aliases
|
|
91
|
+
def int(self, low, high):
|
|
92
|
+
"""Legacy alias for random_int (deprecated: shadows built-in)"""
|
|
93
|
+
return self.random_int(low, high)
|
|
94
|
+
|
|
95
|
+
def float(self, low, high, shape=None):
|
|
96
|
+
"""Legacy alias for random_float (deprecated: shadows built-in)"""
|
|
97
|
+
return self.random_float(low, high, shape)
|
|
98
|
+
|
|
99
|
+
def bool(self):
|
|
100
|
+
"""Legacy alias for random_bool (deprecated: shadows built-in)"""
|
|
101
|
+
return self.random_bool()
|
|
102
|
+
|
|
103
|
+
def color(self):
|
|
104
|
+
"""Legacy alias for random_color (deprecated: not descriptive)"""
|
|
105
|
+
return self.random_color()
|