ParametricGeometry.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /**
  2. * @author zz85 / https://github.com/zz85
  3. * @author Mugen87 / https://github.com/Mugen87
  4. *
  5. * Parametric Surfaces Geometry
  6. * based on the brilliant article by @prideout http://prideout.net/blog/?p=44
  7. */
  8. import { Geometry } from '../core/Geometry.js';
  9. import { BufferGeometry } from '../core/BufferGeometry.js';
  10. import { Float32BufferAttribute } from '../core/BufferAttribute.js';
  11. import { Vector3 } from '../math/Vector3.js';
  12. // ParametricGeometry
  13. function ParametricGeometry( func, slices, stacks ) {
  14. Geometry.call( this );
  15. this.type = 'ParametricGeometry';
  16. this.parameters = {
  17. func: func,
  18. slices: slices,
  19. stacks: stacks
  20. };
  21. this.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );
  22. this.mergeVertices();
  23. }
  24. ParametricGeometry.prototype = Object.create( Geometry.prototype );
  25. ParametricGeometry.prototype.constructor = ParametricGeometry;
  26. // ParametricBufferGeometry
  27. function ParametricBufferGeometry( func, slices, stacks ) {
  28. BufferGeometry.call( this );
  29. this.type = 'ParametricBufferGeometry';
  30. this.parameters = {
  31. func: func,
  32. slices: slices,
  33. stacks: stacks
  34. };
  35. // buffers
  36. var indices = [];
  37. var vertices = [];
  38. var normals = [];
  39. var uvs = [];
  40. var EPS = 0.00001;
  41. var normal = new Vector3();
  42. var p0 = new Vector3(), p1 = new Vector3();
  43. var pu = new Vector3(), pv = new Vector3();
  44. var i, j;
  45. if ( func.length < 3 ) {
  46. console.error( 'THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.' );
  47. }
  48. // generate vertices, normals and uvs
  49. var sliceCount = slices + 1;
  50. for ( i = 0; i <= stacks; i ++ ) {
  51. var v = i / stacks;
  52. for ( j = 0; j <= slices; j ++ ) {
  53. var u = j / slices;
  54. // vertex
  55. func( u, v, p0 );
  56. vertices.push( p0.x, p0.y, p0.z );
  57. // normal
  58. // approximate tangent vectors via finite differences
  59. if ( u - EPS >= 0 ) {
  60. func( u - EPS, v, p1 );
  61. pu.subVectors( p0, p1 );
  62. } else {
  63. func( u + EPS, v, p1 );
  64. pu.subVectors( p1, p0 );
  65. }
  66. if ( v - EPS >= 0 ) {
  67. func( u, v - EPS, p1 );
  68. pv.subVectors( p0, p1 );
  69. } else {
  70. func( u, v + EPS, p1 );
  71. pv.subVectors( p1, p0 );
  72. }
  73. // cross product of tangent vectors returns surface normal
  74. normal.crossVectors( pu, pv ).normalize();
  75. normals.push( normal.x, normal.y, normal.z );
  76. // uv
  77. uvs.push( u, v );
  78. }
  79. }
  80. // generate indices
  81. for ( i = 0; i < stacks; i ++ ) {
  82. for ( j = 0; j < slices; j ++ ) {
  83. var a = i * sliceCount + j;
  84. var b = i * sliceCount + j + 1;
  85. var c = ( i + 1 ) * sliceCount + j + 1;
  86. var d = ( i + 1 ) * sliceCount + j;
  87. // faces one and two
  88. indices.push( a, b, d );
  89. indices.push( b, c, d );
  90. }
  91. }
  92. // build geometry
  93. this.setIndex( indices );
  94. this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  95. this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
  96. this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
  97. }
  98. ParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
  99. ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;
  100. export { ParametricGeometry, ParametricBufferGeometry };
粤ICP备19079148号