NURBSSphere.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. // David Eberly, Geometric Tools, Redmond WA 98052
  2. // Copyright (c) 1998-2020
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  6. // Version: 4.0.2019.08.13
  7. #pragma once
  8. #include <Mathematics/NURBSSurface.h>
  9. #include <Mathematics/Vector3.h>
  10. #include <functional>
  11. // The algorithm for representing a circle as a NURBS curve or a sphere as a
  12. // NURBS surface is described in
  13. // https://www.geometrictools.com/Documentation/NURBSCircleSphere.pdf
  14. // The implementations are related to the documents as shown next.
  15. // NURBSEighthSphereDegree4 implements Section 3.1.2 (triangular domain)
  16. // NURBSHalfSphereDegree3 implements Section 3.2 (rectangular domain)
  17. // NURBSFullSphereDegree3 implements Section 2.3 (rectangular domain)
  18. // TODO: The class NURBSSurface currently assumes a rectangular domain.
  19. // Once support is added for triangular domains, make that new class a
  20. // base class of the sphere-representing NURBS. This will allow sharing
  21. // of the NURBS basis functions and evaluation framework.
  22. namespace WwiseGTE
  23. {
  24. template <typename Real>
  25. class NURBSEighthSphereDegree4
  26. {
  27. public:
  28. // Construction. The eigth sphere is x^2 + y^2 + z^2 = 1 for x >= 0,
  29. // y >= 0 and z >= 0.
  30. NURBSEighthSphereDegree4()
  31. {
  32. Real const sqrt2 = std::sqrt((Real)2);
  33. Real const sqrt3 = std::sqrt((Real)3);
  34. Real const a0 = (sqrt3 - (Real)1) / sqrt3;
  35. Real const a1 = (sqrt3 + (Real)1) / ((Real)2 * sqrt3);
  36. Real const a2 = (Real)1 - ((Real)5 - sqrt2) * ((Real)7 - sqrt3) / (Real)46;
  37. Real const b0 = (Real)4 * sqrt3 * (sqrt3 - (Real)1);
  38. Real const b1 = (Real)3 * sqrt2;
  39. Real const b2 = (Real)4;
  40. Real const b3 = sqrt2 * ((Real)3 + (Real)2 * sqrt2 - sqrt3) / sqrt3;
  41. mControls[0][0] = { (Real)0, (Real)0, (Real)1 }; // P004
  42. mControls[0][1] = { (Real)0, a0, (Real)1 }; // P013
  43. mControls[0][2] = { (Real)0, a1, a1 }; // P022
  44. mControls[0][3] = { (Real)0, (Real)1, a0 }; // P031
  45. mControls[0][4] = { (Real)0, (Real)1, (Real)0 }; // P040
  46. mControls[1][0] = { a0, (Real)0, (Real)1 }; // P103
  47. mControls[1][1] = { a2, a2, (Real)1 }; // P112
  48. mControls[1][2] = { a2, (Real)1, a2 }; // P121
  49. mControls[1][3] = { a0, (Real)1, (Real)0 }; // P130
  50. mControls[1][4] = { (Real)0, (Real)0, (Real)0 }; // unused
  51. mControls[2][0] = { a1, (Real)0, a1 }; // P202
  52. mControls[2][1] = { (Real)1, a2, a2 }; // P211
  53. mControls[2][2] = { a1, a1, (Real)0 }; // P220
  54. mControls[2][3] = { (Real)0, (Real)0, (Real)0 }; // unused
  55. mControls[2][4] = { (Real)0, (Real)0, (Real)0 }; // unused
  56. mControls[3][0] = { (Real)1, (Real)0, a0 }; // P301
  57. mControls[3][1] = { (Real)1, a0, (Real)0 }; // P310
  58. mControls[3][2] = { (Real)0, (Real)0, (Real)0 }; // unused
  59. mControls[3][3] = { (Real)0, (Real)0, (Real)0 }; // unused
  60. mControls[3][4] = { (Real)0, (Real)0, (Real)0 }; // unused
  61. mControls[4][0] = { (Real)1, (Real)0, (Real)0 }; // P400
  62. mControls[4][1] = { (Real)0, (Real)0, (Real)0 }; // unused
  63. mControls[4][2] = { (Real)0, (Real)0, (Real)0 }; // unused
  64. mControls[4][3] = { (Real)0, (Real)0, (Real)0 }; // unused
  65. mControls[4][4] = { (Real)0, (Real)0, (Real)0 }; // unused
  66. mWeights[0][0] = b0; // w004
  67. mWeights[0][1] = b1; // w013
  68. mWeights[0][2] = b2; // w022
  69. mWeights[0][3] = b1; // w031
  70. mWeights[0][4] = b0; // w040
  71. mWeights[1][0] = b1; // w103
  72. mWeights[1][1] = b3; // w112
  73. mWeights[1][2] = b3; // w121
  74. mWeights[1][3] = b1; // w130
  75. mWeights[1][4] = (Real)0; // unused
  76. mWeights[2][0] = b2; // w202
  77. mWeights[2][1] = b3; // w211
  78. mWeights[2][2] = b2; // w220
  79. mWeights[2][3] = (Real)0; // unused
  80. mWeights[2][4] = (Real)0; // unused
  81. mWeights[3][0] = b1; // w301
  82. mWeights[3][1] = b1; // w310
  83. mWeights[3][2] = (Real)0; // unused
  84. mWeights[3][3] = (Real)0; // unused
  85. mWeights[3][4] = (Real)0; // unused
  86. mWeights[4][0] = b0; // w400
  87. mWeights[4][1] = (Real)0; // unused
  88. mWeights[4][2] = (Real)0; // unused
  89. mWeights[4][3] = (Real)0; // unused
  90. mWeights[4][4] = (Real)0; // unused
  91. }
  92. // Evaluation of the surface. The function supports derivative
  93. // calculation through order 2; that is, maxOrder <= 2 is required.
  94. // If you want only the position, pass in maxOrder of 0. If you want
  95. // the position and first-order derivatives, pass in maxOrder of 1,
  96. // and so on. The output 'values' are ordered as: position X;
  97. // first-order derivatives dX/du, dX/dv; second-order derivatives
  98. // d2X/du2, d2X/dudv, d2X/dv2.
  99. void Evaluate(Real u, Real v, unsigned int maxOrder, Vector<3, Real> values[6]) const
  100. {
  101. // TODO: Some of the polynomials are used in other polynomials.
  102. // Optimize the code by eliminating the redundant computations.
  103. Real w = (Real)1 - u - v;
  104. Real uu = u * u, uv = u * v, uw = u * w, vv = v * v, vw = v * w, ww = w * w;
  105. // Compute the order-0 polynomials. Only the elements to be used
  106. // are filled in. The other terms are uninitialized but never
  107. // used.
  108. Real B[5][5];
  109. B[0][0] = ww * ww;
  110. B[0][1] = (Real)4 * vw * ww;
  111. B[0][2] = (Real)6 * vv * ww;
  112. B[0][3] = (Real)4 * vv * vw;
  113. B[0][4] = vv * vv;
  114. B[1][0] = (Real)4 * uw * ww;
  115. B[1][1] = (Real)12 * uv * ww;
  116. B[1][2] = (Real)12 * uv * vw;
  117. B[1][3] = (Real)4 * uv * vv;
  118. B[2][0] = (Real)6 * uu * ww;
  119. B[2][1] = (Real)12 * uu * vw;
  120. B[2][2] = (Real)6 * uu * vv;
  121. B[3][0] = (Real)4 * uu * uw;
  122. B[3][1] = (Real)4 * uu * uv;
  123. B[4][0] = uu * uu;
  124. // Compute the NURBS position.
  125. Vector<3, Real> N{ (Real)0, (Real)0, (Real)0 };
  126. Real D(0);
  127. for (int j1 = 0; j1 <= 4; ++j1)
  128. {
  129. for (int j0 = 0; j0 <= 4 - j1; ++j0)
  130. {
  131. Real product = mWeights[j1][j0] * B[j1][j0];
  132. N += product * mControls[j1][j0];
  133. D += product;
  134. }
  135. }
  136. values[0] = N / D;
  137. if (maxOrder >= 1)
  138. {
  139. // Compute the order-1 polynomials. Only the elements to be
  140. // used are filled in. The other terms are uninitialized but
  141. // never used.
  142. Real WmU = w - u;
  143. Real WmTwoU = WmU - u;
  144. Real WmThreeU = WmTwoU - u;
  145. Real TwoWmU = w + WmU;
  146. Real ThreeWmU = w + TwoWmU;
  147. Real WmV = w - v;
  148. Real WmTwoV = WmV - v;
  149. Real WmThreeV = WmTwoV - v;
  150. Real TwoWmV = w + WmV;
  151. Real ThreeWmV = w + TwoWmV;
  152. Real Dsqr = D * D;
  153. Real Bu[5][5];
  154. Bu[0][0] = (Real)-4 * ww * w;
  155. Bu[0][1] = (Real)-12 * v * ww;
  156. Bu[0][2] = (Real)-12 * vv * w;
  157. Bu[0][3] = (Real)-4 * v * vv;
  158. Bu[0][4] = (Real)0;
  159. Bu[1][0] = (Real)4 * ww * WmThreeU;
  160. Bu[1][1] = (Real)12 * vw * WmTwoU;
  161. Bu[1][2] = (Real)12 * vv * WmU;
  162. Bu[1][3] = (Real)4 * vv;
  163. Bu[2][0] = (Real)12 * uw * WmU;
  164. Bu[2][1] = (Real)12 * uv * TwoWmU;
  165. Bu[2][2] = (Real)12 * u * vv;
  166. Bu[3][0] = (Real)4 * uu * ThreeWmU;
  167. Bu[3][1] = (Real)12 * uu * v;
  168. Bu[4][0] = (Real)4 * uu * u;
  169. Real Bv[5][5];
  170. Bv[0][0] = (Real)-4 * ww * w;
  171. Bv[0][1] = (Real)4 * ww * WmThreeV;
  172. Bv[0][2] = (Real)12 * vw * WmV;
  173. Bv[0][3] = (Real)4 * vv * ThreeWmV;
  174. Bv[0][4] = (Real)4 * vv * v;
  175. Bv[1][0] = (Real)-12 * u * ww;
  176. Bv[1][1] = (Real)12 * uw * WmTwoV;
  177. Bv[1][2] = (Real)12 * uv * TwoWmV;
  178. Bv[1][3] = (Real)12 * u * vv;
  179. Bv[2][0] = (Real)-12 * uu * w;
  180. Bv[2][1] = (Real)12 * uu * WmV;
  181. Bv[2][2] = (Real)12 * uu * v;
  182. Bv[3][0] = (Real)-4 * uu * u;
  183. Bv[3][1] = (Real)4 * uu * u;
  184. Bv[4][0] = (Real)0;
  185. Vector<3, Real> Nu{ (Real)0, (Real)0, (Real)0 };
  186. Vector<3, Real> Nv{ (Real)0, (Real)0, (Real)0 };
  187. Real Du(0), Dv(0);
  188. for (int j1 = 0; j1 <= 4; ++j1)
  189. {
  190. for (int j0 = 0; j0 <= 4 - j1; ++j0)
  191. {
  192. Real product = mWeights[j1][j0] * Bu[j1][j0];
  193. Nu += product * mControls[j1][j0];
  194. Du += product;
  195. product = mWeights[j1][j0] * Bv[j1][j0];
  196. Nv += product * mControls[j1][j0];
  197. Dv += product;
  198. }
  199. }
  200. Vector<3, Real> numerDU = D * Nu - Du * N;
  201. Vector<3, Real> numerDV = D * Nv - Dv * N;
  202. values[1] = numerDU / Dsqr;
  203. values[2] = numerDV / Dsqr;
  204. if (maxOrder >= 2)
  205. {
  206. // Compute the order-2 polynomials. Only the elements to
  207. // be used are filled in. The other terms are
  208. // uninitialized but never used.
  209. Real Dcub = Dsqr * D;
  210. Real Buu[5][5];
  211. Buu[0][0] = (Real)12 * ww;
  212. Buu[0][1] = (Real)24 * vw;
  213. Buu[0][2] = (Real)12 * vv;
  214. Buu[0][3] = (Real)0;
  215. Buu[0][4] = (Real)0;
  216. Buu[1][0] = (Real)-24 * w * WmU;
  217. Buu[1][1] = (Real)-24 * v * TwoWmU;
  218. Buu[1][2] = (Real)-24 * vv;
  219. Buu[1][3] = (Real)0;
  220. Buu[2][0] = (Real)12 * (ww - (Real)4 * uw + uu);
  221. Buu[2][1] = (Real)24 * v * WmTwoU;
  222. Buu[2][2] = (Real)12 * vv;
  223. Buu[3][0] = (Real)24 * u * WmU;
  224. Buu[3][1] = (Real)24 * uv;
  225. Buu[4][0] = (Real)12 * uu;
  226. Real Buv[5][5];
  227. Buv[0][0] = (Real)12 * ww;
  228. Buv[0][1] = (Real)-12 * w * WmTwoV;
  229. Buv[0][2] = (Real)-12 * v * TwoWmV;
  230. Buv[0][3] = (Real)-12 * vv;
  231. Buv[0][4] = (Real)0;
  232. Buv[1][0] = (Real)-12 * w * WmTwoU;
  233. Buv[1][1] = (Real)12 * (ww + (Real)2 * (uv - uw - vw));
  234. Buv[1][2] = (Real)12 * v * ((Real)2 * WmU - v);
  235. Buv[1][3] = (Real)12 * vv;
  236. Buv[2][0] = (Real)-12 * u * TwoWmU;
  237. Buv[2][1] = (Real)12 * u * ((Real)2 * WmV - u);
  238. Buv[2][2] = (Real)24 * uv;
  239. Buv[3][0] = (Real)-12 * uu;
  240. Buv[3][1] = (Real)12 * uu;
  241. Buv[4][0] = (Real)0;
  242. Real Bvv[5][5];
  243. Bvv[0][0] = (Real)12 * ww;
  244. Bvv[0][1] = (Real)-24 * w * WmV;
  245. Bvv[0][2] = (Real)12 * (ww - (Real)4 * vw + vv);
  246. Bvv[0][3] = (Real)24 * v * WmV;
  247. Bvv[0][4] = (Real)12 * vv;
  248. Bvv[1][0] = (Real)24 * uw;
  249. Bvv[1][1] = (Real)-24 * u * TwoWmV;
  250. Bvv[1][2] = (Real)24 * u * WmTwoV;
  251. Bvv[1][3] = (Real)24 * uv;
  252. Bvv[2][0] = (Real)12 * uu;
  253. Bvv[2][1] = (Real)-24 * uu;
  254. Bvv[2][2] = (Real)12 * uu;
  255. Bvv[3][0] = (Real)0;
  256. Bvv[3][1] = (Real)0;
  257. Bvv[4][0] = (Real)0;
  258. Vector<3, Real> Nuu{ (Real)0, (Real)0, (Real)0 };
  259. Vector<3, Real> Nuv{ (Real)0, (Real)0, (Real)0 };
  260. Vector<3, Real> Nvv{ (Real)0, (Real)0, (Real)0 };
  261. Real Duu(0), Duv(0), Dvv(0);
  262. for (int j1 = 0; j1 <= 4; ++j1)
  263. {
  264. for (int j0 = 0; j0 <= 4 - j1; ++j0)
  265. {
  266. Real product = mWeights[j1][j0] * Buu[j1][j0];
  267. Nuu += product * mControls[j1][j0];
  268. Duu += product;
  269. product = mWeights[j1][j0] * Buv[j1][j0];
  270. Nuv += product * mControls[j1][j0];
  271. Duv += product;
  272. product = mWeights[j1][j0] * Bvv[j1][j0];
  273. Nvv += product * mControls[j1][j0];
  274. Dvv += product;
  275. }
  276. }
  277. Vector<3, Real> termDuu = D * (D * Nuu - Duu * N);
  278. Vector<3, Real> termDuv = D * (D * Nuv - Duv * N - Du * Nv - Dv * Nu);
  279. Vector<3, Real> termDvv = D * (D * Nvv - Dvv * N);
  280. values[3] = (D * termDuu - (Real)2 * Du * numerDU) / Dcub;
  281. values[4] = (D * termDuv + (Real)2 * Du * Dv * N) / Dcub;
  282. values[5] = (D * termDvv - (Real)2 * Dv * numerDV) / Dcub;
  283. }
  284. }
  285. }
  286. private:
  287. // For simplicity of the implementation, 2-dimensional arrays
  288. // of size 5-by-5 are used. Only array[r][c] is used where
  289. // 0 <= r <= 4 and 0 <= c < 4 - r.
  290. Vector3<Real> mControls[5][5];
  291. Real mWeights[5][5];
  292. };
  293. template <typename Real>
  294. class NURBSHalfSphereDegree3 : public NURBSSurface<3, Real>
  295. {
  296. public:
  297. NURBSHalfSphereDegree3()
  298. :
  299. NURBSSurface<3, Real>(BasisFunctionInput<Real>(4, 3),
  300. BasisFunctionInput<Real>(4, 3), nullptr, nullptr)
  301. {
  302. // weight[j][i] is mWeights[i + 4 * j], 0 <= i < 4, 0 <= j < 4
  303. Real const oneThird = (Real)1 / (Real)3;
  304. Real const oneNinth = (Real)1 / (Real)9;
  305. this->mWeights[0] = (Real)1;
  306. this->mWeights[1] = oneThird;
  307. this->mWeights[2] = oneThird;
  308. this->mWeights[3] = (Real)1;
  309. this->mWeights[4] = oneThird;
  310. this->mWeights[5] = oneNinth;
  311. this->mWeights[6] = oneNinth;
  312. this->mWeights[7] = oneThird;
  313. this->mWeights[8] = oneThird;
  314. this->mWeights[9] = oneNinth;
  315. this->mWeights[10] = oneNinth;
  316. this->mWeights[11] = oneThird;
  317. this->mWeights[12] = (Real)1;
  318. this->mWeights[13] = oneThird;
  319. this->mWeights[14] = oneThird;
  320. this->mWeights[15] = (Real)1;
  321. // control[j][i] is mControls[i + 4 * j], 0 <= i < 4, 0 <= j < 4
  322. this->mControls[0] = { (Real)0, (Real)0, (Real)1 };
  323. this->mControls[1] = { (Real)0, (Real)0, (Real)1 };
  324. this->mControls[2] = { (Real)0, (Real)0, (Real)1 };
  325. this->mControls[3] = { (Real)0, (Real)0, (Real)1 };
  326. this->mControls[4] = { (Real)2, (Real)0, (Real)1 };
  327. this->mControls[5] = { (Real)2, (Real)4, (Real)1 };
  328. this->mControls[6] = { (Real)-2, (Real)4, (Real)1 };
  329. this->mControls[7] = { (Real)-2, (Real)0, (Real)1 };
  330. this->mControls[8] = { (Real)2, (Real)0, (Real)-1 };
  331. this->mControls[9] = { (Real)2, (Real)4, (Real)-1 };
  332. this->mControls[10] = { (Real)-2, (Real)4, (Real)-1 };
  333. this->mControls[11] = { (Real)-2, (Real)0, (Real)-1 };
  334. this->mControls[12] = { (Real)0, (Real)0, (Real)-1 };
  335. this->mControls[13] = { (Real)0, (Real)0, (Real)-1 };
  336. this->mControls[14] = { (Real)0, (Real)0, (Real)-1 };
  337. this->mControls[15] = { (Real)0, (Real)0, (Real)-1 };
  338. }
  339. };
  340. template <typename Real>
  341. class NURBSFullSphereDegree3 : public NURBSSurface<3, Real>
  342. {
  343. public:
  344. NURBSFullSphereDegree3()
  345. :
  346. NURBSSurface<3, Real>(BasisFunctionInput<Real>(4, 3),
  347. CreateBasisFunctionInputV(), nullptr, nullptr)
  348. {
  349. // weight[j][i] is mWeights[i + 4 * j], 0 <= i < 4, 0 <= j < 7
  350. Real const oneThird = (Real)1 / (Real)3;
  351. Real const oneNinth = (Real)1 / (Real)9;
  352. this->mWeights[0] = (Real)1;
  353. this->mWeights[4] = oneThird;
  354. this->mWeights[8] = oneThird;
  355. this->mWeights[12] = (Real)1;
  356. this->mWeights[16] = oneThird;
  357. this->mWeights[20] = oneThird;
  358. this->mWeights[24] = (Real)1;
  359. this->mWeights[1] = oneThird;
  360. this->mWeights[5] = oneNinth;
  361. this->mWeights[9] = oneNinth;
  362. this->mWeights[13] = oneThird;
  363. this->mWeights[17] = oneNinth;
  364. this->mWeights[21] = oneNinth;
  365. this->mWeights[25] = oneThird;
  366. this->mWeights[2] = oneThird;
  367. this->mWeights[6] = oneNinth;
  368. this->mWeights[10] = oneNinth;
  369. this->mWeights[14] = oneThird;
  370. this->mWeights[18] = oneNinth;
  371. this->mWeights[22] = oneNinth;
  372. this->mWeights[26] = oneThird;
  373. this->mWeights[3] = (Real)1;
  374. this->mWeights[7] = oneThird;
  375. this->mWeights[11] = oneThird;
  376. this->mWeights[15] = (Real)1;
  377. this->mWeights[19] = oneThird;
  378. this->mWeights[23] = oneThird;
  379. this->mWeights[27] = (Real)1;
  380. // control[j][i] is mControls[i + 4 * j], 0 <= i < 4, 0 <= j < 7
  381. this->mControls[0] = { (Real)0, (Real)0, (Real)1 };
  382. this->mControls[4] = { (Real)0, (Real)0, (Real)1 };
  383. this->mControls[8] = { (Real)0, (Real)0, (Real)1 };
  384. this->mControls[12] = { (Real)0, (Real)0, (Real)1 };
  385. this->mControls[16] = { (Real)0, (Real)0, (Real)1 };
  386. this->mControls[20] = { (Real)0, (Real)0, (Real)1 };
  387. this->mControls[24] = { (Real)0, (Real)0, (Real)1 };
  388. this->mControls[1] = { (Real)2, (Real)0, (Real)1 };
  389. this->mControls[5] = { (Real)2, (Real)4, (Real)1 };
  390. this->mControls[9] = { (Real)-2, (Real)4, (Real)1 };
  391. this->mControls[13] = { (Real)-2, (Real)0, (Real)1 };
  392. this->mControls[17] = { (Real)-2, (Real)-4, (Real)1 };
  393. this->mControls[21] = { (Real)2, (Real)-4, (Real)1 };
  394. this->mControls[25] = { (Real)2, (Real)0, (Real)1 };
  395. this->mControls[2] = { (Real)2, (Real)0, (Real)-1 };
  396. this->mControls[6] = { (Real)2, (Real)4, (Real)-1 };
  397. this->mControls[10] = { (Real)-2, (Real)4, (Real)-1 };
  398. this->mControls[14] = { (Real)-2, (Real)0, (Real)-1 };
  399. this->mControls[18] = { (Real)-2, (Real)-4, (Real)-1 };
  400. this->mControls[22] = { (Real)2, (Real)-4, (Real)-1 };
  401. this->mControls[26] = { (Real)2, (Real)0, (Real)-1 };
  402. this->mControls[3] = { (Real)0, (Real)0, (Real)-1 };
  403. this->mControls[7] = { (Real)0, (Real)0, (Real)-1 };
  404. this->mControls[11] = { (Real)0, (Real)0, (Real)-1 };
  405. this->mControls[15] = { (Real)0, (Real)0, (Real)-1 };
  406. this->mControls[19] = { (Real)0, (Real)0, (Real)-1 };
  407. this->mControls[23] = { (Real)0, (Real)0, (Real)-1 };
  408. this->mControls[27] = { (Real)0, (Real)0, (Real)-1 };
  409. }
  410. private:
  411. static BasisFunctionInput<Real> CreateBasisFunctionInputV()
  412. {
  413. BasisFunctionInput<Real> input;
  414. input.numControls = 7;
  415. input.degree = 3;
  416. input.uniform = true;
  417. input.periodic = false;
  418. input.numUniqueKnots = 3;
  419. input.uniqueKnots.resize(input.numUniqueKnots);
  420. input.uniqueKnots[0] = { (Real)0, 4 };
  421. input.uniqueKnots[1] = { (Real)0.5, 3 };
  422. input.uniqueKnots[2] = { (Real)1, 4 };
  423. return input;
  424. }
  425. };
  426. }