6.3 KiB
Buoyancy System Analysis and Debugging Guide
Problem Analysis
After analyzing the buoyancy system in src/features/editScene, I identified several key issues why characters are not affected by buoyancy:
1. Broadphase Query Area Not Following Camera
The original buoyancy system used a fixed position (0, waterSurfaceY, 0) for the broadphase query AABox. This meant the water detection area was static at world origin, not following the camera or characters.
Fix Applied: Modified BuoyancySystem::update() to use camera XZ position with water Y position:
Ogre::Vector3 waterSurfacePos(m_cameraPosition.x, waterPhysics->waterSurfaceY, m_cameraPosition.z);
2. Character Physics Layer Issue
Characters are created with Layers::MOVING but the broadphase query in physics.cpp was checking for bodies in specific layers. The query needs to include the MOVING layer.
Fix Applied: Updated broadphaseQuery in physics.cpp to include Layers::MOVING:
if (body->GetMotionType() == JPH::EMotionType::Dynamic &&
(body->GetObjectLayer() == Layers::MOVING ||
body->GetObjectLayer() == Layers::NON_MOVING)) {
3. Character Gravity Factor Management
Characters have gravity factor 0 by default (to prevent sinking into terrain). When they enter water, we need to:
- Save original gravity factor
- Set gravity factor to 1.0 to allow sinking
- Restore original gravity when leaving water
Fix Applied: Added gravity factor caching in BuoyancySystem:
// Save original gravity factor if not already saved
if (m_characterOriginalGravity.find(bodyID) == m_characterOriginalGravity.end()) {
m_characterOriginalGravity[bodyID] = m_physics->getGravityFactor(bodyID);
}
// Enable gravity for characters in water so they sink
m_physics->setGravityFactor(bodyID, 1.0f);
4. Water AABox Size Configuration
The broadphase query uses an AABox centered at water surface position with size (100, 10, 100). This may need adjustment based on your scene scale.
Debugging Approach
1. Enable Debug Logging
Run the editor with the --debug-buoyancy command line option:
./build/Editor --debug-buoyancy
This enables verbose logging every 60 frames (about 1 second at 60 FPS) showing:
- Water physics state (surface Y, enabled, buoyancy)
- Camera position
- Water detection center position
- All characters and their positions
- Bodies detected in water by broadphase query
- Character gravity factor cache
2. Broadphase Query Settings
The water detection area is configured in src/features/editScene/physics/physics.cpp:
// AABox for water detection (centered at water surface position)
// Box extends from (-1000, 1.0, -1000) to (1000, 1000, 1000) relative to surface
// Total size: 2000x999x2000 units
JPH::AABox water_box(-JPH::Vec3(1000, 1.0f, 1000),
JPH::Vec3(1000, 1000, 1000));
water_box.Translate(JPH::Vec3(surface_point));
Current Filter Settings:
- Only checks
Layers::MOVINGbodies (line 1587) - Uses
BroadPhaseLayers::MOVINGfilter (line 1586)
Adjustment Recommendations:
- Check character layer: Ensure characters are in
Layers::MOVING - Adjust box size: The current 2000x999x2000 box is very large
- Reduce 1000 values for smaller detection area
- Adjust Y values (1.0f and 1000) for vertical detection range
- Add NON_MOVING layer: If characters are in NON_MOVING layer, update filter:
JPH::SpecifiedObjectLayerFilter(Layers::MOVING | Layers::NON_MOVING) - Box follows camera: The box is translated to
surface_pointwhich now uses camera XZ position
3. Water Physics Configuration
Default water settings (in EditorApp::createDefaultEntities()):
waterSurfaceY = -0.1f(just below ground level)defaultBuoyancy = 1.0f(neutral buoyancy)defaultLinearDrag = 0.1fdefaultAngularDrag = 0.05fgravity = 9.81f
To adjust: Use the Water Physics editor UI or modify the WaterPhysics component.
4. Character Configuration
Ensure characters:
- Have
CharacterComponentattached - Are in the
MOVINGphysics layer - Have proper collision shapes
- Are spawned at Y position below water surface for testing
Testing Procedure
- Build the project:
cmake --build build --target Editor
- Run with debug mode:
./build/Editor --debug-buoyancy
-
Create test scene:
- Add water (WaterPhysics entity exists by default)
- Spawn characters (use Character spawner in UI)
- Position characters below water surface (Y < -0.1)
-
Monitor console output for debug messages showing:
- "Bodies in water (broadphase): X"
- Character positions and "inWater" status
- Gravity factor changes
-
Adjust settings as needed:
- Increase water surface Y if characters are above water
- Adjust AABox size in physics.cpp
- Modify buoyancy/drag coefficients
Key Code Changes Made
-
BuoyancySystem.cpp/hpp:
- Added camera position tracking
- Added gravity factor caching for characters
- Added debug logging system
- Fixed broadphase query position
-
physics.cpp:
- Fixed broadphase query to include MOVING layer
- Ensured character bodies are detected
-
EditorApp.cpp/hpp:
- Added
--debug-buoyancycommand line option - Added
setDebugBuoyancy()method - Updated camera position to buoyancy system each frame
- Added
-
EditorCamera.hpp:
- Added
getPosition()method
- Added
-
main.cpp:
- Added command line argument parsing for
--debug-buoyancy
- Added command line argument parsing for
Expected Behavior After Fixes
- Characters should sink into water (gravity enabled)
- Buoyancy forces should push characters upward
- Debug logs should show bodies detected in water
- Character gravity should be restored when leaving water
- Water detection area should follow camera movement
Troubleshooting
If characters still aren't affected:
- Check debug logs: Ensure bodies are being detected
- Verify water surface Y: Characters must be below this value
- Check physics layers: Characters should be in MOVING layer
- Test with simple objects: Create a simple box to verify buoyancy works
- Adjust AABox size: Increase detection area if characters are far from camera
The system is now properly configured to detect characters in water and apply buoyancy forces with comprehensive debugging capabilities.