mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Corrected some spelling errors
This commit is contained in:
parent
6125b17a7a
commit
2be4202d01
@ -3,8 +3,8 @@
|
|||||||
/* TODO: Add the ability to control the tendency to do stuff in the vertex vs. fragment shader.
|
/* TODO: Add the ability to control the tendency to do stuff in the vertex vs. fragment shader.
|
||||||
* Currently this flag is ignored and always set to prefer fragment, but this tradeoff is not correct on all
|
* Currently this flag is ignored and always set to prefer fragment, but this tradeoff is not correct on all
|
||||||
* machines in all cases (mine, for instance). */
|
* machines in all cases (mine, for instance). */
|
||||||
#define VOXYGEN_COMPUTATION_PREERENCE_FRAGMENT 0
|
#define VOXYGEN_COMPUTATION_PREFERENCE_FRAGMENT 0
|
||||||
#define VOXYGEN_COMPUTATION_PREERENCE_VERTEX 1
|
#define VOXYGEN_COMPUTATION_PREFERENCE_VERTEX 1
|
||||||
|
|
||||||
#define FLUID_MODE_CHEAP 0
|
#define FLUID_MODE_CHEAP 0
|
||||||
#define FLUID_MODE_SHINY 1
|
#define FLUID_MODE_SHINY 1
|
||||||
@ -43,7 +43,7 @@
|
|||||||
/* Constants expected to be defined automatically by configuration: */
|
/* Constants expected to be defined automatically by configuration: */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define VOXYGEN_COMPUTATION_PREERENCE <preference>
|
#define VOXYGEN_COMPUTATION_PREFERENCE <preference>
|
||||||
#define FLUID_MODE <mode>
|
#define FLUID_MODE <mode>
|
||||||
#define CLOUD_MODE <mode>
|
#define CLOUD_MODE <mode>
|
||||||
#define LIGHTING_ALGORITHM <algorithm>
|
#define LIGHTING_ALGORITHM <algorithm>
|
||||||
|
@ -1000,7 +1000,7 @@ impl Client {
|
|||||||
// -0.5 for being able to move to the corner of the current chunk
|
// -0.5 for being able to move to the corner of the current chunk
|
||||||
// -1 because chunks are not meshed if they don't have all their neighbors
|
// -1 because chunks are not meshed if they don't have all their neighbors
|
||||||
// (notice also that view_distance is decreased by 1)
|
// (notice also that view_distance is decreased by 1)
|
||||||
// (this subtraction on vd is ommitted elsewhere in order to provide
|
// (this subtraction on vd is omitted elsewhere in order to provide
|
||||||
// a buffer layer of loaded chunks)
|
// a buffer layer of loaded chunks)
|
||||||
let top = if 2 * (dist - 2).max(0).pow(2) > (view_distance - 1).pow(2) as i32 {
|
let top = if 2 * (dist - 2).max(0).pow(2) > (view_distance - 1).pow(2) as i32 {
|
||||||
((view_distance - 1).pow(2) as f32 - (dist - 2).pow(2) as f32)
|
((view_distance - 1).pow(2) as f32 - (dist - 2).pow(2) as f32)
|
||||||
@ -1383,7 +1383,7 @@ impl Client {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
ServerMsg::Disconnect => {
|
ServerMsg::Disconnect => {
|
||||||
debug!("finally sendinge ClientMsg::Terminate");
|
debug!("finally sending ClientMsg::Terminate");
|
||||||
frontend_events.push(Event::Disconnect);
|
frontend_events.push(Event::Disconnect);
|
||||||
self.singleton_stream.send(ClientMsg::Terminate)?;
|
self.singleton_stream.send(ClientMsg::Terminate)?;
|
||||||
break Ok(());
|
break Ok(());
|
||||||
|
@ -87,7 +87,7 @@ impl Input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Update input with newer version
|
/// Update input with newer version
|
||||||
/// Used to update inputs with input recieved from clients
|
/// Used to update inputs with input received from clients
|
||||||
pub fn update_with_new(&mut self, new: Self) {
|
pub fn update_with_new(&mut self, new: Self) {
|
||||||
if self.pressed != new.pressed {
|
if self.pressed != new.pressed {
|
||||||
self.freshness = Freshness::New;
|
self.freshness = Freshness::New;
|
||||||
|
@ -11,7 +11,7 @@ use tracing::{error, warn};
|
|||||||
// - no support for more complex group structures
|
// - no support for more complex group structures
|
||||||
// - lack of npc group integration
|
// - lack of npc group integration
|
||||||
// - relies on careful management of groups to maintain a valid state
|
// - relies on careful management of groups to maintain a valid state
|
||||||
// - the possesion rod could probably wreck this
|
// - the possession rod could probably wreck this
|
||||||
// - clients don't know which pets are theirs (could be easy to solve by
|
// - clients don't know which pets are theirs (could be easy to solve by
|
||||||
// putting owner uid in Role::Pet)
|
// putting owner uid in Role::Pet)
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ pub enum ChangeNotification<E> {
|
|||||||
// Note: now that we are dipping into uids here consider just using
|
// Note: now that we are dipping into uids here consider just using
|
||||||
// ChangeNotification<Uid> everywhere
|
// ChangeNotification<Uid> everywhere
|
||||||
// Also note when the same notification is sent to multiple destinations the
|
// Also note when the same notification is sent to multiple destinations the
|
||||||
// maping might be duplicated effort
|
// mapping might be duplicated effort
|
||||||
impl<E> ChangeNotification<E> {
|
impl<E> ChangeNotification<E> {
|
||||||
pub fn try_map<T>(self, f: impl Fn(E) -> Option<T>) -> Option<ChangeNotification<T>> {
|
pub fn try_map<T>(self, f: impl Fn(E) -> Option<T>) -> Option<ChangeNotification<T>> {
|
||||||
match self {
|
match self {
|
||||||
|
@ -86,7 +86,7 @@ impl ArmorSlot {
|
|||||||
// when they are not equipped, when that is implemented this helper function
|
// when they are not equipped, when that is implemented this helper function
|
||||||
// should no longer be needed
|
// should no longer be needed
|
||||||
|
|
||||||
/// Create an ItemConfig for an item. Apply abilties to item.
|
/// Create an ItemConfig for an item. Apply abilities to item.
|
||||||
fn item_config(item: item::Item) -> comp::ItemConfig {
|
fn item_config(item: item::Item) -> comp::ItemConfig {
|
||||||
let mut abilities = if let item::ItemKind::Tool(tool) = &item.kind {
|
let mut abilities = if let item::ItemKind::Tool(tool) = &item.kind {
|
||||||
tool.get_abilities()
|
tool.get_abilities()
|
||||||
@ -105,7 +105,7 @@ fn item_config(item: item::Item) -> comp::ItemConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replace an equiptment slot with an item. Return the item that was in the
|
/// Replace an equipment slot with an item. Return the item that was in the
|
||||||
/// slot, if any. Doesn't update the inventory.
|
/// slot, if any. Doesn't update the inventory.
|
||||||
fn loadout_replace(
|
fn loadout_replace(
|
||||||
equip_slot: EquipSlot,
|
equip_slot: EquipSlot,
|
||||||
|
@ -161,7 +161,7 @@ impl Stats {
|
|||||||
// TODO: define base stats somewhere else (maybe method on Body?)
|
// TODO: define base stats somewhere else (maybe method on Body?)
|
||||||
let (endurance, fitness, willpower) = match species {
|
let (endurance, fitness, willpower) = match species {
|
||||||
Some(Species::Danari) => (0, 2, 3), // Small, flexible, intelligent, physically weak
|
Some(Species::Danari) => (0, 2, 3), // Small, flexible, intelligent, physically weak
|
||||||
Some(Species::Dwarf) => (2, 2, 1), // phyiscally strong, intelligent, slow reflexes
|
Some(Species::Dwarf) => (2, 2, 1), // physically strong, intelligent, slow reflexes
|
||||||
Some(Species::Elf) => (1, 2, 2), // Intelligent, quick, physically weak
|
Some(Species::Elf) => (1, 2, 2), // Intelligent, quick, physically weak
|
||||||
Some(Species::Human) => (2, 1, 2), // Perfectly balanced
|
Some(Species::Human) => (2, 1, 2), // Perfectly balanced
|
||||||
Some(Species::Orc) => (3, 2, 0), /* Physically strong, non intelligent, medium */
|
Some(Species::Orc) => (3, 2, 0), /* Physically strong, non intelligent, medium */
|
||||||
|
@ -116,7 +116,7 @@ pub struct WorldMapMsg {
|
|||||||
/// big a deal on the world map but is probably needed in order to ensure
|
/// big a deal on the world map but is probably needed in order to ensure
|
||||||
/// smooth transitions between chunks in LoD view. Additionally, when we
|
/// smooth transitions between chunks in LoD view. Additionally, when we
|
||||||
/// start using the shadow information to do local lighting on the world
|
/// start using the shadow information to do local lighting on the world
|
||||||
/// map, we'll want a quick way to test where we can go out of shadoow at
|
/// map, we'll want a quick way to test where we can go out of shadow at
|
||||||
/// arbitrary heights (since the player and other entities cajn find
|
/// arbitrary heights (since the player and other entities cajn find
|
||||||
/// themselves far from the ground at times). While this is only an
|
/// themselves far from the ground at times). While this is only an
|
||||||
/// approximation to a proper distance map, hopefully it will give us
|
/// approximation to a proper distance map, hopefully it will give us
|
||||||
@ -151,7 +151,7 @@ pub struct WorldMapMsg {
|
|||||||
/// probably be less effective.
|
/// probably be less effective.
|
||||||
///
|
///
|
||||||
/// For related reasons, rather than storing distances as in a standard
|
/// For related reasons, rather than storing distances as in a standard
|
||||||
/// distance map (which would lead to monotonically *decreaing* values
|
/// distance map (which would lead to monotonically *decreasing* values
|
||||||
/// as we approached the occluder from a given direction), we store the
|
/// as we approached the occluder from a given direction), we store the
|
||||||
/// estimated *occluder height.* The idea here is that we replace the
|
/// estimated *occluder height.* The idea here is that we replace the
|
||||||
/// monotonic sequences with constant sequences, which are extremely
|
/// monotonic sequences with constant sequences, which are extremely
|
||||||
@ -196,7 +196,7 @@ pub enum ServerMsg {
|
|||||||
CharacterDataLoadError(String),
|
CharacterDataLoadError(String),
|
||||||
/// A list of characters belonging to the a authenticated player was sent
|
/// A list of characters belonging to the a authenticated player was sent
|
||||||
CharacterListUpdate(Vec<CharacterItem>),
|
CharacterListUpdate(Vec<CharacterItem>),
|
||||||
/// An error occured while creating or deleting a character
|
/// An error occurred while creating or deleting a character
|
||||||
CharacterActionError(String),
|
CharacterActionError(String),
|
||||||
PlayerListUpdate(PlayerListUpdate),
|
PlayerListUpdate(PlayerListUpdate),
|
||||||
GroupUpdate(comp::group::ChangeNotification<sync::Uid>),
|
GroupUpdate(comp::group::ChangeNotification<sync::Uid>),
|
||||||
|
@ -117,7 +117,7 @@ impl FromStr for NpcBody {
|
|||||||
type Err = ();
|
type Err = ();
|
||||||
|
|
||||||
/// Get an NPC kind from a string. If a body kind is matched without an
|
/// Get an NPC kind from a string. If a body kind is matched without an
|
||||||
/// associated species, generate the species randmly within it; if an
|
/// associated species, generate the species randomly within it; if an
|
||||||
/// explicit species is found, generate a random member of the species;
|
/// explicit species is found, generate a random member of the species;
|
||||||
/// otherwise, return Err(()).
|
/// otherwise, return Err(()).
|
||||||
fn from_str(s: &str) -> Result<Self, ()> { Self::from_str_with(s, kind_to_body) }
|
fn from_str(s: &str) -> Result<Self, ()> { Self::from_str_with(s, kind_to_body) }
|
||||||
|
@ -18,7 +18,7 @@ pub struct Region {
|
|||||||
// Indices of neighboring regions
|
// Indices of neighboring regions
|
||||||
neighbors: [Option<usize>; 8],
|
neighbors: [Option<usize>; 8],
|
||||||
// TODO consider SmallVec for these
|
// TODO consider SmallVec for these
|
||||||
// Entites that left or entered this region
|
// Entities that left or entered this region
|
||||||
events: Vec<Event>,
|
events: Vec<Event>,
|
||||||
}
|
}
|
||||||
impl Region {
|
impl Region {
|
||||||
@ -96,7 +96,7 @@ impl RegionMap {
|
|||||||
tracked_entities: BitSet::new(),
|
tracked_entities: BitSet::new(),
|
||||||
entities_to_move: Vec::new(),
|
entities_to_move: Vec::new(),
|
||||||
entities_to_remove: Vec::new(),
|
entities_to_remove: Vec::new(),
|
||||||
// rate is depedent on the rate the caller calls region_manager.tick()
|
// rate is dependent on the rate the caller calls region_manager.tick()
|
||||||
tick: 0,
|
tick: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ impl RegionMap {
|
|||||||
.clear();
|
.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add any untracked entites
|
// Add any untracked entities
|
||||||
for (pos, id) in (&pos, &entities, !&self.tracked_entities)
|
for (pos, id) in (&pos, &entities, !&self.tracked_entities)
|
||||||
.join()
|
.join()
|
||||||
.map(|(pos, e, _)| (pos, e.id()))
|
.map(|(pos, e, _)| (pos, e.id()))
|
||||||
@ -146,7 +146,7 @@ impl RegionMap {
|
|||||||
let current_region = self.index_key(i).unwrap();
|
let current_region = self.index_key(i).unwrap();
|
||||||
let key = Self::pos_key(pos);
|
let key = Self::pos_key(pos);
|
||||||
// Consider switching
|
// Consider switching
|
||||||
// Caculate distance outside border
|
// Calculate distance outside border
|
||||||
if key != current_region
|
if key != current_region
|
||||||
&& (Vec2::<i32>::from(pos) - Self::key_pos(current_region))
|
&& (Vec2::<i32>::from(pos) - Self::key_pos(current_region))
|
||||||
.map(|e| e.abs() as u32)
|
.map(|e| e.abs() as u32)
|
||||||
@ -168,7 +168,7 @@ impl RegionMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove region if it is empty
|
// Remove region if it is empty
|
||||||
// TODO: distribute this betweeen ticks
|
// TODO: distribute this between ticks
|
||||||
let (key, region) = self.regions.get_index(i).unwrap();
|
let (key, region) = self.regions.get_index(i).unwrap();
|
||||||
if region.removable() {
|
if region.removable() {
|
||||||
regions_to_remove.push(*key);
|
regions_to_remove.push(*key);
|
||||||
|
@ -9,7 +9,7 @@ use std::time::Duration;
|
|||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Data {
|
pub struct Data {
|
||||||
/// Can you hold the abilty beyond the prepare duration
|
/// Can you hold the ability beyond the prepare duration
|
||||||
pub holdable: bool,
|
pub holdable: bool,
|
||||||
/// How long we have to prepare the weapon
|
/// How long we have to prepare the weapon
|
||||||
pub prepare_duration: Duration,
|
pub prepare_duration: Duration,
|
||||||
|
@ -23,7 +23,7 @@ pub struct Data {
|
|||||||
pub initial_damage: u32,
|
pub initial_damage: u32,
|
||||||
/// How much damage is dealt with max charge
|
/// How much damage is dealt with max charge
|
||||||
pub max_damage: u32,
|
pub max_damage: u32,
|
||||||
/// How much knockback there is with no chage
|
/// How much knockback there is with no charge
|
||||||
pub initial_knockback: f32,
|
pub initial_knockback: f32,
|
||||||
/// How much knockback there is at max charge
|
/// How much knockback there is at max charge
|
||||||
pub max_knockback: f32,
|
pub max_knockback: f32,
|
||||||
|
@ -60,7 +60,7 @@ pub struct Data {
|
|||||||
pub stage_time_active: Duration,
|
pub stage_time_active: Duration,
|
||||||
/// Whether current stage has exhausted its attack
|
/// Whether current stage has exhausted its attack
|
||||||
pub stage_exhausted: bool,
|
pub stage_exhausted: bool,
|
||||||
/// Whether state has performed intialization logic
|
/// Whether state has performed initialization logic
|
||||||
pub initialized: bool,
|
pub initialized: bool,
|
||||||
/// What this instance's current transition stat is
|
/// What this instance's current transition stat is
|
||||||
pub transition_style: TransitionStyle,
|
pub transition_style: TransitionStyle,
|
||||||
|
@ -141,7 +141,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
|
|
||||||
let mut inputs = &mut controller.inputs;
|
let mut inputs = &mut controller.inputs;
|
||||||
|
|
||||||
// Default to looking in orientation direction (can be overriden below)
|
// Default to looking in orientation direction (can be overridden below)
|
||||||
inputs.look_dir = ori.0;
|
inputs.look_dir = ori.0;
|
||||||
|
|
||||||
const AVG_FOLLOW_DIST: f32 = 6.0;
|
const AVG_FOLLOW_DIST: f32 = 6.0;
|
||||||
@ -553,7 +553,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
debug_assert!(inputs.look_dir.map(|e| !e.is_nan()).reduce_and());
|
debug_assert!(inputs.look_dir.map(|e| !e.is_nan()).reduce_and());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proccess group invites
|
// Process group invites
|
||||||
for (_invite, alignment, agent, controller) in
|
for (_invite, alignment, agent, controller) in
|
||||||
(&invites, &alignments, &mut agents, &mut controllers).join()
|
(&invites, &alignments, &mut agents, &mut controllers).join()
|
||||||
{
|
{
|
||||||
|
@ -130,7 +130,7 @@ impl<'a> JoinData<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// ## Character Behavior System
|
/// ## Character Behavior System
|
||||||
/// Passes `JoinData` to `CharacterState`'s `behavior` handler fn's. Recieves a
|
/// Passes `JoinData` to `CharacterState`'s `behavior` handler fn's. Receives a
|
||||||
/// `StateUpdate` in return and performs updates to ECS Components from that.
|
/// `StateUpdate` in return and performs updates to ECS Components from that.
|
||||||
pub struct Sys;
|
pub struct Sys;
|
||||||
|
|
||||||
|
@ -21,9 +21,10 @@ pub const GRAVITY: f32 = 9.81 * 5.0;
|
|||||||
const BOUYANCY: f32 = 1.0;
|
const BOUYANCY: f32 = 1.0;
|
||||||
// Friction values used for linear damping. They are unitless quantities. The
|
// Friction values used for linear damping. They are unitless quantities. The
|
||||||
// value of these quantities must be between zero and one. They represent the
|
// value of these quantities must be between zero and one. They represent the
|
||||||
// amount an object will slow down within 1/60th of a second. Eg. if the frction
|
// amount an object will slow down within 1/60th of a second. Eg. if the
|
||||||
// is 0.01, and the speed is 1.0, then after 1/60th of a second the speed will
|
// friction is 0.01, and the speed is 1.0, then after 1/60th of a second the
|
||||||
// be 0.99. after 1 second the speed will be 0.54, which is 0.99 ^ 60.
|
// speed will be 0.99. after 1 second the speed will be 0.54, which is 0.99 ^
|
||||||
|
// 60.
|
||||||
const FRIC_GROUND: f32 = 0.15;
|
const FRIC_GROUND: f32 = 0.15;
|
||||||
const FRIC_AIR: f32 = 0.0125;
|
const FRIC_AIR: f32 = 0.0125;
|
||||||
const FRIC_FLUID: f32 = 0.2;
|
const FRIC_FLUID: f32 = 0.2;
|
||||||
|
@ -112,7 +112,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
energy.get_mut_unchecked().regen_rate = 0.0
|
energy.get_mut_unchecked().regen_rate = 0.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// recover small amount of pasive energy from blocking, and bonus energy from
|
// recover small amount of passive energy from blocking, and bonus energy from
|
||||||
// blocking attacks?
|
// blocking attacks?
|
||||||
CharacterState::BasicBlock => {
|
CharacterState::BasicBlock => {
|
||||||
let res = {
|
let res = {
|
||||||
|
@ -250,7 +250,7 @@ pub struct MapConfig<'a> {
|
|||||||
///
|
///
|
||||||
/// (where θ is the half-angle of the FOV).
|
/// (where θ is the half-angle of the FOV).
|
||||||
///
|
///
|
||||||
/// Taking the limit as θ → 90, we show that this degenrates to an
|
/// Taking the limit as θ → 90, we show that this degenerates to an
|
||||||
/// orthogonal projection:
|
/// orthogonal projection:
|
||||||
///
|
///
|
||||||
/// lim{n → ∞}(-f(-n / z - 1) / (f - n)) = -(z - -n) / (f - n).
|
/// lim{n → ∞}(-f(-n / z - 1) / (f - n)) = -(z - -n) / (f - n).
|
||||||
@ -560,7 +560,7 @@ impl<'a> MapConfig<'a> {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Color in connectins.
|
// Color in connections.
|
||||||
let water_color_factor = 2.0;
|
let water_color_factor = 2.0;
|
||||||
let g_water = 32.0 * water_color_factor;
|
let g_water = 32.0 * water_color_factor;
|
||||||
let b_water = 64.0 * water_color_factor;
|
let b_water = 64.0 * water_color_factor;
|
||||||
|
@ -93,7 +93,7 @@ impl<Context: SubContext<S>, T, S> Typed<Context, Pure<T>, S> for T {
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// /// The actual *cases.* If you think of pattern match arms as being closures that accept
|
/// /// The actual *cases.* If you think of pattern match arms as being closures that accept
|
||||||
/// /// the cconstructor types as arguments, you can think of this structure as somehow
|
/// /// the constructor types as arguments, you can think of this structure as somehow
|
||||||
/// /// representing just the data *owned* by the closure. This is also what you will
|
/// /// representing just the data *owned* by the closure. This is also what you will
|
||||||
/// /// generally store in your ron file--it has a field for each constructor of your enum,
|
/// /// generally store in your ron file--it has a field for each constructor of your enum,
|
||||||
/// /// with the types of all the fields specified by the implementation of [PackedElim] for
|
/// /// with the types of all the fields specified by the implementation of [PackedElim] for
|
||||||
|
@ -141,7 +141,7 @@ pub fn saturate_srgb(col: Rgb<f32>, value: f32) -> Rgb<f32> {
|
|||||||
linear_to_srgb(hsv_to_rgb(hsv).map(|e| e.min(1.0).max(0.0)))
|
linear_to_srgb(hsv_to_rgb(hsv).map(|e| e.min(1.0).max(0.0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Preserves the luma of one color while changing its chromaticty to match the
|
/// Preserves the luma of one color while changing its chromaticity to match the
|
||||||
/// other
|
/// other
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn chromify_srgb(luma: Rgb<f32>, chroma: Rgb<f32>) -> Rgb<f32> {
|
pub fn chromify_srgb(luma: Rgb<f32>, chroma: Rgb<f32>) -> Rgb<f32> {
|
||||||
|
@ -81,7 +81,7 @@ impl Dir {
|
|||||||
Self(slerp_normalized(from.0, to.0, factor))
|
Self(slerp_normalized(from.0, to.0, factor))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Note: this uses `from` if `to` is unormalizable
|
/// Note: this uses `from` if `to` is unnormalizable
|
||||||
pub fn slerp_to_vec3(from: Self, to: Vec3<f32>, factor: f32) -> Self {
|
pub fn slerp_to_vec3(from: Self, to: Vec3<f32>, factor: f32) -> Self {
|
||||||
Self(slerp_to_unnormalized(from.0, to, factor).unwrap_or_else(|e| e))
|
Self(slerp_to_unnormalized(from.0, to, factor).unwrap_or_else(|e| e))
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ fn slerp_normalized(from: vek::Vec3<f32>, to: vek::Vec3<f32>, factor: f32) -> ve
|
|||||||
/// Additionally, it avoids unnecessary calculations if they are near identical
|
/// Additionally, it avoids unnecessary calculations if they are near identical
|
||||||
/// Assumes `from` is normalized and returns a normalized vector, but `to`
|
/// Assumes `from` is normalized and returns a normalized vector, but `to`
|
||||||
/// doesn't need to be normalized
|
/// doesn't need to be normalized
|
||||||
/// Returns `Err(from)`` if `to` is unormalizable
|
/// Returns `Err(from)`` if `to` is unnormalizable
|
||||||
// TODO: in some cases we might want to base the slerp rate on the magnitude of
|
// TODO: in some cases we might want to base the slerp rate on the magnitude of
|
||||||
// `to` for example when `to` is velocity and `from` is orientation
|
// `to` for example when `to` is velocity and `from` is orientation
|
||||||
fn slerp_to_unnormalized(
|
fn slerp_to_unnormalized(
|
||||||
|
@ -83,7 +83,7 @@ fn get_options<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.setting(clap::AppSettings::ColorAuto)
|
.setting(clap::AppSettings::ColorAuto)
|
||||||
.subcommand(SubCommand::with_name("quit").about("closes program"))
|
.subcommand(SubCommand::with_name("quit").about("closes program"))
|
||||||
.subcommand(SubCommand::with_name("disconnect").about("stop connections to all servers"))
|
.subcommand(SubCommand::with_name("disconnect").about("stop connections to all servers"))
|
||||||
.subcommand(SubCommand::with_name("t").about("quick test by connectiong to 127.0.0.1:1231"))
|
.subcommand(SubCommand::with_name("t").about("quick test by connecting to 127.0.0.1:1231"))
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("connect")
|
SubCommand::with_name("connect")
|
||||||
.about("opens a connection to another instance of this fileserver network")
|
.about("opens a connection to another instance of this fileserver network")
|
||||||
|
@ -72,7 +72,7 @@ impl Server {
|
|||||||
match self.network.connect(addr.clone()).await {
|
match self.network.connect(addr.clone()).await {
|
||||||
Ok(p) => self.loop_participant(p).await,
|
Ok(p) => self.loop_participant(p).await,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Failled to connect to {:?}, err: {:?}", &addr, e);
|
println!("Failed to connect to {:?}, err: {:?}", &addr, e);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -93,7 +93,7 @@ fn main() -> Result<(), u32> {
|
|||||||
let cur = Instant::now();
|
let cur = Instant::now();
|
||||||
let dur = cur.duration_since(start_time);
|
let dur = cur.duration_since(start_time);
|
||||||
println!("================");
|
println!("================");
|
||||||
println!("test endet");
|
println!("test ended");
|
||||||
println!(
|
println!(
|
||||||
"total send: {}MiB",
|
"total send: {}MiB",
|
||||||
total_bytes_send.load(Ordering::Relaxed) / (1024 * 1024)
|
total_bytes_send.load(Ordering::Relaxed) / (1024 * 1024)
|
||||||
|
@ -166,7 +166,7 @@ impl Network {
|
|||||||
/// * `FnOnce` - you need to run the returning FnOnce exactly once, probably
|
/// * `FnOnce` - you need to run the returning FnOnce exactly once, probably
|
||||||
/// in it's own thread. this is NOT done internally, so that you are free
|
/// in it's own thread. this is NOT done internally, so that you are free
|
||||||
/// to choose the threadpool implementation of your choice. We recommend
|
/// to choose the threadpool implementation of your choice. We recommend
|
||||||
/// using [`ThreadPool`] from [`uvth`] crate. This fn will runn the
|
/// using [`ThreadPool`] from [`uvth`] crate. This fn will run the
|
||||||
/// Scheduler to handle all `Network` internals. Additional threads will
|
/// Scheduler to handle all `Network` internals. Additional threads will
|
||||||
/// be allocated on an internal async-aware threadpool
|
/// be allocated on an internal async-aware threadpool
|
||||||
///
|
///
|
||||||
@ -208,7 +208,7 @@ impl Network {
|
|||||||
/// See [`new`]
|
/// See [`new`]
|
||||||
///
|
///
|
||||||
/// # additional Arguments
|
/// # additional Arguments
|
||||||
/// * `registry` - Provide a Registy in order to collect Prometheus metrics
|
/// * `registry` - Provide a Registry in order to collect Prometheus metrics
|
||||||
/// by this `Network`, `None` will deactivate Tracing. Tracing is done via
|
/// by this `Network`, `None` will deactivate Tracing. Tracing is done via
|
||||||
/// [`prometheus`]
|
/// [`prometheus`]
|
||||||
///
|
///
|
||||||
@ -301,14 +301,14 @@ impl Network {
|
|||||||
.send((address, s2a_result_s))
|
.send((address, s2a_result_s))
|
||||||
.await?;
|
.await?;
|
||||||
match s2a_result_r.await? {
|
match s2a_result_r.await? {
|
||||||
//waiting guarantees that we either listened sucessfully or get an error like port in
|
//waiting guarantees that we either listened successfully or get an error like port in
|
||||||
// use
|
// use
|
||||||
Ok(()) => Ok(()),
|
Ok(()) => Ok(()),
|
||||||
Err(e) => Err(NetworkError::ListenFailed(e)),
|
Err(e) => Err(NetworkError::ListenFailed(e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// starts connectiong to an [`ProtocolAddr`].
|
/// starts connection to an [`ProtocolAddr`].
|
||||||
/// When the method returns the Network either returns a [`Participant`]
|
/// When the method returns the Network either returns a [`Participant`]
|
||||||
/// ready to open [`Streams`] on OR has returned a [`NetworkError`] (e.g.
|
/// ready to open [`Streams`] on OR has returned a [`NetworkError`] (e.g.
|
||||||
/// can't connect, or invalid Handshake) # Examples
|
/// can't connect, or invalid Handshake) # Examples
|
||||||
@ -443,7 +443,7 @@ impl Participant {
|
|||||||
/// * `promises` - use a combination of you prefered [`Promises`], see the
|
/// * `promises` - use a combination of you prefered [`Promises`], see the
|
||||||
/// link for further documentation. You can combine them, e.g.
|
/// link for further documentation. You can combine them, e.g.
|
||||||
/// `PROMISES_ORDERED | PROMISES_CONSISTENCY` The Stream will then
|
/// `PROMISES_ORDERED | PROMISES_CONSISTENCY` The Stream will then
|
||||||
/// guarantee that those promisses are met.
|
/// guarantee that those promises are met.
|
||||||
///
|
///
|
||||||
/// A [`ParticipantError`] might be thrown if the `Participant` is already
|
/// A [`ParticipantError`] might be thrown if the `Participant` is already
|
||||||
/// closed. [`Streams`] can be created without a answer from the remote
|
/// closed. [`Streams`] can be created without a answer from the remote
|
||||||
@ -511,7 +511,7 @@ impl Participant {
|
|||||||
///
|
///
|
||||||
/// # fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
/// # fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
||||||
/// // Create a Network, connect on port 2110 and wait for the other side to open a stream
|
/// // Create a Network, connect on port 2110 and wait for the other side to open a stream
|
||||||
/// // Note: It's quite unusal to activly connect, but then wait on a stream to be connected, usually the Appication taking initiative want's to also create the first Stream.
|
/// // Note: It's quite unusual to actively connect, but then wait on a stream to be connected, usually the Application taking initiative want's to also create the first Stream.
|
||||||
/// let (network, f) = Network::new(Pid::new());
|
/// let (network, f) = Network::new(Pid::new());
|
||||||
/// std::thread::spawn(f);
|
/// std::thread::spawn(f);
|
||||||
/// # let (remote, fr) = Network::new(Pid::new());
|
/// # let (remote, fr) = Network::new(Pid::new());
|
||||||
@ -557,7 +557,7 @@ impl Participant {
|
|||||||
/// There is NO `disconnected` function in `Participant`, if a `Participant`
|
/// There is NO `disconnected` function in `Participant`, if a `Participant`
|
||||||
/// is no longer reachable (e.g. as the network cable was unplugged) the
|
/// is no longer reachable (e.g. as the network cable was unplugged) the
|
||||||
/// `Participant` will fail all action, but needs to be manually
|
/// `Participant` will fail all action, but needs to be manually
|
||||||
/// disconected, using this function.
|
/// disconnected, using this function.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```rust
|
/// ```rust
|
||||||
@ -607,7 +607,7 @@ impl Participant {
|
|||||||
match res {
|
match res {
|
||||||
Ok(()) => trace!(?pid, "Participant is now closed"),
|
Ok(()) => trace!(?pid, "Participant is now closed"),
|
||||||
Err(ref e) => {
|
Err(ref e) => {
|
||||||
trace!(?pid, ?e, "Error occured during shutdown of participant")
|
trace!(?pid, ?e, "Error occurred during shutdown of participant")
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
res
|
res
|
||||||
@ -684,7 +684,7 @@ impl Stream {
|
|||||||
/// will be send. If the `Stream` is dropped from remote side no further
|
/// will be send. If the `Stream` is dropped from remote side no further
|
||||||
/// messages are send, because the remote side has no way of listening
|
/// messages are send, because the remote side has no way of listening
|
||||||
/// to them either way. If the last channel is destroyed (e.g. by losing
|
/// to them either way. If the last channel is destroyed (e.g. by losing
|
||||||
/// the internet connection or non-gracefull shutdown, pending messages
|
/// the internet connection or non-graceful shutdown, pending messages
|
||||||
/// are also dropped.
|
/// are also dropped.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -906,7 +906,7 @@ impl Drop for Participant {
|
|||||||
match task::block_on(self.a2s_disconnect_s.lock()).take() {
|
match task::block_on(self.a2s_disconnect_s.lock()).take() {
|
||||||
None => trace!(
|
None => trace!(
|
||||||
?pid,
|
?pid,
|
||||||
"Participant has been shutdown cleanly, no further waiting is requiered!"
|
"Participant has been shutdown cleanly, no further waiting is required!"
|
||||||
),
|
),
|
||||||
Some(mut a2s_disconnect_s) => {
|
Some(mut a2s_disconnect_s) => {
|
||||||
debug!(?pid, "Disconnect from Scheduler");
|
debug!(?pid, "Disconnect from Scheduler");
|
||||||
@ -936,7 +936,7 @@ impl Drop for Participant {
|
|||||||
|
|
||||||
impl Drop for Stream {
|
impl Drop for Stream {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// send if closed is unecessary but doesnt hurt, we must not crash
|
// send if closed is unnecessary but doesnt hurt, we must not crash
|
||||||
if !self.send_closed.load(Ordering::Relaxed) {
|
if !self.send_closed.load(Ordering::Relaxed) {
|
||||||
let sid = self.sid;
|
let sid = self.sid;
|
||||||
let pid = self.pid;
|
let pid = self.pid;
|
||||||
|
@ -88,7 +88,7 @@ pub(crate) struct Handshake {
|
|||||||
|
|
||||||
impl Handshake {
|
impl Handshake {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
const WRONG_NUMBER: &'static [u8] = "Handshake does not contain the magic number requiered by \
|
const WRONG_NUMBER: &'static [u8] = "Handshake does not contain the magic number required by \
|
||||||
veloren server.\nWe are not sure if you are a valid \
|
veloren server.\nWe are not sure if you are a valid \
|
||||||
veloren client.\nClosing the connection"
|
veloren client.\nClosing the connection"
|
||||||
.as_bytes();
|
.as_bytes();
|
||||||
@ -150,7 +150,7 @@ impl Handshake {
|
|||||||
if cnt > 0 {
|
if cnt > 0 {
|
||||||
debug!(
|
debug!(
|
||||||
?cnt,
|
?cnt,
|
||||||
"Some additional frames got already transfered, piping them to the \
|
"Some additional frames got already transferred, piping them to the \
|
||||||
bparticipant as leftover_frames"
|
bparticipant as leftover_frames"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
//! other [`Networks`] over the network protocols (e.g. TCP, UDP)
|
//! other [`Networks`] over the network protocols (e.g. TCP, UDP)
|
||||||
//!
|
//!
|
||||||
//! To connect to another application, you must know it's [`ProtocolAddr`]. One
|
//! To connect to another application, you must know it's [`ProtocolAddr`]. One
|
||||||
//! side will call [`connect`], the other [`connected`]. If successfull both
|
//! side will call [`connect`], the other [`connected`]. If successful both
|
||||||
//! applications will now get a [`Participant`].
|
//! applications will now get a [`Participant`].
|
||||||
//!
|
//!
|
||||||
//! This [`Participant`] represents the connection between those 2 applications.
|
//! This [`Participant`] represents the connection between those 2 applications.
|
||||||
//! over the respective [`ProtocolAddr`] and with it the choosen network
|
//! over the respective [`ProtocolAddr`] and with it the chosen network
|
||||||
//! protocol. However messages can't be send directly via [`Participants`],
|
//! protocol. However messages can't be send directly via [`Participants`],
|
||||||
//! instead you must open a [`Stream`] on it. Like above, one side has to call
|
//! instead you must open a [`Stream`] on it. Like above, one side has to call
|
||||||
//! [`open`], the other [`opened`]. [`Streams`] can have a different priority
|
//! [`open`], the other [`opened`]. [`Streams`] can have a different priority
|
||||||
|
@ -5,7 +5,7 @@ use std::{io, sync::Arc};
|
|||||||
|
|
||||||
//Todo: Evaluate switching to VecDeque for quickly adding and removing data
|
//Todo: Evaluate switching to VecDeque for quickly adding and removing data
|
||||||
// from front, back.
|
// from front, back.
|
||||||
// - It would prob requiere custom bincode code but thats possible.
|
// - It would prob require custom bincode code but thats possible.
|
||||||
/// Support struct used for optimising sending the same Message to multiple
|
/// Support struct used for optimising sending the same Message to multiple
|
||||||
/// [`Stream`]
|
/// [`Stream`]
|
||||||
///
|
///
|
||||||
@ -47,7 +47,7 @@ pub(crate) fn deserialize<M: DeserializeOwned>(buffer: MessageBuffer) -> bincode
|
|||||||
let span = lz4_compress::decompress(&buffer.data)
|
let span = lz4_compress::decompress(&buffer.data)
|
||||||
.expect("lz4 decompression failed, failed to deserialze");
|
.expect("lz4 decompression failed, failed to deserialze");
|
||||||
//this might fail if you choose the wrong type for M. in that case probably X
|
//this might fail if you choose the wrong type for M. in that case probably X
|
||||||
// got transfered while you assume Y. probably this means your application
|
// got transferred while you assume Y. probably this means your application
|
||||||
// logic is wrong. E.g. You expect a String, but just get a u8.
|
// logic is wrong. E.g. You expect a String, but just get a u8.
|
||||||
bincode::deserialize(span.as_slice())
|
bincode::deserialize(span.as_slice())
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ impl BParticipant {
|
|||||||
mut b2s_prio_statistic_s: mpsc::UnboundedSender<B2sPrioStatistic>,
|
mut b2s_prio_statistic_s: mpsc::UnboundedSender<B2sPrioStatistic>,
|
||||||
) {
|
) {
|
||||||
//This time equals the MINIMUM Latency in average, so keep it down and //Todo:
|
//This time equals the MINIMUM Latency in average, so keep it down and //Todo:
|
||||||
// make it configureable or switch to await E.g. Prio 0 = await, prio 50
|
// make it configurable or switch to await E.g. Prio 0 = await, prio 50
|
||||||
// wait for more messages
|
// wait for more messages
|
||||||
const TICK_TIME: Duration = Duration::from_millis(10);
|
const TICK_TIME: Duration = Duration::from_millis(10);
|
||||||
const FRAMES_PER_TICK: usize = 10005;
|
const FRAMES_PER_TICK: usize = 10005;
|
||||||
@ -244,7 +244,7 @@ impl BParticipant {
|
|||||||
self.running_mgr.fetch_sub(1, Ordering::Relaxed);
|
self.running_mgr.fetch_sub(1, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
//retruns false if sending isn't possible. In that case we have to render the
|
//returns false if sending isn't possible. In that case we have to render the
|
||||||
// Participant `closed`
|
// Participant `closed`
|
||||||
#[must_use = "You need to check if the send was successful and report to client!"]
|
#[must_use = "You need to check if the send was successful and report to client!"]
|
||||||
async fn send_frame(
|
async fn send_frame(
|
||||||
@ -425,7 +425,7 @@ impl BParticipant {
|
|||||||
warn!(
|
warn!(
|
||||||
?e,
|
?e,
|
||||||
?mid,
|
?mid,
|
||||||
"Dropping message, as streams seem to be in act of beeing \
|
"Dropping message, as streams seem to be in act of being \
|
||||||
dropped right now"
|
dropped right now"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -584,7 +584,7 @@ impl BParticipant {
|
|||||||
self.running_mgr.fetch_sub(1, Ordering::Relaxed);
|
self.running_mgr.fetch_sub(1, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// when activated this function will drop the participant completly and
|
/// when activated this function will drop the participant completely and
|
||||||
/// wait for everything to go right! Then return 1. Shutting down
|
/// wait for everything to go right! Then return 1. Shutting down
|
||||||
/// Streams for API and End user! 2. Wait for all "prio queued" Messages
|
/// Streams for API and End user! 2. Wait for all "prio queued" Messages
|
||||||
/// to be send. 3. Send Stream
|
/// to be send. 3. Send Stream
|
||||||
@ -791,7 +791,7 @@ impl BParticipant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///closing api::Participant is done by closing all channels, exepct for the
|
///closing api::Participant is done by closing all channels, expect for the
|
||||||
/// shutdown channel at this point!
|
/// shutdown channel at this point!
|
||||||
async fn close_api(&self, reason: Option<ParticipantError>) {
|
async fn close_api(&self, reason: Option<ParticipantError>) {
|
||||||
self.close_write_api(reason).await;
|
self.close_write_api(reason).await;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
//!all 5 numbers the throughput is halved.
|
//!all 5 numbers the throughput is halved.
|
||||||
//!E.g. in the same time 100 prio0 messages are send, only 50 prio5, 25 prio10,
|
//!E.g. in the same time 100 prio0 messages are send, only 50 prio5, 25 prio10,
|
||||||
//! 12 prio15 or 6 prio20 messages are send. Note: TODO: prio0 will be send
|
//! 12 prio15 or 6 prio20 messages are send. Note: TODO: prio0 will be send
|
||||||
//! immeadiatly when found!
|
//! immediately when found!
|
||||||
//!
|
//!
|
||||||
#[cfg(feature = "metrics")]
|
#[cfg(feature = "metrics")]
|
||||||
use crate::metrics::NetworkMetrics;
|
use crate::metrics::NetworkMetrics;
|
||||||
@ -29,7 +29,7 @@ pub(crate) struct PrioManager {
|
|||||||
messages: [VecDeque<(Sid, OutgoingMessage)>; PRIO_MAX],
|
messages: [VecDeque<(Sid, OutgoingMessage)>; PRIO_MAX],
|
||||||
messages_rx: Receiver<(Prio, Sid, OutgoingMessage)>,
|
messages_rx: Receiver<(Prio, Sid, OutgoingMessage)>,
|
||||||
sid_owned: HashMap<Sid, PidSidInfo>,
|
sid_owned: HashMap<Sid, PidSidInfo>,
|
||||||
//you can register to be notified if a pid_sid combination is flushed completly here
|
//you can register to be notified if a pid_sid combination is flushed completely here
|
||||||
sid_flushed_rx: Receiver<(Sid, oneshot::Sender<()>)>,
|
sid_flushed_rx: Receiver<(Sid, oneshot::Sender<()>)>,
|
||||||
queued: HashSet<u8>,
|
queued: HashSet<u8>,
|
||||||
#[cfg(feature = "metrics")]
|
#[cfg(feature = "metrics")]
|
||||||
@ -194,7 +194,7 @@ impl PrioManager {
|
|||||||
lowest = n_points;
|
lowest = n_points;
|
||||||
lowest_id = Some(n)
|
lowest_id = Some(n)
|
||||||
} else if n_points == lowest && lowest_id.is_some() && n < lowest_id.unwrap() {
|
} else if n_points == lowest && lowest_id.is_some() && n < lowest_id.unwrap() {
|
||||||
//on equial points lowest first!
|
//on equal points lowest first!
|
||||||
lowest_id = Some(n)
|
lowest_id = Some(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,7 +231,7 @@ impl PrioManager {
|
|||||||
self.points[prio as usize] += Self::PRIOS[prio as usize];
|
self.points[prio as usize] += Self::PRIOS[prio as usize];
|
||||||
//pop message from front of VecDeque, handle it and push it back, so that all
|
//pop message from front of VecDeque, handle it and push it back, so that all
|
||||||
// => messages with same prio get a fair chance :)
|
// => messages with same prio get a fair chance :)
|
||||||
//TODO: evalaute not poping every time
|
//TODO: evaluate not popping every time
|
||||||
let (sid, mut msg) = self.messages[prio as usize].pop_front().unwrap();
|
let (sid, mut msg) = self.messages[prio as usize].pop_front().unwrap();
|
||||||
if msg.fill_next(sid, frames) {
|
if msg.fill_next(sid, frames) {
|
||||||
//trace!(?m.mid, "finish message");
|
//trace!(?m.mid, "finish message");
|
||||||
@ -556,7 +556,7 @@ mod tests {
|
|||||||
|
|
||||||
//important in that test is, that after the first frames got cleared i reset
|
//important in that test is, that after the first frames got cleared i reset
|
||||||
// the Points even though 998 prio 16 messages have been send at this
|
// the Points even though 998 prio 16 messages have been send at this
|
||||||
// point and 0 prio20 messages the next mesasge is a prio16 message
|
// point and 0 prio20 messages the next message is a prio16 message
|
||||||
// again, and only then prio20! we dont want to build dept over a idling
|
// again, and only then prio20! we dont want to build dept over a idling
|
||||||
// connection
|
// connection
|
||||||
assert_header(&mut frames, 2, 3);
|
assert_header(&mut frames, 2, 3);
|
||||||
|
@ -481,8 +481,8 @@ impl UdpProtocol {
|
|||||||
start += n;
|
start += n;
|
||||||
if n != len {
|
if n != len {
|
||||||
error!(
|
error!(
|
||||||
"THIS DOESNT WORK, as RECEIVER CURRENLTY ONLY HANDLES 1 FRAME per \
|
"THIS DOESN'T WORK, as RECEIVER CURRENTLY ONLY HANDLES 1 FRAME \
|
||||||
UDP message. splitting up will fail!"
|
per UDP message. splitting up will fail!"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -327,8 +327,8 @@ impl Scheduler {
|
|||||||
error!(
|
error!(
|
||||||
?pid,
|
?pid,
|
||||||
?e,
|
?e,
|
||||||
"Failed to finish sending all remainding messages to participant when \
|
"Failed to finish sending all remaining messages to participant when shutting \
|
||||||
shutting down"
|
down"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -490,7 +490,7 @@ impl Scheduler {
|
|||||||
//channels are unknown till PID is known!
|
//channels are unknown till PID is known!
|
||||||
/* When A connects to a NETWORK, we, the listener answers with a Handshake.
|
/* When A connects to a NETWORK, we, the listener answers with a Handshake.
|
||||||
Pro: - Its easier to debug, as someone who opens a port gets a magic number back!
|
Pro: - Its easier to debug, as someone who opens a port gets a magic number back!
|
||||||
Contra: - DOS posibility because we answer fist
|
Contra: - DOS possibility because we answer first
|
||||||
- Speed, because otherwise the message can be send with the creation
|
- Speed, because otherwise the message can be send with the creation
|
||||||
*/
|
*/
|
||||||
let mut participant_channels = self.participant_channels.lock().await.clone().unwrap();
|
let mut participant_channels = self.participant_channels.lock().await.clone().unwrap();
|
||||||
@ -585,7 +585,7 @@ impl Scheduler {
|
|||||||
// someone is waiting with `connect`, so give them their PID
|
// someone is waiting with `connect`, so give them their PID
|
||||||
pid_oneshot.send(Ok(participant)).unwrap();
|
pid_oneshot.send(Ok(participant)).unwrap();
|
||||||
} else {
|
} else {
|
||||||
// noone is waiting on this Participant, return in to Network
|
// no one is waiting on this Participant, return in to Network
|
||||||
participant_channels
|
participant_channels
|
||||||
.s2a_connected_s
|
.s2a_connected_s
|
||||||
.send(participant)
|
.send(participant)
|
||||||
|
@ -25,7 +25,7 @@ pub const PROMISES_ORDERED: Promises = 1;
|
|||||||
/// like bit flips, this is done with a checksum.
|
/// like bit flips, this is done with a checksum.
|
||||||
pub const PROMISES_CONSISTENCY: Promises = 2;
|
pub const PROMISES_CONSISTENCY: Promises = 2;
|
||||||
/// this will guarantee that the other side will receive every message exactly
|
/// this will guarantee that the other side will receive every message exactly
|
||||||
/// once no messages are droped
|
/// once no messages are dropped
|
||||||
pub const PROMISES_GUARANTEED_DELIVERY: Promises = 4;
|
pub const PROMISES_GUARANTEED_DELIVERY: Promises = 4;
|
||||||
/// this will enable the internal compression on this
|
/// this will enable the internal compression on this
|
||||||
/// [`Stream`](crate::api::Stream)
|
/// [`Stream`](crate::api::Stream)
|
||||||
@ -65,7 +65,7 @@ pub(crate) enum Frame {
|
|||||||
pid: Pid,
|
pid: Pid,
|
||||||
secret: u128,
|
secret: u128,
|
||||||
},
|
},
|
||||||
Shutdown, /* Shutsdown this channel gracefully, if all channels are shut down, Participant
|
Shutdown, /* Shutdown this channel gracefully, if all channels are shutdown, Participant
|
||||||
* is deleted */
|
* is deleted */
|
||||||
OpenStream {
|
OpenStream {
|
||||||
sid: Sid,
|
sid: Sid,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//! - in the first line we call the helper, this is only debug code. in case
|
//! - in the first line we call the helper, this is only debug code. in case
|
||||||
//! you want to have tracing for a special test you set set the bool = true
|
//! you want to have tracing for a special test you set set the bool = true
|
||||||
//! and the sleep to 10000 and your test will start 10 sec delayed with
|
//! and the sleep to 10000 and your test will start 10 sec delayed with
|
||||||
//! tracing. You need a delay as otherwise the other tests polute your trace
|
//! tracing. You need a delay as otherwise the other tests pollute your trace
|
||||||
//! - the second line is to simulate a client and a server
|
//! - the second line is to simulate a client and a server
|
||||||
//! `network_participant_stream` will return
|
//! `network_participant_stream` will return
|
||||||
//! - 2 networks
|
//! - 2 networks
|
||||||
|
@ -82,7 +82,7 @@ pub fn handle_client_disconnect(server: &mut Server, entity: EcsEntity) -> Event
|
|||||||
let participant = match client.participant.try_lock() {
|
let participant = match client.participant.try_lock() {
|
||||||
Ok(mut p) => p.take().unwrap(),
|
Ok(mut p) => p.take().unwrap(),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(?e, ?entity, "coudln't lock participant for removal");
|
error!(?e, ?entity, "couldn't lock participant for removal");
|
||||||
return Event::ClientDisconnected { entity };
|
return Event::ClientDisconnected { entity };
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -102,9 +102,9 @@ pub fn handle_client_disconnect(server: &mut Server, entity: EcsEntity) -> Event
|
|||||||
trace!(?pid, "finished disconnect");
|
trace!(?pid, "finished disconnect");
|
||||||
let elapsed = now.elapsed();
|
let elapsed = now.elapsed();
|
||||||
if elapsed.as_millis() > 100 {
|
if elapsed.as_millis() > 100 {
|
||||||
warn!(?elapsed, ?pid, "disconecting took quite long");
|
warn!(?elapsed, ?pid, "disconnecting took quite long");
|
||||||
} else {
|
} else {
|
||||||
debug!(?elapsed, ?pid, "disconecting took");
|
debug!(?elapsed, ?pid, "disconnecting took");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -217,19 +217,19 @@ impl Server {
|
|||||||
.unwrap_or(center_chunk);
|
.unwrap_or(center_chunk);
|
||||||
|
|
||||||
// calculate the absolute position of the chunk in the world
|
// calculate the absolute position of the chunk in the world
|
||||||
// (we could add TerrainChunkSize::RECT_SIZE / 2 here, to spawn in the midde of
|
// (we could add TerrainChunkSize::RECT_SIZE / 2 here, to spawn in the middle of
|
||||||
// the chunk)
|
// the chunk)
|
||||||
let spawn_location = spawn_chunk.map2(TerrainChunkSize::RECT_SIZE, |e, sz| {
|
let spawn_location = spawn_chunk.map2(TerrainChunkSize::RECT_SIZE, |e, sz| {
|
||||||
e as i32 * sz as i32 + sz as i32 / 2
|
e as i32 * sz as i32 + sz as i32 / 2
|
||||||
});
|
});
|
||||||
|
|
||||||
// get a z cache for the collumn in which we want to spawn
|
// get a z cache for the column in which we want to spawn
|
||||||
let mut block_sampler = world.sample_blocks();
|
let mut block_sampler = world.sample_blocks();
|
||||||
let z_cache = block_sampler
|
let z_cache = block_sampler
|
||||||
.get_z_cache(spawn_location, index)
|
.get_z_cache(spawn_location, index)
|
||||||
.expect(&format!("no z_cache found for chunk: {}", spawn_chunk));
|
.expect(&format!("no z_cache found for chunk: {}", spawn_chunk));
|
||||||
|
|
||||||
// get the minimum and maximum z values at which there could be soild blocks
|
// get the minimum and maximum z values at which there could be solid blocks
|
||||||
let (min_z, _, max_z) = z_cache.get_z_limits(&mut block_sampler, index);
|
let (min_z, _, max_z) = z_cache.get_z_limits(&mut block_sampler, index);
|
||||||
// round range outwards, so no potential air block is missed
|
// round range outwards, so no potential air block is missed
|
||||||
let min_z = min_z.floor() as i32;
|
let min_z = min_z.floor() as i32;
|
||||||
@ -237,7 +237,7 @@ impl Server {
|
|||||||
|
|
||||||
// loop over all blocks from min_z to max_z + 1
|
// loop over all blocks from min_z to max_z + 1
|
||||||
// until the first air block is found
|
// until the first air block is found
|
||||||
// (up to max_z + 1, because max_z could still be a soild block)
|
// (up to max_z + 1, because max_z could still be a solid block)
|
||||||
// if no air block is found default to max_z + 1
|
// if no air block is found default to max_z + 1
|
||||||
let z = (min_z..(max_z + 1) + 1)
|
let z = (min_z..(max_z + 1) + 1)
|
||||||
.find(|z| {
|
.find(|z| {
|
||||||
@ -394,7 +394,7 @@ impl Server {
|
|||||||
|
|
||||||
let before_message_system = Instant::now();
|
let before_message_system = Instant::now();
|
||||||
|
|
||||||
// Run message recieving sys before the systems in common for decreased latency
|
// Run message receiving sys before the systems in common for decreased latency
|
||||||
// (e.g. run before controller system)
|
// (e.g. run before controller system)
|
||||||
sys::message::Sys.run_now(&self.state.ecs());
|
sys::message::Sys.run_now(&self.state.ecs());
|
||||||
|
|
||||||
@ -414,7 +414,7 @@ impl Server {
|
|||||||
|
|
||||||
// Apply terrain changes and update the region map after processing server
|
// Apply terrain changes and update the region map after processing server
|
||||||
// events so that changes made by server events will be immediately
|
// events so that changes made by server events will be immediately
|
||||||
// visble to client synchronization systems, minimizing the latency of
|
// visible to client synchronization systems, minimizing the latency of
|
||||||
// `ServerEvent` mediated effects
|
// `ServerEvent` mediated effects
|
||||||
self.state.update_region_map();
|
self.state.update_region_map();
|
||||||
self.state.apply_terrain_changes();
|
self.state.apply_terrain_changes();
|
||||||
@ -519,10 +519,10 @@ impl Server {
|
|||||||
chunk_generator.cancel_all();
|
chunk_generator.cancel_all();
|
||||||
|
|
||||||
if client.is_empty() {
|
if client.is_empty() {
|
||||||
// No cilents, so just clear all terrain.
|
// No clients, so just clear all terrain.
|
||||||
terrain.clear();
|
terrain.clear();
|
||||||
} else {
|
} else {
|
||||||
// There's at leasat one client, so regenerate all chunks.
|
// There's at least one client, so regenerate all chunks.
|
||||||
terrain.iter().for_each(|(pos, _)| {
|
terrain.iter().for_each(|(pos, _)| {
|
||||||
chunk_generator.generate_chunk(
|
chunk_generator.generate_chunk(
|
||||||
None,
|
None,
|
||||||
|
@ -65,7 +65,7 @@ impl TickMetrics {
|
|||||||
"number of all chunks currently active on the server",
|
"number of all chunks currently active on the server",
|
||||||
))?;
|
))?;
|
||||||
let tick_time = IntGaugeVec::new(
|
let tick_time = IntGaugeVec::new(
|
||||||
Opts::new("tick_time", "time in ns requiered for a tick of the server"),
|
Opts::new("tick_time", "time in ns required for a tick of the server"),
|
||||||
&["period"],
|
&["period"],
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ use tracing::{error, warn};
|
|||||||
|
|
||||||
type CharacterLoaderRequest = (specs::Entity, CharacterLoaderRequestKind);
|
type CharacterLoaderRequest = (specs::Entity, CharacterLoaderRequestKind);
|
||||||
|
|
||||||
/// Available database operations when modifying a player's characetr list
|
/// Available database operations when modifying a player's character list
|
||||||
enum CharacterLoaderRequestKind {
|
enum CharacterLoaderRequestKind {
|
||||||
CreateCharacter {
|
CreateCharacter {
|
||||||
player_uuid: String,
|
player_uuid: String,
|
||||||
@ -311,7 +311,7 @@ fn load_character_list(player_uuid: &str, db_dir: &str) -> CharacterListResult {
|
|||||||
///
|
///
|
||||||
/// Note that sqlite does not support returning the inserted data after a
|
/// Note that sqlite does not support returning the inserted data after a
|
||||||
/// successful insert. To workaround, we wrap this in a transaction which
|
/// successful insert. To workaround, we wrap this in a transaction which
|
||||||
/// inserts, queries for the newly created chaacter id, then uses the character
|
/// inserts, queries for the newly created character id, then uses the character
|
||||||
/// id for subsequent insertions
|
/// id for subsequent insertions
|
||||||
fn create_character(
|
fn create_character(
|
||||||
uuid: &str,
|
uuid: &str,
|
||||||
|
@ -8,11 +8,11 @@ use std::fmt;
|
|||||||
pub enum Error {
|
pub enum Error {
|
||||||
// The player has already reached the max character limit
|
// The player has already reached the max character limit
|
||||||
CharacterLimitReached,
|
CharacterLimitReached,
|
||||||
// An error occured while establish a db connection
|
// An error occurred while establish a db connection
|
||||||
DatabaseConnectionError(diesel::ConnectionError),
|
DatabaseConnectionError(diesel::ConnectionError),
|
||||||
// An error occured while running migrations
|
// An error occurred while running migrations
|
||||||
DatabaseMigrationError(diesel_migrations::RunMigrationsError),
|
DatabaseMigrationError(diesel_migrations::RunMigrationsError),
|
||||||
// An error occured when performing a database action
|
// An error occurred when performing a database action
|
||||||
DatabaseError(diesel::result::Error),
|
DatabaseError(diesel::result::Error),
|
||||||
// Unable to load body or stats for a character
|
// Unable to load body or stats for a character
|
||||||
CharacterDataError,
|
CharacterDataError,
|
||||||
|
@ -264,7 +264,7 @@ impl From<&comp::Inventory> for InventoryUpdate {
|
|||||||
/// which is loaded with their character data, however there are plans for each
|
/// which is loaded with their character data, however there are plans for each
|
||||||
/// character to have multiple Loadouts which they can switch between during
|
/// character to have multiple Loadouts which they can switch between during
|
||||||
/// gameplay. Due to this Loadouts have a many to one relationship with
|
/// gameplay. Due to this Loadouts have a many to one relationship with
|
||||||
/// characetrs, and a distinct `id`.
|
/// characters, and a distinct `id`.
|
||||||
#[derive(Associations, Queryable, Debug, Identifiable)]
|
#[derive(Associations, Queryable, Debug, Identifiable)]
|
||||||
#[belongs_to(Character)]
|
#[belongs_to(Character)]
|
||||||
#[primary_key(id)]
|
#[primary_key(id)]
|
||||||
|
@ -229,8 +229,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
{
|
{
|
||||||
let mut comp_sync_package = CompSyncPackage::new();
|
let mut comp_sync_package = CompSyncPackage::new();
|
||||||
let mut throttle = true;
|
let mut throttle = true;
|
||||||
// TODO: An entity that stoppped moving on a tick that it wasn't sent to the
|
// TODO: An entity that stopped moving on a tick that it wasn't sent to the
|
||||||
// player will never have it's position updated
|
// player will never have its position updated
|
||||||
match last_pos.get(entity).map(|&l| l.0 != pos) {
|
match last_pos.get(entity).map(|&l| l.0 != pos) {
|
||||||
Some(false) => {},
|
Some(false) => {},
|
||||||
Some(true) => {
|
Some(true) => {
|
||||||
|
@ -274,7 +274,7 @@ impl Sys {
|
|||||||
Err(ChatMsgValidationError::TooLong) => {
|
Err(ChatMsgValidationError::TooLong) => {
|
||||||
let max = MAX_BYTES_CHAT_MSG;
|
let max = MAX_BYTES_CHAT_MSG;
|
||||||
let len = message.len();
|
let len = message.len();
|
||||||
warn!(?len, ?max, "Recieved a chat message that's too long")
|
warn!(?len, ?max, "Received a chat message that's too long")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -60,9 +60,9 @@ impl<'a> System<'a> for Sys {
|
|||||||
// To update subscriptions
|
// To update subscriptions
|
||||||
// 1. Iterate through clients
|
// 1. Iterate through clients
|
||||||
// 2. Calculate current chunk position
|
// 2. Calculate current chunk position
|
||||||
// 3. If chunk is the same return, otherwise continue (use fuzzyiness)
|
// 3. If chunk is the same return, otherwise continue (use fuzziness)
|
||||||
// 4. Iterate through subscribed regions
|
// 4. Iterate through subscribed regions
|
||||||
// 5. Check if region is still in range (use fuzzyiness)
|
// 5. Check if region is still in range (use fuzziness)
|
||||||
// 6. If not in range
|
// 6. If not in range
|
||||||
// - remove from hashset
|
// - remove from hashset
|
||||||
// - inform client of which entities to remove
|
// - inform client of which entities to remove
|
||||||
@ -178,7 +178,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
(vd as f32 * chunk_size)
|
(vd as f32 * chunk_size)
|
||||||
+ (client::CHUNK_FUZZ as f32 + chunk_size) * 2.0f32.sqrt(),
|
+ (client::CHUNK_FUZZ as f32 + chunk_size) * 2.0f32.sqrt(),
|
||||||
) {
|
) {
|
||||||
// Send client intial info about the entities in this region if it was not
|
// Send client initial info about the entities in this region if it was not
|
||||||
// already within the set of subscribed regions
|
// already within the set of subscribed regions
|
||||||
if subscription.regions.insert(key) {
|
if subscription.regions.insert(key) {
|
||||||
if let Some(region) = region_map.get(key) {
|
if let Some(region) = region_map.get(key) {
|
||||||
@ -268,7 +268,7 @@ pub fn initialize_region_subscription(world: &World, entity: specs::Entity) {
|
|||||||
} else {
|
} else {
|
||||||
debug!(
|
debug!(
|
||||||
?entity,
|
?entity,
|
||||||
"Failed to initialize region subcription. Couldn't retrieve all the neccesary \
|
"Failed to initialize region subscription. Couldn't retrieve all the neccesary \
|
||||||
components on the provided entity"
|
components on the provided entity"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,9 @@ use std::{sync::Arc, time::Duration};
|
|||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
/// This system will handle loading generated chunks and unloading
|
/// This system will handle loading generated chunks and unloading
|
||||||
/// uneeded chunks.
|
/// unneeded chunks.
|
||||||
/// 1. Inserts newly generated chunks into the TerrainGrid
|
/// 1. Inserts newly generated chunks into the TerrainGrid
|
||||||
/// 2. Sends new chunks to neaby clients
|
/// 2. Sends new chunks to nearby clients
|
||||||
/// 3. Handles the chunk's supplement (e.g. npcs)
|
/// 3. Handles the chunk's supplement (e.g. npcs)
|
||||||
/// 4. Removes chunks outside the range of players
|
/// 4. Removes chunks outside the range of players
|
||||||
pub struct Sys;
|
pub struct Sys;
|
||||||
|
@ -10,7 +10,7 @@ pub struct HpFloater {
|
|||||||
pub timer: f32,
|
pub timer: f32,
|
||||||
// Numbers of times significant damage has been dealt
|
// Numbers of times significant damage has been dealt
|
||||||
pub hp_change: i32,
|
pub hp_change: i32,
|
||||||
// Used for randomly offseting
|
// Used for randomly offsetting
|
||||||
pub rand: f32,
|
pub rand: f32,
|
||||||
}
|
}
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
|
@ -33,8 +33,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
&mut self,
|
&mut self,
|
||||||
(entities, my_entity, dt, mut my_exp_floater_list, uids, pos, stats, mut hp_floater_lists): Self::SystemData,
|
(entities, my_entity, dt, mut my_exp_floater_list, uids, pos, stats, mut hp_floater_lists): Self::SystemData,
|
||||||
) {
|
) {
|
||||||
// Add hp floater lists to all entities with stats and a postion
|
// Add hp floater lists to all entities with stats and a position
|
||||||
// Note: neccessary in order to know last_hp
|
// Note: necessary in order to know last_hp
|
||||||
for (entity, last_hp) in (&entities, &stats, &pos, !&hp_floater_lists)
|
for (entity, last_hp) in (&entities, &stats, &pos, !&hp_floater_lists)
|
||||||
.join()
|
.join()
|
||||||
.map(|(e, s, _, _)| (e, s.health.current()))
|
.map(|(e, s, _, _)| (e, s.health.current()))
|
||||||
@ -63,9 +63,9 @@ impl<'a> System<'a> for Sys {
|
|||||||
// equivalently in the same frame)
|
// equivalently in the same frame)
|
||||||
if hp_floater_list.last_hp != health.current() {
|
if hp_floater_list.last_hp != health.current() {
|
||||||
hp_floater_list.last_hp = health.current();
|
hp_floater_list.last_hp = health.current();
|
||||||
// TODO: What if multiple health changes occured since last check here
|
// TODO: What if multiple health changes occurred since last check here
|
||||||
// Also, If we make stats store a vec of the last_changes (from say the last
|
// Also, If we make stats store a vec of the last_changes (from say the last
|
||||||
// frame), what if the client recieves the stats component from
|
// frame), what if the client receives the stats component from
|
||||||
// two different server ticks at once, then one will be lost
|
// two different server ticks at once, then one will be lost
|
||||||
// (tbf this is probably a rare occurance and the results
|
// (tbf this is probably a rare occurance and the results
|
||||||
// would just be a transient glitch in the display of these damage numbers)
|
// would just be a transient glitch in the display of these damage numbers)
|
||||||
@ -96,7 +96,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove floater lists on entities without stats or without posistion
|
// Remove floater lists on entities without stats or without position
|
||||||
for entity in (&entities, !&stats, &hp_floater_lists)
|
for entity in (&entities, !&stats, &hp_floater_lists)
|
||||||
.join()
|
.join()
|
||||||
.map(|(e, _, _)| e)
|
.map(|(e, _, _)| e)
|
||||||
|
@ -173,7 +173,7 @@ impl<'a> Widget for Bag<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let exp_percentage = (self.stats.exp.current() as f64) / (self.stats.exp.maximum() as f64);
|
let exp_percentage = (self.stats.exp.current() as f64) / (self.stats.exp.maximum() as f64);
|
||||||
let exp_treshold = format!(
|
let exp_threshold = format!(
|
||||||
"{}/{} {}",
|
"{}/{} {}",
|
||||||
self.stats.exp.current(),
|
self.stats.exp.current(),
|
||||||
self.stats.exp.maximum(),
|
self.stats.exp.maximum(),
|
||||||
@ -532,7 +532,7 @@ impl<'a> Widget for Bag<'a> {
|
|||||||
.set(state.ids.expbar, ui);
|
.set(state.ids.expbar, ui);
|
||||||
|
|
||||||
// Exp-Text
|
// Exp-Text
|
||||||
Text::new(&exp_treshold)
|
Text::new(&exp_threshold)
|
||||||
.mid_top_with_margin_on(state.ids.expbar, 10.0)
|
.mid_top_with_margin_on(state.ids.expbar, 10.0)
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
.font_size(self.fonts.cyri.scale(15))
|
.font_size(self.fonts.cyri.scale(15))
|
||||||
|
@ -189,7 +189,7 @@ impl<'a> Widget for MiniMap<'a> {
|
|||||||
.get(self.client.entity())
|
.get(self.client.entity())
|
||||||
.map_or(Vec3::zero(), |pos| pos.0);
|
.map_or(Vec3::zero(), |pos| pos.0);
|
||||||
|
|
||||||
// Get map image source rectangle dimensons.
|
// Get map image source rectangle dimensions.
|
||||||
let w_src = max_zoom / zoom;
|
let w_src = max_zoom / zoom;
|
||||||
let h_src = max_zoom / zoom;
|
let h_src = max_zoom / zoom;
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ widget_ids! {
|
|||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
ids: Ids,
|
ids: Ids,
|
||||||
// Holds the time when selection is made since this selection can be overriden
|
// Holds the time when selection is made since this selection can be overridden
|
||||||
// by selecting an entity in-game
|
// by selecting an entity in-game
|
||||||
selected_uid: Option<(Uid, Instant)>,
|
selected_uid: Option<(Uid, Instant)>,
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ pub struct GreedyConfig<D, FL, FC, FO, FS, FP> {
|
|||||||
/// for queries against the volume.
|
/// for queries against the volume.
|
||||||
pub draw_delta: Vec3<i32>,
|
pub draw_delta: Vec3<i32>,
|
||||||
/// For each dimension i, for faces drawn in planes *parallel* to i,
|
/// For each dimension i, for faces drawn in planes *parallel* to i,
|
||||||
/// represents the number of voxels considered along dimenson i in those
|
/// represents the number of voxels considered along dimension i in those
|
||||||
/// planes, starting from `draw_delta`.
|
/// planes, starting from `draw_delta`.
|
||||||
pub greedy_size: Vec3<usize>,
|
pub greedy_size: Vec3<usize>,
|
||||||
/// For each dimension i, represents the number of planes considered
|
/// For each dimension i, represents the number of planes considered
|
||||||
@ -53,7 +53,7 @@ pub struct GreedyConfig<D, FL, FC, FO, FS, FP> {
|
|||||||
/// otherwise have the same orientation, dimensions, and are
|
/// otherwise have the same orientation, dimensions, and are
|
||||||
/// next to each other.
|
/// next to each other.
|
||||||
pub should_draw: FS,
|
pub should_draw: FS,
|
||||||
/// Create an opauqe quad (used for only display rendering) from its
|
/// Create an opaque quad (used for only display rendering) from its
|
||||||
/// top-left atlas position, the rectangle's dimensions in (2D) atlas
|
/// top-left atlas position, the rectangle's dimensions in (2D) atlas
|
||||||
/// space, a world position, the u and v axes of the rectangle in (3D)
|
/// space, a world position, the u and v axes of the rectangle in (3D)
|
||||||
/// world space, the normal facing out frmo the rectangle in world
|
/// world space, the normal facing out frmo the rectangle in world
|
||||||
@ -165,7 +165,7 @@ impl<'a> GreedyMesh<'a> {
|
|||||||
/// suspend meshing partway through in order to meet frame budget, and
|
/// suspend meshing partway through in order to meet frame budget, and
|
||||||
/// potentially use a single staged upload to the GPU.
|
/// potentially use a single staged upload to the GPU.
|
||||||
///
|
///
|
||||||
/// Returns the ColLightsInfo corresponding to the consstructed atlas.
|
/// Returns the ColLightsInfo corresponding to the constructed atlas.
|
||||||
pub fn finalize(self) -> ColLightInfo {
|
pub fn finalize(self) -> ColLightInfo {
|
||||||
let cur_size = self.col_lights_size;
|
let cur_size = self.col_lights_size;
|
||||||
let col_lights = vec![
|
let col_lights = vec![
|
||||||
@ -530,7 +530,7 @@ fn draw_col_lights<D>(
|
|||||||
// could be if we used the right AO strategy).
|
// could be if we used the right AO strategy).
|
||||||
// Each indirect light needs to come in through the direct light.
|
// Each indirect light needs to come in through the direct light.
|
||||||
// Thus, we assign each light a score based on opacity (currently just 0 or
|
// Thus, we assign each light a score based on opacity (currently just 0 or
|
||||||
// 1, but it could support transluscent lights in the future).
|
// 1, but it could support translucent lights in the future).
|
||||||
// Thus, indirect_u_opacity and indirect_v_opacity are multiplied by
|
// Thus, indirect_u_opacity and indirect_v_opacity are multiplied by
|
||||||
// direct_opacity, and indirect_uv_opacity is multiplied by
|
// direct_opacity, and indirect_uv_opacity is multiplied by
|
||||||
// the maximum of both of u and v's indirect opacities (since there are
|
// the maximum of both of u and v's indirect opacities (since there are
|
||||||
@ -553,7 +553,7 @@ fn draw_col_lights<D>(
|
|||||||
// top-right block
|
// top-right block
|
||||||
let direct_v_opacity = get_opacity(data, light_pos - uv.y);
|
let direct_v_opacity = get_opacity(data, light_pos - uv.y);
|
||||||
|
|
||||||
// NOTE: Since we only support 0/1 opacities currently, we asssume
|
// NOTE: Since we only support 0/1 opacities currently, we assume
|
||||||
// direct_opacity is 1, and the light value will be zero anyway for objects
|
// direct_opacity is 1, and the light value will be zero anyway for objects
|
||||||
// with opacity 0, we only "multiply" by indirect_uv_opacity for now (since
|
// with opacity 0, we only "multiply" by indirect_uv_opacity for now (since
|
||||||
// it's the only one that could be 0 even if its light value is not).
|
// it's the only one that could be 0 even if its light value is not).
|
||||||
|
@ -126,7 +126,7 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Propage light
|
// Propagate light
|
||||||
while let Some(pos) = prop_que.pop_front() {
|
while let Some(pos) = prop_que.pop_front() {
|
||||||
let pos = Vec3::new(pos.0 as i32, pos.1 as i32, pos.2 as i32);
|
let pos = Vec3::new(pos.0 as i32, pos.1 as i32, pos.2 as i32);
|
||||||
let light = light_map[lm_idx(pos.x, pos.y, pos.z)];
|
let light = light_map[lm_idx(pos.x, pos.y, pos.z)];
|
||||||
|
@ -40,7 +40,7 @@ impl Default for ServerProfile {
|
|||||||
/// `Profile` contains everything that can be configured in the profile.ron
|
/// `Profile` contains everything that can be configured in the profile.ron
|
||||||
///
|
///
|
||||||
/// Initially it is just for persisting things that don't belong in
|
/// Initially it is just for persisting things that don't belong in
|
||||||
/// setttings.ron - like the state of hotbar and any other character level
|
/// settings.ron - like the state of hotbar and any other character level
|
||||||
/// configuration.
|
/// configuration.
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -75,19 +75,19 @@ pub enum AaMode {
|
|||||||
/// Multisampling AA, up to 4 samples per pixel.
|
/// Multisampling AA, up to 4 samples per pixel.
|
||||||
///
|
///
|
||||||
/// NOTE: MSAA modes don't (currently) work with greedy meshing, and will
|
/// NOTE: MSAA modes don't (currently) work with greedy meshing, and will
|
||||||
/// also struggle in the futrue with deferred shading, so they may be
|
/// also struggle in the future with deferred shading, so they may be
|
||||||
/// removed in the future.
|
/// removed in the future.
|
||||||
MsaaX4,
|
MsaaX4,
|
||||||
/// Multisampling AA, up to 8 samples per pixel.
|
/// Multisampling AA, up to 8 samples per pixel.
|
||||||
///
|
///
|
||||||
/// NOTE: MSAA modes don't (currently) work with greedy meshing, and will
|
/// NOTE: MSAA modes don't (currently) work with greedy meshing, and will
|
||||||
/// also struggle in the futrue with deferred shading, so they may be
|
/// also struggle in the future with deferred shading, so they may be
|
||||||
/// removed in the future.
|
/// removed in the future.
|
||||||
MsaaX8,
|
MsaaX8,
|
||||||
/// Multisampling AA, up to 16 samples per pixel.
|
/// Multisampling AA, up to 16 samples per pixel.
|
||||||
///
|
///
|
||||||
/// NOTE: MSAA modes don't (currently) work with greedy meshing, and will
|
/// NOTE: MSAA modes don't (currently) work with greedy meshing, and will
|
||||||
/// also struggle in the futrue with deferred shading, so they may be
|
/// also struggle in the future with deferred shading, so they may be
|
||||||
/// removed in the future.
|
/// removed in the future.
|
||||||
MsaaX16,
|
MsaaX16,
|
||||||
/// Super-sampling antialiasing, 4 samples per pixel.
|
/// Super-sampling antialiasing, 4 samples per pixel.
|
||||||
@ -123,7 +123,7 @@ pub enum CloudMode {
|
|||||||
/// - The volumetric clouds use raymarching, which will cause catastrophic
|
/// - The volumetric clouds use raymarching, which will cause catastrophic
|
||||||
/// performance degradation on GPUs without good support for loops. There
|
/// performance degradation on GPUs without good support for loops. There
|
||||||
/// is an attempt to minimize the impact of this using a z-range check,
|
/// is an attempt to minimize the impact of this using a z-range check,
|
||||||
/// but on some low-end GPUs (such as some integraetd graphics cards) this
|
/// but on some low-end GPUs (such as some integrated graphics cards) this
|
||||||
/// test doesn't appear to be able to be predicted well at shader
|
/// test doesn't appear to be able to be predicted well at shader
|
||||||
/// invocation time.
|
/// invocation time.
|
||||||
/// - The cloud computations themselves are fairly involved, further
|
/// - The cloud computations themselves are fairly involved, further
|
||||||
@ -180,7 +180,7 @@ pub enum LightingMode {
|
|||||||
/// Ashikhmin-Shirley BRDF lighting model. Attempts to generate a
|
/// Ashikhmin-Shirley BRDF lighting model. Attempts to generate a
|
||||||
/// physically plausible (to some extent) lighting distribution.
|
/// physically plausible (to some extent) lighting distribution.
|
||||||
///
|
///
|
||||||
/// This mdoel may not work as well with purely directional lighting, and is
|
/// This model may not work as well with purely directional lighting, and is
|
||||||
/// more expensive than the other models.
|
/// more expensive than the other models.
|
||||||
Ashikhmin,
|
Ashikhmin,
|
||||||
/// Standard Blinn-Phong shading, combing Lambertian diffuse reflections and
|
/// Standard Blinn-Phong shading, combing Lambertian diffuse reflections and
|
||||||
|
@ -40,7 +40,7 @@ gfx_defines! {
|
|||||||
// a cube is: f32 x 3 x 3 x 12 = 3456 bits
|
// a cube is: f32 x 3 x 3 x 12 = 3456 bits
|
||||||
// this vec is: f32 x 3 x 1 x 1 = 96 bits (per instance!)
|
// this vec is: f32 x 3 x 1 x 1 = 96 bits (per instance!)
|
||||||
// consider using a throw-away mesh and
|
// consider using a throw-away mesh and
|
||||||
// positioning the vertex verticies instead,
|
// positioning the vertex vertices instead,
|
||||||
// if we have:
|
// if we have:
|
||||||
// - a triangle mesh, and 3 or more instances.
|
// - a triangle mesh, and 3 or more instances.
|
||||||
// - a quad mesh, and 6 or more instances.
|
// - a quad mesh, and 6 or more instances.
|
||||||
|
@ -75,7 +75,7 @@ pub type TgtColorRes = gfx::handle::ShaderResourceView<
|
|||||||
<TgtColorFmt as gfx::format::Formatted>::View,
|
<TgtColorFmt as gfx::format::Formatted>::View,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/// A handle to a greedy meshed color-light texture as a resorce.
|
/// A handle to a greedy meshed color-light texture as a resource.
|
||||||
pub type ColLightRes = gfx::handle::ShaderResourceView<
|
pub type ColLightRes = gfx::handle::ShaderResourceView<
|
||||||
gfx_backend::Resources,
|
gfx_backend::Resources,
|
||||||
<ColLightFmt as gfx::format::Formatted>::View,
|
<ColLightFmt as gfx::format::Formatted>::View,
|
||||||
@ -615,7 +615,7 @@ impl Renderer {
|
|||||||
// NOTE: Safe because GL_TEXTURE_CUBE_MAP_SEAMLESS is supported by OpenGL 3.2+
|
// NOTE: Safe because GL_TEXTURE_CUBE_MAP_SEAMLESS is supported by OpenGL 3.2+
|
||||||
// (see https://www.khronos.org/opengl/wiki/Cubemap_Texture#Seamless_cubemap);
|
// (see https://www.khronos.org/opengl/wiki/Cubemap_Texture#Seamless_cubemap);
|
||||||
// enabling seamless cube maps should always be safe regardless of the state of
|
// enabling seamless cube maps should always be safe regardless of the state of
|
||||||
// the OpenGL context, so no further checks are needd.
|
// the OpenGL context, so no further checks are needed.
|
||||||
device.with_gl(|gl| {
|
device.with_gl(|gl| {
|
||||||
gl.Enable(gfx_gl::TEXTURE_CUBE_MAP_SEAMLESS);
|
gl.Enable(gfx_gl::TEXTURE_CUBE_MAP_SEAMLESS);
|
||||||
});
|
});
|
||||||
@ -1686,7 +1686,7 @@ fn create_pipelines(
|
|||||||
r#"
|
r#"
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#define VOXYGEN_COMPUTATION_PREERENCE {}
|
#define VOXYGEN_COMPUTATION_PREFERENCE {}
|
||||||
#define FLUID_MODE {}
|
#define FLUID_MODE {}
|
||||||
#define CLOUD_MODE {}
|
#define CLOUD_MODE {}
|
||||||
#define LIGHTING_ALGORITHM {}
|
#define LIGHTING_ALGORITHM {}
|
||||||
@ -1695,7 +1695,7 @@ fn create_pipelines(
|
|||||||
"#,
|
"#,
|
||||||
constants,
|
constants,
|
||||||
// TODO: Configurable vertex/fragment shader preference.
|
// TODO: Configurable vertex/fragment shader preference.
|
||||||
"VOXYGEN_COMPUTATION_PREERENCE_FRAGMENT",
|
"VOXYGEN_COMPUTATION_PREFERENCE_FRAGMENT",
|
||||||
match mode.fluid {
|
match mode.fluid {
|
||||||
FluidMode::Cheap => "FLUID_MODE_CHEAP",
|
FluidMode::Cheap => "FLUID_MODE_CHEAP",
|
||||||
FluidMode::Shiny => "FLUID_MODE_SHINY",
|
FluidMode::Shiny => "FLUID_MODE_SHINY",
|
||||||
|
@ -23,7 +23,7 @@ pub fn run(mut global_state: GlobalState, event_loop: EventLoop) {
|
|||||||
let mut polled_twice = false;
|
let mut polled_twice = false;
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
// Continously run loop since we handle sleeping
|
// Continuously run loop since we handle sleeping
|
||||||
*control_flow = winit::event_loop::ControlFlow::Poll;
|
*control_flow = winit::event_loop::ControlFlow::Poll;
|
||||||
|
|
||||||
// Get events for the ui.
|
// Get events for the ui.
|
||||||
|
@ -1064,7 +1064,7 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Update the figure bounds to the largest granularity seen so far
|
// Update the figure bounds to the largest granularity seen so far
|
||||||
// (NOTE: this is more than a little imeprfect).
|
// (NOTE: this is more than a little imperfect).
|
||||||
//
|
//
|
||||||
// FIXME: Maybe use the default bone position in the idle animation
|
// FIXME: Maybe use the default bone position in the idle animation
|
||||||
// to figure this out instead?
|
// to figure this out instead?
|
||||||
|
@ -275,7 +275,7 @@ impl HumHeadSpec {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Armor spects should be in the same order, top to bottom.
|
// Armor aspects should be in the same order, top to bottom.
|
||||||
// These seem overly split up, but wanted to keep the armor seperated
|
// These seem overly split up, but wanted to keep the armor seperated
|
||||||
// unlike head which is done above.
|
// unlike head which is done above.
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
@ -24,7 +24,7 @@ pub fn aabb_to_points<T: Float>(bounds: Aabb<T>) -> [Vec3<T>; 8] {
|
|||||||
/// a(x - x0) + b(y - y0) + c(z - z0) = 0, i.e.
|
/// a(x - x0) + b(y - y0) + c(z - z0) = 0, i.e.
|
||||||
/// ax + by + cz - (a * x0 + b * y0 + c * z0) = 0, i.e.
|
/// ax + by + cz - (a * x0 + b * y0 + c * z0) = 0, i.e.
|
||||||
/// ax + by + cz = (a * x0 + b * y0 + c * z0), i.e.
|
/// ax + by + cz = (a * x0 + b * y0 + c * z0), i.e.
|
||||||
/// (lettiing d = a * x0 + b * y0 + c * z0)
|
/// (letting d = a * x0 + b * y0 + c * z0)
|
||||||
/// ax + by + cz = d
|
/// ax + by + cz = d
|
||||||
///
|
///
|
||||||
/// where d is the distance of the plane from the origin.
|
/// where d is the distance of the plane from the origin.
|
||||||
|
@ -121,7 +121,7 @@ impl<'a> SceneData<'a> {
|
|||||||
pub fn get_moon_dir(&self) -> Vec3<f32> { Globals::get_moon_dir(self.state.get_time_of_day()) }
|
pub fn get_moon_dir(&self) -> Vec3<f32> { Globals::get_moon_dir(self.state.get_time_of_day()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Approximte a scalar field of view angle using the parameterization from
|
/// Approximate a scalar field of view angle using the parameterization from
|
||||||
/// section 4.3 of Lloyd's thesis:
|
/// section 4.3 of Lloyd's thesis:
|
||||||
///
|
///
|
||||||
/// W_e = 2 n_e tan θ
|
/// W_e = 2 n_e tan θ
|
||||||
@ -678,13 +678,13 @@ impl Scene {
|
|||||||
// n_opt = 1 / sin y (z_n + √(z_n + (f - n) sin y))
|
// n_opt = 1 / sin y (z_n + √(z_n + (f - n) sin y))
|
||||||
//
|
//
|
||||||
// where n is near plane, f is far plane, y is the tilt angle between view and
|
// where n is near plane, f is far plane, y is the tilt angle between view and
|
||||||
// light directon, and n_opt is the optimal near plane.
|
// light direction, and n_opt is the optimal near plane.
|
||||||
// We also want a way to transform and scale this matrix (* 0.5 + 0.5) in order
|
// We also want a way to transform and scale this matrix (* 0.5 + 0.5) in order
|
||||||
// to transform it correctly into texture coordinates, as well as
|
// to transform it correctly into texture coordinates, as well as
|
||||||
// OpenGL coordinates. Note that the matrix for directional light
|
// OpenGL coordinates. Note that the matrix for directional light
|
||||||
// is *already* linear in the depth buffer.
|
// is *already* linear in the depth buffer.
|
||||||
let texture_mat = Mat4::scaling_3d(0.5f32) * Mat4::translation_3d(1.0f32);
|
let texture_mat = Mat4::scaling_3d(0.5f32) * Mat4::translation_3d(1.0f32);
|
||||||
// We need to compute these offset matrices to tranform world space coordinates
|
// We need to compute these offset matrices to transform world space coordinates
|
||||||
// to the translated ones we use when multiplying by the light space
|
// to the translated ones we use when multiplying by the light space
|
||||||
// matrix; this helps avoid precision loss during the
|
// matrix; this helps avoid precision loss during the
|
||||||
// multiplication.
|
// multiplication.
|
||||||
|
@ -422,7 +422,7 @@ impl HeartbeatScheduler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// updates the last elapsed times and elasped counts
|
/// updates the last elapsed times and elapsed counts
|
||||||
/// this should be called once, and only once per tick.
|
/// this should be called once, and only once per tick.
|
||||||
pub fn maintain(&mut self, now: f64) {
|
pub fn maintain(&mut self, now: f64) {
|
||||||
self.last_known_time = now;
|
self.last_known_time = now;
|
||||||
@ -436,10 +436,10 @@ impl HeartbeatScheduler {
|
|||||||
|
|
||||||
*heartbeats = full_heartbeats as u8;
|
*heartbeats = full_heartbeats as u8;
|
||||||
|
|
||||||
// the remaining partial freqency cycle, as a decimal.
|
// the remaining partial frequency cycle, as a decimal.
|
||||||
let partial_heartbeat = total_heartbeats - full_heartbeats;
|
let partial_heartbeat = total_heartbeats - full_heartbeats;
|
||||||
|
|
||||||
// the remaining partial freqency cycle, as a unit of time(f64).
|
// the remaining partial frequency cycle, as a unit of time(f64).
|
||||||
let partial_heartbeat_as_time = frequency.mul_f64(partial_heartbeat).as_secs_f64();
|
let partial_heartbeat_as_time = frequency.mul_f64(partial_heartbeat).as_secs_f64();
|
||||||
|
|
||||||
// now minus the left over heart beat count precision as seconds,
|
// now minus the left over heart beat count precision as seconds,
|
||||||
@ -449,7 +449,7 @@ impl HeartbeatScheduler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns the number of times this duration has elasped since the last
|
/// returns the number of times this duration has elapsed since the last
|
||||||
/// tick:
|
/// tick:
|
||||||
/// - if it's more frequent then tick rate, it could be 1 or more.
|
/// - if it's more frequent then tick rate, it could be 1 or more.
|
||||||
/// - if it's less frequent then tick rate, it could be 1 or 0.
|
/// - if it's less frequent then tick rate, it could be 1 or 0.
|
||||||
|
@ -430,7 +430,7 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
|||||||
let ori = (block.get_ori().unwrap_or((seed % 4) as u8 * 2)) & 0b111;
|
let ori = (block.get_ori().unwrap_or((seed % 4) as u8 * 2)) & 0b111;
|
||||||
let variation = seed as usize % cfg.variations;
|
let variation = seed as usize % cfg.variations;
|
||||||
let key = (block.kind(), variation);
|
let key = (block.kind(), variation);
|
||||||
// NOTE: Safe bbecause we called sprite_config_for already.
|
// NOTE: Safe because we called sprite_config_for already.
|
||||||
// NOTE: Safe because 0 ≤ ori < 8
|
// NOTE: Safe because 0 ≤ ori < 8
|
||||||
let sprite_data = &sprite_data[&key][0];
|
let sprite_data = &sprite_data[&key][0];
|
||||||
let instance = SpriteInstance::new(
|
let instance = SpriteInstance::new(
|
||||||
@ -2684,7 +2684,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
.get(&response.pos)
|
.get(&response.pos)
|
||||||
.map(|chunk| chunk.load_time)
|
.map(|chunk| chunk.load_time)
|
||||||
.unwrap_or(current_time as f32);
|
.unwrap_or(current_time as f32);
|
||||||
// TODO: Allocate new atlas on allocation faillure.
|
// TODO: Allocate new atlas on allocation failure.
|
||||||
let (tex, tex_size) = response.col_lights_info;
|
let (tex, tex_size) = response.col_lights_info;
|
||||||
let atlas = &mut self.atlas;
|
let atlas = &mut self.atlas;
|
||||||
let allocation = atlas
|
let allocation = atlas
|
||||||
@ -2692,7 +2692,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
i32::from(tex_size.x),
|
i32::from(tex_size.x),
|
||||||
i32::from(tex_size.y),
|
i32::from(tex_size.y),
|
||||||
))
|
))
|
||||||
.expect("Not yet implemented: allocate new atlas on allocation faillure.");
|
.expect("Not yet implemented: allocate new atlas on allocation failure.");
|
||||||
// NOTE: Cast is safe since the origin was a u16.
|
// NOTE: Cast is safe since the origin was a u16.
|
||||||
let atlas_offs = Vec2::new(
|
let atlas_offs = Vec2::new(
|
||||||
allocation.rectangle.min.x as u16,
|
allocation.rectangle.min.x as u16,
|
||||||
|
@ -46,7 +46,7 @@ pub enum Rotation {
|
|||||||
|
|
||||||
/// Images larger than this are stored in individual textures
|
/// Images larger than this are stored in individual textures
|
||||||
/// Fraction of the total graphic cache size
|
/// Fraction of the total graphic cache size
|
||||||
const ATLAS_CUTTOFF_FRAC: f32 = 0.2;
|
const ATLAS_CUTOFF_FRAC: f32 = 0.2;
|
||||||
/// Multiplied by current window size
|
/// Multiplied by current window size
|
||||||
const GRAPHIC_CACHE_RELATIVE_SIZE: u16 = 1;
|
const GRAPHIC_CACHE_RELATIVE_SIZE: u16 = 1;
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ impl GraphicCache {
|
|||||||
|
|
||||||
pub fn get_graphic(&self, id: Id) -> Option<&Graphic> { self.graphic_map.get(&id) }
|
pub fn get_graphic(&self, id: Id) -> Option<&Graphic> { self.graphic_map.get(&id) }
|
||||||
|
|
||||||
/// Used to aquire textures for rendering
|
/// Used to acquire textures for rendering
|
||||||
pub fn get_tex(&self, id: TexId) -> &Texture {
|
pub fn get_tex(&self, id: TexId) -> &Texture {
|
||||||
self.textures.get(id.0).expect("Invalid TexId used")
|
self.textures.get(id.0).expect("Invalid TexId used")
|
||||||
}
|
}
|
||||||
@ -287,7 +287,7 @@ impl GraphicCache {
|
|||||||
textures.push(texture);
|
textures.push(texture);
|
||||||
CachedDetails::Immutable { index }
|
CachedDetails::Immutable { index }
|
||||||
} else if atlas_size
|
} else if atlas_size
|
||||||
.map2(dims, |a, d| a as f32 * ATLAS_CUTTOFF_FRAC >= d as f32)
|
.map2(dims, |a, d| a as f32 * ATLAS_CUTOFF_FRAC >= d as f32)
|
||||||
.reduce_and()
|
.reduce_and()
|
||||||
{
|
{
|
||||||
// Fit into an atlas
|
// Fit into an atlas
|
||||||
|
@ -14,18 +14,18 @@ const EPSILON: f32 = 0.0001;
|
|||||||
// Say we have two areas that we are combining to form a single pixel
|
// Say we have two areas that we are combining to form a single pixel
|
||||||
// A1 and A2 where these are the fraction of the area of the pixel each color
|
// A1 and A2 where these are the fraction of the area of the pixel each color
|
||||||
// contributes to Then if the colors were opaque we would say that the final
|
// contributes to Then if the colors were opaque we would say that the final
|
||||||
// color ouput color o3 is
|
// color output color o3 is
|
||||||
// E1: o3 = A1 * o1 + A2 * o2
|
// E1: o3 = A1 * o1 + A2 * o2
|
||||||
// where o1 and o2 are the opaque colors of the two areas
|
// where o1 and o2 are the opaque colors of the two areas
|
||||||
// now say the areas are actually translucent and these opaque colors are
|
// now say the areas are actually translucent and these opaque colors are
|
||||||
// derived by blending with a common backgound color b
|
// derived by blending with a common background color b
|
||||||
// E2: o1 = c1 * a1 + b * (1 - a1)
|
// E2: o1 = c1 * a1 + b * (1 - a1)
|
||||||
// E3: o2 = c2 * a2 + b * (1 - a2)
|
// E3: o2 = c2 * a2 + b * (1 - a2)
|
||||||
// we want to find the combined color (c3) and combined alpha (a3) such that
|
// we want to find the combined color (c3) and combined alpha (a3) such that
|
||||||
// E4: o3 = c3 * a3 + b * (1 - a3)
|
// E4: o3 = c3 * a3 + b * (1 - a3)
|
||||||
// substitution of E2 and E3 into E1 gives
|
// substitution of E2 and E3 into E1 gives
|
||||||
// E5: o3 = A1 * (c1 * a1 + b * (1 - a1)) + A2 * (c2 * a2 + b * (1 - a2))
|
// E5: o3 = A1 * (c1 * a1 + b * (1 - a1)) + A2 * (c2 * a2 + b * (1 - a2))
|
||||||
// combining E4 and E5 then separting like terms into separte equations gives
|
// combining E4 and E5 then separating like terms into separate equations gives
|
||||||
// E6: c3 * a3 = A1 * c1 * a1 + A2 * c2 * a2
|
// E6: c3 * a3 = A1 * c1 * a1 + A2 * c2 * a2
|
||||||
// E7: b * (1 - a3) = A1 * b * (1 - a1) + A2 * b * (1 - a2)
|
// E7: b * (1 - a3) = A1 * b * (1 - a1) + A2 * b * (1 - a2)
|
||||||
// dropping b from E7 and solving for a3
|
// dropping b from E7 and solving for a3
|
||||||
@ -119,7 +119,7 @@ pub fn resize_pixel_art(image: &RgbaImage, new_width: u32, new_height: u32) -> R
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Divide summed color by area sample covers and convert back to srgb
|
// Divide summed color by area sample covers and convert back to srgb
|
||||||
// I wonder if precalulating the inverse of these divs would have a significant
|
// I wonder if precalculating the inverse of these divs would have a significant
|
||||||
// effect
|
// effect
|
||||||
linear_color = linear_color / wratio / hratio;
|
linear_color = linear_color / wratio / hratio;
|
||||||
linear_color =
|
linear_color =
|
||||||
|
@ -29,7 +29,7 @@ impl<'a> GraphicCreator<'a> for ImageGraphic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum VoxelGraphic {}
|
pub enum VoxelGraphic {}
|
||||||
// TODO: Are these uneeded now that we have PixArtGraphic?
|
// TODO: Are these unneeded now that we have PixArtGraphic?
|
||||||
pub enum VoxelSsGraphic {}
|
pub enum VoxelSsGraphic {}
|
||||||
pub enum VoxelSs4Graphic {}
|
pub enum VoxelSs4Graphic {}
|
||||||
pub enum VoxelSs9Graphic {}
|
pub enum VoxelSs9Graphic {}
|
||||||
|
@ -117,7 +117,7 @@ pub struct Ui {
|
|||||||
cache: Cache,
|
cache: Cache,
|
||||||
// Draw commands for the next render
|
// Draw commands for the next render
|
||||||
draw_commands: Vec<DrawCommand>,
|
draw_commands: Vec<DrawCommand>,
|
||||||
// Mesh buffer for UI vertics; we reuse its allocation in order to limit vector reallocations
|
// Mesh buffer for UI vertices; we reuse its allocation in order to limit vector reallocations
|
||||||
// during redrawing.
|
// during redrawing.
|
||||||
mesh: Mesh<UiPipeline>,
|
mesh: Mesh<UiPipeline>,
|
||||||
// Model for drawing the ui
|
// Model for drawing the ui
|
||||||
@ -762,7 +762,7 @@ impl Ui {
|
|||||||
// Don't do anything if resolution is zero
|
// Don't do anything if resolution is zero
|
||||||
if resolution.map(|e| e == 0).reduce_or() {
|
if resolution.map(|e| e == 0).reduce_or() {
|
||||||
continue;
|
continue;
|
||||||
// TODO: consider logging uneeded elements
|
// TODO: consider logging unneeded elements
|
||||||
}
|
}
|
||||||
|
|
||||||
let color =
|
let color =
|
||||||
|
@ -127,7 +127,7 @@ pub fn apply_scatter_to<'a>(
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
// Collecable Objects
|
// Collectable Objects
|
||||||
// Only spawn twigs in temperate forests
|
// Only spawn twigs in temperate forests
|
||||||
(Twigs, false, |c| {
|
(Twigs, false, |c| {
|
||||||
((c.tree_density - 0.5).max(0.0) * 1.0e-3, None)
|
((c.tree_density - 0.5).max(0.0) * 1.0e-3, None)
|
||||||
|
@ -637,7 +637,7 @@ fn get_max_slope(
|
|||||||
/// areas.
|
/// areas.
|
||||||
/// 3. Now, iterate through the list in *order.* Whether we used the filling
|
/// 3. Now, iterate through the list in *order.* Whether we used the filling
|
||||||
/// method to compute a "filled" version of each depression, or used the lake
|
/// method to compute a "filled" version of each depression, or used the lake
|
||||||
/// connection algoirthm described in [1], each node is guaranteed to have
|
/// connection algorithm described in [1], each node is guaranteed to have
|
||||||
/// zero or one drainage edges out, representing the direction of water flow
|
/// zero or one drainage edges out, representing the direction of water flow
|
||||||
/// for that node. For nodes i with zero drainage edges out (boundary nodes
|
/// for that node. For nodes i with zero drainage edges out (boundary nodes
|
||||||
/// and lake bottoms) we set the slope to 0 (so the change in altitude is
|
/// and lake bottoms) we set the slope to 0 (so the change in altitude is
|
||||||
@ -664,7 +664,7 @@ fn get_max_slope(
|
|||||||
///
|
///
|
||||||
/// https://github.com/fastscape-lem/fastscapelib-fortran/blob/master/src/StreamPowerLaw.f90
|
/// https://github.com/fastscape-lem/fastscapelib-fortran/blob/master/src/StreamPowerLaw.f90
|
||||||
///
|
///
|
||||||
/// The approximate equation for soil production function (predictng the rate
|
/// The approximate equation for soil production function (predicting the rate
|
||||||
/// at which bedrock turns into soil, increasing the distance between the
|
/// at which bedrock turns into soil, increasing the distance between the
|
||||||
/// basement and altitude) is taken from equation (11) from [2]. This (among
|
/// basement and altitude) is taken from equation (11) from [2]. This (among
|
||||||
/// numerous other sources) also includes at least one prediction that hillslope
|
/// numerous other sources) also includes at least one prediction that hillslope
|
||||||
@ -1387,7 +1387,7 @@ fn erode(
|
|||||||
// Because in the next round, if the old height is still wh_j or under,
|
// Because in the next round, if the old height is still wh_j or under,
|
||||||
// it will be set precisely equal to the
|
// it will be set precisely equal to the
|
||||||
// estimated height, meaning it effectively
|
// estimated height, meaning it effectively
|
||||||
// "vanishes" and just deposits sediment to its reciever.
|
// "vanishes" and just deposits sediment to its receiver.
|
||||||
// (This is probably related to criteria for block Gauss-Seidel, etc.).
|
// (This is probably related to criteria for block Gauss-Seidel, etc.).
|
||||||
// NOTE: If we want erosion to proceed underwater, use h_j here instead
|
// NOTE: If we want erosion to proceed underwater, use h_j here instead
|
||||||
// of wh_j.
|
// of wh_j.
|
||||||
@ -1445,7 +1445,7 @@ fn erode(
|
|||||||
}
|
}
|
||||||
if n_gs_stream_power_law == max_n_gs_stream_power_law {
|
if n_gs_stream_power_law == max_n_gs_stream_power_law {
|
||||||
warn!(
|
warn!(
|
||||||
"Beware: Gauss-Siedel scheme not convergent: err={:?}, expected={:?}",
|
"Beware: Gauss-Seidel scheme not convergent: err={:?}, expected={:?}",
|
||||||
err, tol
|
err, tol
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1477,7 +1477,7 @@ fn erode(
|
|||||||
|
|
||||||
let posj = dh[posi];
|
let posj = dh[posi];
|
||||||
// Sediment height normal to bedrock. NOTE: Currently we can actually have
|
// Sediment height normal to bedrock. NOTE: Currently we can actually have
|
||||||
// sedment and bedrock slope at different heights, meaning there's
|
// sediment and bedrock slope at different heights, meaning there's
|
||||||
// no uniform slope. There are probably more correct ways to
|
// no uniform slope. There are probably more correct ways to
|
||||||
// account for this, such as averaging, integrating, or doing things
|
// account for this, such as averaging, integrating, or doing things
|
||||||
// by mass / volume instead of height, but for now we use the time-honored
|
// by mass / volume instead of height, but for now we use the time-honored
|
||||||
@ -1772,7 +1772,7 @@ pub fn fill_sinks<F: Float + Send + Sync>(
|
|||||||
// Otherwise, we know this node's original height is below the new height of all
|
// Otherwise, we know this node's original height is below the new height of all
|
||||||
// of its neighbors. Then, we try to choose the minimum new
|
// of its neighbors. Then, we try to choose the minimum new
|
||||||
// height among all this node's neighbors that is (plus a
|
// height among all this node's neighbors that is (plus a
|
||||||
// constant epislon) below this node's new height.
|
// constant epsilon) below this node's new height.
|
||||||
//
|
//
|
||||||
// (If there is no such node, then the node's new height must be (minus a
|
// (If there is no such node, then the node's new height must be (minus a
|
||||||
// constant epsilon) lower than the new height of every
|
// constant epsilon) lower than the new height of every
|
||||||
|
@ -223,7 +223,7 @@ pub enum WorldFileError {
|
|||||||
/// least, we will try hard not to break maps between versions; if we can't
|
/// least, we will try hard not to break maps between versions; if we can't
|
||||||
/// avoid it, we can at least give a reasonable error message).
|
/// avoid it, we can at least give a reasonable error message).
|
||||||
///
|
///
|
||||||
/// NOTE: We rely somemwhat heavily on the implementation specifics of bincode
|
/// NOTE: We rely somewhat heavily on the implementation specifics of bincode
|
||||||
/// to make sure this is backwards compatible. When adding new variants here,
|
/// to make sure this is backwards compatible. When adding new variants here,
|
||||||
/// Be very careful to make sure tha the old variants are preserved in the
|
/// Be very careful to make sure tha the old variants are preserved in the
|
||||||
/// correct order and with the correct names and indices, and make sure to keep
|
/// correct order and with the correct names and indices, and make sure to keep
|
||||||
@ -244,7 +244,7 @@ pub enum WorldFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Data for the most recent map type. Update this when you add a new map
|
/// Data for the most recent map type. Update this when you add a new map
|
||||||
/// verson.
|
/// version.
|
||||||
pub type ModernMap = WorldMap_0_7_0;
|
pub type ModernMap = WorldMap_0_7_0;
|
||||||
|
|
||||||
/// The default world map.
|
/// The default world map.
|
||||||
@ -266,7 +266,7 @@ impl WorldFileLegacy {
|
|||||||
/// should construct a call chain that ultimately ends up with a modern
|
/// should construct a call chain that ultimately ends up with a modern
|
||||||
/// version.
|
/// version.
|
||||||
pub fn into_modern(self) -> Result<ModernMap, WorldFileError> {
|
pub fn into_modern(self) -> Result<ModernMap, WorldFileError> {
|
||||||
// NOTE: At this point, we ssume that any remaining legacy maps were 1024 ×
|
// NOTE: At this point, we assume that any remaining legacy maps were 1024 ×
|
||||||
// 1024.
|
// 1024.
|
||||||
if self.alt.len() != self.basement.len() || self.alt.len() != 1024 * 1024 {
|
if self.alt.len() != self.basement.len() || self.alt.len() != 1024 * 1024 {
|
||||||
return Err(WorldFileError::WorldSizeInvalid);
|
return Err(WorldFileError::WorldSizeInvalid);
|
||||||
@ -1135,7 +1135,7 @@ impl WorldSim {
|
|||||||
basement,
|
basement,
|
||||||
} = map.into_modern().unwrap();
|
} = map.into_modern().unwrap();
|
||||||
|
|
||||||
// Additional small-scale eroson after map load, only used during testing.
|
// Additional small-scale erosion after map load, only used during testing.
|
||||||
let (alt, basement) = if n_post_load_steps == 0 {
|
let (alt, basement) = if n_post_load_steps == 0 {
|
||||||
(alt, basement)
|
(alt, basement)
|
||||||
} else {
|
} else {
|
||||||
@ -2065,7 +2065,7 @@ impl SimChunk {
|
|||||||
// Not clear that we want this yet, let's see.
|
// Not clear that we want this yet, let's see.
|
||||||
let latitude_uniform = (pos.y as f32 / f32::from(self.map_size_lg().chunks().y)).sub(0.5).mul(2.0);
|
let latitude_uniform = (pos.y as f32 / f32::from(self.map_size_lg().chunks().y)).sub(0.5).mul(2.0);
|
||||||
|
|
||||||
// Even less granular--if this matters we can make the sign affect the quantiy slightly.
|
// Even less granular--if this matters we can make the sign affect the quantity slightly.
|
||||||
let abs_lat_uniform = latitude_uniform.abs(); */
|
let abs_lat_uniform = latitude_uniform.abs(); */
|
||||||
|
|
||||||
// Take the weighted average of our randomly generated base humidity, and the
|
// Take the weighted average of our randomly generated base humidity, and the
|
||||||
@ -2228,7 +2228,7 @@ impl SimChunk {
|
|||||||
// Temperate climate with jungle humidity...
|
// Temperate climate with jungle humidity...
|
||||||
// https://en.wikipedia.org/wiki/Humid_subtropical_climates are often
|
// https://en.wikipedia.org/wiki/Humid_subtropical_climates are often
|
||||||
// densely wooded and full of water. Semitropical rainforests, basically.
|
// densely wooded and full of water. Semitropical rainforests, basically.
|
||||||
// For now we just treet them like other rainforests.
|
// For now we just treat them like other rainforests.
|
||||||
ForestKind::Oak
|
ForestKind::Oak
|
||||||
} else if humidity > CONFIG.forest_hum {
|
} else if humidity > CONFIG.forest_hum {
|
||||||
// Moderate climate, moderate humidity.
|
// Moderate climate, moderate humidity.
|
||||||
|
@ -40,7 +40,7 @@ pub fn map_edge_factor(map_size_lg: MapSizeLg, posi: usize) -> f32 {
|
|||||||
///
|
///
|
||||||
/// NOTE:
|
/// NOTE:
|
||||||
///
|
///
|
||||||
/// Per [[1]], the problem of determing the CDF of
|
/// Per [[1]], the problem of determining the CDF of
|
||||||
/// the sum of uniformly distributed random variables over *different* ranges is
|
/// the sum of uniformly distributed random variables over *different* ranges is
|
||||||
/// considerably more complicated than it is for the same-range case.
|
/// considerably more complicated than it is for the same-range case.
|
||||||
/// Fortunately, it also provides a reference to [2], which contains a complete
|
/// Fortunately, it also provides a reference to [2], which contains a complete
|
||||||
|
@ -100,14 +100,14 @@ pub fn tick(index: &mut Index, _world: &mut WorldSim, dt: f32) {
|
|||||||
/// simulation begins by assigning arbitrary values to each commodity and then
|
/// simulation begins by assigning arbitrary values to each commodity and then
|
||||||
/// incrementally updates them according to the final scarcity of the commodity
|
/// incrementally updates them according to the final scarcity of the commodity
|
||||||
/// at the end of the tick. This results in the formulation of values that are
|
/// at the end of the tick. This results in the formulation of values that are
|
||||||
/// roughly analgous to prices for each commodity. The workforce is then
|
/// roughly analogous to prices for each commodity. The workforce is then
|
||||||
/// reassigned according to the respective commodity values. The simulation also
|
/// reassigned according to the respective commodity values. The simulation also
|
||||||
/// includes damping terms that prevent cyclical inconsistencies in value
|
/// includes damping terms that prevent cyclical inconsistencies in value
|
||||||
/// rationalisation magnifying enough to crash the economy. We also ensure that
|
/// rationalisation magnifying enough to crash the economy. We also ensure that
|
||||||
/// a small number of workers are allocated to every industry (even inactive
|
/// a small number of workers are allocated to every industry (even inactive
|
||||||
/// ones) each tick. This is not an accident: a small amount of productive
|
/// ones) each tick. This is not an accident: a small amount of productive
|
||||||
/// capacity in one industry allows the economy to quickly pivot to a different
|
/// capacity in one industry allows the economy to quickly pivot to a different
|
||||||
/// prodution configuration should an additional commodity that acts as
|
/// production configuration should an additional commodity that acts as
|
||||||
/// production input become available. This means that the economy will
|
/// production input become available. This means that the economy will
|
||||||
/// dynamically react to environmental changes. If a product becomes available
|
/// dynamically react to environmental changes. If a product becomes available
|
||||||
/// through a mechanism such as trade, an entire arm of the economy may
|
/// through a mechanism such as trade, an entire arm of the economy may
|
||||||
|
Loading…
Reference in New Issue
Block a user