diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a86081..b20778f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -853,6 +853,11 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/akgl.pc DESTINATION "lib/pkgconfig/") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/akgl/version.h DESTINATION "include/akgl/") install(TARGETS akgl DESTINATION "lib/") install(FILES "deps/semver/semver.h" DESTINATION "include/") +# libccd is compiled into libakgl.so, and its BSD-3 licence requires the notice +# to travel with the binary form. Nothing else in deps/ is linked in statically +# -- SDL, jansson, libakerror and libakstdlib are all separate shared objects +# that ship their own -- so this is the only third-party notice we owe. +install(FILES "deps/libccd/BSD-LICENSE" DESTINATION "share/doc/akgl/" RENAME "BSD-LICENSE.libccd") foreach(header IN LISTS AKGL_PUBLIC_HEADERS) install(FILES "include/akgl/${header}.h" DESTINATION "include/akgl/") endforeach() diff --git a/README.md b/README.md index 9f1b48f..1a20453 100644 --- a/README.md +++ b/README.md @@ -199,3 +199,21 @@ scripts/memcheck.sh -LE perf # skip the benchmarks The run forces `SDL_VIDEO_DRIVER=dummy`, `SDL_RENDER_DRIVER=software` and `SDL_AUDIO_DRIVER=dummy` so the vendor GPU stack is never loaded — that removes thousands of unfixable findings inside the driver without suppressing anything. Definite leaks, invalid accesses and uninitialised reads are counted and set the exit status; "still reachable" is not, because that is what SDL and FreeType keep for the process lifetime. Suppressions for genuine third-party findings are in `scripts/valgrind.supp`. What it found the first time it ran is in `TODO.md` under **Memory checking**. + +## What is compiled in, and the notice it carries + +**[libccd](https://github.com/danfis/libccd) is compiled into `libakgl.so`.** It is the +collision narrowphase -- GJK, EPA and MPR, the same code vendored in ODE, FCL and Bullet -- +and it is **BSD-3-Clause**. Its licence is `deps/libccd/BSD-LICENSE`, and `cmake --install` +puts a copy at `share/doc/akgl/BSD-LICENSE.libccd`. If you redistribute a binary built from +this tree, that notice has to travel with it. + +It is the only dependency in that position. SDL3, SDL3_image, SDL3_mixer, SDL3_ttf, jansson, +libakerror and libakstdlib are all linked as separate shared objects and carry their own +notices; `deps/semver` is a single header, MIT, installed alongside ours; and `deps/tg` is +vendored but **compiled into nothing** -- see `TODO.md`, "tg is vendored and has no +consumer". + +libccd is given a static arena rather than the allocator it ships with, so "libakgl does not +call `malloc` at runtime" stays literally true with it linked in. That is +`src/collision_arena.c`, and [Chapter 15](docs/15-collision.md) explains why. diff --git a/TODO.md b/TODO.md index ae792f1..1bed944 100644 --- a/TODO.md +++ b/TODO.md @@ -2517,3 +2517,37 @@ follow that are true today and would not survive a change: from a caller who has explicitly asked for EPA's manifold. `akgl_ccd_arena_highwater()` is public so a game can assert its own ceiling. + +## The `util.h` rectangle helpers stay, and why + +The collision plan's last step was to **delete `akgl_rectangle_points`, +`akgl_collide_point_rectangle` and `akgl_collide_rectangles`** once the shape API +landed, on the grounds that collision now has a real narrowphase. That step was +not taken, and this is the reasoning rather than an oversight. + +- **They still have callers that are correct.** `examples/sidescroller/player.c` + uses `akgl_collide_rectangles` twice, for coins and for hazards. Those are + overlap *questions* asked from an `updatefunc` -- "am I touching this" -- and + the right answer is a `bool`. Routing them through a collision shape would + mean a proxy, a broad-phase insert and a narrowphase call to compute a normal + and a depth that nothing reads. +- **`akgl_collide_rectangles` was fixed in this same series**, not left broken. + It was a corner test that missed the cross case and truncated through + `akgl_Point`'s `int` members; it is a span test now, exact in `float32_t`. + Deleting it two commits after fixing it is a strange thing to do to a caller. +- **A game-level overlap question is not always a physics question.** A minimap + marker, a UI hit test, "is the cursor over this". None of those wants to be + pushed, and none of them belongs in a collision world. + +`akgl_rectangle_points` and `akgl_collide_point_rectangle` are the weaker case: +nothing outside `tests/` calls either, and `akgl_collide_rectangles` no longer +does since it stopped working corner by corner. They are kept for symmetry with +the one that is used and because a point-in-rectangle test is the other half of +the same question -- but if a 0.9.0 wants to trim the public surface, those two +are the candidates, not `akgl_collide_rectangles`. + +One thing found while writing this and fixed rather than recorded: +`akgl_RectanglePoints`' Doxygen comment still said `akgl_collide_rectangles` +"works corner by corner rather than by comparing edge spans", which had been +false since the fix. [Chapter 19](docs/19-utilities.md) already described the +current behaviour correctly, so the header was the only place saying otherwise. diff --git a/include/akgl/util.h b/include/akgl/util.h index 19ef1cb..64c3e12 100644 --- a/include/akgl/util.h +++ b/include/akgl/util.h @@ -30,9 +30,13 @@ typedef struct akgl_Point { /** * @brief The four corners of an axis-aligned rectangle, precomputed. * - * akgl_collide_rectangles works corner by corner rather than by comparing edge - * spans, so it wants the corners as points. akgl_rectangle_points derives one of - * these from an `SDL_FRect`. + * The form akgl_collide_point_rectangle wants. akgl_rectangle_points derives one + * of these from an `SDL_FRect`. + * + * @note akgl_collide_rectangles used to be built on this, corner by corner, and + * missed the cross case that way -- two rectangles overlapping in a plus + * sign have no corner of either inside the other. It compares edge spans + * in `float32_t` since 0.8.0 and does not go through here at all. */ typedef struct akgl_RectanglePoints { akgl_Point topleft; /**< (x, y). */