diff --git a/luisa_compute/src/lang/types/core.rs b/luisa_compute/src/lang/types/core.rs index 38df683..a4ecc73 100644 --- a/luisa_compute/src/lang/types/core.rs +++ b/luisa_compute/src/lang/types/core.rs @@ -1,3 +1,5 @@ +use std::ops::Neg; + use crate::lang::soa::SoaBuffer; use super::*; @@ -496,5 +498,5 @@ impls!(Numeric for f16, f32, f64, i8, i16, i32, i64, u8, u16, u32, u64); pub trait Floating: Numeric {} impls!(Floating for f16, f32, f64); -pub trait Signed: Numeric {} +pub trait Signed: Numeric + Neg {} impls!(Signed for f16, f32, f64, i8, i16, i32, i64); diff --git a/luisa_compute/src/lang/types/vector/impls.rs b/luisa_compute/src/lang/types/vector/impls.rs index 7d43b80..93dac79 100644 --- a/luisa_compute/src/lang/types/vector/impls.rs +++ b/luisa_compute/src/lang/types/vector/impls.rs @@ -1,6 +1,6 @@ use super::*; use crate::lang::index::IntoIndex; -use std::ops::Index; +use std::ops::{Index, Neg}; impl, const N: usize> From<[T; N]> for Vector { fn from(elements: [T; N]) -> Self { @@ -115,6 +115,98 @@ impl_sized!(Vec2(2), VectorExprProxy2, VectorVarProxy2: x, y); impl_sized!(Vec3(3), VectorExprProxy3, VectorVarProxy3: x, y, z); impl_sized!(Vec4(4), VectorExprProxy4, VectorVarProxy4: x, y, z, w); +pub trait ZeroOne { + fn zero() -> Self; + fn one() -> Self; +} +impl ZeroOne for bool { + fn zero() -> Self { + false + } + fn one() -> Self { + true + } +} +macro_rules! zero_one { + ($($t:ty),*) => { + $( + impl ZeroOne for $t { + fn zero() -> Self { + 0 + } + fn one() -> Self { + 1 + } + } + )* + } +} +zero_one!(u8, u16, u32, u64, i8, i16, i32, i64); +impl ZeroOne for f16 { + fn zero() -> Self { + f16::ZERO + } + fn one() -> Self { + f16::ONE + } +} +impl ZeroOne for f32 { + fn zero() -> Self { + 0.0 + } + fn one() -> Self { + 1.0 + } +} +impl ZeroOne for f64 { + fn zero() -> Self { + 0.0 + } + fn one() -> Self { + 1.0 + } +} + +impl> Vector { + pub fn x() -> Self { + Self::new(T::one(), T::zero()) + } + pub fn y() -> Self { + Self::new(T::zero(), T::one()) + } +} +impl> Vector { + pub fn x() -> Self { + Self::new(T::one(), T::zero(), T::zero()) + } + pub fn y() -> Self { + Self::new(T::zero(), T::one(), T::zero()) + } + pub fn z() -> Self { + Self::new(T::zero(), T::zero(), T::one()) + } +} +impl> Vector { + pub fn x() -> Self { + Self::new(T::one(), T::zero(), T::zero(), T::zero()) + } + pub fn y() -> Self { + Self::new(T::zero(), T::one(), T::zero(), T::zero()) + } + pub fn z() -> Self { + Self::new(T::zero(), T::zero(), T::one(), T::zero()) + } + pub fn w() -> Self { + Self::new(T::zero(), T::zero(), T::zero(), T::one()) + } +} +impl + VectorAlign, const N: usize> Neg for Vector { + type Output = Self; + fn neg(self) -> Self { + Self::from(self.elements.map(|x| -x)) + } +} + pub trait VectorExprProxy { const N: usize; type T: Primitive; diff --git a/luisa_compute_derive_impl/src/lib.rs b/luisa_compute_derive_impl/src/lib.rs index 0ea5699..d6b9c17 100644 --- a/luisa_compute_derive_impl/src/lib.rs +++ b/luisa_compute_derive_impl/src/lib.rs @@ -395,6 +395,7 @@ impl Compiler { let crate_path = &self.crate_path; let lang_path = self.lang_path(); let name = &enum_.ident; + let vis = &enum_.vis; let expr_proxy_name = syn::Ident::new(&format!("{}Expr", name), name.span()); let var_proxy_name = syn::Ident::new(&format!("{}Var", name), name.span()); let atomic_ref_proxy_name = syn::Ident::new(&format!("{}AtomicRef", name), name.span()); @@ -426,21 +427,21 @@ impl Compiler { #crate_path::impl_simple_atomic_ref_proxy!(#atomic_ref_proxy_name for #name); impl #expr_proxy_name { - pub fn #as_repr(&self) -> #lang_path::types::Expr<#repr> { + #vis fn #as_repr(&self) -> #lang_path::types::Expr<#repr> { use #lang_path::ToNode; use #lang_path::types::ExprProxy; #lang_path::FromNode::from_node(self.as_expr_from_proxy().node()) } } impl #var_proxy_name { - pub fn #as_repr(&self) -> #lang_path::types::Var<#repr> { + #vis fn #as_repr(&self) -> #lang_path::types::Var<#repr> { use #lang_path::ToNode; use #lang_path::types::VarProxy; #lang_path::FromNode::from_node(self.as_var_from_proxy().node()) } } impl #atomic_ref_proxy_name { - pub fn #as_repr(&self) -> #lang_path::types::AtomicRef<#repr> { + #vis fn #as_repr(&self) -> #lang_path::types::AtomicRef<#repr> { use #lang_path::ToNode; use #lang_path::types::AtomicRefProxy; #lang_path::FromNode::from_node(self.as_atomic_ref_from_proxy().node())