Compare commits

...
2 Commits
Author SHA1 Message Date
EIREXE 937910a800 wording fixes
CI / build-and-test (pull_request) Canceled after 5m26s
2026-09-14 15:05:21 +02:00
EIREXE 60ee58daac Add support for split .gltf and .bin files 2026-09-14 14:49:22 +02:00
2 changed files with 58 additions and 6 deletions
+2 -2
View File
@@ -739,9 +739,9 @@ fn draw_palette(
}
ui.separator();
let controls = if matches!(page, DebugMenuPage::PlayerRows(_)) {
"Mouse: choose Arrows/WASD: select/change Escape/B: back"
"Arrows/WASD: select/change Escape/B: back"
} else {
"Mouse: activate Arrows/WASD: select Enter/A: activate Escape/B: back"
"Arrows/WASD: select Enter/A: activate Escape/B: back"
};
ui.label(controls);
});
+56 -4
View File
@@ -517,6 +517,7 @@ struct FighterBakeDeclaration {
#[derive(Asset, TypePath)]
struct FighterBakeSource {
model_bytes: Vec<u8>,
buffers: Vec<Vec<u8>>,
animations: HashMap<AnimKind, String>,
}
@@ -546,12 +547,38 @@ impl AssetLoader for FighterBakeSourceLoader {
let manifest: FighterManifest = ron::de::from_bytes(&manifest_bytes)
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
let model_path = load_context
.path()
.resolve_embed_str(&manifest.model_path)
.map_err(|error| io::Error::other(error.to_string()))?;
let model_bytes = load_context
.read_asset_bytes(&manifest.model_path)
.read_asset_bytes(model_path.clone_owned())
.await
.map_err(|error| io::Error::other(error.to_string()))?;
let gltf = gltf::Gltf::from_slice(&model_bytes)
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
let mut buffers = Vec::with_capacity(gltf.buffers().len());
for buffer in gltf.buffers() {
let bytes = match buffer.source() {
gltf::buffer::Source::Uri(uri) => load_context
.read_asset_bytes(
model_path
.resolve_embed_str(uri)
.map_err(|error| io::Error::other(error.to_string()))?,
)
.await
.map_err(|error| io::Error::other(error.to_string()))?,
gltf::buffer::Source::Bin => gltf.blob.clone().ok_or_else(|| {
io::Error::new(io::ErrorKind::InvalidData, "missing glTF binary blob")
})?,
};
buffers.push(bytes);
}
Ok(FighterBakeSource {
model_bytes,
buffers,
animations: manifest.animations,
})
}
@@ -600,7 +627,7 @@ impl AssetTransformer for FighterBakeTransformer {
source: TransformedAsset<Self::AssetInput>,
_: &'a Self::Settings,
) -> Result<TransformedAsset<Self::AssetOutput>, Self::Error> {
let baked = bake_gltf(&source.model_bytes, &source.animations)?;
let baked = bake_gltf(&source.model_bytes, &source.buffers, &source.animations)?;
Ok(source.replace_asset(baked))
}
}
@@ -656,11 +683,36 @@ impl Plugin for BakedAnimationPlugin {
fn bake_gltf(
bytes: &[u8],
buffer_bytes: &[Vec<u8>],
animations: &HashMap<AnimKind, String>,
) -> io::Result<BakedFighterAnimations> {
let (document, buffers, _) = gltf::import_slice(bytes)
let gltf = gltf::Gltf::from_slice(bytes)
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
bake_gltf_document(document, buffers, animations)
let buffers = gltf
.buffers()
.zip(buffer_bytes)
.map(|(buffer, bytes)| {
if bytes.len() < buffer.length() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"glTF buffer {} is too short: expected {}, got {}",
buffer.index(),
buffer.length(),
bytes.len()
),
));
}
Ok(gltf::buffer::Data(bytes.clone()))
})
.collect::<io::Result<Vec<_>>>()?;
if buffers.len() != gltf.buffers().len() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"glTF buffer data is incomplete",
));
}
bake_gltf_document(gltf.document, buffers, animations)
}
fn bake_gltf_document(