Skip to content

Latest commit

 

History

History
203 lines (155 loc) · 6.15 KB

File metadata and controls

203 lines (155 loc) · 6.15 KB

NativeGLBImporter ECS Integration

The NativeGLBImporter is now fully integrated into the ECS system! This provides:

  • Direct GLB loading - No conversion to .scn files
  • Automatic collider separation - Meshes with "collider" in their name become physics bodies
  • Thread-based loading - Non-blocking, smooth performance
  • Chunked instance creation - No frame drops even with large models
  • PBR material support - Extracts metallic, roughness, emission, and textures

How It Works

Before (Legacy Mode):

GltfContainer → ConvertingGLB (GlbImporter) → RequestingLoad → LoadingThreaded
→ ExtractingMeshes → CreatingInstances → Loaded

Now (Native Mode - DEFAULT):

GltfContainer → LoadingNativeGLB (NativeGLBImporter) → CreatingInstances → Loaded

Much faster and simpler!

Usage

Automatic Integration

The NativeGLBImporter is enabled by default! Just use GltfContainer as before:

# In GDScript
var entity_id = 100
scene_manager.create_entity(entity_id)
scene_manager.put_transform(entity_id, Vector3.ZERO, Quaternion.IDENTITY, Vector3.ONE, 0)
scene_manager.put_gltf_container(entity_id, "res://models/my_model.glb")
// In Rust
world.start_gltf_load(entity, "res://models/my_model.glb".to_string());

That's it! The system will automatically:

  1. Load the GLB in a background thread
  2. Parse meshes and materials directly from GLB
  3. Separate colliders - Any mesh with "collider" in its name
  4. Create RenderingServer instances for visual meshes (chunked)
  5. Create PhysicsServer bodies for collider shapes (chunked)

Collider Mesh Naming Convention

To create physics colliders, name your meshes in Blender/your 3D tool with "collider" anywhere in the name:

  • building_visual → Visual mesh (rendered)
  • building_collider → Collider shape (physics only, not rendered)
  • floor_mesh_collider → Collider shape
  • wall_COLLIDER_01 → Collider shape (case-insensitive)

The system automatically:

  • Creates ConcavePolygonShape3D for each collider mesh
  • Creates a static PhysicsBody3D in PhysicsServer
  • Sets the correct transform
  • Keeps shape resources alive

Demo

Run the ECS demo to see it in action:

# 1. Make sure the Rust library is compiled
cd rust && cargo build

# 2. Restart Godot to load the new library
# (Important! Godot needs to reload the .dll/.so/.dylib)

# 3. Open and run the demo scene
godot/demos/ecs_demo.tscn

You should see:

🚀 Starting native GLB load for entity 5000: res://models/agora.glb
✅ Native GLB loaded for entity 5000: 15 meshes, 3 colliders
  ✅ All instances and colliders created for entity 5000

Performance

The NativeGLBImporter is optimized for performance:

  • Chunked creation: Creates 50 instances per frame by default
  • Thread-based parsing: GLB parsing happens in background thread
  • Direct RenderingServer: Bypasses scene tree for maximum performance
  • Resource pooling: Keeps mesh and shape resources alive efficiently

You can adjust the chunk size:

// In Rust
if let Some(loading_data) = world.get_gltf_loading_data_mut(&entity) {
    loading_data.instances_per_frame = 100; // Create 100 per frame
}

Legacy Mode

If you need to use the old GlbImporter (for debugging or comparison), you can enable it:

// In Rust - modify world.rs
impl GltfLoadingData {
    pub fn new(path: String) -> Self {
        Self::new_with_mode(path, false) // false = use legacy GlbImporter
    }
}

Architecture

Files Modified:

  1. rust/src/systems/ecs/world.rs

    • Added LoadingNativeGLB state
    • Added native_importer: Option<NativeGlbImporter>
    • Added collider support fields
    • Added shape_resources to EntityPhysicsState
  2. rust/src/systems/ecs_systems/gltf_loading_system.rs

    • Added poll_native_glb_loading() function
    • Updated create_instances_chunked() to handle colliders
    • Transfers mesh and shape resources to entity states

Data Flow:

1. GltfContainer component added to entity
   ↓
2. ECS calls world.start_gltf_load(entity, path)
   ↓
3. Creates GltfLoadingData with NativeGlbImporter
   ↓
4. State = LoadingNativeGLB
   ↓
5. poll_native_glb_loading() called each frame:
   - Calls importer.process() (creates resources in chunks)
   - When complete, extracts visual meshes and colliders
   - Transitions to CreatingInstances state
   ↓
6. create_instances_chunked() called each frame:
   - Creates RenderingServer instances (visual meshes)
   - Creates PhysicsServer bodies (colliders)
   - Transfers resources to EntityRenderState/EntityPhysicsState
   ↓
7. State = Loaded

Troubleshooting

Models not loading?

  1. Restart Godot - The Rust library needs to be reloaded after compilation
  2. Check paths - Use res:// paths, not absolute paths
  3. Check console - Look for "🚀 Starting native GLB load" messages

Still seeing legacy GlbImporter?

  • Restart Godot to reload the newly compiled library
  • Check that GltfLoadingData::new() calls new_with_mode(path, true)

Colliders not working?

  • Check mesh names contain "collider" (case-insensitive)
  • Verify the GLB has triangle data (not just points/lines)
  • Check console for "X meshes, Y colliders" message

Future Enhancements

Potential improvements:

  • Texture loading support
  • Convex hull collider option
  • Animation support
  • LOD (Level of Detail) support
  • Material caching
  • Mesh instancing optimization

Comparison: Legacy vs Native

Feature Legacy GlbImporter Native GlbImporter
GLB Parsing Godot's GltfDocument Native gltf crate
Conversion GLB → .scn file Direct
States 5 states 2 states
Colliders Manual AnimatableBody3D Automatic by name
Performance Slower Faster
Threading ResourceLoader threads std::thread
Dependencies Godot import system Pure Rust

Questions?

  • Check rust/src/systems/native_glb_importer.rs for implementation details
  • Check rust/src/systems/native_glb_importer_example.rs for usage examples
  • Check existing ECS tests in rust/src/systems/tests.rs