Computations.h tdm/Types.h tdm/Mat.h tdm/Vec.h cmath utility TDM.h Transforms.h tdm tdm::impl //CopyrightEpicGames,Inc.AllRightsReserved. #pragmaonce #include"tdm/Types.h" #include"tdm/Mat.h" #include"tdm/Vec.h" #ifdef_MSC_VER #pragmawarning(push) #pragmawarning(disable:43654987) #endif #include<cmath> #include<utility> #ifdef_MSC_VER #pragmawarning(pop) #endif namespacetdm{ template<typenameT> inlinevec3<T>cross(constvec3<T>&lhs,constvec3<T>&rhs){ returnvec3<T>{ lhs[1]*rhs[2]-lhs[2]*rhs[1], lhs[2]*rhs[0]-lhs[0]*rhs[2], lhs[0]*rhs[1]-lhs[1]*rhs[0] }; } template<dim_tL,typenameT> inlineTdot(constvec<L, T>&lhs,constvec<L, T>&rhs){ return(lhs*rhs).sum(); } template<dim_tL,typenameT> inlinevec<L, T>negate(vec<L, T>v){ returnv.negate(); } template<dim_tR,dim_tC,typenameT> inlinemat<R, C, T>negate(constmat<R, C, T>&m){ returnm.negate(); } template<dim_tL,typenameT> inlinetypenamestd::enable_if<std::is_floating_point<T>::value,T>::typelength(constvec<L, T>&v){ returnv.length(); } template<dim_tL,typenameT> inlinetypenamestd::enable_if<std::is_floating_point<T>::value,vec<L, T>>::typenormalize(vec<L, T>v){ v.normalize(); returnv; } template<dim_tR,dim_tC,typenameT> inlinemat<C, R, T>transpose(constmat<R, C, T>&m){ usingrow_type=typenamemat<C, R, T>::row_type; mat<C, R, T>ret; ret.apply([&m](row_type&row,dim_ti){ row=m.column(i); }); returnret; } namespaceimpl{ #pragmapush_macro("minor") #undefminor template<dim_tN,typenameT> inlinevoidminor(constmat<N, N, T>&input,dim_tdimensions,dim_ti,dim_tj,mat<N, N, T>&output){ for(dim_toutRow{},inRow{};inRow<dimensions;++inRow){ for(dim_toutCol{},inCol{};inCol<dimensions;++inCol){ if((inRow!=i)&&(inCol!=j)){ output(outRow,outCol)=input(inRow,inCol); ++outCol; if(outCol==(dimensions-static_cast<dim_t>(1))){ outCol={}; ++outRow; } } } } } template<dim_tN,typenameT> inlineTdeterminant(constmat<N, N, T>&m,dim_tdimensions){ if(dimensions==static_cast<dim_t>(1)){ returnm(0,0); } Tresult{}; mat<N, N, T>temp; autosign=static_cast<T>(1); constdim_ti{}; for(dim_tj{};j<dimensions;++j){ minor(m,dimensions,i,j,temp); result+=(sign*m(i,j)*determinant(temp,dimensions-1)); sign=-sign; } returnresult; } template<dim_tN,typenameT> inlinemat<N, N, T>adjoint(constmat<N, N, T>&m){ if(m.rows()==static_cast<dim_t>(1)){ returnmat<N, N, T>{static_cast<T>(1)}; } mat<N, N, T>result; mat<N, N, T>temp; for(dim_trow{};row<m.rows();++row){ for(dim_tcol{};col<m.columns();++col){ minor(m,N,row,col,temp); constTsign=static_cast<T>((row+col)%2u==0u?1:-1); result(col,row)=(sign*determinant(temp,N-1)); } } returnresult; } #pragmapop_macro("minor") }//namespaceimpl template<dim_tN,typenameT> inlineTdeterminant(constmat<N, N, T>&m){ returnimpl::determinant(m,N); } template<dim_tN,typenameT> inlinemat<N, N, T>inverse(constmat<N, N, T>&m){ Tdet=determinant(m); if(det==T{}){ return{}; } mat<N, N, T>adj=impl::adjoint(m); mat<N, N, T>inv; for(dim_trow{};row<m.rows();++row){ for(dim_tcol{};col<m.columns();++col){ inv(row,col)=adj(row,col)/det; } } returninv; } template<dim_tN,typenameT> inlineTtrace(constmat<N, N, T>&m){ Ttrace{0}; for(dim_trow{};row<m.rows();++row){ trace+=m(row,row); } returntrace; } }//namespacetdm