#![allow(clippy::too_many_arguments)]
mod error;
pub mod generator;
mod metadata;
mod safe;
pub use error::FastNoiseError;
pub use metadata::MemberType;
use metadata::{format_lookup, MemberValue, METADATA_NAME_LOOKUP, NODE_METADATA};
pub use safe::SafeNode;
use fastnoise2_sys::*;
use std::{ffi::CString, fmt::Debug};
#[derive(Debug)]
pub struct Node {
handle: *mut core::ffi::c_void,
metadata_id: i32,
}
impl Node {
#[cfg_attr(feature = "trace", tracing::instrument(level = "debug"))]
pub fn from_name(metadata_name: &str) -> Result<Self, FastNoiseError> {
let metadata_name = format_lookup(metadata_name);
let metadata_id = *METADATA_NAME_LOOKUP.get(&metadata_name).ok_or_else(|| {
FastNoiseError::MetadataNameNotFound {
expected: METADATA_NAME_LOOKUP.keys().cloned().collect(),
found: metadata_name,
}
})?;
let handle = unsafe { fnNewFromMetadata(metadata_id, u32::MAX) };
Ok(Self {
handle,
metadata_id,
})
}
#[cfg_attr(feature = "trace", tracing::instrument(level = "debug"))]
pub fn from_encoded_node_tree(encoded_node_tree: &str) -> Result<Self, FastNoiseError> {
let cstring =
CString::new(encoded_node_tree).map_err(FastNoiseError::CStringCreationFailed)?;
let node_ptr = unsafe { fnNewFromEncodedNodeTree(cstring.as_ptr(), u32::MAX) };
if node_ptr.is_null() {
Err(FastNoiseError::NodeCreationFailed)
} else {
Ok(Self {
handle: node_ptr,
metadata_id: unsafe { fnGetMetadataID(node_ptr) },
})
}
}
pub fn get_simd_level(&self) -> u32 {
unsafe { fnGetSIMDLevel(self.handle) }
}
#[allow(private_bounds)]
#[cfg_attr(feature = "trace", tracing::instrument(level = "trace"))]
pub fn set<V>(&mut self, member_name: &str, value: V) -> Result<(), FastNoiseError>
where
V: MemberValue + Debug,
{
let metadata = &NODE_METADATA[self.metadata_id as usize];
let member_name = format_lookup(member_name);
let member = metadata.members.get(&member_name).ok_or_else(|| {
FastNoiseError::MemberNameNotFound {
expected: metadata.members.values().map(|m| m.name.clone()).collect(),
found: member_name,
}
})?;
value.apply(self, member)
}
#[cfg_attr(
feature = "trace",
tracing::instrument(level = "trace", skip(noise_out))
)]
pub unsafe fn gen_uniform_grid_2d_unchecked(
&self,
noise_out: &mut [f32],
x_offset: f32,
y_offset: f32,
x_count: i32,
y_count: i32,
x_step_size: f32,
y_step_size: f32,
seed: i32,
) -> OutputMinMax {
let mut min_max = [0.0; 2];
fnGenUniformGrid2D(
self.handle,
noise_out.as_mut_ptr(),
x_offset,
y_offset,
x_count,
y_count,
x_step_size,
y_step_size,
seed,
min_max.as_mut_ptr(),
);
OutputMinMax::new(min_max)
}
#[cfg_attr(
feature = "trace",
tracing::instrument(level = "trace", skip(noise_out))
)]
pub unsafe fn gen_uniform_grid_3d_unchecked(
&self,
noise_out: &mut [f32],
x_offset: f32,
y_offset: f32,
z_offset: f32,
x_count: i32,
y_count: i32,
z_count: i32,
x_step_size: f32,
y_step_size: f32,
z_step_size: f32,
seed: i32,
) -> OutputMinMax {
let mut min_max = [0.0; 2];
fnGenUniformGrid3D(
self.handle,
noise_out.as_mut_ptr(),
x_offset,
y_offset,
z_offset,
x_count,
y_count,
z_count,
x_step_size,
y_step_size,
z_step_size,
seed,
min_max.as_mut_ptr(),
);
OutputMinMax::new(min_max)
}
#[cfg_attr(
feature = "trace",
tracing::instrument(level = "trace", skip(noise_out))
)]
pub unsafe fn gen_uniform_grid_4d_unchecked(
&self,
noise_out: &mut [f32],
x_offset: f32,
y_offset: f32,
z_offset: f32,
w_offset: f32,
x_count: i32,
y_count: i32,
z_count: i32,
w_count: i32,
x_step_size: f32,
y_step_size: f32,
z_step_size: f32,
w_step_size: f32,
seed: i32,
) -> OutputMinMax {
let mut min_max = [0.0; 2];
fnGenUniformGrid4D(
self.handle,
noise_out.as_mut_ptr(),
x_offset,
y_offset,
z_offset,
w_offset,
x_count,
y_count,
z_count,
w_count,
x_step_size,
y_step_size,
z_step_size,
w_step_size,
seed,
min_max.as_mut_ptr(),
);
OutputMinMax::new(min_max)
}
#[cfg_attr(
feature = "trace",
tracing::instrument(level = "trace", skip(noise_out))
)]
pub unsafe fn gen_position_array_2d_unchecked(
&self,
noise_out: &mut [f32],
x_pos_array: &[f32],
y_pos_array: &[f32],
x_offset: f32,
y_offset: f32,
seed: i32,
) -> OutputMinMax {
let mut min_max = [0.0; 2];
fnGenPositionArray2D(
self.handle,
noise_out.as_mut_ptr(),
x_pos_array.len() as i32,
x_pos_array.as_ptr(),
y_pos_array.as_ptr(),
x_offset,
y_offset,
seed,
min_max.as_mut_ptr(),
);
OutputMinMax::new(min_max)
}
#[cfg_attr(
feature = "trace",
tracing::instrument(level = "trace", skip(noise_out))
)]
pub unsafe fn gen_position_array_3d_unchecked(
&self,
noise_out: &mut [f32],
x_pos_array: &[f32],
y_pos_array: &[f32],
z_pos_array: &[f32],
x_offset: f32,
y_offset: f32,
z_offset: f32,
seed: i32,
) -> OutputMinMax {
let mut min_max = [0.0; 2];
fnGenPositionArray3D(
self.handle,
noise_out.as_mut_ptr(),
x_pos_array.len() as i32,
x_pos_array.as_ptr(),
y_pos_array.as_ptr(),
z_pos_array.as_ptr(),
x_offset,
y_offset,
z_offset,
seed,
min_max.as_mut_ptr(),
);
OutputMinMax::new(min_max)
}
#[cfg_attr(
feature = "trace",
tracing::instrument(level = "trace", skip(noise_out))
)]
pub unsafe fn gen_position_array_4d_unchecked(
&self,
noise_out: &mut [f32],
x_pos_array: &[f32],
y_pos_array: &[f32],
z_pos_array: &[f32],
w_pos_array: &[f32],
x_offset: f32,
y_offset: f32,
z_offset: f32,
w_offset: f32,
seed: i32,
) -> OutputMinMax {
let mut min_max = [0.0; 2];
fnGenPositionArray4D(
self.handle,
noise_out.as_mut_ptr(),
x_pos_array.len() as i32,
x_pos_array.as_ptr(),
y_pos_array.as_ptr(),
z_pos_array.as_ptr(),
w_pos_array.as_ptr(),
x_offset,
y_offset,
z_offset,
w_offset,
seed,
min_max.as_mut_ptr(),
);
OutputMinMax::new(min_max)
}
#[cfg_attr(
feature = "trace",
tracing::instrument(level = "trace", skip(noise_out))
)]
pub unsafe fn gen_tileable_2d_unchecked(
&self,
noise_out: &mut [f32],
x_size: i32,
y_size: i32,
x_step_size: f32,
y_step_size: f32,
seed: i32,
) -> OutputMinMax {
let mut min_max = [0.0; 2];
fnGenTileable2D(
self.handle,
noise_out.as_mut_ptr(),
x_size,
y_size,
x_step_size,
y_step_size,
seed,
min_max.as_mut_ptr(),
);
OutputMinMax::new(min_max)
}
#[cfg_attr(feature = "trace", tracing::instrument(level = "trace"))]
pub unsafe fn gen_single_2d_unchecked(&self, x: f32, y: f32, seed: i32) -> f32 {
unsafe { fnGenSingle2D(self.handle, x, y, seed) }
}
#[cfg_attr(feature = "trace", tracing::instrument(level = "trace"))]
pub unsafe fn gen_single_3d_unchecked(&self, x: f32, y: f32, z: f32, seed: i32) -> f32 {
unsafe { fnGenSingle3D(self.handle, x, y, z, seed) }
}
#[cfg_attr(feature = "trace", tracing::instrument(level = "trace"))]
pub unsafe fn gen_single_4d_unchecked(&self, x: f32, y: f32, z: f32, w: f32, seed: i32) -> f32 {
unsafe { fnGenSingle4D(self.handle, x, y, z, w, seed) }
}
}
impl Drop for Node {
#[cfg_attr(feature = "trace", tracing::instrument(level = "trace"))]
fn drop(&mut self) {
unsafe { fnDeleteNodeRef(self.handle) };
}
}
#[derive(Debug)]
pub struct OutputMinMax {
pub min: f32,
pub max: f32,
}
impl OutputMinMax {
fn new([min, max]: [f32; 2]) -> Self {
Self { min, max }
}
}
#[cfg(test)]
pub mod test_utils;