Skip to content

joltc-sys: derive Default for JPC_PlaneShapeSettings (depends on JoltC#25)#14

Open
Solidor777 wants to merge 3 commits into
SecondHalfGames:mainfrom
Solidor777:plane-shape-default
Open

joltc-sys: derive Default for JPC_PlaneShapeSettings (depends on JoltC#25)#14
Solidor777 wants to merge 3 commits into
SecondHalfGames:mainfrom
Solidor777:plane-shape-default

Conversation

@Solidor777
Copy link
Copy Markdown
Contributor

Depends on SecondHalfGames/JoltC#25, which adds the C-side JPC_PlaneShapeSettings + _default exports.

This PR is one line — add JPC_PlaneShapeSettings -> JPC_PlaneShapeSettings_default to the ffi_default! list in joltc-sys/src/lib.rs so the new shape gets the same struct-update idiom every other ShapeSettings has:

let settings = JPC_PlaneShapeSettings {
    Normal: JPC_Vec3 { x: 0.0, y: 1.0, z: 0.0, _w: 0.0 },
    ..Default::default()
};

Stacking

Filed on top of #12 + #13 (Android + iOS cross-compile) so the diff against main is bigger than the actual change. The relevant added line is the only one outside the iOS / Android branches.

If #12 and #13 merge first this PR auto-shrinks to the single-line diff above. If a maintainer prefers, the line is trivial to cherry-pick onto a fresh PR.

Test plan

  • Compiles against the new JoltC#25 binding.
  • Round-trip: JPC_PlaneShapeSettings::default() returns the same field values as JPC_PlaneShapeSettings_default() writes (Normal=+Y, Constant=0, HalfExtent=cDefaultHalfExtent).
  • Used end-to-end in Titan engine's titan-jolt-3d; new integration test (halfspace_authors_non_y_normal) raycasts a +X-normal halfspace and asserts the surface normal returned by Jolt matches.

Solidor777 added 3 commits May 8, 2026 02:39
Two coupled bugs surfaced when cross-compiling joltc-sys to
Android (aarch64-linux-android via NDK r26d clang from a Windows
host):

1. `cfg!(windows)` is a HOST-OS check inside build.rs. When
   targeting Android from Windows, the conditional always fires
   and adds the MSVC-only `/EHsc` flag to the cmake config — NDK
   clang then receives `/EHsc` as a path argument and errors out
   ("error: no such file or directory: '/EHsc'").

   Fix: read `CARGO_CFG_TARGET_OS` and only add `/EHsc` when the
   actual target is windows.

2. Building for Android requires three CMake-side hints that
   joltc-sys does not currently set: `CMAKE_TOOLCHAIN_FILE`
   (NDK's `android.toolchain.cmake`), `ANDROID_ABI` (string the
   toolchain reads — env var alone is ignored), and the
   generator (Ninja, since cmake-rs defaults to MSBuild on
   Windows hosts).

   Fix: when `target_os == "android"`, derive ANDROID_ABI from
   `CARGO_CFG_TARGET_ARCH` (aarch64 → arm64-v8a, arm →
   armeabi-v7a, etc.), look up the NDK at
   `ANDROID_NDK_HOME` / `ANDROID_NDK_ROOT` / `ANDROID_NDK`,
   and force Ninja.

End-user contract after this change: set ANDROID_NDK_HOME,
run `cargo ndk --target aarch64-linux-android check -p joltc-sys`.
The standard cargo-ndk + nttld/setup-ndk@v1 flow Just Works.

Validated locally on Windows-host → aarch64-linux-android with
NDK r26d (full JoltPhysics + JoltC compiles in ~20s). 32-bit ARM
(armv7-linux-androideabi) hits an unrelated upstream JoltC
LAYOUT_COMPATIBLE static_assert (`JPC_*Settings` 16-byte
alignment vs `JPH::*Settings` 8-byte alignment on 32-bit ARM)
that this PR does not address.
Adds an iOS branch alongside the Android branch from SecondHalfGames#12. Covers both
`aarch64-apple-ios` (device) and `aarch64-apple-ios-sim` (simulator on
Apple Silicon hosts); `x86_64-apple-ios` is the legacy Intel-Mac
simulator path. From a macOS host:

```sh
cargo check --target aarch64-apple-ios -p joltc-sys
cargo check --target aarch64-apple-ios-sim -p joltc-sys
```

Both succeed with no extra env-var setup.

## Two coupled fixes

1. **`build_joltc()` iOS branch.** Sets `CMAKE_SYSTEM_NAME=iOS`,
   `CMAKE_OSX_SYSROOT` (`iphoneos` for device vs `iphonesimulator` for
   simulator, distinguished via `CARGO_CFG_TARGET_ABI=sim`),
   `CMAKE_OSX_ARCHITECTURES` from `target_arch`, and
   `CMAKE_OSX_DEPLOYMENT_TARGET=12.0`. Forces Ninja so the build is
   generator-agnostic on macos CI runners.

2. **`generate_bindings()` clang-target translation.** bindgen passes
   rustc's TARGET to clang verbatim. rustc's iOS-simulator triple
   `aarch64-apple-ios-sim` is invalid clang syntax — clang errors with
   `version 'sim' in target triple is invalid`. Translate to clang's
   recognised form (`arm64-apple-ios-simulator` for sim, `arm64-apple-ios`
   for device) and supply the matching SDK sysroot via `xcrun
   --show-sdk-path` so iOS system headers (stdint.h, etc.) resolve.

## Validation

- `cargo check --target aarch64-apple-ios -p joltc-sys` on macOS host
  (Xcode 16.4, iPhoneOS 18.5 SDK): succeeds.
- `cargo check --target aarch64-apple-ios-sim -p joltc-sys`: succeeds.
- Downstream Titan engine's `titan-jolt-3d` builds against both iOS
  targets in CI on `macos-latest`.
- Desktop targets unaffected (iOS branch gated on `target_os == "ios"`).

## Stacking note

This PR is stacked on SecondHalfGames#12 (`android-cross-compile-and-target-os-fix`)
to share the host-vs-target awareness scaffolding. Either PR can merge
first — the iOS branch is a strict additive layer.
Once SecondHalfGames/JoltC#25 lands, PlaneShape gets a JPC_*Settings
struct + matching _default initializer. Add it to the ffi_default!
list so consumers can use the same struct-update idiom they use for
every other ShapeSettings:

    let settings = JPC_PlaneShapeSettings {
        Normal: JPC_Vec3 { x: 0.0, y: 1.0, z: 0.0, _w: 0.0 },
        ..Default::default()
    };

This PR is stacked on SecondHalfGames#12 + SecondHalfGames#13 (Android + iOS cross-compile) but only
adds one line; it can be cherry-picked onto main once those land or
left on the stack.
Solidor777 added a commit to Solidor777/Titan that referenced this pull request May 8, 2026
m34-a-ii shipped Halfspace as a 100×0.05×100 thin static box because
JoltC didn't expose JPH's PlaneShape. The authored normal was ignored;
raycasts returned axis-aligned box-face normals; rotated halfspaces
silently used the ground approximation.

Bumps the Solidor777/JoltC submodule to 3eddf05, which adds a TITAN
PATCH exposing `JPC_PlaneShapeSettings` + `_default` + `_Create`
following the existing BoxShape/SphereShape pattern. Companion one-line
patch on `crates/third_party/joltc-sys/src/lib.rs` adds the new shape
to the `ffi_default!` list so `JPC_PlaneShapeSettings::default()` works
from rust.

`titan-jolt-3d`'s `BodyShape::Halfspace { normal }` arm now constructs
a real `PlaneShape` with the authored normal as the plane's outward
direction and `Constant = 0` (plane through body-local origin). Module
docs updated.

New regression test `halfspace_authors_non_y_normal` raycasts a +X-
normal halfspace and asserts:
- ray distance lands on the plane (5 m for a 5 m offset along the
  authored normal)
- raycast surface normal returned by Jolt matches the authored normal
  (dot with +X > 0.95). The thin-box approx returned (0, ±1, 0) here.

Existing `dynamic_body_rests_on_static_ground` updated: the ball now
settles at y ≈ radius (0.4..0.6) instead of radius + box-half-extent
(0.4..0.7) since the plane is exactly at y=0.

508 tests pass (was 507). Smoke-launched: editor reaches `boot
complete` cleanly.

Upstream PRs: [SecondHalfGames/JoltC#25](SecondHalfGames/JoltC#25)
+ [SecondHalfGames/jolt-rust#14](SecondHalfGames/jolt-rust#14).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Solidor777 added a commit to Solidor777/Titan that referenced this pull request May 17, 2026
m34-a-ii shipped Halfspace as a 100×0.05×100 thin static box because
JoltC didn't expose JPH's PlaneShape. The authored normal was ignored;
raycasts returned axis-aligned box-face normals; rotated halfspaces
silently used the ground approximation.

Bumps the Solidor777/JoltC submodule to 3eddf05, which adds a TITAN
PATCH exposing `JPC_PlaneShapeSettings` + `_default` + `_Create`
following the existing BoxShape/SphereShape pattern. Companion one-line
patch on `crates/third_party/joltc-sys/src/lib.rs` adds the new shape
to the `ffi_default!` list so `JPC_PlaneShapeSettings::default()` works
from rust.

`titan-jolt-3d`'s `BodyShape::Halfspace { normal }` arm now constructs
a real `PlaneShape` with the authored normal as the plane's outward
direction and `Constant = 0` (plane through body-local origin). Module
docs updated.

New regression test `halfspace_authors_non_y_normal` raycasts a +X-
normal halfspace and asserts:
- ray distance lands on the plane (5 m for a 5 m offset along the
  authored normal)
- raycast surface normal returned by Jolt matches the authored normal
  (dot with +X > 0.95). The thin-box approx returned (0, ±1, 0) here.

Existing `dynamic_body_rests_on_static_ground` updated: the ball now
settles at y ≈ radius (0.4..0.6) instead of radius + box-half-extent
(0.4..0.7) since the plane is exactly at y=0.

508 tests pass (was 507). Smoke-launched: editor reaches `boot
complete` cleanly.

Upstream PRs: [SecondHalfGames/JoltC#25](SecondHalfGames/JoltC#25)
+ [SecondHalfGames/jolt-rust#14](SecondHalfGames/jolt-rust#14).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Solidor777 added a commit to Solidor777/Titan that referenced this pull request Jun 4, 2026
m34-a-ii shipped Halfspace as a 100×0.05×100 thin static box because
JoltC didn't expose JPH's PlaneShape. The authored normal was ignored;
raycasts returned axis-aligned box-face normals; rotated halfspaces
silently used the ground approximation.

Bumps the Solidor777/JoltC submodule to 3eddf05, which adds a TITAN
PATCH exposing `JPC_PlaneShapeSettings` + `_default` + `_Create`
following the existing BoxShape/SphereShape pattern. Companion one-line
patch on `crates/third_party/joltc-sys/src/lib.rs` adds the new shape
to the `ffi_default!` list so `JPC_PlaneShapeSettings::default()` works
from rust.

`titan-jolt-3d`'s `BodyShape::Halfspace { normal }` arm now constructs
a real `PlaneShape` with the authored normal as the plane's outward
direction and `Constant = 0` (plane through body-local origin). Module
docs updated.

New regression test `halfspace_authors_non_y_normal` raycasts a +X-
normal halfspace and asserts:
- ray distance lands on the plane (5 m for a 5 m offset along the
  authored normal)
- raycast surface normal returned by Jolt matches the authored normal
  (dot with +X > 0.95). The thin-box approx returned (0, ±1, 0) here.

Existing `dynamic_body_rests_on_static_ground` updated: the ball now
settles at y ≈ radius (0.4..0.6) instead of radius + box-half-extent
(0.4..0.7) since the plane is exactly at y=0.

508 tests pass (was 507). Smoke-launched: editor reaches `boot
complete` cleanly.

Upstream PRs: [SecondHalfGames/JoltC#25](SecondHalfGames/JoltC#25)
+ [SecondHalfGames/jolt-rust#14](SecondHalfGames/jolt-rust#14).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant