Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2b51ae03b | ||
|
|
075a033a2c | ||
|
|
b13d3ce0b3 | ||
|
|
9d786d1bd5 |
@@ -20,13 +20,7 @@ jobs:
|
|||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
|
||||||
sh -s -- -y --profile minimal
|
sh -s -- -y --profile minimal
|
||||||
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||||
"$HOME/.cargo/bin/rustup" toolchain install nightly-2026-09-14 --profile minimal
|
"$HOME/.cargo/bin/rustup" toolchain install nightly --profile minimal
|
||||||
|
|
||||||
- name: Cache Rust dependencies and build artifacts
|
|
||||||
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
|
|
||||||
with:
|
|
||||||
shared-key: linux-nightly
|
|
||||||
cache-bin: false
|
|
||||||
|
|
||||||
- name: Install Linux dependencies
|
- name: Install Linux dependencies
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2026-09-14"
|
channel = "nightly"
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
io,
|
io,
|
||||||
path::Path,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
@@ -518,7 +517,6 @@ struct FighterBakeDeclaration {
|
|||||||
#[derive(Asset, TypePath)]
|
#[derive(Asset, TypePath)]
|
||||||
struct FighterBakeSource {
|
struct FighterBakeSource {
|
||||||
model_bytes: Vec<u8>,
|
model_bytes: Vec<u8>,
|
||||||
buffers: Vec<Vec<u8>>,
|
|
||||||
animations: HashMap<AnimKind, String>,
|
animations: HashMap<AnimKind, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,31 +550,8 @@ impl AssetLoader for FighterBakeSourceLoader {
|
|||||||
.read_asset_bytes(&manifest.model_path)
|
.read_asset_bytes(&manifest.model_path)
|
||||||
.await
|
.await
|
||||||
.map_err(|error| io::Error::other(error.to_string()))?;
|
.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(AssetPath::from_path_buf(
|
|
||||||
Path::new(&manifest.model_path)
|
|
||||||
.parent()
|
|
||||||
.unwrap_or_else(|| Path::new(""))
|
|
||||||
.join(uri),
|
|
||||||
))
|
|
||||||
.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 {
|
Ok(FighterBakeSource {
|
||||||
model_bytes,
|
model_bytes,
|
||||||
buffers,
|
|
||||||
animations: manifest.animations,
|
animations: manifest.animations,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -625,7 +600,7 @@ impl AssetTransformer for FighterBakeTransformer {
|
|||||||
source: TransformedAsset<Self::AssetInput>,
|
source: TransformedAsset<Self::AssetInput>,
|
||||||
_: &'a Self::Settings,
|
_: &'a Self::Settings,
|
||||||
) -> Result<TransformedAsset<Self::AssetOutput>, Self::Error> {
|
) -> Result<TransformedAsset<Self::AssetOutput>, Self::Error> {
|
||||||
let baked = bake_gltf(&source.model_bytes, &source.buffers, &source.animations)?;
|
let baked = bake_gltf(&source.model_bytes, &source.animations)?;
|
||||||
Ok(source.replace_asset(baked))
|
Ok(source.replace_asset(baked))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -681,36 +656,11 @@ impl Plugin for BakedAnimationPlugin {
|
|||||||
|
|
||||||
fn bake_gltf(
|
fn bake_gltf(
|
||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
buffer_bytes: &[Vec<u8>],
|
|
||||||
animations: &HashMap<AnimKind, String>,
|
animations: &HashMap<AnimKind, String>,
|
||||||
) -> io::Result<BakedFighterAnimations> {
|
) -> io::Result<BakedFighterAnimations> {
|
||||||
let gltf = gltf::Gltf::from_slice(bytes)
|
let (document, buffers, _) = gltf::import_slice(bytes)
|
||||||
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
|
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
|
||||||
let buffers = gltf
|
bake_gltf_document(document, buffers, animations)
|
||||||
.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(
|
fn bake_gltf_document(
|
||||||
|
|||||||
Reference in New Issue
Block a user