TubePainter.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /**
  2. * @author mr.doob / http://mrdoob.com/
  3. */
  4. import {
  5. BufferAttribute,
  6. BufferGeometry,
  7. Color,
  8. DynamicDrawUsage,
  9. Mesh,
  10. MeshStandardMaterial,
  11. Vector3,
  12. VertexColors
  13. } from '../../../build/three.module.js';
  14. function TubePainter() {
  15. const BUFFER_SIZE = 1000000 * 3;
  16. let positions = new BufferAttribute( new Float32Array( BUFFER_SIZE ), 3 );
  17. positions.usage = DynamicDrawUsage;
  18. let normals = new BufferAttribute( new Float32Array( BUFFER_SIZE ), 3 );
  19. normals.usage = DynamicDrawUsage;
  20. let colors = new BufferAttribute( new Float32Array( BUFFER_SIZE ), 3 );
  21. colors.usage = DynamicDrawUsage;
  22. let geometry = new BufferGeometry();
  23. geometry.setAttribute( 'position', positions );
  24. geometry.setAttribute( 'normal', normals );
  25. geometry.setAttribute( 'color', colors );
  26. geometry.drawRange.count = 0;
  27. let material = new MeshStandardMaterial( {
  28. roughness: 0.9,
  29. metalness: 0.0,
  30. vertexColors: VertexColors
  31. } );
  32. let mesh = new Mesh( geometry, material );
  33. mesh.frustumCulled = false;
  34. //
  35. function getPoints( size ) {
  36. let PI2 = Math.PI * 2;
  37. let sides = 10;
  38. let array = [];
  39. let radius = 0.01 * size;
  40. for ( let i = 0; i < sides; i ++ ) {
  41. let angle = ( i / sides ) * PI2;
  42. array.push( new Vector3( Math.sin( angle ) * radius, Math.cos( angle ) * radius, 0 ) );
  43. }
  44. return array;
  45. }
  46. let vector1 = new Vector3();
  47. let vector2 = new Vector3();
  48. let vector3 = new Vector3();
  49. let vector4 = new Vector3();
  50. let color = new Color( 0xffffff );
  51. let size = 1;
  52. function stroke( position1, position2, matrix1, matrix2 ) {
  53. if ( position1.distanceToSquared( position2 ) === 0 ) return;
  54. let count = geometry.drawRange.count;
  55. let points = getPoints( size );
  56. for ( let i = 0, il = points.length; i < il; i ++ ) {
  57. let vertex1 = points[ i ];
  58. let vertex2 = points[ ( i + 1 ) % il ];
  59. // positions
  60. vector1.copy( vertex1 ).applyMatrix4( matrix2 ).add( position2 );
  61. vector2.copy( vertex2 ).applyMatrix4( matrix2 ).add( position2 );
  62. vector3.copy( vertex2 ).applyMatrix4( matrix1 ).add( position1 );
  63. vector4.copy( vertex1 ).applyMatrix4( matrix1 ).add( position1 );
  64. vector1.toArray( positions.array, ( count + 0 ) * 3 );
  65. vector2.toArray( positions.array, ( count + 1 ) * 3 );
  66. vector4.toArray( positions.array, ( count + 2 ) * 3 );
  67. vector2.toArray( positions.array, ( count + 3 ) * 3 );
  68. vector3.toArray( positions.array, ( count + 4 ) * 3 );
  69. vector4.toArray( positions.array, ( count + 5 ) * 3 );
  70. // normals
  71. vector1.copy( vertex1 ).applyMatrix4( matrix2 ).normalize();
  72. vector2.copy( vertex2 ).applyMatrix4( matrix2 ).normalize();
  73. vector3.copy( vertex2 ).applyMatrix4( matrix1 ).normalize();
  74. vector4.copy( vertex1 ).applyMatrix4( matrix1 ).normalize();
  75. vector1.toArray( normals.array, ( count + 0 ) * 3 );
  76. vector2.toArray( normals.array, ( count + 1 ) * 3 );
  77. vector4.toArray( normals.array, ( count + 2 ) * 3 );
  78. vector2.toArray( normals.array, ( count + 3 ) * 3 );
  79. vector3.toArray( normals.array, ( count + 4 ) * 3 );
  80. vector4.toArray( normals.array, ( count + 5 ) * 3 );
  81. // colors
  82. color.toArray( colors.array, ( count + 0 ) * 3 );
  83. color.toArray( colors.array, ( count + 1 ) * 3 );
  84. color.toArray( colors.array, ( count + 2 ) * 3 );
  85. color.toArray( colors.array, ( count + 3 ) * 3 );
  86. color.toArray( colors.array, ( count + 4 ) * 3 );
  87. color.toArray( colors.array, ( count + 5 ) * 3 );
  88. count += 6;
  89. }
  90. geometry.drawRange.count = count;
  91. }
  92. function setSize( value ) {
  93. size = value;
  94. }
  95. function updateGeometry( start, end ) {
  96. if ( start === end ) return;
  97. let offset = start * 3;
  98. let count = ( end - start ) * 3;
  99. positions.updateRange.offset = offset;
  100. positions.updateRange.count = count;
  101. positions.needsUpdate = true;
  102. normals.updateRange.offset = offset;
  103. normals.updateRange.count = count;
  104. normals.needsUpdate = true;
  105. colors.updateRange.offset = offset;
  106. colors.updateRange.count = count;
  107. colors.needsUpdate = true;
  108. }
  109. return {
  110. mesh: mesh,
  111. stroke: stroke,
  112. setSize: setSize,
  113. updateGeometry: updateGeometry
  114. };
  115. }
  116. export { TubePainter };