HDK
|
#include "pxr/pxr.h"
#include "pxr/base/arch/math.h"
#include "pxr/base/gf/api.h"
#include "pxr/base/gf/traits.h"
#include <type_traits>
Go to the source code of this file.
Functions | |
PXR_NAMESPACE_OPEN_SCOPE bool | GfIsClose (double a, double b, double epsilon) |
double | GfRadiansToDegrees (double radians) |
double | GfDegreesToRadians (double degrees) |
GF_API double | GfSmoothStep (double min, double max, double val, double slope0=0.0, double slope1=0.0) |
GF_API double | GfSmoothRamp (double tmin, double tmax, double t, double w0, double w1) |
template<class T > | |
double | GfSqr (const T &x) |
template<typename T > | |
T | GfSgn (T v) |
double | GfSqrt (double f) |
float | GfSqrt (float f) |
double | GfExp (double f) |
float | GfExp (float f) |
double | GfLog (double f) |
float | GfLog (float f) |
double | GfFloor (double f) |
float | GfFloor (float f) |
double | GfCeil (double f) |
float | GfCeil (float f) |
double | GfAbs (double f) |
float | GfAbs (float f) |
double | GfRound (double f) |
float | GfRound (float f) |
double | GfPow (double f, double p) |
float | GfPow (float f, float p) |
double | GfSin (double v) |
float | GfSin (float v) |
double | GfCos (double v) |
float | GfCos (float v) |
void | GfSinCos (double v, double *s, double *c) |
void | GfSinCos (float v, float *s, float *c) |
double | GfClamp (double value, double min, double max) |
float | GfClamp (float value, float min, float max) |
GF_API double | GfMod (double a, double b) |
GF_API float | GfMod (float a, float b) |
template<class T > | |
T | GfLerp (double alpha, const T &a, const T &b) |
template<class T > | |
T | GfMin (T a1, T a2) |
template<class T > | |
T | GfMin (T a1, T a2, T a3) |
template<class T > | |
T | GfMin (T a1, T a2, T a3, T a4) |
template<class T > | |
T | GfMin (T a1, T a2, T a3, T a4, T a5) |
template<class T > | |
T | GfMax (T a1, T a2) |
template<class T > | |
T | GfMax (T a1, T a2, T a3) |
template<class T > | |
T | GfMax (T a1, T a2, T a3, T a4) |
template<class T > | |
T | GfMax (T a1, T a2, T a3, T a4, T a5) |
template<typename Left , typename Right , std::enable_if_t< GfIsArithmetic< Left >::value &&GfIsArithmetic< Right >::value, int > = 0> | |
decltype(std::declval< Left > ()*std::declval< Right >()) | GfDot (Left left, Right right) |
template<typename Left , typename Right , std::enable_if_t< GfIsArithmetic< Left >::value &&GfIsArithmetic< Right >::value, int > = 0> | |
decltype(std::declval< Left > ()*std::declval< Right >()) | GfCompMult (Left left, Right right) |
template<typename Left , typename Right , std::enable_if_t< GfIsArithmetic< Left >::value &&GfIsArithmetic< Right >::value, int > = 0> | |
decltype(std::declval< Left > ()/std::declval< Right >()) | GfCompDiv (Left left, Right right) |
Assorted mathematical utility functions.
Definition in file math.h.
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
GF_API double GfMod | ( | double | a, |
double | b | ||
) |
The mod function with "correct" behaviour for negative numbers.
If a
= n
b
for some integer n
, zero is returned. Otherwise, for positive a
, the value returned is fmod(a,b)
, and for negative a
, the value returned is fmod(a,b)+b
.
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
|
inline |
|
inline |
|
inline |
GF_API double GfSmoothRamp | ( | double | tmin, |
double | tmax, | ||
double | t, | ||
double | w0, | ||
double | w1 | ||
) |
Smooth Step with independently controllable shoulders
Based on an idea and different implementation by Rob Cook. See his notes attached at the end.
I (whorfin) extended this to have independently controllable shoulders at either end, and to specify shoulders directly in the domain of the curve. Rob's derivation frankly confused me, so I proceeded slightly differently. This derivation has more degrees of freedom but is the same order, so some tricks must be done.
Summary: This function is similar to "smoothstep" except that instead of using a Hermite curve, the interpolation is done with a linear ramp with smooth shoulders (i.e., C1 = continuous first derivatives).
Conceptually, it's a line with variable C1 zero-slope junctures.
Additionally, w0 + w1 <= 1. Otherwise, the curves will take up more space than is available, and "that would be bad". A value of 0 for w0 and w1 gives a pure linear ramp. A reasonable value for a symmetric smooth ramp is .2 for w0 and w1. this means that the middle 60% of the ramp is linear, and the left 20% and right 20% are the transition into and out of the linear ramp.
The ramp looks like this:
smooth ********** <-result = 1 ***| ** | * | | linear * | | * | | * | | smooth ** | tmax = end of ramp *** | | result=0 -> ******* | tmax - w1*(tmax-tmin) = end of linear region | | | tmin + w0*(tmax-tmin) = start of linear region | tmin = start of ramp
Derivation:
We're going to splice parabolas onto both ends for the "0 slope smooth" connectors. So we therefore constrain the parabolic sections to have a given width and given slope (the slope of the connecting line segment) at the "w" edge.
We'll first derive the equations for the parabolic splicing segment, expressed at the origin (but generalizable by flipping).
Given:
f(t) = a t� + b t + c f(0) = 0 f'(0) = 0 f(w) = y At the "w" edge of the shoulder, value is y f'(w) = s ...what is the slope there? s...
--> c = 0 b = 0 a = � s/w y = � w s --> g(t,w,s) = � s t� / w # Our parabolic segment
Now, in our desired composite curve, the slope is the same at both endpoints (since they're connected by a line). This slope is (1-y0-y1)/(1-w0-w1) [from simple geometry].
More formally, let's express the constraints Given:
y(w,s) = w s /2 s = ( 1 - y(w0, s) - y(w1, s) ) / (1 - w0 - w1)
--> s(w0,w1) = 2 / (2 - w0 - w1)
So now we're done; we splice these two together and connect with a line.
The domain and range of this function is [0,1]
f(t, w0, w1) = g(t, w0, s(w0,w1)) t<w0
1-g(1-t, w1, s(w0,w1)) t>1-w1
s(w0,w1) t - y(w0, s(w0,w1)) w0 <= t <= 1-w1
Expanding and collecting terms gives us the result expressed in the code below. We also generalize to tmin/tmax form, in keeping with smoothstep. This simply involves reranging to [0,1] on input.
tmin | where the ramp starts |
tmax | where the ramp ends (must be > tmin) |
t | location to evaluate in this call |
w0 | size of the first smooth section as a fraction of the size of the ramp (tmax-tmin). This value must be in the range 0-1. |
w1 | size of the second smooth section as a fraction of the size of the ramp (tmax-tmin). This value must be in the range 0-1. |
GF_API double GfSmoothStep | ( | double | min, |
double | max, | ||
double | val, | ||
double | slope0 = 0.0 , |
||
double | slope1 = 0.0 |
||
) |
Smooth step function using a cubic hermite blend.
Returns 0 if val
<= min
, and 1 if val
>= max
. As val
varies between min
and max
, the return value smoothly varies from 0 to 1 using a cubic hermite blend, with given slopes at the min and max points. The slopes are in the space that min and max are in.
|
inline |