diff --git a/Cargo.lock b/Cargo.lock index 7bb58131..818847b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,12 +79,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -94,12 +88,6 @@ dependencies = [ "libc", ] -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - [[package]] name = "ansi_term" version = "0.12.1" @@ -438,12 +426,6 @@ dependencies = [ "wayland-client", ] -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - [[package]] name = "cc" version = "1.0.83" @@ -484,47 +466,6 @@ dependencies = [ "serde", ] -[[package]] -name = "chrono" -version = "0.4.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-targets 0.52.0", -] - -[[package]] -name = "ciborium" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" - -[[package]] -name = "ciborium-ll" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" -dependencies = [ - "ciborium-io", - "half 1.8.2", -] - [[package]] name = "clap" version = "2.34.0" @@ -589,15 +530,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "cmake" -version = "0.1.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" -dependencies = [ - "cc", -] - [[package]] name = "codespan-reporting" version = "0.11.1" @@ -690,12 +622,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "const-cstr" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3d0b5ff30645a68f35ece8cea4556ca14ef8a1651455f789a099a0513532a6" - [[package]] name = "core-foundation" version = "0.9.4" @@ -712,19 +638,6 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" -[[package]] -name = "core-graphics" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-graphics-types", - "foreign-types 0.3.2", - "libc", -] - [[package]] name = "core-graphics" version = "0.23.1" @@ -734,7 +647,7 @@ dependencies = [ "bitflags 1.3.2", "core-foundation", "core-graphics-types", - "foreign-types 0.5.0", + "foreign-types", "libc", ] @@ -749,18 +662,6 @@ dependencies = [ "libc", ] -[[package]] -name = "core-text" -version = "19.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" -dependencies = [ - "core-foundation", - "core-graphics 0.22.3", - "foreign-types 0.3.2", - "libc", -] - [[package]] name = "crabslab" version = "0.4.6" @@ -793,42 +694,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "criterion" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" -dependencies = [ - "anes", - "cast", - "ciborium", - "clap 4.5.4", - "criterion-plot", - "is-terminal", - "itertools", - "num-traits", - "once_cell", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" -dependencies = [ - "cast", - "itertools", -] - [[package]] name = "crossbeam-deque" version = "0.8.3" @@ -919,27 +784,6 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "dispatch" version = "0.2.0" @@ -973,18 +817,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" -[[package]] -name = "dwrote" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" -dependencies = [ - "lazy_static", - "libc", - "winapi", - "wio", -] - [[package]] name = "either" version = "1.9.0" @@ -1097,7 +929,7 @@ checksum = "279d3efcc55e19917fff7ab3ddd6c14afb6a90881a0078465196fe2f99d08c56" dependencies = [ "bit_field", "flume", - "half 2.3.1", + "half", "lebe", "miniz_oxide", "rayon-core", @@ -1154,12 +986,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "float-ord" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bad48618fdb549078c333a7a8528acb57af271d0433bdecd523eb620628364e" - [[package]] name = "flume" version = "0.10.14" @@ -1173,40 +999,6 @@ dependencies = [ "spin", ] -[[package]] -name = "font-kit" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21fe28504d371085fae9ac7a3450f0b289ab71e07c8e57baa3fb68b9e57d6ce5" -dependencies = [ - "bitflags 1.3.2", - "byteorder", - "core-foundation", - "core-graphics 0.22.3", - "core-text", - "dirs-next", - "dwrote", - "float-ord", - "freetype", - "lazy_static", - "libc", - "log", - "pathfinder_geometry", - "pathfinder_simd", - "walkdir", - "winapi", - "yeslogic-fontconfig-sys", -] - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared 0.1.1", -] - [[package]] name = "foreign-types" version = "0.5.0" @@ -1214,7 +1006,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared 0.3.1", + "foreign-types-shared", ] [[package]] @@ -1228,39 +1020,12 @@ dependencies = [ "syn 2.0.49", ] -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "foreign-types-shared" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" -[[package]] -name = "freetype" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee38378a9e3db1cc693b4f88d166ae375338a0ff75cb8263e1c601d51f35dc6" -dependencies = [ - "freetype-sys", - "libc", -] - -[[package]] -name = "freetype-sys" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" -dependencies = [ - "cmake", - "libc", - "pkg-config", -] - [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -1472,12 +1237,6 @@ dependencies = [ "bitflags 2.4.1", ] -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - [[package]] name = "half" version = "2.3.1" @@ -1552,29 +1311,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "iana-time-zone" -version = "0.1.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - [[package]] name = "icosahedron" version = "0.1.1" @@ -1684,15 +1420,6 @@ version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.9" @@ -1809,17 +1536,6 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" -[[package]] -name = "libredox" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" -dependencies = [ - "bitflags 2.4.1", - "libc", - "redox_syscall 0.4.1", -] - [[package]] name = "libredox" version = "0.0.2" @@ -1907,7 +1623,7 @@ dependencies = [ "bitflags 2.4.1", "block", "core-graphics-types", - "foreign-types 0.5.0", + "foreign-types", "log", "objc", "paste", @@ -2098,19 +1814,13 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - [[package]] name = "orbclient" version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" dependencies = [ - "libredox 0.0.2", + "libredox", ] [[package]] @@ -2119,7 +1829,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4586edfe4c648c71797a74c84bacb32b52b212eff5dfe2bb9f2c599844023e7" dependencies = [ - "ttf-parser 0.20.0", + "ttf-parser", ] [[package]] @@ -2157,25 +1867,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" -[[package]] -name = "pathfinder_geometry" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b7e7b4ea703700ce73ebf128e1450eb69c3a8329199ffbfb9b2a0418e5ad3" -dependencies = [ - "log", - "pathfinder_simd", -] - -[[package]] -name = "pathfinder_simd" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0444332826c70dc47be74a7c6a5fc44e23a7905ad6858d4162b658320455ef93" -dependencies = [ - "rustc_version", -] - [[package]] name = "percent-encoding" version = "2.3.1" @@ -2235,52 +1926,6 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "plotters" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" -dependencies = [ - "chrono", - "font-kit", - "image 0.24.7", - "lazy_static", - "num-traits", - "pathfinder_geometry", - "plotters-backend", - "plotters-bitmap", - "plotters-svg", - "ttf-parser 0.17.1", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" - -[[package]] -name = "plotters-bitmap" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cebbe1f70205299abc69e8b295035bb52a6a70ee35474ad10011f0a4efb8543" -dependencies = [ - "gif", - "image 0.24.7", - "plotters-backend", -] - -[[package]] -name = "plotters-svg" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" -dependencies = [ - "plotters-backend", -] - [[package]] name = "png" version = "0.17.10" @@ -2541,17 +2186,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_users" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" -dependencies = [ - "getrandom", - "libredox 0.0.1", - "thiserror", -] - [[package]] name = "regex" version = "1.10.2" @@ -2595,7 +2229,6 @@ dependencies = [ "async-channel 1.9.0", "bytemuck", "crabslab", - "criterion", "crunch", "ctor", "dagga", @@ -2603,19 +2236,18 @@ dependencies = [ "futures-lite 1.13.0", "glam", "gltf", - "half 2.3.1", + "half", "icosahedron", "image 0.24.7", "img-diff", "log", "naga", - "plotters", "pretty_assertions", "rustc-hash", "send_wrapper", "snafu", "spirv-std", - "ttf-parser 0.20.0", + "ttf-parser", "wgpu", "winit", ] @@ -2626,15 +2258,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - [[package]] name = "rustix" version = "0.38.26" @@ -2697,12 +2320,6 @@ dependencies = [ "tiny-skia", ] -[[package]] -name = "semver" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" - [[package]] name = "send_wrapper" version = "0.6.0" @@ -2995,16 +2612,6 @@ dependencies = [ "strict-num", ] -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "toml_datetime" version = "0.6.5" @@ -3038,12 +2645,6 @@ version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -[[package]] -name = "ttf-parser" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375812fa44dab6df41c195cd2f7fecb488f6c09fbaafb62807488cefab642bff" - [[package]] name = "ttf-parser" version = "0.20.0" @@ -3720,7 +3321,7 @@ dependencies = [ "calloop", "cfg_aliases", "core-foundation", - "core-graphics 0.23.1", + "core-graphics", "cursor-icon", "icrate", "js-sys", @@ -3763,15 +3364,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "wio" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" -dependencies = [ - "winapi", -] - [[package]] name = "x11-dl" version = "2.21.0" @@ -3844,18 +3436,6 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" -[[package]] -name = "yeslogic-fontconfig-sys" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2bbd69036d397ebbff671b1b8e4d918610c181c5a16073b96f984a38d08c386" -dependencies = [ - "const-cstr", - "dlib", - "once_cell", - "pkg-config", -] - [[package]] name = "zerocopy" version = "0.7.32" diff --git a/Cargo.toml b/Cargo.toml index eecef26d..47e7d594 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,6 @@ gltf = { git = 'https://github.com/schell/gltf.git', branch ="feature/channel-sa image = "0.24" log = "0.4" naga = { version = "0.19", features = ["spv-in", "wgsl-out", "wgsl-in", "msl-out"] } -plotters = "0.3" pretty_assertions = "1.4.0" proc-macro2 = { version = "1.0", features = ["span-locations"] } glam = { version = "0.24.2", default-features = false } diff --git a/crates/example/src/lib.rs b/crates/example/src/lib.rs index a0df7ca3..7dfba2f8 100644 --- a/crates/example/src/lib.rs +++ b/crates/example/src/lib.rs @@ -11,7 +11,7 @@ use renderling::{ math::{Mat4, UVec2, Vec3, Vec4}, skybox::Skybox, slab::Hybrid, - stage::{Animator, GltfDocument, Node, Stage}, + stage::{Animator, GltfDocument, Stage}, transform::Transform, Context, }; @@ -68,7 +68,6 @@ pub struct App { camera: Hybrid, document: Option, - nodes: Option>, animators: Option>, animations_conflict: bool, @@ -106,7 +105,6 @@ impl App { camera, document: None, - nodes: None, animators: None, animations_conflict: false, @@ -162,11 +160,13 @@ impl App { self.last_cursor_position = None; self.stage.set_images(std::iter::empty()).unwrap(); self.document = None; - self.nodes = None; log::debug!("ticking stage to reclaim buffers"); self.stage.tick(); - let mut doc = match self.stage.load_gltf_document_from_bytes(bytes) { + let doc = match self + .stage + .load_gltf_document_from_bytes(bytes, self.camera.id()) + { Err(e) => { log::error!("gltf loading error: {e}"); return; @@ -204,13 +204,7 @@ impl App { } } } - let nodes = match self.stage.draw_gltf_scene(&doc, nodes, self.camera.id()) { - Err(e) => { - log::error!("could not draw scene: {e}"); - vec![] - } - Ok(ns) => ns, - }; + if doc.animations.is_empty() { log::trace!(" animations: none"); } else { @@ -219,8 +213,8 @@ impl App { let mut animated_nodes = HashSet::default(); let mut has_conflicting_animations = false; self.animators = Some( - std::mem::take(&mut doc.animations) - .into_iter() + doc.animations + .iter() .enumerate() .map(|(i, a)| { let target_nodes = a.target_node_indices().collect::>(); @@ -236,7 +230,7 @@ impl App { tween.properties.description() ); } - Animator::new(&nodes, a) + Animator::new(doc.nodes.iter(), a.clone()) }) .collect(), ); @@ -244,7 +238,6 @@ impl App { log::trace!(" and some animations conflict"); } self.animations_conflict = has_conflicting_animations; - self.nodes = Some(nodes); self.document = Some(doc); let halfway_point = min + ((max - min).normalize() * ((max - min).length() / 2.0)); diff --git a/crates/renderling/Cargo.toml b/crates/renderling/Cargo.toml index 53cf0bfc..0cb431d3 100644 --- a/crates/renderling/Cargo.toml +++ b/crates/renderling/Cargo.toml @@ -119,13 +119,11 @@ features = ["gltf", "raw-window-handle", "winit"] [dev-dependencies] assert_approx_eq = {workspace = true} -criterion = { version = "0.5", features = ["html_reports"] } ctor = "0.2.2" env_logger = {workspace = true} icosahedron = "0.1" img-diff = { path = "../img-diff" } naga.workspace = true -plotters.workspace = true pretty_assertions.workspace = true ttf-parser = "0.20.0" diff --git a/crates/renderling/src/bloom/cpu.rs b/crates/renderling/src/bloom/cpu.rs index 795bec1b..d34c6551 100644 --- a/crates/renderling/src/bloom/cpu.rs +++ b/crates/renderling/src/bloom/cpu.rs @@ -713,9 +713,7 @@ mod test { let height = 128; let ctx = Context::headless(width, height); let mut stage = ctx.new_stage().with_bloom(false); - let doc = stage - .load_gltf_document_from_path("../../gltf/EmissiveStrengthTest.glb") - .unwrap(); + let projection = crate::camera::perspective(width as f32, height as f32); let view = crate::camera::look_at(Vec3::new(0.0, 2.0, 18.0), Vec3::ZERO, Vec3::Y); let camera = stage.new_value(Camera::new(projection, view)); @@ -723,11 +721,11 @@ mod test { .new_skybox_from_path("../../img/hdr/night.hdr", camera.id()) .unwrap(); stage.set_skybox(skybox); - let scene_index = doc.default_scene.unwrap(); - let nodes = doc.scenes.get(scene_index).unwrap(); - let _scene = stage - .draw_gltf_scene(&doc, nodes.into_iter().copied(), camera.id()) + + let _doc = stage + .load_gltf_document_from_path("../../gltf/EmissiveStrengthTest.glb", camera.id()) .unwrap(); + let frame = ctx.get_next_frame().unwrap(); stage.render(&frame.view()); let img = frame.read_image().unwrap(); diff --git a/crates/renderling/src/linkage/stage-renderlet_fragment.spv b/crates/renderling/src/linkage/stage-renderlet_fragment.spv index 74d598d4..8d991b0c 100644 Binary files a/crates/renderling/src/linkage/stage-renderlet_fragment.spv and b/crates/renderling/src/linkage/stage-renderlet_fragment.spv differ diff --git a/crates/renderling/src/linkage/stage-renderlet_vertex.spv b/crates/renderling/src/linkage/stage-renderlet_vertex.spv index 7031997d..203c1d72 100644 Binary files a/crates/renderling/src/linkage/stage-renderlet_vertex.spv and b/crates/renderling/src/linkage/stage-renderlet_vertex.spv differ diff --git a/crates/renderling/src/linkage/tutorial-tutorial_slabbed_renderlet.spv b/crates/renderling/src/linkage/tutorial-tutorial_slabbed_renderlet.spv index 9b816184..878b7519 100644 Binary files a/crates/renderling/src/linkage/tutorial-tutorial_slabbed_renderlet.spv and b/crates/renderling/src/linkage/tutorial-tutorial_slabbed_renderlet.spv differ diff --git a/crates/renderling/src/stage.rs b/crates/renderling/src/stage.rs index 13bd8770..9de7ee51 100644 --- a/crates/renderling/src/stage.rs +++ b/crates/renderling/src/stage.rs @@ -34,6 +34,7 @@ pub use gltf_support::*; /// For more info on vertex skinning, see /// #[derive(Clone, Copy, Default, SlabItem)] +#[cfg_attr(not(target_arch = "spirv"), derive(Debug))] pub struct Skin { // Ids of the skeleton nodes' global transforms used as joints in this skin. pub joints: Array>, @@ -45,22 +46,27 @@ pub struct Skin { } impl Skin { - pub fn get_transform(&self, vertex: Vertex, slab: &[u32]) -> Transform { + pub fn get_transform(&self, vertex: Vertex, slab: &[u32]) -> Mat4 { let mut mat = Mat4::ZERO; for i in 0..vertex.joints.len() { + let joint_weight = vertex.weights[i]; + if joint_weight == 0.0 { + continue; + } + + let inverse_bind_matrix = slab.read(self.inverse_bind_matrices.at(i)); + let joint_index = vertex.joints[i] as usize; let joint_id = slab.read(self.joints.at(joint_index)); - let inverse_bind_matrix = slab.read(self.inverse_bind_matrices.at(i)); let joint_matrix = Mat4::from(slab.read(joint_id)) * inverse_bind_matrix; - let joint_weight = vertex.weights[i]; - mat += joint_weight * joint_matrix; + + mat += joint_matrix * joint_weight; } - let mat = if mat == Mat4::ZERO { + if mat == Mat4::ZERO { Mat4::IDENTITY } else { mat - }; - Transform::from(mat) + } } } @@ -245,6 +251,8 @@ pub fn renderlet_vertex( out_world_pos: &mut Vec3, #[spirv(position)] out_clip_pos: &mut Vec4, ) { + use crate::math::IsMatrix; + let renderlet = slab.read_unchecked(renderlet_id); let mut vertex_log = RenderletVertexLog::new(renderlet_id, renderlet.debug_index, vertex_index); @@ -266,18 +274,15 @@ pub fn renderlet_vertex( *out_uv0 = vertex.uv0; *out_uv1 = vertex.uv1; - let transform = if renderlet.skin_id.is_some() { + let model_matrix = if renderlet.skin_id.is_some() { let skin = slab.read(renderlet.skin_id); skin.get_transform(vertex, slab) } else { - slab.read(renderlet.transform_id) + let t = slab.read(renderlet.transform_id); + Mat4::from(t) }; - let model_matrix = Mat4::from_scale_rotation_translation( - transform.scale, - transform.rotation, - transform.translation, - ); - let scale2 = transform.scale * transform.scale; + let (scale, _, _) = model_matrix.to_scale_rotation_translation_or_id(); + let scale2 = scale * scale; let normal = vertex.normal.alt_norm_or_zero(); let tangent = vertex.tangent.xyz().alt_norm_or_zero(); let normal_w: Vec3 = (model_matrix * (normal / scale2).extend(0.0)) diff --git a/crates/renderling/src/stage/gltf_support.rs b/crates/renderling/src/stage/gltf_support.rs index f03df2ec..6174d233 100644 --- a/crates/renderling/src/stage/gltf_support.rs +++ b/crates/renderling/src/stage/gltf_support.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use crabslab::{Array, Id}; use glam::{Mat4, Vec2, Vec3, Vec4}; +use rustc_hash::FxHashMap; use snafu::{OptionExt, ResultExt, Snafu}; use crate::{ @@ -15,7 +16,7 @@ use crate::{ Material, }, slab::*, - stage::{NestedTransform, Renderlet, Stage, Vertex}, + stage::{NestedTransform, Renderlet, Skin, Stage, Vertex}, transform::Transform, }; @@ -72,6 +73,12 @@ pub enum StageGltfError { #[snafu(display("Missing gltf camera at index {index}"))] MissingCamera { index: usize }, + #[snafu(display("Node has no skin"))] + NoSkin, + + #[snafu(display("Missing gltf skin at index {index}"))] + MissingSkin { index: usize }, + #[snafu(display("{source}"))] Animation { source: anime::AnimationError }, @@ -610,12 +617,76 @@ pub struct GltfNode { pub transform: NestedTransform, } +impl From<&GltfNode> for (usize, NestedTransform) { + fn from(node: &GltfNode) -> Self { + (node.index, node.transform.clone()) + } +} + impl GltfNode { pub fn global_transform(&self) -> Transform { self.transform.get_global_transform() } } + +#[derive(Clone, Debug)] +pub struct GltfSkin { + pub index: usize, + // Indices of the skeleton nodes used as joints in this skin + pub joint_nodes: Vec, + pub joint_transforms: HybridArray>, + // Containins the 4x4 inverse-bind matrices. + // + // When None, each matrix is assumed to be the 4x4 identity matrix which implies that the + // inverse-bind matrices were pre-applied. + pub inverse_bind_matrices: Option>, + // Index of the node used as the skeleton root. + // When None, joints transforms resolve to scene root. + pub skeleton: Option, + + pub skin: Hybrid, +} + +impl GltfSkin { + pub fn from_gltf( + stage: &mut Stage, + buffer_data: &[gltf::buffer::Data], + nodes: &[GltfNode], + skin: gltf::Skin, + ) -> Result { + let joint_nodes = skin.joints().map(|n| n.index()).collect::>(); + let mut joint_transforms = vec![]; + for node_index in joint_nodes.iter() { + let gltf_node: &GltfNode = nodes + .get(*node_index) + .context(MissingNodeSnafu { index: *node_index })?; + let transform_id = gltf_node.transform.global_transform_id(); + joint_transforms.push(transform_id); + } + let joint_transforms = stage.new_array(joint_transforms); + let reader = skin.reader(|b| buffer_data.get(b.index()).map(|d| d.0.as_slice())); + let inverse_bind_matrices = reader + .read_inverse_bind_matrices() + .map(|mats| stage.new_array(mats.into_iter().map(|m| Mat4::from_cols_array_2d(&m)))); + let skeleton = skin.skeleton().map(|n| n.index()); + Ok(GltfSkin { + index: skin.index(), + skin: stage.new_value(Skin { + joints: joint_transforms.array(), + inverse_bind_matrices: inverse_bind_matrices + .as_ref() + .map(|a| a.array()) + .unwrap_or_default(), + }), + joint_nodes, + joint_transforms, + inverse_bind_matrices, + skeleton, + }) + } +} + #[derive(Debug)] pub struct GltfDocument { pub animations: Vec, @@ -630,6 +701,7 @@ pub struct GltfDocument { pub default_scene: Option, pub textures: HybridArray, pub lights: Vec, + pub renderlets: FxHashMap>>, } impl GltfDocument { @@ -638,6 +710,8 @@ impl GltfDocument { document: &gltf::Document, buffer_data: Vec, images: Vec, + // Camera id to use for any created Renderlets + camera_id: Id, ) -> Result { log::debug!("Loading {} nodes", document.nodes().count()); let mut nodes = vec![]; @@ -840,10 +914,10 @@ impl GltfDocument { } log::trace!("Loading skins"); - let skins = document - .skins() - .map(|skin| GltfSkin::from_gltf(&buffer_data, skin)) - .collect::>(); + let mut skins = vec![]; + for skin in document.skins() { + skins.push(GltfSkin::from_gltf(stage, &buffer_data, &nodes, skin)?); + } log::trace!("Loading animations"); let mut animations = vec![]; @@ -857,6 +931,55 @@ impl GltfDocument { .map(|scene| scene.nodes().map(|node| node.index()).collect()) .collect(); + log::debug!("Creating renderlets"); + + let mut renderlets = FxHashMap::default(); + for gltf_node in nodes.iter() { + log::debug!( + " creating renderlets for node {} {:?}", + gltf_node.index, + gltf_node.name + ); + + let mut node_renderlets = vec![]; + let skin_id = if let Some(skin_index) = gltf_node.skin { + let gltf_skin = skins + .get(skin_index) + .context(MissingSkinSnafu { index: skin_index })?; + gltf_skin.skin.id() + } else { + Id::NONE + }; + + if let Some(mesh_index) = gltf_node.mesh { + log::debug!(" mesh {mesh_index}"); + let mesh = meshes + .get(mesh_index) + .context(MissingMeshSnafu { index: mesh_index })?; + let num_prims = mesh.primitives.len(); + log::debug!(" has {num_prims} primitives"); + for (prim, i) in mesh.primitives.iter().zip(1..) { + let hybrid = stage.new_value(Renderlet { + vertices_array: prim.vertices.array(), + indices_array: prim.indices.array(), + transform_id: gltf_node.transform.global_transform_id(), + material_id: prim.material, + camera_id, + skin_id, + ..Default::default() + }); + log::debug!(" created renderlet {i}/{num_prims}: {:#?}", hybrid.get()); + stage.add_renderlet(&hybrid); + node_renderlets.push(hybrid); + } + } else { + log::debug!(" node has no mesh"); + } + if !node_renderlets.is_empty() { + renderlets.insert(gltf_node.index, node_renderlets); + } + } + log::trace!("Done loading gltf"); Ok(GltfDocument { @@ -871,30 +994,25 @@ impl GltfDocument { skins, default_scene: document.default_scene().map(|scene| scene.index()), textures, + renderlets, }) } -} - -/// A collection of [`Renderlet`]s that represent one entity. -/// -/// A node may be part of a hierarchy and have child nodes, or be the child -/// of another node. -/// -/// Hierachical transformations are maintained by [`NestedTransform`]. -#[derive(Debug, Clone)] -pub struct Node { - pub gltf_node: GltfNode, - pub renderlets: Vec>, - pub children: Vec, -} -impl Node { - pub fn index(&self) -> usize { - self.gltf_node.index + pub fn renderlets_iter(&self) -> impl Iterator> { + self.renderlets.iter().flat_map(|(_, rs)| rs.iter()) } - pub fn name(&self) -> Option<&str> { - self.gltf_node.name.as_deref() + pub fn nodes_in_scene(&self, scene_index: usize) -> impl Iterator { + let scene = self.scenes.get(scene_index); + let mut nodes = vec![]; + if let Some(indices) = scene { + for node_index in indices { + if let Some(node) = self.nodes.get(*node_index) { + nodes.push(node); + } + } + } + nodes.into_iter() } } @@ -902,90 +1020,19 @@ impl Stage { pub fn load_gltf_document_from_path( &mut self, path: impl AsRef, + camera_id: Id, ) -> Result { let (document, buffers, images) = gltf::import(path)?; - GltfDocument::from_gltf(self, &document, buffers, images) + GltfDocument::from_gltf(self, &document, buffers, images, camera_id) } pub fn load_gltf_document_from_bytes( &mut self, bytes: impl AsRef<[u8]>, + camera_id: Id, ) -> Result { let (document, buffers, images) = gltf::import_slice(bytes)?; - GltfDocument::from_gltf(self, &document, buffers, images) - } - - /// Draws the `StagedGltfNode` with the given `Camera`. - pub fn draw_gltf_node( - &mut self, - doc: &GltfDocument, - node_index: usize, - camera: Id, - ) -> Result { - let gltf_node = doc - .nodes - .get(node_index) - .context(MissingNodeSnafu { index: node_index })? - .clone(); - - log::debug!("drawing GLTF node {node_index} {:?}", gltf_node.name); - - let mut renderlets = vec![]; - if let Some(mesh_index) = gltf_node.mesh { - log::debug!(" mesh {mesh_index}"); - let mesh = doc - .meshes - .get(mesh_index) - .context(MissingMeshSnafu { index: mesh_index })?; - let num_prims = mesh.primitives.len(); - log::debug!(" has {num_prims} primitives"); - for (prim, i) in mesh.primitives.iter().zip(1..) { - let hybrid = self.new_value(Renderlet { - vertices_array: prim.vertices.array(), - indices_array: prim.indices.array(), - camera_id: camera, - transform_id: gltf_node.transform.global_transform_id(), - material_id: prim.material, - ..Default::default() - }); - log::debug!(" created renderlet {i}/{num_prims}: {:#?}", hybrid.get()); - self.add_renderlet(&hybrid); - renderlets.push(hybrid); - } - } else { - log::debug!(" node has no mesh"); - } - - let mut children = vec![]; - log::debug!( - " has {} children: {:?}", - gltf_node.children.len(), - gltf_node.children - ); - for child_index in gltf_node.children.iter() { - children.push(self.draw_gltf_node(doc, *child_index, camera)?); - } - - Ok(Node { - gltf_node, - renderlets, - children, - }) - } - - pub fn draw_gltf_scene( - &mut self, - doc: &GltfDocument, - // Any list of nodes makes a scene. - nodes: impl IntoIterator, - camera: Id, - ) -> Result, StageGltfError> { - let mut scene_nodes = vec![]; - for node_index in nodes.into_iter() { - let node = self.draw_gltf_node(doc, node_index, camera)?; - scene_nodes.push(node); - } - Ok(scene_nodes) + GltfDocument::from_gltf(self, &document, buffers, images, camera_id) } } @@ -1032,26 +1079,17 @@ mod test { .with_lighting(false) .with_bloom(false) .with_background_color(Vec3::splat(0.0).extend(1.0)); - let mut doc = stage - .load_gltf_document_from_path("../../gltf/gltfTutorial_008_SimpleMeshes.gltf") - .unwrap(); - println!("doc: {doc:#?}"); - let camera = Camera { + let camera = stage.new_value(Camera { projection, view, position, - }; - let camera = stage.new_value(camera); - let scene_index = doc.default_scene.unwrap(); - let scene_nodes = doc.scenes.get(scene_index).unwrap().clone(); - let scene = stage - .draw_gltf_scene(&mut doc, scene_nodes, camera.id()) + }); + let _doc = stage + .load_gltf_document_from_path( + "../../gltf/gltfTutorial_008_SimpleMeshes.gltf", + camera.id(), + ) .unwrap(); - println!("scene: {scene:#?}"); - - // let default_scene = document.default_scene().unwrap(); - // let unit_ids = stage.draw_gltf_scene(&gpu_doc, camera_id, default_scene); - // assert_eq!(2, unit_ids.len()); let frame = ctx.get_next_frame().unwrap(); stage.render(&frame.view()); @@ -1068,24 +1106,22 @@ mod test { .with_lighting(false) .with_bloom(false) .with_background_color(Vec3::splat(0.0).extend(1.0)); - let mut doc = stage - .load_gltf_document_from_path("../../gltf/gltfTutorial_003_MinimalGltfFile.gltf") - .unwrap(); + let projection = crate::camera::perspective(20.0, 20.0); let eye = Vec3::new(0.5, 0.5, 2.0); let view = crate::camera::look_at(eye, Vec3::new(0.5, 0.5, 0.0), Vec3::Y); - let camera = Camera { + let camera = stage.new_value(Camera { projection, view, position: Vec3::new(0.5, 0.5, 2.0), - }; - let camera = stage.new_value(camera); - let default_scene = doc.default_scene.unwrap(); - let nodes = doc.scenes.get(default_scene).unwrap().clone(); - let scene = stage.draw_gltf_scene(&mut doc, nodes, camera.id()).unwrap(); - for (i, node) in scene.iter().enumerate() { - println!("node_{i}: {node:#?}"); - } + }); + + let _doc = stage + .load_gltf_document_from_path( + "../../gltf/gltfTutorial_003_MinimalGltfFile.gltf", + camera.id(), + ) + .unwrap(); let frame = ctx.get_next_frame().unwrap(); stage.render(&frame.view()); @@ -1103,11 +1139,11 @@ mod test { .new_stage() .with_lighting(false) .with_background_color(Vec4::splat(1.0)); - let doc = stage - .load_gltf_document_from_path("../../gltf/cheetah_cone.glb") - .unwrap(); let (projection, view) = crate::camera::default_ortho2d(100.0, 100.0); let camera = stage.new_value(Camera::new(projection, view)); + let doc = stage + .load_gltf_document_from_path("../../gltf/cheetah_cone.glb", camera.id()) + .unwrap(); assert!(!doc.textures.is_empty()); let albedo_texture = doc.textures.get(0); assert!(albedo_texture.is_some()); @@ -1163,17 +1199,17 @@ mod test { // let's force it to be unlit. .with_lighting(false) .with_bloom(false); - let mut doc = stage - .load_gltf_document_from_path("../../gltf/gltfTutorial_013_SimpleTexture.gltf") - .unwrap(); - let projection = crate::camera::perspective(size as f32, size as f32); let view = crate::camera::look_at(Vec3::new(0.5, 0.5, 1.25), Vec3::new(0.5, 0.5, 0.0), Vec3::Y); let camera = stage.new_value(Camera::new(projection, view)); - let default_scene_index = doc.default_scene.unwrap(); - let nodes = doc.scenes.get(default_scene_index).unwrap().clone(); - let _scene = stage.draw_gltf_scene(&mut doc, nodes, camera.id()).unwrap(); + + let _doc = stage + .load_gltf_document_from_path( + "../../gltf/gltfTutorial_013_SimpleTexture.gltf", + camera.id(), + ) + .unwrap(); let frame = ctx.get_next_frame().unwrap(); stage.render(&frame.view()); @@ -1191,13 +1227,16 @@ mod test { .new_stage() .with_lighting(true) .with_background_color(Vec3::splat(1.0).extend(1.0)); + let doc = stage - .load_gltf_document_from_path("../../gltf/red_brick_03_1k.glb") + .load_gltf_document_from_path("../../gltf/red_brick_03_1k.glb", Id::NONE) .unwrap(); let gltf_camera = doc.cameras.get(0).unwrap(); - let scene_index = doc.default_scene.unwrap(); - let nodes = doc.scenes.get(scene_index).unwrap().iter().copied(); - let _scene = stage.draw_gltf_scene(&doc, nodes, gltf_camera.camera.id()); + doc.renderlets_iter().for_each(|hybrid| { + hybrid.modify(|r| { + r.camera_id = gltf_camera.camera.id(); + }); + }); stage.set_lights(doc.lights.iter().map(|gltf_light| gltf_light.light.id())); diff --git a/crates/renderling/src/stage/gltf_support/anime.rs b/crates/renderling/src/stage/gltf_support/anime.rs index ebc07d45..69631e34 100644 --- a/crates/renderling/src/stage/gltf_support/anime.rs +++ b/crates/renderling/src/stage/gltf_support/anime.rs @@ -1,8 +1,8 @@ //! Animation helpers for gltf. -use glam::{Mat4, Quat, Vec3}; +use glam::{Quat, Vec3}; use snafu::prelude::*; -use crate::stage::Node; +use crate::stage::NestedTransform; #[derive(Debug, Snafu)] pub enum InterpolationError { @@ -28,41 +28,6 @@ pub enum InterpolationError { MismatchedProperties, } -#[derive(Clone, Default, Debug)] -pub struct GltfSkin { - pub index: usize, - // Indices of the skeleton nodes used as joints in this skin - pub joints: Vec, - // Containins the 4x4 inverse-bind matrices. - // - // When None, each matrix is assumed to be the 4x4 identity matrix which implies that the - // inverse-bind matrices were pre-applied. - pub inverse_bind_matrices: Option>, - // Index of the node used as the skeleton root. - // When None, joints transforms resolve to scene root. - pub skeleton: Option, -} - -impl GltfSkin { - pub fn from_gltf(buffer_data: &[gltf::buffer::Data], skin: gltf::Skin) -> Self { - let index = skin.index(); - let joints = skin.joints().map(|n| n.index()).collect::>(); - let reader = skin.reader(|b| buffer_data.get(b.index()).map(|d| d.0.as_slice())); - let inverse_bind_matrices = reader.read_inverse_bind_matrices().map(|mats| { - mats.into_iter() - .map(|m| Mat4::from_cols_array_2d(&m)) - .collect() - }); - let skeleton = skin.skeleton().map(|n| n.index()); - GltfSkin { - index, - joints, - inverse_bind_matrices, - skeleton, - } - } -} - #[derive(Debug, Clone, Copy)] pub enum Interpolation { Linear, @@ -690,7 +655,10 @@ impl Animation { Ok(tweens.into_iter().collect()) } - pub fn into_animator<'a>(self, nodes: impl IntoIterator) -> Animator { + pub fn into_animator<'a>( + self, + nodes: impl IntoIterator, + ) -> Animator { Animator::new(nodes, self) } @@ -714,22 +682,18 @@ pub struct Animator { // of the current animation. pub timestamp: f32, // All nodes under this animator's control. - pub nodes: rustc_hash::FxHashMap, + pub nodes: rustc_hash::FxHashMap, // The animation that will apply to the nodes. pub animation: Animation, } impl Animator { /// Create a new animator with the given nodes and animation. - pub fn new<'a>(nodes: impl IntoIterator, animation: Animation) -> Self { - // a function to return this node and all its descendants - fn get_descendants(node: &Node) -> Vec { - let mut nodes: Vec = node.children.iter().flat_map(get_descendants).collect(); - nodes.push(node.clone()); - nodes - } - let nodes = nodes.into_iter(); - let nodes = nodes.flat_map(get_descendants).map(|n| (n.index(), n)); + pub fn new( + nodes: impl IntoIterator>, + animation: Animation, + ) -> Self { + let nodes = nodes.into_iter().map(|n| n.into()); let nodes = rustc_hash::FxHashMap::from_iter(nodes); Animator { nodes, @@ -759,20 +723,20 @@ impl Animator { // * business logic has removed it // * ...and the beat goes on // So we won't fret if we can't find it... - if let Some(node) = self.nodes.get(&node_index) { + if let Some(transform) = self.nodes.get(&node_index) { match property { TweenProperty::Translation(translation) => { - node.gltf_node.transform.modify_local_transform(|t| { + transform.modify_local_transform(|t| { t.translation = translation; }); } TweenProperty::Rotation(rotation) => { - node.gltf_node.transform.modify_local_transform(|t| { + transform.modify_local_transform(|t| { t.rotation = rotation; }); } TweenProperty::Scale(scale) => { - node.gltf_node.transform.modify_local_transform(|t| { + transform.modify_local_transform(|t| { t.scale = scale; }); } @@ -788,7 +752,7 @@ impl Animator { #[cfg(test)] mod test { - use crate::{camera::Camera, math::Vec3, stage::GltfDocument, Context}; + use crate::{camera::Camera, math::Vec3, stage::Animator, Context}; #[test] fn gltf_simple_animation() { @@ -800,13 +764,14 @@ mod test { let projection = crate::camera::perspective(50.0, 50.0); let view = crate::camera::look_at(Vec3::Z * 3.0, Vec3::ZERO, Vec3::Y); let camera = stage.new_value(Camera::new(projection, view)); + let doc = stage - .load_gltf_document_from_path("../../gltf/animated_triangle.gltf") + .load_gltf_document_from_path("../../gltf/animated_triangle.gltf", camera.id()) .unwrap(); - let nodes = vec![stage.draw_gltf_node(&doc, 0, camera.id()).unwrap()]; - let GltfDocument { mut animations, .. } = doc; - let mut animator = animations.pop().unwrap().into_animator(&nodes); + let nodes = doc.nodes_in_scene(doc.default_scene.unwrap_or_default()); + + let mut animator = Animator::new(nodes, doc.animations.first().unwrap().clone()); log::info!("animator: {animator:#?}"); let frame = ctx.get_next_frame().unwrap();