Advertisement
Guest User

Untitled

a guest
Jan 19th, 2020
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 9.73 KB | None | 0 0
  1. use amethyst::{
  2.     controls::{CursorHideSystem, MouseFocusUpdateSystemDesc},
  3.     core::{
  4.         math::Vector3,
  5.         timing::Time,
  6.         transform::{Transform, TransformBundle},
  7.         Parent,
  8.     },
  9.     input::{InputBundle, StringBindings},
  10.     prelude::*,
  11.     renderer::{
  12.         camera::Camera,
  13.         light,
  14.         palette::{LinSrgba, Srgb},
  15.         plugins::{RenderShaded3D, RenderToWindow},
  16.         rendy::mesh::{Normal, Position, Tangent, TexCoord},
  17.         shape::Shape,
  18.         types,
  19.         visibility::BoundingSphere,
  20.         RenderingBundle,
  21.     },
  22.     utils::application_root_dir,
  23.     window::ScreenDimensions,
  24.     Error,
  25. };
  26. use rand::prelude::*;
  27.  
  28. use amethyst_nphysics::NPhysicsBackend;
  29. use amethyst_physics::{prelude::*, PhysicsBundle};
  30.  
  31. mod components;
  32. mod systems;
  33. mod visual_utils;
  34.  
  35. #[derive(Default)]
  36. struct Example {
  37.     time_bank: f32,
  38. }
  39.  
  40. impl SimpleState for Example {
  41.     fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) {
  42.        // Add light
  43.        add_light_entity(
  44.            data.world,
  45.            Srgb::new(1.0, 1.0, 1.0),
  46.            Vector3::new(-0.2, -1.0, -0.2),
  47.            1.0,
  48.        );
  49.        add_light_entity(
  50.            data.world,
  51.            Srgb::new(1.0, 0.8, 0.8),
  52.            Vector3::new(0.2, -1.0, 0.2),
  53.            1.0,
  54.        );
  55.  
  56.        // Create floor
  57.        create_floor(data.world);
  58.  
  59.        // Create the character + camera.
  60.        create_character_entity(data.world);
  61.  
  62.        // Create Box
  63.        add_cube_entity(data.world, Vector3::new(0.0, 6.0, 0.0));
  64.    }
  65.  
  66.    fn update(&mut self, data: &mut StateData<'_, GameData<'_, '_>>) -> SimpleTrans {
  67.         // TODO this code must go inside a System.
  68.         // Spawn a new cube each X sec.
  69.         {
  70.             let time = data.world.fetch::<Time>();
  71.             self.time_bank += time.delta_seconds();
  72.         }
  73.  
  74.         let time_threshold = 10.0; // Each 10 sec
  75.         let spawn_scale = 10.0f32; // Scale
  76.  
  77.         let mut rng = rand::thread_rng();
  78.  
  79.         while self.time_bank > time_threshold {
  80.             add_cube_entity(
  81.                 data.world,
  82.                 Vector3::new(
  83.                     rng.gen::<f32>() * spawn_scale - spawn_scale * 0.5,
  84.                     6.0,
  85.                     rng.gen::<f32>() * spawn_scale - spawn_scale * 0.5,
  86.                 ),
  87.             );
  88.             self.time_bank -= time_threshold;
  89.         }
  90.  
  91.         Trans::None
  92.     }
  93. }
  94.  
  95. fn main() -> Result<(), Error> {
  96.     amethyst::start_logger(Default::default());
  97.  
  98.     let app_root = application_root_dir()?;
  99.  
  100.     let assets_dir = app_root.join("assets");
  101.     let display_config_path = app_root.join("config").join("display.ron");
  102.  
  103.     let game_data = GameDataBuilder::default()
  104.         .with_system_desc(
  105.             MouseFocusUpdateSystemDesc::default(),
  106.             "mouse_focus_update",
  107.             &[],
  108.         )
  109.         .with(
  110.             CursorHideSystem::default(),
  111.             "cursor_hide",
  112.             &["mouse_focus_update"],
  113.         )
  114.         .with_bundle(
  115.             InputBundle::<StringBindings>::new()
  116.                 .with_bindings_from_file(assets_dir.join("input_bindings.ron"))
  117.                 .unwrap(),
  118.         )?
  119.         .with(
  120.             systems::CameraMotionSystem::new(),
  121.             "camera_motion_system",
  122.             &["input_system"],
  123.         )
  124.         .with_bundle(TransformBundle::new())?
  125.         .with_bundle(
  126.             PhysicsBundle::<f32, NPhysicsBackend>::new()
  127.                 .with_frames_per_seconds(60)
  128.                 .with_max_sub_steps(8) // Safety
  129.                 .with_pre_physics(
  130.                     systems::CharacterMotionControllerSystem::new(),
  131.                     String::from("character_motion_controller"),
  132.                     vec![],
  133.                 ),
  134.         )?
  135.         .with_bundle(
  136.             RenderingBundle::<dyn types:: Backend>::new()
  137.                 .with_plugin(
  138.                     RenderToWindow::from_config_path(display_config_path)
  139.                         .with_clear([0.34, 0.36, 0.52, 1.0]),
  140.                 )
  141.                 .with_plugin(RenderShaded3D::default()),
  142.         )?;
  143.     let mut game = Application::build(assets_dir, Example::default())?.build(game_data)?;
  144.     game.run();
  145.     Ok(())
  146. }
  147.  
  148. fn add_light_entity(world: &mut World, color: Srgb, direction: Vector3<f32>, intensity: f32) {
  149.     let light: light::Light = light::DirectionalLight {
  150.         color,
  151.         direction: direction.normalize(),
  152.         intensity,
  153.     }
  154.     .into();
  155.  
  156.     world.create_entity().with(light).build();
  157. }
  158.  
  159. fn create_floor(world: &mut World) {
  160.     let shape = {
  161.         let desc = ShapeDesc::Cube {
  162.             half_extents: Vector3::new(20.0, 0.2, 20.0),
  163.         };
  164.         let physics_world = world.fetch::<PhysicsWorld<f32>>();
  165.         physics_world.shape_server().create(&desc)
  166.     };
  167.  
  168.     let rb = {
  169.         let mut rb_desc = RigidBodyDesc::default();
  170.         rb_desc.mode = BodyMode::Static;
  171.  
  172.         let physics_world = world.fetch::<PhysicsWorld<f32>>();
  173.         physics_world.rigid_body_server().create(&rb_desc)
  174.     };
  175.  
  176.     let mesh = {
  177.         let mesh_data: types::MeshData = Shape::Cube
  178.             .generate::<(Vec<Position>, Vec<Normal>, Vec<Tangent>, Vec<TexCoord>)>(Some((
  179.                 20.0, 0.2, 20.0,
  180.             )))
  181.             .into();
  182.  
  183.         visual_utils::create_mesh(world, mesh_data)
  184.     };
  185.  
  186.     let mat = visual_utils::create_material(
  187.         world,
  188.         LinSrgba::new(0.0, 1.0, 0.0, 1.0),
  189.         0.0, // Metallic
  190.         1.0, // Roughness
  191.     );
  192.  
  193.     world
  194.         .create_entity()
  195.         .with(mesh)
  196.         .with(mat)
  197.         .with(BoundingSphere::origin(20.0))
  198.         .with(Transform::default())
  199.         .with(shape)
  200.         .with(rb)
  201.         .build();
  202. }
  203.  
  204. fn add_cube_entity(world: &mut World, pos: Vector3<f32>) {
  205.     let shape = {
  206.         let desc = ShapeDesc::Cube {
  207.             half_extents: Vector3::new(1.0, 1.0, 1.0),
  208.         };
  209.         let physics_world = world.fetch::<PhysicsWorld<f32>>();
  210.         physics_world.shape_server().create(&desc)
  211.     };
  212.  
  213.     let rb = {
  214.         let rb_desc = RigidBodyDesc::default();
  215.  
  216.         let physics_world = world.fetch::<PhysicsWorld<f32>>();
  217.         physics_world.rigid_body_server().create(&rb_desc)
  218.     };
  219.  
  220.     let mesh = {
  221.         let mesh_data: types::MeshData = Shape::Cube
  222.             .generate::<(Vec<Position>, Vec<Normal>, Vec<Tangent>, Vec<TexCoord>)>(Some((
  223.                 1.0, 1.0, 1.0,
  224.             )))
  225.             .into();
  226.  
  227.         visual_utils::create_mesh(world, mesh_data)
  228.     };
  229.  
  230.     let mut rng = rand::thread_rng();
  231.     let mat = visual_utils::create_material(
  232.         world,
  233.         LinSrgba::new(rng.gen(), rng.gen(), rng.gen(), 1.0),
  234.         0.0,
  235.         1.0,
  236.     );
  237.  
  238.     let mut transf = Transform::default();
  239.     transf.set_translation(pos);
  240.  
  241.     world
  242.         .create_entity()
  243.         .with(mesh)
  244.         .with(mat)
  245.         .with(BoundingSphere::origin(1.0))
  246.         .with(transf)
  247.         .with(shape)
  248.         .with(rb)
  249.         .build();
  250. }
  251.  
  252. /// Creates three entities:
  253. /// 1. The character (With RigidBody).
  254. /// 2. The camera boom handle attached to the character.
  255. /// 3. The camera attached to the camera bool handle.
  256. fn create_character_entity(world: &mut World) {
  257.     let character = {
  258.         let shape = {
  259.             let desc = ShapeDesc::Capsule {
  260.                 half_height: 1.0,
  261.                 radius: 0.5,
  262.             };
  263.             let physics_world = world.fetch::<PhysicsWorld<f32>>();
  264.             physics_world.shape_server().create(&desc)
  265.         };
  266.  
  267.         let rb = {
  268.             let mut rb_desc = RigidBodyDesc::default();
  269.             rb_desc.lock_rotation_x = true;
  270.             rb_desc.lock_rotation_y = true;
  271.             rb_desc.lock_rotation_z = true;
  272.             rb_desc.contacts_to_report = 3;
  273.             rb_desc.friction = 0.0;
  274.             rb_desc.bounciness = 0.0;
  275.  
  276.             let physics_world = world.fetch::<PhysicsWorld<f32>>();
  277.             physics_world.rigid_body_server().create(&rb_desc)
  278.         };
  279.  
  280.         let mesh = {
  281.             let mesh_data: types::MeshData = Shape::Cube
  282.                 .generate::<(Vec<Position>, Vec<Normal>, Vec<Tangent>, Vec<TexCoord>)>(Some((
  283.                     0.5, 1.5, 0.5,
  284.                 )))
  285.                 .into();
  286.  
  287.             visual_utils::create_mesh(world, mesh_data)
  288.         };
  289.  
  290.         let mat =
  291.             visual_utils::create_material(world, LinSrgba::new(0.65, 1.0, 0.90, 1.0), 0.0, 1.0);
  292.  
  293.         let mut transf = Transform::default();
  294.         transf.set_translation(Vector3::new(-3.0, 2.0, -3.0));
  295.  
  296.         world
  297.             .create_entity()
  298.             .with(mesh)
  299.             .with(mat)
  300.             .with(BoundingSphere::origin(1.0))
  301.             .with(transf)
  302.             .with(shape)
  303.             .with(rb)
  304.             .with(components::CharacterBody)
  305.             .build()
  306.     };
  307.  
  308.     let camera_boom_handle = {
  309.         let mut transf = Transform::default();
  310.         transf.set_translation_y(1.5);
  311.  
  312.         world
  313.             .create_entity()
  314.             .with(transf)
  315.             .with(components::CameraBoomHandle)
  316.             .with(Parent { entity: character })
  317.             .build()
  318.     };
  319.  
  320.     let _camera = {
  321.         let mut camera_transform = Transform::default();
  322.         camera_transform.set_translation_xyz(0.0, 0.0, 6.0);
  323.  
  324.         let (width, height) = {
  325.             let dim = world.read_resource::<ScreenDimensions>();
  326.             (dim.width(), dim.height())
  327.         };
  328.  
  329.         world
  330.             .create_entity()
  331.             .with(camera_transform)
  332.             .with(Camera::standard_3d(width, height))
  333.             .with(Parent {
  334.                 entity: camera_boom_handle,
  335.             })
  336.             .build()
  337.     };
  338. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement