BufferGeometry.tests.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  1. /**
  2. * @author simonThiele / https://github.com/simonThiele
  3. * @author TristanVALCKE / https://github.com/Itee
  4. */
  5. /* global QUnit */
  6. import { BufferGeometry } from '../../../../src/core/BufferGeometry';
  7. import {
  8. BufferAttribute,
  9. Uint16BufferAttribute,
  10. Uint32BufferAttribute
  11. } from '../../../../src/core/BufferAttribute';
  12. import { Color } from '../../../../src/math/Color';
  13. import { Vector2 } from '../../../../src/math/Vector2';
  14. import { Vector3 } from '../../../../src/math/Vector3';
  15. import { Vector4 } from '../../../../src/math/Vector4';
  16. import { Matrix4 } from '../../../../src/math/Matrix4';
  17. import { Sphere } from '../../../../src/math/Sphere';
  18. import { Geometry } from '../../../../src/core/Geometry';
  19. import { Face3 } from '../../../../src/core/Face3';
  20. import { Mesh } from '../../../../src/objects/Mesh';
  21. import { Line } from '../../../../src/objects/Line.js';
  22. import {
  23. x,
  24. y,
  25. z
  26. } from '../math/Constants.tests';
  27. var DegToRad = Math.PI / 180;
  28. function bufferAttributeEquals( a, b, tolerance ) {
  29. tolerance = tolerance || 0.0001;
  30. if ( a.count !== b.count || a.itemSize !== b.itemSize ) {
  31. return false;
  32. }
  33. for ( var i = 0, il = a.count * a.itemSize; i < il; i ++ ) {
  34. var delta = a[ i ] - b[ i ];
  35. if ( delta > tolerance ) {
  36. return false;
  37. }
  38. }
  39. return true;
  40. }
  41. function getBBForVertices( vertices ) {
  42. var geometry = new BufferGeometry();
  43. geometry.setAttribute( "position", new BufferAttribute( new Float32Array( vertices ), 3 ) );
  44. geometry.computeBoundingBox();
  45. return geometry.boundingBox;
  46. }
  47. function getBSForVertices( vertices ) {
  48. var geometry = new BufferGeometry();
  49. geometry.setAttribute( "position", new BufferAttribute( new Float32Array( vertices ), 3 ) );
  50. geometry.computeBoundingSphere();
  51. return geometry.boundingSphere;
  52. }
  53. function getNormalsForVertices( vertices, assert ) {
  54. var geometry = new BufferGeometry();
  55. geometry.setAttribute( "position", new BufferAttribute( new Float32Array( vertices ), 3 ) );
  56. geometry.computeVertexNormals();
  57. assert.ok( geometry.attributes.normal !== undefined, "normal attribute was created" );
  58. return geometry.attributes.normal.array;
  59. }
  60. function comparePositions( pos, v ) {
  61. return (
  62. pos[ 0 ] === v[ 0 ].x && pos[ 1 ] === v[ 0 ].y && pos[ 2 ] === v[ 0 ].z &&
  63. pos[ 3 ] === v[ 1 ].x && pos[ 4 ] === v[ 1 ].y && pos[ 5 ] === v[ 1 ].z &&
  64. pos[ 6 ] === v[ 2 ].x && pos[ 7 ] === v[ 2 ].y && pos[ 8 ] === v[ 2 ].z
  65. );
  66. }
  67. function compareColors( col, c ) {
  68. return (
  69. col[ 0 ] === c[ 0 ].r && col[ 1 ] === c[ 0 ].g && col[ 2 ] === c[ 0 ].b &&
  70. col[ 3 ] === c[ 1 ].r && col[ 4 ] === c[ 1 ].g && col[ 5 ] === c[ 1 ].b &&
  71. col[ 6 ] === c[ 2 ].r && col[ 7 ] === c[ 2 ].g && col[ 8 ] === c[ 2 ].b
  72. );
  73. }
  74. function compareUvs( uvs, u ) {
  75. return (
  76. uvs[ 0 ] === u[ 0 ].x && uvs[ 1 ] === u[ 0 ].y &&
  77. uvs[ 2 ] === u[ 1 ].x && uvs[ 3 ] === u[ 1 ].y &&
  78. uvs[ 4 ] === u[ 2 ].x && uvs[ 5 ] === u[ 2 ].y
  79. );
  80. }
  81. export default QUnit.module( 'Core', () => {
  82. QUnit.module( 'BufferGeometry', () => {
  83. // INHERITANCE
  84. QUnit.todo( "Extending", ( assert ) => {
  85. assert.ok( false, "everything's gonna be alright" );
  86. } );
  87. // INSTANCING
  88. QUnit.todo( "Instancing", ( assert ) => {
  89. assert.ok( false, "everything's gonna be alright" );
  90. } );
  91. // PUBLIC STUFF
  92. QUnit.todo( "isBufferGeometry", ( assert ) => {
  93. assert.ok( false, "everything's gonna be alright" );
  94. } );
  95. QUnit.test( "setIndex/getIndex", ( assert ) => {
  96. var a = new BufferGeometry();
  97. var uint16 = [ 1, 2, 3 ];
  98. var uint32 = [ 65535, 65536, 65537 ];
  99. var str = "foo";
  100. a.setIndex( uint16 );
  101. assert.ok( a.getIndex() instanceof Uint16BufferAttribute, "Index has the right type" );
  102. assert.deepEqual( a.getIndex().array, new Uint16Array( uint16 ), "Small index gets stored correctly" );
  103. a.setIndex( uint32 );
  104. assert.ok( a.getIndex() instanceof Uint32BufferAttribute, "Index has the right type" );
  105. assert.deepEqual( a.getIndex().array, new Uint32Array( uint32 ), "Large index gets stored correctly" );
  106. a.setIndex( str );
  107. assert.strictEqual( a.getIndex(), str, "Weird index gets stored correctly" );
  108. } );
  109. QUnit.todo( "getAttribute", ( assert ) => {
  110. assert.ok( false, "everything's gonna be alright" );
  111. } );
  112. QUnit.test( "set / delete Attribute", ( assert ) => {
  113. var geometry = new BufferGeometry();
  114. var attributeName = "position";
  115. assert.ok( geometry.attributes[ attributeName ] === undefined, 'no attribute defined' );
  116. geometry.setAttribute( attributeName, new BufferAttribute( new Float32Array( [ 1, 2, 3 ], 1 ) ) );
  117. assert.ok( geometry.attributes[ attributeName ] !== undefined, 'attribute is defined' );
  118. geometry.deleteAttribute( attributeName );
  119. assert.ok( geometry.attributes[ attributeName ] === undefined, 'no attribute defined' );
  120. } );
  121. QUnit.test( "addGroup", ( assert ) => {
  122. var a = new BufferGeometry();
  123. var expected = [
  124. {
  125. start: 0,
  126. count: 1,
  127. materialIndex: 0
  128. },
  129. {
  130. start: 1,
  131. count: 2,
  132. materialIndex: 2
  133. }
  134. ];
  135. a.addGroup( 0, 1, 0 );
  136. a.addGroup( 1, 2, 2 );
  137. assert.deepEqual( a.groups, expected, "Check groups were stored correctly and in order" );
  138. a.clearGroups();
  139. assert.strictEqual( a.groups.length, 0, "Check groups were deleted correctly" );
  140. } );
  141. QUnit.todo( "clearGroups", ( assert ) => {
  142. assert.ok( false, "everything's gonna be alright" );
  143. } );
  144. QUnit.test( "setDrawRange", ( assert ) => {
  145. var a = new BufferGeometry();
  146. a.setDrawRange( 1.0, 7 );
  147. assert.deepEqual( a.drawRange, {
  148. start: 1,
  149. count: 7
  150. }, "Check draw range was stored correctly" );
  151. } );
  152. QUnit.test( "applyMatrix4", ( assert ) => {
  153. var geometry = new BufferGeometry();
  154. geometry.setAttribute( "position", new BufferAttribute( new Float32Array( 6 ), 3 ) );
  155. var matrix = new Matrix4().set(
  156. 1, 0, 0, 1.5,
  157. 0, 1, 0, - 2,
  158. 0, 0, 1, 3,
  159. 0, 0, 0, 1
  160. );
  161. geometry.applyMatrix4( matrix );
  162. var position = geometry.attributes.position.array;
  163. var m = matrix.elements;
  164. assert.ok( position[ 0 ] === m[ 12 ] && position[ 1 ] === m[ 13 ] && position[ 2 ] === m[ 14 ], "position was extracted from matrix" );
  165. assert.ok( position[ 3 ] === m[ 12 ] && position[ 4 ] === m[ 13 ] && position[ 5 ] === m[ 14 ], "position was extracted from matrix twice" );
  166. assert.ok( geometry.attributes.position.version === 1, "version was increased during update" );
  167. } );
  168. QUnit.test( "rotateX/Y/Z", ( assert ) => {
  169. var geometry = new BufferGeometry();
  170. geometry.setAttribute( "position", new BufferAttribute( new Float32Array( [ 1, 2, 3, 4, 5, 6 ] ), 3 ) );
  171. var pos = geometry.attributes.position.array;
  172. geometry.rotateX( 180 * DegToRad );
  173. // object was rotated around x so all items should be flipped but the x ones
  174. assert.ok( pos[ 0 ] === 1 && pos[ 1 ] === - 2 && pos[ 2 ] === - 3 &&
  175. pos[ 3 ] === 4 && pos[ 4 ] === - 5 && pos[ 5 ] === - 6, "vertices were rotated around x by 180 degrees" );
  176. geometry.rotateY( 180 * DegToRad );
  177. // vertices were rotated around y so all items should be flipped again but the y ones
  178. assert.ok( pos[ 0 ] === - 1 && pos[ 1 ] === - 2 && pos[ 2 ] === 3 &&
  179. pos[ 3 ] === - 4 && pos[ 4 ] === - 5 && pos[ 5 ] === 6, "vertices were rotated around y by 180 degrees" );
  180. geometry.rotateZ( 180 * DegToRad );
  181. // vertices were rotated around z so all items should be flipped again but the z ones
  182. assert.ok( pos[ 0 ] === 1 && pos[ 1 ] === 2 && pos[ 2 ] === 3 &&
  183. pos[ 3 ] === 4 && pos[ 4 ] === 5 && pos[ 5 ] === 6, "vertices were rotated around z by 180 degrees" );
  184. } );
  185. QUnit.test( "translate", ( assert ) => {
  186. var geometry = new BufferGeometry();
  187. geometry.setAttribute( "position", new BufferAttribute( new Float32Array( [ 1, 2, 3, 4, 5, 6 ] ), 3 ) );
  188. var pos = geometry.attributes.position.array;
  189. geometry.translate( 10, 20, 30 );
  190. assert.ok( pos[ 0 ] === 11 && pos[ 1 ] === 22 && pos[ 2 ] === 33 &&
  191. pos[ 3 ] === 14 && pos[ 4 ] === 25 && pos[ 5 ] === 36, "vertices were translated" );
  192. } );
  193. QUnit.test( "scale", ( assert ) => {
  194. var geometry = new BufferGeometry();
  195. geometry.setAttribute( "position", new BufferAttribute( new Float32Array( [ - 1, - 1, - 1, 2, 2, 2 ] ), 3 ) );
  196. var pos = geometry.attributes.position.array;
  197. geometry.scale( 1, 2, 3 );
  198. assert.ok( pos[ 0 ] === - 1 && pos[ 1 ] === - 2 && pos[ 2 ] === - 3 &&
  199. pos[ 3 ] === 2 && pos[ 4 ] === 4 && pos[ 5 ] === 6, "vertices were scaled" );
  200. } );
  201. QUnit.test( "lookAt", ( assert ) => {
  202. var a = new BufferGeometry();
  203. var vertices = new Float32Array( [
  204. - 1.0, - 1.0, 1.0,
  205. 1.0, - 1.0, 1.0,
  206. 1.0, 1.0, 1.0,
  207. 1.0, 1.0, 1.0,
  208. - 1.0, 1.0, 1.0,
  209. - 1.0, - 1.0, 1.0
  210. ] );
  211. a.setAttribute( 'position', new BufferAttribute( vertices, 3 ) );
  212. var sqrt = Math.sqrt( 2 );
  213. var expected = new Float32Array( [
  214. 1, 0, - sqrt,
  215. - 1, 0, - sqrt,
  216. - 1, sqrt, 0,
  217. - 1, sqrt, 0,
  218. 1, sqrt, 0,
  219. 1, 0, - sqrt
  220. ] );
  221. a.lookAt( new Vector3( 0, 1, - 1 ) );
  222. assert.ok( bufferAttributeEquals( a.attributes.position.array, expected ), "Rotation is correct" );
  223. } );
  224. QUnit.test( "center", ( assert ) => {
  225. var geometry = new BufferGeometry();
  226. geometry.setAttribute( "position", new BufferAttribute( new Float32Array( [
  227. - 1, - 1, - 1,
  228. 1, 1, 1,
  229. 4, 4, 4
  230. ] ), 3 ) );
  231. geometry.center();
  232. var pos = geometry.attributes.position.array;
  233. // the boundingBox should go from (-1, -1, -1) to (4, 4, 4) so it has a size of (5, 5, 5)
  234. // after centering it the vertices should be placed between (-2.5, -2.5, -2.5) and (2.5, 2.5, 2.5)
  235. assert.ok( pos[ 0 ] === - 2.5 && pos[ 1 ] === - 2.5 && pos[ 2 ] === - 2.5 &&
  236. pos[ 3 ] === - 0.5 && pos[ 4 ] === - 0.5 && pos[ 5 ] === - 0.5 &&
  237. pos[ 6 ] === 2.5 && pos[ 7 ] === 2.5 && pos[ 8 ] === 2.5, "vertices were replaced by boundingBox dimensions" );
  238. } );
  239. QUnit.test( "setFromObject", ( assert ) => {
  240. var lineGeo = new Geometry();
  241. lineGeo.vertices.push(
  242. new Vector3( - 10, 0, 0 ),
  243. new Vector3( 0, 10, 0 ),
  244. new Vector3( 10, 0, 0 )
  245. );
  246. lineGeo.colors.push(
  247. new Color( 1, 0, 0 ),
  248. new Color( 0, 1, 0 ),
  249. new Color( 0, 0, 1 )
  250. );
  251. var line = new Line( lineGeo, null );
  252. var geometry = new BufferGeometry().setFromObject( line );
  253. var pos = geometry.attributes.position.array;
  254. var col = geometry.attributes.color.array;
  255. var v = lineGeo.vertices;
  256. var c = lineGeo.colors;
  257. assert.ok(
  258. // position exists
  259. pos !== undefined &&
  260. // vertex arrays have the same size
  261. v.length * 3 === pos.length &&
  262. // there are three complete vertices (each vertex contains three values)
  263. geometry.attributes.position.count === 3 &&
  264. // check if both arrays contains the same data
  265. pos[ 0 ] === v[ 0 ].x && pos[ 1 ] === v[ 0 ].y && pos[ 2 ] === v[ 0 ].z &&
  266. pos[ 3 ] === v[ 1 ].x && pos[ 4 ] === v[ 1 ].y && pos[ 5 ] === v[ 1 ].z &&
  267. pos[ 6 ] === v[ 2 ].x && pos[ 7 ] === v[ 2 ].y && pos[ 8 ] === v[ 2 ].z
  268. , "positions are equal" );
  269. assert.ok(
  270. // color exists
  271. col !== undefined &&
  272. // color arrays have the same size
  273. c.length * 3 === col.length &&
  274. // there are three complete colors (each color contains three values)
  275. geometry.attributes.color.count === 3 &&
  276. // check if both arrays contains the same data
  277. col[ 0 ] === c[ 0 ].r && col[ 1 ] === c[ 0 ].g && col[ 2 ] === c[ 0 ].b &&
  278. col[ 3 ] === c[ 1 ].r && col[ 4 ] === c[ 1 ].g && col[ 5 ] === c[ 1 ].b &&
  279. col[ 6 ] === c[ 2 ].r && col[ 7 ] === c[ 2 ].g && col[ 8 ] === c[ 2 ].b
  280. , "colors are equal" );
  281. } );
  282. QUnit.test( "setFromObject (more)", ( assert ) => {
  283. var lineGeo = new Geometry();
  284. lineGeo.vertices.push(
  285. new Vector3( - 10, 0, 0 ),
  286. new Vector3( 0, 10, 0 ),
  287. new Vector3( 10, 0, 0 )
  288. );
  289. lineGeo.colors.push(
  290. new Color( 1, 0, 0 ),
  291. new Color( 0, 1, 0 ),
  292. new Color( 0, 0, 1 )
  293. );
  294. lineGeo.computeBoundingBox();
  295. lineGeo.computeBoundingSphere();
  296. var line = new Line( lineGeo );
  297. var geometry = new BufferGeometry().setFromObject( line );
  298. assert.ok( geometry.boundingBox.equals( lineGeo.boundingBox ), "BoundingBox was set correctly" );
  299. assert.ok( geometry.boundingSphere.equals( lineGeo.boundingSphere ), "BoundingSphere was set correctly" );
  300. var pos = geometry.attributes.position.array;
  301. var col = geometry.attributes.color.array;
  302. var v = lineGeo.vertices;
  303. var c = lineGeo.colors;
  304. // adapted from setFromObject QUnit.test (way up)
  305. assert.notStrictEqual( pos, undefined, "Position attribute exists" );
  306. assert.strictEqual( v.length * 3, pos.length, "Vertex arrays have the same size" );
  307. assert.strictEqual( geometry.attributes.position.count, 3, "Correct number of vertices" );
  308. assert.ok( comparePositions( pos, v ), "Positions are identical" );
  309. assert.notStrictEqual( col, undefined, "Color attribute exists" );
  310. assert.strictEqual( c.length * 3, col.length, "Color arrays have the same size" );
  311. assert.strictEqual( geometry.attributes.color.count, 3, "Correct number of colors" );
  312. assert.ok( compareColors( col, c ), "Colors are identical" );
  313. // setFromObject with a Mesh as object
  314. lineGeo.faces.push( new Face3( 0, 1, 2 ) );
  315. var lineMesh = new Mesh( lineGeo );
  316. var geometry = new BufferGeometry().setFromObject( lineMesh );
  317. // no colors
  318. var pos = geometry.attributes.position.array;
  319. var v = lineGeo.vertices;
  320. assert.notStrictEqual( pos, undefined, "Mesh: position attribute exists" );
  321. assert.strictEqual( v.length * 3, pos.length, "Mesh: vertex arrays have the same size" );
  322. assert.strictEqual( geometry.attributes.position.count, 3, "Mesh: correct number of vertices" );
  323. assert.ok( comparePositions( pos, v ), "Mesh: positions are identical" );
  324. } );
  325. QUnit.test( "updateFromObject", ( assert ) => {
  326. var geo = new Geometry();
  327. geo.vertices.push(
  328. new Vector3( - 10, 0, 0 ),
  329. new Vector3( 0, 10, 0 ),
  330. new Vector3( 10, 0, 0 )
  331. );
  332. geo.faces.push( new Face3( 0, 1, 2 ) );
  333. geo.faces[ 0 ].vertexColors.push(
  334. new Color( 1, 0, 0 ),
  335. new Color( 0, 1, 0 ),
  336. new Color( 0, 0, 1 )
  337. );
  338. geo.faceVertexUvs[ 0 ] = [
  339. [
  340. new Vector2( 0, 0 ),
  341. new Vector2( 1, 0 ),
  342. new Vector2( 1, 1 )
  343. ]
  344. ];
  345. geo.computeFaceNormals();
  346. geo.computeVertexNormals();
  347. geo.verticesNeedUpdate = true;
  348. geo.normalsNeedUpdate = true;
  349. geo.colorsNeedUpdate = true;
  350. geo.uvsNeedUpdate = true;
  351. geo.groupsNeedUpdate = true;
  352. var mesh = new Mesh( geo );
  353. var geometry = new BufferGeometry();
  354. geometry.updateFromObject( mesh ); // first call to create the underlying structure (DirectGeometry)
  355. geometry.updateFromObject( mesh ); // second time to actually go thru the motions and update
  356. var pos = geometry.attributes.position.array;
  357. var col = geometry.attributes.color.array;
  358. var norm = geometry.attributes.normal.array;
  359. var uvs = geometry.attributes.uv.array;
  360. var v = geo.vertices;
  361. var c = geo.faces[ 0 ].vertexColors;
  362. var n = geo.faces[ 0 ].vertexNormals;
  363. var u = geo.faceVertexUvs[ 0 ][ 0 ];
  364. assert.notStrictEqual( pos, undefined, "Position attribute exists" );
  365. assert.strictEqual( v.length * 3, pos.length, "Both arrays have the same size" );
  366. assert.strictEqual( geometry.attributes.position.count, v.length, "Correct number of vertices" );
  367. assert.ok( comparePositions( pos, v ), "Positions are identical" );
  368. assert.notStrictEqual( col, undefined, "Color attribute exists" );
  369. assert.strictEqual( c.length * 3, col.length, "Both arrays have the same size" );
  370. assert.strictEqual( geometry.attributes.color.count, c.length, "Correct number of colors" );
  371. assert.ok( compareColors( col, c ), "Colors are identical" );
  372. assert.notStrictEqual( norm, undefined, "Normal attribute exists" );
  373. assert.strictEqual( n.length * 3, norm.length, "Both arrays have the same size" );
  374. assert.strictEqual( geometry.attributes.normal.count, n.length, "Correct number of normals" );
  375. assert.ok( comparePositions( norm, n ), "Normals are identical" );
  376. assert.notStrictEqual( uvs, undefined, "UV attribute exists" );
  377. assert.strictEqual( u.length * 2, uvs.length, "Both arrays have the same size" );
  378. assert.strictEqual( geometry.attributes.uv.count, u.length, "Correct number of UV coordinates" );
  379. assert.ok( compareUvs( uvs, u ), "UVs are identical" );
  380. } );
  381. QUnit.test( "fromGeometry/fromDirectGeometry", ( assert ) => {
  382. // geometry definition
  383. var geometry = new Geometry();
  384. // vertices
  385. var v1 = new Vector3( 1, - 1, 0 );
  386. var v2 = new Vector3( 1, 1, 0 );
  387. var v3 = new Vector3( - 1, 1, 0 );
  388. var v4 = new Vector3( - 1, - 1, 0 );
  389. // faces, normals and colors
  390. geometry.vertices.push( v1, v2, v3, v4 );
  391. var f1 = new Face3( 0, 1, 2 );
  392. f1.normal.set( 0, 0, 1 );
  393. f1.color.set( 0xff0000 );
  394. var f2 = new Face3( 2, 3, 0 );
  395. f2.normal.set( 0, 0, 1 );
  396. f2.color.set( 0xff0000 );
  397. geometry.faces.push( f1, f2 );
  398. // uvs
  399. var uvs = geometry.faceVertexUvs[ 0 ];
  400. uvs.length = 0;
  401. uvs.push( [
  402. new Vector2( 1, 0 ),
  403. new Vector2( 1, 1 ),
  404. new Vector2( 0, 1 )
  405. ] );
  406. uvs.push( [
  407. new Vector2( 0, 1 ),
  408. new Vector2( 0, 0 ),
  409. new Vector2( 1, 0 )
  410. ] );
  411. // skin weights
  412. var sw1 = new Vector4( 0.8, 0.2, 0, 0 );
  413. var sw2 = new Vector4( 0.7, 0.2, 0.1, 0 );
  414. var sw3 = new Vector4( 0.8, 0.1, 0.1, 0 );
  415. var sw4 = new Vector4( 1, 0, 0, 0 );
  416. geometry.skinWeights.push( sw1, sw2, sw3, sw4 );
  417. // skin indices
  418. var si1 = new Vector4( 0, 1, 2, 3 );
  419. var si2 = new Vector4( 2, 3, 4, 5 );
  420. var si3 = new Vector4( 4, 5, 6, 7 );
  421. var si4 = new Vector4( 6, 7, 8, 9 );
  422. geometry.skinIndices.push( si1, si2, si3, si4 );
  423. // create BufferGeometry
  424. var bufferGeometry = new BufferGeometry().fromGeometry( geometry );
  425. // expected values
  426. var vertices = new Float32Array( [ 1, - 1, 0, 1, 1, 0, - 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ] );
  427. var normals = new Float32Array( [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 ] );
  428. var colors = new Float32Array( [ 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 ] );
  429. var uvs = new Float32Array( [ 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0 ] );
  430. var skinIndices = new Float32Array( [ 0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 4, 5, 6, 7, 6, 7, 8, 9, 0, 1, 2, 3 ] );
  431. var skindWeights = new Float32Array( [
  432. 0.8, 0.2, 0, 0, 0.7, 0.2, 0.1, 0, 0.8, 0.1, 0.1, 0,
  433. 0.8, 0.1, 0.1, 0, 1, 0, 0, 0, 0.8, 0.2, 0, 0
  434. ] );
  435. var attributes = bufferGeometry.attributes;
  436. assert.deepEqual( attributes.position.array, vertices, "Vertices are as expected" );
  437. assert.deepEqual( attributes.normal.array, normals, "Normals are as expected" );
  438. assert.deepEqual( attributes.color.array, colors, "Colors are as expected" );
  439. assert.deepEqual( attributes.uv.array, uvs, "Texture coordinates are as expected" );
  440. assert.deepEqual( attributes.skinIndex.array, skinIndices, "Skin indices are as expected" );
  441. assert.deepEqual( attributes.skinWeight.array, skindWeights, "Skin weights are as expected" );
  442. } );
  443. QUnit.test( "computeBoundingBox", ( assert ) => {
  444. var bb = getBBForVertices( [ - 1, - 2, - 3, 13, - 2, - 3.5, - 1, - 20, 0, - 4, 5, 6 ] );
  445. assert.ok( bb.min.x === - 4 && bb.min.y === - 20 && bb.min.z === - 3.5, "min values are set correctly" );
  446. assert.ok( bb.max.x === 13 && bb.max.y === 5 && bb.max.z === 6, "max values are set correctly" );
  447. var bb = getBBForVertices( [ - 1, - 1, - 1 ] );
  448. assert.ok( bb.min.x === bb.max.x && bb.min.y === bb.max.y && bb.min.z === bb.max.z, "since there is only one vertex, max and min are equal" );
  449. assert.ok( bb.min.x === - 1 && bb.min.y === - 1 && bb.min.z === - 1, "since there is only one vertex, min and max are this vertex" );
  450. } );
  451. QUnit.test( "computeBoundingSphere", ( assert ) => {
  452. var bs = getBSForVertices( [ - 10, 0, 0, 10, 0, 0 ] );
  453. assert.ok( bs.radius === ( 10 + 10 ) / 2, "radius is equal to deltaMinMax / 2" );
  454. assert.ok( bs.center.x === 0 && bs.center.y === 0 && bs.center.y === 0, "bounding sphere is at ( 0, 0, 0 )" );
  455. var bs = getBSForVertices( [ - 5, 11, - 3, 5, - 11, 3 ] );
  456. var radius = new Vector3( 5, 11, 3 ).length();
  457. assert.ok( bs.radius === radius, "radius is equal to directionLength" );
  458. assert.ok( bs.center.x === 0 && bs.center.y === 0 && bs.center.y === 0, "bounding sphere is at ( 0, 0, 0 )" );
  459. } );
  460. QUnit.todo( "computeFaceNormals", ( assert ) => {
  461. assert.ok( false, "everything's gonna be alright" );
  462. } );
  463. QUnit.test( "computeVertexNormals", ( assert ) => {
  464. // get normals for a counter clockwise created triangle
  465. var normals = getNormalsForVertices( [ - 1, 0, 0, 1, 0, 0, 0, 1, 0 ], assert );
  466. assert.ok( normals[ 0 ] === 0 && normals[ 1 ] === 0 && normals[ 2 ] === 1,
  467. "first normal is pointing to screen since the the triangle was created counter clockwise" );
  468. assert.ok( normals[ 3 ] === 0 && normals[ 4 ] === 0 && normals[ 5 ] === 1,
  469. "second normal is pointing to screen since the the triangle was created counter clockwise" );
  470. assert.ok( normals[ 6 ] === 0 && normals[ 7 ] === 0 && normals[ 8 ] === 1,
  471. "third normal is pointing to screen since the the triangle was created counter clockwise" );
  472. // get normals for a clockwise created triangle
  473. var normals = getNormalsForVertices( [ 1, 0, 0, - 1, 0, 0, 0, 1, 0 ], assert );
  474. assert.ok( normals[ 0 ] === 0 && normals[ 1 ] === 0 && normals[ 2 ] === - 1,
  475. "first normal is pointing to screen since the the triangle was created clockwise" );
  476. assert.ok( normals[ 3 ] === 0 && normals[ 4 ] === 0 && normals[ 5 ] === - 1,
  477. "second normal is pointing to screen since the the triangle was created clockwise" );
  478. assert.ok( normals[ 6 ] === 0 && normals[ 7 ] === 0 && normals[ 8 ] === - 1,
  479. "third normal is pointing to screen since the the triangle was created clockwise" );
  480. var normals = getNormalsForVertices( [ 0, 0, 1, 0, 0, - 1, 1, 1, 0 ], assert );
  481. // the triangle is rotated by 45 degrees to the right so the normals of the three vertices
  482. // should point to (1, -1, 0).normalized(). The simplest solution is to check against a normalized
  483. // vector (1, -1, 0) but you will get calculation errors because of floating calculations so another
  484. // valid technique is to create a vector which stands in 90 degrees to the normals and calculate the
  485. // dot product which is the cos of the angle between them. This should be < floating calculation error
  486. // which can be taken from Number.EPSILON
  487. var direction = new Vector3( 1, 1, 0 ).normalize(); // a vector which should have 90 degrees difference to normals
  488. var difference = direction.dot( new Vector3( normals[ 0 ], normals[ 1 ], normals[ 2 ] ) );
  489. assert.ok( difference < Number.EPSILON, "normal is equal to reference vector" );
  490. // get normals for a line should be NAN because you need min a triangle to calculate normals
  491. var normals = getNormalsForVertices( [ 1, 0, 0, - 1, 0, 0 ], assert );
  492. for ( var i = 0; i < normals.length; i ++ ) {
  493. assert.ok( ! normals[ i ], "normals can't be calculated which is good" );
  494. }
  495. } );
  496. QUnit.test( "computeVertexNormals (indexed)", ( assert ) => {
  497. var sqrt = 0.5 * Math.sqrt( 2 );
  498. var normal = new BufferAttribute( new Float32Array( [
  499. - 1, 0, 0, - 1, 0, 0, - 1, 0, 0,
  500. sqrt, sqrt, 0, sqrt, sqrt, 0, sqrt, sqrt, 0,
  501. - 1, 0, 0
  502. ] ), 3 );
  503. var position = new BufferAttribute( new Float32Array( [
  504. 0.5, 0.5, 0.5, 0.5, 0.5, - 0.5, 0.5, - 0.5, 0.5,
  505. 0.5, - 0.5, - 0.5, - 0.5, 0.5, - 0.5, - 0.5, 0.5, 0.5,
  506. - 0.5, - 0.5, - 0.5
  507. ] ), 3 );
  508. var index = new BufferAttribute( new Uint16Array( [
  509. 0, 2, 1, 2, 3, 1, 4, 6, 5, 6, 7, 5
  510. ] ), 1 );
  511. var a = new BufferGeometry();
  512. a.setAttribute( "position", position );
  513. a.computeVertexNormals();
  514. assert.ok(
  515. bufferAttributeEquals( normal, a.getAttribute( "normal" ) ),
  516. "Regular geometry: first computed normals are correct"
  517. );
  518. // a second time to see if the existing normals get properly deleted
  519. a.computeVertexNormals();
  520. assert.ok(
  521. bufferAttributeEquals( normal, a.getAttribute( "normal" ) ),
  522. "Regular geometry: second computed normals are correct"
  523. );
  524. // indexed geometry
  525. var a = new BufferGeometry();
  526. a.setAttribute( "position", position );
  527. a.setIndex( index );
  528. a.computeVertexNormals();
  529. assert.ok( bufferAttributeEquals( normal, a.getAttribute( "normal" ) ), "Indexed geometry: computed normals are correct" );
  530. } );
  531. QUnit.test( "merge", ( assert ) => {
  532. var geometry1 = new BufferGeometry();
  533. geometry1.setAttribute( "attrName", new BufferAttribute( new Float32Array( [ 1, 2, 3, 0, 0, 0 ] ), 3 ) );
  534. var geometry2 = new BufferGeometry();
  535. geometry2.setAttribute( "attrName", new BufferAttribute( new Float32Array( [ 4, 5, 6 ] ), 3 ) );
  536. var attr = geometry1.attributes.attrName.array;
  537. geometry1.merge( geometry2, 1 );
  538. // merged array should be 1, 2, 3, 4, 5, 6
  539. for ( var i = 0; i < attr.length; i ++ ) {
  540. assert.ok( attr[ i ] === i + 1, "" );
  541. }
  542. geometry1.merge( geometry2 );
  543. assert.ok( attr[ 0 ] === 4 && attr[ 1 ] === 5 && attr[ 2 ] === 6, "copied the 3 attributes without offset" );
  544. } );
  545. QUnit.todo( "normalizeNormals", ( assert ) => {
  546. assert.ok( false, "everything's gonna be alright" );
  547. } );
  548. QUnit.test( "toNonIndexed", ( assert ) => {
  549. var geometry = new BufferGeometry();
  550. var vertices = new Float32Array( [
  551. 0.5, 0.5, 0.5, 0.5, 0.5, - 0.5, 0.5, - 0.5, 0.5, 0.5, - 0.5, - 0.5
  552. ] );
  553. var index = new BufferAttribute( new Uint16Array( [ 0, 2, 1, 2, 3, 1 ] ) );
  554. var expected = new Float32Array( [
  555. 0.5, 0.5, 0.5, 0.5, - 0.5, 0.5, 0.5, 0.5, - 0.5,
  556. 0.5, - 0.5, 0.5, 0.5, - 0.5, - 0.5, 0.5, 0.5, - 0.5
  557. ] );
  558. geometry.setAttribute( 'position', new BufferAttribute( vertices, 3 ) );
  559. geometry.setIndex( index );
  560. var nonIndexed = geometry.toNonIndexed();
  561. assert.deepEqual( nonIndexed.getAttribute( "position" ).array, expected, "Expected vertices" );
  562. } );
  563. QUnit.test( "toJSON", ( assert ) => {
  564. var index = new BufferAttribute( new Uint16Array( [ 0, 1, 2, 3 ] ), 1 );
  565. var attribute1 = new BufferAttribute( new Uint16Array( [ 1, 3, 5, 7 ] ), 1 );
  566. attribute1.name = "attribute1";
  567. var a = new BufferGeometry();
  568. a.name = "JSONQUnit.test";
  569. // a.parameters = { "placeholder": 0 };
  570. a.setAttribute( "attribute1", attribute1 );
  571. a.setIndex( index );
  572. a.addGroup( 0, 1, 2 );
  573. a.boundingSphere = new Sphere( new Vector3( x, y, z ), 0.5 );
  574. var j = a.toJSON();
  575. var gold = {
  576. "metadata": {
  577. "version": 4.5,
  578. "type": "BufferGeometry",
  579. "generator": "BufferGeometry.toJSON"
  580. },
  581. "uuid": a.uuid,
  582. "type": "BufferGeometry",
  583. "name": "JSONQUnit.test",
  584. "data": {
  585. "attributes": {
  586. "attribute1": {
  587. "itemSize": 1,
  588. "type": "Uint16Array",
  589. "array": [ 1, 3, 5, 7 ],
  590. "normalized": false,
  591. "name": "attribute1"
  592. }
  593. },
  594. "index": {
  595. "type": "Uint16Array",
  596. "array": [ 0, 1, 2, 3 ]
  597. },
  598. "groups": [
  599. {
  600. "start": 0,
  601. "count": 1,
  602. "materialIndex": 2
  603. }
  604. ],
  605. "boundingSphere": {
  606. "center": [ 2, 3, 4 ],
  607. "radius": 0.5
  608. }
  609. }
  610. };
  611. assert.deepEqual( j, gold, "Generated JSON is as expected" );
  612. // add morphAttributes
  613. a.morphAttributes.attribute1 = [];
  614. a.morphAttributes.attribute1.push( attribute1.clone() );
  615. j = a.toJSON();
  616. gold.data.morphAttributes = {
  617. "attribute1": [ {
  618. "itemSize": 1,
  619. "type": "Uint16Array",
  620. "array": [ 1, 3, 5, 7 ],
  621. "normalized": false,
  622. "name": "attribute1"
  623. } ]
  624. };
  625. gold.data.morphTargetsRelative = false;
  626. assert.deepEqual( j, gold, "Generated JSON with morphAttributes is as expected" );
  627. } );
  628. QUnit.test( "clone", ( assert ) => {
  629. var a = new BufferGeometry();
  630. a.setAttribute( "attribute1", new BufferAttribute( new Float32Array( [ 1, 2, 3, 4, 5, 6 ] ), 3 ) );
  631. a.setAttribute( "attribute2", new BufferAttribute( new Float32Array( [ 0, 1, 3, 5, 6 ] ), 1 ) );
  632. a.addGroup( 0, 1, 2 );
  633. a.computeBoundingBox();
  634. a.computeBoundingSphere();
  635. a.setDrawRange( 0, 1 );
  636. var b = a.clone();
  637. assert.notEqual( a, b, "A new object was created" );
  638. assert.notEqual( a.id, b.id, "New object has a different GUID" );
  639. assert.strictEqual(
  640. Object.keys( a.attributes ).count, Object.keys( b.attributes ).count,
  641. "Both objects have the same amount of attributes"
  642. );
  643. assert.ok(
  644. bufferAttributeEquals( a.getAttribute( "attribute1" ), b.getAttribute( "attribute1" ) ),
  645. "First attributes buffer is identical"
  646. );
  647. assert.ok(
  648. bufferAttributeEquals( a.getAttribute( "attribute2" ), b.getAttribute( "attribute2" ) ),
  649. "Second attributes buffer is identical"
  650. );
  651. assert.deepEqual( a.groups, b.groups, "Groups are identical" );
  652. assert.ok( a.boundingBox.equals( b.boundingBox ), "BoundingBoxes are equal" );
  653. assert.ok( a.boundingSphere.equals( b.boundingSphere ), "BoundingSpheres are equal" );
  654. assert.strictEqual( a.drawRange.start, b.drawRange.start, "DrawRange start is identical" );
  655. assert.strictEqual( a.drawRange.count, b.drawRange.count, "DrawRange count is identical" );
  656. } );
  657. QUnit.test( "copy", ( assert ) => {
  658. var geometry = new BufferGeometry();
  659. geometry.setAttribute( "attrName", new BufferAttribute( new Float32Array( [ 1, 2, 3, 4, 5, 6 ] ), 3 ) );
  660. geometry.setAttribute( "attrName2", new BufferAttribute( new Float32Array( [ 0, 1, 3, 5, 6 ] ), 1 ) );
  661. var copy = new BufferGeometry().copy( geometry );
  662. assert.ok( copy !== geometry && geometry.id !== copy.id, "new object was created" );
  663. Object.keys( geometry.attributes ).forEach( function ( key ) {
  664. var attribute = geometry.attributes[ key ];
  665. assert.ok( attribute !== undefined, "all attributes where copied" );
  666. for ( var i = 0; i < attribute.array.length; i ++ ) {
  667. assert.ok( attribute.array[ i ] === copy.attributes[ key ].array[ i ], "values of the attribute are equal" );
  668. }
  669. } );
  670. } );
  671. QUnit.todo( "dispose", ( assert ) => {
  672. assert.ok( false, "everything's gonna be alright" );
  673. } );
  674. } );
  675. } );