123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- #pragma once
- #include <Mathematics/BasisFunction.h>
- #include <Mathematics/Vector.h>
- namespace WwiseGTE
- {
- template <int N, typename Real>
- class BSplineVolume
- {
- public:
-
-
-
-
-
-
-
- BSplineVolume(BasisFunctionInput<Real> const input[3], Vector<N, Real> const* controls)
- :
- mConstructed(false)
- {
- for (int i = 0; i < 3; ++i)
- {
- mNumControls[i] = input[i].numControls;
- mBasisFunction[i].Create(input[i]);
- }
-
-
- int numControls = mNumControls[0] * mNumControls[1] * mNumControls[2];
- mControls.resize(numControls);
- if (controls)
- {
- std::copy(controls, controls + numControls, mControls.begin());
- }
- else
- {
- Vector<N, Real> zero{ (Real)0 };
- std::fill(mControls.begin(), mControls.end(), zero);
- }
- mConstructed = true;
- }
-
-
-
- inline operator bool() const
- {
- return mConstructed;
- }
-
- inline BasisFunction<Real> const& GetBasisFunction(int dim) const
- {
- return mBasisFunction[dim];
- }
- inline Real GetMinDomain(int dim) const
- {
- return mBasisFunction[dim].GetMinDomain();
- }
- inline Real GetMaxDomain(int dim) const
- {
- return mBasisFunction[dim].GetMaxDomain();
- }
- inline int GetNumControls(int dim) const
- {
- return mNumControls[dim];
- }
- inline Vector<N, Real> const* GetControls() const
- {
- return mControls.data();
- }
- inline Vector<N, Real>* GetControls()
- {
- return mControls.data();
- }
- void SetControl(int i0, int i1, int i2, Vector<N, Real> const& control)
- {
- if (0 <= i0 && i0 < GetNumControls(0)
- && 0 <= i1 && i1 < GetNumControls(1)
- && 0 <= i2 && i2 < GetNumControls(2))
- {
- mControls[i0 + mNumControls[0] * (i1 + mNumControls[1] * i2)] = control;
- }
- }
- Vector<N, Real> const& GetControl(int i0, int i1, int i2) const
- {
- if (0 <= i0 && i0 < GetNumControls(0)
- && 0 <= i1 && i1 < GetNumControls(1)
- && 0 <= i2 && i2 < GetNumControls(2))
- {
- return mControls[i0 + mNumControls[0] * (i1 + mNumControls[1] * i2)];
- }
- else
- {
- return mControls[0];
- }
- }
-
-
-
-
-
-
-
-
-
- enum { SUP_ORDER = 10 };
- void Evaluate(Real u, Real v, Real w, unsigned int order, Vector<N, Real>* jet) const
- {
- if (!mConstructed || order >= SUP_ORDER)
- {
-
- for (unsigned int i = 0; i < SUP_ORDER; ++i)
- {
- jet[i].MakeZero();
- }
- return;
- }
- int iumin, iumax, ivmin, ivmax, iwmin, iwmax;
- mBasisFunction[0].Evaluate(u, order, iumin, iumax);
- mBasisFunction[1].Evaluate(v, order, ivmin, ivmax);
- mBasisFunction[2].Evaluate(w, order, iwmin, iwmax);
-
- jet[0] = Compute(0, 0, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
- if (order >= 1)
- {
-
- jet[1] = Compute(1, 0, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
- jet[2] = Compute(0, 1, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
- jet[3] = Compute(0, 0, 1, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
- if (order >= 2)
- {
-
- jet[4] = Compute(2, 0, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
- jet[5] = Compute(0, 2, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
- jet[6] = Compute(0, 0, 2, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
- jet[7] = Compute(1, 1, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
- jet[8] = Compute(1, 0, 1, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
- jet[9] = Compute(0, 1, 1, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
- }
- }
- }
- private:
-
- Vector<N, Real> Compute(unsigned int uOrder, unsigned int vOrder,
- unsigned int wOrder, int iumin, int iumax, int ivmin, int ivmax,
- int iwmin, int iwmax) const
- {
-
-
-
- int const numControls0 = mNumControls[0];
- int const numControls1 = mNumControls[1];
- int const numControls2 = mNumControls[2];
- Vector<N, Real> result;
- result.MakeZero();
- for (int iw = iwmin; iw <= iwmax; ++iw)
- {
- Real tmpw = mBasisFunction[2].GetValue(wOrder, iw);
- int jw = (iw >= numControls2 ? iw - numControls2 : iw);
- for (int iv = ivmin; iv <= ivmax; ++iv)
- {
- Real tmpv = mBasisFunction[1].GetValue(vOrder, iv);
- Real tmpvw = tmpv * tmpw;
- int jv = (iv >= numControls1 ? iv - numControls1 : iv);
- for (int iu = iumin; iu <= iumax; ++iu)
- {
- Real tmpu = mBasisFunction[0].GetValue(uOrder, iu);
- int ju = (iu >= numControls0 ? iu - numControls0 : iu);
- result += (tmpu * tmpvw) *
- mControls[ju + numControls0 * (jv + numControls1 * jw)];
- }
- }
- }
- return result;
- }
- std::array<BasisFunction<Real>, 3> mBasisFunction;
- std::array<int, 3> mNumControls;
- std::vector<Vector<N, Real>> mControls;
- bool mConstructed;
- };
- }
|