nd_vector 0.1.0

[WIP] Lengthen! Shrink! Iterate! Scale! Twist and turn to your imagination along any dimension on a vector!
Documentation
use bevy::{input::mouse::MouseMotion, pbr::wireframe::WireframeConfig, prelude::*};
use mesher::{Block, BlockType};
use vector_grid::VectorGrid;

mod mesher;

const A: Block = Block { block_type: BlockType::Air };
const D: Block = Block { block_type: BlockType::Dirt };
const G: Block = Block { block_type: BlockType::Grass };
const S: Block = Block { block_type: BlockType::Stone };
const LO: Block = Block { block_type: BlockType::Log };
const LE: Block = Block { block_type: BlockType::Leaves };
const W: Block = Block { block_type: BlockType::Water };

const WORLD: &str =
"
SSSSS
D   D
D   D
D   D
:::::
S   S
     
     
     
:   :
S   S
     
     
     
:   :
S   S
     
     
     
:   :
SSSSS
D   D
D   D
D   D
:::::
";
/*"
       
       
       
       
       
       
 ###   
 ###   
       
       
 SSSSSS
 DDDDDD
 ::::::
       
       
       
#####  
#####  
  #    
  #    
 SSSSSS
 SDDDDD
 ::::::
  |    
  |    
  |    
#####  
#####  
 ###   
 ###   
 SSSSSS
 SSDDDD
 ::::=:
       
       
       
#####  
#####  
  #    
  #    
    SSS
    DDD
    :=:
       
       
       
 ###   
 ###   
       
       
    SSS
    DDD
    :=:
       
       
       
       
       
       
       
    SSS
    DDD
    :::
       
       
       
       
       
       
       
";*/

fn move_camera(
    mut query_camera: Query<(&mut Transform, &Camera)>,
    time: Res<Time>,

    mut mouse_motion: EventReader<MouseMotion>,
    mouse_input: Res<ButtonInput<MouseButton>>,
    key_input: Res<ButtonInput<KeyCode>>,
) {
    for (mut camera_transform, camera) in query_camera.iter_mut() {
        
        let movement_speed = 10.0 * time.delta_seconds();
        let rotation_speed = -100.0 * time.delta_seconds();

        if mouse_input.pressed(MouseButton::Left) {
            for motion in mouse_motion.read() {
                let mut motion = motion.delta;
                motion /= camera.logical_viewport_size().unwrap_or(Vec2::ZERO).min_element();
                camera_transform.rotate_local_x(rotation_speed * motion.y);
                camera_transform.rotate_y(rotation_speed * motion.x);
            }
        }

        let mut movement = Vec3::ZERO;

        if key_input.pressed(KeyCode::KeyS) {
            movement.z += movement_speed;
        }
        if key_input.pressed(KeyCode::KeyW) {
            movement.z -= movement_speed;
        }

        if key_input.pressed(KeyCode::KeyD) {
            movement.x += movement_speed;
        }
        if key_input.pressed(KeyCode::KeyA) {
            movement.x -= movement_speed;
        }
        movement = camera_transform.rotation.mul_vec3(movement);

        camera_transform.translation += movement;
    }
}

fn setup(
    mut commands: Commands,
    mut ambient_light: ResMut<AmbientLight>,
    asses_server: Res<AssetServer>,
) {
    
    ambient_light.brightness = 2000.0;
    ambient_light.color = Color::rgb(0.5, 0.5, 1.0);

    commands.spawn(Camera3dBundle {
        transform: Transform::from_xyz(0.0, 0.0, 2.0),
        ..default()
    });

    commands.spawn(DirectionalLightBundle {
        directional_light: DirectionalLight { 
            color: Color::rgb(1.0, 1.0, 0.7),
            illuminance: 6000.0,
            ..default()
        },
        transform: Transform::from_xyz(-10.0, 20.0, 7.0).looking_at(Vec3::ZERO, Vec3::Y),
        ..default()
    });

    /*commands.spawn(MaterialMeshBundle {
        mesh: asses_server.add(Sphere::new(0.5).mesh().build()),
        material: asses_server.add(StandardMaterial {
            base_color: Color::rgb(1.0, 0.0, 0.0),
            ..default()
        }),
        ..default()
    });*/

    let mut items = Vec::new();
    for character in WORLD.chars() {
        match character {
            ' ' => items.push(A),
            'D' => items.push(D),
            ':' => items.push(G),
            'S' => items.push(S),
            '|' => items.push(LO),
            '#' => items.push(LE),
            '=' => items.push(W),
            _ => {}
        }
    }
    let mut grid = VectorGrid::<Block>::from_vector(
        vec![5, 5],
        items
    );

    grid.cut(2, 1..3);

    commands.spawn(
        MaterialMeshBundle {
            mesh: asses_server.add(grid.generate_mesh3d()),
            material: asses_server.add(StandardMaterial {
                base_color_texture: Some(asses_server.load("block_textures.png")),
                reflectance: 0.0,
                alpha_mode: AlphaMode::Blend,
                ..default()
            }),
            transform: Transform::from_xyz(0.0, 0.0, 0.0),
            ..default()
        },
    );
}

fn main() {
    App::new()
        .add_plugins(
            DefaultPlugins
            .set(ImagePlugin::default_nearest())
            /* .set(RenderPlugin {
                render_creation: RenderCreation::Automatic(WgpuSettings {
                    // WARN this is a native only feature. It will not work with webgl or webgpu
                    features: WgpuFeatures::POLYGON_MODE_LINE,
                    ..default()
                }),
                ..default()
            }),
            WireframePlugin, */
        )
        .insert_resource(Msaa::Off)
        .insert_resource(WireframeConfig {
            // The global wireframe config enables drawing of wireframes on every mesh,
            // except those with `NoWireframe`. Meshes with `Wireframe` will always have a wireframe,
            // regardless of the global configuration.
            global: true,
            // Controls the default color of all wireframes. Used as the default color for global wireframes.
            // Can be changed per mesh using the `WireframeColor` component.
            default_color: Color::WHITE,
        })
        .add_systems(Startup, setup)
        .add_systems(Update, move_camera)
        .run();
}