Skip to content

Commit a0080d6

Browse files
committed
feat: dummy plugin
1 parent 7f9fbe5 commit a0080d6

File tree

8 files changed

+794
-1
lines changed

8 files changed

+794
-1
lines changed

EDITOR_PLUGIN_USAGE.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Editor Import Plugin Usage
2+
3+
This guide explains how to use the LeagueToolkit Editor Import Plugin in Godot 4.
4+
5+
## What is an EditorImportPlugin?
6+
7+
An `EditorImportPlugin` allows Godot to automatically recognize and import custom file formats when you drag them into your project. Unlike manual loaders, the import plugin integrates seamlessly with Godot's asset pipeline.
8+
9+
## Installation
10+
11+
1. Copy the entire `ltk-godot` directory into your Godot project
12+
2. The `ltk_godot.gdextension` file tells Godot where to find the native library
13+
3. Ensure you have built the extension (see the main README for build instructions)
14+
15+
## Enabling the Plugin
16+
17+
To enable the import plugin in the Godot editor:
18+
19+
1. Open your project in Godot 4
20+
2. Go to `Project > Project Settings > Plugins`
21+
3. Find "LeagueToolkit Importer" in the list
22+
4. Check the box to enable it
23+
24+
You should see console output indicating the plugin has been loaded and import plugins registered.
25+
26+
## Supported File Formats
27+
28+
### Mesh Files
29+
- **Extensions**: `.skn`, `.scb`, `.sco`
30+
- **Imports as**: Godot Mesh resource
31+
- **Import Options**:
32+
- `scale`: Scale factor for the mesh (default: 1.0)
33+
- `generate_normals`: Generate normals if not present (default: false)
34+
- `generate_tangents`: Generate tangents for normal mapping (default: true)
35+
36+
### Texture Files
37+
- **Extensions**: `.tex`
38+
- **Imports as**: CompressedTexture2D
39+
- **Import Presets**:
40+
- **2D Texture**: Default preset for 2D textures with sRGB enabled
41+
- **3D Texture**: Preset for 3D textures with sRGB disabled
42+
- **Import Options**:
43+
- `compress/mode`: Compression mode (Lossless, Lossy, or Uncompressed)
44+
- `mipmaps/generate`: Generate mipmaps for LOD (default: true)
45+
- `process/srgb`: Use sRGB color space (default: true for 2D preset)
46+
- `process/fix_alpha_border`: Fix alpha borders to prevent seams (default: true)
47+
- `process/normal_map`: Treat as normal map (default: false)
48+
49+
## Using Imported Assets
50+
51+
### Automatic Import
52+
53+
Simply drag and drop your League of Legends asset files into your Godot project:
54+
55+
1. Open the FileSystem panel in Godot
56+
2. Drag `.skn`, `.scb`, `.sco`, or `.tex` files into your project
57+
3. Godot will automatically detect and import them using the appropriate plugin
58+
4. The imported resources will have a `.import` file generated alongside them
59+
60+
### Configuring Import Settings
61+
62+
1. Select the imported file in the FileSystem panel
63+
2. The Import dock will appear (usually on the left side)
64+
3. Adjust the import options as needed
65+
4. Click "Reimport" to apply the changes
66+
67+
### Using in Scenes
68+
69+
Once imported, you can use the resources just like any other Godot asset:
70+
71+
```gdscript
72+
# For meshes
73+
var mesh_instance = MeshInstance3D.new()
74+
mesh_instance.mesh = load("res://path/to/your/model.skn")
75+
add_child(mesh_instance)
76+
77+
# For textures
78+
var sprite = Sprite2D.new()
79+
sprite.texture = load("res://path/to/your/texture.tex")
80+
add_child(sprite)
81+
```
82+
83+
## Current Implementation Status
84+
85+
⚠️ **Note**: The import plugins are currently set up with placeholder implementations. The actual file parsing and conversion using `league-toolkit` needs to be implemented.
86+
87+
**TODO for full functionality**:
88+
- Implement mesh parsing using `league-toolkit`'s mesh module
89+
- Convert League mesh data to Godot's `ArrayMesh` format
90+
- Implement texture parsing using `league-toolkit`'s texture module
91+
- Convert League texture data to Godot's `Image` format
92+
- Add proper error handling and validation
93+
- Implement resource saving using Godot's `ResourceSaver`
94+
95+
## Troubleshooting
96+
97+
### Plugin not appearing in the Plugins list
98+
- Ensure the extension is built (`cargo build` or `cargo build --release`)
99+
- Check that the `.gdextension` file is in the project root
100+
- Verify that the library path in `.gdextension` matches your build output
101+
102+
### Import fails with errors
103+
- Check the Godot console for error messages
104+
- Ensure the source file is a valid League of Legends asset
105+
- Try adjusting import settings
106+
107+
### Changes not taking effect
108+
- Make sure to click "Reimport" after changing settings
109+
- Try cleaning the `.godot/imported` directory and reimporting
110+
111+
## Manual Loaders (Alternative)
112+
113+
If you prefer manual control over loading, the extension also provides loader classes:
114+
115+
```gdscript
116+
# Manual mesh loading
117+
var mesh_loader = MeshLoader.new()
118+
mesh_loader.load("res://path/to/model.skn")
119+
120+
# Manual texture loading
121+
var texture_loader = TextureLoader.new()
122+
texture_loader.load("res://path/to/texture.tex")
123+
```
124+
125+
However, using the EditorImportPlugin provides better integration with Godot's workflow.
126+

IMPLEMENTATION_GUIDE.md

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
# Implementation Guide
2+
3+
This guide is for developers who want to implement the actual file parsing and conversion logic for the EditorImportPlugins.
4+
5+
## Current Status
6+
7+
The EditorImportPlugin infrastructure is complete and functional. The plugins are registered with Godot and will be called when the appropriate file types are added to a project. However, the actual file parsing and conversion is not yet implemented - the `import()` methods currently return `Error::OK` without doing any actual work.
8+
9+
## What Needs to be Implemented
10+
11+
### 1. Mesh Importer (`src/importers/mesh_importer.rs`)
12+
13+
The `import()` method needs to:
14+
15+
1. **Read the source file**
16+
```rust
17+
// Use league-toolkit to parse the mesh file
18+
use league_toolkit::mesh::{Skn, Scb, Sco};
19+
20+
// Determine file type from extension
21+
let extension = source_file.to_string().split('.').last().unwrap();
22+
let mesh_data = match extension {
23+
"skn" => parse_skn_file(&source_file),
24+
"scb" => parse_scb_file(&source_file),
25+
"sco" => parse_sco_file(&source_file),
26+
_ => return Error::ERR_FILE_UNRECOGNIZED,
27+
};
28+
```
29+
30+
2. **Convert to Godot's ArrayMesh format**
31+
```rust
32+
use godot::classes::{ArrayMesh, Mesh as GodotMesh};
33+
use godot::builtin::VariantArray;
34+
35+
// Create ArrayMesh
36+
let mut array_mesh = ArrayMesh::new_gd();
37+
38+
// Convert mesh data to Godot arrays
39+
let mut arrays = VariantArray::new();
40+
arrays.resize(ArrayMesh::ARRAY_MAX as usize);
41+
42+
// Set vertex positions (ARRAY_VERTEX = 0)
43+
let vertices = PackedVector3Array::from(&mesh_data.vertices);
44+
arrays.set(ArrayMesh::ARRAY_VERTEX as usize, vertices.to_variant());
45+
46+
// Set normals (ARRAY_NORMAL = 1)
47+
if mesh_data.has_normals || generate_normals {
48+
let normals = calculate_or_use_normals(&mesh_data, generate_normals);
49+
arrays.set(ArrayMesh::ARRAY_NORMAL as usize, normals.to_variant());
50+
}
51+
52+
// Set UVs (ARRAY_TEX_UV = 4)
53+
let uvs = PackedVector2Array::from(&mesh_data.uvs);
54+
arrays.set(ArrayMesh::ARRAY_TEX_UV as usize, uvs.to_variant());
55+
56+
// Set indices (ARRAY_INDEX = 12)
57+
let indices = PackedInt32Array::from(&mesh_data.indices);
58+
arrays.set(ArrayMesh::ARRAY_INDEX as usize, indices.to_variant());
59+
60+
// Add surface to mesh
61+
array_mesh.add_surface_from_arrays(
62+
godot::classes::mesh::PrimitiveType::TRIANGLES,
63+
arrays,
64+
VariantArray::new(),
65+
Dictionary::new(),
66+
0
67+
);
68+
```
69+
70+
3. **Apply import options**
71+
```rust
72+
// Apply scale
73+
if scale != 1.0 {
74+
// Transform all vertices by scale factor
75+
}
76+
77+
// Generate tangents if requested
78+
if generate_tangents {
79+
array_mesh.surface_generate_tangents(0);
80+
}
81+
```
82+
83+
4. **Save the resource**
84+
```rust
85+
use godot::classes::ResourceSaver;
86+
87+
let mut resource_saver = ResourceSaver::singleton();
88+
let save_result = resource_saver.save(
89+
array_mesh.upcast(),
90+
format!("{}.{}", save_path, get_save_extension()).into()
91+
);
92+
93+
if save_result != Error::OK {
94+
godot_error!("Failed to save mesh resource: {:?}", save_result);
95+
return save_result;
96+
}
97+
```
98+
99+
### 2. Texture Importer (`src/importers/texture_importer.rs`)
100+
101+
The `import()` method needs to:
102+
103+
1. **Read and parse the texture file**
104+
```rust
105+
use league_toolkit::texture::Tex;
106+
107+
// Parse the .tex file
108+
let tex_data = match Tex::from_file(&source_file.to_string()) {
109+
Ok(tex) => tex,
110+
Err(e) => {
111+
godot_error!("Failed to parse texture: {:?}", e);
112+
return Error::ERR_FILE_CORRUPT;
113+
}
114+
};
115+
```
116+
117+
2. **Convert to Godot Image**
118+
```rust
119+
use godot::classes::{Image, ImageTexture};
120+
121+
// Create a Godot Image from the texture data
122+
let mut image = Image::new();
123+
124+
// Determine format and create image
125+
let format = match tex_data.format {
126+
// Map League texture formats to Godot formats
127+
TexFormat::DXT1 => Image::FORMAT_DXT1,
128+
TexFormat::DXT5 => Image::FORMAT_DXT5,
129+
TexFormat::RGBA8 => Image::FORMAT_RGBA8,
130+
// ... handle other formats
131+
};
132+
133+
image.create_from_data(
134+
tex_data.width as i32,
135+
tex_data.height as i32,
136+
tex_data.has_mipmaps,
137+
format,
138+
tex_data.pixel_data.into()
139+
);
140+
```
141+
142+
3. **Apply import settings**
143+
```rust
144+
// Apply sRGB
145+
if srgb {
146+
image.srgb_to_linear();
147+
}
148+
149+
// Generate mipmaps if needed
150+
if generate_mipmaps && !image.has_mipmaps() {
151+
image.generate_mipmaps();
152+
}
153+
154+
// Fix alpha border
155+
if fix_alpha_border {
156+
image.fix_alpha_edges();
157+
}
158+
159+
// Apply compression
160+
match compress_mode {
161+
0 => image.compress(Image::COMPRESS_BPTC), // Lossless
162+
1 => image.compress(Image::COMPRESS_S3TC), // Lossy
163+
2 => {}, // Uncompressed
164+
_ => {}
165+
}
166+
```
167+
168+
4. **Save the texture resource**
169+
```rust
170+
use godot::classes::ResourceSaver;
171+
172+
let mut resource_saver = ResourceSaver::singleton();
173+
let save_result = resource_saver.save(
174+
image.upcast(),
175+
format!("{}.{}", save_path, get_save_extension()).into()
176+
);
177+
```
178+
179+
## Key Godot-Rust Concepts
180+
181+
### Working with Godot File Paths
182+
183+
Godot uses `res://` paths internally. When reading files in the import plugin:
184+
185+
```rust
186+
use godot::classes::{FileAccess, DirAccess};
187+
188+
// Convert res:// path to absolute path if needed
189+
let mut file = FileAccess::open(source_file.clone(), FileAccess::READ);
190+
let bytes = file.get_buffer(file.get_length() as i32);
191+
```
192+
193+
### Error Handling
194+
195+
Always return appropriate `Error` enum values:
196+
- `Error::OK` - Success
197+
- `Error::ERR_FILE_NOT_FOUND` - File doesn't exist
198+
- `Error::ERR_FILE_CORRUPT` - File is invalid/corrupted
199+
- `Error::ERR_FILE_UNRECOGNIZED` - Unknown format
200+
- `Error::FAILED` - Generic failure
201+
202+
### Type Conversions
203+
204+
Converting Rust data to Godot types:
205+
206+
```rust
207+
// Rust Vec to PackedArray
208+
let rust_vec: Vec<Vector3> = vec![...];
209+
let godot_array = PackedVector3Array::from(&rust_vec);
210+
211+
// Godot types to Variant
212+
let variant = godot_array.to_variant();
213+
```
214+
215+
## Testing
216+
217+
To test your implementation:
218+
219+
1. Build the extension: `cargo build`
220+
2. Open a Godot project with the extension
221+
3. Enable the plugin in Project Settings
222+
4. Drop a League file into the project
223+
5. Check the console for debug output
224+
6. Verify the imported resource in the inspector
225+
226+
## Debugging Tips
227+
228+
1. Use `godot_print!()`, `godot_warn!()`, and `godot_error!()` for logging
229+
2. Check the Godot console for output
230+
3. Use `RUST_BACKTRACE=1` when running Godot from terminal
231+
4. Test with small, simple files first
232+
5. Validate that league-toolkit is parsing files correctly before converting to Godot
233+
234+
## Resources
235+
236+
- [Godot-Rust Book](https://godot-rust.github.io/book/)
237+
- [godot-rust API Docs](https://godot-rust.github.io/docs/gdext/)
238+
- [Godot ArrayMesh Documentation](https://docs.godotengine.org/en/stable/classes/class_arraymesh.html)
239+
- [Godot Image Documentation](https://docs.godotengine.org/en/stable/classes/class_image.html)
240+
- [League Toolkit Documentation](https://github.com/LeagueToolkit/league-toolkit)
241+
242+
## Next Steps
243+
244+
1. Start with the texture importer as it's generally simpler
245+
2. Implement basic file reading and parsing
246+
3. Convert to Godot Image format
247+
4. Test with various texture files
248+
5. Move on to mesh importer
249+
6. Implement vertex/normal/UV conversion
250+
7. Test with various mesh files
251+
8. Add error handling and edge cases
252+
9. Optimize performance for large files
253+

0 commit comments

Comments
 (0)