ShapeGeometry.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /**
  2. * @author jonobr1 / http://jonobr1.com
  3. * @author Mugen87 / https://github.com/Mugen87
  4. */
  5. import { Geometry } from '../core/Geometry.js';
  6. import { BufferGeometry } from '../core/BufferGeometry.js';
  7. import { Float32BufferAttribute } from '../core/BufferAttribute.js';
  8. import { ShapeUtils } from '../extras/ShapeUtils.js';
  9. // ShapeGeometry
  10. function ShapeGeometry( shapes, curveSegments ) {
  11. Geometry.call( this );
  12. this.type = 'ShapeGeometry';
  13. if ( typeof curveSegments === 'object' ) {
  14. console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );
  15. curveSegments = curveSegments.curveSegments;
  16. }
  17. this.parameters = {
  18. shapes: shapes,
  19. curveSegments: curveSegments
  20. };
  21. this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );
  22. this.mergeVertices();
  23. }
  24. ShapeGeometry.prototype = Object.create( Geometry.prototype );
  25. ShapeGeometry.prototype.constructor = ShapeGeometry;
  26. // ShapeBufferGeometry
  27. function ShapeBufferGeometry( shapes, curveSegments ) {
  28. BufferGeometry.call( this );
  29. this.type = 'ShapeBufferGeometry';
  30. this.parameters = {
  31. shapes: shapes,
  32. curveSegments: curveSegments
  33. };
  34. curveSegments = curveSegments || 12;
  35. // buffers
  36. var indices = [];
  37. var vertices = [];
  38. var normals = [];
  39. var uvs = [];
  40. // helper variables
  41. var groupStart = 0;
  42. var groupCount = 0;
  43. // allow single and array values for "shapes" parameter
  44. if ( Array.isArray( shapes ) === false ) {
  45. addShape( shapes );
  46. } else {
  47. for ( var i = 0; i < shapes.length; i ++ ) {
  48. addShape( shapes[ i ] );
  49. this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support
  50. groupStart += groupCount;
  51. groupCount = 0;
  52. }
  53. }
  54. // build geometry
  55. this.setIndex( indices );
  56. this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  57. this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
  58. this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
  59. // helper functions
  60. function addShape( shape ) {
  61. var i, l, shapeHole;
  62. var indexOffset = vertices.length / 3;
  63. var points = shape.extractPoints( curveSegments );
  64. var shapeVertices = points.shape;
  65. var shapeHoles = points.holes;
  66. // check direction of vertices
  67. if ( ShapeUtils.isClockWise( shapeVertices ) === false ) {
  68. shapeVertices = shapeVertices.reverse();
  69. // also check if holes are in the opposite direction
  70. for ( i = 0, l = shapeHoles.length; i < l; i ++ ) {
  71. shapeHole = shapeHoles[ i ];
  72. if ( ShapeUtils.isClockWise( shapeHole ) === true ) {
  73. shapeHoles[ i ] = shapeHole.reverse();
  74. }
  75. }
  76. }
  77. var faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );
  78. // join vertices of inner and outer paths to a single array
  79. for ( i = 0, l = shapeHoles.length; i < l; i ++ ) {
  80. shapeHole = shapeHoles[ i ];
  81. shapeVertices = shapeVertices.concat( shapeHole );
  82. }
  83. // vertices, normals, uvs
  84. for ( i = 0, l = shapeVertices.length; i < l; i ++ ) {
  85. var vertex = shapeVertices[ i ];
  86. vertices.push( vertex.x, vertex.y, 0 );
  87. normals.push( 0, 0, 1 );
  88. uvs.push( vertex.x, vertex.y ); // world uvs
  89. }
  90. // incides
  91. for ( i = 0, l = faces.length; i < l; i ++ ) {
  92. var face = faces[ i ];
  93. var a = face[ 0 ] + indexOffset;
  94. var b = face[ 1 ] + indexOffset;
  95. var c = face[ 2 ] + indexOffset;
  96. indices.push( a, b, c );
  97. groupCount += 3;
  98. }
  99. }
  100. }
  101. ShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
  102. ShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;
  103. export { ShapeGeometry, ShapeBufferGeometry };