#![allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum RmChannel {
Roughness,
Metalness,
Combined,
}
#[derive(Debug, Clone)]
pub struct RoughnessMetalnessViewConfig {
pub channel: RmChannel,
pub roughness_tint: [f32; 3],
pub metalness_tint: [f32; 3],
}
impl Default for RoughnessMetalnessViewConfig {
fn default() -> Self {
Self {
channel: RmChannel::Combined,
roughness_tint: [1.0, 0.5, 0.0],
metalness_tint: [0.0, 0.5, 1.0],
}
}
}
#[derive(Debug, Clone)]
pub struct RoughnessMetalnessView {
pub config: RoughnessMetalnessViewConfig,
pub enabled: bool,
}
impl Default for RoughnessMetalnessView {
fn default() -> Self {
Self { config: RoughnessMetalnessViewConfig::default(), enabled: false }
}
}
pub fn rmv_enable(view: &mut RoughnessMetalnessView) {
view.enabled = true;
}
pub fn rmv_disable(view: &mut RoughnessMetalnessView) {
view.enabled = false;
}
pub fn rmv_set_channel(view: &mut RoughnessMetalnessView, channel: RmChannel) {
view.config.channel = channel;
}
pub fn rmv_to_color(roughness: f32, metalness: f32, config: &RoughnessMetalnessViewConfig) -> [f32; 4] {
let r = roughness.clamp(0.0, 1.0);
let m = metalness.clamp(0.0, 1.0);
match config.channel {
RmChannel::Roughness => [r, r, r, 1.0],
RmChannel::Metalness => [m, m, m, 1.0],
RmChannel::Combined => {
let t = config.roughness_tint;
let u = config.metalness_tint;
[
t[0] * r + u[0] * m,
t[1] * r + u[1] * m,
t[2] * r + u[2] * m,
1.0,
]
}
}
}
pub fn rmv_is_metallic(metalness: f32) -> bool {
metalness > 0.5
}
pub fn rmv_to_json(view: &RoughnessMetalnessView) -> String {
let ch = match view.config.channel {
RmChannel::Roughness => "roughness",
RmChannel::Metalness => "metalness",
RmChannel::Combined => "combined",
};
format!(r#"{{"channel":"{}","enabled":{}}}"#, ch, view.enabled)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_disabled() {
let v = RoughnessMetalnessView::default();
assert!(!v.enabled);
}
#[test]
fn test_enable_disable() {
let mut v = RoughnessMetalnessView::default();
rmv_enable(&mut v);
assert!(v.enabled);
rmv_disable(&mut v);
assert!(!v.enabled);
}
#[test]
fn test_set_channel() {
let mut v = RoughnessMetalnessView::default();
rmv_set_channel(&mut v, RmChannel::Roughness);
assert_eq!(v.config.channel, RmChannel::Roughness);
}
#[test]
fn test_roughness_channel_greyscale() {
let cfg = RoughnessMetalnessViewConfig { channel: RmChannel::Roughness, ..Default::default() };
let c = rmv_to_color(0.7, 0.0, &cfg);
assert!((c[0] - 0.7).abs() < 1e-6);
assert!((c[0] - c[1]).abs() < 1e-6);
}
#[test]
fn test_metalness_channel_greyscale() {
let cfg = RoughnessMetalnessViewConfig { channel: RmChannel::Metalness, ..Default::default() };
let c = rmv_to_color(0.0, 0.8, &cfg);
assert!((c[0] - 0.8).abs() < 1e-6);
}
#[test]
fn test_alpha_always_one() {
let cfg = RoughnessMetalnessViewConfig::default();
let c = rmv_to_color(0.5, 0.5, &cfg);
assert!((c[3] - 1.0).abs() < 1e-6);
}
#[test]
fn test_is_metallic_above_half() {
assert!(rmv_is_metallic(0.8));
}
#[test]
fn test_is_not_metallic_below_half() {
assert!(!rmv_is_metallic(0.4));
}
#[test]
fn test_to_json_channel() {
let v = RoughnessMetalnessView::default();
let json = rmv_to_json(&v);
assert!(json.contains("combined"));
}
}