TeapotBufferGeometry.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. /**
  2. * @author Eric Haines / http://erichaines.com/
  3. *
  4. * Tessellates the famous Utah teapot database by Martin Newell into triangles.
  5. *
  6. * THREE.TeapotBufferGeometry = function ( size, segments, bottom, lid, body, fitLid, blinn )
  7. *
  8. * defaults: size = 50, segments = 10, bottom = true, lid = true, body = true,
  9. * fitLid = false, blinn = true
  10. *
  11. * size is a relative scale: I've scaled the teapot to fit vertically between -1 and 1.
  12. * Think of it as a "radius".
  13. * segments - number of line segments to subdivide each patch edge;
  14. * 1 is possible but gives degenerates, so two is the real minimum.
  15. * bottom - boolean, if true (default) then the bottom patches are added. Some consider
  16. * adding the bottom heresy, so set this to "false" to adhere to the One True Way.
  17. * lid - to remove the lid and look inside, set to true.
  18. * body - to remove the body and leave the lid, set this and "bottom" to false.
  19. * fitLid - the lid is a tad small in the original. This stretches it a bit so you can't
  20. * see the teapot's insides through the gap.
  21. * blinn - Jim Blinn scaled the original data vertically by dividing by about 1.3 to look
  22. * nicer. If you want to see the original teapot, similar to the real-world model, set
  23. * this to false. True by default.
  24. * See http://en.wikipedia.org/wiki/File:Original_Utah_Teapot.jpg for the original
  25. * real-world teapot (from http://en.wikipedia.org/wiki/Utah_teapot).
  26. *
  27. * Note that the bottom (the last four patches) is not flat - blame Frank Crow, not me.
  28. *
  29. * The teapot should normally be rendered as a double sided object, since for some
  30. * patches both sides can be seen, e.g., the gap around the lid and inside the spout.
  31. *
  32. * Segments 'n' determines the number of triangles output.
  33. * Total triangles = 32*2*n*n - 8*n [degenerates at the top and bottom cusps are deleted]
  34. *
  35. * size_factor # triangles
  36. * 1 56
  37. * 2 240
  38. * 3 552
  39. * 4 992
  40. *
  41. * 10 6320
  42. * 20 25440
  43. * 30 57360
  44. *
  45. * Code converted from my ancient SPD software, http://tog.acm.org/resources/SPD/
  46. * Created for the Udacity course "Interactive Rendering", http://bit.ly/ericity
  47. * Lesson: https://www.udacity.com/course/viewer#!/c-cs291/l-68866048/m-106482448
  48. * YouTube video on teapot history: https://www.youtube.com/watch?v=DxMfblPzFNc
  49. *
  50. * See https://en.wikipedia.org/wiki/Utah_teapot for the history of the teapot
  51. *
  52. */
  53. /*global THREE */
  54. THREE.TeapotBufferGeometry = function ( size, segments, bottom, lid, body, fitLid, blinn ) {
  55. "use strict";
  56. // 32 * 4 * 4 Bezier spline patches
  57. var teapotPatches = [
  58. /*rim*/
  59. 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
  60. 3,16,17,18,7,19,20,21,11,22,23,24,15,25,26,27,
  61. 18,28,29,30,21,31,32,33,24,34,35,36,27,37,38,39,
  62. 30,40,41,0,33,42,43,4,36,44,45,8,39,46,47,12,
  63. /*body*/
  64. 12,13,14,15,48,49,50,51,52,53,54,55,56,57,58,59,
  65. 15,25,26,27,51,60,61,62,55,63,64,65,59,66,67,68,
  66. 27,37,38,39,62,69,70,71,65,72,73,74,68,75,76,77,
  67. 39,46,47,12,71,78,79,48,74,80,81,52,77,82,83,56,
  68. 56,57,58,59,84,85,86,87,88,89,90,91,92,93,94,95,
  69. 59,66,67,68,87,96,97,98,91,99,100,101,95,102,103,104,
  70. 68,75,76,77,98,105,106,107,101,108,109,110,104,111,112,113,
  71. 77,82,83,56,107,114,115,84,110,116,117,88,113,118,119,92,
  72. /*handle*/
  73. 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,
  74. 123,136,137,120,127,138,139,124,131,140,141,128,135,142,143,132,
  75. 132,133,134,135,144,145,146,147,148,149,150,151,68,152,153,154,
  76. 135,142,143,132,147,155,156,144,151,157,158,148,154,159,160,68,
  77. /*spout*/
  78. 161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,
  79. 164,177,178,161,168,179,180,165,172,181,182,169,176,183,184,173,
  80. 173,174,175,176,185,186,187,188,189,190,191,192,193,194,195,196,
  81. 176,183,184,173,188,197,198,185,192,199,200,189,196,201,202,193,
  82. /*lid*/
  83. 203,203,203,203,204,205,206,207,208,208,208,208,209,210,211,212,
  84. 203,203,203,203,207,213,214,215,208,208,208,208,212,216,217,218,
  85. 203,203,203,203,215,219,220,221,208,208,208,208,218,222,223,224,
  86. 203,203,203,203,221,225,226,204,208,208,208,208,224,227,228,209,
  87. 209,210,211,212,229,230,231,232,233,234,235,236,237,238,239,240,
  88. 212,216,217,218,232,241,242,243,236,244,245,246,240,247,248,249,
  89. 218,222,223,224,243,250,251,252,246,253,254,255,249,256,257,258,
  90. 224,227,228,209,252,259,260,229,255,261,262,233,258,263,264,237,
  91. /*bottom*/
  92. 265,265,265,265,266,267,268,269,270,271,272,273,92,119,118,113,
  93. 265,265,265,265,269,274,275,276,273,277,278,279,113,112,111,104,
  94. 265,265,265,265,276,280,281,282,279,283,284,285,104,103,102,95,
  95. 265,265,265,265,282,286,287,266,285,288,289,270,95,94,93,92
  96. ] ;
  97. var teapotVertices = [
  98. 1.4,0,2.4,
  99. 1.4,-0.784,2.4,
  100. 0.784,-1.4,2.4,
  101. 0,-1.4,2.4,
  102. 1.3375,0,2.53125,
  103. 1.3375,-0.749,2.53125,
  104. 0.749,-1.3375,2.53125,
  105. 0,-1.3375,2.53125,
  106. 1.4375,0,2.53125,
  107. 1.4375,-0.805,2.53125,
  108. 0.805,-1.4375,2.53125,
  109. 0,-1.4375,2.53125,
  110. 1.5,0,2.4,
  111. 1.5,-0.84,2.4,
  112. 0.84,-1.5,2.4,
  113. 0,-1.5,2.4,
  114. -0.784,-1.4,2.4,
  115. -1.4,-0.784,2.4,
  116. -1.4,0,2.4,
  117. -0.749,-1.3375,2.53125,
  118. -1.3375,-0.749,2.53125,
  119. -1.3375,0,2.53125,
  120. -0.805,-1.4375,2.53125,
  121. -1.4375,-0.805,2.53125,
  122. -1.4375,0,2.53125,
  123. -0.84,-1.5,2.4,
  124. -1.5,-0.84,2.4,
  125. -1.5,0,2.4,
  126. -1.4,0.784,2.4,
  127. -0.784,1.4,2.4,
  128. 0,1.4,2.4,
  129. -1.3375,0.749,2.53125,
  130. -0.749,1.3375,2.53125,
  131. 0,1.3375,2.53125,
  132. -1.4375,0.805,2.53125,
  133. -0.805,1.4375,2.53125,
  134. 0,1.4375,2.53125,
  135. -1.5,0.84,2.4,
  136. -0.84,1.5,2.4,
  137. 0,1.5,2.4,
  138. 0.784,1.4,2.4,
  139. 1.4,0.784,2.4,
  140. 0.749,1.3375,2.53125,
  141. 1.3375,0.749,2.53125,
  142. 0.805,1.4375,2.53125,
  143. 1.4375,0.805,2.53125,
  144. 0.84,1.5,2.4,
  145. 1.5,0.84,2.4,
  146. 1.75,0,1.875,
  147. 1.75,-0.98,1.875,
  148. 0.98,-1.75,1.875,
  149. 0,-1.75,1.875,
  150. 2,0,1.35,
  151. 2,-1.12,1.35,
  152. 1.12,-2,1.35,
  153. 0,-2,1.35,
  154. 2,0,0.9,
  155. 2,-1.12,0.9,
  156. 1.12,-2,0.9,
  157. 0,-2,0.9,
  158. -0.98,-1.75,1.875,
  159. -1.75,-0.98,1.875,
  160. -1.75,0,1.875,
  161. -1.12,-2,1.35,
  162. -2,-1.12,1.35,
  163. -2,0,1.35,
  164. -1.12,-2,0.9,
  165. -2,-1.12,0.9,
  166. -2,0,0.9,
  167. -1.75,0.98,1.875,
  168. -0.98,1.75,1.875,
  169. 0,1.75,1.875,
  170. -2,1.12,1.35,
  171. -1.12,2,1.35,
  172. 0,2,1.35,
  173. -2,1.12,0.9,
  174. -1.12,2,0.9,
  175. 0,2,0.9,
  176. 0.98,1.75,1.875,
  177. 1.75,0.98,1.875,
  178. 1.12,2,1.35,
  179. 2,1.12,1.35,
  180. 1.12,2,0.9,
  181. 2,1.12,0.9,
  182. 2,0,0.45,
  183. 2,-1.12,0.45,
  184. 1.12,-2,0.45,
  185. 0,-2,0.45,
  186. 1.5,0,0.225,
  187. 1.5,-0.84,0.225,
  188. 0.84,-1.5,0.225,
  189. 0,-1.5,0.225,
  190. 1.5,0,0.15,
  191. 1.5,-0.84,0.15,
  192. 0.84,-1.5,0.15,
  193. 0,-1.5,0.15,
  194. -1.12,-2,0.45,
  195. -2,-1.12,0.45,
  196. -2,0,0.45,
  197. -0.84,-1.5,0.225,
  198. -1.5,-0.84,0.225,
  199. -1.5,0,0.225,
  200. -0.84,-1.5,0.15,
  201. -1.5,-0.84,0.15,
  202. -1.5,0,0.15,
  203. -2,1.12,0.45,
  204. -1.12,2,0.45,
  205. 0,2,0.45,
  206. -1.5,0.84,0.225,
  207. -0.84,1.5,0.225,
  208. 0,1.5,0.225,
  209. -1.5,0.84,0.15,
  210. -0.84,1.5,0.15,
  211. 0,1.5,0.15,
  212. 1.12,2,0.45,
  213. 2,1.12,0.45,
  214. 0.84,1.5,0.225,
  215. 1.5,0.84,0.225,
  216. 0.84,1.5,0.15,
  217. 1.5,0.84,0.15,
  218. -1.6,0,2.025,
  219. -1.6,-0.3,2.025,
  220. -1.5,-0.3,2.25,
  221. -1.5,0,2.25,
  222. -2.3,0,2.025,
  223. -2.3,-0.3,2.025,
  224. -2.5,-0.3,2.25,
  225. -2.5,0,2.25,
  226. -2.7,0,2.025,
  227. -2.7,-0.3,2.025,
  228. -3,-0.3,2.25,
  229. -3,0,2.25,
  230. -2.7,0,1.8,
  231. -2.7,-0.3,1.8,
  232. -3,-0.3,1.8,
  233. -3,0,1.8,
  234. -1.5,0.3,2.25,
  235. -1.6,0.3,2.025,
  236. -2.5,0.3,2.25,
  237. -2.3,0.3,2.025,
  238. -3,0.3,2.25,
  239. -2.7,0.3,2.025,
  240. -3,0.3,1.8,
  241. -2.7,0.3,1.8,
  242. -2.7,0,1.575,
  243. -2.7,-0.3,1.575,
  244. -3,-0.3,1.35,
  245. -3,0,1.35,
  246. -2.5,0,1.125,
  247. -2.5,-0.3,1.125,
  248. -2.65,-0.3,0.9375,
  249. -2.65,0,0.9375,
  250. -2,-0.3,0.9,
  251. -1.9,-0.3,0.6,
  252. -1.9,0,0.6,
  253. -3,0.3,1.35,
  254. -2.7,0.3,1.575,
  255. -2.65,0.3,0.9375,
  256. -2.5,0.3,1.125,
  257. -1.9,0.3,0.6,
  258. -2,0.3,0.9,
  259. 1.7,0,1.425,
  260. 1.7,-0.66,1.425,
  261. 1.7,-0.66,0.6,
  262. 1.7,0,0.6,
  263. 2.6,0,1.425,
  264. 2.6,-0.66,1.425,
  265. 3.1,-0.66,0.825,
  266. 3.1,0,0.825,
  267. 2.3,0,2.1,
  268. 2.3,-0.25,2.1,
  269. 2.4,-0.25,2.025,
  270. 2.4,0,2.025,
  271. 2.7,0,2.4,
  272. 2.7,-0.25,2.4,
  273. 3.3,-0.25,2.4,
  274. 3.3,0,2.4,
  275. 1.7,0.66,0.6,
  276. 1.7,0.66,1.425,
  277. 3.1,0.66,0.825,
  278. 2.6,0.66,1.425,
  279. 2.4,0.25,2.025,
  280. 2.3,0.25,2.1,
  281. 3.3,0.25,2.4,
  282. 2.7,0.25,2.4,
  283. 2.8,0,2.475,
  284. 2.8,-0.25,2.475,
  285. 3.525,-0.25,2.49375,
  286. 3.525,0,2.49375,
  287. 2.9,0,2.475,
  288. 2.9,-0.15,2.475,
  289. 3.45,-0.15,2.5125,
  290. 3.45,0,2.5125,
  291. 2.8,0,2.4,
  292. 2.8,-0.15,2.4,
  293. 3.2,-0.15,2.4,
  294. 3.2,0,2.4,
  295. 3.525,0.25,2.49375,
  296. 2.8,0.25,2.475,
  297. 3.45,0.15,2.5125,
  298. 2.9,0.15,2.475,
  299. 3.2,0.15,2.4,
  300. 2.8,0.15,2.4,
  301. 0,0,3.15,
  302. 0.8,0,3.15,
  303. 0.8,-0.45,3.15,
  304. 0.45,-0.8,3.15,
  305. 0,-0.8,3.15,
  306. 0,0,2.85,
  307. 0.2,0,2.7,
  308. 0.2,-0.112,2.7,
  309. 0.112,-0.2,2.7,
  310. 0,-0.2,2.7,
  311. -0.45,-0.8,3.15,
  312. -0.8,-0.45,3.15,
  313. -0.8,0,3.15,
  314. -0.112,-0.2,2.7,
  315. -0.2,-0.112,2.7,
  316. -0.2,0,2.7,
  317. -0.8,0.45,3.15,
  318. -0.45,0.8,3.15,
  319. 0,0.8,3.15,
  320. -0.2,0.112,2.7,
  321. -0.112,0.2,2.7,
  322. 0,0.2,2.7,
  323. 0.45,0.8,3.15,
  324. 0.8,0.45,3.15,
  325. 0.112,0.2,2.7,
  326. 0.2,0.112,2.7,
  327. 0.4,0,2.55,
  328. 0.4,-0.224,2.55,
  329. 0.224,-0.4,2.55,
  330. 0,-0.4,2.55,
  331. 1.3,0,2.55,
  332. 1.3,-0.728,2.55,
  333. 0.728,-1.3,2.55,
  334. 0,-1.3,2.55,
  335. 1.3,0,2.4,
  336. 1.3,-0.728,2.4,
  337. 0.728,-1.3,2.4,
  338. 0,-1.3,2.4,
  339. -0.224,-0.4,2.55,
  340. -0.4,-0.224,2.55,
  341. -0.4,0,2.55,
  342. -0.728,-1.3,2.55,
  343. -1.3,-0.728,2.55,
  344. -1.3,0,2.55,
  345. -0.728,-1.3,2.4,
  346. -1.3,-0.728,2.4,
  347. -1.3,0,2.4,
  348. -0.4,0.224,2.55,
  349. -0.224,0.4,2.55,
  350. 0,0.4,2.55,
  351. -1.3,0.728,2.55,
  352. -0.728,1.3,2.55,
  353. 0,1.3,2.55,
  354. -1.3,0.728,2.4,
  355. -0.728,1.3,2.4,
  356. 0,1.3,2.4,
  357. 0.224,0.4,2.55,
  358. 0.4,0.224,2.55,
  359. 0.728,1.3,2.55,
  360. 1.3,0.728,2.55,
  361. 0.728,1.3,2.4,
  362. 1.3,0.728,2.4,
  363. 0,0,0,
  364. 1.425,0,0,
  365. 1.425,0.798,0,
  366. 0.798,1.425,0,
  367. 0,1.425,0,
  368. 1.5,0,0.075,
  369. 1.5,0.84,0.075,
  370. 0.84,1.5,0.075,
  371. 0,1.5,0.075,
  372. -0.798,1.425,0,
  373. -1.425,0.798,0,
  374. -1.425,0,0,
  375. -0.84,1.5,0.075,
  376. -1.5,0.84,0.075,
  377. -1.5,0,0.075,
  378. -1.425,-0.798,0,
  379. -0.798,-1.425,0,
  380. 0,-1.425,0,
  381. -1.5,-0.84,0.075,
  382. -0.84,-1.5,0.075,
  383. 0,-1.5,0.075,
  384. 0.798,-1.425,0,
  385. 1.425,-0.798,0,
  386. 0.84,-1.5,0.075,
  387. 1.5,-0.84,0.075
  388. ] ;
  389. THREE.BufferGeometry.call( this );
  390. this.type = 'TeapotBufferGeometry';
  391. this.parameters = {
  392. size: size,
  393. segments: segments,
  394. bottom: bottom,
  395. lid: lid,
  396. body: body,
  397. fitLid: fitLid,
  398. blinn: blinn
  399. };
  400. size = size || 50;
  401. // number of segments per patch
  402. segments = segments !== undefined ? Math.max( 2, Math.floor( segments ) || 10 ) : 10;
  403. // which parts should be visible
  404. bottom = bottom === undefined ? true : bottom;
  405. lid = lid === undefined ? true : lid;
  406. body = body === undefined ? true : body;
  407. // Should the lid be snug? It's not traditional, but we make it snug by default
  408. fitLid = fitLid === undefined ? true : fitLid;
  409. // Jim Blinn scaled the teapot down in size by about 1.3 for
  410. // some rendering tests. He liked the new proportions that he kept
  411. // the data in this form. The model was distributed with these new
  412. // proportions and became the norm. Trivia: comparing images of the
  413. // real teapot and the computer model, the ratio for the bowl of the
  414. // real teapot is more like 1.25, but since 1.3 is the traditional
  415. // value given, we use it here.
  416. var blinnScale = 1.3;
  417. blinn = blinn === undefined ? true : blinn;
  418. // scale the size to be the real scaling factor
  419. var maxHeight = 3.15 * ( blinn ? 1 : blinnScale );
  420. var maxHeight2 = maxHeight / 2;
  421. var trueSize = size / maxHeight2;
  422. // Number of elements depends on what is needed. Subtract degenerate
  423. // triangles at tip of bottom and lid out in advance.
  424. var numTriangles = bottom ? ( 8 * segments - 4 ) * segments : 0;
  425. numTriangles += lid ? ( 16 * segments - 4 ) * segments : 0;
  426. numTriangles += body ? 40 * segments * segments : 0;
  427. var indices = new Uint32Array( numTriangles * 3 );
  428. var numVertices = bottom ? 4 : 0;
  429. numVertices += lid ? 8 : 0;
  430. numVertices += body ? 20 : 0;
  431. numVertices *= ( segments + 1 ) * ( segments + 1 );
  432. var vertices = new Float32Array( numVertices * 3 );
  433. var normals = new Float32Array( numVertices * 3 );
  434. var uvs = new Float32Array( numVertices * 2 );
  435. // Bezier form
  436. var ms = new THREE.Matrix4();
  437. ms.set( -1.0, 3.0, -3.0, 1.0,
  438. 3.0, -6.0, 3.0, 0.0,
  439. -3.0, 3.0, 0.0, 0.0,
  440. 1.0, 0.0, 0.0, 0.0 ) ;
  441. var g = [];
  442. var i, r, c;
  443. var sp = [];
  444. var tp = [];
  445. var dsp = [];
  446. var dtp = [];
  447. // M * G * M matrix, sort of see
  448. // http://www.cs.helsinki.fi/group/goa/mallinnus/curves/surfaces.html
  449. var mgm = [];
  450. var vert = [];
  451. var sdir = [];
  452. var tdir = [];
  453. var norm = new THREE.Vector3();
  454. var tcoord;
  455. var sstep, tstep;
  456. var vertPerRow, eps;
  457. var s, t, sval, tval, p;
  458. var dsval = 0;
  459. var dtval = 0;
  460. var normOut = new THREE.Vector3();
  461. var v1, v2, v3, v4;
  462. var gmx = new THREE.Matrix4();
  463. var tmtx = new THREE.Matrix4();
  464. var vsp = new THREE.Vector4();
  465. var vtp = new THREE.Vector4();
  466. var vdsp = new THREE.Vector4();
  467. var vdtp = new THREE.Vector4();
  468. var vsdir = new THREE.Vector3();
  469. var vtdir = new THREE.Vector3();
  470. var mst = ms.clone();
  471. mst.transpose();
  472. // internal function: test if triangle has any matching vertices;
  473. // if so, don't save triangle, since it won't display anything.
  474. var notDegenerate = function ( vtx1, vtx2, vtx3 ) {
  475. // if any vertex matches, return false
  476. return ! ( ( ( vertices[ vtx1 * 3 ] === vertices[ vtx2 * 3 ] ) &&
  477. ( vertices[ vtx1 * 3 + 1 ] === vertices[ vtx2 * 3 + 1 ] ) &&
  478. ( vertices[ vtx1 * 3 + 2 ] === vertices[ vtx2 * 3 + 2 ] ) ) ||
  479. ( ( vertices[ vtx1 * 3 ] === vertices[ vtx3 * 3 ] ) &&
  480. ( vertices[ vtx1 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] ) &&
  481. ( vertices[ vtx1 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ) ) ||
  482. ( ( vertices[ vtx2 * 3 ] === vertices[ vtx3 * 3 ] ) &&
  483. ( vertices[ vtx2 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] ) &&
  484. ( vertices[ vtx2 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ) ) );
  485. };
  486. for ( i = 0; i < 3; i ++ )
  487. {
  488. mgm[ i ] = new THREE.Matrix4();
  489. }
  490. var minPatches = body ? 0 : 20;
  491. var maxPatches = bottom ? 32 : 28;
  492. vertPerRow = segments + 1;
  493. eps = 0.0000001;
  494. var surfCount = 0;
  495. var vertCount = 0;
  496. var normCount = 0;
  497. var uvCount = 0;
  498. var indexCount = 0;
  499. for ( var surf = minPatches ; surf < maxPatches ; surf ++ ) {
  500. // lid is in the middle of the data, patches 20-27,
  501. // so ignore it for this part of the loop if the lid is not desired
  502. if ( lid || ( surf < 20 || surf >= 28 ) ) {
  503. // get M * G * M matrix for x,y,z
  504. for ( i = 0 ; i < 3 ; i ++ ) {
  505. // get control patches
  506. for ( r = 0 ; r < 4 ; r ++ ) {
  507. for ( c = 0 ; c < 4 ; c ++ ) {
  508. // transposed
  509. g[ c * 4 + r ] = teapotVertices[ teapotPatches[ surf * 16 + r * 4 + c ] * 3 + i ] ;
  510. // is the lid to be made larger, and is this a point on the lid
  511. // that is X or Y?
  512. if ( fitLid && ( surf >= 20 && surf < 28 ) && ( i !== 2 ) ) {
  513. // increase XY size by 7.7%, found empirically. I don't
  514. // increase Z so that the teapot will continue to fit in the
  515. // space -1 to 1 for Y (Y is up for the final model).
  516. g[ c * 4 + r ] *= 1.077;
  517. }
  518. // Blinn "fixed" the teapot by dividing Z by blinnScale, and that's the
  519. // data we now use. The original teapot is taller. Fix it:
  520. if ( ! blinn && ( i === 2 ) ) {
  521. g[ c * 4 + r ] *= blinnScale;
  522. }
  523. }
  524. }
  525. gmx.set( g[ 0 ], g[ 1 ], g[ 2 ], g[ 3 ], g[ 4 ], g[ 5 ], g[ 6 ], g[ 7 ], g[ 8 ], g[ 9 ], g[ 10 ], g[ 11 ], g[ 12 ], g[ 13 ], g[ 14 ], g[ 15 ] );
  526. tmtx.multiplyMatrices( gmx, ms );
  527. mgm[ i ].multiplyMatrices( mst, tmtx );
  528. }
  529. // step along, get points, and output
  530. for ( sstep = 0 ; sstep <= segments ; sstep ++ ) {
  531. s = sstep / segments;
  532. for ( tstep = 0 ; tstep <= segments ; tstep ++ ) {
  533. t = tstep / segments;
  534. // point from basis
  535. // get power vectors and their derivatives
  536. for ( p = 4, sval = tval = 1.0 ; p -- ; ) {
  537. sp[ p ] = sval ;
  538. tp[ p ] = tval ;
  539. sval *= s ;
  540. tval *= t ;
  541. if ( p === 3 ) {
  542. dsp[ p ] = dtp[ p ] = 0.0 ;
  543. dsval = dtval = 1.0 ;
  544. } else {
  545. dsp[ p ] = dsval * ( 3 - p ) ;
  546. dtp[ p ] = dtval * ( 3 - p ) ;
  547. dsval *= s ;
  548. dtval *= t ;
  549. }
  550. }
  551. vsp.fromArray( sp );
  552. vtp.fromArray( tp );
  553. vdsp.fromArray( dsp );
  554. vdtp.fromArray( dtp );
  555. // do for x,y,z
  556. for ( i = 0 ; i < 3 ; i ++ ) {
  557. // multiply power vectors times matrix to get value
  558. tcoord = vsp.clone();
  559. tcoord.applyMatrix4( mgm[ i ] );
  560. vert[ i ] = tcoord.dot( vtp );
  561. // get s and t tangent vectors
  562. tcoord = vdsp.clone();
  563. tcoord.applyMatrix4( mgm[ i ] );
  564. sdir[ i ] = tcoord.dot( vtp ) ;
  565. tcoord = vsp.clone();
  566. tcoord.applyMatrix4( mgm[ i ] );
  567. tdir[ i ] = tcoord.dot( vdtp ) ;
  568. }
  569. // find normal
  570. vsdir.fromArray( sdir );
  571. vtdir.fromArray( tdir );
  572. norm.crossVectors( vtdir, vsdir );
  573. norm.normalize();
  574. // if X and Z length is 0, at the cusp, so point the normal up or down, depending on patch number
  575. if ( vert[ 0 ] === 0 && vert[ 1 ] === 0 )
  576. {
  577. // if above the middle of the teapot, normal points up, else down
  578. normOut.set( 0, vert[ 2 ] > maxHeight2 ? 1 : - 1, 0 );
  579. }
  580. else
  581. {
  582. // standard output: rotate on X axis
  583. normOut.set( norm.x, norm.z, - norm.y );
  584. }
  585. // store it all
  586. vertices[ vertCount ++ ] = trueSize * vert[ 0 ];
  587. vertices[ vertCount ++ ] = trueSize * ( vert[ 2 ] - maxHeight2 );
  588. vertices[ vertCount ++ ] = - trueSize * vert[ 1 ];
  589. normals[ normCount ++ ] = normOut.x;
  590. normals[ normCount ++ ] = normOut.y;
  591. normals[ normCount ++ ] = normOut.z;
  592. uvs[ uvCount ++ ] = 1 - t;
  593. uvs[ uvCount ++ ] = 1 - s;
  594. }
  595. }
  596. // save the faces
  597. for ( sstep = 0 ; sstep < segments ; sstep ++ ) {
  598. for ( tstep = 0 ; tstep < segments ; tstep ++ ) {
  599. v1 = surfCount * vertPerRow * vertPerRow + sstep * vertPerRow + tstep;
  600. v2 = v1 + 1;
  601. v3 = v2 + vertPerRow;
  602. v4 = v1 + vertPerRow;
  603. // Normals and UVs cannot be shared. Without clone(), you can see the consequences
  604. // of sharing if you call geometry.applyMatrix( matrix ).
  605. if ( notDegenerate ( v1, v2, v3 ) ) {
  606. indices[ indexCount ++ ] = v1;
  607. indices[ indexCount ++ ] = v2;
  608. indices[ indexCount ++ ] = v3;
  609. }
  610. if ( notDegenerate ( v1, v3, v4 ) ) {
  611. indices[ indexCount ++ ] = v1;
  612. indices[ indexCount ++ ] = v3;
  613. indices[ indexCount ++ ] = v4;
  614. }
  615. }
  616. }
  617. // increment only if a surface was used
  618. surfCount ++;
  619. }
  620. }
  621. this.setIndex( new THREE.BufferAttribute( indices, 1 ) );
  622. this.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
  623. this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
  624. this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
  625. this.computeBoundingSphere();
  626. };
  627. THREE.TeapotBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
  628. THREE.TeapotBufferGeometry.prototype.constructor = THREE.TeapotBufferGeometry;
  629. THREE.TeapotBufferGeometry.prototype.clone = function () {
  630. var bufferGeometry = new THREE.TeapotBufferGeometry(
  631. this.parameters.size,
  632. this.parameters.segments,
  633. this.parameters.bottom,
  634. this.parameters.lid,
  635. this.parameters.body,
  636. this.parameters.fitLid,
  637. this.parameters.blinn
  638. );
  639. return bufferGeometry;
  640. };