MAJOR rendering overhaul. Snow deformation, persistent light, flowmap out. Also ECS architexture overhaul
This commit is contained in:
207
src/bundles/player.rs
Normal file
207
src/bundles/player.rs
Normal file
@@ -0,0 +1,207 @@
|
||||
use std::f32::consts::PI;
|
||||
use std::rc::Rc;
|
||||
|
||||
use glam::Vec3;
|
||||
use rapier3d::control::{CharacterAutostep, KinematicCharacterController};
|
||||
use rapier3d::prelude::{ColliderBuilder, RigidBodyBuilder};
|
||||
|
||||
use crate::bundles::Bundle;
|
||||
use crate::components::jump::JumpComponent;
|
||||
use crate::components::lights::spot::SpotlightComponent;
|
||||
use crate::components::{InputComponent, MeshComponent, MovementComponent, PhysicsComponent};
|
||||
use crate::entity::EntityHandle;
|
||||
use crate::loaders::mesh::Mesh;
|
||||
use crate::physics::PhysicsManager;
|
||||
use crate::render::Pipeline;
|
||||
use crate::state::StateMachine;
|
||||
use crate::systems::player_states::{
|
||||
PlayerFallingState, PlayerIdleState, PlayerJumpingState, PlayerWalkingState,
|
||||
};
|
||||
use crate::world::{Transform, World};
|
||||
|
||||
pub struct PlayerBundle
|
||||
{
|
||||
pub position: Vec3,
|
||||
}
|
||||
|
||||
impl Bundle for PlayerBundle
|
||||
{
|
||||
fn spawn(self, world: &mut World) -> Result<EntityHandle, String>
|
||||
{
|
||||
let entity = world.spawn();
|
||||
|
||||
let spawn_transform = Transform::from_position(self.position);
|
||||
|
||||
let rigidbody = RigidBodyBuilder::kinematic_position_based()
|
||||
.translation(spawn_transform.position.into())
|
||||
.build();
|
||||
let collider = ColliderBuilder::capsule_y(0.5, 0.5).build();
|
||||
let _controller = KinematicCharacterController {
|
||||
slide: true,
|
||||
autostep: Some(CharacterAutostep::default()),
|
||||
max_slope_climb_angle: 45.0,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let rigidbody_handle = PhysicsManager::add_rigidbody(rigidbody);
|
||||
let collider_handle = PhysicsManager::add_collider(collider, Some(rigidbody_handle));
|
||||
|
||||
let mesh = Mesh::load_mesh("meshes/player_mesh.glb")
|
||||
.map_err(|e| format!("missing player mesh: {}", e))?;
|
||||
|
||||
let falling_state = PlayerFallingState { entity };
|
||||
let idle_state = PlayerIdleState { entity };
|
||||
let walking_state = PlayerWalkingState {
|
||||
entity,
|
||||
enter_time_stamp: 0.0,
|
||||
};
|
||||
let jumping_state = PlayerJumpingState {
|
||||
entity,
|
||||
enter_time_stamp: 0.0,
|
||||
};
|
||||
|
||||
let mut state_machine = StateMachine::new(Box::new(falling_state));
|
||||
state_machine.add_state(walking_state);
|
||||
state_machine.add_state(idle_state);
|
||||
state_machine.add_state(jumping_state);
|
||||
|
||||
let entity_id = entity;
|
||||
|
||||
state_machine.add_transition::<PlayerFallingState, PlayerIdleState>(move |world| {
|
||||
let is_grounded = world
|
||||
.movements
|
||||
.with(entity_id, |m| m.movement_config.movement_context.is_floored)
|
||||
.unwrap_or(false);
|
||||
let has_input = world
|
||||
.inputs
|
||||
.with(entity_id, |i| i.move_direction.length() > 0.01)
|
||||
.unwrap_or(false);
|
||||
is_grounded && !has_input
|
||||
});
|
||||
|
||||
state_machine.add_transition::<PlayerFallingState, PlayerWalkingState>(move |world| {
|
||||
let is_grounded = world
|
||||
.movements
|
||||
.with(entity_id, |m| m.movement_config.movement_context.is_floored)
|
||||
.unwrap_or(false);
|
||||
let has_input = world
|
||||
.inputs
|
||||
.with(entity_id, |i| i.move_direction.length() > 0.01)
|
||||
.unwrap_or(false);
|
||||
is_grounded && has_input
|
||||
});
|
||||
|
||||
state_machine.add_transition::<PlayerIdleState, PlayerWalkingState>(move |world| {
|
||||
let is_grounded = world
|
||||
.movements
|
||||
.with(entity_id, |m| m.movement_config.movement_context.is_floored)
|
||||
.unwrap_or(false);
|
||||
let has_input = world
|
||||
.inputs
|
||||
.with(entity_id, |i| i.move_direction.length() > 0.01)
|
||||
.unwrap_or(false);
|
||||
is_grounded && has_input
|
||||
});
|
||||
|
||||
state_machine.add_transition::<PlayerWalkingState, PlayerIdleState>(move |world| {
|
||||
let is_grounded = world
|
||||
.movements
|
||||
.with(entity_id, |m| m.movement_config.movement_context.is_floored)
|
||||
.unwrap_or(false);
|
||||
let has_input = world
|
||||
.inputs
|
||||
.with(entity_id, |i| i.move_direction.length() > 0.01)
|
||||
.unwrap_or(false);
|
||||
is_grounded && !has_input
|
||||
});
|
||||
|
||||
state_machine.add_transition::<PlayerIdleState, PlayerFallingState>(move |world| {
|
||||
let is_grounded = world
|
||||
.movements
|
||||
.with(entity_id, |m| m.movement_config.movement_context.is_floored)
|
||||
.unwrap_or(false);
|
||||
!is_grounded
|
||||
});
|
||||
|
||||
state_machine.add_transition::<PlayerWalkingState, PlayerFallingState>(move |world| {
|
||||
let is_grounded = world
|
||||
.movements
|
||||
.with(entity_id, |m| m.movement_config.movement_context.is_floored)
|
||||
.unwrap_or(false);
|
||||
!is_grounded
|
||||
});
|
||||
|
||||
state_machine.add_transition::<PlayerIdleState, PlayerJumpingState>(move |world| {
|
||||
let is_grounded = world
|
||||
.movements
|
||||
.with(entity_id, |m| m.movement_config.movement_context.is_floored)
|
||||
.unwrap_or(false);
|
||||
let jump_pressed = world
|
||||
.inputs
|
||||
.with(entity_id, |i| i.jump_just_pressed)
|
||||
.unwrap_or(false);
|
||||
is_grounded && jump_pressed
|
||||
});
|
||||
|
||||
state_machine.add_transition::<PlayerWalkingState, PlayerJumpingState>(move |world| {
|
||||
let is_grounded = world
|
||||
.movements
|
||||
.with(entity_id, |m| m.movement_config.movement_context.is_floored)
|
||||
.unwrap_or(false);
|
||||
let jump_pressed = world
|
||||
.inputs
|
||||
.with(entity_id, |i| i.jump_just_pressed)
|
||||
.unwrap_or(false);
|
||||
is_grounded && jump_pressed
|
||||
});
|
||||
|
||||
state_machine.add_transition::<PlayerJumpingState, PlayerFallingState>(move |world| {
|
||||
world
|
||||
.jumps
|
||||
.with(entity_id, |jump| {
|
||||
jump.jump_config.jump_context.duration >= jump.jump_config.jump_duration
|
||||
})
|
||||
.unwrap_or(true)
|
||||
});
|
||||
|
||||
world.transforms.insert(entity, spawn_transform);
|
||||
world.movements.insert(entity, MovementComponent::new());
|
||||
world.jumps.insert(entity, JumpComponent::new());
|
||||
world.inputs.insert(entity, InputComponent::default());
|
||||
world.physics.insert(
|
||||
entity,
|
||||
PhysicsComponent {
|
||||
rigidbody: rigidbody_handle,
|
||||
collider: Some(collider_handle),
|
||||
},
|
||||
);
|
||||
world.meshes.insert(
|
||||
entity,
|
||||
MeshComponent {
|
||||
mesh: Rc::new(mesh),
|
||||
pipeline: Pipeline::Standard,
|
||||
instance_buffer: None,
|
||||
num_instances: 1,
|
||||
tile_scale: 4.0,
|
||||
enable_dissolve: false,
|
||||
enable_snow_light: false,
|
||||
},
|
||||
);
|
||||
world.player_tags.insert(entity, ());
|
||||
world.state_machines.insert(entity, state_machine);
|
||||
|
||||
let outer_angle = PI / 2.0 * 0.9;
|
||||
world.spotlights.insert(
|
||||
entity,
|
||||
SpotlightComponent::new(
|
||||
Vec3::new(1.0, 2.5, 1.0),
|
||||
Vec3::new(0.0, -1.0, 0.0),
|
||||
100.0,
|
||||
outer_angle * 0.5,
|
||||
outer_angle,
|
||||
),
|
||||
);
|
||||
|
||||
Ok(entity)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user