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.

Files changed (280) hide show
  1. miniworld_maze/__init__.py +37 -0
  2. miniworld_maze/core/__init__.py +8 -0
  3. miniworld_maze/core/constants.py +130 -0
  4. miniworld_maze/core/miniworld_gymnasium/README.md +1 -0
  5. miniworld_maze/core/miniworld_gymnasium/__init__.py +4 -0
  6. miniworld_maze/core/miniworld_gymnasium/base_env.py +52 -0
  7. miniworld_maze/core/miniworld_gymnasium/entities/__init__.py +7 -0
  8. miniworld_maze/core/miniworld_gymnasium/entities/agent.py +117 -0
  9. miniworld_maze/core/miniworld_gymnasium/entities/base_entity.py +135 -0
  10. miniworld_maze/core/miniworld_gymnasium/entities/objects.py +116 -0
  11. miniworld_maze/core/miniworld_gymnasium/entity_manager.py +358 -0
  12. miniworld_maze/core/miniworld_gymnasium/envs/__init__.py +3 -0
  13. miniworld_maze/core/miniworld_gymnasium/math.py +83 -0
  14. miniworld_maze/core/miniworld_gymnasium/objmesh.py +294 -0
  15. miniworld_maze/core/miniworld_gymnasium/occlusion_queries.py +97 -0
  16. miniworld_maze/core/miniworld_gymnasium/opengl.py +21 -0
  17. miniworld_maze/core/miniworld_gymnasium/params.py +128 -0
  18. miniworld_maze/core/miniworld_gymnasium/random.py +105 -0
  19. miniworld_maze/core/miniworld_gymnasium/rendering/__init__.py +7 -0
  20. miniworld_maze/core/miniworld_gymnasium/rendering/drawing.py +77 -0
  21. miniworld_maze/core/miniworld_gymnasium/rendering/framebuffer.py +260 -0
  22. miniworld_maze/core/miniworld_gymnasium/rendering/texture.py +101 -0
  23. miniworld_maze/core/miniworld_gymnasium/rendering_engine.py +293 -0
  24. miniworld_maze/core/miniworld_gymnasium/room.py +330 -0
  25. miniworld_maze/core/miniworld_gymnasium/texture_utils.py +64 -0
  26. miniworld_maze/core/miniworld_gymnasium/textures/airduct_grate_1.png +0 -0
  27. miniworld_maze/core/miniworld_gymnasium/textures/asphalt_1.png +0 -0
  28. miniworld_maze/core/miniworld_gymnasium/textures/beanpaste_1.png +0 -0
  29. miniworld_maze/core/miniworld_gymnasium/textures/beige_1.png +0 -0
  30. miniworld_maze/core/miniworld_gymnasium/textures/black_1.png +0 -0
  31. miniworld_maze/core/miniworld_gymnasium/textures/blueberry_1.png +0 -0
  32. miniworld_maze/core/miniworld_gymnasium/textures/brick_wall_1.png +0 -0
  33. miniworld_maze/core/miniworld_gymnasium/textures/cardboard_1.png +0 -0
  34. miniworld_maze/core/miniworld_gymnasium/textures/cardboard_2.png +0 -0
  35. miniworld_maze/core/miniworld_gymnasium/textures/cardboard_3.png +0 -0
  36. miniworld_maze/core/miniworld_gymnasium/textures/cardboard_4.png +0 -0
  37. miniworld_maze/core/miniworld_gymnasium/textures/ceiling_tile_noborder_1.png +0 -0
  38. miniworld_maze/core/miniworld_gymnasium/textures/ceiling_tiles_1.png +0 -0
  39. miniworld_maze/core/miniworld_gymnasium/textures/cinder_blocks_1.png +0 -0
  40. miniworld_maze/core/miniworld_gymnasium/textures/cobaltgreen_1.png +0 -0
  41. miniworld_maze/core/miniworld_gymnasium/textures/concrete_1.png +0 -0
  42. miniworld_maze/core/miniworld_gymnasium/textures/concrete_2.png +0 -0
  43. miniworld_maze/core/miniworld_gymnasium/textures/concrete_3.png +0 -0
  44. miniworld_maze/core/miniworld_gymnasium/textures/concrete_4.png +0 -0
  45. miniworld_maze/core/miniworld_gymnasium/textures/concrete_tiles_1.png +0 -0
  46. miniworld_maze/core/miniworld_gymnasium/textures/copperred_1.png +0 -0
  47. miniworld_maze/core/miniworld_gymnasium/textures/crimson_1.png +0 -0
  48. miniworld_maze/core/miniworld_gymnasium/textures/door_doom_1.png +0 -0
  49. miniworld_maze/core/miniworld_gymnasium/textures/door_doom_2.png +0 -0
  50. miniworld_maze/core/miniworld_gymnasium/textures/door_garage_red.png +0 -0
  51. miniworld_maze/core/miniworld_gymnasium/textures/door_garage_white.png +0 -0
  52. miniworld_maze/core/miniworld_gymnasium/textures/door_steel_brown.png +0 -0
  53. miniworld_maze/core/miniworld_gymnasium/textures/door_steel_grey.png +0 -0
  54. miniworld_maze/core/miniworld_gymnasium/textures/door_steel_red.png +0 -0
  55. miniworld_maze/core/miniworld_gymnasium/textures/drywall_1.png +0 -0
  56. miniworld_maze/core/miniworld_gymnasium/textures/floor_tiles_bw_1.png +0 -0
  57. miniworld_maze/core/miniworld_gymnasium/textures/floor_tiles_white.png +0 -0
  58. miniworld_maze/core/miniworld_gymnasium/textures/grass_1.png +0 -0
  59. miniworld_maze/core/miniworld_gymnasium/textures/grass_2.png +0 -0
  60. miniworld_maze/core/miniworld_gymnasium/textures/lava_1.png +0 -0
  61. miniworld_maze/core/miniworld_gymnasium/textures/lava_2.png +0 -0
  62. miniworld_maze/core/miniworld_gymnasium/textures/lemongrass_1.png +0 -0
  63. miniworld_maze/core/miniworld_gymnasium/textures/lightbeige_1.png +0 -0
  64. miniworld_maze/core/miniworld_gymnasium/textures/lightcobaltgreen_1.png +0 -0
  65. miniworld_maze/core/miniworld_gymnasium/textures/lightgray_1.png +0 -0
  66. miniworld_maze/core/miniworld_gymnasium/textures/lightnavyblue_1.png +0 -0
  67. miniworld_maze/core/miniworld_gymnasium/textures/lightskyblue_1.png +0 -0
  68. miniworld_maze/core/miniworld_gymnasium/textures/lime_1.png +0 -0
  69. miniworld_maze/core/miniworld_gymnasium/textures/logo_mila_1.png +0 -0
  70. miniworld_maze/core/miniworld_gymnasium/textures/magenta_1.png +0 -0
  71. miniworld_maze/core/miniworld_gymnasium/textures/marble_1.png +0 -0
  72. miniworld_maze/core/miniworld_gymnasium/textures/marble_2.png +0 -0
  73. miniworld_maze/core/miniworld_gymnasium/textures/metal_grill_1.png +0 -0
  74. miniworld_maze/core/miniworld_gymnasium/textures/metal_grill_2.png +0 -0
  75. miniworld_maze/core/miniworld_gymnasium/textures/morningglory_1.png +0 -0
  76. miniworld_maze/core/miniworld_gymnasium/textures/navyblue_1.png +0 -0
  77. miniworld_maze/core/miniworld_gymnasium/textures/oakbrown_1.png +0 -0
  78. miniworld_maze/core/miniworld_gymnasium/textures/orange_1.png +0 -0
  79. miniworld_maze/core/miniworld_gymnasium/textures/orchid_1.png +0 -0
  80. miniworld_maze/core/miniworld_gymnasium/textures/picket_fence_1.png +0 -0
  81. miniworld_maze/core/miniworld_gymnasium/textures/portraits/adelaide_hanscom1.license +2 -0
  82. miniworld_maze/core/miniworld_gymnasium/textures/portraits/adelaide_hanscom1.png +0 -0
  83. miniworld_maze/core/miniworld_gymnasium/textures/portraits/alessandro_allori1.license +2 -0
  84. miniworld_maze/core/miniworld_gymnasium/textures/portraits/alessandro_allori1.png +0 -0
  85. miniworld_maze/core/miniworld_gymnasium/textures/portraits/alessandro_allori2.license +2 -0
  86. miniworld_maze/core/miniworld_gymnasium/textures/portraits/alessandro_allori2.png +0 -0
  87. miniworld_maze/core/miniworld_gymnasium/textures/portraits/alexandre_cabanel1.license +2 -0
  88. miniworld_maze/core/miniworld_gymnasium/textures/portraits/alexandre_cabanel1.png +0 -0
  89. miniworld_maze/core/miniworld_gymnasium/textures/portraits/alexei_harlamov1.license +2 -0
  90. miniworld_maze/core/miniworld_gymnasium/textures/portraits/alexei_harlamov1.png +0 -0
  91. miniworld_maze/core/miniworld_gymnasium/textures/portraits/alexey_petrovich_antropov1.license +2 -0
  92. miniworld_maze/core/miniworld_gymnasium/textures/portraits/alexey_petrovich_antropov1.png +0 -0
  93. miniworld_maze/core/miniworld_gymnasium/textures/portraits/alice_pike_barney1.license +2 -0
  94. miniworld_maze/core/miniworld_gymnasium/textures/portraits/alice_pike_barney1.png +0 -0
  95. miniworld_maze/core/miniworld_gymnasium/textures/portraits/aman_theodor1.license +2 -0
  96. miniworld_maze/core/miniworld_gymnasium/textures/portraits/aman_theodor1.png +0 -0
  97. miniworld_maze/core/miniworld_gymnasium/textures/portraits/antonello_messina1.license +2 -0
  98. miniworld_maze/core/miniworld_gymnasium/textures/portraits/antonello_messina1.png +0 -0
  99. miniworld_maze/core/miniworld_gymnasium/textures/portraits/antonio_herrera_toro1.license +2 -0
  100. miniworld_maze/core/miniworld_gymnasium/textures/portraits/antonio_herrera_toro1.png +0 -0
  101. miniworld_maze/core/miniworld_gymnasium/textures/portraits/benjamin-constant1.license +2 -0
  102. miniworld_maze/core/miniworld_gymnasium/textures/portraits/benjamin-constant1.png +0 -0
  103. miniworld_maze/core/miniworld_gymnasium/textures/portraits/benoist_marie-guillemine1.license +2 -0
  104. miniworld_maze/core/miniworld_gymnasium/textures/portraits/benoist_marie-guillemine1.png +0 -0
  105. miniworld_maze/core/miniworld_gymnasium/textures/portraits/bouguereau_william-adolphe1.license +2 -0
  106. miniworld_maze/core/miniworld_gymnasium/textures/portraits/bouguereau_william-adolphe1.png +0 -0
  107. miniworld_maze/core/miniworld_gymnasium/textures/portraits/byron1.license +2 -0
  108. miniworld_maze/core/miniworld_gymnasium/textures/portraits/byron1.png +0 -0
  109. miniworld_maze/core/miniworld_gymnasium/textures/portraits/carl_fredric_breda1.license +2 -0
  110. miniworld_maze/core/miniworld_gymnasium/textures/portraits/carl_fredric_breda1.png +0 -0
  111. miniworld_maze/core/miniworld_gymnasium/textures/portraits/carl_fredric_breda2.license +2 -0
  112. miniworld_maze/core/miniworld_gymnasium/textures/portraits/carl_fredric_breda2.png +0 -0
  113. miniworld_maze/core/miniworld_gymnasium/textures/portraits/cramacj_lucas1.license +2 -0
  114. miniworld_maze/core/miniworld_gymnasium/textures/portraits/cramacj_lucas1.png +0 -0
  115. miniworld_maze/core/miniworld_gymnasium/textures/portraits/cranach_lucas2.license +2 -0
  116. miniworld_maze/core/miniworld_gymnasium/textures/portraits/cranach_lucas2.png +0 -0
  117. miniworld_maze/core/miniworld_gymnasium/textures/portraits/cristobal_rojas1.license +2 -0
  118. miniworld_maze/core/miniworld_gymnasium/textures/portraits/cristobal_rojas1.png +0 -0
  119. miniworld_maze/core/miniworld_gymnasium/textures/portraits/delacroix_eugene_ferdinand_victor1.license +2 -0
  120. miniworld_maze/core/miniworld_gymnasium/textures/portraits/delacroix_eugene_ferdinand_victor1.png +0 -0
  121. miniworld_maze/core/miniworld_gymnasium/textures/portraits/domenikos_theotokopoulos1.license +2 -0
  122. miniworld_maze/core/miniworld_gymnasium/textures/portraits/domenikos_theotokopoulos1.png +0 -0
  123. miniworld_maze/core/miniworld_gymnasium/textures/portraits/edmund_blair_leighton1.license +2 -0
  124. miniworld_maze/core/miniworld_gymnasium/textures/portraits/edmund_blair_leighton1.png +0 -0
  125. miniworld_maze/core/miniworld_gymnasium/textures/portraits/edmund_blair_leighton2.license +2 -0
  126. miniworld_maze/core/miniworld_gymnasium/textures/portraits/edmund_blair_leighton2.png +0 -0
  127. miniworld_maze/core/miniworld_gymnasium/textures/portraits/edwin_longsden_long1.license +2 -0
  128. miniworld_maze/core/miniworld_gymnasium/textures/portraits/edwin_longsden_long1.png +0 -0
  129. miniworld_maze/core/miniworld_gymnasium/textures/portraits/falero_luis_ricardo1.license +2 -0
  130. miniworld_maze/core/miniworld_gymnasium/textures/portraits/falero_luis_ricardo1.png +0 -0
  131. miniworld_maze/core/miniworld_gymnasium/textures/portraits/felix_bonfils1.license +2 -0
  132. miniworld_maze/core/miniworld_gymnasium/textures/portraits/felix_bonfils1.png +0 -0
  133. miniworld_maze/core/miniworld_gymnasium/textures/portraits/francesco_hayez1.license +2 -0
  134. miniworld_maze/core/miniworld_gymnasium/textures/portraits/francesco_hayez1.png +0 -0
  135. miniworld_maze/core/miniworld_gymnasium/textures/portraits/francisco_goya_lucientes1.license +2 -0
  136. miniworld_maze/core/miniworld_gymnasium/textures/portraits/francisco_goya_lucientes1.png +0 -0
  137. miniworld_maze/core/miniworld_gymnasium/textures/portraits/francisco_goya_lucientes2.license +2 -0
  138. miniworld_maze/core/miniworld_gymnasium/textures/portraits/francisco_goya_lucientes2.png +0 -0
  139. miniworld_maze/core/miniworld_gymnasium/textures/portraits/francisco_zurbaran1.license +2 -0
  140. miniworld_maze/core/miniworld_gymnasium/textures/portraits/francisco_zurbaran1.png +0 -0
  141. miniworld_maze/core/miniworld_gymnasium/textures/portraits/franz_von_defregger1.license +2 -0
  142. miniworld_maze/core/miniworld_gymnasium/textures/portraits/franz_von_defregger1.png +0 -0
  143. miniworld_maze/core/miniworld_gymnasium/textures/portraits/franz_von_defregger2.license +2 -0
  144. miniworld_maze/core/miniworld_gymnasium/textures/portraits/franz_von_defregger2.png +0 -0
  145. miniworld_maze/core/miniworld_gymnasium/textures/portraits/franz_von_defregger3.license +2 -0
  146. miniworld_maze/core/miniworld_gymnasium/textures/portraits/franz_von_defregger3.png +0 -0
  147. miniworld_maze/core/miniworld_gymnasium/textures/portraits/frederic_westin1.license +2 -0
  148. miniworld_maze/core/miniworld_gymnasium/textures/portraits/frederic_westin1.png +0 -0
  149. miniworld_maze/core/miniworld_gymnasium/textures/portraits/frederic_yates1.license +2 -0
  150. miniworld_maze/core/miniworld_gymnasium/textures/portraits/frederic_yates1.png +0 -0
  151. miniworld_maze/core/miniworld_gymnasium/textures/portraits/frederick_leighton1.license +2 -0
  152. miniworld_maze/core/miniworld_gymnasium/textures/portraits/frederick_leighton1.png +0 -0
  153. miniworld_maze/core/miniworld_gymnasium/textures/portraits/gaston_bussiere1.license +2 -0
  154. miniworld_maze/core/miniworld_gymnasium/textures/portraits/gaston_bussiere1.png +0 -0
  155. miniworld_maze/core/miniworld_gymnasium/textures/portraits/george_henry_hall1.license +2 -0
  156. miniworld_maze/core/miniworld_gymnasium/textures/portraits/george_henry_hall1.png +0 -0
  157. miniworld_maze/core/miniworld_gymnasium/textures/portraits/giovanni_battista_tiepolo1.license +2 -0
  158. miniworld_maze/core/miniworld_gymnasium/textures/portraits/giovanni_battista_tiepolo1.png +0 -0
  159. miniworld_maze/core/miniworld_gymnasium/textures/portraits/giovanni_bellini1.license +2 -0
  160. miniworld_maze/core/miniworld_gymnasium/textures/portraits/giovanni_bellini1.png +0 -0
  161. miniworld_maze/core/miniworld_gymnasium/textures/portraits/hans_holbein1.license +2 -0
  162. miniworld_maze/core/miniworld_gymnasium/textures/portraits/hans_holbein1.png +0 -0
  163. miniworld_maze/core/miniworld_gymnasium/textures/portraits/hayez_francesco1.license +2 -0
  164. miniworld_maze/core/miniworld_gymnasium/textures/portraits/hayez_francesco1.png +0 -0
  165. miniworld_maze/core/miniworld_gymnasium/textures/portraits/henryk_siemiradzki1.license +2 -0
  166. miniworld_maze/core/miniworld_gymnasium/textures/portraits/henryk_siemiradzki1.png +0 -0
  167. miniworld_maze/core/miniworld_gymnasium/textures/portraits/ilja_jefimowitsch_repin1.license +2 -0
  168. miniworld_maze/core/miniworld_gymnasium/textures/portraits/ilja_jefimowitsch_repin1.png +0 -0
  169. miniworld_maze/core/miniworld_gymnasium/textures/portraits/james_carrol_beckwith1.license +2 -0
  170. miniworld_maze/core/miniworld_gymnasium/textures/portraits/james_carrol_beckwith1.png +0 -0
  171. miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-baptiste-camille_corot1.license +2 -0
  172. miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-baptiste-camille_corot1.png +0 -0
  173. miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-baptiste-camille_corot2.license +2 -0
  174. miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-baptiste-camille_corot2.png +0 -0
  175. miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome1.license +2 -0
  176. miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome1.png +0 -0
  177. miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome2.license +2 -0
  178. miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome2.png +0 -0
  179. miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome3.license +2 -0
  180. miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome3.png +0 -0
  181. miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome4.license +2 -0
  182. miniworld_maze/core/miniworld_gymnasium/textures/portraits/jean-leon_gerome4.png +0 -0
  183. miniworld_maze/core/miniworld_gymnasium/textures/portraits/john_william_godward1.license +2 -0
  184. miniworld_maze/core/miniworld_gymnasium/textures/portraits/john_william_godward1.png +0 -0
  185. miniworld_maze/core/miniworld_gymnasium/textures/portraits/john_william_godward2.license +2 -0
  186. miniworld_maze/core/miniworld_gymnasium/textures/portraits/john_william_godward2.png +0 -0
  187. miniworld_maze/core/miniworld_gymnasium/textures/portraits/john_william_godward3.license +2 -0
  188. miniworld_maze/core/miniworld_gymnasium/textures/portraits/john_william_godward3.png +0 -0
  189. miniworld_maze/core/miniworld_gymnasium/textures/portraits/julije_klovic1.license +2 -0
  190. miniworld_maze/core/miniworld_gymnasium/textures/portraits/julije_klovic1.png +0 -0
  191. miniworld_maze/core/miniworld_gymnasium/textures/portraits/juriaen_streek1.license +2 -0
  192. miniworld_maze/core/miniworld_gymnasium/textures/portraits/juriaen_streek1.png +0 -0
  193. miniworld_maze/core/miniworld_gymnasium/textures/portraits/kiprenskij_orest_adamovic1.license +2 -0
  194. miniworld_maze/core/miniworld_gymnasium/textures/portraits/kiprenskij_orest_adamovic1.png +0 -0
  195. miniworld_maze/core/miniworld_gymnasium/textures/portraits/konstantin_makovsky1.license +2 -0
  196. miniworld_maze/core/miniworld_gymnasium/textures/portraits/konstantin_makovsky1.png +0 -0
  197. miniworld_maze/core/miniworld_gymnasium/textures/portraits/lefebvre_jules_joseph1.license +2 -0
  198. miniworld_maze/core/miniworld_gymnasium/textures/portraits/lefebvre_jules_joseph1.png +0 -0
  199. miniworld_maze/core/miniworld_gymnasium/textures/portraits/leon-francois_comerre1.license +2 -0
  200. miniworld_maze/core/miniworld_gymnasium/textures/portraits/leon-francois_comerre1.png +0 -0
  201. miniworld_maze/core/miniworld_gymnasium/textures/portraits/leopold_loffler1.license +2 -0
  202. miniworld_maze/core/miniworld_gymnasium/textures/portraits/leopold_loffler1.png +0 -0
  203. miniworld_maze/core/miniworld_gymnasium/textures/portraits/lewis_john_frederick1.license +2 -0
  204. miniworld_maze/core/miniworld_gymnasium/textures/portraits/lewis_john_frederick1.png +0 -0
  205. miniworld_maze/core/miniworld_gymnasium/textures/portraits/madrazo_garreta_raimundo1.license +2 -0
  206. miniworld_maze/core/miniworld_gymnasium/textures/portraits/madrazo_garreta_raimundo1.png +0 -0
  207. miniworld_maze/core/miniworld_gymnasium/textures/portraits/marie_bashkirtseff1.license +2 -0
  208. miniworld_maze/core/miniworld_gymnasium/textures/portraits/marie_bashkirtseff1.png +0 -0
  209. miniworld_maze/core/miniworld_gymnasium/textures/portraits/moritz_kellerhoven1.license +2 -0
  210. miniworld_maze/core/miniworld_gymnasium/textures/portraits/moritz_kellerhoven1.png +0 -0
  211. miniworld_maze/core/miniworld_gymnasium/textures/portraits/nathaniel_jocelyn1.license +2 -0
  212. miniworld_maze/core/miniworld_gymnasium/textures/portraits/nathaniel_jocelyn1.png +0 -0
  213. miniworld_maze/core/miniworld_gymnasium/textures/portraits/nikolai_alexandrowitsch_jaroschenko1.license +2 -0
  214. miniworld_maze/core/miniworld_gymnasium/textures/portraits/nikolai_alexandrowitsch_jaroschenko1.png +0 -0
  215. miniworld_maze/core/miniworld_gymnasium/textures/portraits/nils_johan_olsson_blommer1.license +2 -0
  216. miniworld_maze/core/miniworld_gymnasium/textures/portraits/nils_johan_olsson_blommer1.png +0 -0
  217. miniworld_maze/core/miniworld_gymnasium/textures/portraits/paolo_veronese1.license +2 -0
  218. miniworld_maze/core/miniworld_gymnasium/textures/portraits/paolo_veronese1.png +0 -0
  219. miniworld_maze/core/miniworld_gymnasium/textures/portraits/parmigianino1.license +2 -0
  220. miniworld_maze/core/miniworld_gymnasium/textures/portraits/parmigianino1.png +0 -0
  221. miniworld_maze/core/miniworld_gymnasium/textures/portraits/paul_cesar_helleu1.license +2 -0
  222. miniworld_maze/core/miniworld_gymnasium/textures/portraits/paul_cesar_helleu1.png +0 -0
  223. miniworld_maze/core/miniworld_gymnasium/textures/portraits/regnault_henri1.license +2 -0
  224. miniworld_maze/core/miniworld_gymnasium/textures/portraits/regnault_henri1.png +0 -0
  225. miniworld_maze/core/miniworld_gymnasium/textures/portraits/richard_bergh1.license +2 -0
  226. miniworld_maze/core/miniworld_gymnasium/textures/portraits/richard_bergh1.png +0 -0
  227. miniworld_maze/core/miniworld_gymnasium/textures/portraits/richard_bergh2.license +2 -0
  228. miniworld_maze/core/miniworld_gymnasium/textures/portraits/richard_bergh2.png +0 -0
  229. miniworld_maze/core/miniworld_gymnasium/textures/portraits/robert_dampier1.license +2 -0
  230. miniworld_maze/core/miniworld_gymnasium/textures/portraits/robert_dampier1.png +0 -0
  231. miniworld_maze/core/miniworld_gymnasium/textures/portraits/robert_lefevre1.license +2 -0
  232. miniworld_maze/core/miniworld_gymnasium/textures/portraits/robert_lefevre1.png +0 -0
  233. miniworld_maze/core/miniworld_gymnasium/textures/portraits/robert_leopold1.license +2 -0
  234. miniworld_maze/core/miniworld_gymnasium/textures/portraits/robert_leopold1.png +0 -0
  235. miniworld_maze/core/miniworld_gymnasium/textures/portraits/sichel_nathanael1.license +2 -0
  236. miniworld_maze/core/miniworld_gymnasium/textures/portraits/sichel_nathanael1.png +0 -0
  237. miniworld_maze/core/miniworld_gymnasium/textures/portraits/svetoslav_roerich1.license +2 -0
  238. miniworld_maze/core/miniworld_gymnasium/textures/portraits/svetoslav_roerich1.png +0 -0
  239. miniworld_maze/core/miniworld_gymnasium/textures/portraits/velazquez_diego1.license +2 -0
  240. miniworld_maze/core/miniworld_gymnasium/textures/portraits/velazquez_diego1.png +0 -0
  241. miniworld_maze/core/miniworld_gymnasium/textures/portraits/viktor_vasnetsov1.license +2 -0
  242. miniworld_maze/core/miniworld_gymnasium/textures/portraits/viktor_vasnetsov1.png +0 -0
  243. miniworld_maze/core/miniworld_gymnasium/textures/portraits/william-adolphe_bouguereau1.license +2 -0
  244. miniworld_maze/core/miniworld_gymnasium/textures/portraits/william-adolphe_bouguereau1.png +0 -0
  245. miniworld_maze/core/miniworld_gymnasium/textures/realblueberry_1.png +0 -0
  246. miniworld_maze/core/miniworld_gymnasium/textures/redbean_1.png +0 -0
  247. miniworld_maze/core/miniworld_gymnasium/textures/rock_1.png +0 -0
  248. miniworld_maze/core/miniworld_gymnasium/textures/seablue_1.png +0 -0
  249. miniworld_maze/core/miniworld_gymnasium/textures/silver_1.png +0 -0
  250. miniworld_maze/core/miniworld_gymnasium/textures/skyblue_1.png +0 -0
  251. miniworld_maze/core/miniworld_gymnasium/textures/slime_1.png +0 -0
  252. miniworld_maze/core/miniworld_gymnasium/textures/stucco_1.png +0 -0
  253. miniworld_maze/core/miniworld_gymnasium/textures/sunnyyellow_1.png +0 -0
  254. miniworld_maze/core/miniworld_gymnasium/textures/turquoise_1.png +0 -0
  255. miniworld_maze/core/miniworld_gymnasium/textures/violet_1.png +0 -0
  256. miniworld_maze/core/miniworld_gymnasium/textures/water_1.png +0 -0
  257. miniworld_maze/core/miniworld_gymnasium/textures/water_2.png +0 -0
  258. miniworld_maze/core/miniworld_gymnasium/textures/water_3.png +0 -0
  259. miniworld_maze/core/miniworld_gymnasium/textures/white_1.png +0 -0
  260. miniworld_maze/core/miniworld_gymnasium/textures/wood_1.png +0 -0
  261. miniworld_maze/core/miniworld_gymnasium/textures/wood_2.png +0 -0
  262. miniworld_maze/core/miniworld_gymnasium/textures/wood_planks_1.png +0 -0
  263. miniworld_maze/core/miniworld_gymnasium/unified_env.py +1364 -0
  264. miniworld_maze/core/miniworld_gymnasium/utils.py +37 -0
  265. miniworld_maze/core/miniworld_gymnasium/wrappers.py +2 -0
  266. miniworld_maze/core/observation_types.py +32 -0
  267. miniworld_maze/environments/__init__.py +16 -0
  268. miniworld_maze/environments/base_grid_rooms.py +204 -0
  269. miniworld_maze/environments/factory.py +155 -0
  270. miniworld_maze/environments/nine_rooms.py +74 -0
  271. miniworld_maze/environments/spiral_nine_rooms.py +70 -0
  272. miniworld_maze/environments/twenty_five_rooms.py +122 -0
  273. miniworld_maze/tools/__init__.py +5 -0
  274. miniworld_maze/tools/generate_observations.py +199 -0
  275. miniworld_maze/wrappers/__init__.py +5 -0
  276. miniworld_maze/wrappers/image_transforms.py +40 -0
  277. miniworld_maze-1.0.0.dist-info/METADATA +108 -0
  278. miniworld_maze-1.0.0.dist-info/RECORD +280 -0
  279. miniworld_maze-1.0.0.dist-info/WHEEL +4 -0
  280. miniworld_maze-1.0.0.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,293 @@
1
+ """
2
+ Centralized rendering system for MiniWorld environments.
3
+
4
+ This module provides a comprehensive rendering architecture that separates
5
+ OpenGL state management from high-level rendering logic, providing better
6
+ maintainability and testability.
7
+ """
8
+
9
+ from typing import Any, Optional
10
+
11
+ import numpy as np
12
+ from pyglet.gl import *
13
+ from pyglet.gl.glu import *
14
+
15
+ from ..observation_types import ObservationLevel
16
+ from .rendering.framebuffer import FrameBuffer
17
+
18
+
19
+ class OpenGLContextManager:
20
+ """Manage OpenGL state and context switching."""
21
+
22
+ def __init__(self):
23
+ """Initialize OpenGL context manager."""
24
+ self._saved_state = {}
25
+
26
+ def save_state(self):
27
+ """Save current OpenGL state."""
28
+ self._saved_state = {
29
+ "viewport": (GLint * 4)(),
30
+ "projection_matrix": (GLfloat * 16)(),
31
+ "modelview_matrix": (GLfloat * 16)(),
32
+ }
33
+ glGetIntegerv(GL_VIEWPORT, self._saved_state["viewport"])
34
+ glGetFloatv(GL_PROJECTION_MATRIX, self._saved_state["projection_matrix"])
35
+ glGetFloatv(GL_MODELVIEW_MATRIX, self._saved_state["modelview_matrix"])
36
+
37
+ def restore_state(self):
38
+ """Restore previously saved OpenGL state."""
39
+ if self._saved_state:
40
+ glViewport(*self._saved_state["viewport"])
41
+ glMatrixMode(GL_PROJECTION)
42
+ glLoadMatrixf(self._saved_state["projection_matrix"])
43
+ glMatrixMode(GL_MODELVIEW)
44
+ glLoadMatrixf(self._saved_state["modelview_matrix"])
45
+
46
+ def rendering_context(self):
47
+ """Context manager for safe rendering state management."""
48
+ return RenderingContext(self)
49
+
50
+
51
+ class RenderingContext:
52
+ """Context manager for OpenGL rendering state."""
53
+
54
+ def __init__(self, context_manager: OpenGLContextManager):
55
+ """Initialize rendering context with OpenGL context manager."""
56
+ self.context_manager = context_manager
57
+
58
+ def __enter__(self):
59
+ """Enter rendering context and save OpenGL state."""
60
+ self.context_manager.save_state()
61
+ return self
62
+
63
+ def __exit__(self, exc_type, exc_val, exc_tb):
64
+ """Exit rendering context and restore OpenGL state."""
65
+ self.context_manager.restore_state()
66
+
67
+
68
+ class FrameBufferManager:
69
+ """Manage frame buffers and resolution handling."""
70
+
71
+ def __init__(self, obs_width: int, obs_height: int):
72
+ """Initialize framebuffer manager with default observation dimensions."""
73
+ self.obs_width = obs_width
74
+ self.obs_height = obs_height
75
+ self.frame_buffers = {}
76
+
77
+ def get_or_create_framebuffer(
78
+ self, name: str, width: Optional[int] = None, height: Optional[int] = None
79
+ ) -> FrameBuffer:
80
+ """Get existing framebuffer or create new one."""
81
+ width = width or self.obs_width
82
+ height = height or self.obs_height
83
+ key = (name, width, height)
84
+
85
+ if key not in self.frame_buffers:
86
+ self.frame_buffers[key] = FrameBuffer(width, height)
87
+
88
+ return self.frame_buffers[key]
89
+
90
+ def cleanup(self):
91
+ """Clean up all frame buffers."""
92
+ for fb in self.frame_buffers.values():
93
+ if hasattr(fb, "cleanup"):
94
+ fb.cleanup()
95
+ self.frame_buffers.clear()
96
+
97
+
98
+ class CameraSystem:
99
+ """Handle camera positioning and projection matrices."""
100
+
101
+ def __init__(self):
102
+ """Initialize camera system with configuration cache."""
103
+ self.camera_configs = {}
104
+
105
+ def get_config(self, obs_level: ObservationLevel, agent: Any) -> dict:
106
+ """Get camera configuration for observation level."""
107
+ if obs_level == ObservationLevel.FIRST_PERSON:
108
+ return {
109
+ "type": "perspective",
110
+ "position": agent.pos + np.array([0, agent.cam_height, 0]),
111
+ "direction": agent.dir_vec,
112
+ "up": np.array([0, 1, 0]),
113
+ "fov": agent.cam_fov_y,
114
+ }
115
+ elif obs_level in [
116
+ ObservationLevel.TOP_DOWN_PARTIAL,
117
+ ObservationLevel.TOP_DOWN_FULL,
118
+ ]:
119
+ return {
120
+ "type": "orthographic",
121
+ "position": agent.pos + np.array([0, 10, 0]), # High above
122
+ "direction": np.array([0, -1, 0]), # Looking down
123
+ "up": np.array([0, 0, -1]), # Z-axis points up in top view
124
+ "bounds": self._calculate_view_bounds(obs_level, agent),
125
+ }
126
+ else:
127
+ raise ValueError(f"Unsupported observation level: {obs_level}")
128
+
129
+ def _calculate_view_bounds(self, obs_level: ObservationLevel, agent: Any) -> dict:
130
+ """Calculate view bounds for top-down rendering."""
131
+ if obs_level == ObservationLevel.TOP_DOWN_PARTIAL:
132
+ # POMDP view - limited around agent
133
+ view_size = 8.0 # Configurable view size
134
+ return {
135
+ "left": agent.pos[0] - view_size,
136
+ "right": agent.pos[0] + view_size,
137
+ "bottom": agent.pos[2] - view_size,
138
+ "top": agent.pos[2] + view_size,
139
+ }
140
+ else:
141
+ # Full view - would need environment bounds
142
+ return {"left": -20, "right": 20, "bottom": -20, "top": 20}
143
+
144
+ def setup_camera(self, config: dict, frame_buffer: FrameBuffer):
145
+ """Setup camera projection and view matrices."""
146
+ glMatrixMode(GL_PROJECTION)
147
+ glLoadIdentity()
148
+
149
+ if config["type"] == "perspective":
150
+ aspect_ratio = frame_buffer.width / frame_buffer.height
151
+ # Setup perspective projection
152
+ gluPerspective(config["fov"], aspect_ratio, 0.04, 100.0)
153
+ elif config["type"] == "orthographic":
154
+ bounds = config["bounds"]
155
+ glOrtho(
156
+ bounds["left"],
157
+ bounds["right"],
158
+ bounds["bottom"],
159
+ bounds["top"],
160
+ 0.01,
161
+ 100.0,
162
+ )
163
+
164
+ glMatrixMode(GL_MODELVIEW)
165
+ glLoadIdentity()
166
+
167
+ # Setup view matrix
168
+ pos = config["position"]
169
+ direction = config["direction"]
170
+ up = config["up"]
171
+ target = pos + direction
172
+
173
+ gluLookAt(
174
+ pos[0], pos[1], pos[2], target[0], target[1], target[2], up[0], up[1], up[2]
175
+ )
176
+
177
+
178
+ class RenderingEngine:
179
+ """Centralized rendering system for MiniWorld environments."""
180
+
181
+ def __init__(self, obs_width: int, obs_height: int):
182
+ """Initialize rendering engine with all subsystems."""
183
+ self.context_manager = OpenGLContextManager()
184
+ self.framebuffer_manager = FrameBufferManager(obs_width, obs_height)
185
+ self.camera_system = CameraSystem()
186
+
187
+ self.obs_width = obs_width
188
+ self.obs_height = obs_height
189
+
190
+ def render_observation(
191
+ self,
192
+ obs_level: ObservationLevel,
193
+ agent: Any,
194
+ entities: list,
195
+ rooms: list,
196
+ frame_buffer: Optional[FrameBuffer] = None,
197
+ ) -> np.ndarray:
198
+ """Unified observation rendering."""
199
+ if frame_buffer is None:
200
+ frame_buffer = self.framebuffer_manager.get_or_create_framebuffer("obs")
201
+
202
+ camera_config = self.camera_system.get_config(obs_level, agent)
203
+
204
+ with self.context_manager.rendering_context():
205
+ frame_buffer.bind()
206
+ self.camera_system.setup_camera(camera_config, frame_buffer)
207
+ self._setup_scene()
208
+ self._render_entities_and_rooms(
209
+ entities,
210
+ rooms,
211
+ agent,
212
+ render_agent=(obs_level != ObservationLevel.FIRST_PERSON),
213
+ )
214
+ img = frame_buffer.resolve()
215
+
216
+ return img
217
+
218
+ def render_top_view(
219
+ self,
220
+ agent: Any,
221
+ entities: list,
222
+ rooms: list,
223
+ POMDP: bool = False,
224
+ render_agent: bool = True,
225
+ frame_buffer: Optional[FrameBuffer] = None,
226
+ ) -> np.ndarray:
227
+ """Render top-down view of the environment."""
228
+ if frame_buffer is None:
229
+ frame_buffer = self.framebuffer_manager.get_or_create_framebuffer("topview")
230
+
231
+ obs_level = (
232
+ ObservationLevel.TOP_DOWN_PARTIAL
233
+ if POMDP
234
+ else ObservationLevel.TOP_DOWN_FULL
235
+ )
236
+ camera_config = self.camera_system.get_config(obs_level, agent)
237
+
238
+ with self.context_manager.rendering_context():
239
+ frame_buffer.bind()
240
+ self.camera_system.setup_camera(camera_config, frame_buffer)
241
+ self._setup_scene()
242
+ self._render_entities_and_rooms(entities, rooms, agent, render_agent)
243
+ img = frame_buffer.resolve()
244
+
245
+ return img
246
+
247
+ def _setup_scene(self):
248
+ """Setup basic OpenGL scene state."""
249
+ # Clear buffers
250
+ glClearColor(0.8, 0.9, 1.0, 1.0) # Light blue background
251
+ glClearDepth(1.0)
252
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
253
+
254
+ # Enable depth testing
255
+ glEnable(GL_DEPTH_TEST)
256
+ glDepthFunc(GL_LESS)
257
+
258
+ # Enable face culling
259
+ glEnable(GL_CULL_FACE)
260
+ glCullFace(GL_BACK)
261
+ glFrontFace(GL_CCW)
262
+
263
+ # Setup lighting (basic ambient light)
264
+ glEnable(GL_LIGHTING)
265
+ glEnable(GL_LIGHT0)
266
+
267
+ light_pos = (GLfloat * 4)(10.0, 10.0, 10.0, 1.0)
268
+ light_ambient = (GLfloat * 4)(0.2, 0.2, 0.2, 1.0)
269
+ light_diffuse = (GLfloat * 4)(0.8, 0.8, 0.8, 1.0)
270
+
271
+ glLightfv(GL_LIGHT0, GL_POSITION, light_pos)
272
+ glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient)
273
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse)
274
+
275
+ def _render_entities_and_rooms(
276
+ self, entities: list, rooms: list, agent: Any, render_agent: bool = True
277
+ ):
278
+ """Render all entities and rooms in the scene."""
279
+ # Render rooms first (floors, walls, ceilings)
280
+ for room in rooms:
281
+ if hasattr(room, "_render"):
282
+ room._render()
283
+
284
+ # Render entities
285
+ for entity in entities:
286
+ if entity is agent and not render_agent:
287
+ continue
288
+ if hasattr(entity, "render"):
289
+ entity.render()
290
+
291
+ def cleanup(self):
292
+ """Clean up rendering resources."""
293
+ self.framebuffer_manager.cleanup()
@@ -0,0 +1,330 @@
1
+ """Room class for MiniWorld environments."""
2
+
3
+ import numpy as np
4
+ from pyglet.gl import *
5
+
6
+ from .math import Y_VEC
7
+ from .opengl import Texture
8
+ from .texture_utils import gen_texcs_floor, gen_texcs_wall
9
+
10
+ # Default wall height for room
11
+ DEFAULT_WALL_HEIGHT = 2.74
12
+
13
+
14
+ class Room:
15
+ """Represent an individual room and its contents"""
16
+
17
+ def __init__(
18
+ self,
19
+ outline,
20
+ wall_height=DEFAULT_WALL_HEIGHT,
21
+ floor_tex="floor_tiles_bw",
22
+ wall_tex="concrete",
23
+ ceil_tex="concrete_tiles",
24
+ no_ceiling=False,
25
+ ):
26
+ # The outlien should have shape Nx2
27
+ assert len(outline.shape) == 2
28
+ assert outline.shape[1] == 2
29
+ assert outline.shape[0] >= 3
30
+
31
+ # Add a Y coordinate to the outline points
32
+ outline = np.insert(outline, 1, 0, axis=1)
33
+
34
+ # Number of outline vertices / walls
35
+ self.num_walls = outline.shape[0]
36
+
37
+ # List of 2D points forming the outline of the room
38
+ # Shape is Nx3
39
+ self.outline = outline
40
+
41
+ # Compute the min and max x, z extents
42
+ self.min_x = self.outline[:, 0].min()
43
+ self.max_x = self.outline[:, 0].max()
44
+ self.min_z = self.outline[:, 2].min()
45
+ self.max_z = self.outline[:, 2].max()
46
+
47
+ # Compute midpoint coordinates
48
+ self.mid_x = (self.max_x + self.min_x) / 2
49
+ self.mid_z = (self.max_z + self.min_z) / 2
50
+
51
+ # Compute approximate surface area
52
+ self.area = (self.max_x - self.min_x) * (self.max_z - self.min_z)
53
+
54
+ # Compute room edge directions and normals
55
+ # Compute edge vectors (p1 - p0)
56
+ # For the first point, p0 is the last
57
+ # For the last point, p0 is p_n-1
58
+ next_pts = np.concatenate(
59
+ [self.outline[1:], np.expand_dims(self.outline[0], axis=0)], axis=0
60
+ )
61
+ self.edge_dirs = next_pts - self.outline
62
+ self.edge_dirs = (self.edge_dirs.T / np.linalg.norm(self.edge_dirs, axis=1)).T
63
+ self.edge_norms = -np.cross(self.edge_dirs, Y_VEC)
64
+ self.edge_norms = (
65
+ self.edge_norms.T / np.linalg.norm(self.edge_norms, axis=1)
66
+ ).T
67
+
68
+ # Height of the room walls
69
+ self.wall_height = wall_height
70
+
71
+ # No ceiling flag
72
+ self.no_ceiling = no_ceiling
73
+
74
+ # Texture names
75
+ self.wall_tex_name = wall_tex
76
+ self.floor_tex_name = floor_tex
77
+ self.ceil_tex_name = ceil_tex
78
+
79
+ # Lists of portals, indexed by wall/edge index
80
+ self.portals = [[] for i in range(self.num_walls)]
81
+
82
+ # List of neighbor rooms
83
+ # Same length as list of portals
84
+ self.neighbors = []
85
+
86
+ def add_portal(
87
+ self,
88
+ edge,
89
+ start_pos=None,
90
+ end_pos=None,
91
+ min_x=None,
92
+ max_x=None,
93
+ min_z=None,
94
+ max_z=None,
95
+ min_y=0,
96
+ max_y=None,
97
+ ):
98
+ """Create a new portal/opening in a wall of this room"""
99
+
100
+ if max_y is None:
101
+ max_y = self.wall_height
102
+
103
+ assert edge <= self.num_walls
104
+ assert max_y > min_y
105
+
106
+ # Get the edge points, compute the direction vector
107
+ e_p0 = self.outline[edge]
108
+ e_p1 = self.outline[(edge + 1) % self.num_walls]
109
+ e_len = np.linalg.norm(e_p1 - e_p0)
110
+ e_dir = (e_p1 - e_p0) / e_len
111
+ x0, _, z0 = e_p0
112
+ x1, _, z1 = e_p1
113
+ dx, _, dz = e_dir
114
+
115
+ # If the portal extents are specified by x coordinates
116
+ if min_x is not None:
117
+ assert min_z is None and max_z is None
118
+ assert start_pos is None and end_pos is None
119
+ assert x0 != x1
120
+
121
+ m0 = (min_x - x0) / dx
122
+ m1 = (max_x - x0) / dx
123
+
124
+ if m1 < m0:
125
+ m0, m1 = m1, m0
126
+
127
+ start_pos, end_pos = m0, m1
128
+
129
+ # If the portal extents are specified by z coordinates
130
+ elif min_z is not None:
131
+ assert min_x is None and max_x is None
132
+ assert start_pos is None and end_pos is None
133
+ assert z0 != z1
134
+
135
+ m0 = (min_z - z0) / dz
136
+ m1 = (max_z - z0) / dz
137
+
138
+ if m1 < m0:
139
+ m0, m1 = m1, m0
140
+
141
+ start_pos, end_pos = m0, m1
142
+
143
+ else:
144
+ assert min_x is None and max_x is None
145
+ assert min_z is None and max_z is None
146
+
147
+ assert end_pos > start_pos
148
+ assert start_pos >= 0, "portal outside of wall extents"
149
+ assert end_pos <= e_len, "portal outside of wall extents"
150
+
151
+ self.portals[edge].append(
152
+ {"start_pos": start_pos, "end_pos": end_pos, "min_y": min_y, "max_y": max_y}
153
+ )
154
+
155
+ # Sort the portals by start position
156
+ self.portals[edge].sort(key=lambda e: e["start_pos"])
157
+
158
+ return start_pos, end_pos
159
+
160
+ def point_inside(self, p):
161
+ """Test if a point is inside the room"""
162
+
163
+ # Vector from edge start to test point
164
+ ap = p - self.outline
165
+
166
+ # Compute the dot products of normals to AP vectors
167
+ dotNAP = np.sum(self.edge_norms * ap, axis=1)
168
+
169
+ # The point is inside if all the dot products are greater than zero
170
+ return np.all(np.greater(dotNAP, 0))
171
+
172
+ def _gen_static_data(self, params, rng):
173
+ """Generate polygons and static data for this room
174
+
175
+ Needed for rendering and collision detection
176
+ Note: the wall polygons are quads, but the floor and
177
+ ceiling can be arbitrary n-gons
178
+ """
179
+ self._load_textures(rng)
180
+ self._generate_floor_geometry()
181
+ self._generate_ceiling_geometry()
182
+ self._generate_wall_geometry()
183
+ self._finalize_wall_geometry()
184
+
185
+ def _load_textures(self, rng):
186
+ """Load and randomize room textures."""
187
+ self.wall_tex = Texture.get(self.wall_tex_name, rng)
188
+ self.floor_tex = Texture.get(self.floor_tex_name, rng)
189
+ self.ceil_tex = Texture.get(self.ceil_tex_name, rng)
190
+
191
+ def _generate_floor_geometry(self):
192
+ """Generate floor vertices and texture coordinates."""
193
+ self.floor_verts = self.outline
194
+ self.floor_texcs = gen_texcs_floor(self.floor_tex, self.floor_verts)
195
+
196
+ def _generate_ceiling_geometry(self):
197
+ """Generate ceiling vertices and texture coordinates."""
198
+ # Flip the ceiling vertex order because of backface culling
199
+ self.ceil_verts = np.flip(self.outline, axis=0) + self.wall_height * Y_VEC
200
+ self.ceil_texcs = gen_texcs_floor(self.ceil_tex, self.ceil_verts)
201
+
202
+ def _generate_wall_geometry(self):
203
+ """Generate wall vertices, normals, texture coordinates, and collision segments."""
204
+ self.wall_verts = []
205
+ self.wall_norms = []
206
+ self.wall_texcs = []
207
+ self.wall_segs = []
208
+
209
+ def gen_seg_poly(edge_p0, side_vec, seg_start, seg_end, min_y, max_y):
210
+ if seg_end == seg_start:
211
+ return
212
+
213
+ if min_y == max_y:
214
+ return
215
+
216
+ s_p0 = edge_p0 + seg_start * side_vec
217
+ s_p1 = edge_p0 + seg_end * side_vec
218
+
219
+ # If this polygon starts at ground level, add a collidable segment
220
+ if min_y == 0:
221
+ self.wall_segs.append(np.array([s_p1, s_p0]))
222
+
223
+ # Generate the vertices
224
+ # Vertices are listed in counter-clockwise order
225
+ self.wall_verts.append(s_p0 + min_y * Y_VEC)
226
+ self.wall_verts.append(s_p0 + max_y * Y_VEC)
227
+ self.wall_verts.append(s_p1 + max_y * Y_VEC)
228
+ self.wall_verts.append(s_p1 + min_y * Y_VEC)
229
+
230
+ # Compute the normal for the polygon
231
+ normal = np.cross(s_p1 - s_p0, Y_VEC)
232
+ normal = -normal / np.linalg.norm(normal)
233
+ for i in range(4):
234
+ self.wall_norms.append(normal)
235
+
236
+ # Generate the texture coordinates
237
+ texcs = gen_texcs_wall(
238
+ self.wall_tex, seg_start, min_y, seg_end - seg_start, max_y - min_y
239
+ )
240
+ self.wall_texcs.append(texcs)
241
+
242
+ # For each wall
243
+ for wall_idx in range(self.num_walls):
244
+ edge_p0 = self.outline[wall_idx, :]
245
+ edge_p1 = self.outline[(wall_idx + 1) % self.num_walls, :]
246
+ wall_width = np.linalg.norm(edge_p1 - edge_p0)
247
+ side_vec = (edge_p1 - edge_p0) / wall_width
248
+
249
+ if len(self.portals[wall_idx]) > 0:
250
+ seg_end = self.portals[wall_idx][0]["start_pos"]
251
+ else:
252
+ seg_end = wall_width
253
+
254
+ # Generate the first polygon (going up to the first portal)
255
+ gen_seg_poly(edge_p0, side_vec, 0, seg_end, 0, self.wall_height)
256
+
257
+ # For each portal in this wall
258
+ for portal_idx, portal in enumerate(self.portals[wall_idx]):
259
+ portal = self.portals[wall_idx][portal_idx]
260
+ start_pos = portal["start_pos"]
261
+ end_pos = portal["end_pos"]
262
+ min_y = portal["min_y"]
263
+ max_y = portal["max_y"]
264
+
265
+ # Generate the bottom polygon
266
+ gen_seg_poly(edge_p0, side_vec, start_pos, end_pos, 0, min_y)
267
+
268
+ # Generate the top polygon
269
+ gen_seg_poly(
270
+ edge_p0, side_vec, start_pos, end_pos, max_y, self.wall_height
271
+ )
272
+
273
+ if portal_idx < len(self.portals[wall_idx]) - 1:
274
+ next_portal = self.portals[wall_idx][portal_idx + 1]
275
+ next_portal_start = next_portal["start_pos"]
276
+ else:
277
+ next_portal_start = wall_width
278
+
279
+ # Generate the polygon going up to the next portal
280
+ gen_seg_poly(
281
+ edge_p0, side_vec, end_pos, next_portal_start, 0, self.wall_height
282
+ )
283
+
284
+ def _finalize_wall_geometry(self):
285
+ """Convert wall geometry lists to numpy arrays."""
286
+ self.wall_verts = np.array(self.wall_verts)
287
+ self.wall_norms = np.array(self.wall_norms)
288
+
289
+ if len(self.wall_segs) > 0:
290
+ self.wall_segs = np.array(self.wall_segs)
291
+ else:
292
+ self.wall_segs = np.array([]).reshape(0, 2, 3)
293
+
294
+ if len(self.wall_texcs) > 0:
295
+ self.wall_texcs = np.concatenate(self.wall_texcs)
296
+ else:
297
+ self.wall_texcs = np.array([]).reshape(0, 2)
298
+
299
+ def _render(self):
300
+ """Render the static elements of the room"""
301
+
302
+ glColor3f(1, 1, 1)
303
+
304
+ # Draw the floor
305
+ self.floor_tex.bind()
306
+ glBegin(GL_POLYGON)
307
+ glNormal3f(0, 1, 0)
308
+ for i in range(self.floor_verts.shape[0]):
309
+ glTexCoord2f(*self.floor_texcs[i, :])
310
+ glVertex3f(*self.floor_verts[i, :])
311
+ glEnd()
312
+
313
+ # Draw the ceiling
314
+ if not self.no_ceiling:
315
+ self.ceil_tex.bind()
316
+ glBegin(GL_POLYGON)
317
+ glNormal3f(0, -1, 0)
318
+ for i in range(self.ceil_verts.shape[0]):
319
+ glTexCoord2f(*self.ceil_texcs[i, :])
320
+ glVertex3f(*self.ceil_verts[i, :])
321
+ glEnd()
322
+
323
+ # Draw the walls
324
+ self.wall_tex.bind()
325
+ glBegin(GL_QUADS)
326
+ for i in range(self.wall_verts.shape[0]):
327
+ glNormal3f(*self.wall_norms[i, :])
328
+ glTexCoord2f(*self.wall_texcs[i, :])
329
+ glVertex3f(*self.wall_verts[i, :])
330
+ glEnd()
@@ -0,0 +1,64 @@
1
+ """Texture utility functions for MiniWorld environments."""
2
+
3
+ import numpy as np
4
+
5
+ # Texture size/density in texels/meter
6
+ TEX_DENSITY = 512
7
+
8
+
9
+ def gen_texcs_wall(tex, min_x, min_y, width, height):
10
+ """
11
+ Generate texture coordinates for a wall quad.
12
+
13
+ Maps wall surface dimensions to texture coordinates based on texture density.
14
+
15
+ Args:
16
+ tex: Texture object with width/height properties
17
+ min_x (float): Minimum x coordinate of wall surface
18
+ min_y (float): Minimum y coordinate of wall surface
19
+ width (float): Width of wall surface
20
+ height (float): Height of wall surface
21
+
22
+ Returns:
23
+ np.ndarray: 4x2 array of texture coordinates for wall quad vertices
24
+ """
25
+ xc = TEX_DENSITY / tex.width
26
+ yc = TEX_DENSITY / tex.height
27
+
28
+ min_u = (min_x) * xc
29
+ max_u = (min_x + width) * xc
30
+ min_v = (min_y) * yc
31
+ max_v = (min_y + height) * yc
32
+
33
+ return np.array(
34
+ [
35
+ [min_u, min_v],
36
+ [min_u, max_v],
37
+ [max_u, max_v],
38
+ [max_u, min_v],
39
+ ],
40
+ dtype=np.float32,
41
+ )
42
+
43
+
44
+ def gen_texcs_floor(tex, poss):
45
+ """
46
+ Generate texture coordinates for floor or ceiling surfaces.
47
+
48
+ Maps 3D world positions directly to 2D texture coordinates by projecting
49
+ x,z coordinates onto texture space using texture density scaling.
50
+
51
+ Args:
52
+ tex: Texture object with width/height properties
53
+ poss (np.ndarray): Nx3 array of 3D world positions
54
+
55
+ Returns:
56
+ np.ndarray: Nx2 array of texture coordinates
57
+ """
58
+ texc_mul = np.array(
59
+ [TEX_DENSITY / tex.width, TEX_DENSITY / tex.height], dtype=float
60
+ )
61
+
62
+ coords = np.stack([poss[:, 0], poss[:, 2]], axis=1) * texc_mul
63
+
64
+ return coords