koffi 2.1.1 → 2.1.3

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.
Files changed (312) hide show
  1. package/ChangeLog.md +12 -0
  2. package/build/qemu/2.1.3/koffi_darwin_arm64.tar.gz +0 -0
  3. package/build/qemu/2.1.3/koffi_darwin_x64.tar.gz +0 -0
  4. package/build/qemu/2.1.3/koffi_freebsd_arm64.tar.gz +0 -0
  5. package/build/qemu/2.1.3/koffi_freebsd_ia32.tar.gz +0 -0
  6. package/build/qemu/2.1.3/koffi_freebsd_x64.tar.gz +0 -0
  7. package/build/qemu/2.1.3/koffi_linux_arm32hf.tar.gz +0 -0
  8. package/build/qemu/2.1.3/koffi_linux_arm64.tar.gz +0 -0
  9. package/build/qemu/2.1.3/koffi_linux_ia32.tar.gz +0 -0
  10. package/build/qemu/2.1.3/koffi_linux_riscv64hf64.tar.gz +0 -0
  11. package/build/qemu/2.1.3/koffi_linux_x64.tar.gz +0 -0
  12. package/build/qemu/2.1.3/koffi_openbsd_ia32.tar.gz +0 -0
  13. package/build/qemu/2.1.3/koffi_openbsd_x64.tar.gz +0 -0
  14. package/build/qemu/2.1.3/koffi_win32_arm64.tar.gz +0 -0
  15. package/build/qemu/2.1.3/koffi_win32_ia32.tar.gz +0 -0
  16. package/build/qemu/2.1.3/koffi_win32_x64.tar.gz +0 -0
  17. package/doc/templates/badges.html +3 -0
  18. package/package.json +2 -2
  19. package/src/abi_arm64.cc +35 -1
  20. package/src/abi_x64_win.cc +2 -8
  21. package/src/abi_x86.cc +1 -7
  22. package/src/ffi.cc +2 -2
  23. package/src/ffi.hh +1 -1
  24. package/src/util.hh +6 -0
  25. package/test/raylib.js +37 -5
  26. package/vendor/libcc/libcc.cc +430 -196
  27. package/vendor/libcc/libcc.hh +1417 -1283
  28. package/vendor/raylib/BINDINGS.md +87 -70
  29. package/vendor/raylib/CHANGELOG +263 -50
  30. package/vendor/raylib/CMakeLists.txt +12 -0
  31. package/vendor/raylib/CMakeOptions.txt +8 -1
  32. package/vendor/raylib/CONVENTIONS.md +2 -3
  33. package/vendor/raylib/FAQ.md +137 -0
  34. package/vendor/raylib/HISTORY.md +62 -29
  35. package/vendor/raylib/LICENSE +1 -1
  36. package/vendor/raylib/README.md +22 -17
  37. package/vendor/raylib/ROADMAP.md +8 -7
  38. package/vendor/raylib/cmake/CompileDefinitions.cmake +19 -15
  39. package/vendor/raylib/cmake/GlfwImport.cmake +2 -0
  40. package/vendor/raylib/cmake/LibraryConfigurations.cmake +22 -16
  41. package/vendor/raylib/cmake/raylib-config.cmake +52 -49
  42. package/vendor/raylib/examples/CMakeLists.txt +14 -9
  43. package/vendor/raylib/examples/Makefile +112 -125
  44. package/vendor/raylib/examples/Makefile.Android +1 -1
  45. package/vendor/raylib/examples/Makefile.Web +145 -158
  46. package/vendor/raylib/examples/README.md +141 -141
  47. package/vendor/raylib/examples/audio/audio_module_playing.c +9 -4
  48. package/vendor/raylib/examples/audio/audio_multichannel_sound.c +8 -3
  49. package/vendor/raylib/examples/audio/audio_music_stream.c +16 -11
  50. package/vendor/raylib/examples/audio/audio_raw_stream.c +57 -9
  51. package/vendor/raylib/examples/audio/audio_sound_loading.c +8 -3
  52. package/vendor/raylib/examples/audio/audio_stream_effects.c +179 -0
  53. package/vendor/raylib/examples/audio/audio_stream_effects.png +0 -0
  54. package/vendor/raylib/examples/build.zig +17 -6
  55. package/vendor/raylib/examples/core/core_2d_camera.c +8 -4
  56. package/vendor/raylib/examples/core/core_2d_camera_mouse_zoom.c +105 -0
  57. package/vendor/raylib/examples/core/core_2d_camera_mouse_zoom.png +0 -0
  58. package/vendor/raylib/examples/core/core_2d_camera_platformer.c +11 -6
  59. package/vendor/raylib/examples/core/core_3d_camera_first_person.c +9 -4
  60. package/vendor/raylib/examples/core/core_3d_camera_free.c +9 -4
  61. package/vendor/raylib/examples/core/core_3d_camera_mode.c +8 -3
  62. package/vendor/raylib/examples/core/core_3d_picking.c +9 -4
  63. package/vendor/raylib/examples/core/core_basic_screen_manager.c +9 -7
  64. package/vendor/raylib/examples/core/core_basic_window.c +8 -3
  65. package/vendor/raylib/examples/core/core_basic_window_web.c +13 -11
  66. package/vendor/raylib/examples/core/core_custom_frame_control.c +9 -4
  67. package/vendor/raylib/examples/core/core_custom_logging.c +12 -8
  68. package/vendor/raylib/examples/core/core_drop_files.c +20 -12
  69. package/vendor/raylib/examples/core/core_input_gamepad.c +20 -15
  70. package/vendor/raylib/examples/core/core_input_gestures.c +19 -15
  71. package/vendor/raylib/examples/core/core_input_keys.c +8 -3
  72. package/vendor/raylib/examples/core/core_input_mouse.c +8 -3
  73. package/vendor/raylib/examples/core/core_input_mouse_wheel.c +8 -3
  74. package/vendor/raylib/examples/core/core_input_multitouch.c +8 -3
  75. package/vendor/raylib/examples/core/core_loading_thread.c +10 -6
  76. package/vendor/raylib/examples/core/core_random_values.c +8 -3
  77. package/vendor/raylib/examples/core/core_scissor_test.c +8 -3
  78. package/vendor/raylib/examples/core/core_smooth_pixelperfect.c +9 -4
  79. package/vendor/raylib/examples/core/core_split_screen.c +8 -3
  80. package/vendor/raylib/examples/core/core_storage_values.c +109 -3
  81. package/vendor/raylib/examples/core/core_vr_simulator.c +15 -7
  82. package/vendor/raylib/examples/core/core_window_flags.c +8 -3
  83. package/vendor/raylib/examples/core/core_window_letterbox.c +13 -18
  84. package/vendor/raylib/examples/core/core_window_should_close.c +77 -0
  85. package/vendor/raylib/examples/core/core_window_should_close.png +0 -0
  86. package/vendor/raylib/examples/core/core_world_screen.c +9 -4
  87. package/vendor/raylib/examples/examples_template.c +8 -3
  88. package/vendor/raylib/examples/models/models_animation.c +11 -7
  89. package/vendor/raylib/examples/models/models_billboard.c +9 -4
  90. package/vendor/raylib/examples/models/models_box_collisions.c +8 -3
  91. package/vendor/raylib/examples/models/models_cubicmap.c +9 -4
  92. package/vendor/raylib/examples/models/models_first_person_maze.c +9 -4
  93. package/vendor/raylib/examples/models/models_geometric_shapes.c +8 -3
  94. package/vendor/raylib/examples/models/models_heightmap.c +9 -4
  95. package/vendor/raylib/examples/models/models_loading.c +21 -17
  96. package/vendor/raylib/examples/models/models_loading_gltf.c +15 -41
  97. package/vendor/raylib/examples/models/models_loading_vox.c +9 -4
  98. package/vendor/raylib/examples/models/models_mesh_generation.c +71 -58
  99. package/vendor/raylib/examples/models/models_mesh_picking.c +25 -7
  100. package/vendor/raylib/examples/models/models_orthographic_projection.c +8 -5
  101. package/vendor/raylib/examples/models/models_rlgl_solar_system.c +6 -4
  102. package/vendor/raylib/examples/models/models_skybox.c +16 -12
  103. package/vendor/raylib/examples/models/models_waving_cubes.c +9 -4
  104. package/vendor/raylib/examples/models/models_yaw_pitch_roll.c +12 -7
  105. package/vendor/raylib/examples/models/resources/LICENSE.md +9 -10
  106. package/vendor/raylib/examples/models/resources/models/gltf/LICENSE +2 -23
  107. package/vendor/raylib/examples/models/resources/models/gltf/{raylib_32x32.glb → raylib_logo_3d.glb} +0 -0
  108. package/vendor/raylib/examples/models/resources/models/gltf/robot.blend +0 -0
  109. package/vendor/raylib/examples/models/resources/models/gltf/robot.glb +0 -0
  110. package/vendor/raylib/examples/others/easings_testbed.c +10 -8
  111. package/vendor/raylib/examples/others/easings_testbed.png +0 -0
  112. package/vendor/raylib/examples/others/embedded_files_loading.c +10 -5
  113. package/vendor/raylib/examples/others/embedded_files_loading.png +0 -0
  114. package/vendor/raylib/examples/others/raylib_opengl_interop.c +10 -6
  115. package/vendor/raylib/{src/extras/easings.h → examples/others/reasings.h} +38 -38
  116. package/vendor/raylib/examples/others/rlgl_compute_shader.c +21 -20
  117. package/vendor/raylib/examples/others/rlgl_compute_shader.png +0 -0
  118. package/vendor/raylib/examples/others/rlgl_standalone.c +4 -4
  119. package/vendor/raylib/examples/others/rlgl_standalone.png +0 -0
  120. package/vendor/raylib/examples/raylib_compile_execute.bat +2 -2
  121. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/lighting.fs +1 -1
  122. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/{base_lighting_instanced.vs → lighting_instancing.vs} +2 -2
  123. package/vendor/raylib/examples/shaders/rlights.h +14 -27
  124. package/vendor/raylib/examples/shaders/shaders_basic_lighting.c +24 -26
  125. package/vendor/raylib/examples/shaders/shaders_custom_uniform.c +10 -5
  126. package/vendor/raylib/examples/shaders/shaders_eratosthenes.c +13 -8
  127. package/vendor/raylib/examples/shaders/shaders_fog.c +8 -12
  128. package/vendor/raylib/examples/shaders/shaders_hot_reloading.c +10 -5
  129. package/vendor/raylib/examples/shaders/shaders_julia_set.c +9 -4
  130. package/vendor/raylib/examples/shaders/shaders_mesh_instancing.c +45 -119
  131. package/vendor/raylib/examples/shaders/shaders_model_shader.c +10 -5
  132. package/vendor/raylib/examples/shaders/shaders_multi_sample2d.c +8 -3
  133. package/vendor/raylib/examples/shaders/shaders_palette_switch.c +8 -3
  134. package/vendor/raylib/examples/shaders/shaders_postprocessing.c +9 -4
  135. package/vendor/raylib/examples/shaders/shaders_raymarching.c +14 -11
  136. package/vendor/raylib/examples/shaders/shaders_shapes_textures.c +8 -3
  137. package/vendor/raylib/examples/shaders/shaders_simple_mask.c +10 -5
  138. package/vendor/raylib/examples/shaders/shaders_spotlight.c +10 -6
  139. package/vendor/raylib/examples/shaders/shaders_texture_drawing.c +9 -4
  140. package/vendor/raylib/examples/shaders/shaders_texture_outline.c +8 -3
  141. package/vendor/raylib/examples/shaders/shaders_texture_waves.c +8 -3
  142. package/vendor/raylib/{src/extras → examples/shapes}/raygui.h +1290 -1141
  143. package/vendor/raylib/examples/{others/easings.h → shapes/reasings.h} +40 -40
  144. package/vendor/raylib/examples/shapes/shapes_basic_shapes.c +8 -3
  145. package/vendor/raylib/examples/shapes/shapes_bouncing_ball.c +8 -3
  146. package/vendor/raylib/examples/shapes/shapes_collision_area.c +10 -4
  147. package/vendor/raylib/examples/shapes/shapes_colors_palette.c +8 -3
  148. package/vendor/raylib/examples/shapes/shapes_draw_circle_sector.c +9 -4
  149. package/vendor/raylib/examples/shapes/shapes_draw_rectangle_rounded.c +9 -4
  150. package/vendor/raylib/examples/shapes/shapes_draw_ring.c +10 -6
  151. package/vendor/raylib/examples/shapes/shapes_easings_ball_anim.c +9 -4
  152. package/vendor/raylib/examples/shapes/shapes_easings_box_anim.c +9 -4
  153. package/vendor/raylib/examples/shapes/shapes_easings_rectangle_array.c +9 -4
  154. package/vendor/raylib/examples/shapes/shapes_following_eyes.c +8 -3
  155. package/vendor/raylib/examples/shapes/shapes_lines_bezier.c +8 -3
  156. package/vendor/raylib/examples/shapes/shapes_logo_raylib.c +8 -3
  157. package/vendor/raylib/examples/shapes/shapes_logo_raylib_anim.c +8 -3
  158. package/vendor/raylib/examples/shapes/shapes_rectangle_scaling.c +14 -5
  159. package/vendor/raylib/examples/shapes/shapes_top_down_lights.c +355 -0
  160. package/vendor/raylib/examples/shapes/shapes_top_down_lights.png +0 -0
  161. package/vendor/raylib/examples/text/resources/DotGothic16-Regular.ttf +0 -0
  162. package/vendor/raylib/examples/text/resources/DotGothic16-Regular_OFL.txt +93 -0
  163. package/vendor/raylib/examples/text/resources/LICENSE.md +1 -1
  164. package/vendor/raylib/examples/text/text_codepoints_loading.c +138 -0
  165. package/vendor/raylib/examples/text/text_codepoints_loading.png +0 -0
  166. package/vendor/raylib/examples/text/text_draw_3d.c +42 -33
  167. package/vendor/raylib/examples/text/text_font_filters.c +14 -11
  168. package/vendor/raylib/examples/text/text_font_loading.c +9 -4
  169. package/vendor/raylib/examples/text/text_font_sdf.c +9 -4
  170. package/vendor/raylib/examples/text/text_font_spritefont.c +12 -6
  171. package/vendor/raylib/examples/text/text_format_text.c +8 -3
  172. package/vendor/raylib/examples/text/text_input_box.c +8 -3
  173. package/vendor/raylib/examples/text/text_raylib_fonts.c +9 -4
  174. package/vendor/raylib/examples/text/text_rectangle_bounds.c +9 -5
  175. package/vendor/raylib/examples/text/text_unicode.c +9 -7
  176. package/vendor/raylib/examples/text/text_writing_anim.c +8 -3
  177. package/vendor/raylib/examples/textures/resources/scarfy_run.gif +0 -0
  178. package/vendor/raylib/examples/textures/textures_background_scrolling.c +8 -3
  179. package/vendor/raylib/examples/textures/textures_blend_modes.c +8 -3
  180. package/vendor/raylib/examples/textures/textures_bunnymark.c +8 -3
  181. package/vendor/raylib/examples/textures/textures_draw_tiled.c +14 -10
  182. package/vendor/raylib/examples/textures/textures_fog_of_war.c +154 -0
  183. package/vendor/raylib/examples/textures/textures_fog_of_war.png +0 -0
  184. package/vendor/raylib/examples/textures/textures_gif_player.c +121 -0
  185. package/vendor/raylib/examples/textures/textures_gif_player.png +0 -0
  186. package/vendor/raylib/examples/textures/textures_image_drawing.c +8 -3
  187. package/vendor/raylib/examples/textures/textures_image_generation.c +8 -3
  188. package/vendor/raylib/examples/textures/textures_image_loading.c +8 -3
  189. package/vendor/raylib/examples/textures/textures_image_processing.c +8 -3
  190. package/vendor/raylib/examples/textures/textures_image_text.c +8 -3
  191. package/vendor/raylib/examples/textures/textures_logo_raylib.c +8 -3
  192. package/vendor/raylib/examples/textures/textures_mouse_painting.c +9 -4
  193. package/vendor/raylib/examples/textures/textures_npatch_drawing.c +8 -3
  194. package/vendor/raylib/examples/textures/textures_particles_blending.c +8 -3
  195. package/vendor/raylib/examples/textures/textures_polygon.c +9 -5
  196. package/vendor/raylib/examples/textures/textures_raw_data.c +8 -3
  197. package/vendor/raylib/examples/textures/{textures_rectangle.c → textures_sprite_anim.c} +11 -5
  198. package/vendor/raylib/examples/textures/{textures_rectangle.png → textures_sprite_anim.png} +0 -0
  199. package/vendor/raylib/examples/textures/textures_sprite_button.c +8 -3
  200. package/vendor/raylib/examples/textures/textures_sprite_explosion.c +8 -3
  201. package/vendor/raylib/examples/textures/textures_srcrec_dstrec.c +8 -3
  202. package/vendor/raylib/examples/textures/textures_to_image.c +8 -3
  203. package/vendor/raylib/parser/LICENSE +1 -1
  204. package/vendor/raylib/parser/Makefile +28 -0
  205. package/vendor/raylib/parser/README.md +49 -5
  206. package/vendor/raylib/parser/output/raylib_api.json +10717 -0
  207. package/vendor/raylib/parser/output/raylib_api.lua +7435 -0
  208. package/vendor/raylib/parser/{raylib_api.txt → output/raylib_api.txt} +1371 -824
  209. package/vendor/raylib/parser/{raylib_api.xml → output/raylib_api.xml} +827 -595
  210. package/vendor/raylib/parser/raylib_parser.c +1174 -196
  211. package/vendor/raylib/projects/4coder/Makefile +2 -4
  212. package/vendor/raylib/projects/4coder/main.c +0 -1
  213. package/vendor/raylib/projects/CMake/CMakeLists.txt +13 -16
  214. package/vendor/raylib/projects/CMake/README.md +27 -0
  215. package/vendor/raylib/projects/CMake/core_basic_window.c +52 -31
  216. package/vendor/raylib/projects/CodeBlocks/README.md +4 -4
  217. package/vendor/raylib/projects/Geany/core_basic_window.c +1 -1
  218. package/vendor/raylib/projects/Notepad++/c_raylib.xml +168 -128
  219. package/vendor/raylib/projects/Notepad++/npes_saved_tcc.txt +0 -0
  220. package/vendor/raylib/projects/Notepad++/npes_saved_w64devkit.txt +0 -0
  221. package/vendor/raylib/projects/Notepad++/npes_saved_zig.txt +0 -0
  222. package/vendor/raylib/projects/Notepad++/raylib_npp_parser/raylib_npp.xml +168 -84
  223. package/vendor/raylib/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h +67 -51
  224. package/vendor/raylib/projects/README.md +1 -1
  225. package/vendor/raylib/projects/VSCode/.vscode/c_cpp_properties.json +1 -1
  226. package/vendor/raylib/projects/VSCode/Makefile +8 -11
  227. package/vendor/raylib/projects/VSCode/main.c +53 -26
  228. package/vendor/raylib/projects/VSCode/resources/LICENSE +1 -0
  229. package/vendor/raylib/projects/scripts/build-linux.sh +6 -6
  230. package/vendor/raylib/projects/scripts/build-osx.sh +6 -6
  231. package/vendor/raylib/projects/scripts/build-rpi.sh +6 -6
  232. package/vendor/raylib/projects/scripts/build-windows.bat +2 -2
  233. package/vendor/raylib/src/CMakeLists.txt +6 -7
  234. package/vendor/raylib/src/Makefile +209 -103
  235. package/vendor/raylib/src/build.zig +56 -20
  236. package/vendor/raylib/src/config.h +32 -27
  237. package/vendor/raylib/src/external/cgltf.h +342 -104
  238. package/vendor/raylib/src/external/dr_wav.h +487 -225
  239. package/vendor/raylib/src/external/glfw/src/posix_time.c +1 -3
  240. package/vendor/raylib/src/external/glfw/src/wl_init.c +1 -3
  241. package/vendor/raylib/src/external/jar_xm.h +2 -1
  242. package/vendor/raylib/src/external/miniaudio.h +62251 -42061
  243. package/vendor/raylib/src/external/qoi.h +671 -0
  244. package/vendor/raylib/src/external/stb_vorbis.h +1 -1
  245. package/vendor/raylib/src/external/vox_loader.h +30 -25
  246. package/vendor/raylib/src/minshell.html +82 -0
  247. package/vendor/raylib/src/raudio.c +359 -201
  248. package/vendor/raylib/src/raylib.dll.rc +5 -5
  249. package/vendor/raylib/src/raylib.dll.rc.data +0 -0
  250. package/vendor/raylib/src/raylib.h +95 -63
  251. package/vendor/raylib/src/raylib.rc +5 -5
  252. package/vendor/raylib/src/raylib.rc.data +0 -0
  253. package/vendor/raylib/src/raymath.h +391 -133
  254. package/vendor/raylib/src/rcamera.h +32 -41
  255. package/vendor/raylib/src/rcore.c +775 -471
  256. package/vendor/raylib/src/rgestures.h +5 -5
  257. package/vendor/raylib/src/rglfw.c +3 -3
  258. package/vendor/raylib/src/rlgl.h +184 -144
  259. package/vendor/raylib/src/rmodels.c +207 -144
  260. package/vendor/raylib/src/rshapes.c +105 -47
  261. package/vendor/raylib/src/rtext.c +255 -38
  262. package/vendor/raylib/src/rtextures.c +167 -71
  263. package/vendor/raylib/src/shell.html +63 -63
  264. package/vendor/raylib/src/utils.c +49 -3
  265. package/vendor/raylib/src/utils.h +3 -3
  266. package/build/qemu/2.1.1/koffi_darwin_arm64.tar.gz +0 -0
  267. package/build/qemu/2.1.1/koffi_darwin_x64.tar.gz +0 -0
  268. package/build/qemu/2.1.1/koffi_freebsd_arm64.tar.gz +0 -0
  269. package/build/qemu/2.1.1/koffi_freebsd_ia32.tar.gz +0 -0
  270. package/build/qemu/2.1.1/koffi_freebsd_x64.tar.gz +0 -0
  271. package/build/qemu/2.1.1/koffi_linux_arm32hf.tar.gz +0 -0
  272. package/build/qemu/2.1.1/koffi_linux_arm64.tar.gz +0 -0
  273. package/build/qemu/2.1.1/koffi_linux_ia32.tar.gz +0 -0
  274. package/build/qemu/2.1.1/koffi_linux_riscv64hf64.tar.gz +0 -0
  275. package/build/qemu/2.1.1/koffi_linux_x64.tar.gz +0 -0
  276. package/build/qemu/2.1.1/koffi_openbsd_ia32.tar.gz +0 -0
  277. package/build/qemu/2.1.1/koffi_openbsd_x64.tar.gz +0 -0
  278. package/build/qemu/2.1.1/koffi_win32_arm64.tar.gz +0 -0
  279. package/build/qemu/2.1.1/koffi_win32_ia32.tar.gz +0 -0
  280. package/build/qemu/2.1.1/koffi_win32_x64.tar.gz +0 -0
  281. package/vendor/raylib/CONTRIBUTORS.md +0 -63
  282. package/vendor/raylib/SPONSORS.md +0 -68
  283. package/vendor/raylib/examples/core/core_quat_conversion.c +0 -132
  284. package/vendor/raylib/examples/core/core_quat_conversion.png +0 -0
  285. package/vendor/raylib/examples/models/resources/models/gltf/AnimatedMorphCube.glb +0 -0
  286. package/vendor/raylib/examples/models/resources/models/gltf/AnimatedTriangle.gltf +0 -118
  287. package/vendor/raylib/examples/models/resources/models/gltf/BoxAnimated.glb +0 -0
  288. package/vendor/raylib/examples/models/resources/models/gltf/girl.glb +0 -0
  289. package/vendor/raylib/examples/models/resources/models/gltf/rigged_figure.glb +0 -0
  290. package/vendor/raylib/examples/models/resources/models/gltf/vertex_colored_object.glb +0 -0
  291. package/vendor/raylib/examples/models/resources/models/iqm/vertex_colored_object.iqm +0 -0
  292. package/vendor/raylib/examples/models/rlights.h +0 -183
  293. package/vendor/raylib/examples/others/raudio_standalone.c +0 -152
  294. package/vendor/raylib/examples/others/resources/audio/country.mp3 +0 -0
  295. package/vendor/raylib/examples/others/resources/audio/target.ogg +0 -0
  296. package/vendor/raylib/examples/others/resources/audio/weird.wav +0 -0
  297. package/vendor/raylib/examples/physics/physics_demo.c +0 -128
  298. package/vendor/raylib/examples/physics/physics_demo.png +0 -0
  299. package/vendor/raylib/examples/physics/physics_friction.c +0 -142
  300. package/vendor/raylib/examples/physics/physics_friction.png +0 -0
  301. package/vendor/raylib/examples/physics/physics_movement.c +0 -128
  302. package/vendor/raylib/examples/physics/physics_movement.png +0 -0
  303. package/vendor/raylib/examples/physics/physics_restitution.c +0 -129
  304. package/vendor/raylib/examples/physics/physics_restitution.png +0 -0
  305. package/vendor/raylib/examples/physics/physics_shatter.c +0 -111
  306. package/vendor/raylib/examples/physics/physics_shatter.png +0 -0
  307. package/vendor/raylib/parser/raylib_api.json +0 -6668
  308. package/vendor/raylib/projects/VS2019/raylib/raylib.rc +0 -0
  309. package/vendor/raylib/projects/VS2019/raylib/resource.h +0 -14
  310. package/vendor/raylib/src/extras/physac.h +0 -1977
  311. package/vendor/raylib/src/extras/rmem.h +0 -751
  312. package/vendor/raylib/src/raudio.h +0 -198
@@ -1,1977 +0,0 @@
1
- /**********************************************************************************************
2
- *
3
- * Physac v1.1 - 2D Physics library for videogames
4
- *
5
- * DESCRIPTION:
6
- *
7
- * Physac is a small 2D physics engine written in pure C. The engine uses a fixed time-step thread loop
8
- * to simluate physics. A physics step contains the following phases: get collision information,
9
- * apply dynamics, collision solving and position correction. It uses a very simple struct for physic
10
- * bodies with a position vector to be used in any 3D rendering API.
11
- *
12
- * CONFIGURATION:
13
- *
14
- * #define PHYSAC_IMPLEMENTATION
15
- * Generates the implementation of the library into the included file.
16
- * If not defined, the library is in header only mode and can be included in other headers
17
- * or source files without problems. But only ONE file should hold the implementation.
18
- *
19
- * #define PHYSAC_DEBUG
20
- * Show debug traces log messages about physic bodies creation/destruction, physic system errors,
21
- * some calculations results and NULL reference exceptions.
22
- *
23
- * #define PHYSAC_AVOID_TIMMING_SYSTEM
24
- * Disables internal timming system, used by UpdatePhysics() to launch timmed physic steps,
25
- * it allows just running UpdatePhysics() automatically on a separate thread at a desired time step.
26
- * In case physics steps update needs to be controlled by user with a custom timming mechanism,
27
- * just define this flag and the internal timming mechanism will be avoided, in that case,
28
- * timming libraries are neither required by the module.
29
- *
30
- * #define PHYSAC_MALLOC()
31
- * #define PHYSAC_CALLOC()
32
- * #define PHYSAC_FREE()
33
- * You can define your own malloc/free implementation replacing stdlib.h malloc()/free() functions.
34
- * Otherwise it will include stdlib.h and use the C standard library malloc()/free() function.
35
- *
36
- * COMPILATION:
37
- *
38
- * Use the following code to compile with GCC:
39
- * gcc -o $(NAME_PART).exe $(FILE_NAME) -s -static -lraylib -lopengl32 -lgdi32 -lwinmm -std=c99
40
- *
41
- * VERSIONS HISTORY:
42
- * 1.1 (20-Jan-2021) @raysan5: Library general revision
43
- * Removed threading system (up to the user)
44
- * Support MSVC C++ compilation using CLITERAL()
45
- * Review DEBUG mechanism for TRACELOG() and all TRACELOG() messages
46
- * Review internal variables/functions naming for consistency
47
- * Allow option to avoid internal timming system, to allow app manage the steps
48
- * 1.0 (12-Jun-2017) First release of the library
49
- *
50
- *
51
- * LICENSE: zlib/libpng
52
- *
53
- * Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
54
- *
55
- * This software is provided "as-is", without any express or implied warranty. In no event
56
- * will the authors be held liable for any damages arising from the use of this software.
57
- *
58
- * Permission is granted to anyone to use this software for any purpose, including commercial
59
- * applications, and to alter it and redistribute it freely, subject to the following restrictions:
60
- *
61
- * 1. The origin of this software must not be misrepresented; you must not claim that you
62
- * wrote the original software. If you use this software in a product, an acknowledgment
63
- * in the product documentation would be appreciated but is not required.
64
- *
65
- * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
66
- * as being the original software.
67
- *
68
- * 3. This notice may not be removed or altered from any source distribution.
69
- *
70
- **********************************************************************************************/
71
-
72
- #if !defined(PHYSAC_H)
73
- #define PHYSAC_H
74
-
75
- #ifndef PHYSACDEF
76
- #define PHYSACDEF // We are building or using physac as a static library
77
- #endif
78
-
79
- // Allow custom memory allocators
80
- #ifndef PHYSAC_MALLOC
81
- #define PHYSAC_MALLOC(size) malloc(size)
82
- #endif
83
- #ifndef PHYSAC_CALLOC
84
- #define PHYSAC_CALLOC(size, n) calloc(size, n)
85
- #endif
86
- #ifndef PHYSAC_FREE
87
- #define PHYSAC_FREE(ptr) free(ptr)
88
- #endif
89
-
90
- //----------------------------------------------------------------------------------
91
- // Defines and Macros
92
- //----------------------------------------------------------------------------------
93
- #define PHYSAC_MAX_BODIES 64 // Maximum number of physic bodies supported
94
- #define PHYSAC_MAX_MANIFOLDS 4096 // Maximum number of physic bodies interactions (64x64)
95
- #define PHYSAC_MAX_VERTICES 24 // Maximum number of vertex for polygons shapes
96
- #define PHYSAC_DEFAULT_CIRCLE_VERTICES 24 // Default number of vertices for circle shapes
97
-
98
- #define PHYSAC_COLLISION_ITERATIONS 100
99
- #define PHYSAC_PENETRATION_ALLOWANCE 0.05f
100
- #define PHYSAC_PENETRATION_CORRECTION 0.4f
101
-
102
- #define PHYSAC_PI 3.14159265358979323846f
103
- #define PHYSAC_DEG2RAD (PHYSAC_PI/180.0f)
104
-
105
- //----------------------------------------------------------------------------------
106
- // Data Types Structure Definition
107
- //----------------------------------------------------------------------------------
108
- #if defined(__STDC__) && __STDC_VERSION__ >= 199901L
109
- #include <stdbool.h>
110
- #endif
111
-
112
- typedef enum PhysicsShapeType { PHYSICS_CIRCLE = 0, PHYSICS_POLYGON } PhysicsShapeType;
113
-
114
- // Previously defined to be used in PhysicsShape struct as circular dependencies
115
- typedef struct PhysicsBodyData *PhysicsBody;
116
-
117
- #if !defined(RL_VECTOR2_TYPE)
118
- // Vector2 type
119
- typedef struct Vector2 {
120
- float x;
121
- float y;
122
- } Vector2;
123
- #endif
124
-
125
- // Matrix2x2 type (used for polygon shape rotation matrix)
126
- typedef struct Matrix2x2 {
127
- float m00;
128
- float m01;
129
- float m10;
130
- float m11;
131
- } Matrix2x2;
132
-
133
- typedef struct PhysicsVertexData {
134
- unsigned int vertexCount; // Vertex count (positions and normals)
135
- Vector2 positions[PHYSAC_MAX_VERTICES]; // Vertex positions vectors
136
- Vector2 normals[PHYSAC_MAX_VERTICES]; // Vertex normals vectors
137
- } PhysicsVertexData;
138
-
139
- typedef struct PhysicsShape {
140
- PhysicsShapeType type; // Shape type (circle or polygon)
141
- PhysicsBody body; // Shape physics body data pointer
142
- PhysicsVertexData vertexData; // Shape vertices data (used for polygon shapes)
143
- float radius; // Shape radius (used for circle shapes)
144
- Matrix2x2 transform; // Vertices transform matrix 2x2
145
- } PhysicsShape;
146
-
147
- typedef struct PhysicsBodyData {
148
- unsigned int id; // Unique identifier
149
- bool enabled; // Enabled dynamics state (collisions are calculated anyway)
150
- Vector2 position; // Physics body shape pivot
151
- Vector2 velocity; // Current linear velocity applied to position
152
- Vector2 force; // Current linear force (reset to 0 every step)
153
- float angularVelocity; // Current angular velocity applied to orient
154
- float torque; // Current angular force (reset to 0 every step)
155
- float orient; // Rotation in radians
156
- float inertia; // Moment of inertia
157
- float inverseInertia; // Inverse value of inertia
158
- float mass; // Physics body mass
159
- float inverseMass; // Inverse value of mass
160
- float staticFriction; // Friction when the body has not movement (0 to 1)
161
- float dynamicFriction; // Friction when the body has movement (0 to 1)
162
- float restitution; // Restitution coefficient of the body (0 to 1)
163
- bool useGravity; // Apply gravity force to dynamics
164
- bool isGrounded; // Physics grounded on other body state
165
- bool freezeOrient; // Physics rotation constraint
166
- PhysicsShape shape; // Physics body shape information (type, radius, vertices, transform)
167
- } PhysicsBodyData;
168
-
169
- typedef struct PhysicsManifoldData {
170
- unsigned int id; // Unique identifier
171
- PhysicsBody bodyA; // Manifold first physics body reference
172
- PhysicsBody bodyB; // Manifold second physics body reference
173
- float penetration; // Depth of penetration from collision
174
- Vector2 normal; // Normal direction vector from 'a' to 'b'
175
- Vector2 contacts[2]; // Points of contact during collision
176
- unsigned int contactsCount; // Current collision number of contacts
177
- float restitution; // Mixed restitution during collision
178
- float dynamicFriction; // Mixed dynamic friction during collision
179
- float staticFriction; // Mixed static friction during collision
180
- } PhysicsManifoldData, *PhysicsManifold;
181
-
182
- //----------------------------------------------------------------------------------
183
- // Module Functions Declaration
184
- //----------------------------------------------------------------------------------
185
-
186
- #if defined(__cplusplus)
187
- extern "C" { // Prevents name mangling of functions
188
- #endif
189
- // Physics system management
190
- PHYSACDEF void InitPhysics(void); // Initializes physics system
191
- PHYSACDEF void UpdatePhysics(void); // Update physics system
192
- PHYSACDEF void ResetPhysics(void); // Reset physics system (global variables)
193
- PHYSACDEF void ClosePhysics(void); // Close physics system and unload used memory
194
- PHYSACDEF void SetPhysicsTimeStep(double delta); // Sets physics fixed time step in milliseconds. 1.666666 by default
195
- PHYSACDEF void SetPhysicsGravity(float x, float y); // Sets physics global gravity force
196
-
197
- // Physic body creation/destroy
198
- PHYSACDEF PhysicsBody CreatePhysicsBodyCircle(Vector2 pos, float radius, float density); // Creates a new circle physics body with generic parameters
199
- PHYSACDEF PhysicsBody CreatePhysicsBodyRectangle(Vector2 pos, float width, float height, float density); // Creates a new rectangle physics body with generic parameters
200
- PHYSACDEF PhysicsBody CreatePhysicsBodyPolygon(Vector2 pos, float radius, int sides, float density); // Creates a new polygon physics body with generic parameters
201
- PHYSACDEF void DestroyPhysicsBody(PhysicsBody body); // Destroy a physics body
202
-
203
- // Physic body forces
204
- PHYSACDEF void PhysicsAddForce(PhysicsBody body, Vector2 force); // Adds a force to a physics body
205
- PHYSACDEF void PhysicsAddTorque(PhysicsBody body, float amount); // Adds an angular force to a physics body
206
- PHYSACDEF void PhysicsShatter(PhysicsBody body, Vector2 position, float force); // Shatters a polygon shape physics body to little physics bodies with explosion force
207
- PHYSACDEF void SetPhysicsBodyRotation(PhysicsBody body, float radians); // Sets physics body shape transform based on radians parameter
208
-
209
- // Query physics info
210
- PHYSACDEF PhysicsBody GetPhysicsBody(int index); // Returns a physics body of the bodies pool at a specific index
211
- PHYSACDEF int GetPhysicsBodiesCount(void); // Returns the current amount of created physics bodies
212
- PHYSACDEF int GetPhysicsShapeType(int index); // Returns the physics body shape type (PHYSICS_CIRCLE or PHYSICS_POLYGON)
213
- PHYSACDEF int GetPhysicsShapeVerticesCount(int index); // Returns the amount of vertices of a physics body shape
214
- PHYSACDEF Vector2 GetPhysicsShapeVertex(PhysicsBody body, int vertex); // Returns transformed position of a body shape (body position + vertex transformed position)
215
- #if defined(__cplusplus)
216
- }
217
- #endif
218
-
219
- #endif // PHYSAC_H
220
-
221
- /***********************************************************************************
222
- *
223
- * PHYSAC IMPLEMENTATION
224
- *
225
- ************************************************************************************/
226
-
227
- #if defined(PHYSAC_IMPLEMENTATION)
228
-
229
- // Support TRACELOG macros
230
- #if defined(PHYSAC_DEBUG)
231
- #include <stdio.h> // Required for: printf()
232
- #define TRACELOG(...) printf(__VA_ARGS__)
233
- #else
234
- #define TRACELOG(...) (void)0;
235
- #endif
236
-
237
- #include <stdlib.h> // Required for: malloc(), calloc(), free()
238
- #include <math.h> // Required for: cosf(), sinf(), fabs(), sqrtf()
239
-
240
- #if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
241
- // Time management functionality
242
- #include <time.h> // Required for: time(), clock_gettime()
243
- #if defined(_WIN32)
244
- #if defined(__cplusplus)
245
- extern "C" { // Prevents name mangling of functions
246
- #endif
247
- // Functions required to query time on Windows
248
- int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
249
- int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
250
- #if defined(__cplusplus)
251
- }
252
- #endif
253
- #endif
254
- #if defined(__linux__) || defined(__FreeBSD__)
255
- #if _POSIX_C_SOURCE < 199309L
256
- #undef _POSIX_C_SOURCE
257
- #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
258
- #endif
259
- #include <sys/time.h> // Required for: timespec
260
- #endif
261
- #if defined(__APPLE__) // macOS also defines __MACH__
262
- #include <mach/mach_time.h> // Required for: mach_absolute_time()
263
- #endif
264
- #endif
265
-
266
- // NOTE: MSVC C++ compiler does not support compound literals (C99 feature)
267
- // Plain structures in C++ (without constructors) can be initialized from { } initializers.
268
- #if defined(__cplusplus)
269
- #define CLITERAL(type) type
270
- #else
271
- #define CLITERAL(type) (type)
272
- #endif
273
-
274
- //----------------------------------------------------------------------------------
275
- // Defines and Macros
276
- //----------------------------------------------------------------------------------
277
- #define PHYSAC_MIN(a,b) (((a)<(b))?(a):(b))
278
- #define PHYSAC_MAX(a,b) (((a)>(b))?(a):(b))
279
- #define PHYSAC_FLT_MAX 3.402823466e+38f
280
- #define PHYSAC_EPSILON 0.000001f
281
- #define PHYSAC_K 1.0f/3.0f
282
- #define PHYSAC_VECTOR_ZERO CLITERAL(Vector2){ 0.0f, 0.0f }
283
-
284
- //----------------------------------------------------------------------------------
285
- // Global Variables Definition
286
- //----------------------------------------------------------------------------------
287
- static double deltaTime = 1.0/60.0/10.0 * 1000; // Delta time in milliseconds used for physics steps
288
-
289
- #if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
290
- // Time measure variables
291
- static double baseClockTicks = 0.0; // Offset clock ticks for MONOTONIC clock
292
- static unsigned long long int frequency = 0; // Hi-res clock frequency
293
- static double startTime = 0.0; // Start time in milliseconds
294
- static double currentTime = 0.0; // Current time in milliseconds
295
- #endif
296
-
297
- // Physics system configuration
298
- static PhysicsBody bodies[PHYSAC_MAX_BODIES]; // Physics bodies pointers array
299
- static unsigned int physicsBodiesCount = 0; // Physics world current bodies counter
300
- static PhysicsManifold contacts[PHYSAC_MAX_MANIFOLDS]; // Physics bodies pointers array
301
- static unsigned int physicsManifoldsCount = 0; // Physics world current manifolds counter
302
-
303
- static Vector2 gravityForce = { 0.0f, 9.81f }; // Physics world gravity force
304
-
305
- // Utilities variables
306
- static unsigned int usedMemory = 0; // Total allocated dynamic memory
307
-
308
- //----------------------------------------------------------------------------------
309
- // Module Internal Functions Declaration
310
- //----------------------------------------------------------------------------------
311
- #if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
312
- // Timming measure functions
313
- static void InitTimerHiRes(void); // Initializes hi-resolution MONOTONIC timer
314
- static unsigned long long int GetClockTicks(void); // Get hi-res MONOTONIC time measure in mseconds
315
- static double GetCurrentTime(void); // Get current time measure in milliseconds
316
- #endif
317
-
318
- static void UpdatePhysicsStep(void); // Update physics step (dynamics, collisions and position corrections)
319
-
320
- static int FindAvailableBodyIndex(); // Finds a valid index for a new physics body initialization
321
- static int FindAvailableManifoldIndex(); // Finds a valid index for a new manifold initialization
322
- static PhysicsVertexData CreateDefaultPolygon(float radius, int sides); // Creates a random polygon shape with max vertex distance from polygon pivot
323
- static PhysicsVertexData CreateRectanglePolygon(Vector2 pos, Vector2 size); // Creates a rectangle polygon shape based on a min and max positions
324
-
325
- static void InitializePhysicsManifolds(PhysicsManifold manifold); // Initializes physics manifolds to solve collisions
326
- static PhysicsManifold CreatePhysicsManifold(PhysicsBody a, PhysicsBody b); // Creates a new physics manifold to solve collision
327
- static void DestroyPhysicsManifold(PhysicsManifold manifold); // Unitializes and destroys a physics manifold
328
-
329
- static void SolvePhysicsManifold(PhysicsManifold manifold); // Solves a created physics manifold between two physics bodies
330
- static void SolveCircleToCircle(PhysicsManifold manifold); // Solves collision between two circle shape physics bodies
331
- static void SolveCircleToPolygon(PhysicsManifold manifold); // Solves collision between a circle to a polygon shape physics bodies
332
- static void SolvePolygonToCircle(PhysicsManifold manifold); // Solves collision between a polygon to a circle shape physics bodies
333
- static void SolvePolygonToPolygon(PhysicsManifold manifold); // Solves collision between two polygons shape physics bodies
334
- static void IntegratePhysicsForces(PhysicsBody body); // Integrates physics forces into velocity
335
- static void IntegratePhysicsVelocity(PhysicsBody body); // Integrates physics velocity into position and forces
336
- static void IntegratePhysicsImpulses(PhysicsManifold manifold); // Integrates physics collisions impulses to solve collisions
337
- static void CorrectPhysicsPositions(PhysicsManifold manifold); // Corrects physics bodies positions based on manifolds collision information
338
- static void FindIncidentFace(Vector2 *v0, Vector2 *v1, PhysicsShape ref, PhysicsShape inc, int index); // Finds two polygon shapes incident face
339
- static float FindAxisLeastPenetration(int *faceIndex, PhysicsShape shapeA, PhysicsShape shapeB); // Finds polygon shapes axis least penetration
340
-
341
- // Math required functions
342
- static Vector2 MathVector2Product(Vector2 vector, float value); // Returns the product of a vector and a value
343
- static float MathVector2CrossProduct(Vector2 v1, Vector2 v2); // Returns the cross product of two vectors
344
- static float MathVector2SqrLen(Vector2 vector); // Returns the len square root of a vector
345
- static float MathVector2DotProduct(Vector2 v1, Vector2 v2); // Returns the dot product of two vectors
346
- static inline float MathVector2SqrDistance(Vector2 v1, Vector2 v2); // Returns the square root of distance between two vectors
347
- static void MathVector2Normalize(Vector2 *vector); // Returns the normalized values of a vector
348
- static Vector2 MathVector2Add(Vector2 v1, Vector2 v2); // Returns the sum of two given vectors
349
- static Vector2 MathVector2Subtract(Vector2 v1, Vector2 v2); // Returns the subtract of two given vectors
350
- static Matrix2x2 MathMatFromRadians(float radians); // Returns a matrix 2x2 from a given radians value
351
- static inline Matrix2x2 MathMatTranspose(Matrix2x2 matrix); // Returns the transpose of a given matrix 2x2
352
- static inline Vector2 MathMatVector2Product(Matrix2x2 matrix, Vector2 vector); // Returns product between matrix 2x2 and vector
353
- static int MathVector2Clip(Vector2 normal, Vector2 *faceA, Vector2 *faceB, float clip); // Returns clipping value based on a normal and two faces
354
- static Vector2 MathTriangleBarycenter(Vector2 v1, Vector2 v2, Vector2 v3); // Returns the barycenter of a triangle given by 3 points
355
-
356
- //----------------------------------------------------------------------------------
357
- // Module Functions Definition
358
- //----------------------------------------------------------------------------------
359
-
360
- // Initializes physics values, pointers and creates physics loop thread
361
- void InitPhysics(void)
362
- {
363
- #if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
364
- // Initialize high resolution timer
365
- InitTimerHiRes();
366
- #endif
367
-
368
- TRACELOG("[PHYSAC] Physics module initialized successfully\n");
369
- }
370
-
371
- // Sets physics global gravity force
372
- void SetPhysicsGravity(float x, float y)
373
- {
374
- gravityForce.x = x;
375
- gravityForce.y = y;
376
- }
377
-
378
- // Creates a new circle physics body with generic parameters
379
- PhysicsBody CreatePhysicsBodyCircle(Vector2 pos, float radius, float density)
380
- {
381
- PhysicsBody body = CreatePhysicsBodyPolygon(pos, radius, PHYSAC_DEFAULT_CIRCLE_VERTICES, density);
382
- return body;
383
- }
384
-
385
- // Creates a new rectangle physics body with generic parameters
386
- PhysicsBody CreatePhysicsBodyRectangle(Vector2 pos, float width, float height, float density)
387
- {
388
- // NOTE: Make sure body data is initialized to 0
389
- PhysicsBody body = (PhysicsBody)PHYSAC_CALLOC(sizeof(PhysicsBodyData), 1);
390
- usedMemory += sizeof(PhysicsBodyData);
391
-
392
- int id = FindAvailableBodyIndex();
393
- if (id != -1)
394
- {
395
- // Initialize new body with generic values
396
- body->id = id;
397
- body->enabled = true;
398
- body->position = pos;
399
- body->shape.type = PHYSICS_POLYGON;
400
- body->shape.body = body;
401
- body->shape.transform = MathMatFromRadians(0.0f);
402
- body->shape.vertexData = CreateRectanglePolygon(pos, CLITERAL(Vector2){ width, height });
403
-
404
- // Calculate centroid and moment of inertia
405
- Vector2 center = { 0.0f, 0.0f };
406
- float area = 0.0f;
407
- float inertia = 0.0f;
408
-
409
- for (unsigned int i = 0; i < body->shape.vertexData.vertexCount; i++)
410
- {
411
- // Triangle vertices, third vertex implied as (0, 0)
412
- Vector2 p1 = body->shape.vertexData.positions[i];
413
- unsigned int nextIndex = (((i + 1) < body->shape.vertexData.vertexCount) ? (i + 1) : 0);
414
- Vector2 p2 = body->shape.vertexData.positions[nextIndex];
415
-
416
- float D = MathVector2CrossProduct(p1, p2);
417
- float triangleArea = D/2;
418
-
419
- area += triangleArea;
420
-
421
- // Use area to weight the centroid average, not just vertex position
422
- center.x += triangleArea*PHYSAC_K*(p1.x + p2.x);
423
- center.y += triangleArea*PHYSAC_K*(p1.y + p2.y);
424
-
425
- float intx2 = p1.x*p1.x + p2.x*p1.x + p2.x*p2.x;
426
- float inty2 = p1.y*p1.y + p2.y*p1.y + p2.y*p2.y;
427
- inertia += (0.25f*PHYSAC_K*D)*(intx2 + inty2);
428
- }
429
-
430
- center.x *= 1.0f/area;
431
- center.y *= 1.0f/area;
432
-
433
- // Translate vertices to centroid (make the centroid (0, 0) for the polygon in model space)
434
- // Note: this is not really necessary
435
- for (unsigned int i = 0; i < body->shape.vertexData.vertexCount; i++)
436
- {
437
- body->shape.vertexData.positions[i].x -= center.x;
438
- body->shape.vertexData.positions[i].y -= center.y;
439
- }
440
-
441
- body->mass = density*area;
442
- body->inverseMass = ((body->mass != 0.0f) ? 1.0f/body->mass : 0.0f);
443
- body->inertia = density*inertia;
444
- body->inverseInertia = ((body->inertia != 0.0f) ? 1.0f/body->inertia : 0.0f);
445
- body->staticFriction = 0.4f;
446
- body->dynamicFriction = 0.2f;
447
- body->restitution = 0.0f;
448
- body->useGravity = true;
449
- body->isGrounded = false;
450
- body->freezeOrient = false;
451
-
452
- // Add new body to bodies pointers array and update bodies count
453
- bodies[physicsBodiesCount] = body;
454
- physicsBodiesCount++;
455
-
456
- TRACELOG("[PHYSAC] Physic body created successfully (id: %i)\n", body->id);
457
- }
458
- else TRACELOG("[PHYSAC] Physic body could not be created, PHYSAC_MAX_BODIES reached\n");
459
-
460
- return body;
461
- }
462
-
463
- // Creates a new polygon physics body with generic parameters
464
- PhysicsBody CreatePhysicsBodyPolygon(Vector2 pos, float radius, int sides, float density)
465
- {
466
- PhysicsBody body = (PhysicsBody)PHYSAC_MALLOC(sizeof(PhysicsBodyData));
467
- usedMemory += sizeof(PhysicsBodyData);
468
-
469
- int id = FindAvailableBodyIndex();
470
- if (id != -1)
471
- {
472
- // Initialize new body with generic values
473
- body->id = id;
474
- body->enabled = true;
475
- body->position = pos;
476
- body->velocity = PHYSAC_VECTOR_ZERO;
477
- body->force = PHYSAC_VECTOR_ZERO;
478
- body->angularVelocity = 0.0f;
479
- body->torque = 0.0f;
480
- body->orient = 0.0f;
481
- body->shape.type = PHYSICS_POLYGON;
482
- body->shape.body = body;
483
- body->shape.transform = MathMatFromRadians(0.0f);
484
- body->shape.vertexData = CreateDefaultPolygon(radius, sides);
485
-
486
- // Calculate centroid and moment of inertia
487
- Vector2 center = { 0.0f, 0.0f };
488
- float area = 0.0f;
489
- float inertia = 0.0f;
490
-
491
- for (unsigned int i = 0; i < body->shape.vertexData.vertexCount; i++)
492
- {
493
- // Triangle vertices, third vertex implied as (0, 0)
494
- Vector2 position1 = body->shape.vertexData.positions[i];
495
- unsigned int nextIndex = (((i + 1) < body->shape.vertexData.vertexCount) ? (i + 1) : 0);
496
- Vector2 position2 = body->shape.vertexData.positions[nextIndex];
497
-
498
- float cross = MathVector2CrossProduct(position1, position2);
499
- float triangleArea = cross/2;
500
-
501
- area += triangleArea;
502
-
503
- // Use area to weight the centroid average, not just vertex position
504
- center.x += triangleArea*PHYSAC_K*(position1.x + position2.x);
505
- center.y += triangleArea*PHYSAC_K*(position1.y + position2.y);
506
-
507
- float intx2 = position1.x*position1.x + position2.x*position1.x + position2.x*position2.x;
508
- float inty2 = position1.y*position1.y + position2.y*position1.y + position2.y*position2.y;
509
- inertia += (0.25f*PHYSAC_K*cross)*(intx2 + inty2);
510
- }
511
-
512
- center.x *= 1.0f/area;
513
- center.y *= 1.0f/area;
514
-
515
- // Translate vertices to centroid (make the centroid (0, 0) for the polygon in model space)
516
- // Note: this is not really necessary
517
- for (unsigned int i = 0; i < body->shape.vertexData.vertexCount; i++)
518
- {
519
- body->shape.vertexData.positions[i].x -= center.x;
520
- body->shape.vertexData.positions[i].y -= center.y;
521
- }
522
-
523
- body->mass = density*area;
524
- body->inverseMass = ((body->mass != 0.0f) ? 1.0f/body->mass : 0.0f);
525
- body->inertia = density*inertia;
526
- body->inverseInertia = ((body->inertia != 0.0f) ? 1.0f/body->inertia : 0.0f);
527
- body->staticFriction = 0.4f;
528
- body->dynamicFriction = 0.2f;
529
- body->restitution = 0.0f;
530
- body->useGravity = true;
531
- body->isGrounded = false;
532
- body->freezeOrient = false;
533
-
534
- // Add new body to bodies pointers array and update bodies count
535
- bodies[physicsBodiesCount] = body;
536
- physicsBodiesCount++;
537
-
538
- TRACELOG("[PHYSAC] Physic body created successfully (id: %i)\n", body->id);
539
- }
540
- else TRACELOG("[PHYSAC] Physics body could not be created, PHYSAC_MAX_BODIES reached\n");
541
-
542
- return body;
543
- }
544
-
545
- // Adds a force to a physics body
546
- void PhysicsAddForce(PhysicsBody body, Vector2 force)
547
- {
548
- if (body != NULL) body->force = MathVector2Add(body->force, force);
549
- }
550
-
551
- // Adds an angular force to a physics body
552
- void PhysicsAddTorque(PhysicsBody body, float amount)
553
- {
554
- if (body != NULL) body->torque += amount;
555
- }
556
-
557
- // Shatters a polygon shape physics body to little physics bodies with explosion force
558
- void PhysicsShatter(PhysicsBody body, Vector2 position, float force)
559
- {
560
- if (body != NULL)
561
- {
562
- if (body->shape.type == PHYSICS_POLYGON)
563
- {
564
- PhysicsVertexData vertexData = body->shape.vertexData;
565
- bool collision = false;
566
-
567
- for (unsigned int i = 0; i < vertexData.vertexCount; i++)
568
- {
569
- Vector2 positionA = body->position;
570
- Vector2 positionB = MathMatVector2Product(body->shape.transform, MathVector2Add(body->position, vertexData.positions[i]));
571
- unsigned int nextIndex = (((i + 1) < vertexData.vertexCount) ? (i + 1) : 0);
572
- Vector2 positionC = MathMatVector2Product(body->shape.transform, MathVector2Add(body->position, vertexData.positions[nextIndex]));
573
-
574
- // Check collision between each triangle
575
- float alpha = ((positionB.y - positionC.y)*(position.x - positionC.x) + (positionC.x - positionB.x)*(position.y - positionC.y))/
576
- ((positionB.y - positionC.y)*(positionA.x - positionC.x) + (positionC.x - positionB.x)*(positionA.y - positionC.y));
577
-
578
- float beta = ((positionC.y - positionA.y)*(position.x - positionC.x) + (positionA.x - positionC.x)*(position.y - positionC.y))/
579
- ((positionB.y - positionC.y)*(positionA.x - positionC.x) + (positionC.x - positionB.x)*(positionA.y - positionC.y));
580
-
581
- float gamma = 1.0f - alpha - beta;
582
-
583
- if ((alpha > 0.0f) && (beta > 0.0f) & (gamma > 0.0f))
584
- {
585
- collision = true;
586
- break;
587
- }
588
- }
589
-
590
- if (collision)
591
- {
592
- int count = vertexData.vertexCount;
593
- Vector2 bodyPos = body->position;
594
- Vector2 *vertices = (Vector2 *)PHYSAC_MALLOC(sizeof(Vector2)*count);
595
- Matrix2x2 trans = body->shape.transform;
596
- for (int i = 0; i < count; i++) vertices[i] = vertexData.positions[i];
597
-
598
- // Destroy shattered physics body
599
- DestroyPhysicsBody(body);
600
-
601
- for (int i = 0; i < count; i++)
602
- {
603
- int nextIndex = (((i + 1) < count) ? (i + 1) : 0);
604
- Vector2 center = MathTriangleBarycenter(vertices[i], vertices[nextIndex], PHYSAC_VECTOR_ZERO);
605
- center = MathVector2Add(bodyPos, center);
606
- Vector2 offset = MathVector2Subtract(center, bodyPos);
607
-
608
- PhysicsBody body = CreatePhysicsBodyPolygon(center, 10, 3, 10); // Create polygon physics body with relevant values
609
-
610
- PhysicsVertexData vertexData = { 0 };
611
- vertexData.vertexCount = 3;
612
-
613
- vertexData.positions[0] = MathVector2Subtract(vertices[i], offset);
614
- vertexData.positions[1] = MathVector2Subtract(vertices[nextIndex], offset);
615
- vertexData.positions[2] = MathVector2Subtract(position, center);
616
-
617
- // Separate vertices to avoid unnecessary physics collisions
618
- vertexData.positions[0].x *= 0.95f;
619
- vertexData.positions[0].y *= 0.95f;
620
- vertexData.positions[1].x *= 0.95f;
621
- vertexData.positions[1].y *= 0.95f;
622
- vertexData.positions[2].x *= 0.95f;
623
- vertexData.positions[2].y *= 0.95f;
624
-
625
- // Calculate polygon faces normals
626
- for (unsigned int j = 0; j < vertexData.vertexCount; j++)
627
- {
628
- unsigned int nextVertex = (((j + 1) < vertexData.vertexCount) ? (j + 1) : 0);
629
- Vector2 face = MathVector2Subtract(vertexData.positions[nextVertex], vertexData.positions[j]);
630
-
631
- vertexData.normals[j] = CLITERAL(Vector2){ face.y, -face.x };
632
- MathVector2Normalize(&vertexData.normals[j]);
633
- }
634
-
635
- // Apply computed vertex data to new physics body shape
636
- body->shape.vertexData = vertexData;
637
- body->shape.transform = trans;
638
-
639
- // Calculate centroid and moment of inertia
640
- center = PHYSAC_VECTOR_ZERO;
641
- float area = 0.0f;
642
- float inertia = 0.0f;
643
-
644
- for (unsigned int j = 0; j < body->shape.vertexData.vertexCount; j++)
645
- {
646
- // Triangle vertices, third vertex implied as (0, 0)
647
- Vector2 p1 = body->shape.vertexData.positions[j];
648
- unsigned int nextVertex = (((j + 1) < body->shape.vertexData.vertexCount) ? (j + 1) : 0);
649
- Vector2 p2 = body->shape.vertexData.positions[nextVertex];
650
-
651
- float D = MathVector2CrossProduct(p1, p2);
652
- float triangleArea = D/2;
653
-
654
- area += triangleArea;
655
-
656
- // Use area to weight the centroid average, not just vertex position
657
- center.x += triangleArea*PHYSAC_K*(p1.x + p2.x);
658
- center.y += triangleArea*PHYSAC_K*(p1.y + p2.y);
659
-
660
- float intx2 = p1.x*p1.x + p2.x*p1.x + p2.x*p2.x;
661
- float inty2 = p1.y*p1.y + p2.y*p1.y + p2.y*p2.y;
662
- inertia += (0.25f*PHYSAC_K*D)*(intx2 + inty2);
663
- }
664
-
665
- center.x *= 1.0f/area;
666
- center.y *= 1.0f/area;
667
-
668
- body->mass = area;
669
- body->inverseMass = ((body->mass != 0.0f) ? 1.0f/body->mass : 0.0f);
670
- body->inertia = inertia;
671
- body->inverseInertia = ((body->inertia != 0.0f) ? 1.0f/body->inertia : 0.0f);
672
-
673
- // Calculate explosion force direction
674
- Vector2 pointA = body->position;
675
- Vector2 pointB = MathVector2Subtract(vertexData.positions[1], vertexData.positions[0]);
676
- pointB.x /= 2.0f;
677
- pointB.y /= 2.0f;
678
- Vector2 forceDirection = MathVector2Subtract(MathVector2Add(pointA, MathVector2Add(vertexData.positions[0], pointB)), body->position);
679
- MathVector2Normalize(&forceDirection);
680
- forceDirection.x *= force;
681
- forceDirection.y *= force;
682
-
683
- // Apply force to new physics body
684
- PhysicsAddForce(body, forceDirection);
685
- }
686
-
687
- PHYSAC_FREE(vertices);
688
- }
689
- }
690
- }
691
- else TRACELOG("[PHYSAC] WARNING: PhysicsShatter: NULL physic body\n");
692
- }
693
-
694
- // Returns the current amount of created physics bodies
695
- int GetPhysicsBodiesCount(void)
696
- {
697
- return physicsBodiesCount;
698
- }
699
-
700
- // Returns a physics body of the bodies pool at a specific index
701
- PhysicsBody GetPhysicsBody(int index)
702
- {
703
- PhysicsBody body = NULL;
704
-
705
- if (index < (int)physicsBodiesCount)
706
- {
707
- body = bodies[index];
708
-
709
- if (body == NULL) TRACELOG("[PHYSAC] WARNING: GetPhysicsBody: NULL physic body\n");
710
- }
711
- else TRACELOG("[PHYSAC] WARNING: Physic body index is out of bounds\n");
712
-
713
- return body;
714
- }
715
-
716
- // Returns the physics body shape type (PHYSICS_CIRCLE or PHYSICS_POLYGON)
717
- int GetPhysicsShapeType(int index)
718
- {
719
- int result = -1;
720
-
721
- if (index < (int)physicsBodiesCount)
722
- {
723
- PhysicsBody body = bodies[index];
724
-
725
- if (body != NULL) result = body->shape.type;
726
- else TRACELOG("[PHYSAC] WARNING: GetPhysicsShapeType: NULL physic body\n");
727
- }
728
- else TRACELOG("[PHYSAC] WARNING: Physic body index is out of bounds\n");
729
-
730
- return result;
731
- }
732
-
733
- // Returns the amount of vertices of a physics body shape
734
- int GetPhysicsShapeVerticesCount(int index)
735
- {
736
- int result = 0;
737
-
738
- if (index < (int)physicsBodiesCount)
739
- {
740
- PhysicsBody body = bodies[index];
741
-
742
- if (body != NULL)
743
- {
744
- switch (body->shape.type)
745
- {
746
- case PHYSICS_CIRCLE: result = PHYSAC_DEFAULT_CIRCLE_VERTICES; break;
747
- case PHYSICS_POLYGON: result = body->shape.vertexData.vertexCount; break;
748
- default: break;
749
- }
750
- }
751
- else TRACELOG("[PHYSAC] WARNING: GetPhysicsShapeVerticesCount: NULL physic body\n");
752
- }
753
- else TRACELOG("[PHYSAC] WARNING: Physic body index is out of bounds\n");
754
-
755
- return result;
756
- }
757
-
758
- // Returns transformed position of a body shape (body position + vertex transformed position)
759
- Vector2 GetPhysicsShapeVertex(PhysicsBody body, int vertex)
760
- {
761
- Vector2 position = { 0.0f, 0.0f };
762
-
763
- if (body != NULL)
764
- {
765
- switch (body->shape.type)
766
- {
767
- case PHYSICS_CIRCLE:
768
- {
769
- position.x = body->position.x + cosf(360.0f/PHYSAC_DEFAULT_CIRCLE_VERTICES*vertex*PHYSAC_DEG2RAD)*body->shape.radius;
770
- position.y = body->position.y + sinf(360.0f/PHYSAC_DEFAULT_CIRCLE_VERTICES*vertex*PHYSAC_DEG2RAD)*body->shape.radius;
771
- } break;
772
- case PHYSICS_POLYGON:
773
- {
774
- PhysicsVertexData vertexData = body->shape.vertexData;
775
- position = MathVector2Add(body->position, MathMatVector2Product(body->shape.transform, vertexData.positions[vertex]));
776
- } break;
777
- default: break;
778
- }
779
- }
780
- else TRACELOG("[PHYSAC] WARNING: GetPhysicsShapeVertex: NULL physic body\n");
781
-
782
- return position;
783
- }
784
-
785
- // Sets physics body shape transform based on radians parameter
786
- void SetPhysicsBodyRotation(PhysicsBody body, float radians)
787
- {
788
- if (body != NULL)
789
- {
790
- body->orient = radians;
791
-
792
- if (body->shape.type == PHYSICS_POLYGON) body->shape.transform = MathMatFromRadians(radians);
793
- }
794
- }
795
-
796
- // Unitializes and destroys a physics body
797
- void DestroyPhysicsBody(PhysicsBody body)
798
- {
799
- if (body != NULL)
800
- {
801
- int id = body->id;
802
- int index = -1;
803
-
804
- for (unsigned int i = 0; i < physicsBodiesCount; i++)
805
- {
806
- if (bodies[i]->id == id)
807
- {
808
- index = i;
809
- break;
810
- }
811
- }
812
-
813
- if (index == -1)
814
- {
815
- TRACELOG("[PHYSAC] WARNING: Requested body (id: %i) can not be found\n", id);
816
- return; // Prevent access to index -1
817
- }
818
-
819
- // Free body allocated memory
820
- PHYSAC_FREE(body);
821
- usedMemory -= sizeof(PhysicsBodyData);
822
- bodies[index] = NULL;
823
-
824
- // Reorder physics bodies pointers array and its catched index
825
- for (unsigned int i = index; i < physicsBodiesCount; i++)
826
- {
827
- if ((i + 1) < physicsBodiesCount) bodies[i] = bodies[i + 1];
828
- }
829
-
830
- // Update physics bodies count
831
- physicsBodiesCount--;
832
-
833
- TRACELOG("[PHYSAC] Physic body destroyed successfully (id: %i)\n", id);
834
- }
835
- else TRACELOG("[PHYSAC] WARNING: DestroyPhysicsBody: NULL physic body\n");
836
- }
837
-
838
- // Destroys created physics bodies and manifolds and resets global values
839
- void ResetPhysics(void)
840
- {
841
- if (physicsBodiesCount > 0)
842
- {
843
- // Unitialize physics bodies dynamic memory allocations
844
- for (int i = physicsBodiesCount - 1; i >= 0; i--)
845
- {
846
- PhysicsBody body = bodies[i];
847
-
848
- if (body != NULL)
849
- {
850
- PHYSAC_FREE(body);
851
- bodies[i] = NULL;
852
- usedMemory -= sizeof(PhysicsBodyData);
853
- }
854
- }
855
-
856
- physicsBodiesCount = 0;
857
- }
858
-
859
- if (physicsManifoldsCount > 0)
860
- {
861
- // Unitialize physics manifolds dynamic memory allocations
862
- for (int i = physicsManifoldsCount - 1; i >= 0; i--)
863
- {
864
- PhysicsManifold manifold = contacts[i];
865
-
866
- if (manifold != NULL)
867
- {
868
- PHYSAC_FREE(manifold);
869
- contacts[i] = NULL;
870
- usedMemory -= sizeof(PhysicsManifoldData);
871
- }
872
- }
873
-
874
- physicsManifoldsCount = 0;
875
- }
876
-
877
- TRACELOG("[PHYSAC] Physics module reseted successfully\n");
878
- }
879
-
880
- // Unitializes physics pointers and exits physics loop thread
881
- void ClosePhysics(void)
882
- {
883
- // Unitialize physics manifolds dynamic memory allocations
884
- if (physicsManifoldsCount > 0)
885
- {
886
- for (int i = physicsManifoldsCount - 1; i >= 0; i--) DestroyPhysicsManifold(contacts[i]);
887
- }
888
-
889
- // Unitialize physics bodies dynamic memory allocations
890
- if (physicsBodiesCount > 0)
891
- {
892
- for (int i = physicsBodiesCount - 1; i >= 0; i--) DestroyPhysicsBody(bodies[i]);
893
- }
894
-
895
- // Trace log info
896
- if ((physicsBodiesCount > 0) || (usedMemory != 0))
897
- {
898
- TRACELOG("[PHYSAC] WARNING: Physics module closed with unallocated bodies (BODIES: %i, MEMORY: %i bytes)\n", physicsBodiesCount, usedMemory);
899
- }
900
- else if ((physicsManifoldsCount > 0) || (usedMemory != 0))
901
- {
902
- TRACELOG("[PHYSAC] WARNING: Pysics module closed with unallocated manifolds (MANIFOLDS: %i, MEMORY: %i bytes)\n", physicsManifoldsCount, usedMemory);
903
- }
904
- else TRACELOG("[PHYSAC] Physics module closed successfully\n");
905
- }
906
-
907
- // Update physics system
908
- // Physics steps are launched at a fixed time step if enabled
909
- void UpdatePhysics(void)
910
- {
911
- #if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
912
- static double deltaTimeAccumulator = 0.0;
913
-
914
- // Calculate current time (ms)
915
- currentTime = GetCurrentTime();
916
-
917
- // Calculate current delta time (ms)
918
- const double delta = currentTime - startTime;
919
-
920
- // Store the time elapsed since the last frame began
921
- deltaTimeAccumulator += delta;
922
-
923
- // Fixed time stepping loop
924
- while (deltaTimeAccumulator >= deltaTime)
925
- {
926
- UpdatePhysicsStep();
927
- deltaTimeAccumulator -= deltaTime;
928
- }
929
-
930
- // Record the starting of this frame
931
- startTime = currentTime;
932
- #else
933
- UpdatePhysicsStep();
934
- #endif
935
- }
936
-
937
- void SetPhysicsTimeStep(double delta)
938
- {
939
- deltaTime = delta;
940
- }
941
-
942
- //----------------------------------------------------------------------------------
943
- // Module Internal Functions Definition
944
- //----------------------------------------------------------------------------------
945
- #if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
946
- // Initializes hi-resolution MONOTONIC timer
947
- static void InitTimerHiRes(void)
948
- {
949
- #if defined(_WIN32)
950
- QueryPerformanceFrequency((unsigned long long int *) &frequency);
951
- #endif
952
-
953
- #if defined(__EMSCRIPTEN__) || defined(__linux__)
954
- struct timespec now;
955
- if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) frequency = 1000000000;
956
- #endif
957
-
958
- #if defined(__APPLE__)
959
- mach_timebase_info_data_t timebase;
960
- mach_timebase_info(&timebase);
961
- frequency = (timebase.denom*1e9)/timebase.numer;
962
- #endif
963
-
964
- baseClockTicks = (double)GetClockTicks(); // Get MONOTONIC clock time offset
965
- startTime = GetCurrentTime(); // Get current time in milliseconds
966
- }
967
-
968
- // Get hi-res MONOTONIC time measure in clock ticks
969
- static unsigned long long int GetClockTicks(void)
970
- {
971
- unsigned long long int value = 0;
972
-
973
- #if defined(_WIN32)
974
- QueryPerformanceCounter((unsigned long long int *) &value);
975
- #endif
976
-
977
- #if defined(__linux__)
978
- struct timespec now;
979
- clock_gettime(CLOCK_MONOTONIC, &now);
980
- value = (unsigned long long int)now.tv_sec*(unsigned long long int)1000000000 + (unsigned long long int)now.tv_nsec;
981
- #endif
982
-
983
- #if defined(__APPLE__)
984
- value = mach_absolute_time();
985
- #endif
986
-
987
- return value;
988
- }
989
-
990
- // Get current time in milliseconds
991
- static double GetCurrentTime(void)
992
- {
993
- return (double)(GetClockTicks() - baseClockTicks)/frequency*1000;
994
- }
995
- #endif // !PHYSAC_AVOID_TIMMING_SYSTEM
996
-
997
- // Update physics step (dynamics, collisions and position corrections)
998
- static void UpdatePhysicsStep(void)
999
- {
1000
- // Clear previous generated collisions information
1001
- for (int i = (int)physicsManifoldsCount - 1; i >= 0; i--)
1002
- {
1003
- PhysicsManifold manifold = contacts[i];
1004
- if (manifold != NULL) DestroyPhysicsManifold(manifold);
1005
- }
1006
-
1007
- // Reset physics bodies grounded state
1008
- for (unsigned int i = 0; i < physicsBodiesCount; i++)
1009
- {
1010
- PhysicsBody body = bodies[i];
1011
- body->isGrounded = false;
1012
- }
1013
-
1014
- // Generate new collision information
1015
- for (unsigned int i = 0; i < physicsBodiesCount; i++)
1016
- {
1017
- PhysicsBody bodyA = bodies[i];
1018
-
1019
- if (bodyA != NULL)
1020
- {
1021
- for (unsigned int j = i + 1; j < physicsBodiesCount; j++)
1022
- {
1023
- PhysicsBody bodyB = bodies[j];
1024
-
1025
- if (bodyB != NULL)
1026
- {
1027
- if ((bodyA->inverseMass == 0) && (bodyB->inverseMass == 0)) continue;
1028
-
1029
- PhysicsManifold manifold = CreatePhysicsManifold(bodyA, bodyB);
1030
- SolvePhysicsManifold(manifold);
1031
-
1032
- if (manifold->contactsCount > 0)
1033
- {
1034
- // Create a new manifold with same information as previously solved manifold and add it to the manifolds pool last slot
1035
- PhysicsManifold manifold = CreatePhysicsManifold(bodyA, bodyB);
1036
- manifold->penetration = manifold->penetration;
1037
- manifold->normal = manifold->normal;
1038
- manifold->contacts[0] = manifold->contacts[0];
1039
- manifold->contacts[1] = manifold->contacts[1];
1040
- manifold->contactsCount = manifold->contactsCount;
1041
- manifold->restitution = manifold->restitution;
1042
- manifold->dynamicFriction = manifold->dynamicFriction;
1043
- manifold->staticFriction = manifold->staticFriction;
1044
- }
1045
- }
1046
- }
1047
- }
1048
- }
1049
-
1050
- // Integrate forces to physics bodies
1051
- for (unsigned int i = 0; i < physicsBodiesCount; i++)
1052
- {
1053
- PhysicsBody body = bodies[i];
1054
- if (body != NULL) IntegratePhysicsForces(body);
1055
- }
1056
-
1057
- // Initialize physics manifolds to solve collisions
1058
- for (unsigned int i = 0; i < physicsManifoldsCount; i++)
1059
- {
1060
- PhysicsManifold manifold = contacts[i];
1061
- if (manifold != NULL) InitializePhysicsManifolds(manifold);
1062
- }
1063
-
1064
- // Integrate physics collisions impulses to solve collisions
1065
- for (unsigned int i = 0; i < PHYSAC_COLLISION_ITERATIONS; i++)
1066
- {
1067
- for (unsigned int j = 0; j < physicsManifoldsCount; j++)
1068
- {
1069
- PhysicsManifold manifold = contacts[i];
1070
- if (manifold != NULL) IntegratePhysicsImpulses(manifold);
1071
- }
1072
- }
1073
-
1074
- // Integrate velocity to physics bodies
1075
- for (unsigned int i = 0; i < physicsBodiesCount; i++)
1076
- {
1077
- PhysicsBody body = bodies[i];
1078
- if (body != NULL) IntegratePhysicsVelocity(body);
1079
- }
1080
-
1081
- // Correct physics bodies positions based on manifolds collision information
1082
- for (unsigned int i = 0; i < physicsManifoldsCount; i++)
1083
- {
1084
- PhysicsManifold manifold = contacts[i];
1085
- if (manifold != NULL) CorrectPhysicsPositions(manifold);
1086
- }
1087
-
1088
- // Clear physics bodies forces
1089
- for (unsigned int i = 0; i < physicsBodiesCount; i++)
1090
- {
1091
- PhysicsBody body = bodies[i];
1092
- if (body != NULL)
1093
- {
1094
- body->force = PHYSAC_VECTOR_ZERO;
1095
- body->torque = 0.0f;
1096
- }
1097
- }
1098
- }
1099
-
1100
- // Finds a valid index for a new physics body initialization
1101
- static int FindAvailableBodyIndex()
1102
- {
1103
- int index = -1;
1104
- for (int i = 0; i < PHYSAC_MAX_BODIES; i++)
1105
- {
1106
- int currentId = i;
1107
-
1108
- // Check if current id already exist in other physics body
1109
- for (unsigned int k = 0; k < physicsBodiesCount; k++)
1110
- {
1111
- if (bodies[k]->id == currentId)
1112
- {
1113
- currentId++;
1114
- break;
1115
- }
1116
- }
1117
-
1118
- // If it is not used, use it as new physics body id
1119
- if (currentId == (int)i)
1120
- {
1121
- index = (int)i;
1122
- break;
1123
- }
1124
- }
1125
-
1126
- return index;
1127
- }
1128
-
1129
- // Creates a default polygon shape with max vertex distance from polygon pivot
1130
- static PhysicsVertexData CreateDefaultPolygon(float radius, int sides)
1131
- {
1132
- PhysicsVertexData data = { 0 };
1133
- data.vertexCount = sides;
1134
-
1135
- // Calculate polygon vertices positions
1136
- for (unsigned int i = 0; i < data.vertexCount; i++)
1137
- {
1138
- data.positions[i].x = (float)cosf(360.0f/sides*i*PHYSAC_DEG2RAD)*radius;
1139
- data.positions[i].y = (float)sinf(360.0f/sides*i*PHYSAC_DEG2RAD)*radius;
1140
- }
1141
-
1142
- // Calculate polygon faces normals
1143
- for (int i = 0; i < (int)data.vertexCount; i++)
1144
- {
1145
- int nextIndex = (((i + 1) < sides) ? (i + 1) : 0);
1146
- Vector2 face = MathVector2Subtract(data.positions[nextIndex], data.positions[i]);
1147
-
1148
- data.normals[i] = CLITERAL(Vector2){ face.y, -face.x };
1149
- MathVector2Normalize(&data.normals[i]);
1150
- }
1151
-
1152
- return data;
1153
- }
1154
-
1155
- // Creates a rectangle polygon shape based on a min and max positions
1156
- static PhysicsVertexData CreateRectanglePolygon(Vector2 pos, Vector2 size)
1157
- {
1158
- PhysicsVertexData data = { 0 };
1159
- data.vertexCount = 4;
1160
-
1161
- // Calculate polygon vertices positions
1162
- data.positions[0] = CLITERAL(Vector2){ pos.x + size.x/2, pos.y - size.y/2 };
1163
- data.positions[1] = CLITERAL(Vector2){ pos.x + size.x/2, pos.y + size.y/2 };
1164
- data.positions[2] = CLITERAL(Vector2){ pos.x - size.x/2, pos.y + size.y/2 };
1165
- data.positions[3] = CLITERAL(Vector2){ pos.x - size.x/2, pos.y - size.y/2 };
1166
-
1167
- // Calculate polygon faces normals
1168
- for (unsigned int i = 0; i < data.vertexCount; i++)
1169
- {
1170
- int nextIndex = (((i + 1) < data.vertexCount) ? (i + 1) : 0);
1171
- Vector2 face = MathVector2Subtract(data.positions[nextIndex], data.positions[i]);
1172
-
1173
- data.normals[i] = CLITERAL(Vector2){ face.y, -face.x };
1174
- MathVector2Normalize(&data.normals[i]);
1175
- }
1176
-
1177
- return data;
1178
- }
1179
-
1180
- // Finds a valid index for a new manifold initialization
1181
- static int FindAvailableManifoldIndex()
1182
- {
1183
- int index = -1;
1184
- for (int i = 0; i < PHYSAC_MAX_MANIFOLDS; i++)
1185
- {
1186
- int currentId = i;
1187
-
1188
- // Check if current id already exist in other physics body
1189
- for (unsigned int k = 0; k < physicsManifoldsCount; k++)
1190
- {
1191
- if (contacts[k]->id == currentId)
1192
- {
1193
- currentId++;
1194
- break;
1195
- }
1196
- }
1197
-
1198
- // If it is not used, use it as new physics body id
1199
- if (currentId == i)
1200
- {
1201
- index = i;
1202
- break;
1203
- }
1204
- }
1205
-
1206
- return index;
1207
- }
1208
-
1209
- // Creates a new physics manifold to solve collision
1210
- static PhysicsManifold CreatePhysicsManifold(PhysicsBody a, PhysicsBody b)
1211
- {
1212
- PhysicsManifold manifold = (PhysicsManifold)PHYSAC_MALLOC(sizeof(PhysicsManifoldData));
1213
- usedMemory += sizeof(PhysicsManifoldData);
1214
-
1215
- int id = FindAvailableManifoldIndex();
1216
- if (id != -1)
1217
- {
1218
- // Initialize new manifold with generic values
1219
- manifold->id = id;
1220
- manifold->bodyA = a;
1221
- manifold->bodyB = b;
1222
- manifold->penetration = 0;
1223
- manifold->normal = PHYSAC_VECTOR_ZERO;
1224
- manifold->contacts[0] = PHYSAC_VECTOR_ZERO;
1225
- manifold->contacts[1] = PHYSAC_VECTOR_ZERO;
1226
- manifold->contactsCount = 0;
1227
- manifold->restitution = 0.0f;
1228
- manifold->dynamicFriction = 0.0f;
1229
- manifold->staticFriction = 0.0f;
1230
-
1231
- // Add new body to bodies pointers array and update bodies count
1232
- contacts[physicsManifoldsCount] = manifold;
1233
- physicsManifoldsCount++;
1234
- }
1235
- else TRACELOG("[PHYSAC] Physic manifold could not be created, PHYSAC_MAX_MANIFOLDS reached\n");
1236
-
1237
- return manifold;
1238
- }
1239
-
1240
- // Unitializes and destroys a physics manifold
1241
- static void DestroyPhysicsManifold(PhysicsManifold manifold)
1242
- {
1243
- if (manifold != NULL)
1244
- {
1245
- int id = manifold->id;
1246
- int index = -1;
1247
-
1248
- for (unsigned int i = 0; i < physicsManifoldsCount; i++)
1249
- {
1250
- if (contacts[i]->id == id)
1251
- {
1252
- index = i;
1253
- break;
1254
- }
1255
- }
1256
-
1257
- if (index == -1) return; // Prevent access to index -1
1258
-
1259
- // Free manifold allocated memory
1260
- PHYSAC_FREE(manifold);
1261
- usedMemory -= sizeof(PhysicsManifoldData);
1262
- contacts[index] = NULL;
1263
-
1264
- // Reorder physics manifolds pointers array and its catched index
1265
- for (unsigned int i = index; i < physicsManifoldsCount; i++)
1266
- {
1267
- if ((i + 1) < physicsManifoldsCount) contacts[i] = contacts[i + 1];
1268
- }
1269
-
1270
- // Update physics manifolds count
1271
- physicsManifoldsCount--;
1272
- }
1273
- else TRACELOG("[PHYSAC] WARNING: DestroyPhysicsManifold: NULL physic manifold\n");
1274
- }
1275
-
1276
- // Solves a created physics manifold between two physics bodies
1277
- static void SolvePhysicsManifold(PhysicsManifold manifold)
1278
- {
1279
- switch (manifold->bodyA->shape.type)
1280
- {
1281
- case PHYSICS_CIRCLE:
1282
- {
1283
- switch (manifold->bodyB->shape.type)
1284
- {
1285
- case PHYSICS_CIRCLE: SolveCircleToCircle(manifold); break;
1286
- case PHYSICS_POLYGON: SolveCircleToPolygon(manifold); break;
1287
- default: break;
1288
- }
1289
- } break;
1290
- case PHYSICS_POLYGON:
1291
- {
1292
- switch (manifold->bodyB->shape.type)
1293
- {
1294
- case PHYSICS_CIRCLE: SolvePolygonToCircle(manifold); break;
1295
- case PHYSICS_POLYGON: SolvePolygonToPolygon(manifold); break;
1296
- default: break;
1297
- }
1298
- } break;
1299
- default: break;
1300
- }
1301
-
1302
- // Update physics body grounded state if normal direction is down and grounded state is not set yet in previous manifolds
1303
- if (!manifold->bodyB->isGrounded) manifold->bodyB->isGrounded = (manifold->normal.y < 0);
1304
- }
1305
-
1306
- // Solves collision between two circle shape physics bodies
1307
- static void SolveCircleToCircle(PhysicsManifold manifold)
1308
- {
1309
- PhysicsBody bodyA = manifold->bodyA;
1310
- PhysicsBody bodyB = manifold->bodyB;
1311
-
1312
- if ((bodyA == NULL) || (bodyB == NULL)) return;
1313
-
1314
- // Calculate translational vector, which is normal
1315
- Vector2 normal = MathVector2Subtract(bodyB->position, bodyA->position);
1316
-
1317
- float distSqr = MathVector2SqrLen(normal);
1318
- float radius = bodyA->shape.radius + bodyB->shape.radius;
1319
-
1320
- // Check if circles are not in contact
1321
- if (distSqr >= radius*radius)
1322
- {
1323
- manifold->contactsCount = 0;
1324
- return;
1325
- }
1326
-
1327
- float distance = sqrtf(distSqr);
1328
- manifold->contactsCount = 1;
1329
-
1330
- if (distance == 0.0f)
1331
- {
1332
- manifold->penetration = bodyA->shape.radius;
1333
- manifold->normal = CLITERAL(Vector2){ 1.0f, 0.0f };
1334
- manifold->contacts[0] = bodyA->position;
1335
- }
1336
- else
1337
- {
1338
- manifold->penetration = radius - distance;
1339
- manifold->normal = CLITERAL(Vector2){ normal.x/distance, normal.y/distance }; // Faster than using MathVector2Normalize() due to sqrt is already performed
1340
- manifold->contacts[0] = CLITERAL(Vector2){ manifold->normal.x*bodyA->shape.radius + bodyA->position.x, manifold->normal.y*bodyA->shape.radius + bodyA->position.y };
1341
- }
1342
-
1343
- // Update physics body grounded state if normal direction is down
1344
- if (!bodyA->isGrounded) bodyA->isGrounded = (manifold->normal.y < 0);
1345
- }
1346
-
1347
- // Solves collision between a circle to a polygon shape physics bodies
1348
- static void SolveCircleToPolygon(PhysicsManifold manifold)
1349
- {
1350
- PhysicsBody bodyA = manifold->bodyA;
1351
- PhysicsBody bodyB = manifold->bodyB;
1352
-
1353
- if ((bodyA == NULL) || (bodyB == NULL)) return;
1354
-
1355
- manifold->contactsCount = 0;
1356
-
1357
- // Transform circle center to polygon transform space
1358
- Vector2 center = bodyA->position;
1359
- center = MathMatVector2Product(MathMatTranspose(bodyB->shape.transform), MathVector2Subtract(center, bodyB->position));
1360
-
1361
- // Find edge with minimum penetration
1362
- // It is the same concept as using support points in SolvePolygonToPolygon
1363
- float separation = -PHYSAC_FLT_MAX;
1364
- int faceNormal = 0;
1365
- PhysicsVertexData vertexData = bodyB->shape.vertexData;
1366
-
1367
- for (unsigned int i = 0; i < vertexData.vertexCount; i++)
1368
- {
1369
- float currentSeparation = MathVector2DotProduct(vertexData.normals[i], MathVector2Subtract(center, vertexData.positions[i]));
1370
-
1371
- if (currentSeparation > bodyA->shape.radius) return;
1372
-
1373
- if (currentSeparation > separation)
1374
- {
1375
- separation = currentSeparation;
1376
- faceNormal = i;
1377
- }
1378
- }
1379
-
1380
- // Grab face's vertices
1381
- Vector2 v1 = vertexData.positions[faceNormal];
1382
- int nextIndex = (((faceNormal + 1) < (int)vertexData.vertexCount) ? (faceNormal + 1) : 0);
1383
- Vector2 v2 = vertexData.positions[nextIndex];
1384
-
1385
- // Check to see if center is within polygon
1386
- if (separation < PHYSAC_EPSILON)
1387
- {
1388
- manifold->contactsCount = 1;
1389
- Vector2 normal = MathMatVector2Product(bodyB->shape.transform, vertexData.normals[faceNormal]);
1390
- manifold->normal = CLITERAL(Vector2){ -normal.x, -normal.y };
1391
- manifold->contacts[0] = CLITERAL(Vector2){ manifold->normal.x*bodyA->shape.radius + bodyA->position.x, manifold->normal.y*bodyA->shape.radius + bodyA->position.y };
1392
- manifold->penetration = bodyA->shape.radius;
1393
- return;
1394
- }
1395
-
1396
- // Determine which voronoi region of the edge center of circle lies within
1397
- float dot1 = MathVector2DotProduct(MathVector2Subtract(center, v1), MathVector2Subtract(v2, v1));
1398
- float dot2 = MathVector2DotProduct(MathVector2Subtract(center, v2), MathVector2Subtract(v1, v2));
1399
- manifold->penetration = bodyA->shape.radius - separation;
1400
-
1401
- if (dot1 <= 0.0f) // Closest to v1
1402
- {
1403
- if (MathVector2SqrDistance(center, v1) > bodyA->shape.radius*bodyA->shape.radius) return;
1404
-
1405
- manifold->contactsCount = 1;
1406
- Vector2 normal = MathVector2Subtract(v1, center);
1407
- normal = MathMatVector2Product(bodyB->shape.transform, normal);
1408
- MathVector2Normalize(&normal);
1409
- manifold->normal = normal;
1410
- v1 = MathMatVector2Product(bodyB->shape.transform, v1);
1411
- v1 = MathVector2Add(v1, bodyB->position);
1412
- manifold->contacts[0] = v1;
1413
- }
1414
- else if (dot2 <= 0.0f) // Closest to v2
1415
- {
1416
- if (MathVector2SqrDistance(center, v2) > bodyA->shape.radius*bodyA->shape.radius) return;
1417
-
1418
- manifold->contactsCount = 1;
1419
- Vector2 normal = MathVector2Subtract(v2, center);
1420
- v2 = MathMatVector2Product(bodyB->shape.transform, v2);
1421
- v2 = MathVector2Add(v2, bodyB->position);
1422
- manifold->contacts[0] = v2;
1423
- normal = MathMatVector2Product(bodyB->shape.transform, normal);
1424
- MathVector2Normalize(&normal);
1425
- manifold->normal = normal;
1426
- }
1427
- else // Closest to face
1428
- {
1429
- Vector2 normal = vertexData.normals[faceNormal];
1430
-
1431
- if (MathVector2DotProduct(MathVector2Subtract(center, v1), normal) > bodyA->shape.radius) return;
1432
-
1433
- normal = MathMatVector2Product(bodyB->shape.transform, normal);
1434
- manifold->normal = CLITERAL(Vector2){ -normal.x, -normal.y };
1435
- manifold->contacts[0] = CLITERAL(Vector2){ manifold->normal.x*bodyA->shape.radius + bodyA->position.x, manifold->normal.y*bodyA->shape.radius + bodyA->position.y };
1436
- manifold->contactsCount = 1;
1437
- }
1438
- }
1439
-
1440
- // Solves collision between a polygon to a circle shape physics bodies
1441
- static void SolvePolygonToCircle(PhysicsManifold manifold)
1442
- {
1443
- PhysicsBody bodyA = manifold->bodyA;
1444
- PhysicsBody bodyB = manifold->bodyB;
1445
-
1446
- if ((bodyA == NULL) || (bodyB == NULL)) return;
1447
-
1448
- manifold->bodyA = bodyB;
1449
- manifold->bodyB = bodyA;
1450
- SolveCircleToPolygon(manifold);
1451
-
1452
- manifold->normal.x *= -1.0f;
1453
- manifold->normal.y *= -1.0f;
1454
- }
1455
-
1456
- // Solves collision between two polygons shape physics bodies
1457
- static void SolvePolygonToPolygon(PhysicsManifold manifold)
1458
- {
1459
- if ((manifold->bodyA == NULL) || (manifold->bodyB == NULL)) return;
1460
-
1461
- PhysicsShape bodyA = manifold->bodyA->shape;
1462
- PhysicsShape bodyB = manifold->bodyB->shape;
1463
- manifold->contactsCount = 0;
1464
-
1465
- // Check for separating axis with A shape's face planes
1466
- int faceA = 0;
1467
- float penetrationA = FindAxisLeastPenetration(&faceA, bodyA, bodyB);
1468
- if (penetrationA >= 0.0f) return;
1469
-
1470
- // Check for separating axis with B shape's face planes
1471
- int faceB = 0;
1472
- float penetrationB = FindAxisLeastPenetration(&faceB, bodyB, bodyA);
1473
- if (penetrationB >= 0.0f) return;
1474
-
1475
- int referenceIndex = 0;
1476
- bool flip = false; // Always point from A shape to B shape
1477
-
1478
- PhysicsShape refPoly; // Reference
1479
- PhysicsShape incPoly; // Incident
1480
-
1481
- // Determine which shape contains reference face
1482
- // Checking bias range for penetration
1483
- if (penetrationA >= (penetrationB*0.95f + penetrationA*0.01f))
1484
- {
1485
- refPoly = bodyA;
1486
- incPoly = bodyB;
1487
- referenceIndex = faceA;
1488
- }
1489
- else
1490
- {
1491
- refPoly = bodyB;
1492
- incPoly = bodyA;
1493
- referenceIndex = faceB;
1494
- flip = true;
1495
- }
1496
-
1497
- // World space incident face
1498
- Vector2 incidentFace[2];
1499
- FindIncidentFace(&incidentFace[0], &incidentFace[1], refPoly, incPoly, referenceIndex);
1500
-
1501
- // Setup reference face vertices
1502
- PhysicsVertexData refData = refPoly.vertexData;
1503
- Vector2 v1 = refData.positions[referenceIndex];
1504
- referenceIndex = (((referenceIndex + 1) < (int)refData.vertexCount) ? (referenceIndex + 1) : 0);
1505
- Vector2 v2 = refData.positions[referenceIndex];
1506
-
1507
- // Transform vertices to world space
1508
- v1 = MathMatVector2Product(refPoly.transform, v1);
1509
- v1 = MathVector2Add(v1, refPoly.body->position);
1510
- v2 = MathMatVector2Product(refPoly.transform, v2);
1511
- v2 = MathVector2Add(v2, refPoly.body->position);
1512
-
1513
- // Calculate reference face side normal in world space
1514
- Vector2 sidePlaneNormal = MathVector2Subtract(v2, v1);
1515
- MathVector2Normalize(&sidePlaneNormal);
1516
-
1517
- // Orthogonalize
1518
- Vector2 refFaceNormal = { sidePlaneNormal.y, -sidePlaneNormal.x };
1519
- float refC = MathVector2DotProduct(refFaceNormal, v1);
1520
- float negSide = MathVector2DotProduct(sidePlaneNormal, v1)*-1;
1521
- float posSide = MathVector2DotProduct(sidePlaneNormal, v2);
1522
-
1523
- // MathVector2Clip incident face to reference face side planes (due to floating point error, possible to not have required points
1524
- if (MathVector2Clip(CLITERAL(Vector2){ -sidePlaneNormal.x, -sidePlaneNormal.y }, &incidentFace[0], &incidentFace[1], negSide) < 2) return;
1525
- if (MathVector2Clip(sidePlaneNormal, &incidentFace[0], &incidentFace[1], posSide) < 2) return;
1526
-
1527
- // Flip normal if required
1528
- manifold->normal = (flip ? CLITERAL(Vector2){ -refFaceNormal.x, -refFaceNormal.y } : refFaceNormal);
1529
-
1530
- // Keep points behind reference face
1531
- int currentPoint = 0; // MathVector2Clipped points behind reference face
1532
- float separation = MathVector2DotProduct(refFaceNormal, incidentFace[0]) - refC;
1533
- if (separation <= 0.0f)
1534
- {
1535
- manifold->contacts[currentPoint] = incidentFace[0];
1536
- manifold->penetration = -separation;
1537
- currentPoint++;
1538
- }
1539
- else manifold->penetration = 0.0f;
1540
-
1541
- separation = MathVector2DotProduct(refFaceNormal, incidentFace[1]) - refC;
1542
-
1543
- if (separation <= 0.0f)
1544
- {
1545
- manifold->contacts[currentPoint] = incidentFace[1];
1546
- manifold->penetration += -separation;
1547
- currentPoint++;
1548
-
1549
- // Calculate total penetration average
1550
- manifold->penetration /= currentPoint;
1551
- }
1552
-
1553
- manifold->contactsCount = currentPoint;
1554
- }
1555
-
1556
- // Integrates physics forces into velocity
1557
- static void IntegratePhysicsForces(PhysicsBody body)
1558
- {
1559
- if ((body == NULL) || (body->inverseMass == 0.0f) || !body->enabled) return;
1560
-
1561
- body->velocity.x += (float)((body->force.x*body->inverseMass)*(deltaTime/2.0));
1562
- body->velocity.y += (float)((body->force.y*body->inverseMass)*(deltaTime/2.0));
1563
-
1564
- if (body->useGravity)
1565
- {
1566
- body->velocity.x += (float)(gravityForce.x*(deltaTime/1000/2.0));
1567
- body->velocity.y += (float)(gravityForce.y*(deltaTime/1000/2.0));
1568
- }
1569
-
1570
- if (!body->freezeOrient) body->angularVelocity += (float)(body->torque*body->inverseInertia*(deltaTime/2.0));
1571
- }
1572
-
1573
- // Initializes physics manifolds to solve collisions
1574
- static void InitializePhysicsManifolds(PhysicsManifold manifold)
1575
- {
1576
- PhysicsBody bodyA = manifold->bodyA;
1577
- PhysicsBody bodyB = manifold->bodyB;
1578
-
1579
- if ((bodyA == NULL) || (bodyB == NULL)) return;
1580
-
1581
- // Calculate average restitution, static and dynamic friction
1582
- manifold->restitution = sqrtf(bodyA->restitution*bodyB->restitution);
1583
- manifold->staticFriction = sqrtf(bodyA->staticFriction*bodyB->staticFriction);
1584
- manifold->dynamicFriction = sqrtf(bodyA->dynamicFriction*bodyB->dynamicFriction);
1585
-
1586
- for (unsigned int i = 0; i < manifold->contactsCount; i++)
1587
- {
1588
- // Caculate radius from center of mass to contact
1589
- Vector2 radiusA = MathVector2Subtract(manifold->contacts[i], bodyA->position);
1590
- Vector2 radiusB = MathVector2Subtract(manifold->contacts[i], bodyB->position);
1591
-
1592
- Vector2 crossA = MathVector2Product(radiusA, bodyA->angularVelocity);
1593
- Vector2 crossB = MathVector2Product(radiusB, bodyB->angularVelocity);
1594
-
1595
- Vector2 radiusV = { 0.0f, 0.0f };
1596
- radiusV.x = bodyB->velocity.x + crossB.x - bodyA->velocity.x - crossA.x;
1597
- radiusV.y = bodyB->velocity.y + crossB.y - bodyA->velocity.y - crossA.y;
1598
-
1599
- // Determine if we should perform a resting collision or not;
1600
- // The idea is if the only thing moving this object is gravity, then the collision should be performed without any restitution
1601
- if (MathVector2SqrLen(radiusV) < (MathVector2SqrLen(CLITERAL(Vector2){ (float)(gravityForce.x*deltaTime/1000), (float)(gravityForce.y*deltaTime/1000) }) + PHYSAC_EPSILON)) manifold->restitution = 0;
1602
- }
1603
- }
1604
-
1605
- // Integrates physics collisions impulses to solve collisions
1606
- static void IntegratePhysicsImpulses(PhysicsManifold manifold)
1607
- {
1608
- PhysicsBody bodyA = manifold->bodyA;
1609
- PhysicsBody bodyB = manifold->bodyB;
1610
-
1611
- if ((bodyA == NULL) || (bodyB == NULL)) return;
1612
-
1613
- // Early out and positional correct if both objects have infinite mass
1614
- if (fabs(bodyA->inverseMass + bodyB->inverseMass) <= PHYSAC_EPSILON)
1615
- {
1616
- bodyA->velocity = PHYSAC_VECTOR_ZERO;
1617
- bodyB->velocity = PHYSAC_VECTOR_ZERO;
1618
- return;
1619
- }
1620
-
1621
- for (unsigned int i = 0; i < manifold->contactsCount; i++)
1622
- {
1623
- // Calculate radius from center of mass to contact
1624
- Vector2 radiusA = MathVector2Subtract(manifold->contacts[i], bodyA->position);
1625
- Vector2 radiusB = MathVector2Subtract(manifold->contacts[i], bodyB->position);
1626
-
1627
- // Calculate relative velocity
1628
- Vector2 radiusV = { 0.0f, 0.0f };
1629
- radiusV.x = bodyB->velocity.x + MathVector2Product(radiusB, bodyB->angularVelocity).x - bodyA->velocity.x - MathVector2Product(radiusA, bodyA->angularVelocity).x;
1630
- radiusV.y = bodyB->velocity.y + MathVector2Product(radiusB, bodyB->angularVelocity).y - bodyA->velocity.y - MathVector2Product(radiusA, bodyA->angularVelocity).y;
1631
-
1632
- // Relative velocity along the normal
1633
- float contactVelocity = MathVector2DotProduct(radiusV, manifold->normal);
1634
-
1635
- // Do not resolve if velocities are separating
1636
- if (contactVelocity > 0.0f) return;
1637
-
1638
- float raCrossN = MathVector2CrossProduct(radiusA, manifold->normal);
1639
- float rbCrossN = MathVector2CrossProduct(radiusB, manifold->normal);
1640
-
1641
- float inverseMassSum = bodyA->inverseMass + bodyB->inverseMass + (raCrossN*raCrossN)*bodyA->inverseInertia + (rbCrossN*rbCrossN)*bodyB->inverseInertia;
1642
-
1643
- // Calculate impulse scalar value
1644
- float impulse = -(1.0f + manifold->restitution)*contactVelocity;
1645
- impulse /= inverseMassSum;
1646
- impulse /= (float)manifold->contactsCount;
1647
-
1648
- // Apply impulse to each physics body
1649
- Vector2 impulseV = { manifold->normal.x*impulse, manifold->normal.y*impulse };
1650
-
1651
- if (bodyA->enabled)
1652
- {
1653
- bodyA->velocity.x += bodyA->inverseMass*(-impulseV.x);
1654
- bodyA->velocity.y += bodyA->inverseMass*(-impulseV.y);
1655
- if (!bodyA->freezeOrient) bodyA->angularVelocity += bodyA->inverseInertia*MathVector2CrossProduct(radiusA, CLITERAL(Vector2){ -impulseV.x, -impulseV.y });
1656
- }
1657
-
1658
- if (bodyB->enabled)
1659
- {
1660
- bodyB->velocity.x += bodyB->inverseMass*(impulseV.x);
1661
- bodyB->velocity.y += bodyB->inverseMass*(impulseV.y);
1662
- if (!bodyB->freezeOrient) bodyB->angularVelocity += bodyB->inverseInertia*MathVector2CrossProduct(radiusB, impulseV);
1663
- }
1664
-
1665
- // Apply friction impulse to each physics body
1666
- radiusV.x = bodyB->velocity.x + MathVector2Product(radiusB, bodyB->angularVelocity).x - bodyA->velocity.x - MathVector2Product(radiusA, bodyA->angularVelocity).x;
1667
- radiusV.y = bodyB->velocity.y + MathVector2Product(radiusB, bodyB->angularVelocity).y - bodyA->velocity.y - MathVector2Product(radiusA, bodyA->angularVelocity).y;
1668
-
1669
- Vector2 tangent = { radiusV.x - (manifold->normal.x*MathVector2DotProduct(radiusV, manifold->normal)), radiusV.y - (manifold->normal.y*MathVector2DotProduct(radiusV, manifold->normal)) };
1670
- MathVector2Normalize(&tangent);
1671
-
1672
- // Calculate impulse tangent magnitude
1673
- float impulseTangent = -MathVector2DotProduct(radiusV, tangent);
1674
- impulseTangent /= inverseMassSum;
1675
- impulseTangent /= (float)manifold->contactsCount;
1676
-
1677
- float absImpulseTangent = (float)fabs(impulseTangent);
1678
-
1679
- // Don't apply tiny friction impulses
1680
- if (absImpulseTangent <= PHYSAC_EPSILON) return;
1681
-
1682
- // Apply coulumb's law
1683
- Vector2 tangentImpulse = { 0.0f, 0.0f };
1684
- if (absImpulseTangent < impulse*manifold->staticFriction) tangentImpulse = CLITERAL(Vector2){ tangent.x*impulseTangent, tangent.y*impulseTangent };
1685
- else tangentImpulse = CLITERAL(Vector2){ tangent.x*-impulse*manifold->dynamicFriction, tangent.y*-impulse*manifold->dynamicFriction };
1686
-
1687
- // Apply friction impulse
1688
- if (bodyA->enabled)
1689
- {
1690
- bodyA->velocity.x += bodyA->inverseMass*(-tangentImpulse.x);
1691
- bodyA->velocity.y += bodyA->inverseMass*(-tangentImpulse.y);
1692
-
1693
- if (!bodyA->freezeOrient) bodyA->angularVelocity += bodyA->inverseInertia*MathVector2CrossProduct(radiusA, CLITERAL(Vector2){ -tangentImpulse.x, -tangentImpulse.y });
1694
- }
1695
-
1696
- if (bodyB->enabled)
1697
- {
1698
- bodyB->velocity.x += bodyB->inverseMass*(tangentImpulse.x);
1699
- bodyB->velocity.y += bodyB->inverseMass*(tangentImpulse.y);
1700
-
1701
- if (!bodyB->freezeOrient) bodyB->angularVelocity += bodyB->inverseInertia*MathVector2CrossProduct(radiusB, tangentImpulse);
1702
- }
1703
- }
1704
- }
1705
-
1706
- // Integrates physics velocity into position and forces
1707
- static void IntegratePhysicsVelocity(PhysicsBody body)
1708
- {
1709
- if ((body == NULL) ||!body->enabled) return;
1710
-
1711
- body->position.x += (float)(body->velocity.x*deltaTime);
1712
- body->position.y += (float)(body->velocity.y*deltaTime);
1713
-
1714
- if (!body->freezeOrient) body->orient += (float)(body->angularVelocity*deltaTime);
1715
- body->shape.transform = MathMatFromRadians(body->orient);
1716
-
1717
- IntegratePhysicsForces(body);
1718
- }
1719
-
1720
- // Corrects physics bodies positions based on manifolds collision information
1721
- static void CorrectPhysicsPositions(PhysicsManifold manifold)
1722
- {
1723
- PhysicsBody bodyA = manifold->bodyA;
1724
- PhysicsBody bodyB = manifold->bodyB;
1725
-
1726
- if ((bodyA == NULL) || (bodyB == NULL)) return;
1727
-
1728
- Vector2 correction = { 0.0f, 0.0f };
1729
- correction.x = (PHYSAC_MAX(manifold->penetration - PHYSAC_PENETRATION_ALLOWANCE, 0.0f)/(bodyA->inverseMass + bodyB->inverseMass))*manifold->normal.x*PHYSAC_PENETRATION_CORRECTION;
1730
- correction.y = (PHYSAC_MAX(manifold->penetration - PHYSAC_PENETRATION_ALLOWANCE, 0.0f)/(bodyA->inverseMass + bodyB->inverseMass))*manifold->normal.y*PHYSAC_PENETRATION_CORRECTION;
1731
-
1732
- if (bodyA->enabled)
1733
- {
1734
- bodyA->position.x -= correction.x*bodyA->inverseMass;
1735
- bodyA->position.y -= correction.y*bodyA->inverseMass;
1736
- }
1737
-
1738
- if (bodyB->enabled)
1739
- {
1740
- bodyB->position.x += correction.x*bodyB->inverseMass;
1741
- bodyB->position.y += correction.y*bodyB->inverseMass;
1742
- }
1743
- }
1744
-
1745
- // Returns the extreme point along a direction within a polygon
1746
- static Vector2 GetSupport(PhysicsShape shape, Vector2 dir)
1747
- {
1748
- float bestProjection = -PHYSAC_FLT_MAX;
1749
- Vector2 bestVertex = { 0.0f, 0.0f };
1750
- PhysicsVertexData data = shape.vertexData;
1751
-
1752
- for (unsigned int i = 0; i < data.vertexCount; i++)
1753
- {
1754
- Vector2 vertex = data.positions[i];
1755
- float projection = MathVector2DotProduct(vertex, dir);
1756
-
1757
- if (projection > bestProjection)
1758
- {
1759
- bestVertex = vertex;
1760
- bestProjection = projection;
1761
- }
1762
- }
1763
-
1764
- return bestVertex;
1765
- }
1766
-
1767
- // Finds polygon shapes axis least penetration
1768
- static float FindAxisLeastPenetration(int *faceIndex, PhysicsShape shapeA, PhysicsShape shapeB)
1769
- {
1770
- float bestDistance = -PHYSAC_FLT_MAX;
1771
- int bestIndex = 0;
1772
-
1773
- PhysicsVertexData dataA = shapeA.vertexData;
1774
- //PhysicsVertexData dataB = shapeB.vertexData;
1775
-
1776
- for (unsigned int i = 0; i < dataA.vertexCount; i++)
1777
- {
1778
- // Retrieve a face normal from A shape
1779
- Vector2 normal = dataA.normals[i];
1780
- Vector2 transNormal = MathMatVector2Product(shapeA.transform, normal);
1781
-
1782
- // Transform face normal into B shape's model space
1783
- Matrix2x2 buT = MathMatTranspose(shapeB.transform);
1784
- normal = MathMatVector2Product(buT, transNormal);
1785
-
1786
- // Retrieve support point from B shape along -n
1787
- Vector2 support = GetSupport(shapeB, CLITERAL(Vector2){ -normal.x, -normal.y });
1788
-
1789
- // Retrieve vertex on face from A shape, transform into B shape's model space
1790
- Vector2 vertex = dataA.positions[i];
1791
- vertex = MathMatVector2Product(shapeA.transform, vertex);
1792
- vertex = MathVector2Add(vertex, shapeA.body->position);
1793
- vertex = MathVector2Subtract(vertex, shapeB.body->position);
1794
- vertex = MathMatVector2Product(buT, vertex);
1795
-
1796
- // Compute penetration distance in B shape's model space
1797
- float distance = MathVector2DotProduct(normal, MathVector2Subtract(support, vertex));
1798
-
1799
- // Store greatest distance
1800
- if (distance > bestDistance)
1801
- {
1802
- bestDistance = distance;
1803
- bestIndex = i;
1804
- }
1805
- }
1806
-
1807
- *faceIndex = bestIndex;
1808
- return bestDistance;
1809
- }
1810
-
1811
- // Finds two polygon shapes incident face
1812
- static void FindIncidentFace(Vector2 *v0, Vector2 *v1, PhysicsShape ref, PhysicsShape inc, int index)
1813
- {
1814
- PhysicsVertexData refData = ref.vertexData;
1815
- PhysicsVertexData incData = inc.vertexData;
1816
-
1817
- Vector2 referenceNormal = refData.normals[index];
1818
-
1819
- // Calculate normal in incident's frame of reference
1820
- referenceNormal = MathMatVector2Product(ref.transform, referenceNormal); // To world space
1821
- referenceNormal = MathMatVector2Product(MathMatTranspose(inc.transform), referenceNormal); // To incident's model space
1822
-
1823
- // Find most anti-normal face on polygon
1824
- int incidentFace = 0;
1825
- float minDot = PHYSAC_FLT_MAX;
1826
-
1827
- for (unsigned int i = 0; i < incData.vertexCount; i++)
1828
- {
1829
- float dot = MathVector2DotProduct(referenceNormal, incData.normals[i]);
1830
-
1831
- if (dot < minDot)
1832
- {
1833
- minDot = dot;
1834
- incidentFace = i;
1835
- }
1836
- }
1837
-
1838
- // Assign face vertices for incident face
1839
- *v0 = MathMatVector2Product(inc.transform, incData.positions[incidentFace]);
1840
- *v0 = MathVector2Add(*v0, inc.body->position);
1841
- incidentFace = (((incidentFace + 1) < (int)incData.vertexCount) ? (incidentFace + 1) : 0);
1842
- *v1 = MathMatVector2Product(inc.transform, incData.positions[incidentFace]);
1843
- *v1 = MathVector2Add(*v1, inc.body->position);
1844
- }
1845
-
1846
- // Returns clipping value based on a normal and two faces
1847
- static int MathVector2Clip(Vector2 normal, Vector2 *faceA, Vector2 *faceB, float clip)
1848
- {
1849
- int sp = 0;
1850
- Vector2 out[2] = { *faceA, *faceB };
1851
-
1852
- // Retrieve distances from each endpoint to the line
1853
- float distanceA = MathVector2DotProduct(normal, *faceA) - clip;
1854
- float distanceB = MathVector2DotProduct(normal, *faceB) - clip;
1855
-
1856
- // If negative (behind plane)
1857
- if (distanceA <= 0.0f) out[sp++] = *faceA;
1858
- if (distanceB <= 0.0f) out[sp++] = *faceB;
1859
-
1860
- // If the points are on different sides of the plane
1861
- if ((distanceA*distanceB) < 0.0f)
1862
- {
1863
- // Push intersection point
1864
- float alpha = distanceA/(distanceA - distanceB);
1865
- out[sp] = *faceA;
1866
- Vector2 delta = MathVector2Subtract(*faceB, *faceA);
1867
- delta.x *= alpha;
1868
- delta.y *= alpha;
1869
- out[sp] = MathVector2Add(out[sp], delta);
1870
- sp++;
1871
- }
1872
-
1873
- // Assign the new converted values
1874
- *faceA = out[0];
1875
- *faceB = out[1];
1876
-
1877
- return sp;
1878
- }
1879
-
1880
- // Returns the barycenter of a triangle given by 3 points
1881
- static Vector2 MathTriangleBarycenter(Vector2 v1, Vector2 v2, Vector2 v3)
1882
- {
1883
- Vector2 result = { 0.0f, 0.0f };
1884
-
1885
- result.x = (v1.x + v2.x + v3.x)/3;
1886
- result.y = (v1.y + v2.y + v3.y)/3;
1887
-
1888
- return result;
1889
- }
1890
-
1891
- // Returns the cross product of a vector and a value
1892
- static inline Vector2 MathVector2Product(Vector2 vector, float value)
1893
- {
1894
- Vector2 result = { -value*vector.y, value*vector.x };
1895
- return result;
1896
- }
1897
-
1898
- // Returns the cross product of two vectors
1899
- static inline float MathVector2CrossProduct(Vector2 v1, Vector2 v2)
1900
- {
1901
- return (v1.x*v2.y - v1.y*v2.x);
1902
- }
1903
-
1904
- // Returns the len square root of a vector
1905
- static inline float MathVector2SqrLen(Vector2 vector)
1906
- {
1907
- return (vector.x*vector.x + vector.y*vector.y);
1908
- }
1909
-
1910
- // Returns the dot product of two vectors
1911
- static inline float MathVector2DotProduct(Vector2 v1, Vector2 v2)
1912
- {
1913
- return (v1.x*v2.x + v1.y*v2.y);
1914
- }
1915
-
1916
- // Returns the square root of distance between two vectors
1917
- static inline float MathVector2SqrDistance(Vector2 v1, Vector2 v2)
1918
- {
1919
- Vector2 dir = MathVector2Subtract(v1, v2);
1920
- return MathVector2DotProduct(dir, dir);
1921
- }
1922
-
1923
- // Returns the normalized values of a vector
1924
- static void MathVector2Normalize(Vector2 *vector)
1925
- {
1926
- float length, ilength;
1927
-
1928
- Vector2 aux = *vector;
1929
- length = sqrtf(aux.x*aux.x + aux.y*aux.y);
1930
-
1931
- if (length == 0) length = 1.0f;
1932
-
1933
- ilength = 1.0f/length;
1934
-
1935
- vector->x *= ilength;
1936
- vector->y *= ilength;
1937
- }
1938
-
1939
- // Returns the sum of two given vectors
1940
- static inline Vector2 MathVector2Add(Vector2 v1, Vector2 v2)
1941
- {
1942
- Vector2 result = { v1.x + v2.x, v1.y + v2.y };
1943
- return result;
1944
- }
1945
-
1946
- // Returns the subtract of two given vectors
1947
- static inline Vector2 MathVector2Subtract(Vector2 v1, Vector2 v2)
1948
- {
1949
- Vector2 result = { v1.x - v2.x, v1.y - v2.y };
1950
- return result;
1951
- }
1952
-
1953
- // Creates a matrix 2x2 from a given radians value
1954
- static Matrix2x2 MathMatFromRadians(float radians)
1955
- {
1956
- float cos = cosf(radians);
1957
- float sin = sinf(radians);
1958
-
1959
- Matrix2x2 result = { cos, -sin, sin, cos };
1960
- return result;
1961
- }
1962
-
1963
- // Returns the transpose of a given matrix 2x2
1964
- static inline Matrix2x2 MathMatTranspose(Matrix2x2 matrix)
1965
- {
1966
- Matrix2x2 result = { matrix.m00, matrix.m10, matrix.m01, matrix.m11 };
1967
- return result;
1968
- }
1969
-
1970
- // Multiplies a vector by a matrix 2x2
1971
- static inline Vector2 MathMatVector2Product(Matrix2x2 matrix, Vector2 vector)
1972
- {
1973
- Vector2 result = { matrix.m00*vector.x + matrix.m01*vector.y, matrix.m10*vector.x + matrix.m11*vector.y };
1974
- return result;
1975
- }
1976
-
1977
- #endif // PHYSAC_IMPLEMENTATION