Skip to content

Conversation

@csouls
Copy link

@csouls csouls commented Jan 13, 2026

Summary

Fixes #326

  • Modified scaleBoundingBox to scale from the bounding box center instead of the origin
  • This prevents the bounding box from shifting when scaling models positioned away from the origin
  • Resolves frustum culling issues where models would disappear during camera rotation

Note

@hannojg Thanks for the suggestion! I tried to add an example to the example app, but ran into a C++ build error on Android:

error: lambda capture 'sharedFuture' is not used [-Werror,-Wunused-lambda-capture]

Looks like a pre-existing build config issue. Let me know if there's a workaround.

@hannojg
Copy link
Member

hannojg commented Jan 13, 2026

Do you have a full log of the build error you're getting?

I will test the PR on my own, but it would be really cool to see if we could get the example app working for you.

It should be "as simple as":

  • Make sure you have the git submodules initialized
  • bun install in project root
  • cd package
  • bun build-bullet3
  • bun build-filament:release (if thats taking too long you can check if setup-filament-quick is working)
  • And then you can build the example app, ie with: cd examples/AppExampleFabric, bun android)

@hannojg
Copy link
Member

hannojg commented Jan 13, 2026

thanks for the PR btw!

When a component unmounts and remounts while async resource loading is
in progress, race conditions can occur:

- useBuffer: stale Promise callbacks would call setBuffer() with
  outdated data after remount
- useDisposableResource: calling release() on stale callbacks could
  release resources still in use by the new mount, causing
  "Pointer has already been manually released!" errors

This commonly happens with:
- Fast navigation (navigating away before loading completes)
- Fast Refresh / Hot Reload during development
- Conditional rendering with rapid state changes
- React StrictMode (which double-mounts components in development)

Changes:
- Add token-based invalidation to useDisposableResource to ignore
  stale Promise callbacks from previous mounts
- Don't call release() on stale callbacks - let GC handle cleanup
  via C++ shared_ptr preventing memory leaks
- Add releaseOnUnmount option for explicit resource lifecycle control
- Refactor useBuffer to use useDisposableResource (removes duplication)
@csouls
Copy link
Author

csouls commented Jan 15, 2026

@hannojg Thanks! Looks like I forgot to run git submodule update. Sorry for the beginner mistake!
While developing the example app, I also found issues with useBuffer and useDisposableResource, so I'll suggest fixes for those as well.

@csouls csouls marked this pull request as draft January 15, 2026 06:06
@csouls csouls force-pushed the fix/scale-bounding-box-from-center branch from 4f36844 to 211c9ea Compare January 15, 2026 06:14
Add example screen to verify frustum culling behavior with scaleBoundingBox:

- FrustumCulling.tsx: Interactive test with model and scale selection
- hiphopgirl_offset.glb: Test model with mesh vertices baked at X=100
  (world position X≈1 after Armature scale 0.01)

Test behavior with offset model:
- 1x, 2x scale: Model displays correctly
- 5x+ scale: Model disappears due to bounding box center shift
  (demonstrates the bug that scaling from center fixes)

Features:
- Model type selection (Normal / Offset)
- Scale factor selection (1x to 1000x)
- Back button to return to settings
Previously, scaleBoundingBox multiplied min/max by scaleFactor, which
shifted the bounding box center away from the model when the model
was not at the origin.

Now scales from center by:
1. Computing the bounding box center
2. Scaling the half-extent by scaleFactor
3. Reconstructing min/max from center ± scaledHalfExtent

This preserves the bounding box position relative to the model,
ensuring frustum culling works correctly for offset models.
@csouls csouls force-pushed the fix/scale-bounding-box-from-center branch from 211c9ea to 28aab32 Compare January 15, 2026 08:08
@csouls csouls marked this pull request as ready for review January 15, 2026 08:13
@csouls
Copy link
Author

csouls commented Jan 15, 2026

@hannojg

Added a few more changes:

FrustumCulling Example

  • Added example screen to test scaleBoundingBox behavior
  • Offset model (1x-2x visible, 5x+ disappears) demonstrates the bug

StrictMode Race Condition Fix

  • Added token system to useModel to prevent stale async cleanup on remount

Should I move the useBuffer/useDisposableResources fixes to a separate PR?

@hannojg
Copy link
Member

hannojg commented Jan 15, 2026

hey, thanks for taking the time and the awesome fixes!

Actually i will leave this up to you 😊
If you separate it in two PRs it will appear as two changes in the changelog which is preferred.
But its also fine if you want to leave it as is, just lmk

@csouls
Copy link
Author

csouls commented Jan 15, 2026

The example app depends on the useBuffer/useDisposableResources fixes - without them, the model doesn't load correctly in StrictMode. So it would be great to keep them in this PR if possible!

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.

Bug: scaleBoundingBox scales from origin instead of center

2 participants