111 lines
3.5 KiB
Rust
111 lines
3.5 KiB
Rust
use crate::core::texture::{CreateSpectrumTexture, FloatTexture, SpectrumTexture};
|
|
use crate::core::texture::{FloatTextureTrait, SpectrumTextureTrait};
|
|
use crate::utils::{FileLoc, TextureParameterDictionary};
|
|
use crate::Arena;
|
|
use anyhow::Result;
|
|
use shared::core::spectrum::Spectrum;
|
|
use shared::core::texture::{SpectrumType, TextureEvalContext};
|
|
use shared::spectra::{SampledSpectrum, SampledWavelengths, ConstantSpectrum};
|
|
use shared::utils::Transform;
|
|
use shared::Float;
|
|
use std::sync::Arc;
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct FloatScaledTexture {
|
|
pub tex: Arc<FloatTexture>,
|
|
pub scale: Arc<FloatTexture>,
|
|
}
|
|
|
|
impl FloatScaledTexture {
|
|
pub fn new(tex: Arc<FloatTexture>, scale: Arc<FloatTexture>) -> Self {
|
|
Self { tex, scale }
|
|
}
|
|
|
|
pub fn create(
|
|
_render_from_texture: &Transform,
|
|
params: &TextureParameterDictionary,
|
|
_loc: &FileLoc,
|
|
_arena: &Arena,
|
|
) -> Result<FloatTexture> {
|
|
let mut tex = params.get_float_texture("tex", 1.)?;
|
|
let mut scale = params.get_float_texture("scale", 1.)?;
|
|
|
|
for _ in 0..2 {
|
|
if let FloatTexture::Constant(c_tex) = &*scale {
|
|
let cs = c_tex.value;
|
|
if cs == 1.0 {
|
|
return Ok((*tex).clone());
|
|
} else if let FloatTexture::Image(img_tex) = &*tex {
|
|
let mut image_copy = img_tex.clone();
|
|
image_copy.base.multiply_scale(cs);
|
|
return Ok(FloatTexture::Image(image_copy));
|
|
}
|
|
}
|
|
|
|
std::mem::swap(&mut tex, &mut scale);
|
|
}
|
|
std::mem::swap(&mut tex, &mut scale);
|
|
Ok(FloatTexture::Scaled(FloatScaledTexture::new(
|
|
tex.clone(),
|
|
scale.clone(),
|
|
)))
|
|
}
|
|
}
|
|
|
|
impl FloatTextureTrait for FloatScaledTexture {
|
|
fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
|
|
let sc = self.scale.evaluate(ctx);
|
|
if sc == 0. {
|
|
return 0.;
|
|
}
|
|
self.tex.evaluate(ctx)
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct SpectrumScaledTexture {
|
|
pub tex: Arc<SpectrumTexture>,
|
|
pub scale: Arc<FloatTexture>,
|
|
}
|
|
|
|
impl CreateSpectrumTexture for SpectrumScaledTexture {
|
|
fn create(
|
|
_render_from_texture: Transform,
|
|
parameters: TextureParameterDictionary,
|
|
spectrum_type: SpectrumType,
|
|
_loc: FileLoc,
|
|
) -> Result<SpectrumTexture> {
|
|
let one = Spectrum::Constant(ConstantSpectrum::new(1.0));
|
|
let tex = parameters
|
|
.get_spectrum_texture("tex", Some(one), spectrum_type)
|
|
.ok_or_else(|| anyhow::anyhow!("{}: missing \"tex\" parameter", _loc))?;
|
|
let scale = parameters.get_float_texture("scale", 1.0)?;
|
|
|
|
if let FloatTexture::Constant(ref cscale) = *scale {
|
|
let cs = cscale.value;
|
|
if cs == 1.0 {
|
|
return Ok((*tex).clone());
|
|
}
|
|
if let SpectrumTexture::Image(ref image) = *tex {
|
|
let mut image_copy = image.clone();
|
|
image_copy.base.multiply_scale(cs);
|
|
return Ok(SpectrumTexture::Image(image_copy));
|
|
}
|
|
}
|
|
|
|
Ok(SpectrumTexture::Scaled(SpectrumScaledTexture {
|
|
tex,
|
|
scale,
|
|
}))
|
|
}
|
|
}
|
|
|
|
impl SpectrumTextureTrait for SpectrumScaledTexture {
|
|
fn evaluate(&self, ctx: &TextureEvalContext, lambda: &SampledWavelengths) -> SampledSpectrum {
|
|
let sc = self.scale.evaluate(ctx);
|
|
if sc == 0. {
|
|
return SampledSpectrum::new(0.);
|
|
}
|
|
self.tex.evaluate(ctx, lambda) * sc
|
|
}
|
|
}
|