Photon Engine 2.0.0-beta
A physically based renderer.
|
Miscellaneous math utilities. More...
#include "Math/constant.h"
#include "Math/math_fwd.h"
#include "Math/math_table.h"
#include "Utility/utility.h"
#include "Utility/traits.h"
#include "Utility/TSpan.h"
#include <Common/assertion.h>
#include <Common/primitive_type.h>
#include <Common/compiler.h>
#include <Common/math_basics.h>
#include <Common/utility.h>
#include <cmath>
#include <algorithm>
#include <numeric>
#include <type_traits>
#include <utility>
#include <limits>
#include <array>
#include <vector>
#include <cstdint>
#include <climits>
#include <bit>
#include <concepts>
#include "Math/math.ipp"
Go to the source code of this file.
Namespaces | |
namespace | ph |
The root for all renderer implementations. | |
namespace | ph::math |
Math functions and utilities. | |
Functions | |
template<typename T > | |
auto | ph::math::matrix2x2 (const T e00, const T e01, const T e10, const T e11) -> std::array< std::array< T, 2 >, 2 > |
template<typename T > | |
T | ph::math::squared (const T value) |
void | ph::math::form_orthonormal_basis_frisvad (const Vector3R &unitYaxis, Vector3R *const out_unitXaxis, Vector3R *const out_unitZaxis) |
template<typename T > | |
T | ph::math::clamp (const T value, const T lowerBound, const T upperBound) |
Clamps a value to [lowerBound, upperBound]. None of value , lowerBound and upperBound can be NaN, or the method's behavior is undefined. | |
template<typename T > | |
T | ph::math::safe_clamp (const T value, const T lowerBound, const T upperBound) |
Clamps a value to [lowerBound, upperBound], fallback to lowerBound . If a floating-point value is non-finite (e.g., being Inf, NaN), its value is clamped to lowerBound . Neither lowerBound nor upperBound can be NaN, or the method's behavior is undefined. | |
template<typename T > | |
T | ph::math::safe_rcp (const T value) |
Calculates the reciprocal of a value, fallback to 0. If the resulting reciprocal is non-finite (e.g., being Inf, NaN), 0 will be returned instead. | |
template<typename T > | |
T | ph::math::to_degrees (const T radians) |
Convert radians to degrees. | |
template<typename T > | |
T | ph::math::to_radians (const T degrees) |
Convert degrees to radians. | |
template<typename T > | |
int | ph::math::sign (const T value) |
Extract the sign of value . | |
uint32 | ph::math::next_power_of_2 (uint32 value) |
Gets the minimum power of 2 value that is >= value . | |
template<typename T > | |
T | ph::math::log2_floor (const T value) |
Calculate a positive number's base 2 logarithm (floored). | |
template<typename T , std::enable_if_t< std::is_floating_point_v< T >, int > = 0> | |
T | ph::math::fractional_part (const T value) |
Retrieve the fractional part of value (with the sign unchanged). The result is not guaranteed to be the same as the bit representation of 's fractional part. The result is undefined if input value is NaN or +-Inf. | |
template<typename T , std::enable_if_t< std::is_integral_v< T >, int > = 0> | |
T | ph::math::wrap (T value, const T lowerBound, const T upperBound) |
Wraps an integer around [lower-bound, upper-bound]. For example, given a bound [-1, 2], 3 will be wrapped to -1. | |
template<typename T > | |
bool | ph::math::is_even (const T value) |
Checks if a number is even. | |
template<typename T > | |
bool | ph::math::is_odd (const T value) |
Checks if a number is odd. | |
bool | ph::math::is_same_hemisphere (const Vector3R &vector, const Vector3R &N) |
Checks whether the specified vector is within the hemisphere defined by the normal vector N . N points to the hemisphere's peak, i.e., theta = 0 in spherical coordinates. | |
bool | ph::math::is_opposite_hemisphere (const Vector3R &vector, const Vector3R &N) |
Checks whether the specified vector is within the hemisphere defined by the normal vector -N . N points to the hemisphere's peak, i.e., theta = 0 in spherical coordinates. | |
template<typename NumberType > | |
constexpr NumberType | ph::math::bytes_to_KiB (const std::size_t numBytes) |
template<typename NumberType > | |
constexpr NumberType | ph::math::bytes_to_MiB (const std::size_t numBytes) |
template<typename NumberType > | |
constexpr NumberType | ph::math::bytes_to_GiB (const std::size_t numBytes) |
template<typename NumberType > | |
constexpr NumberType | ph::math::bytes_to_TiB (const std::size_t numBytes) |
template<typename NumberType > | |
constexpr NumberType | ph::math::bytes_to_PiB (const std::size_t numBytes) |
std::pair< std::size_t, std::size_t > | ph::math::ith_evenly_divided_range (const std::size_t rangeIndex, const std::size_t totalSize, const std::size_t numDivisions) |
Gets the i-th evenly divided range. | |
float | ph::math::fast_rcp_sqrt (float x) |
Computes 1/sqrt(x) in a fast but approximative way. | |
float | ph::math::fast_sqrt (const float x) |
Computes sqrt(x) in a fast but approximative way. | |
template<typename T , typename = std::enable_if_t<std::is_integral_v<T>>> | |
T | ph::math::reverse_bits (const T value) |
Get an integral value with reversed bits. | |
template<std::unsigned_integral UIntType, std::integral RangeType> | |
UIntType | ph::math::set_bits_in_range (const UIntType bits, const RangeType beginBitIdx, const RangeType endBitIdx) |
Set bits in the range to 1. The bits in [beginBitIdx, endBitIdx) will be set to 1, while the rest remain the same. LSB has the bit index 0. | |
template<std::unsigned_integral UIntType, std::integral RangeType> | |
UIntType | ph::math::clear_bits_in_range (const UIntType bits, const RangeType beginBitIdx, const RangeType endBitIdx) |
Set bits in the range to 0. The bits in [beginBitIdx, endBitIdx) will be set to 0, while the rest remain the same. LSB has the bit index 0. | |
template<typename T , T MIN, T MAX, std::size_t N> | |
std::array< T, N > | ph::math::evenly_spaced_array () |
template<typename T > | |
std::vector< T > | ph::math::evenly_spaced_vector (const T min, const T max, const std::size_t n) |
template<std::floating_point FloatType, std::integral IntType> | |
FloatType | ph::math::normalize_integer (const IntType intVal) |
Transform an integer to the range [0, 1] ([-1, 1] for signed integer). When transforming an unsigned integer, the minimum value the integer can hold will be mapped to 0, while the maximum value will be mapped to 1; the rest of the integer values will be uniformally mapped to the range [0, 1]. Signed integer types follow the same rule, except the mapped range will be [-1, 1]. | |
template<std::integral IntType, std::floating_point FloatType> | |
IntType | ph::math::quantize_normalized_float (const FloatType floatVal) |
void | ph::math::uint64_mul (const uint64 lhs, const uint64 rhs, uint64 &out_high64, uint64 &out_low64) |
Multiply two unsigined 64-bit numbers and get a 128-bit result. | |
template<typename T , std::size_t N> | |
T | ph::math::summation (const std::array< T, N > &values, T initialValue=0) |
Sum all values within a container together. | |
template<typename T > | |
T | ph::math::summation (const std::vector< T > &values, T initialValue=0) |
template<typename T , std::size_t EXTENT = std::dynamic_extent> | |
T | ph::math::summation (TSpanView< T, EXTENT > values, T initialValue=0) |
template<typename T , std::size_t N> | |
T | ph::math::product (const std::array< T, N > &values, T initialValue=1) |
Multiplies all values within a container together. | |
template<typename T > | |
T | ph::math::product (const std::vector< T > &values, T initialValue=1) |
template<typename T , std::size_t EXTENT = std::dynamic_extent> | |
T | ph::math::product (TSpanView< T, EXTENT > values, T initialValue=1) |
template<std::unsigned_integral UIntType> | |
UIntType | ph::math::flag_bit (const UIntType bitIdx) |
Set a single bit to 1, others remain 0. LSB has the bit index 0. | |
template<std::unsigned_integral UIntType, UIntType BIT_IDX> | |
consteval UIntType | ph::math::flag_bit () |
uint16 | ph::math::fp32_to_fp16_bits (const float32 value) |
Convert a 32-bit float to 16-bit representation. | |
float32 | ph::math::fp16_bits_to_fp32 (const uint16 fp16Bits) |
Convert a 16-bit representation back to 32-bit float. | |
template<typename T , std::size_t N> | |
T | ph::math::length (const std::array< T, N > &vec) |
Treating input values as a vector and calculates its length. | |
template<typename T > | |
T | ph::math::length (const std::vector< T > &vec) |
template<typename T , std::size_t EXTENT = std::dynamic_extent> | |
T | ph::math::length (TSpanView< T, EXTENT > vec) |
template<typename T , std::size_t N> | |
T | ph::math::length_squared (const std::array< T, N > &vec) |
Treating input values as a vector and calculates its squared length. | |
template<typename T > | |
T | ph::math::length_squared (const std::vector< T > &vec) |
template<typename T , std::size_t EXTENT = std::dynamic_extent> | |
T | ph::math::length_squared (TSpanView< T, EXTENT > vec) |
template<typename T , std::size_t N> | |
T | ph::math::p_norm (const std::array< T, N > &vec) |
Treating input values as a vector and calculates its p-norm. | |
template<typename T > | |
T | ph::math::p_norm (const std::vector< T > &vec) |
template<std::size_t P, typename T , std::size_t EXTENT = std::dynamic_extent> | |
T | ph::math::p_norm (TSpanView< T, EXTENT > vec) |
template<typename T , std::size_t N> | |
void | ph::math::normalize (std::array< T, N > &vec) |
Treating input values as a vector and normalize it. Notice that normalizing a integer typed vector will result in 0-vector most of the time. | |
template<typename T > | |
void | ph::math::normalize (std::vector< T > &vec) |
template<typename T , std::size_t EXTENT = std::dynamic_extent> | |
void | ph::math::normalize (TSpan< T, EXTENT > vec) |
template<typename T , std::size_t N> | |
T | ph::math::dot_product (const std::array< T, N > &vecA, const std::array< T, N > &vecB) |
Treating input values as vectors and calculates their dot product. | |
template<typename T > | |
T | ph::math::dot_product (const std::vector< T > &vecA, const std::vector< T > &vecB) |
template<typename T , std::size_t EXTENT = std::dynamic_extent> | |
T | ph::math::dot_product (TSpanView< T, EXTENT > vecA, TSpanView< T, EXTENT > vecB) |
Miscellaneous math utilities.
If the standard library has the same/similar math utility defined, prefer the implementation here since most of them is developed with performance regarding to rendering in mind.