diff --git a/Cargo.lock b/Cargo.lock index 08ab110..c525bf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,16 +19,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" @@ -412,25 +406,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -454,16 +429,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "deflate" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" -dependencies = [ - "adler32", - "byteorder", -] - [[package]] name = "dispatch" version = "0.2.0" @@ -494,12 +459,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - [[package]] name = "env_logger" version = "0.10.2" @@ -529,6 +488,25 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "foldhash" version = "0.1.4" @@ -562,6 +540,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "gethostname" version = "0.4.3" @@ -583,16 +567,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "gif" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" -dependencies = [ - "color_quant", - "weezl", -] - [[package]] name = "gl_generator" version = "0.14.0" @@ -604,6 +578,12 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + [[package]] name = "glow" version = "0.13.1" @@ -732,21 +712,16 @@ dependencies = [ [[package]] name = "image" -version = "0.23.14" +version = "0.24.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" dependencies = [ "bytemuck", "byteorder", "color_quant", - "gif", "jpeg-decoder", - "num-iter", - "num-rational", "num-traits", "png", - "scoped_threadpool", - "tiff", ] [[package]] @@ -803,12 +778,9 @@ dependencies = [ [[package]] name = "jpeg-decoder" -version = "0.1.22" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" -dependencies = [ - "rayon", -] +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" @@ -933,21 +905,12 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.3.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" dependencies = [ - "adler32", -] - -[[package]] -name = "miniz_oxide" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" -dependencies = [ - "adler", - "autocfg", + "adler2", + "simd-adler32", ] [[package]] @@ -1002,37 +965,6 @@ dependencies = [ "jni-sys", ] -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -1117,9 +1049,12 @@ dependencies = [ "bytemuck", "cgmath", "env_logger", + "fs_extra", + "glob", "image", "log", "pollster", + "tobj", "wgpu", "winit", ] @@ -1182,14 +1117,15 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "png" -version = "0.16.8" +version = "0.17.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" dependencies = [ "bitflags 1.3.2", "crc32fast", - "deflate", - "miniz_oxide 0.3.7", + "fdeflate", + "flate2", + "miniz_oxide", ] [[package]] @@ -1279,26 +1215,6 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "redox_syscall" version = "0.3.5" @@ -1392,12 +1308,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" -[[package]] -name = "scoped_threadpool" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" - [[package]] name = "scopeguard" version = "1.2.0" @@ -1443,6 +1353,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "slab" version = "0.4.9" @@ -1573,17 +1489,6 @@ dependencies = [ "syn 2.0.96", ] -[[package]] -name = "tiff" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437" -dependencies = [ - "jpeg-decoder", - "miniz_oxide 0.4.4", - "weezl", -] - [[package]] name = "tiny-skia" version = "0.11.4" @@ -1609,6 +1514,12 @@ dependencies = [ "strict-num", ] +[[package]] +name = "tobj" +version = "3.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57381207291289bad19de63acd3fbf5948ff99b2868116c367b7224c37d55f90" + [[package]] name = "toml_datetime" version = "0.6.8" @@ -1894,12 +1805,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "weezl" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" - [[package]] name = "wgpu" version = "22.1.0" diff --git a/Cargo.toml b/Cargo.toml index 98379a7..cc79611 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -image = "0.23" cgmath = "0.18" winit = { version = "0.29", features = ["rwh_05"] } env_logger = "0.10" @@ -12,4 +11,17 @@ log = "0.4" pollster = "0.3" wgpu = "22.0" bytemuck = { version = "1.16", features = [ "derive" ] } -anyhow = "1.0" \ No newline at end of file +anyhow = "1.0" +tobj = { version = "3.2", default-features = false, features = ["async"]} +fs_extra = "1.2" +glob = "0.3" + +[dependencies.image] +version = "0.24" +default-features = false +features = ["png", "jpeg"] + +[build-dependencies] +anyhow = "1.0" +fs_extra = "1.2" +glob = "0.3" \ No newline at end of file diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..1efecc6 --- /dev/null +++ b/build.rs @@ -0,0 +1,18 @@ +use anyhow::*; +use fs_extra::copy_items; +use fs_extra::dir::CopyOptions; +use std::env; + +fn main() -> Result<()> { + // This tells Cargo to rerun this script if something in /res/ changes. + println!("cargo:rerun-if-changed=res/*"); + + let out_dir = env::var("OUT_DIR")?; + let mut copy_options = CopyOptions::new(); + copy_options.overwrite = true; + let mut paths_to_copy = Vec::new(); + paths_to_copy.push("res/"); + copy_items(&paths_to_copy, out_dir, ©_options)?; + + Ok(()) +} \ No newline at end of file diff --git a/res/cube-diffuse.jpg b/res/cube-diffuse.jpg new file mode 100644 index 0000000..c89b31d Binary files /dev/null and b/res/cube-diffuse.jpg differ diff --git a/res/cube-normal.png b/res/cube-normal.png new file mode 100644 index 0000000..5bbac0a Binary files /dev/null and b/res/cube-normal.png differ diff --git a/res/cube.mtl b/res/cube.mtl new file mode 100644 index 0000000..6be388c --- /dev/null +++ b/res/cube.mtl @@ -0,0 +1,14 @@ +# Blender MTL File: 'cube.blend' +# Material Count: 1 + +newmtl Material.001 +Ns 323.999994 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 +map_Bump cube-normal.png +map_Kd cube-diffuse.jpg diff --git a/res/cube.obj b/res/cube.obj new file mode 100644 index 0000000..e6aecc8 --- /dev/null +++ b/res/cube.obj @@ -0,0 +1,933 @@ +# Blender v2.82 (sub 7) OBJ File: 'cube.blend' +# www.blender.org +mtllib cube.mtl +o Cube_Finished_Cube.001 +v 0.900000 0.900000 -1.000000 +v 0.900000 1.000000 -0.900000 +v 1.000000 0.900000 -0.900000 +v 0.900000 0.930907 -0.995104 +v 0.900000 0.958769 -0.980909 +v 0.930907 0.900000 -0.995104 +v 0.931727 0.931906 -0.989305 +v 0.930693 0.957414 -0.975905 +v 0.958769 0.900000 -0.980909 +v 0.957466 0.930772 -0.975834 +v 0.952912 0.952912 -0.966338 +v 0.930907 0.995104 -0.900000 +v 0.958769 0.980909 -0.900000 +v 0.900000 0.995104 -0.930907 +v 0.931906 0.989305 -0.931727 +v 0.957414 0.975905 -0.930693 +v 0.900000 0.980909 -0.958769 +v 0.930772 0.975834 -0.957466 +v 0.952912 0.966338 -0.952912 +v 0.995104 0.900000 -0.930907 +v 0.980909 0.900000 -0.958769 +v 0.995104 0.930907 -0.900000 +v 0.989305 0.931727 -0.931906 +v 0.975905 0.930693 -0.957414 +v 0.980909 0.958769 -0.900000 +v 0.975834 0.957466 -0.930772 +v 0.966338 0.952912 -0.952912 +v 0.900000 -1.000000 -0.900000 +v 0.900000 -0.900000 -1.000000 +v 1.000000 -0.900000 -0.900000 +v 0.900000 -0.995104 -0.930907 +v 0.900000 -0.980909 -0.958769 +v 0.930907 -0.995104 -0.900000 +v 0.931727 -0.989305 -0.931906 +v 0.930693 -0.975905 -0.957414 +v 0.958769 -0.980909 -0.900000 +v 0.957466 -0.975834 -0.930772 +v 0.952912 -0.966338 -0.952912 +v 0.930907 -0.900000 -0.995104 +v 0.958769 -0.900000 -0.980909 +v 0.900000 -0.930907 -0.995104 +v 0.931906 -0.931727 -0.989305 +v 0.957414 -0.930693 -0.975905 +v 0.900000 -0.958769 -0.980909 +v 0.930772 -0.957466 -0.975834 +v 0.952912 -0.952912 -0.966338 +v 0.995104 -0.930907 -0.900000 +v 0.980909 -0.958769 -0.900000 +v 0.995104 -0.900000 -0.930907 +v 0.989305 -0.931906 -0.931727 +v 0.975905 -0.957414 -0.930693 +v 0.980909 -0.900000 -0.958769 +v 0.975834 -0.930772 -0.957466 +v 0.966338 -0.952912 -0.952912 +v 1.000000 0.900000 0.900000 +v 0.900000 1.000000 0.900000 +v 0.900000 0.900000 1.000000 +v 0.995104 0.930907 0.900000 +v 0.980909 0.958769 0.900000 +v 0.995104 0.900000 0.930907 +v 0.989305 0.931906 0.931727 +v 0.975905 0.957414 0.930693 +v 0.980909 0.900000 0.958769 +v 0.975834 0.930772 0.957466 +v 0.966338 0.952912 0.952912 +v 0.900000 0.995104 0.930907 +v 0.900000 0.980909 0.958769 +v 0.930907 0.995104 0.900000 +v 0.931727 0.989305 0.931906 +v 0.930693 0.975905 0.957414 +v 0.958769 0.980909 0.900000 +v 0.957466 0.975834 0.930772 +v 0.952912 0.966338 0.952912 +v 0.930907 0.900000 0.995104 +v 0.958769 0.900000 0.980909 +v 0.900000 0.930907 0.995104 +v 0.931906 0.931727 0.989305 +v 0.957414 0.930693 0.975905 +v 0.900000 0.958769 0.980909 +v 0.930772 0.957466 0.975834 +v 0.952912 0.952912 0.966338 +v 1.000000 -0.900000 0.900000 +v 0.900000 -0.900000 1.000000 +v 0.900000 -1.000000 0.900000 +v 0.995104 -0.900000 0.930907 +v 0.980909 -0.900000 0.958769 +v 0.995104 -0.930907 0.900000 +v 0.989305 -0.931727 0.931906 +v 0.975905 -0.930693 0.957414 +v 0.980909 -0.958769 0.900000 +v 0.975834 -0.957466 0.930772 +v 0.966338 -0.952912 0.952912 +v 0.900000 -0.930907 0.995104 +v 0.900000 -0.958769 0.980909 +v 0.930907 -0.900000 0.995104 +v 0.931727 -0.931906 0.989305 +v 0.930693 -0.957414 0.975905 +v 0.958769 -0.900000 0.980909 +v 0.957466 -0.930772 0.975834 +v 0.952912 -0.952912 0.966338 +v 0.930907 -0.995104 0.900000 +v 0.958769 -0.980909 0.900000 +v 0.900000 -0.995104 0.930907 +v 0.931906 -0.989305 0.931727 +v 0.957414 -0.975905 0.930693 +v 0.900000 -0.980909 0.958769 +v 0.930772 -0.975834 0.957466 +v 0.952912 -0.966338 0.952912 +v -0.900000 0.900000 -1.000000 +v -1.000000 0.900000 -0.900000 +v -0.900000 1.000000 -0.900000 +v -0.930907 0.900000 -0.995104 +v -0.958769 0.900000 -0.980909 +v -0.900000 0.930907 -0.995104 +v -0.931906 0.931727 -0.989305 +v -0.957414 0.930693 -0.975905 +v -0.900000 0.958769 -0.980909 +v -0.930772 0.957466 -0.975834 +v -0.952912 0.952912 -0.966338 +v -0.995104 0.930907 -0.900000 +v -0.980909 0.958769 -0.900000 +v -0.995104 0.900000 -0.930907 +v -0.989305 0.931906 -0.931727 +v -0.975905 0.957414 -0.930693 +v -0.980909 0.900000 -0.958769 +v -0.975834 0.930772 -0.957466 +v -0.966338 0.952912 -0.952912 +v -0.900000 0.995104 -0.930907 +v -0.900000 0.980909 -0.958769 +v -0.930907 0.995104 -0.900000 +v -0.931727 0.989305 -0.931906 +v -0.930693 0.975905 -0.957414 +v -0.958769 0.980909 -0.900000 +v -0.957466 0.975834 -0.930772 +v -0.952912 0.966338 -0.952912 +v -1.000000 -0.900000 -0.900000 +v -0.900000 -0.900000 -1.000000 +v -0.900000 -1.000000 -0.900000 +v -0.995104 -0.900000 -0.930907 +v -0.980909 -0.900000 -0.958769 +v -0.995104 -0.930907 -0.900000 +v -0.989305 -0.931727 -0.931906 +v -0.975905 -0.930693 -0.957414 +v -0.980909 -0.958769 -0.900000 +v -0.975834 -0.957466 -0.930772 +v -0.966338 -0.952912 -0.952912 +v -0.900000 -0.930907 -0.995104 +v -0.900000 -0.958769 -0.980909 +v -0.930907 -0.900000 -0.995104 +v -0.931727 -0.931906 -0.989305 +v -0.930693 -0.957414 -0.975905 +v -0.958769 -0.900000 -0.980909 +v -0.957466 -0.930772 -0.975834 +v -0.952912 -0.952912 -0.966338 +v -0.930907 -0.995104 -0.900000 +v -0.958769 -0.980909 -0.900000 +v -0.900000 -0.995104 -0.930907 +v -0.931906 -0.989305 -0.931727 +v -0.957414 -0.975905 -0.930693 +v -0.900000 -0.980909 -0.958769 +v -0.930772 -0.975834 -0.957466 +v -0.952912 -0.966338 -0.952912 +v -1.000000 0.900000 0.900000 +v -0.900000 0.900000 1.000000 +v -0.900000 1.000000 0.900000 +v -0.995104 0.900000 0.930907 +v -0.980909 0.900000 0.958769 +v -0.995104 0.930907 0.900000 +v -0.989305 0.931727 0.931906 +v -0.975905 0.930693 0.957414 +v -0.980909 0.958769 0.900000 +v -0.975834 0.957466 0.930772 +v -0.966338 0.952912 0.952912 +v -0.900000 0.930907 0.995104 +v -0.900000 0.958769 0.980909 +v -0.930907 0.900000 0.995104 +v -0.931727 0.931906 0.989305 +v -0.930693 0.957414 0.975905 +v -0.958769 0.900000 0.980909 +v -0.957466 0.930772 0.975834 +v -0.952912 0.952912 0.966338 +v -0.930907 0.995104 0.900000 +v -0.958769 0.980909 0.900000 +v -0.900000 0.995104 0.930907 +v -0.931906 0.989305 0.931727 +v -0.957414 0.975905 0.930693 +v -0.900000 0.980909 0.958769 +v -0.930772 0.975834 0.957466 +v -0.952912 0.966338 0.952912 +v -0.900000 -1.000000 0.900000 +v -0.900000 -0.900000 1.000000 +v -1.000000 -0.900000 0.900000 +v -0.900000 -0.995104 0.930907 +v -0.900000 -0.980909 0.958769 +v -0.930907 -0.995104 0.900000 +v -0.931727 -0.989305 0.931906 +v -0.930693 -0.975905 0.957414 +v -0.958769 -0.980909 0.900000 +v -0.957466 -0.975834 0.930772 +v -0.952912 -0.966338 0.952912 +v -0.930907 -0.900000 0.995104 +v -0.958769 -0.900000 0.980909 +v -0.900000 -0.930907 0.995104 +v -0.931906 -0.931727 0.989305 +v -0.957414 -0.930693 0.975905 +v -0.900000 -0.958769 0.980909 +v -0.930772 -0.957466 0.975834 +v -0.952912 -0.952912 0.966338 +v -0.995104 -0.930907 0.900000 +v -0.980909 -0.958769 0.900000 +v -0.995104 -0.900000 0.930907 +v -0.989305 -0.931906 0.931727 +v -0.975905 -0.957414 0.930693 +v -0.980909 -0.900000 0.958769 +v -0.975834 -0.930772 0.957466 +v -0.966338 -0.952912 0.952912 +vt 0.137500 0.512500 +vt 0.362500 0.512500 +vt 0.362500 0.737500 +vt 0.137500 0.737500 +vt 0.387500 0.012500 +vt 0.612500 0.012500 +vt 0.612500 0.237500 +vt 0.387500 0.237500 +vt 0.387500 0.762500 +vt 0.612500 0.762500 +vt 0.612500 0.987500 +vt 0.387500 0.987500 +vt 0.637500 0.512500 +vt 0.862500 0.512500 +vt 0.862500 0.737500 +vt 0.637500 0.737500 +vt 0.387500 0.512500 +vt 0.612500 0.512500 +vt 0.612500 0.737500 +vt 0.387500 0.737500 +vt 0.612500 0.487500 +vt 0.616363 0.487500 +vt 0.616488 0.491466 +vt 0.612500 0.491363 +vt 0.619846 0.487500 +vt 0.619677 0.491337 +vt 0.625000 0.487500 +vt 0.625000 0.491347 +vt 0.616346 0.494683 +vt 0.612500 0.494846 +vt 0.619114 0.494114 +vt 0.625000 0.494114 +vt 0.633637 0.512500 +vt 0.633512 0.508534 +vt 0.637500 0.508637 +vt 0.630154 0.512500 +vt 0.630323 0.508663 +vt 0.619846 0.512500 +vt 0.619683 0.508653 +vt 0.633654 0.505317 +vt 0.637500 0.505154 +vt 0.630886 0.505886 +vt 0.619114 0.505886 +vt 0.612500 0.508637 +vt 0.616466 0.508512 +vt 0.616363 0.512500 +vt 0.612500 0.505154 +vt 0.616337 0.505323 +vt 0.619114 0.500000 +vt 0.362500 0.508637 +vt 0.366466 0.508512 +vt 0.366363 0.512500 +vt 0.362500 0.505154 +vt 0.366337 0.505323 +vt 0.362500 0.500000 +vt 0.366347 0.500000 +vt 0.369683 0.508653 +vt 0.369846 0.512500 +vt 0.369114 0.505886 +vt 0.369114 0.500000 +vt 0.387500 0.487500 +vt 0.387500 0.491363 +vt 0.383534 0.491488 +vt 0.383637 0.487500 +vt 0.387500 0.494846 +vt 0.383663 0.494677 +vt 0.387500 0.505154 +vt 0.383653 0.505317 +vt 0.380317 0.491346 +vt 0.380154 0.487500 +vt 0.380886 0.494114 +vt 0.380886 0.505886 +vt 0.383637 0.512500 +vt 0.383512 0.508534 +vt 0.387500 0.508637 +vt 0.380154 0.512500 +vt 0.380323 0.508663 +vt 0.375000 0.505886 +vt 0.616363 0.737500 +vt 0.616488 0.741466 +vt 0.612500 0.741363 +vt 0.619846 0.737500 +vt 0.619677 0.741337 +vt 0.630154 0.737500 +vt 0.630317 0.741346 +vt 0.616346 0.744683 +vt 0.612500 0.744846 +vt 0.619114 0.744114 +vt 0.630886 0.744114 +vt 0.637500 0.741363 +vt 0.633534 0.741488 +vt 0.633637 0.737500 +vt 0.637500 0.744846 +vt 0.633664 0.744677 +vt 0.637500 0.750000 +vt 0.633653 0.750000 +vt 0.630886 0.750000 +vt 0.612500 0.758637 +vt 0.616466 0.758512 +vt 0.616363 0.762500 +vt 0.612500 0.755154 +vt 0.616337 0.755323 +vt 0.619683 0.758653 +vt 0.619846 0.762500 +vt 0.619114 0.755886 +vt 0.625000 0.744114 +vt 0.619114 0.750000 +vt 0.387500 0.741363 +vt 0.383534 0.741488 +vt 0.383637 0.737500 +vt 0.387500 0.744846 +vt 0.383663 0.744677 +vt 0.387500 0.755154 +vt 0.383653 0.755317 +vt 0.380317 0.741346 +vt 0.380154 0.737500 +vt 0.380886 0.744114 +vt 0.380886 0.755886 +vt 0.383637 0.762500 +vt 0.383512 0.758534 +vt 0.387500 0.758637 +vt 0.380154 0.762500 +vt 0.380323 0.758663 +vt 0.375000 0.762500 +vt 0.375000 0.758654 +vt 0.375000 0.755886 +vt 0.366363 0.737500 +vt 0.366488 0.741466 +vt 0.362500 0.741363 +vt 0.369846 0.737500 +vt 0.369677 0.741337 +vt 0.366347 0.744683 +vt 0.362500 0.744846 +vt 0.369114 0.744114 +vt 0.380886 0.750000 +vt 0.375000 0.744114 +vt 0.612500 0.262500 +vt 0.612500 0.258637 +vt 0.616466 0.258512 +vt 0.616363 0.262500 +vt 0.612500 0.255154 +vt 0.616337 0.255323 +vt 0.612500 0.244846 +vt 0.616346 0.244683 +vt 0.619683 0.258653 +vt 0.619846 0.262500 +vt 0.619114 0.255886 +vt 0.619114 0.244114 +vt 0.616363 0.237500 +vt 0.616488 0.241466 +vt 0.612500 0.241363 +vt 0.619846 0.237500 +vt 0.619677 0.241337 +vt 0.625000 0.237500 +vt 0.625000 0.241347 +vt 0.625000 0.244114 +vt 0.862500 0.508637 +vt 0.866466 0.508512 +vt 0.866363 0.512500 +vt 0.862500 0.505154 +vt 0.866337 0.505323 +vt 0.862500 0.500000 +vt 0.866347 0.500000 +vt 0.869683 0.508653 +vt 0.869846 0.512500 +vt 0.869114 0.505886 +vt 0.869114 0.500000 +vt 0.619114 0.250000 +vt 0.625000 0.255886 +vt 0.387500 0.241363 +vt 0.383534 0.241488 +vt 0.383637 0.237500 +vt 0.387500 0.244846 +vt 0.383663 0.244677 +vt 0.387500 0.255154 +vt 0.383653 0.255317 +vt 0.380317 0.241346 +vt 0.380154 0.237500 +vt 0.380886 0.244114 +vt 0.380886 0.255886 +vt 0.387500 0.262500 +vt 0.383637 0.262500 +vt 0.383512 0.258534 +vt 0.387500 0.258637 +vt 0.380154 0.262500 +vt 0.380323 0.258663 +vt 0.375000 0.262500 +vt 0.375000 0.258653 +vt 0.375000 0.255886 +vt 0.133637 0.512500 +vt 0.133512 0.508534 +vt 0.137500 0.508637 +vt 0.130154 0.512500 +vt 0.130323 0.508663 +vt 0.125000 0.512500 +vt 0.125000 0.508654 +vt 0.133653 0.505317 +vt 0.137500 0.505154 +vt 0.130886 0.505886 +vt 0.125000 0.505886 +vt 0.380886 0.250000 +vt 0.375000 0.244114 +vt 0.612500 0.008637 +vt 0.616466 0.008512 +vt 0.616363 0.012500 +vt 0.612500 0.005154 +vt 0.616337 0.005323 +vt 0.612500 0.000000 +vt 0.616346 0.000000 +vt 0.619683 0.008654 +vt 0.619846 0.012500 +vt 0.619114 0.005886 +vt 0.619114 0.000000 +vt 0.616363 0.987500 +vt 0.616488 0.991466 +vt 0.612500 0.991363 +vt 0.619846 0.987500 +vt 0.619677 0.991337 +vt 0.625000 0.987500 +vt 0.625000 0.991346 +vt 0.616346 0.994683 +vt 0.612500 0.994846 +vt 0.619114 0.994114 +vt 0.625000 0.994114 +vt 0.866363 0.737500 +vt 0.866488 0.741466 +vt 0.862500 0.741363 +vt 0.869846 0.737500 +vt 0.869677 0.741337 +vt 0.875000 0.737500 +vt 0.875000 0.741347 +vt 0.866346 0.744683 +vt 0.862500 0.744846 +vt 0.869114 0.744114 +vt 0.875000 0.744114 +vt 0.625000 0.005886 +vt 0.137500 0.741363 +vt 0.133534 0.741488 +vt 0.133637 0.737500 +vt 0.137500 0.744846 +vt 0.133663 0.744677 +vt 0.137500 0.750000 +vt 0.133653 0.750000 +vt 0.130317 0.741346 +vt 0.130154 0.737500 +vt 0.130886 0.744114 +vt 0.130886 0.750000 +vt 0.387500 0.991363 +vt 0.383534 0.991488 +vt 0.383637 0.987500 +vt 0.387500 0.994846 +vt 0.383663 0.994677 +vt 0.387500 1.000000 +vt 0.383654 1.000000 +vt 0.380317 0.991346 +vt 0.380154 0.987500 +vt 0.380886 0.994114 +vt 0.380886 1.000000 +vt 0.383637 0.012500 +vt 0.383512 0.008534 +vt 0.387500 0.008637 +vt 0.380154 0.012500 +vt 0.380323 0.008663 +vt 0.375000 0.012500 +vt 0.375000 0.008653 +vt 0.383653 0.005317 +vt 0.387500 0.005154 +vt 0.380886 0.005886 +vt 0.375000 0.005886 +vt 0.125000 0.744114 +vt 0.125000 0.737500 +vt 0.137500 0.500000 +vt 0.612500 1.000000 +vt 0.862500 0.750000 +vt 0.362500 0.750000 +vt 0.875000 0.512500 +vt 0.637500 0.500000 +vn -0.0802 -0.9935 -0.0802 +vn 0.0802 -0.9935 -0.0802 +vn 0.0802 -0.9935 0.0802 +vn -0.0802 -0.9935 0.0802 +vn -0.9935 -0.0802 0.0802 +vn -0.9935 0.0802 0.0802 +vn -0.9935 0.0802 -0.0802 +vn -0.9935 -0.0802 -0.0802 +vn 0.0802 -0.0802 0.9935 +vn 0.0802 0.0802 0.9935 +vn -0.0802 0.0802 0.9935 +vn -0.0802 -0.0802 0.9935 +vn 0.0802 0.9935 -0.0802 +vn -0.0802 0.9935 -0.0802 +vn -0.0802 0.9935 0.0802 +vn 0.0802 0.9935 0.0802 +vn 0.9935 -0.0802 -0.0802 +vn 0.9935 0.0802 -0.0802 +vn 0.9935 0.0802 0.0802 +vn 0.9935 -0.0802 0.0802 +vn 0.0802 0.0802 -0.9935 +vn 0.0801 0.3083 -0.9479 +vn 0.3068 0.3077 -0.9006 +vn 0.3084 0.0804 -0.9478 +vn 0.0754 0.5855 -0.8071 +vn 0.2854 0.5696 -0.7707 +vn 0.0757 0.8072 -0.5853 +vn 0.2858 0.7704 -0.5698 +vn 0.5698 0.2858 -0.7704 +vn 0.5853 0.0757 -0.8072 +vn 0.5155 0.5155 -0.6844 +vn 0.5155 0.6844 -0.5155 +vn 0.3083 0.9479 -0.0801 +vn 0.3077 0.9006 -0.3068 +vn 0.0804 0.9478 -0.3084 +vn 0.5855 0.8071 -0.0754 +vn 0.5696 0.7707 -0.2854 +vn 0.8072 0.5853 -0.0757 +vn 0.7704 0.5698 -0.2858 +vn 0.6844 0.5155 -0.5155 +vn 0.9479 0.0801 -0.3083 +vn 0.9006 0.3068 -0.3077 +vn 0.9478 0.3084 -0.0804 +vn 0.8071 0.0754 -0.5855 +vn 0.7707 0.2854 -0.5696 +vn 0.0801 -0.9479 -0.3083 +vn 0.3068 -0.9006 -0.3077 +vn 0.3084 -0.9478 -0.0804 +vn 0.0754 -0.8071 -0.5855 +vn 0.2854 -0.7707 -0.5696 +vn 0.0757 -0.5853 -0.8072 +vn 0.2858 -0.5698 -0.7704 +vn 0.5698 -0.7704 -0.2858 +vn 0.5853 -0.8072 -0.0757 +vn 0.5155 -0.6844 -0.5155 +vn 0.5155 -0.5155 -0.6844 +vn 0.0802 -0.0802 -0.9935 +vn 0.3083 -0.0801 -0.9479 +vn 0.3077 -0.3068 -0.9006 +vn 0.0804 -0.3084 -0.9478 +vn 0.5855 -0.0754 -0.8071 +vn 0.5696 -0.2854 -0.7707 +vn 0.8072 -0.0757 -0.5853 +vn 0.7704 -0.2858 -0.5698 +vn 0.6844 -0.5155 -0.5155 +vn 0.9479 -0.3083 -0.0801 +vn 0.9006 -0.3077 -0.3068 +vn 0.9478 -0.0804 -0.3084 +vn 0.8071 -0.5855 -0.0754 +vn 0.7707 -0.5696 -0.2854 +vn 0.9479 0.3083 0.0801 +vn 0.9006 0.3077 0.3068 +vn 0.9478 0.0804 0.3084 +vn 0.8071 0.5855 0.0754 +vn 0.7707 0.5696 0.2854 +vn 0.5853 0.8072 0.0757 +vn 0.5698 0.7704 0.2858 +vn 0.7704 0.2858 0.5698 +vn 0.8072 0.0757 0.5853 +vn 0.6844 0.5155 0.5155 +vn 0.5155 0.6844 0.5155 +vn 0.0801 0.9479 0.3083 +vn 0.3068 0.9006 0.3077 +vn 0.3084 0.9478 0.0804 +vn 0.0754 0.8071 0.5855 +vn 0.2854 0.7707 0.5696 +vn 0.0757 0.5853 0.8072 +vn 0.2858 0.5698 0.7704 +vn 0.5155 0.5155 0.6844 +vn 0.3083 0.0801 0.9479 +vn 0.3077 0.3068 0.9006 +vn 0.0804 0.3084 0.9478 +vn 0.5855 0.0754 0.8071 +vn 0.5696 0.2854 0.7707 +vn 0.9479 -0.0801 0.3083 +vn 0.9006 -0.3068 0.3077 +vn 0.9478 -0.3084 0.0804 +vn 0.8071 -0.0754 0.5855 +vn 0.7707 -0.2854 0.5696 +vn 0.5853 -0.0757 0.8072 +vn 0.5698 -0.2858 0.7704 +vn 0.7704 -0.5698 0.2858 +vn 0.8072 -0.5853 0.0757 +vn 0.6844 -0.5155 0.5155 +vn 0.5155 -0.5155 0.6844 +vn 0.0801 -0.3083 0.9479 +vn 0.3068 -0.3077 0.9006 +vn 0.3084 -0.0804 0.9478 +vn 0.0754 -0.5855 0.8071 +vn 0.2854 -0.5696 0.7707 +vn 0.0757 -0.8072 0.5853 +vn 0.2858 -0.7704 0.5698 +vn 0.5155 -0.6844 0.5155 +vn 0.3083 -0.9479 0.0801 +vn 0.3077 -0.9006 0.3068 +vn 0.0804 -0.9478 0.3084 +vn 0.5855 -0.8071 0.0754 +vn 0.5696 -0.7707 0.2854 +vn -0.0802 0.0802 -0.9935 +vn -0.3083 0.0801 -0.9479 +vn -0.3077 0.3068 -0.9006 +vn -0.0804 0.3084 -0.9478 +vn -0.5855 0.0754 -0.8071 +vn -0.5696 0.2854 -0.7707 +vn -0.8072 0.0757 -0.5853 +vn -0.7704 0.2858 -0.5698 +vn -0.2858 0.5698 -0.7704 +vn -0.0757 0.5853 -0.8072 +vn -0.5155 0.5155 -0.6844 +vn -0.6844 0.5155 -0.5155 +vn -0.9479 0.3083 -0.0801 +vn -0.9006 0.3077 -0.3068 +vn -0.9478 0.0804 -0.3084 +vn -0.8071 0.5855 -0.0754 +vn -0.7707 0.5696 -0.2854 +vn -0.5853 0.8072 -0.0757 +vn -0.5698 0.7704 -0.2858 +vn -0.5155 0.6844 -0.5155 +vn -0.0801 0.9479 -0.3083 +vn -0.3068 0.9006 -0.3077 +vn -0.3084 0.9478 -0.0804 +vn -0.0754 0.8071 -0.5855 +vn -0.2854 0.7707 -0.5696 +vn -0.9479 -0.0801 -0.3083 +vn -0.9006 -0.3068 -0.3077 +vn -0.9478 -0.3084 -0.0804 +vn -0.8071 -0.0754 -0.5855 +vn -0.7707 -0.2854 -0.5696 +vn -0.5853 -0.0757 -0.8072 +vn -0.5698 -0.2858 -0.7704 +vn -0.7704 -0.5698 -0.2858 +vn -0.8072 -0.5853 -0.0757 +vn -0.6844 -0.5155 -0.5155 +vn -0.5155 -0.5155 -0.6844 +vn -0.0802 -0.0802 -0.9935 +vn -0.0801 -0.3083 -0.9479 +vn -0.3068 -0.3077 -0.9006 +vn -0.3084 -0.0804 -0.9478 +vn -0.0754 -0.5855 -0.8071 +vn -0.2854 -0.5696 -0.7707 +vn -0.0757 -0.8072 -0.5853 +vn -0.2858 -0.7704 -0.5698 +vn -0.5155 -0.6844 -0.5155 +vn -0.3083 -0.9479 -0.0801 +vn -0.3077 -0.9006 -0.3068 +vn -0.0804 -0.9478 -0.3084 +vn -0.5855 -0.8071 -0.0754 +vn -0.5696 -0.7707 -0.2854 +vn -0.9479 0.0801 0.3083 +vn -0.9006 0.3068 0.3077 +vn -0.9478 0.3084 0.0804 +vn -0.8071 0.0754 0.5855 +vn -0.7707 0.2854 0.5696 +vn -0.5853 0.0757 0.8072 +vn -0.5698 0.2858 0.7704 +vn -0.7704 0.5698 0.2858 +vn -0.8072 0.5853 0.0757 +vn -0.6844 0.5155 0.5155 +vn -0.5155 0.5155 0.6844 +vn -0.0801 0.3083 0.9479 +vn -0.3068 0.3077 0.9006 +vn -0.3084 0.0804 0.9478 +vn -0.0754 0.5855 0.8071 +vn -0.2854 0.5696 0.7707 +vn -0.0757 0.8072 0.5853 +vn -0.2858 0.7704 0.5698 +vn -0.5155 0.6844 0.5155 +vn -0.3083 0.9479 0.0801 +vn -0.3077 0.9006 0.3068 +vn -0.0804 0.9478 0.3084 +vn -0.5855 0.8071 0.0754 +vn -0.5696 0.7707 0.2854 +vn -0.0801 -0.9479 0.3083 +vn -0.3068 -0.9006 0.3077 +vn -0.3084 -0.9478 0.0804 +vn -0.0754 -0.8071 0.5855 +vn -0.2854 -0.7707 0.5696 +vn -0.0757 -0.5853 0.8072 +vn -0.2858 -0.5698 0.7704 +vn -0.5698 -0.7704 0.2858 +vn -0.5853 -0.8072 0.0757 +vn -0.5155 -0.6844 0.5155 +vn -0.5155 -0.5155 0.6844 +vn -0.3083 -0.0801 0.9479 +vn -0.3077 -0.3068 0.9006 +vn -0.0804 -0.3084 0.9478 +vn -0.5855 -0.0754 0.8071 +vn -0.5696 -0.2854 0.7707 +vn -0.8072 -0.0757 0.5853 +vn -0.7704 -0.2858 0.5698 +vn -0.6844 -0.5155 0.5155 +vn -0.9479 -0.3083 0.0801 +vn -0.9006 -0.3077 0.3068 +vn -0.9478 -0.0804 0.3084 +vn -0.8071 -0.5855 0.0754 +vn -0.7707 -0.5696 0.2854 +usemtl Material.001 +s 1 +f 138/1/1 28/2/2 84/3/3 190/4/4 +f 192/5/5 163/6/6 110/7/7 136/8/8 +f 83/9/9 57/10/10 164/11/11 191/12/12 +f 2/13/13 111/14/14 165/15/15 56/16/16 +f 30/17/17 3/18/18 55/19/19 82/20/20 +f 1/21/21 4/22/22 7/23/23 6/24/24 +f 4/22/22 5/25/25 8/26/26 7/23/23 +f 5/25/25 17/27/27 18/28/28 8/26/26 +f 6/24/24 7/23/23 10/29/29 9/30/30 +f 7/23/23 8/26/26 11/31/31 10/29/29 +f 8/26/26 18/28/28 19/32/32 11/31/31 +f 2/13/13 12/33/33 15/34/34 14/35/35 +f 12/33/33 13/36/36 16/37/37 15/34/34 +f 13/36/36 25/38/38 26/39/39 16/37/37 +f 14/35/35 15/34/34 18/40/28 17/41/27 +f 15/34/34 16/37/37 19/42/32 18/40/28 +f 16/37/37 26/39/39 27/43/40 19/42/32 +f 3/18/18 20/44/41 23/45/42 22/46/43 +f 20/44/41 21/47/44 24/48/45 23/45/42 +f 21/47/44 9/30/30 10/29/29 24/48/45 +f 22/46/43 23/45/42 26/39/39 25/38/38 +f 23/45/42 24/48/45 27/43/40 26/39/39 +f 24/48/45 10/29/29 11/31/31 27/43/40 +f 11/31/31 19/32/32 27/49/40 +f 28/2/2 31/50/46 34/51/47 33/52/48 +f 31/50/46 32/53/49 35/54/50 34/51/47 +f 32/53/49 44/55/51 45/56/52 35/54/50 +f 33/52/48 34/51/47 37/57/53 36/58/54 +f 34/51/47 35/54/50 38/59/55 37/57/53 +f 35/54/50 45/56/52 46/60/56 38/59/55 +f 29/61/57 39/62/58 42/63/59 41/64/60 +f 39/62/58 40/65/61 43/66/62 42/63/59 +f 40/65/61 52/67/63 53/68/64 43/66/62 +f 41/64/60 42/63/59 45/69/52 44/70/51 +f 42/63/59 43/66/62 46/71/56 45/69/52 +f 43/66/62 53/68/64 54/72/65 46/71/56 +f 30/17/17 47/73/66 50/74/67 49/75/68 +f 47/73/66 48/76/69 51/77/70 50/74/67 +f 48/76/69 36/58/54 37/57/53 51/77/70 +f 49/75/68 50/74/67 53/68/64 52/67/63 +f 50/74/67 51/77/70 54/72/65 53/68/64 +f 51/77/70 37/57/53 38/59/55 54/72/65 +f 38/59/55 46/60/56 54/78/65 +f 55/19/19 58/79/71 61/80/72 60/81/73 +f 58/79/71 59/82/74 62/83/75 61/80/72 +f 59/82/74 71/84/76 72/85/77 62/83/75 +f 60/81/73 61/80/72 64/86/78 63/87/79 +f 61/80/72 62/83/75 65/88/80 64/86/78 +f 62/83/75 72/85/77 73/89/81 65/88/80 +f 56/16/16 66/90/82 69/91/83 68/92/84 +f 66/90/82 67/93/85 70/94/86 69/91/83 +f 67/93/85 79/95/87 80/96/88 70/94/86 +f 68/92/84 69/91/83 72/85/77 71/84/76 +f 69/91/83 70/94/86 73/89/81 72/85/77 +f 70/94/86 80/96/88 81/97/89 73/89/81 +f 57/10/10 74/98/90 77/99/91 76/100/92 +f 74/98/90 75/101/93 78/102/94 77/99/91 +f 75/101/93 63/87/79 64/86/78 78/102/94 +f 76/100/92 77/99/91 80/103/88 79/104/87 +f 77/99/91 78/102/94 81/105/89 80/103/88 +f 78/102/94 64/86/78 65/88/80 81/105/89 +f 65/88/80 73/106/81 81/107/89 +f 82/20/20 85/108/95 88/109/96 87/110/97 +f 85/108/95 86/111/98 89/112/99 88/109/96 +f 86/111/98 98/113/100 99/114/101 89/112/99 +f 87/110/97 88/109/96 91/115/102 90/116/103 +f 88/109/96 89/112/99 92/117/104 91/115/102 +f 89/112/99 99/114/101 100/118/105 92/117/104 +f 83/9/9 93/119/106 96/120/107 95/121/108 +f 93/119/106 94/122/109 97/123/110 96/120/107 +f 94/122/109 106/124/111 107/125/112 97/123/110 +f 95/121/108 96/120/107 99/114/101 98/113/100 +f 96/120/107 97/123/110 100/118/105 99/114/101 +f 97/123/110 107/125/112 108/126/113 100/118/105 +f 84/3/3 101/127/114 104/128/115 103/129/116 +f 101/127/114 102/130/117 105/131/118 104/128/115 +f 102/130/117 90/116/103 91/115/102 105/131/118 +f 103/129/116 104/128/115 107/132/112 106/133/111 +f 104/128/115 105/131/118 108/134/113 107/132/112 +f 105/131/118 91/115/102 92/117/104 108/134/113 +f 92/117/104 100/135/105 108/136/113 +f 109/137/119 112/138/120 115/139/121 114/140/122 +f 112/138/120 113/141/123 116/142/124 115/139/121 +f 113/141/123 125/143/125 126/144/126 116/142/124 +f 114/140/122 115/139/121 118/145/127 117/146/128 +f 115/139/121 116/142/124 119/147/129 118/145/127 +f 116/142/124 126/144/126 127/148/130 119/147/129 +f 110/7/7 120/149/131 123/150/132 122/151/133 +f 120/149/131 121/152/134 124/153/135 123/150/132 +f 121/152/134 133/154/136 134/155/137 124/153/135 +f 122/151/133 123/150/132 126/144/126 125/143/125 +f 123/150/132 124/153/135 127/148/130 126/144/126 +f 124/153/135 134/155/137 135/156/138 127/148/130 +f 111/14/14 128/157/139 131/158/140 130/159/141 +f 128/157/139 129/160/142 132/161/143 131/158/140 +f 129/160/142 117/162/128 118/163/127 132/161/143 +f 130/159/141 131/158/140 134/164/137 133/165/136 +f 131/158/140 132/161/143 135/166/138 134/164/137 +f 132/161/143 118/163/127 119/167/129 135/166/138 +f 119/147/129 127/168/130 135/169/138 +f 136/8/8 139/170/144 142/171/145 141/172/146 +f 139/170/144 140/173/147 143/174/148 142/171/145 +f 140/173/147 152/175/149 153/176/150 143/174/148 +f 141/172/146 142/171/145 145/177/151 144/178/152 +f 142/171/145 143/174/148 146/179/153 145/177/151 +f 143/174/148 153/176/150 154/180/154 146/179/153 +f 137/181/155 147/182/156 150/183/157 149/184/158 +f 147/182/156 148/185/159 151/186/160 150/183/157 +f 148/185/159 160/187/161 161/188/162 151/186/160 +f 149/184/158 150/183/157 153/176/150 152/175/149 +f 150/183/157 151/186/160 154/180/154 153/176/150 +f 151/186/160 161/188/162 162/189/163 154/180/154 +f 138/1/1 155/190/164 158/191/165 157/192/166 +f 155/190/164 156/193/167 159/194/168 158/191/165 +f 156/193/167 144/195/152 145/196/151 159/194/168 +f 157/192/166 158/191/165 161/197/162 160/198/161 +f 158/191/165 159/194/168 162/199/163 161/197/162 +f 159/194/168 145/196/151 146/200/153 162/199/163 +f 146/179/153 154/201/154 162/202/163 +f 163/6/6 166/203/169 169/204/170 168/205/171 +f 166/203/169 167/206/172 170/207/173 169/204/170 +f 167/206/172 179/208/174 180/209/175 170/207/173 +f 168/205/171 169/204/170 172/210/176 171/211/177 +f 169/204/170 170/207/173 173/212/178 172/210/176 +f 170/207/173 180/209/175 181/213/179 173/212/178 +f 164/11/11 174/214/180 177/215/181 176/216/182 +f 174/214/180 175/217/183 178/218/184 177/215/181 +f 175/217/183 187/219/185 188/220/186 178/218/184 +f 176/216/182 177/215/181 180/221/175 179/222/174 +f 177/215/181 178/218/184 181/223/179 180/221/175 +f 178/218/184 188/220/186 189/224/187 181/223/179 +f 165/15/15 182/225/188 185/226/189 184/227/190 +f 182/225/188 183/228/191 186/229/192 185/226/189 +f 183/228/191 171/230/177 172/231/176 186/229/192 +f 184/227/190 185/226/189 188/232/186 187/233/185 +f 185/226/189 186/229/192 189/234/187 188/232/186 +f 186/229/192 172/231/176 173/235/178 189/234/187 +f 173/212/178 181/213/179 189/236/187 +f 190/4/4 193/237/193 196/238/194 195/239/195 +f 193/237/193 194/240/196 197/241/197 196/238/194 +f 194/240/196 206/242/198 207/243/199 197/241/197 +f 195/239/195 196/238/194 199/244/200 198/245/201 +f 196/238/194 197/241/197 200/246/202 199/244/200 +f 197/241/197 207/243/199 208/247/203 200/246/202 +f 191/12/12 201/248/204 204/249/205 203/250/206 +f 201/248/204 202/251/207 205/252/208 204/249/205 +f 202/251/207 214/253/209 215/254/210 205/252/208 +f 203/250/206 204/249/205 207/255/199 206/256/198 +f 204/249/205 205/252/208 208/257/203 207/255/199 +f 205/252/208 215/254/210 216/258/211 208/257/203 +f 192/5/5 209/259/212 212/260/213 211/261/214 +f 209/259/212 210/262/215 213/263/216 212/260/213 +f 210/262/215 198/264/201 199/265/200 213/263/216 +f 211/261/214 212/260/213 215/266/210 214/267/209 +f 212/260/213 213/263/216 216/268/211 215/266/210 +f 213/263/216 199/265/200 200/269/202 216/268/211 +f 200/246/202 208/247/203 216/270/211 +f 138/1/1 190/4/4 195/239/195 155/190/164 +f 155/190/164 195/239/195 198/245/201 156/193/167 +f 156/193/167 198/245/201 210/271/215 144/195/152 +f 144/178/152 210/262/215 209/259/212 141/172/146 +f 141/172/146 209/259/212 192/5/5 136/8/8 +f 28/2/2 138/1/1 157/192/166 31/50/46 +f 31/50/46 157/192/166 160/198/161 32/53/49 +f 32/53/49 160/198/161 148/272/159 44/55/51 +f 44/70/51 148/185/159 147/182/156 41/64/60 +f 41/64/60 147/182/156 137/181/155 29/61/57 +f 3/18/18 30/17/17 49/75/68 20/44/41 +f 20/44/41 49/75/68 52/67/63 21/47/44 +f 21/47/44 52/67/63 40/65/61 9/30/30 +f 9/30/30 40/65/61 39/62/58 6/24/24 +f 6/24/24 39/62/58 29/61/57 1/21/21 +f 191/12/12 164/11/11 176/216/182 201/248/204 +f 201/248/204 176/216/182 179/222/174 202/251/207 +f 202/251/207 179/222/174 167/273/172 214/253/209 +f 214/267/209 167/206/172 166/203/169 211/261/214 +f 211/261/214 166/203/169 163/6/6 192/5/5 +f 57/10/10 83/9/9 95/121/108 74/98/90 +f 74/98/90 95/121/108 98/113/100 75/101/93 +f 75/101/93 98/113/100 86/111/98 63/87/79 +f 63/87/79 86/111/98 85/108/95 60/81/73 +f 60/81/73 85/108/95 82/20/20 55/19/19 +f 109/137/119 137/181/155 149/184/158 112/138/120 +f 112/138/120 149/184/158 152/175/149 113/141/123 +f 113/141/123 152/175/149 140/173/147 125/143/125 +f 125/143/125 140/173/147 139/170/144 122/151/133 +f 122/151/133 139/170/144 136/8/8 110/7/7 +f 56/16/16 165/15/15 184/227/190 66/90/82 +f 66/90/82 184/227/190 187/233/185 67/93/85 +f 67/93/85 187/233/185 175/274/183 79/95/87 +f 79/104/87 175/217/183 174/214/180 76/100/92 +f 76/100/92 174/214/180 164/11/11 57/10/10 +f 2/13/13 56/16/16 68/92/84 12/33/33 +f 12/33/33 68/92/84 71/84/76 13/36/36 +f 13/36/36 71/84/76 59/82/74 25/38/38 +f 25/38/38 59/82/74 58/79/71 22/46/43 +f 22/46/43 58/79/71 55/19/19 3/18/18 +f 190/4/4 84/3/3 103/129/116 193/237/193 +f 193/237/193 103/129/116 106/133/111 194/240/196 +f 194/240/196 106/133/111 94/275/109 206/242/198 +f 206/256/198 94/122/109 93/119/106 203/250/206 +f 203/250/206 93/119/106 83/9/9 191/12/12 +f 165/15/15 111/14/14 130/159/141 182/225/188 +f 182/225/188 130/159/141 133/165/136 183/228/191 +f 183/228/191 133/165/136 121/276/134 171/230/177 +f 171/211/177 121/152/134 120/149/131 168/205/171 +f 168/205/171 120/149/131 110/7/7 163/6/6 +f 111/14/14 2/13/13 14/35/35 128/157/139 +f 128/157/139 14/35/35 17/41/27 129/160/142 +f 129/160/142 17/41/27 5/277/25 117/162/128 +f 117/146/128 5/25/25 4/22/22 114/140/122 +f 114/140/122 4/22/22 1/21/21 109/137/119 +f 84/3/3 28/2/2 33/52/48 101/127/114 +f 101/127/114 33/52/48 36/58/54 102/130/117 +f 102/130/117 36/58/54 48/76/69 90/116/103 +f 90/116/103 48/76/69 47/73/66 87/110/97 +f 87/110/97 47/73/66 30/17/17 82/20/20 +f 137/181/155 109/137/119 1/21/21 29/61/57 diff --git a/src/lib.rs b/src/lib.rs index 8c6782a..66fc220 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,128 +1,19 @@ use std::iter; +use cgmath::prelude::*; use wgpu::util::DeviceExt; use winit::{ event::*, event_loop::EventLoop, keyboard::{KeyCode, PhysicalKey}, - window::{Window, WindowBuilder}, + window::Window, }; -use cgmath::prelude::*; -use crate::texture::Texture; +mod model; +mod resources; mod texture; -struct Instance { - position: cgmath::Vector3, - rotation: cgmath::Quaternion, -} - -impl InstanceRaw { - fn desc() -> wgpu::VertexBufferLayout<'static> { - use std::mem; - wgpu::VertexBufferLayout { - array_stride: mem::size_of::() as wgpu::BufferAddress, - // We need to switch from using a step mode of Vertex to Instance - // This means that our shaders will only change to use the next - // instance when the shader starts processing a new instance - step_mode: wgpu::VertexStepMode::Instance, - attributes: &[ - // A mat4 takes up 4 vertex slots as it is technically 4 vec4s. We need to define a slot - // for each vec4. We'll have to reassemble the mat4 in the shader. - wgpu::VertexAttribute { - offset: 0, - // While our vertex shader only uses locations 0, and 1 now, in later tutorials, we'll - // be using 2, 3, and 4, for Vertex. We'll start at slot 5, not conflict with them later - shader_location: 5, - format: wgpu::VertexFormat::Float32x4, - }, - wgpu::VertexAttribute { - offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress, - shader_location: 6, - format: wgpu::VertexFormat::Float32x4, - }, - wgpu::VertexAttribute { - offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress, - shader_location: 7, - format: wgpu::VertexFormat::Float32x4, - }, - wgpu::VertexAttribute { - offset: mem::size_of::<[f32; 12]>() as wgpu::BufferAddress, - shader_location: 8, - format: wgpu::VertexFormat::Float32x4, - }, - ], - } - } -} - -impl Instance { - fn to_raw(&self) -> InstanceRaw { - InstanceRaw { - model: (cgmath::Matrix4::from_translation(self.position) * cgmath::Matrix4::from(self.rotation)).into(), - } - } -} - -#[repr(C)] -#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] -struct InstanceRaw { - model: [[f32; 4]; 4], -} - -#[repr(C)] -#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] -struct Vertex { - position: [f32; 3], - tex_coords: [f32; 2], -} - -impl Vertex { - fn desc() -> wgpu::VertexBufferLayout<'static> { - use std::mem; - wgpu::VertexBufferLayout { - array_stride: mem::size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &[ - wgpu::VertexAttribute { - offset: 0, - shader_location: 0, - format: wgpu::VertexFormat::Float32x3, - }, - wgpu::VertexAttribute { - offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, - shader_location: 1, - format: wgpu::VertexFormat::Float32x2, - }, - ], - } - } -} - -const VERTICES: &[Vertex] = &[ - Vertex { - position: [-0.0868241, 0.49240386, 0.0], - tex_coords: [0.4131759, 0.00759614], - }, // A - Vertex { - position: [-0.49513406, 0.06958647, 0.0], - tex_coords: [0.0048659444, 0.43041354], - }, // B - Vertex { - position: [-0.21918549, -0.44939706, 0.0], - tex_coords: [0.28081453, 0.949397], - }, // C - Vertex { - position: [0.35966998, -0.3473291, 0.0], - tex_coords: [0.85967, 0.84732914], - }, // D - Vertex { - position: [0.44147372, 0.2347359, 0.0], - tex_coords: [0.9414737, 0.2652641], - }, // E -]; - -const INDICES: &[u16] = &[0, 1, 4, 1, 2, 4, 2, 3, 4, /* padding */ 0]; +use model::{DrawModel, Vertex}; #[rustfmt::skip] pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4 = cgmath::Matrix4::new( @@ -132,6 +23,9 @@ pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4 = cgmath::Matrix4::new( 0.0, 0.0, 0.0, 1.0, ); +const NUM_INSTANCES_PER_ROW: u32 = 10; + +#[derive(Debug)] struct Camera { eye: cgmath::Point3, target: cgmath::Point3, @@ -158,7 +52,6 @@ struct CameraUniform { impl CameraUniform { fn new() -> Self { - use cgmath::SquareMatrix; Self { view_proj: cgmath::Matrix4::identity().into(), } @@ -237,7 +130,6 @@ impl CameraController { } fn update_camera(&self, camera: &mut Camera) { - use cgmath::InnerSpace; let forward = camera.target - camera.eye; let forward_norm = forward.normalize(); let forward_mag = forward.magnitude(); @@ -269,6 +161,65 @@ impl CameraController { } } +struct Instance { + position: cgmath::Vector3, + rotation: cgmath::Quaternion, +} + +impl Instance { + fn to_raw(&self) -> InstanceRaw { + InstanceRaw { + model: (cgmath::Matrix4::from_translation(self.position) + * cgmath::Matrix4::from(self.rotation)) + .into(), + } + } +} + +#[repr(C)] +#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] +struct InstanceRaw { + #[allow(dead_code)] + model: [[f32; 4]; 4], +} + +impl InstanceRaw { + fn desc() -> wgpu::VertexBufferLayout<'static> { + use std::mem; + wgpu::VertexBufferLayout { + array_stride: mem::size_of::() as wgpu::BufferAddress, + // We need to switch from using a step mode of Vertex to Instance + // This means that our shaders will only change to use the next + // instance when the shader starts processing a new instance + step_mode: wgpu::VertexStepMode::Instance, + attributes: &[ + wgpu::VertexAttribute { + offset: 0, + shader_location: 5, + format: wgpu::VertexFormat::Float32x4, + }, + // A mat4 takes up 4 vertex slots as it is technically 4 vec4s. We need to define a slot + // for each vec4. We don't have to do this in code though. + wgpu::VertexAttribute { + offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress, + shader_location: 6, + format: wgpu::VertexFormat::Float32x4, + }, + wgpu::VertexAttribute { + offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress, + shader_location: 7, + format: wgpu::VertexFormat::Float32x4, + }, + wgpu::VertexAttribute { + offset: mem::size_of::<[f32; 12]>() as wgpu::BufferAddress, + shader_location: 8, + format: wgpu::VertexFormat::Float32x4, + }, + ], + } + } +} + struct State<'a> { surface: wgpu::Surface<'a>, device: wgpu::Device, @@ -276,32 +227,26 @@ struct State<'a> { config: wgpu::SurfaceConfiguration, size: winit::dpi::PhysicalSize, render_pipeline: wgpu::RenderPipeline, - vertex_buffer: wgpu::Buffer, - index_buffer: wgpu::Buffer, - num_indices: u32, - #[allow(dead_code)] - diffuse_texture: texture::Texture, - diffuse_bind_group: wgpu::BindGroup, + obj_model: model::Model, camera: Camera, camera_controller: CameraController, camera_uniform: CameraUniform, camera_buffer: wgpu::Buffer, camera_bind_group: wgpu::BindGroup, - window: &'a Window, instances: Vec, + #[allow(dead_code)] instance_buffer: wgpu::Buffer, - depth_texture: Texture, + depth_texture: texture::Texture, + window: &'a Window, } -const NUM_INSTANCES_PER_ROW: u32 = 10; -const INSTANCE_DISPLACEMENT: cgmath::Vector3 = cgmath::Vector3::new(NUM_INSTANCES_PER_ROW as f32 * 0.5, 0.0, NUM_INSTANCES_PER_ROW as f32 * 0.5); - impl<'a> State<'a> { async fn new(window: &'a Window) -> State<'a> { let size = window.inner_size(); // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU + log::warn!("WGPU setup"); let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends: wgpu::Backends::PRIMARY, ..Default::default() @@ -317,6 +262,7 @@ impl<'a> State<'a> { }) .await .unwrap(); + log::warn!("device and queue"); let (device, queue) = adapter .request_device( &wgpu::DeviceDescriptor { @@ -327,11 +273,13 @@ impl<'a> State<'a> { required_limits: wgpu::Limits::default(), memory_hints: Default::default(), }, + // Some(&std::path::Path::new("trace")), // Trace path None, // Trace path ) .await .unwrap(); + log::warn!("Surface"); let surface_caps = surface.get_capabilities(&adapter); // Shader code assumes an Srgb surface texture. Using a different // one will result all the colors comming out darker. If you want to support non @@ -353,12 +301,6 @@ impl<'a> State<'a> { desired_maximum_frame_latency: 2, }; - let depth_texture = texture::Texture::create_depth_texture(&device, &config, "depth_texture"); - - let diffuse_bytes = include_bytes!("happy-tree.png"); - let diffuse_texture = - texture::Texture::from_bytes(&device, &queue, diffuse_bytes, "happy-tree.png").unwrap(); - let texture_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { entries: &[ @@ -382,23 +324,8 @@ impl<'a> State<'a> { label: Some("texture_bind_group_layout"), }); - let diffuse_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &texture_bind_group_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::TextureView(&diffuse_texture.view), - }, - wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler), - }, - ], - label: Some("diffuse_bind_group"), - }); - let camera = Camera { - eye: (0.0, 1.0, 2.0).into(), + eye: (0.0, 5.0, -10.0).into(), target: (0.0, 0.0, 0.0).into(), up: cgmath::Vector3::unit_y(), aspect: config.width as f32 / config.height as f32, @@ -406,7 +333,7 @@ impl<'a> State<'a> { znear: 0.1, zfar: 100.0, }; - let camera_controller = CameraController::new(0.005); + let camera_controller = CameraController::new(0.2); let mut camera_uniform = CameraUniform::new(); camera_uniform.update_view_proj(&camera); @@ -417,6 +344,36 @@ impl<'a> State<'a> { usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, }); + const SPACE_BETWEEN: f32 = 3.0; + let instances = (0..NUM_INSTANCES_PER_ROW) + .flat_map(|z| { + (0..NUM_INSTANCES_PER_ROW).map(move |x| { + let x = SPACE_BETWEEN * (x as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0); + let z = SPACE_BETWEEN * (z as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0); + + let position = cgmath::Vector3 { x, y: 0.0, z }; + + let rotation = if position.is_zero() { + cgmath::Quaternion::from_axis_angle( + cgmath::Vector3::unit_z(), + cgmath::Deg(0.0), + ) + } else { + cgmath::Quaternion::from_axis_angle(position.normalize(), cgmath::Deg(45.0)) + }; + + Instance { position, rotation } + }) + }) + .collect::>(); + + let instance_data = instances.iter().map(Instance::to_raw).collect::>(); + let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Instance Buffer"), + contents: bytemuck::cast_slice(&instance_data), + usage: wgpu::BufferUsages::VERTEX, + }); + let camera_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { entries: &[wgpu::BindGroupLayoutEntry { @@ -441,11 +398,20 @@ impl<'a> State<'a> { label: Some("camera_bind_group"), }); + log::warn!("Load model"); + let obj_model = + resources::load_model("cube.obj", &device, &queue, &texture_bind_group_layout) + .await + .unwrap(); + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { - label: Some("Shader"), + label: Some("shader.wgsl"), source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()), }); + let depth_texture = + texture::Texture::create_depth_texture(&device, &config, "depth_texture"); + let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), @@ -459,7 +425,7 @@ impl<'a> State<'a> { vertex: wgpu::VertexState { module: &shader, entry_point: "vs_main", - buffers: &[Vertex::desc(), InstanceRaw::desc()], + buffers: &[model::ModelVertex::desc(), InstanceRaw::desc()], compilation_options: Default::default(), }, fragment: Some(wgpu::FragmentState { @@ -507,45 +473,6 @@ impl<'a> State<'a> { cache: None, }); - let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Vertex Buffer"), - contents: bytemuck::cast_slice(VERTICES), - usage: wgpu::BufferUsages::VERTEX, - }); - let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Index Buffer"), - contents: bytemuck::cast_slice(INDICES), - usage: wgpu::BufferUsages::INDEX, - }); - let num_indices = INDICES.len() as u32; - - let instances = (0..NUM_INSTANCES_PER_ROW).flat_map(|z| { - (0..NUM_INSTANCES_PER_ROW).map(move |x| { - let position = cgmath::Vector3 { x: x as f32, y: 0.0, z: z as f32 } - INSTANCE_DISPLACEMENT; - - let rotation = if position.is_zero() { - // this is needed so an object at (0, 0, 0) won't get scaled to zero - // as Quaternions can affect scale if they're not created correctly - cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_z(), cgmath::Deg(0.0)) - } else { - cgmath::Quaternion::from_axis_angle(position.normalize(), cgmath::Deg(45.0)) - }; - - Instance { - position, rotation, - } - }) - }).collect::>(); - - let instance_data = instances.iter().map(Instance::to_raw).collect::>(); - let instance_buffer = device.create_buffer_init( - &wgpu::util::BufferInitDescriptor { - label: Some("Instance Buffer"), - contents: bytemuck::cast_slice(&instance_data), - usage: wgpu::BufferUsages::VERTEX, - } - ); - Self { surface, device, @@ -553,20 +480,16 @@ impl<'a> State<'a> { config, size, render_pipeline, - vertex_buffer, - index_buffer, - num_indices, - diffuse_texture, - diffuse_bind_group, + obj_model, camera, camera_controller, camera_buffer, camera_bind_group, camera_uniform, - window, instances, instance_buffer, depth_texture, + window, } } @@ -576,24 +499,24 @@ impl<'a> State<'a> { fn resize(&mut self, new_size: winit::dpi::PhysicalSize) { if new_size.width > 0 && new_size.height > 0 { - self.size = new_size; self.config.width = new_size.width; self.config.height = new_size.height; - self.surface.configure(&self.device, &self.config); - - self.depth_texture = Texture::create_depth_texture(&self.device, &self.config, "depth_texture"); - + self.size = new_size; self.camera.aspect = self.config.width as f32 / self.config.height as f32; + self.surface.configure(&self.device, &self.config); + self.depth_texture = + texture::Texture::create_depth_texture(&self.device, &self.config, "depth_texture"); } } - fn input(&mut self, event: &WindowEvent) -> bool { self.camera_controller.process_events(event) } fn update(&mut self) { self.camera_controller.update_camera(&mut self.camera); + log::info!("{:?}", self.camera); self.camera_uniform.update_view_proj(&self.camera); + log::info!("{:?}", self.camera_uniform); self.queue.write_buffer( &self.camera_buffer, 0, @@ -641,13 +564,13 @@ impl<'a> State<'a> { timestamp_writes: None, }); - render_pass.set_pipeline(&self.render_pipeline); - render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]); - render_pass.set_bind_group(1, &self.camera_bind_group, &[]); - render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..)); - render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); - render_pass.draw_indexed(0..self.num_indices, 0, 0..self.instances.len() as _); + render_pass.set_pipeline(&self.render_pipeline); + render_pass.draw_model_instanced( + &self.obj_model, + 0..self.instances.len() as u32, + &self.camera_bind_group, + ); } self.queue.submit(iter::once(encoder.finish())); @@ -661,7 +584,11 @@ pub async fn run() { env_logger::init(); let event_loop = EventLoop::new().unwrap(); - let window = WindowBuilder::new().build(&event_loop).unwrap(); + let title = env!("CARGO_PKG_NAME"); + let window = winit::window::WindowBuilder::new() + .with_title(title) + .build(&event_loop) + .unwrap(); // State::new uses async code, so we're going to wait for it to finish let mut state = State::new(&window).await; diff --git a/src/model.rs b/src/model.rs index 5361932..70fffb1 100644 --- a/src/model.rs +++ b/src/model.rs @@ -1,3 +1,7 @@ +use std::ops::Range; + +use crate::texture; + pub trait Vertex { fn desc() -> wgpu::VertexBufferLayout<'static>; } @@ -10,12 +14,6 @@ pub struct ModelVertex { pub normal: [f32; 3], } -impl Vertex for ModelVertex { - fn desc() -> wgpu::VertexBufferLayout<'static> { - todo!(); - } -} - impl Vertex for ModelVertex { fn desc() -> wgpu::VertexBufferLayout<'static> { use std::mem; @@ -41,4 +39,96 @@ impl Vertex for ModelVertex { ], } } +} + +pub struct Material { + #[allow(unused)] + pub name: String, + #[allow(unused)] + pub diffuse_texture: texture::Texture, + pub bind_group: wgpu::BindGroup, +} + +pub struct Mesh { + #[allow(unused)] + pub name: String, + pub vertex_buffer: wgpu::Buffer, + pub index_buffer: wgpu::Buffer, + pub num_elements: u32, + pub material: usize, +} + +pub struct Model { + pub meshes: Vec, + pub materials: Vec, +} + +pub trait DrawModel<'a> { + #[allow(unused)] + fn draw_mesh( + &mut self, + mesh: &'a Mesh, + material: &'a Material, + camera_bind_group: &'a wgpu::BindGroup, + ); + fn draw_mesh_instanced( + &mut self, + mesh: &'a Mesh, + material: &'a Material, + instances: Range, + camera_bind_group: &'a wgpu::BindGroup, + ); + + #[allow(unused)] + fn draw_model(&mut self, model: &'a Model, camera_bind_group: &'a wgpu::BindGroup); + fn draw_model_instanced( + &mut self, + model: &'a Model, + instances: Range, + camera_bind_group: &'a wgpu::BindGroup, + ); +} + +impl<'a, 'b> DrawModel<'b> for wgpu::RenderPass<'a> +where + 'b: 'a, +{ + fn draw_mesh( + &mut self, + mesh: &'b Mesh, + material: &'b Material, + camera_bind_group: &'b wgpu::BindGroup, + ) { + self.draw_mesh_instanced(mesh, material, 0..1, camera_bind_group); + } + + fn draw_mesh_instanced( + &mut self, + mesh: &'b Mesh, + material: &'b Material, + instances: Range, + camera_bind_group: &'b wgpu::BindGroup, + ) { + self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..)); + self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32); + self.set_bind_group(0, &material.bind_group, &[]); + self.set_bind_group(1, camera_bind_group, &[]); + self.draw_indexed(0..mesh.num_elements, 0, instances); + } + + fn draw_model(&mut self, model: &'b Model, camera_bind_group: &'b wgpu::BindGroup) { + self.draw_model_instanced(model, 0..1, camera_bind_group); + } + + fn draw_model_instanced( + &mut self, + model: &'b Model, + instances: Range, + camera_bind_group: &'b wgpu::BindGroup, + ) { + for mesh in &model.meshes { + let material = &model.materials[mesh.material]; + self.draw_mesh_instanced(mesh, material, instances.clone(), camera_bind_group); + } + } } \ No newline at end of file diff --git a/src/resources.rs b/src/resources.rs new file mode 100644 index 0000000..f5f358a --- /dev/null +++ b/src/resources.rs @@ -0,0 +1,139 @@ +use std::io::{BufReader, Cursor}; + +use wgpu::util::DeviceExt; + +use crate::{model, texture}; + +pub async fn load_string(file_name: &str) -> anyhow::Result { + let path = std::path::Path::new(env!("OUT_DIR")) + .join("res") + .join(file_name); + let txt = std::fs::read_to_string(path)?; + + Ok(txt) +} + +pub async fn load_binary(file_name: &str) -> anyhow::Result> { + let path = std::path::Path::new(env!("OUT_DIR")) + .join("res") + .join(file_name); + let data = std::fs::read(path)?; + + Ok(data) +} + +pub async fn load_texture( + file_name: &str, + device: &wgpu::Device, + queue: &wgpu::Queue, +) -> anyhow::Result { + let data = load_binary(file_name).await?; + texture::Texture::from_bytes(device, queue, &data, file_name) +} + +pub async fn load_model( + file_name: &str, + device: &wgpu::Device, + queue: &wgpu::Queue, + layout: &wgpu::BindGroupLayout, +) -> anyhow::Result { + let obj_text = load_string(file_name).await?; + let obj_cursor = Cursor::new(obj_text); + let mut obj_reader = BufReader::new(obj_cursor); + + let (models, obj_materials) = tobj::load_obj_buf_async( + &mut obj_reader, + &tobj::LoadOptions { + triangulate: true, + single_index: true, + ..Default::default() + }, + |p| async move { + let mat_text = load_string(&p).await.unwrap(); + tobj::load_mtl_buf(&mut BufReader::new(Cursor::new(mat_text))) + }, + ) + .await?; + + let mut materials = Vec::new(); + for m in obj_materials? { + let diffuse_texture = load_texture(&m.diffuse_texture, device, queue).await?; + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&diffuse_texture.view), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler), + }, + ], + label: None, + }); + + materials.push(model::Material { + name: m.name, + diffuse_texture, + bind_group, + }) + } + + let meshes = models + .into_iter() + .map(|m| { + let vertices = (0..m.mesh.positions.len() / 3) + .map(|i| { + if m.mesh.normals.is_empty(){ + model::ModelVertex { + position: [ + m.mesh.positions[i * 3], + m.mesh.positions[i * 3 + 1], + m.mesh.positions[i * 3 + 2], + ], + tex_coords: [m.mesh.texcoords[i * 2], 1.0 - m.mesh.texcoords[i * 2 + 1]], + normal: [0.0, 0.0, 0.0], + } + }else{ + model::ModelVertex { + position: [ + m.mesh.positions[i * 3], + m.mesh.positions[i * 3 + 1], + m.mesh.positions[i * 3 + 2], + ], + tex_coords: [m.mesh.texcoords[i * 2], 1.0 - m.mesh.texcoords[i * 2 + 1]], + normal: [ + m.mesh.normals[i * 3], + m.mesh.normals[i * 3 + 1], + m.mesh.normals[i * 3 + 2], + ], + } + } + }) + .collect::>(); + + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some(&format!("{:?} Vertex Buffer", file_name)), + contents: bytemuck::cast_slice(&vertices), + usage: wgpu::BufferUsages::VERTEX, + }); + let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some(&format!("{:?} Index Buffer", file_name)), + contents: bytemuck::cast_slice(&m.mesh.indices), + usage: wgpu::BufferUsages::INDEX, + }); + + log::info!("Mesh: {}", m.name); + model::Mesh { + name: file_name.to_string(), + vertex_buffer, + index_buffer, + num_elements: m.mesh.indices.len() as u32, + material: m.mesh.material_id.unwrap_or(0), + } + }) + .collect::>(); + + Ok(model::Model { meshes, materials }) +} \ No newline at end of file diff --git a/src/shader.wgsl b/src/shader.wgsl index 9d8155d..c182e66 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -1,21 +1,20 @@ +// Vertex shader + +struct Camera { + view_proj: mat4x4, +} +@group(1) @binding(0) +var camera: Camera; + +struct VertexInput { + @location(0) position: vec3, + @location(1) tex_coords: vec2, +} struct InstanceInput { @location(5) model_matrix_0: vec4, @location(6) model_matrix_1: vec4, @location(7) model_matrix_2: vec4, @location(8) model_matrix_3: vec4, -}; - - -// Vertex shader -struct CameraUniform { - view_proj: mat4x4, -}; -@group(1) @binding(0) // 1. -var camera: CameraUniform; - -struct VertexInput { - @location(0) position: vec3, - @location(1) tex_coords: vec2, } struct VertexOutput { @@ -44,7 +43,7 @@ fn vs_main( @group(0) @binding(0) var t_diffuse: texture_2d; -@group(0) @binding(1) +@group(0)@binding(1) var s_diffuse: sampler; @fragment