diff --git a/naga/src/proc/constant_evaluator.rs b/naga/src/proc/constant_evaluator.rs index 1cffb043a..afb332a95 100644 --- a/naga/src/proc/constant_evaluator.rs +++ b/naga/src/proc/constant_evaluator.rs @@ -1572,6 +1572,57 @@ impl<'a> ConstantEvaluator<'a> { Err(ConstantEvaluatorError::InvalidMathArg) } } + crate::MathFunction::Length => { + let e1 = LiteralVector::from_expr(arg, self, span, true)?; + + fn float_length(e: ArrayVec) -> F + where + F: std::ops::Mul, + F: num_traits::Float + std::iter::Sum, + { + e.iter().map(|&ei| ei * ei).sum::().sqrt() + } + + LiteralVector::from_literal(match e1 { + LiteralVector::AbstractFloat(a) => Literal::AbstractFloat(float_length(a)), + LiteralVector::F32(a) => Literal::F32(float_length(a)), + _ => return Err(ConstantEvaluatorError::InvalidMathArg), + }) + .handle(self, span) + } + crate::MathFunction::Distance => { + let e1 = LiteralVector::from_expr(arg, self, span, true)?; + let e2 = LiteralVector::from_expr(arg1.unwrap(), self, span, true)?; + if e1.len() != e2.len() { + return Err(ConstantEvaluatorError::InvalidMathArg); + } + + fn float_distance( + a: ArrayVec, + b: ArrayVec, + ) -> F + where + F: std::ops::Mul, + F: num_traits::Float + std::iter::Sum + std::ops::Sub, + { + a.iter() + .zip(b.iter()) + .map(|(&aa, &bb)| aa - bb) + .map(|ei| ei * ei) + .sum::() + .sqrt() + } + LiteralVector::from_literal(match (e1, e2) { + (LiteralVector::AbstractFloat(a), LiteralVector::AbstractFloat(b)) => { + Literal::AbstractFloat(float_distance(a, b)) + } + (LiteralVector::F32(a), LiteralVector::F32(b)) => { + Literal::F32(float_distance(a, b)) + } + _ => return Err(ConstantEvaluatorError::InvalidMathArg), + }) + .handle(self, span) + } // computational crate::MathFunction::Sign => { component_wise_signed!(self, span, [arg], |e| { Ok([e.signum()]) })