diff --git a/Cargo.lock b/Cargo.lock index ffb6291..c35674a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2090,6 +2090,7 @@ dependencies = [ "image", "rand 0.9.1", "thiserror 2.0.12", + "tobj", "tracing", "tracing-log", "tracing-subscriber", @@ -2466,6 +2467,15 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tobj" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04aca6092e5978e708ee784e8ab9b5cf3cdb598b28f99a2f257446e7081a7025" +dependencies = [ + "ahash", +] + [[package]] name = "toml" version = "0.8.22" diff --git a/Cargo.toml b/Cargo.toml index af26232..c33debe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,3 +28,6 @@ tracing-tracy = "0.11" # Random rand = "0.9" + +# OBJ loader +tobj = "4.0" diff --git a/res/objects/cube-diffuse.jpg b/res/objects/cube-diffuse.jpg new file mode 100644 index 0000000..c89b31d Binary files /dev/null and b/res/objects/cube-diffuse.jpg differ diff --git a/res/objects/cube-normal.png b/res/objects/cube-normal.png new file mode 100644 index 0000000..5bbac0a Binary files /dev/null and b/res/objects/cube-normal.png differ diff --git a/res/objects/cube.obj b/res/objects/cube.obj new file mode 100644 index 0000000..03b3bca --- /dev/null +++ b/res/objects/cube.obj @@ -0,0 +1,1143 @@ +# 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.362500 0.512500 +vt 0.137500 0.737500 +vt 0.137500 0.512500 +vt 0.612500 0.012500 +vt 0.387500 0.237500 +vt 0.387500 0.012500 +vt 0.612500 0.762500 +vt 0.387500 0.987500 +vt 0.387500 0.762500 +vt 0.862500 0.512500 +vt 0.637500 0.737500 +vt 0.637500 0.512500 +vt 0.612500 0.512500 +vt 0.387500 0.737500 +vt 0.387500 0.512500 +vt 0.616363 0.487500 +vt 0.612500 0.491363 +vt 0.612500 0.487500 +vt 0.619846 0.487500 +vt 0.616488 0.491466 +vt 0.625000 0.487500 +vt 0.619677 0.491337 +vt 0.612500 0.494846 +vt 0.619114 0.494114 +vt 0.616346 0.494683 +vt 0.625000 0.491347 +vt 0.633637 0.512500 +vt 0.637500 0.508637 +vt 0.630154 0.512500 +vt 0.633512 0.508534 +vt 0.619846 0.512500 +vt 0.630323 0.508663 +vt 0.637500 0.505154 +vt 0.630886 0.505886 +vt 0.633654 0.505317 +vt 0.619683 0.508653 +vt 0.612500 0.508637 +vt 0.616363 0.512500 +vt 0.612500 0.505154 +vt 0.616466 0.508512 +vt 0.616337 0.505323 +vt 0.619114 0.505886 +vt 0.625000 0.494114 +vt 0.619114 0.500000 +vt 0.362500 0.508637 +vt 0.366363 0.512500 +vt 0.362500 0.505154 +vt 0.366466 0.508512 +vt 0.362500 0.500000 +vt 0.366337 0.505323 +vt 0.369846 0.512500 +vt 0.369114 0.505886 +vt 0.369683 0.508653 +vt 0.366347 0.500000 +vt 0.387500 0.491363 +vt 0.383637 0.487500 +vt 0.387500 0.487500 +vt 0.387500 0.494846 +vt 0.383534 0.491488 +vt 0.387500 0.505154 +vt 0.383663 0.494677 +vt 0.380154 0.487500 +vt 0.380886 0.494114 +vt 0.380317 0.491346 +vt 0.383653 0.505317 +vt 0.383637 0.512500 +vt 0.387500 0.508637 +vt 0.380154 0.512500 +vt 0.383512 0.508534 +vt 0.380323 0.508663 +vt 0.380886 0.505886 +vt 0.369114 0.500000 +vt 0.375000 0.505886 +vt 0.616363 0.737500 +vt 0.612500 0.741363 +vt 0.612500 0.737500 +vt 0.619846 0.737500 +vt 0.616488 0.741466 +vt 0.630154 0.737500 +vt 0.619677 0.741337 +vt 0.612500 0.744846 +vt 0.619114 0.744114 +vt 0.616346 0.744683 +vt 0.630317 0.741346 +vt 0.637500 0.741363 +vt 0.633637 0.737500 +vt 0.637500 0.744846 +vt 0.633534 0.741488 +vt 0.637500 0.750000 +vt 0.633664 0.744677 +vt 0.630886 0.744114 +vt 0.633653 0.750000 +vt 0.612500 0.758637 +vt 0.616363 0.762500 +vt 0.612500 0.755154 +vt 0.616466 0.758512 +vt 0.616337 0.755323 +vt 0.619846 0.762500 +vt 0.619114 0.755886 +vt 0.619683 0.758653 +vt 0.625000 0.744114 +vt 0.619114 0.750000 +vt 0.387500 0.741363 +vt 0.383637 0.737500 +vt 0.387500 0.744846 +vt 0.383534 0.741488 +vt 0.387500 0.755154 +vt 0.383663 0.744677 +vt 0.380154 0.737500 +vt 0.380886 0.744114 +vt 0.380317 0.741346 +vt 0.383653 0.755317 +vt 0.383637 0.762500 +vt 0.387500 0.758637 +vt 0.380154 0.762500 +vt 0.383512 0.758534 +vt 0.375000 0.762500 +vt 0.380323 0.758663 +vt 0.380886 0.755886 +vt 0.375000 0.758654 +vt 0.366363 0.737500 +vt 0.362500 0.741363 +vt 0.362500 0.737500 +vt 0.369846 0.737500 +vt 0.366488 0.741466 +vt 0.369677 0.741337 +vt 0.362500 0.744846 +vt 0.369114 0.744114 +vt 0.366347 0.744683 +vt 0.380886 0.750000 +vt 0.375000 0.744114 +vt 0.612500 0.258637 +vt 0.616363 0.262500 +vt 0.612500 0.262500 +vt 0.612500 0.255154 +vt 0.616466 0.258512 +vt 0.612500 0.244846 +vt 0.616337 0.255323 +vt 0.619846 0.262500 +vt 0.619114 0.255886 +vt 0.619683 0.258653 +vt 0.616346 0.244683 +vt 0.616363 0.237500 +vt 0.612500 0.241363 +vt 0.612500 0.237500 +vt 0.619846 0.237500 +vt 0.616488 0.241466 +vt 0.625000 0.237500 +vt 0.619677 0.241337 +vt 0.619114 0.244114 +vt 0.625000 0.241347 +vt 0.862500 0.508637 +vt 0.866363 0.512500 +vt 0.862500 0.505154 +vt 0.866466 0.508512 +vt 0.862500 0.500000 +vt 0.866337 0.505323 +vt 0.869846 0.512500 +vt 0.869114 0.505886 +vt 0.869683 0.508653 +vt 0.866347 0.500000 +vt 0.619114 0.250000 +vt 0.625000 0.255886 +vt 0.387500 0.241363 +vt 0.383637 0.237500 +vt 0.387500 0.244846 +vt 0.383534 0.241488 +vt 0.387500 0.255154 +vt 0.383663 0.244677 +vt 0.380154 0.237500 +vt 0.380886 0.244114 +vt 0.380317 0.241346 +vt 0.383653 0.255317 +vt 0.383637 0.262500 +vt 0.387500 0.258637 +vt 0.387500 0.262500 +vt 0.380154 0.262500 +vt 0.383512 0.258534 +vt 0.375000 0.262500 +vt 0.380323 0.258663 +vt 0.380886 0.255886 +vt 0.375000 0.258653 +vt 0.133637 0.512500 +vt 0.137500 0.508637 +vt 0.130154 0.512500 +vt 0.133512 0.508534 +vt 0.125000 0.512500 +vt 0.130323 0.508663 +vt 0.137500 0.505154 +vt 0.130886 0.505886 +vt 0.133653 0.505317 +vt 0.125000 0.508654 +vt 0.380886 0.250000 +vt 0.375000 0.244114 +vt 0.612500 0.008637 +vt 0.616363 0.012500 +vt 0.612500 0.005154 +vt 0.616466 0.008512 +vt 0.612500 0.000000 +vt 0.616337 0.005323 +vt 0.619846 0.012500 +vt 0.619114 0.005886 +vt 0.619683 0.008654 +vt 0.616346 0.000000 +vt 0.616363 0.987500 +vt 0.612500 0.991363 +vt 0.612500 0.987500 +vt 0.619846 0.987500 +vt 0.616488 0.991466 +vt 0.625000 0.987500 +vt 0.619677 0.991337 +vt 0.612500 0.994846 +vt 0.619114 0.994114 +vt 0.616346 0.994683 +vt 0.625000 0.991346 +vt 0.866363 0.737500 +vt 0.862500 0.741363 +vt 0.862500 0.737500 +vt 0.869846 0.737500 +vt 0.866488 0.741466 +vt 0.875000 0.737500 +vt 0.869677 0.741337 +vt 0.862500 0.744846 +vt 0.869114 0.744114 +vt 0.866346 0.744683 +vt 0.875000 0.741347 +vt 0.619114 0.000000 +vt 0.625000 0.005886 +vt 0.137500 0.741363 +vt 0.133637 0.737500 +vt 0.137500 0.744846 +vt 0.133534 0.741488 +vt 0.137500 0.750000 +vt 0.133663 0.744677 +vt 0.130154 0.737500 +vt 0.130886 0.744114 +vt 0.130317 0.741346 +vt 0.133653 0.750000 +vt 0.387500 0.991363 +vt 0.383637 0.987500 +vt 0.387500 0.994846 +vt 0.383534 0.991488 +vt 0.387500 1.000000 +vt 0.383663 0.994677 +vt 0.380154 0.987500 +vt 0.380886 0.994114 +vt 0.380317 0.991346 +vt 0.383654 1.000000 +vt 0.383637 0.012500 +vt 0.387500 0.008637 +vt 0.380154 0.012500 +vt 0.383512 0.008534 +vt 0.375000 0.012500 +vt 0.380323 0.008663 +vt 0.387500 0.005154 +vt 0.380886 0.005886 +vt 0.383653 0.005317 +vt 0.375000 0.008653 +vt 0.130886 0.750000 +vt 0.125000 0.744114 +vt 0.630886 0.750000 +vt 0.375000 0.755886 +vt 0.625000 0.244114 +vt 0.869114 0.500000 +vt 0.375000 0.255886 +vt 0.125000 0.505886 +vt 0.625000 0.994114 +vt 0.875000 0.744114 +vt 0.380886 1.000000 +vt 0.375000 0.005886 +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.0779 -0.9939 -0.0779 +vn -0.0779 -0.9939 0.0779 +vn -0.0779 -0.9939 -0.0779 +vn -0.9939 0.0779 0.0779 +vn -0.9939 -0.0779 -0.0779 +vn -0.9939 -0.0779 0.0779 +vn 0.0779 0.0779 0.9939 +vn -0.0779 -0.0779 0.9939 +vn 0.0779 -0.0779 0.9939 +vn -0.0779 0.9939 -0.0779 +vn 0.0779 0.9939 0.0779 +vn 0.0779 0.9939 -0.0779 +vn 0.9939 0.0779 -0.0779 +vn 0.9939 -0.0779 0.0779 +vn 0.9939 -0.0779 -0.0779 +vn 0.0783 0.3064 -0.9486 +vn 0.3066 0.0787 -0.9485 +vn 0.0779 0.0779 -0.9939 +vn 0.0754 0.5855 -0.8071 +vn 0.3089 0.3098 -0.8992 +vn 0.0757 0.8072 -0.5853 +vn 0.2866 0.5718 -0.7687 +vn 0.5853 0.0757 -0.8072 +vn 0.5154 0.5156 -0.6844 +vn 0.5719 0.2870 -0.7685 +vn 0.2870 0.7685 -0.5719 +vn 0.3064 0.9486 -0.0783 +vn 0.0787 0.9485 -0.3066 +vn 0.5855 0.8071 -0.0754 +vn 0.3098 0.8992 -0.3089 +vn 0.8072 0.5853 -0.0757 +vn 0.5718 0.7687 -0.2866 +vn 0.5156 0.6844 -0.5154 +vn 0.7685 0.5719 -0.2870 +vn 0.9486 0.0783 -0.3064 +vn 0.9485 0.3066 -0.0787 +vn 0.8071 0.0754 -0.5855 +vn 0.8992 0.3089 -0.3098 +vn 0.7687 0.2866 -0.5718 +vn 0.6844 0.5154 -0.5156 +vn 0.0783 -0.9486 -0.3064 +vn 0.3066 -0.9485 -0.0787 +vn 0.0754 -0.8071 -0.5855 +vn 0.3089 -0.8992 -0.3098 +vn 0.0757 -0.5853 -0.8072 +vn 0.2866 -0.7687 -0.5718 +vn 0.5853 -0.8072 -0.0757 +vn 0.5154 -0.6844 -0.5156 +vn 0.5719 -0.7685 -0.2870 +vn 0.2870 -0.5719 -0.7685 +vn 0.3064 -0.0783 -0.9486 +vn 0.0787 -0.3066 -0.9485 +vn 0.0779 -0.0779 -0.9939 +vn 0.5855 -0.0754 -0.8071 +vn 0.3098 -0.3089 -0.8992 +vn 0.8072 -0.0757 -0.5853 +vn 0.5718 -0.2866 -0.7687 +vn 0.5156 -0.5154 -0.6844 +vn 0.7685 -0.2870 -0.5719 +vn 0.9486 -0.3064 -0.0783 +vn 0.9485 -0.0787 -0.3066 +vn 0.8071 -0.5855 -0.0754 +vn 0.8992 -0.3098 -0.3089 +vn 0.7687 -0.5718 -0.2866 +vn 0.6844 -0.5156 -0.5154 +vn 0.9486 0.3064 0.0783 +vn 0.9485 0.0787 0.3066 +vn 0.9939 0.0779 0.0779 +vn 0.8071 0.5855 0.0754 +vn 0.8992 0.3098 0.3089 +vn 0.5853 0.8072 0.0757 +vn 0.7687 0.5718 0.2866 +vn 0.8072 0.0757 0.5853 +vn 0.6844 0.5156 0.5154 +vn 0.7685 0.2870 0.5719 +vn 0.5719 0.7685 0.2870 +vn 0.0783 0.9486 0.3064 +vn 0.3066 0.9485 0.0787 +vn 0.0754 0.8071 0.5855 +vn 0.3089 0.8992 0.3098 +vn 0.0757 0.5853 0.8072 +vn 0.2866 0.7687 0.5718 +vn 0.5154 0.6844 0.5156 +vn 0.2870 0.5719 0.7685 +vn 0.3064 0.0783 0.9486 +vn 0.0787 0.3066 0.9485 +vn 0.5855 0.0754 0.8071 +vn 0.3098 0.3089 0.8992 +vn 0.5718 0.2866 0.7687 +vn 0.5156 0.5154 0.6844 +vn 0.9486 -0.0783 0.3064 +vn 0.9485 -0.3066 0.0787 +vn 0.8071 -0.0754 0.5855 +vn 0.8992 -0.3089 0.3098 +vn 0.5853 -0.0757 0.8072 +vn 0.7687 -0.2866 0.5718 +vn 0.8072 -0.5853 0.0757 +vn 0.6844 -0.5154 0.5156 +vn 0.7685 -0.5719 0.2870 +vn 0.5719 -0.2870 0.7685 +vn 0.0783 -0.3064 0.9486 +vn 0.3066 -0.0787 0.9485 +vn 0.0754 -0.5855 0.8071 +vn 0.3089 -0.3098 0.8992 +vn 0.0757 -0.8072 0.5853 +vn 0.2866 -0.5718 0.7687 +vn 0.5154 -0.5156 0.6844 +vn 0.2870 -0.7685 0.5719 +vn 0.3064 -0.9486 0.0783 +vn 0.0787 -0.9485 0.3066 +vn 0.0779 -0.9939 0.0779 +vn 0.5855 -0.8071 0.0754 +vn 0.3098 -0.8992 0.3089 +vn 0.5718 -0.7687 0.2866 +vn 0.5156 -0.6844 0.5154 +vn -0.3064 0.0783 -0.9486 +vn -0.0787 0.3066 -0.9485 +vn -0.0779 0.0779 -0.9939 +vn -0.5855 0.0754 -0.8071 +vn -0.3098 0.3089 -0.8992 +vn -0.8072 0.0757 -0.5853 +vn -0.5718 0.2866 -0.7687 +vn -0.0757 0.5853 -0.8072 +vn -0.5156 0.5154 -0.6844 +vn -0.2870 0.5719 -0.7685 +vn -0.7685 0.2870 -0.5719 +vn -0.9486 0.3064 -0.0783 +vn -0.9485 0.0787 -0.3066 +vn -0.9939 0.0779 -0.0779 +vn -0.8071 0.5855 -0.0754 +vn -0.8992 0.3098 -0.3089 +vn -0.5853 0.8072 -0.0757 +vn -0.7687 0.5718 -0.2866 +vn -0.6844 0.5156 -0.5154 +vn -0.5719 0.7685 -0.2870 +vn -0.0783 0.9486 -0.3064 +vn -0.3066 0.9485 -0.0787 +vn -0.0754 0.8071 -0.5855 +vn -0.3089 0.8992 -0.3098 +vn -0.2866 0.7687 -0.5718 +vn -0.5154 0.6844 -0.5156 +vn -0.9486 -0.0783 -0.3064 +vn -0.9485 -0.3066 -0.0787 +vn -0.8071 -0.0754 -0.5855 +vn -0.8992 -0.3089 -0.3098 +vn -0.5853 -0.0757 -0.8072 +vn -0.7687 -0.2866 -0.5718 +vn -0.8072 -0.5853 -0.0757 +vn -0.6844 -0.5154 -0.5156 +vn -0.7685 -0.5719 -0.2870 +vn -0.5719 -0.2870 -0.7685 +vn -0.0783 -0.3064 -0.9486 +vn -0.3066 -0.0787 -0.9485 +vn -0.0779 -0.0779 -0.9939 +vn -0.0754 -0.5855 -0.8071 +vn -0.3089 -0.3098 -0.8992 +vn -0.0757 -0.8072 -0.5853 +vn -0.2866 -0.5718 -0.7687 +vn -0.5154 -0.5156 -0.6844 +vn -0.2870 -0.7685 -0.5719 +vn -0.3064 -0.9486 -0.0783 +vn -0.0787 -0.9485 -0.3066 +vn -0.5855 -0.8071 -0.0754 +vn -0.3098 -0.8992 -0.3089 +vn -0.5718 -0.7687 -0.2866 +vn -0.5156 -0.6844 -0.5154 +vn -0.9486 0.0783 0.3064 +vn -0.9485 0.3066 0.0787 +vn -0.8071 0.0754 0.5855 +vn -0.8992 0.3089 0.3098 +vn -0.5853 0.0757 0.8072 +vn -0.7687 0.2866 0.5718 +vn -0.8072 0.5853 0.0757 +vn -0.6844 0.5154 0.5156 +vn -0.7685 0.5719 0.2870 +vn -0.5719 0.2870 0.7685 +vn -0.0783 0.3064 0.9486 +vn -0.3066 0.0787 0.9485 +vn -0.0779 0.0779 0.9939 +vn -0.0754 0.5855 0.8071 +vn -0.3089 0.3098 0.8992 +vn -0.0757 0.8072 0.5853 +vn -0.2866 0.5718 0.7687 +vn -0.5154 0.5156 0.6844 +vn -0.2870 0.7685 0.5719 +vn -0.3064 0.9486 0.0783 +vn -0.0787 0.9485 0.3066 +vn -0.0779 0.9939 0.0779 +vn -0.5855 0.8071 0.0754 +vn -0.3098 0.8992 0.3089 +vn -0.5718 0.7687 0.2866 +vn -0.5156 0.6844 0.5154 +vn -0.0783 -0.9486 0.3064 +vn -0.3066 -0.9485 0.0787 +vn -0.0754 -0.8071 0.5855 +vn -0.3089 -0.8992 0.3098 +vn -0.0757 -0.5853 0.8072 +vn -0.2866 -0.7687 0.5718 +vn -0.5853 -0.8072 0.0757 +vn -0.5154 -0.6844 0.5156 +vn -0.5719 -0.7685 0.2870 +vn -0.2870 -0.5719 0.7685 +vn -0.3064 -0.0783 0.9486 +vn -0.0787 -0.3066 0.9485 +vn -0.5855 -0.0754 0.8071 +vn -0.3098 -0.3089 0.8992 +vn -0.8072 -0.0757 0.5853 +vn -0.5718 -0.2866 0.7687 +vn -0.5156 -0.5154 0.6844 +vn -0.7685 -0.2870 0.5719 +vn -0.9486 -0.3064 0.0783 +vn -0.9485 -0.0787 0.3066 +vn -0.8071 -0.5855 0.0754 +vn -0.8992 -0.3098 0.3089 +vn -0.7687 -0.5718 0.2866 +vn -0.6844 -0.5156 0.5154 +usemtl Material.001 +s 1 +f 28/1/1 190/2/2 138/3/3 +f 163/4/4 136/5/5 192/6/6 +f 57/7/7 191/8/8 83/9/9 +f 111/10/10 56/11/11 2/12/12 +f 3/13/13 82/14/14 30/15/15 +f 4/16/16 6/17/17 1/18/18 +f 5/19/19 7/20/20 4/16/16 +f 17/21/21 8/22/22 5/19/19 +f 7/20/20 9/23/23 6/17/17 +f 7/20/20 11/24/24 10/25/25 +f 18/26/26 11/24/24 8/22/22 +f 12/27/27 14/28/28 2/12/12 +f 13/29/29 15/30/30 12/27/27 +f 25/31/31 16/32/32 13/29/29 +f 15/30/30 17/33/21 14/28/28 +f 15/30/30 19/34/33 18/35/26 +f 26/36/34 19/34/33 16/32/32 +f 20/37/35 22/38/36 3/13/13 +f 21/39/37 23/40/38 20/37/35 +f 9/23/23 24/41/39 21/39/37 +f 23/40/38 25/31/31 22/38/36 +f 23/40/38 27/42/40 26/36/34 +f 10/25/25 27/42/40 24/41/39 +f 11/24/24 19/43/33 27/44/40 +f 31/45/41 33/46/42 28/1/1 +f 32/47/43 34/48/44 31/45/41 +f 44/49/45 35/50/46 32/47/43 +f 34/48/44 36/51/47 33/46/42 +f 34/48/44 38/52/48 37/53/49 +f 45/54/50 38/52/48 35/50/46 +f 39/55/51 41/56/52 29/57/53 +f 40/58/54 42/59/55 39/55/51 +f 52/60/56 43/61/57 40/58/54 +f 42/59/55 44/62/45 41/56/52 +f 42/59/55 46/63/58 45/64/50 +f 53/65/59 46/63/58 43/61/57 +f 47/66/60 49/67/61 30/15/15 +f 48/68/62 50/69/63 47/66/60 +f 36/51/47 51/70/64 48/68/62 +f 50/69/63 52/60/56 49/67/61 +f 50/69/63 54/71/65 53/65/59 +f 37/53/49 54/71/65 51/70/64 +f 38/52/48 46/72/58 54/73/65 +f 58/74/66 60/75/67 55/76/68 +f 59/77/69 61/78/70 58/74/66 +f 71/79/71 62/80/72 59/77/69 +f 61/78/70 63/81/73 60/75/67 +f 61/78/70 65/82/74 64/83/75 +f 72/84/76 65/82/74 62/80/72 +f 66/85/77 68/86/78 56/11/11 +f 67/87/79 69/88/80 66/85/77 +f 79/89/81 70/90/82 67/87/79 +f 69/88/80 71/79/71 68/86/78 +f 69/88/80 73/91/83 72/84/76 +f 80/92/84 73/91/83 70/90/82 +f 74/93/85 76/94/86 57/7/7 +f 75/95/87 77/96/88 74/93/85 +f 63/81/73 78/97/89 75/95/87 +f 77/96/88 79/98/81 76/94/86 +f 77/96/88 81/99/90 80/100/84 +f 64/83/75 81/99/90 78/97/89 +f 65/82/74 73/101/83 81/102/90 +f 85/103/91 87/104/92 82/14/14 +f 86/105/93 88/106/94 85/103/91 +f 98/107/95 89/108/96 86/105/93 +f 88/106/94 90/109/97 87/104/92 +f 88/106/94 92/110/98 91/111/99 +f 99/112/100 92/110/98 89/108/96 +f 93/113/101 95/114/102 83/9/9 +f 94/115/103 96/116/104 93/113/101 +f 106/117/105 97/118/106 94/115/103 +f 96/116/104 98/107/95 95/114/102 +f 96/116/104 100/119/107 99/112/100 +f 107/120/108 100/119/107 97/118/106 +f 101/121/109 103/122/110 84/123/111 +f 102/124/112 104/125/113 101/121/109 +f 90/109/97 105/126/114 102/124/112 +f 104/125/113 106/127/105 103/122/110 +f 104/125/113 108/128/115 107/129/108 +f 91/111/99 108/128/115 105/126/114 +f 92/110/98 100/130/107 108/131/115 +f 112/132/116 114/133/117 109/134/118 +f 113/135/119 115/136/120 112/132/116 +f 125/137/121 116/138/122 113/135/119 +f 115/136/120 117/139/123 114/133/117 +f 115/136/120 119/140/124 118/141/125 +f 126/142/126 119/140/124 116/138/122 +f 120/143/127 122/144/128 110/145/129 +f 121/146/130 123/147/131 120/143/127 +f 133/148/132 124/149/133 121/146/130 +f 123/147/131 125/137/121 122/144/128 +f 123/147/131 127/150/134 126/142/126 +f 134/151/135 127/150/134 124/149/133 +f 128/152/136 130/153/137 111/10/10 +f 129/154/138 131/155/139 128/152/136 +f 117/156/123 132/157/140 129/154/138 +f 131/155/139 133/158/132 130/153/137 +f 131/155/139 135/159/141 134/160/135 +f 118/161/125 135/159/141 132/157/140 +f 119/140/124 127/162/134 135/163/141 +f 139/164/142 141/165/143 136/5/5 +f 140/166/144 142/167/145 139/164/142 +f 152/168/146 143/169/147 140/166/144 +f 142/167/145 144/170/148 141/165/143 +f 142/167/145 146/171/149 145/172/150 +f 153/173/151 146/171/149 143/169/147 +f 147/174/152 149/175/153 137/176/154 +f 148/177/155 150/178/156 147/174/152 +f 160/179/157 151/180/158 148/177/155 +f 150/178/156 152/168/146 149/175/153 +f 150/178/156 154/181/159 153/173/151 +f 161/182/160 154/181/159 151/180/158 +f 155/183/161 157/184/162 138/3/3 +f 156/185/163 158/186/164 155/183/161 +f 144/187/148 159/188/165 156/185/163 +f 158/186/164 160/189/157 157/184/162 +f 158/186/164 162/190/166 161/191/160 +f 145/192/150 162/190/166 159/188/165 +f 146/171/149 154/193/159 162/194/166 +f 166/195/167 168/196/168 163/4/4 +f 167/197/169 169/198/170 166/195/167 +f 179/199/171 170/200/172 167/197/169 +f 169/198/170 171/201/173 168/196/168 +f 169/198/170 173/202/174 172/203/175 +f 180/204/176 173/202/174 170/200/172 +f 174/205/177 176/206/178 164/207/179 +f 175/208/180 177/209/181 174/205/177 +f 187/210/182 178/211/183 175/208/180 +f 177/209/181 179/212/171 176/206/178 +f 177/209/181 181/213/184 180/214/176 +f 188/215/185 181/213/184 178/211/183 +f 182/216/186 184/217/187 165/218/188 +f 183/219/189 185/220/190 182/216/186 +f 171/221/173 186/222/191 183/219/189 +f 185/220/190 187/223/182 184/217/187 +f 185/220/190 189/224/192 188/225/185 +f 172/226/175 189/224/192 186/222/191 +f 173/202/174 181/227/184 189/228/192 +f 193/229/193 195/230/194 190/2/2 +f 194/231/195 196/232/196 193/229/193 +f 206/233/197 197/234/198 194/231/195 +f 196/232/196 198/235/199 195/230/194 +f 196/232/196 200/236/200 199/237/201 +f 207/238/202 200/236/200 197/234/198 +f 201/239/203 203/240/204 191/8/8 +f 202/241/205 204/242/206 201/239/203 +f 214/243/207 205/244/208 202/241/205 +f 204/242/206 206/245/197 203/240/204 +f 204/242/206 208/246/209 207/247/202 +f 215/248/210 208/246/209 205/244/208 +f 209/249/211 211/250/212 192/6/6 +f 210/251/213 212/252/214 209/249/211 +f 198/253/199 213/254/215 210/251/213 +f 212/252/214 214/255/207 211/250/212 +f 212/252/214 216/256/216 215/257/210 +f 199/258/201 216/256/216 213/254/215 +f 200/236/200 208/259/209 216/260/216 +f 190/2/2 155/183/161 138/3/3 +f 195/230/194 156/185/163 155/183/161 +f 198/235/199 144/187/148 156/185/163 +f 210/251/213 141/165/143 144/170/148 +f 209/249/211 136/5/5 141/165/143 +f 138/3/3 31/45/41 28/1/1 +f 157/184/162 32/47/43 31/45/41 +f 160/189/157 44/49/45 32/47/43 +f 148/177/155 41/56/52 44/62/45 +f 147/174/152 29/57/53 41/56/52 +f 30/15/15 20/37/35 3/13/13 +f 49/67/61 21/39/37 20/37/35 +f 52/60/56 9/23/23 21/39/37 +f 40/58/54 6/17/17 9/23/23 +f 39/55/51 1/18/18 6/17/17 +f 164/207/179 201/239/203 191/8/8 +f 176/206/178 202/241/205 201/239/203 +f 179/212/171 214/243/207 202/241/205 +f 167/197/169 211/250/212 214/255/207 +f 166/195/167 192/6/6 211/250/212 +f 83/9/9 74/93/85 57/7/7 +f 95/114/102 75/95/87 74/93/85 +f 98/107/95 63/81/73 75/95/87 +f 86/105/93 60/75/67 63/81/73 +f 85/103/91 55/76/68 60/75/67 +f 137/176/154 112/132/116 109/134/118 +f 149/175/153 113/135/119 112/132/116 +f 152/168/146 125/137/121 113/135/119 +f 140/166/144 122/144/128 125/137/121 +f 139/164/142 110/145/129 122/144/128 +f 165/218/188 66/85/77 56/11/11 +f 184/217/187 67/87/79 66/85/77 +f 187/223/182 79/89/81 67/87/79 +f 175/208/180 76/94/86 79/98/81 +f 174/205/177 57/7/7 76/94/86 +f 56/11/11 12/27/27 2/12/12 +f 68/86/78 13/29/29 12/27/27 +f 71/79/71 25/31/31 13/29/29 +f 59/77/69 22/38/36 25/31/31 +f 58/74/66 3/13/13 22/38/36 +f 84/123/111 193/229/193 190/2/2 +f 103/122/110 194/231/195 193/229/193 +f 106/127/105 206/233/197 194/231/195 +f 94/115/103 203/240/204 206/245/197 +f 93/113/101 191/8/8 203/240/204 +f 111/10/10 182/216/186 165/218/188 +f 130/153/137 183/219/189 182/216/186 +f 133/158/132 171/221/173 183/219/189 +f 121/146/130 168/196/168 171/201/173 +f 120/143/127 163/4/4 168/196/168 +f 2/12/12 128/152/136 111/10/10 +f 14/28/28 129/154/138 128/152/136 +f 17/33/21 117/156/123 129/154/138 +f 5/19/19 114/133/117 117/139/123 +f 4/16/16 109/134/118 114/133/117 +f 28/1/1 101/121/109 84/123/111 +f 33/46/42 102/124/112 101/121/109 +f 36/51/47 90/109/97 102/124/112 +f 48/68/62 87/104/92 90/109/97 +f 47/66/60 82/14/14 87/104/92 +f 109/134/118 29/57/53 137/176/154 +f 28/1/1 84/123/111 190/2/2 +f 163/4/4 110/145/129 136/5/5 +f 57/7/7 164/207/179 191/8/8 +f 111/10/10 165/218/188 56/11/11 +f 3/13/13 55/76/68 82/14/14 +f 4/16/16 7/20/20 6/17/17 +f 5/19/19 8/22/22 7/20/20 +f 17/21/21 18/26/26 8/22/22 +f 7/20/20 10/25/25 9/23/23 +f 7/20/20 8/22/22 11/24/24 +f 18/26/26 19/43/33 11/24/24 +f 12/27/27 15/30/30 14/28/28 +f 13/29/29 16/32/32 15/30/30 +f 25/31/31 26/36/34 16/32/32 +f 15/30/30 18/35/26 17/33/21 +f 15/30/30 16/32/32 19/34/33 +f 26/36/34 27/42/40 19/34/33 +f 20/37/35 23/40/38 22/38/36 +f 21/39/37 24/41/39 23/40/38 +f 9/23/23 10/25/25 24/41/39 +f 23/40/38 26/36/34 25/31/31 +f 23/40/38 24/41/39 27/42/40 +f 10/25/25 11/24/24 27/42/40 +f 31/45/41 34/48/44 33/46/42 +f 32/47/43 35/50/46 34/48/44 +f 44/49/45 45/54/50 35/50/46 +f 34/48/44 37/53/49 36/51/47 +f 34/48/44 35/50/46 38/52/48 +f 45/54/50 46/72/58 38/52/48 +f 39/55/51 42/59/55 41/56/52 +f 40/58/54 43/61/57 42/59/55 +f 52/60/56 53/65/59 43/61/57 +f 42/59/55 45/64/50 44/62/45 +f 42/59/55 43/61/57 46/63/58 +f 53/65/59 54/71/65 46/63/58 +f 47/66/60 50/69/63 49/67/61 +f 48/68/62 51/70/64 50/69/63 +f 36/51/47 37/53/49 51/70/64 +f 50/69/63 53/65/59 52/60/56 +f 50/69/63 51/70/64 54/71/65 +f 37/53/49 38/52/48 54/71/65 +f 58/74/66 61/78/70 60/75/67 +f 59/77/69 62/80/72 61/78/70 +f 71/79/71 72/84/76 62/80/72 +f 61/78/70 64/83/75 63/81/73 +f 61/78/70 62/80/72 65/82/74 +f 72/84/76 73/91/83 65/82/74 +f 66/85/77 69/88/80 68/86/78 +f 67/87/79 70/90/82 69/88/80 +f 79/89/81 80/92/84 70/90/82 +f 69/88/80 72/84/76 71/79/71 +f 69/88/80 70/90/82 73/91/83 +f 80/92/84 81/261/90 73/91/83 +f 74/93/85 77/96/88 76/94/86 +f 75/95/87 78/97/89 77/96/88 +f 63/81/73 64/83/75 78/97/89 +f 77/96/88 80/100/84 79/98/81 +f 77/96/88 78/97/89 81/99/90 +f 64/83/75 65/82/74 81/99/90 +f 85/103/91 88/106/94 87/104/92 +f 86/105/93 89/108/96 88/106/94 +f 98/107/95 99/112/100 89/108/96 +f 88/106/94 91/111/99 90/109/97 +f 88/106/94 89/108/96 92/110/98 +f 99/112/100 100/119/107 92/110/98 +f 93/113/101 96/116/104 95/114/102 +f 94/115/103 97/118/106 96/116/104 +f 106/117/105 107/120/108 97/118/106 +f 96/116/104 99/112/100 98/107/95 +f 96/116/104 97/118/106 100/119/107 +f 107/120/108 108/262/115 100/119/107 +f 101/121/109 104/125/113 103/122/110 +f 102/124/112 105/126/114 104/125/113 +f 90/109/97 91/111/99 105/126/114 +f 104/125/113 107/129/108 106/127/105 +f 104/125/113 105/126/114 108/128/115 +f 91/111/99 92/110/98 108/128/115 +f 112/132/116 115/136/120 114/133/117 +f 113/135/119 116/138/122 115/136/120 +f 125/137/121 126/142/126 116/138/122 +f 115/136/120 118/141/125 117/139/123 +f 115/136/120 116/138/122 119/140/124 +f 126/142/126 127/150/134 119/140/124 +f 120/143/127 123/147/131 122/144/128 +f 121/146/130 124/149/133 123/147/131 +f 133/148/132 134/151/135 124/149/133 +f 123/147/131 126/142/126 125/137/121 +f 123/147/131 124/149/133 127/150/134 +f 134/151/135 135/263/141 127/150/134 +f 128/152/136 131/155/139 130/153/137 +f 129/154/138 132/157/140 131/155/139 +f 117/156/123 118/161/125 132/157/140 +f 131/155/139 134/160/135 133/158/132 +f 131/155/139 132/157/140 135/159/141 +f 118/161/125 119/264/124 135/159/141 +f 139/164/142 142/167/145 141/165/143 +f 140/166/144 143/169/147 142/167/145 +f 152/168/146 153/173/151 143/169/147 +f 142/167/145 145/172/150 144/170/148 +f 142/167/145 143/169/147 146/171/149 +f 153/173/151 154/181/159 146/171/149 +f 147/174/152 150/178/156 149/175/153 +f 148/177/155 151/180/158 150/178/156 +f 160/179/157 161/182/160 151/180/158 +f 150/178/156 153/173/151 152/168/146 +f 150/178/156 151/180/158 154/181/159 +f 161/182/160 162/265/166 154/181/159 +f 155/183/161 158/186/164 157/184/162 +f 156/185/163 159/188/165 158/186/164 +f 144/187/148 145/192/150 159/188/165 +f 158/186/164 161/191/160 160/189/157 +f 158/186/164 159/188/165 162/190/166 +f 145/192/150 146/266/149 162/190/166 +f 166/195/167 169/198/170 168/196/168 +f 167/197/169 170/200/172 169/198/170 +f 179/199/171 180/204/176 170/200/172 +f 169/198/170 172/203/175 171/201/173 +f 169/198/170 170/200/172 173/202/174 +f 180/204/176 181/227/184 173/202/174 +f 174/205/177 177/209/181 176/206/178 +f 175/208/180 178/211/183 177/209/181 +f 187/210/182 188/215/185 178/211/183 +f 177/209/181 180/214/176 179/212/171 +f 177/209/181 178/211/183 181/213/184 +f 188/215/185 189/267/192 181/213/184 +f 182/216/186 185/220/190 184/217/187 +f 183/219/189 186/222/191 185/220/190 +f 171/221/173 172/226/175 186/222/191 +f 185/220/190 188/225/185 187/223/182 +f 185/220/190 186/222/191 189/224/192 +f 172/226/175 173/268/174 189/224/192 +f 193/229/193 196/232/196 195/230/194 +f 194/231/195 197/234/198 196/232/196 +f 206/233/197 207/238/202 197/234/198 +f 196/232/196 199/237/201 198/235/199 +f 196/232/196 197/234/198 200/236/200 +f 207/238/202 208/259/209 200/236/200 +f 201/239/203 204/242/206 203/240/204 +f 202/241/205 205/244/208 204/242/206 +f 214/243/207 215/248/210 205/244/208 +f 204/242/206 207/247/202 206/245/197 +f 204/242/206 205/244/208 208/246/209 +f 215/248/210 216/269/216 208/246/209 +f 209/249/211 212/252/214 211/250/212 +f 210/251/213 213/254/215 212/252/214 +f 198/253/199 199/258/201 213/254/215 +f 212/252/214 215/257/210 214/255/207 +f 212/252/214 213/254/215 216/256/216 +f 199/258/201 200/270/200 216/256/216 +f 190/2/2 195/230/194 155/183/161 +f 195/230/194 198/235/199 156/185/163 +f 198/235/199 210/271/213 144/187/148 +f 210/251/213 209/249/211 141/165/143 +f 209/249/211 192/6/6 136/5/5 +f 138/3/3 157/184/162 31/45/41 +f 157/184/162 160/189/157 32/47/43 +f 160/189/157 148/272/155 44/49/45 +f 148/177/155 147/174/152 41/56/52 +f 147/174/152 137/176/154 29/57/53 +f 30/15/15 49/67/61 20/37/35 +f 49/67/61 52/60/56 21/39/37 +f 52/60/56 40/58/54 9/23/23 +f 40/58/54 39/55/51 6/17/17 +f 39/55/51 29/57/53 1/18/18 +f 164/207/179 176/206/178 201/239/203 +f 176/206/178 179/212/171 202/241/205 +f 179/212/171 167/273/169 214/243/207 +f 167/197/169 166/195/167 211/250/212 +f 166/195/167 163/4/4 192/6/6 +f 83/9/9 95/114/102 74/93/85 +f 95/114/102 98/107/95 75/95/87 +f 98/107/95 86/105/93 63/81/73 +f 86/105/93 85/103/91 60/75/67 +f 85/103/91 82/14/14 55/76/68 +f 137/176/154 149/175/153 112/132/116 +f 149/175/153 152/168/146 113/135/119 +f 152/168/146 140/166/144 125/137/121 +f 140/166/144 139/164/142 122/144/128 +f 139/164/142 136/5/5 110/145/129 +f 165/218/188 184/217/187 66/85/77 +f 184/217/187 187/223/182 67/87/79 +f 187/223/182 175/274/180 79/89/81 +f 175/208/180 174/205/177 76/94/86 +f 174/205/177 164/207/179 57/7/7 +f 56/11/11 68/86/78 12/27/27 +f 68/86/78 71/79/71 13/29/29 +f 71/79/71 59/77/69 25/31/31 +f 59/77/69 58/74/66 22/38/36 +f 58/74/66 55/76/68 3/13/13 +f 84/123/111 103/122/110 193/229/193 +f 103/122/110 106/127/105 194/231/195 +f 106/127/105 94/275/103 206/233/197 +f 94/115/103 93/113/101 203/240/204 +f 93/113/101 83/9/9 191/8/8 +f 111/10/10 130/153/137 182/216/186 +f 130/153/137 133/158/132 183/219/189 +f 133/158/132 121/276/130 171/221/173 +f 121/146/130 120/143/127 168/196/168 +f 120/143/127 110/145/129 163/4/4 +f 2/12/12 14/28/28 128/152/136 +f 14/28/28 17/33/21 129/154/138 +f 17/33/21 5/277/19 117/156/123 +f 5/19/19 4/16/16 114/133/117 +f 4/16/16 1/18/18 109/134/118 +f 28/1/1 33/46/42 101/121/109 +f 33/46/42 36/51/47 102/124/112 +f 36/51/47 48/68/62 90/109/97 +f 48/68/62 47/66/60 87/104/92 +f 47/66/60 30/15/15 82/14/14 +f 109/134/118 1/18/18 29/57/53 diff --git a/src/core/render/mod.rs b/src/core/render/mod.rs index ec7ac54..e0de60f 100644 --- a/src/core/render/mod.rs +++ b/src/core/render/mod.rs @@ -1,5 +1,5 @@ pub mod material_manager; pub mod primitives; pub mod render_pass_manager; -pub mod texture; +pub mod resources; pub mod vulkan_context; diff --git a/src/core/render/primitives/mod.rs b/src/core/render/primitives/mod.rs index 427b633..75743cd 100644 --- a/src/core/render/primitives/mod.rs +++ b/src/core/render/primitives/mod.rs @@ -14,10 +14,9 @@ mod command; pub mod camera; pub mod mvp; +pub mod resource; pub mod transform; pub mod vertex; - -pub mod resource; pub use buffer::{AsBindableBuffer, AsIndexBuffer, AsUniformBuffer, AsVertexBuffer}; pub use command::{AsRecordable, AsRenderableMesh, AsRenderableMeshInstance}; diff --git a/src/core/render/resources/meshes/mod.rs b/src/core/render/resources/meshes/mod.rs new file mode 100644 index 0000000..c086209 --- /dev/null +++ b/src/core/render/resources/meshes/mod.rs @@ -0,0 +1,5 @@ +mod square; +pub use square::SquareMesh; + +mod obj; +pub use obj::ObjMesh; diff --git a/src/core/render/resources/meshes/obj.rs b/src/core/render/resources/meshes/obj.rs new file mode 100644 index 0000000..d699d10 --- /dev/null +++ b/src/core/render/resources/meshes/obj.rs @@ -0,0 +1,76 @@ +use std::{error::Error, path::PathBuf, sync::Arc}; + +use vulkano::{buffer::Subbuffer, memory::allocator::StandardMemoryAllocator}; + +use crate::core::render::primitives::{ + AsIndexBuffer, AsRenderableMesh, AsVertexBuffer, vertex::Vertex3D, +}; + +pub struct ObjMesh { + vertex_buffer: Subbuffer<[Vertex3D]>, + index_buffer: Subbuffer<[u32]>, +} + +impl ObjMesh { + pub fn new( + memory_allocator: &Arc, + file_path: impl Into, + ) -> Result, Box> { + let (models, _) = tobj::load_obj( + &file_path.into(), + &tobj::LoadOptions { + single_index: true, + triangulate: true, + ..Default::default() + }, + )?; + + let meshes = models + .into_iter() + .map(|model| { + let vertices = (0..model.mesh.positions.len() / 3) + .map(|i| Vertex3D { + position: [ + model.mesh.positions[i * 3], + model.mesh.positions[i * 3 + 1], + model.mesh.positions[i * 3 + 2], + ], + uv: [model.mesh.texcoords[i * 2], model.mesh.texcoords[i * 2 + 1]], + }) + .collect::>(); + + let indices = model.mesh.indices; + + let vertex_buffer = Vertex3D::create_vertex_buffer(memory_allocator, &vertices) + .expect("Failed to create vertex buffer"); + let index_buffer = u32::create_index_buffer(memory_allocator, &indices) + .expect("Failed to create index buffer"); + + Self { + vertex_buffer, + index_buffer, + } + }) + .collect::>(); + + Ok(meshes) + } +} + +impl AsRenderableMesh> for ObjMesh { + fn vertex_buffer(&self) -> &Subbuffer<[Vertex3D]> { + &self.vertex_buffer + } + + fn index_buffer(&self) -> Option<&Subbuffer<[u32]>> { + Some(&self.index_buffer) + } + + fn vertex_count(&self) -> u32 { + self.vertex_buffer.len() as u32 + } + + fn index_count(&self) -> u32 { + self.index_buffer.len() as u32 + } +} diff --git a/src/game/assets/meshs/square.rs b/src/core/render/resources/meshes/square.rs similarity index 92% rename from src/game/assets/meshs/square.rs rename to src/core/render/resources/meshes/square.rs index 1a67013..087b1a9 100644 --- a/src/game/assets/meshs/square.rs +++ b/src/core/render/resources/meshes/square.rs @@ -27,12 +27,12 @@ const VERTICES: [Vertex3D; 4] = [ const INDICES: [u32; 6] = [0, 2, 1, 2, 3, 1]; -pub struct Square { +pub struct SquareMesh { vertex_buffer: Subbuffer<[Vertex3D]>, index_buffer: Subbuffer<[u32]>, } -impl Square { +impl SquareMesh { pub fn new(memory_allocator: &Arc) -> Result> { let vertex_buffer = Vertex3D::create_vertex_buffer(memory_allocator, &VERTICES)?; let index_buffer = u32::create_index_buffer(memory_allocator, &INDICES)?; @@ -44,7 +44,7 @@ impl Square { } } -impl AsRenderableMesh> for Square { +impl AsRenderableMesh> for SquareMesh { fn vertex_buffer(&self) -> &Subbuffer<[Vertex3D]> { &self.vertex_buffer } diff --git a/src/core/render/resources/mod.rs b/src/core/render/resources/mod.rs new file mode 100644 index 0000000..26807af --- /dev/null +++ b/src/core/render/resources/mod.rs @@ -0,0 +1,2 @@ +pub mod meshes; +pub mod texture; diff --git a/src/core/render/resources/texture/loader.rs b/src/core/render/resources/texture/loader.rs new file mode 100644 index 0000000..81acdc4 --- /dev/null +++ b/src/core/render/resources/texture/loader.rs @@ -0,0 +1,127 @@ +use std::{collections::HashMap, error::Error, sync::Arc}; + +use vulkano::{ + command_buffer::{ + AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract, + allocator::StandardCommandBufferAllocator, + }, + device::{Device, Queue}, + format::Format, + image::sampler::SamplerCreateInfo, + memory::allocator::StandardMemoryAllocator, +}; + +use crate::core::app::context::WindowContext; + +use super::Texture; + +pub enum TextureSourceKind { + File(String), + Buffer(Vec), +} + +pub struct TextureLoadInfo { + pub source: TextureSourceKind, + pub sampler_create_info: SamplerCreateInfo, + pub image_format: Format, +} + +pub struct TextureLoader { + loaded_textures: HashMap, + pending_textures: HashMap, + device: Arc, + command_buffer_allocator: Arc, + memory_allocator: Arc, + queue: Arc, +} + +impl TextureLoader { + pub fn new(app_context: &WindowContext) -> Self { + Self { + loaded_textures: HashMap::new(), + pending_textures: HashMap::new(), + device: app_context.device.clone(), + command_buffer_allocator: app_context.command_buffer_allocator.clone(), + memory_allocator: app_context.memory_allocator.clone(), + queue: Self::select_best_suitable_queue(app_context), + } + } + + fn select_best_suitable_queue(app_context: &WindowContext) -> Arc { + app_context + .transfer_queue + .as_ref() + .map(|queue| { + tracing::trace!( + "Selected transfer queue for texture loading with family index: {:?}", + queue.queue_family_index() + ); + queue.clone() + }) + .or_else(|| { + tracing::trace!( + "Selected graphics queue for texture loading with family index: {:?}", + app_context.graphics_queue.queue_family_index() + ); + Some(app_context.graphics_queue.clone()) + }) + .unwrap() + } + + pub fn add_texture(&mut self, name: String, load_info: TextureLoadInfo) { + self.pending_textures.insert(name, load_info); + } + + pub fn load_pending_textures(&mut self) -> Result<(), Box> { + let _span = tracing::info_span!("load_pending_textures"); + let mut uploads = AutoCommandBufferBuilder::primary( + self.command_buffer_allocator.clone(), + self.queue.queue_family_index(), + CommandBufferUsage::OneTimeSubmit, + )?; + + let mut loading_textures = HashMap::new(); + + tracing::trace!("Pending textures count: {}", self.pending_textures.len()); + + for (name, info) in self.pending_textures.iter() { + let texture = match &info.source { + TextureSourceKind::File(path) => Texture::from_file( + &self.device, + &self.memory_allocator, + &mut uploads, + path.as_str(), + info, + )?, + TextureSourceKind::Buffer(buffer) => Texture::from_bytes( + &self.device, + &self.memory_allocator, + &mut uploads, + &buffer, + info, + )?, + }; + + loading_textures.insert(name.clone(), texture); + tracing::trace!("Loaded texture: {}", name); + } + + let _ = uploads.build()?.execute(self.queue.clone())?; + + self.loaded_textures.extend(loading_textures); + + Ok(()) + } + + pub fn get_texture(&self, name: &str) -> Option<&Texture> { + self.loaded_textures.get(name) + } + + pub fn pending_textures_count(&self) -> usize { + self.pending_textures.len() + } + + pub fn loaded_textures_count(&self) -> usize { + self.loaded_textures.len() + } +} diff --git a/src/core/render/resources/texture/mod.rs b/src/core/render/resources/texture/mod.rs new file mode 100644 index 0000000..7bd052e --- /dev/null +++ b/src/core/render/resources/texture/mod.rs @@ -0,0 +1,5 @@ +mod texture; +pub use texture::Texture; + +mod loader; +pub use loader::{TextureLoadInfo, TextureLoader, TextureSourceKind}; diff --git a/src/core/render/texture.rs b/src/core/render/resources/texture/texture.rs similarity index 79% rename from src/core/render/texture.rs rename to src/core/render/resources/texture/texture.rs index 38d8147..3147d26 100644 --- a/src/core/render/texture.rs +++ b/src/core/render/resources/texture/texture.rs @@ -7,22 +7,20 @@ use vulkano::{ command_buffer::{AutoCommandBufferBuilder, CopyBufferToImageInfo, PrimaryAutoCommandBuffer}, descriptor_set::{ DescriptorSet, WriteDescriptorSet, - allocator::{DescriptorSetAllocator, StandardDescriptorSetAllocator}, + allocator::StandardDescriptorSetAllocator, layout::{DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorType}, }, device::Device, format::Format, - image::{ - Image, ImageCreateInfo, ImageType, ImageUsage, - sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo}, - view::ImageView, - }, + image::{Image, ImageCreateInfo, ImageType, ImageUsage, sampler::Sampler, view::ImageView}, memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, shader::ShaderStages, }; use crate::core::render::primitives::AsBindableDescriptorSet; +use super::TextureLoadInfo; + pub struct Texture { texture: Arc, sampler: Arc, @@ -33,37 +31,39 @@ impl Texture { Self { texture, sampler } } - pub fn from_file( + pub(super) fn from_file( device: &Arc, memory_allocator: &Arc, builder: &mut AutoCommandBufferBuilder, path: &str, + load_info: &TextureLoadInfo, ) -> Result> { - let _span = tracing::info_span!("texture_load_from_file", path = path); - let bytes = std::fs::read(path)?; - Self::from_bytes(device, memory_allocator, builder, &bytes) + Self::from_bytes(device, memory_allocator, builder, &bytes, load_info) } - pub fn from_bytes( + pub(super) fn from_bytes( device: &Arc, memory_allocator: &Arc, builder: &mut AutoCommandBufferBuilder, bytes: &[u8], + load_info: &TextureLoadInfo, ) -> Result> { let image = image::load_from_memory(bytes)?; - Self::from_dynamic_image(device, memory_allocator, builder, image) + Self::from_dynamic_image(device, memory_allocator, builder, image, load_info) } - pub fn from_dynamic_image( + fn from_dynamic_image( device: &Arc, memory_allocator: &Arc, builder: &mut AutoCommandBufferBuilder, image: DynamicImage, + load_info: &TextureLoadInfo, ) -> Result> { - let _span = tracing::info_span!("texture_from_dynamic_image"); - - let image_data = image.to_rgba8(); + let image_data = match load_info.image_format { + Format::R8G8B8A8_SRGB => image.to_rgba8(), + _ => return Err("Unsupported format".into()), + }; let image_dimensions = image_data.dimensions(); let image_data = image_data.into_raw(); @@ -90,7 +90,7 @@ impl Texture { memory_allocator.clone(), ImageCreateInfo { image_type: ImageType::Dim2d, - format: Format::R8G8B8A8_SRGB, + format: load_info.image_format, extent: [image_dimensions.0, image_dimensions.1, 1], array_layers: 1, usage: ImageUsage::TRANSFER_DST | ImageUsage::SAMPLED, @@ -104,30 +104,12 @@ impl Texture { image.clone(), ))?; - let sampler = Sampler::new( - device.clone(), - SamplerCreateInfo { - mag_filter: Filter::Linear, - min_filter: Filter::Linear, - address_mode: [SamplerAddressMode::Repeat; 3], - ..Default::default() - }, - )?; + let sampler = Sampler::new(device.clone(), load_info.sampler_create_info.clone())?; let image_view = ImageView::new_default(image)?; - tracing::trace!("Texture loaded with dimensions {:?}", image_dimensions); - Ok(Self::new(image_view, sampler)) } - - pub fn get_texture(&self) -> &Arc { - &self.texture - } - - pub fn get_sampler(&self) -> &Arc { - &self.sampler - } } impl AsBindableDescriptorSet for Texture { diff --git a/src/game/assets/meshs/mod.rs b/src/game/assets/meshs/mod.rs deleted file mode 100644 index d793a66..0000000 --- a/src/game/assets/meshs/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod square; diff --git a/src/game/assets/mod.rs b/src/game/assets/mod.rs index a0cac96..81e613f 100644 --- a/src/game/assets/mod.rs +++ b/src/game/assets/mod.rs @@ -1,2 +1 @@ -pub mod meshs; pub mod pipelines; diff --git a/src/game/assets/pipelines/simple.rs b/src/game/assets/pipelines/simple.rs index f26bcda..3c87f9a 100644 --- a/src/game/assets/pipelines/simple.rs +++ b/src/game/assets/pipelines/simple.rs @@ -31,7 +31,7 @@ use crate::core::render::{ AsBindableDescriptorSet, AsRecordable, AsRenderableMesh, AsRenderableMeshInstance, mvp::Mvp, transform::TransformRaw, vertex::Vertex3D, }, - texture::Texture, + resources::texture::Texture, }; pub struct SimplePipelineRenderData<'a> { diff --git a/src/game/assets/square.rs b/src/game/assets/square.rs deleted file mode 100644 index cea1274..0000000 --- a/src/game/assets/square.rs +++ /dev/null @@ -1,255 +0,0 @@ -use std::{error::Error, sync::Arc}; - -use vulkano::{ - buffer::Subbuffer, - command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer}, - descriptor_set::{ - DescriptorSet, allocator::StandardDescriptorSetAllocator, - layout::DescriptorSetLayoutCreateInfo, - }, - device::Device, - format::Format, - memory::allocator::StandardMemoryAllocator, - pipeline::{ - DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout, - PipelineShaderStageCreateInfo, - graphics::{ - GraphicsPipelineCreateInfo, - color_blend::{ColorBlendAttachmentState, ColorBlendState}, - depth_stencil::{DepthState, DepthStencilState}, - input_assembly::InputAssemblyState, - multisample::MultisampleState, - rasterization::RasterizationState, - subpass::PipelineRenderingCreateInfo, - vertex_input::{Vertex, VertexDefinition}, - viewport::ViewportState, - }, - layout::{PipelineDescriptorSetLayoutCreateInfo, PipelineLayoutCreateFlags}, - }, -}; - -use crate::core::render::{ - primitives::{ - AsBindableDescriptorSet, AsDrawable, AsIndexBuffer, AsRecordable, AsVertexBuffer, mvp::Mvp, - transform::TransformRaw, vertex::Vertex3D, - }, - texture::Texture, -}; - -const VERTICES: [Vertex3D; 4] = [ - Vertex3D { - position: [-0.5, -0.5, 0.0], - uv: [0.0, 0.0], - }, - Vertex3D { - position: [-0.5, 0.5, 0.0], - uv: [0.0, 1.0], - }, - Vertex3D { - position: [0.5, -0.5, 0.0], - uv: [1.0, 0.0], - }, - Vertex3D { - position: [0.5, 0.5, 0.0], - uv: [1.0, 1.0], - }, -]; - -const INDICES: [u32; 6] = [0, 2, 1, 2, 3, 1]; - -pub mod shaders { - pub mod vs { - vulkano_shaders::shader! { - ty: "vertex", - path: r"res/shaders/vertex.vert", - generate_structs: false, - } - } - - pub mod fs { - vulkano_shaders::shader! { - ty: "fragment", - path: r"res/shaders/vertex.frag", - generate_structs: false, - } - } -} - -pub struct Square { - vertex_buffer: Subbuffer<[Vertex3D]>, - index_buffer: Subbuffer<[u32]>, - pipeline: Arc, -} - -/// Structure pour encapsuler les données de rendu du Square -pub struct SquareRenderData<'a> { - pub square: &'a Square, - pub mvp_uniform: &'a Subbuffer<[Mvp]>, - pub transform_uniform: &'a Subbuffer<[TransformRaw]>, - pub descriptor_sets: &'a [Arc], - pub texture: &'a Texture, -} - -impl Square { - pub fn new( - device: &Arc, - memory_allocator: &Arc, - swapchain_format: Format, - depth_format: Format, - ) -> Result> { - let vertex_buffer = Vertex3D::create_vertex_buffer(memory_allocator, &VERTICES)?; - - let index_buffer = u32::create_index_buffer(memory_allocator, &INDICES)?; - - let vs = shaders::vs::load(device.clone())? - .entry_point("main") - .ok_or("Failed find main entry point of vertex shader".to_string())?; - - let fs = shaders::fs::load(device.clone())? - .entry_point("main") - .ok_or("Failed find main entry point of fragment shader".to_string())?; - - let vertex_input_state = - [Vertex3D::per_vertex(), TransformRaw::per_instance()].definition(&vs)?; - - let stages = [ - PipelineShaderStageCreateInfo::new(vs), - PipelineShaderStageCreateInfo::new(fs), - ]; - - let vertex_bindings = Mvp::as_descriptor_set_layout_bindings(); - let texture_bindings = Texture::as_descriptor_set_layout_bindings(); - - let vertex_descriptor_set_layout = DescriptorSetLayoutCreateInfo { - bindings: vertex_bindings, - ..Default::default() - }; - - let fragment_descriptor_set_layout = DescriptorSetLayoutCreateInfo { - bindings: texture_bindings, - ..Default::default() - }; - - let create_info = PipelineDescriptorSetLayoutCreateInfo { - set_layouts: vec![vertex_descriptor_set_layout, fragment_descriptor_set_layout], - flags: PipelineLayoutCreateFlags::default(), - push_constant_ranges: vec![], - } - .into_pipeline_layout_create_info(device.clone())?; - - let layout = PipelineLayout::new(device.clone(), create_info)?; - - let subpass = PipelineRenderingCreateInfo { - color_attachment_formats: vec![Some(swapchain_format)], - depth_attachment_format: Some(depth_format), - ..Default::default() - }; - - let pipeline = GraphicsPipeline::new( - device.clone(), - None, - GraphicsPipelineCreateInfo { - stages: stages.into_iter().collect(), - vertex_input_state: Some(vertex_input_state), - input_assembly_state: Some(InputAssemblyState::default()), - viewport_state: Some(ViewportState::default()), - rasterization_state: Some(RasterizationState::default()), - multisample_state: Some(MultisampleState::default()), - color_blend_state: Some(ColorBlendState::with_attachment_states( - subpass.color_attachment_formats.len() as u32, - ColorBlendAttachmentState::default(), - )), - depth_stencil_state: Some(DepthStencilState { - depth: Some(DepthState::simple()), - ..Default::default() - }), - dynamic_state: [DynamicState::Viewport].into_iter().collect(), - subpass: Some(subpass.into()), - ..GraphicsPipelineCreateInfo::layout(layout) - }, - )?; - - Ok(Self { - vertex_buffer, - index_buffer, - pipeline, - }) - } - - pub fn render( - &self, - command_buffer: &mut AutoCommandBufferBuilder, - descriptor_set_allocator: &Arc, - mvp_uniform: &Subbuffer<[Mvp]>, - transform_uniform: &Subbuffer<[TransformRaw]>, - texture: &Texture, - ) -> Result<(), Box> { - let layouts = self.pipeline.layout().set_layouts(); - - let uniform_descriptor_set = - Mvp::as_descriptor_set(descriptor_set_allocator, &layouts[0], mvp_uniform)?; - - let texture_descriptor_set = - Texture::as_descriptor_set(descriptor_set_allocator, &layouts[1], texture)?; - - let render_data = SquareRenderData { - square: self, - mvp_uniform, - transform_uniform, - texture, - descriptor_sets: &[uniform_descriptor_set, texture_descriptor_set], - }; - - // Utiliser les nouveaux traits pour le rendu - Self::record_render_commands(command_buffer, &self.pipeline, &render_data)?; - - Ok(()) - } -} - -impl<'a> AsRecordable> for Square { - fn record_render_commands( - builder: &mut AutoCommandBufferBuilder, - pipeline: &Arc, - data: &SquareRenderData<'a>, - ) -> Result<(), Box> { - // Bind pipeline - builder.bind_pipeline_graphics(pipeline.clone())?; - - // Bind descriptor sets - builder.bind_descriptor_sets( - PipelineBindPoint::Graphics, - pipeline.layout().clone(), - 0, - data.descriptor_sets.iter().cloned().collect::>(), - )?; - - // Bind buffers - builder.bind_vertex_buffers( - 0, - ( - Self::vertex_buffer(data).clone(), - data.transform_uniform.clone(), - ), - )?; - - if let Some(index_buffer) = Self::index_buffer(data) { - builder.bind_index_buffer(index_buffer.clone())?; - unsafe { - builder.draw_indexed( - Self::index_count(data), - Self::instance_count(data), - 0, - 0, - 0, - )?; - } - } else { - unsafe { - builder.draw(Self::vertex_count(data), Self::instance_count(data), 0, 0)?; - } - } - - Ok(()) - } -} diff --git a/src/game/scenes/main_scene.rs b/src/game/scenes/main_scene.rs index 5f1388c..31126ea 100644 --- a/src/game/scenes/main_scene.rs +++ b/src/game/scenes/main_scene.rs @@ -4,19 +4,22 @@ use super::settings_scene::SettingsScene; use crate::core::app::DEPTH_IMAGE_ID; use crate::core::app::context::WindowContext; use crate::core::app::user_event::UserEvent; +use crate::core::render::primitives::AsRecordable; use crate::core::render::primitives::camera::Camera3D; -use crate::core::render::primitives::mvp::Mvp; use crate::core::render::primitives::transform::Transform; -use crate::core::render::primitives::{AsBindableDescriptorSet, AsRecordable}; use crate::core::render::render_pass_manager::{RenderPassConfig, RenderPassManager}; -use crate::core::render::texture::Texture; +use crate::core::render::resources::meshes::{ObjMesh, SquareMesh}; +use crate::core::render::resources::texture::{ + Texture, TextureLoadInfo, TextureLoader, TextureSourceKind, +}; use crate::core::scene::Scene; -use crate::game::assets::meshs::square::Square; use crate::game::assets::pipelines::simple::{SimplePipeline, SimplePipelineRenderData}; use egui_winit_vulkano::egui; use glam::EulerRot; use glam::Quat; use glam::Vec3; +use vulkano::format::Format; +use vulkano::image::sampler::{Filter, SamplerAddressMode, SamplerCreateInfo}; use vulkano::{ command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract}, sync::GpuFuture, @@ -24,11 +27,13 @@ use vulkano::{ use winit::window::CursorGrabMode; pub struct MainSceneState { - square: Square, + texture_loader: TextureLoader, + square: SquareMesh, + obj: ObjMesh, simple_pipeline: SimplePipeline, - instances: Vec, + square_instances: Vec, + obj_instances: Vec, camera: Camera3D, - texture: Texture, speed: f32, } @@ -50,7 +55,41 @@ impl Scene for MainScene { let swapchain_image_view = app_context.with_renderer(|renderer| renderer.swapchain_image_view().clone()); - let square = Square::new(&app_context.memory_allocator)?; + let mut texture_loader = TextureLoader::new(app_context); + texture_loader.add_texture( + "wooden-crate".to_string(), + TextureLoadInfo { + source: TextureSourceKind::File("res/textures/wooden-crate.jpg".to_string()), + sampler_create_info: SamplerCreateInfo { + mag_filter: Filter::Linear, + min_filter: Filter::Linear, + address_mode: [SamplerAddressMode::Repeat; 3], + ..Default::default() + }, + image_format: Format::R8G8B8A8_SRGB, + }, + ); + texture_loader.add_texture( + "cube-diffuse".to_string(), + TextureLoadInfo { + source: TextureSourceKind::File("res/objects/cube-diffuse.jpg".to_string()), + sampler_create_info: SamplerCreateInfo { + mag_filter: Filter::Linear, + min_filter: Filter::Linear, + address_mode: [SamplerAddressMode::Repeat; 3], + ..Default::default() + }, + image_format: Format::R8G8B8A8_SRGB, + }, + ); + texture_loader.load_pending_textures()?; + + let square = SquareMesh::new(&app_context.memory_allocator)?; + + let obj = { + let obj = ObjMesh::new(&app_context.memory_allocator, "res/objects/cube.obj")?; + obj.into_iter().next().unwrap() + }; let simple_pipeline = SimplePipeline::new( &app_context.device, swapchain_image_view.format(), @@ -61,7 +100,7 @@ impl Scene for MainScene { let instance_size = 10.0; let instance_spacing = 10.0; let num_instances_per_row = (num_instances as f32 / instance_spacing).ceil() as u32; - let instances: Vec = (0..num_instances) + let square_instances: Vec = (0..num_instances) .map(|i| { Transform::new( Vec3::new( @@ -75,26 +114,26 @@ impl Scene for MainScene { }) .collect(); - let texture = { - let mut uploads = AutoCommandBufferBuilder::primary( - app_context.command_buffer_allocator.clone(), - app_context.graphics_queue.queue_family_index(), - CommandBufferUsage::OneTimeSubmit, - )?; - - let texture = Texture::from_file( - &app_context.device, - &app_context.memory_allocator, - &mut uploads, - "res/textures/wooden-crate.jpg", - )?; - - let _ = uploads - .build()? - .execute(app_context.graphics_queue.clone())?; - - texture - }; + let obj_instances: Vec = (0..num_instances) + .map(|i| { + Transform::new( + Vec3::new( + (i % num_instances_per_row) as f32 * (instance_spacing + instance_size), + 0.0, + (i / num_instances_per_row) as f32 + * (instance_spacing + instance_size) + * -1.0 + - instance_spacing * 2.0, + ), + Quat::from_euler(EulerRot::XYZ, 0.0, rand::random_range(0.0..=360.0), 0.0), + Vec3::new( + instance_size * 0.5, + instance_size * 0.5, + instance_size * 0.5, + ), + ) + }) + .collect(); let camera = app_context.with_renderer(|renderer| { Camera3D::new( @@ -107,11 +146,13 @@ impl Scene for MainScene { self.state = Some(MainSceneState { square, + obj, simple_pipeline, - instances, + square_instances, + obj_instances, camera, - texture, speed: 50.0, + texture_loader, }); Ok(()) @@ -132,7 +173,14 @@ impl Scene for MainScene { }); let delta_time = app_context.get_delta_time(); - for (i, instance) in state.instances.iter_mut().enumerate() { + for (i, instance) in state.square_instances.iter_mut().enumerate() { + let rotation_speed = (i % 10) as f32; + let rotation_delta = Quat::from_rotation_y(rotation_speed * delta_time); + + instance.rotate(rotation_delta); + } + + for (i, instance) in state.obj_instances.iter_mut().enumerate() { let rotation_speed = (i % 10) as f32; let rotation_delta = Quat::from_rotation_y(rotation_speed * delta_time); @@ -203,21 +251,40 @@ impl Scene for MainScene { // Create camera uniform using the actual camera let camera_uniform = state.camera.create_buffer(&app_context.memory_allocator)?; - let transform_uniform = - Transform::create_buffer(&app_context.memory_allocator, &state.instances)?; + let square_transform_uniform = + Transform::create_buffer(&app_context.memory_allocator, &state.square_instances)?; + let obj_transform_uniform = + Transform::create_buffer(&app_context.memory_allocator, &state.obj_instances)?; SimplePipeline::record_bind_commands( &mut builder, &app_context.descriptor_set_allocator, state.simple_pipeline.pipeline(), &state.square, - &transform_uniform, + &square_transform_uniform, &SimplePipelineRenderData { mvp_uniform: &camera_uniform, - texture: &state.texture, + texture: &state.texture_loader.get_texture("wooden-crate").unwrap(), }, )?; - SimplePipeline::record_draw_commands(&mut builder, &state.square, &transform_uniform)?; + SimplePipeline::record_draw_commands( + &mut builder, + &state.square, + &square_transform_uniform, + )?; + + SimplePipeline::record_bind_commands( + &mut builder, + &app_context.descriptor_set_allocator, + state.simple_pipeline.pipeline(), + &state.obj, + &obj_transform_uniform, + &SimplePipelineRenderData { + mvp_uniform: &camera_uniform, + texture: &state.texture_loader.get_texture("cube-diffuse").unwrap(), + }, + )?; + SimplePipeline::record_draw_commands(&mut builder, &state.obj, &obj_transform_uniform)?; RenderPassManager::end_rendering(&mut builder)?;