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
GltfContainer → ConvertingGLB (GlbImporter) → RequestingLoad → LoadingThreaded
→ ExtractingMeshes → CreatingInstances → Loaded
GltfContainer → LoadingNativeGLB (NativeGLBImporter) → CreatingInstances → Loaded
Much faster and simpler!
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:
- Load the GLB in a background thread
- Parse meshes and materials directly from GLB
- Separate colliders - Any mesh with "collider" in its name
- Create RenderingServer instances for visual meshes (chunked)
- Create PhysicsServer bodies for collider shapes (chunked)
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 shapewall_COLLIDER_01→ Collider shape (case-insensitive)
The system automatically:
- Creates
ConcavePolygonShape3Dfor each collider mesh - Creates a static
PhysicsBody3Din PhysicsServer - Sets the correct transform
- Keeps shape resources alive
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.tscnYou 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
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
}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
}
}-
rust/src/systems/ecs/world.rs- Added
LoadingNativeGLBstate - Added
native_importer: Option<NativeGlbImporter> - Added collider support fields
- Added
shape_resourcestoEntityPhysicsState
- Added
-
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
- Added
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
- Restart Godot - The Rust library needs to be reloaded after compilation
- Check paths - Use
res://paths, not absolute paths - Check console - Look for "🚀 Starting native GLB load" messages
- Restart Godot to reload the newly compiled library
- Check that
GltfLoadingData::new()callsnew_with_mode(path, true)
- 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
Potential improvements:
- Texture loading support
- Convex hull collider option
- Animation support
- LOD (Level of Detail) support
- Material caching
- Mesh instancing optimization
| 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 |
- Check
rust/src/systems/native_glb_importer.rsfor implementation details - Check
rust/src/systems/native_glb_importer_example.rsfor usage examples - Check existing ECS tests in
rust/src/systems/tests.rs