BufferAttribute.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. import { Vector3 } from '../math/Vector3.js';
  2. import { Vector2 } from '../math/Vector2.js';
  3. import { denormalize, normalize } from '../math/MathUtils.js';
  4. import { StaticDrawUsage, FloatType } from '../constants.js';
  5. import { fromHalfFloat, toHalfFloat } from '../extras/DataUtils.js';
  6. const _vector = /*@__PURE__*/ new Vector3();
  7. const _vector2 = /*@__PURE__*/ new Vector2();
  8. class BufferAttribute {
  9. constructor( array, itemSize, normalized = false ) {
  10. if ( Array.isArray( array ) ) {
  11. throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
  12. }
  13. this.isBufferAttribute = true;
  14. this.name = '';
  15. this.array = array;
  16. this.itemSize = itemSize;
  17. this.count = array !== undefined ? array.length / itemSize : 0;
  18. this.normalized = normalized;
  19. this.usage = StaticDrawUsage;
  20. this.updateRange = { offset: 0, count: - 1 };
  21. this.gpuType = FloatType;
  22. this.version = 0;
  23. }
  24. onUploadCallback() {}
  25. set needsUpdate( value ) {
  26. if ( value === true ) this.version ++;
  27. }
  28. setUsage( value ) {
  29. this.usage = value;
  30. return this;
  31. }
  32. copy( source ) {
  33. this.name = source.name;
  34. this.array = new source.array.constructor( source.array );
  35. this.itemSize = source.itemSize;
  36. this.count = source.count;
  37. this.normalized = source.normalized;
  38. this.usage = source.usage;
  39. this.gpuType = source.gpuType;
  40. return this;
  41. }
  42. copyAt( index1, attribute, index2 ) {
  43. index1 *= this.itemSize;
  44. index2 *= attribute.itemSize;
  45. for ( let i = 0, l = this.itemSize; i < l; i ++ ) {
  46. this.array[ index1 + i ] = attribute.array[ index2 + i ];
  47. }
  48. return this;
  49. }
  50. copyArray( array ) {
  51. this.array.set( array );
  52. return this;
  53. }
  54. applyMatrix3( m ) {
  55. if ( this.itemSize === 2 ) {
  56. for ( let i = 0, l = this.count; i < l; i ++ ) {
  57. _vector2.fromBufferAttribute( this, i );
  58. _vector2.applyMatrix3( m );
  59. this.setXY( i, _vector2.x, _vector2.y );
  60. }
  61. } else if ( this.itemSize === 3 ) {
  62. for ( let i = 0, l = this.count; i < l; i ++ ) {
  63. _vector.fromBufferAttribute( this, i );
  64. _vector.applyMatrix3( m );
  65. this.setXYZ( i, _vector.x, _vector.y, _vector.z );
  66. }
  67. }
  68. return this;
  69. }
  70. applyMatrix4( m ) {
  71. for ( let i = 0, l = this.count; i < l; i ++ ) {
  72. _vector.fromBufferAttribute( this, i );
  73. _vector.applyMatrix4( m );
  74. this.setXYZ( i, _vector.x, _vector.y, _vector.z );
  75. }
  76. return this;
  77. }
  78. applyNormalMatrix( m ) {
  79. for ( let i = 0, l = this.count; i < l; i ++ ) {
  80. _vector.fromBufferAttribute( this, i );
  81. _vector.applyNormalMatrix( m );
  82. this.setXYZ( i, _vector.x, _vector.y, _vector.z );
  83. }
  84. return this;
  85. }
  86. transformDirection( m ) {
  87. for ( let i = 0, l = this.count; i < l; i ++ ) {
  88. _vector.fromBufferAttribute( this, i );
  89. _vector.transformDirection( m );
  90. this.setXYZ( i, _vector.x, _vector.y, _vector.z );
  91. }
  92. return this;
  93. }
  94. set( value, offset = 0 ) {
  95. // Matching BufferAttribute constructor, do not normalize the array.
  96. this.array.set( value, offset );
  97. return this;
  98. }
  99. getX( index ) {
  100. let x = this.array[ index * this.itemSize ];
  101. if ( this.normalized ) x = denormalize( x, this.array );
  102. return x;
  103. }
  104. setX( index, x ) {
  105. if ( this.normalized ) x = normalize( x, this.array );
  106. this.array[ index * this.itemSize ] = x;
  107. return this;
  108. }
  109. getY( index ) {
  110. let y = this.array[ index * this.itemSize + 1 ];
  111. if ( this.normalized ) y = denormalize( y, this.array );
  112. return y;
  113. }
  114. setY( index, y ) {
  115. if ( this.normalized ) y = normalize( y, this.array );
  116. this.array[ index * this.itemSize + 1 ] = y;
  117. return this;
  118. }
  119. getZ( index ) {
  120. let z = this.array[ index * this.itemSize + 2 ];
  121. if ( this.normalized ) z = denormalize( z, this.array );
  122. return z;
  123. }
  124. setZ( index, z ) {
  125. if ( this.normalized ) z = normalize( z, this.array );
  126. this.array[ index * this.itemSize + 2 ] = z;
  127. return this;
  128. }
  129. getW( index ) {
  130. let w = this.array[ index * this.itemSize + 3 ];
  131. if ( this.normalized ) w = denormalize( w, this.array );
  132. return w;
  133. }
  134. setW( index, w ) {
  135. if ( this.normalized ) w = normalize( w, this.array );
  136. this.array[ index * this.itemSize + 3 ] = w;
  137. return this;
  138. }
  139. setXY( index, x, y ) {
  140. index *= this.itemSize;
  141. if ( this.normalized ) {
  142. x = normalize( x, this.array );
  143. y = normalize( y, this.array );
  144. }
  145. this.array[ index + 0 ] = x;
  146. this.array[ index + 1 ] = y;
  147. return this;
  148. }
  149. setXYZ( index, x, y, z ) {
  150. index *= this.itemSize;
  151. if ( this.normalized ) {
  152. x = normalize( x, this.array );
  153. y = normalize( y, this.array );
  154. z = normalize( z, this.array );
  155. }
  156. this.array[ index + 0 ] = x;
  157. this.array[ index + 1 ] = y;
  158. this.array[ index + 2 ] = z;
  159. return this;
  160. }
  161. setXYZW( index, x, y, z, w ) {
  162. index *= this.itemSize;
  163. if ( this.normalized ) {
  164. x = normalize( x, this.array );
  165. y = normalize( y, this.array );
  166. z = normalize( z, this.array );
  167. w = normalize( w, this.array );
  168. }
  169. this.array[ index + 0 ] = x;
  170. this.array[ index + 1 ] = y;
  171. this.array[ index + 2 ] = z;
  172. this.array[ index + 3 ] = w;
  173. return this;
  174. }
  175. onUpload( callback ) {
  176. this.onUploadCallback = callback;
  177. return this;
  178. }
  179. clone() {
  180. return new this.constructor( this.array, this.itemSize ).copy( this );
  181. }
  182. toJSON() {
  183. const data = {
  184. itemSize: this.itemSize,
  185. type: this.array.constructor.name,
  186. array: Array.from( this.array ),
  187. normalized: this.normalized
  188. };
  189. if ( this.name !== '' ) data.name = this.name;
  190. if ( this.usage !== StaticDrawUsage ) data.usage = this.usage;
  191. if ( this.updateRange.offset !== 0 || this.updateRange.count !== - 1 ) data.updateRange = this.updateRange;
  192. return data;
  193. }
  194. }
  195. //
  196. class Int8BufferAttribute extends BufferAttribute {
  197. constructor( array, itemSize, normalized ) {
  198. super( new Int8Array( array ), itemSize, normalized );
  199. }
  200. }
  201. class Uint8BufferAttribute extends BufferAttribute {
  202. constructor( array, itemSize, normalized ) {
  203. super( new Uint8Array( array ), itemSize, normalized );
  204. }
  205. }
  206. class Uint8ClampedBufferAttribute extends BufferAttribute {
  207. constructor( array, itemSize, normalized ) {
  208. super( new Uint8ClampedArray( array ), itemSize, normalized );
  209. }
  210. }
  211. class Int16BufferAttribute extends BufferAttribute {
  212. constructor( array, itemSize, normalized ) {
  213. super( new Int16Array( array ), itemSize, normalized );
  214. }
  215. }
  216. class Uint16BufferAttribute extends BufferAttribute {
  217. constructor( array, itemSize, normalized ) {
  218. super( new Uint16Array( array ), itemSize, normalized );
  219. }
  220. }
  221. class Int32BufferAttribute extends BufferAttribute {
  222. constructor( array, itemSize, normalized ) {
  223. super( new Int32Array( array ), itemSize, normalized );
  224. }
  225. }
  226. class Uint32BufferAttribute extends BufferAttribute {
  227. constructor( array, itemSize, normalized ) {
  228. super( new Uint32Array( array ), itemSize, normalized );
  229. }
  230. }
  231. class Float16BufferAttribute extends BufferAttribute {
  232. constructor( array, itemSize, normalized ) {
  233. super( new Uint16Array( array ), itemSize, normalized );
  234. this.isFloat16BufferAttribute = true;
  235. }
  236. getX( index ) {
  237. let x = fromHalfFloat( this.array[ index * this.itemSize ] );
  238. if ( this.normalized ) x = denormalize( x, this.array );
  239. return x;
  240. }
  241. setX( index, x ) {
  242. if ( this.normalized ) x = normalize( x, this.array );
  243. this.array[ index * this.itemSize ] = toHalfFloat( x );
  244. return this;
  245. }
  246. getY( index ) {
  247. let y = fromHalfFloat( this.array[ index * this.itemSize + 1 ] );
  248. if ( this.normalized ) y = denormalize( y, this.array );
  249. return y;
  250. }
  251. setY( index, y ) {
  252. if ( this.normalized ) y = normalize( y, this.array );
  253. this.array[ index * this.itemSize + 1 ] = toHalfFloat( y );
  254. return this;
  255. }
  256. getZ( index ) {
  257. let z = fromHalfFloat( this.array[ index * this.itemSize + 2 ] );
  258. if ( this.normalized ) z = denormalize( z, this.array );
  259. return z;
  260. }
  261. setZ( index, z ) {
  262. if ( this.normalized ) z = normalize( z, this.array );
  263. this.array[ index * this.itemSize + 2 ] = toHalfFloat( z );
  264. return this;
  265. }
  266. getW( index ) {
  267. let w = fromHalfFloat( this.array[ index * this.itemSize + 3 ] );
  268. if ( this.normalized ) w = denormalize( w, this.array );
  269. return w;
  270. }
  271. setW( index, w ) {
  272. if ( this.normalized ) w = normalize( w, this.array );
  273. this.array[ index * this.itemSize + 3 ] = toHalfFloat( w );
  274. return this;
  275. }
  276. setXY( index, x, y ) {
  277. index *= this.itemSize;
  278. if ( this.normalized ) {
  279. x = normalize( x, this.array );
  280. y = normalize( y, this.array );
  281. }
  282. this.array[ index + 0 ] = toHalfFloat( x );
  283. this.array[ index + 1 ] = toHalfFloat( y );
  284. return this;
  285. }
  286. setXYZ( index, x, y, z ) {
  287. index *= this.itemSize;
  288. if ( this.normalized ) {
  289. x = normalize( x, this.array );
  290. y = normalize( y, this.array );
  291. z = normalize( z, this.array );
  292. }
  293. this.array[ index + 0 ] = toHalfFloat( x );
  294. this.array[ index + 1 ] = toHalfFloat( y );
  295. this.array[ index + 2 ] = toHalfFloat( z );
  296. return this;
  297. }
  298. setXYZW( index, x, y, z, w ) {
  299. index *= this.itemSize;
  300. if ( this.normalized ) {
  301. x = normalize( x, this.array );
  302. y = normalize( y, this.array );
  303. z = normalize( z, this.array );
  304. w = normalize( w, this.array );
  305. }
  306. this.array[ index + 0 ] = toHalfFloat( x );
  307. this.array[ index + 1 ] = toHalfFloat( y );
  308. this.array[ index + 2 ] = toHalfFloat( z );
  309. this.array[ index + 3 ] = toHalfFloat( w );
  310. return this;
  311. }
  312. }
  313. class Float32BufferAttribute extends BufferAttribute {
  314. constructor( array, itemSize, normalized ) {
  315. super( new Float32Array( array ), itemSize, normalized );
  316. }
  317. }
  318. class Float64BufferAttribute extends BufferAttribute {
  319. constructor( array, itemSize, normalized ) {
  320. super( new Float64Array( array ), itemSize, normalized );
  321. }
  322. }
  323. //
  324. export {
  325. Float64BufferAttribute,
  326. Float32BufferAttribute,
  327. Float16BufferAttribute,
  328. Uint32BufferAttribute,
  329. Int32BufferAttribute,
  330. Uint16BufferAttribute,
  331. Int16BufferAttribute,
  332. Uint8ClampedBufferAttribute,
  333. Uint8BufferAttribute,
  334. Int8BufferAttribute,
  335. BufferAttribute
  336. };