Skip to content

Commit

Permalink
Improve some docs (djeedai#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
djeedai authored Oct 31, 2022
1 parent 556903a commit 93f68b8
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 18 deletions.
22 changes: 20 additions & 2 deletions src/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,40 @@ pub struct RenderLayout {
#[uuid = "249aefa4-9b8e-48d3-b167-3adf6c081c34"]
pub struct EffectAsset {
/// Display name of the effect.
///
/// This has no internal use, and is mostly for the user to identify an
/// effect or for display is some tool UI.
pub name: String,
/// Maximum number of concurrent particles.
///
/// The capacity is the maximum number of particles that can be alive at the
/// same time. It determines the size of various GPU resources, most notably
/// the particle buffer itself. To prevent wasting GPU resources, users
/// should keep this quantity as close as possible to the maximum number of
/// particles they expect to render.
pub capacity: u32,
/// Spawner.
pub spawner: Spawner,
/// Layout describing the particle initialize code.
///
/// The initialize layout determines how new particles are initialized when
/// spawned. Compatible layouts increase the chance of batching together
/// effects.
#[serde(skip)] // TODO
#[reflect(ignore)] // TODO?
pub init_layout: InitLayout,
/// Layout describing the particle update code.
///
/// The update layout determines how all alive particles are updated each
/// frame. Compatible layouts increase the chance of batching together
/// effects.
#[serde(skip)] // TODO
#[reflect(ignore)] // TODO?
pub update_layout: UpdateLayout,
/// Layout describing the particle rendering code.
///
/// The render layout determines how alive particles are rendered.
/// Compatible layouts increase the chance of batching together effects.
#[serde(skip)] // TODO
#[reflect(ignore)] // TODO?
pub render_layout: RenderLayout,
Expand All @@ -97,8 +117,6 @@ pub struct EffectAsset {
///
/// Ignored for 3D rendering.
pub z_layer_2d: f32,
//#[serde(skip)] // TODO
//modifiers: Vec<Box<dyn Modifier + Send + Sync + 'static>>,
}

impl EffectAsset {
Expand Down
18 changes: 17 additions & 1 deletion src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,35 @@ use crate::{EffectAsset, ParticleEffect, Spawner};
use bevy::prelude::*;

/// A component bundle for a particle effect.
///
/// This bundle contains all necessary components for a [`ParticleEffect`] to
/// function correctly, and is the preferred method for spawning a new
/// [`ParticleEffect`].
#[derive(Bundle, Clone)]
pub struct ParticleEffectBundle {
/// The particle effect itself.
/// The particle effect instance itself.
pub effect: ParticleEffect,
/// Transform of the entity, representing the frame of reference for the
/// particle emission.
///
/// New particles are emitted relative to this transform, ignoring the
/// scale.
pub transform: Transform,
/// Computed global transform.
///
/// Users should not interact with this component manually, but it is
/// required by Bevy's built-in transform system.
pub global_transform: GlobalTransform,
/// User indication of whether an entity is visible.
///
/// Invisible entities do not process any particles, making it efficient to
/// temporarily disable an effect instance.
pub visibility: Visibility,
/// Algorithmically-computed indication of whether an entity is visible and
/// should be extracted for rendering.
///
/// Users should not interact with this component manually, but it is
/// required by Bevy's built-in visibility system.
pub computed_visibility: ComputedVisibility,
}

Expand Down
41 changes: 30 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,12 @@ compile_error!(
"You need to enable at least one of the '2d' or '3d' features for anything to happen."
);

/// Get the smallest multiple of align greater than or equal to value, where `align` must be a power of two.
/// Get the smallest multiple of align greater than or equal to value, where
/// `align` must be a power of two.
///
/// # Panics
///
/// Panics if `align` is not a power of two.
// TODO - filler for usize.next_multiple_of()
// https://github.com/rust-lang/rust/issues/88581
pub(crate) fn next_multiple_of(value: usize, align: usize) -> usize {
Expand All @@ -160,9 +165,9 @@ pub(crate) fn next_multiple_of(value: usize, align: usize) -> usize {
/// format matching the WGSL grammar.
///
/// This is required because WGSL doesn't support a floating point constant
/// without a decimal separator (e.g. `0.` instead of `0`), which would be what
/// a regular float to string formatting produces, but is interpreted as an
/// integral type by WGSL.
/// without a decimal separator (_e.g._ `0.` instead of `0`), which would be
/// what a regular string formatting function like [`format!()`] would produce,
/// but which is interpreted as an integral type by WGSL instead.
///
/// # Example
///
Expand All @@ -171,6 +176,8 @@ pub(crate) fn next_multiple_of(value: usize, align: usize) -> usize {
/// let x = 2.0_f32;
/// assert_eq!("let x = 2.;", format!("let x = {};", x.to_wgsl_string()));
/// ```
///
/// [`format!()`]: std::format
pub trait ToWgslString {
/// Convert a floating point scalar or vector to a string representing a
/// WGSL constant.
Expand Down Expand Up @@ -243,6 +250,10 @@ impl ToWgslString for Value<f32> {
/// effect. The visual effect itself is described by a handle to an
/// [`EffectAsset`]. This instance is associated to an [`Entity`], inheriting
/// its [`Transform`] as the origin frame for its particle spawning.
///
/// When spawning a new [`ParticleEffect`], consider using the
/// [`ParticleEffectBundle`] to ensure all the necessary components are present
/// on the entity for the effect to render correctly.
#[derive(Debug, Default, Clone, Component, Reflect)]
#[reflect(Component)]
pub struct ParticleEffect {
Expand Down Expand Up @@ -314,15 +325,22 @@ impl ParticleEffect {
self
}

/// Sets the spawner of this particle effect.
/// Set the spawner of this particle effect instance.
///
/// By default particle effect instances inherit the spawner of the
/// [`EffectAsset`] they're derived from. This allows overriding the spawner
/// configuration per instance.
pub fn set_spawner(&mut self, spawner: Spawner) {
self.spawner = Some(spawner);
}

/// Configure the spawner of a new particle effect.
///
/// The call returns a reference to the added spawner, allowing to chain
/// adding modifiers to the effect.
/// In general this is called internally while the spawner is ticked, to
/// assign the source asset's spawner to this instance.
///
/// Returns a reference to the added spawner owned by the current instance,
/// allowing to chain adding modifiers to the effect.
pub fn spawner(&mut self, spawner: &Spawner) -> &mut Spawner {
if self.spawner.is_none() {
self.spawner = Some(*spawner);
Expand All @@ -332,8 +350,10 @@ impl ParticleEffect {

/// Get the spawner of this particle effect.
///
/// Returns None if `with_spawner` was not called
/// and the effect has not rendered yet.
/// Returns `None` if [`configure_spawner()`] was not called and the effect
/// has not been internally allocated yet.
///
/// [`configure_spawner()`]: crate::ParticleEffect::configure_spawner
pub fn maybe_spawner(&mut self) -> Option<&mut Spawner> {
self.spawner.as_mut()
}
Expand Down Expand Up @@ -506,8 +526,7 @@ fn tick_spawners(

// Loop over all existing effects to update them
for (computed_visibility, mut effect) in query.p0().iter_mut() {
// Check if visible. Hidden effects are entirely skipped for performance
// reasons.
// Hidden effects are entirely skipped for performance reasons
if !computed_visibility.is_visible() {
continue;
}
Expand Down
21 changes: 17 additions & 4 deletions src/spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ pub struct Random(pub Pcg32);
pub enum Value<T: Copy> {
/// Single constant value.
Single(T),
/// Random value distributed uniformly between two bounds.
/// Random value distributed uniformly between two inclusive bounds.
///
/// The minimum bound must be less than or equal to the maximum one,
/// otherwise some methods like [`sample()`] will panic.
///
/// [`sample()`]: crate::Value::sample
Uniform((T, T)),
}

Expand All @@ -34,6 +39,9 @@ impl<T: Copy + Default> Default for Value<T> {

impl<T: Copy + SampleUniform> Value<T> {
/// Sample the value.
/// - For [`Value::Single`], always return the same single value.
/// - For [`Value::Uniform`], use the given pseudo-random number generator
/// to generate a random sample.
pub fn sample(&self, rng: &mut Pcg32) -> T {
match self {
Value::Single(x) => *x,
Expand All @@ -43,8 +51,8 @@ impl<T: Copy + SampleUniform> Value<T> {
}

impl<T: Copy + PartialOrd> Value<T> {
/// Returns the range of values this can be
/// in the form `[minimum, maximum]`
/// Returns the range of allowable values in the form `[minimum, maximum]`.
/// For [`Value::Single`], both values are the same.
pub fn range(&self) -> [T; 2] {
match self {
Value::Single(x) => [*x; 2],
Expand All @@ -65,7 +73,12 @@ impl<T: Copy> From<T> for Value<T> {
}
}

/// Spawner defining how new particles are created.
/// Spawner defining how new particles are emitted.
///
/// The spawner defines how new particles are emitted and when. Each time the
/// spawner ticks, once per frame, it calculates a number of particles to emit
/// for this tick. This spawn count is passed to the GPU for the init compute
/// pass to actually allocate the new particles and initialize them.
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Reflect)]
pub struct Spawner {
/// Number of particles to spawn over [`spawn_time`].
Expand Down

0 comments on commit 93f68b8

Please sign in to comment.