123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- #pragma once
- #include <Mathematics/BasisFunction.h>
- #include <Mathematics/ParametricCurve.h>
- namespace WwiseGTE
- {
- template <int N, typename Real>
- class NURBSCurve : public ParametricCurve<N, Real>
- {
- public:
-
-
-
-
-
-
- NURBSCurve(BasisFunctionInput<Real> const& input,
- Vector<N, Real> const* controls, Real const* weights)
- :
- ParametricCurve<N, Real>((Real)0, (Real)1),
- mBasisFunction(input)
- {
-
-
- this->mTime.front() = mBasisFunction.GetMinDomain();
- this->mTime.back() = mBasisFunction.GetMaxDomain();
-
-
- mControls.resize(input.numControls);
- mWeights.resize(input.numControls);
- if (controls)
- {
- std::copy(controls, controls + input.numControls, mControls.begin());
- }
- else
- {
- Vector<N, Real> zero{ (Real)0 };
- std::fill(mControls.begin(), mControls.end(), zero);
- }
- if (weights)
- {
- std::copy(weights, weights + input.numControls, mWeights.begin());
- }
- else
- {
- std::fill(mWeights.begin(), mWeights.end(), (Real)0);
- }
- this->mConstructed = true;
- }
-
- inline BasisFunction<Real> const& GetBasisFunction() const
- {
- return mBasisFunction;
- }
- inline int GetNumControls() const
- {
- return static_cast<int>(mControls.size());
- }
- inline Vector<N, Real> const* GetControls() const
- {
- return mControls.data();
- }
- inline Vector<N, Real>* GetControls()
- {
- return mControls.data();
- }
- inline Real const* GetWeights() const
- {
- return mWeights.data();
- }
- inline Real* GetWeights()
- {
- return mWeights.data();
- }
- void SetControl(int i, Vector<N, Real> const& control)
- {
- if (0 <= i && i < GetNumControls())
- {
- mControls[i] = control;
- }
- }
- Vector<N, Real> const& GetControl(int i) const
- {
- if (0 <= i && i < GetNumControls())
- {
- return mControls[i];
- }
- else
- {
-
- return mControls[0];
- }
- }
- void SetWeight(int i, Real weight)
- {
- if (0 <= i && i < GetNumControls())
- {
- mWeights[i] = weight;
- }
- }
- Real const& GetWeight(int i) const
- {
- if (0 <= i && i < GetNumControls())
- {
- return mWeights[i];
- }
- else
- {
-
- return mWeights[0];
- }
- }
-
-
-
-
-
-
-
- virtual void Evaluate(Real t, unsigned int order, Vector<N, Real>* jet) const override
- {
- unsigned int const supOrder = ParametricCurve<N, Real>::SUP_ORDER;
- if (!this->mConstructed || order >= supOrder)
- {
-
- for (unsigned int i = 0; i < supOrder; ++i)
- {
- jet[i].MakeZero();
- }
- return;
- }
- int imin, imax;
- mBasisFunction.Evaluate(t, order, imin, imax);
-
- Vector<N, Real> X;
- Real w;
- Compute(0, imin, imax, X, w);
- Real invW = (Real)1 / w;
- jet[0] = invW * X;
- if (order >= 1)
- {
-
- Vector<N, Real> XDer1;
- Real wDer1;
- Compute(1, imin, imax, XDer1, wDer1);
- jet[1] = invW * (XDer1 - wDer1 * jet[0]);
- if (order >= 2)
- {
-
- Vector<N, Real> XDer2;
- Real wDer2;
- Compute(2, imin, imax, XDer2, wDer2);
- jet[2] = invW * (XDer2 - (Real)2 * wDer1 * jet[1] - wDer2 * jet[0]);
- if (order == 3)
- {
-
- Vector<N, Real> XDer3;
- Real wDer3;
- Compute(3, imin, imax, XDer3, wDer3);
- jet[3] = invW * (XDer3 - (Real)3 * wDer1 * jet[2] -
- (Real)3 * wDer2 * jet[1] - wDer3 * jet[0]);
- }
- }
- }
- }
- protected:
-
- void Compute(unsigned int order, int imin, int imax, Vector<N, Real>& X, Real& w) const
- {
-
-
-
- int numControls = GetNumControls();
- X.MakeZero();
- w = (Real)0;
- for (int i = imin; i <= imax; ++i)
- {
- int j = (i >= numControls ? i - numControls : i);
- Real tmp = mBasisFunction.GetValue(order, i) * mWeights[j];
- X += tmp * mControls[j];
- w += tmp;
- }
- }
- BasisFunction<Real> mBasisFunction;
- std::vector<Vector<N, Real>> mControls;
- std::vector<Real> mWeights;
- };
- }
|