UNPKG

three

Version:

JavaScript 3D library

214 lines (120 loc) 4.13 kB
import { Geometry } from '../core/Geometry.js'; import { BufferGeometry } from '../core/BufferGeometry.js'; import { Float32BufferAttribute } from '../core/BufferAttribute.js'; import { ShapeUtils } from '../extras/ShapeUtils.js'; // ShapeGeometry function ShapeGeometry( shapes, curveSegments ) { Geometry.call( this ); this.type = 'ShapeGeometry'; if ( typeof curveSegments === 'object' ) { console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' ); curveSegments = curveSegments.curveSegments; } this.parameters = { shapes: shapes, curveSegments: curveSegments }; this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) ); this.mergeVertices(); } ShapeGeometry.prototype = Object.create( Geometry.prototype ); ShapeGeometry.prototype.constructor = ShapeGeometry; ShapeGeometry.prototype.toJSON = function () { const data = Geometry.prototype.toJSON.call( this ); const shapes = this.parameters.shapes; return toJSON( shapes, data ); }; // ShapeBufferGeometry function ShapeBufferGeometry( shapes, curveSegments ) { BufferGeometry.call( this ); this.type = 'ShapeBufferGeometry'; this.parameters = { shapes: shapes, curveSegments: curveSegments }; curveSegments = curveSegments || 12; // buffers const indices = []; const vertices = []; const normals = []; const uvs = []; // helper variables let groupStart = 0; let groupCount = 0; // allow single and array values for "shapes" parameter if ( Array.isArray( shapes ) === false ) { addShape( shapes ); } else { for ( let i = 0; i < shapes.length; i ++ ) { addShape( shapes[ i ] ); this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support groupStart += groupCount; groupCount = 0; } } // build geometry this.setIndex( indices ); this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); // helper functions function addShape( shape ) { const indexOffset = vertices.length / 3; const points = shape.extractPoints( curveSegments ); let shapeVertices = points.shape; const shapeHoles = points.holes; // check direction of vertices if ( ShapeUtils.isClockWise( shapeVertices ) === false ) { shapeVertices = shapeVertices.reverse(); } for ( let i = 0, l = shapeHoles.length; i < l; i ++ ) { const shapeHole = shapeHoles[ i ]; if ( ShapeUtils.isClockWise( shapeHole ) === true ) { shapeHoles[ i ] = shapeHole.reverse(); } } const faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles ); // join vertices of inner and outer paths to a single array for ( let i = 0, l = shapeHoles.length; i < l; i ++ ) { const shapeHole = shapeHoles[ i ]; shapeVertices = shapeVertices.concat( shapeHole ); } // vertices, normals, uvs for ( let i = 0, l = shapeVertices.length; i < l; i ++ ) { const vertex = shapeVertices[ i ]; vertices.push( vertex.x, vertex.y, 0 ); normals.push( 0, 0, 1 ); uvs.push( vertex.x, vertex.y ); // world uvs } // incides for ( let i = 0, l = faces.length; i < l; i ++ ) { const face = faces[ i ]; const a = face[ 0 ] + indexOffset; const b = face[ 1 ] + indexOffset; const c = face[ 2 ] + indexOffset; indices.push( a, b, c ); groupCount += 3; } } } ShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); ShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry; ShapeBufferGeometry.prototype.toJSON = function () { const data = BufferGeometry.prototype.toJSON.call( this ); const shapes = this.parameters.shapes; return toJSON( shapes, data ); }; // function toJSON( shapes, data ) { data.shapes = []; if ( Array.isArray( shapes ) ) { for ( let i = 0, l = shapes.length; i < l; i ++ ) { const shape = shapes[ i ]; data.shapes.push( shape.uuid ); } } else { data.shapes.push( shapes.uuid ); } return data; } export { ShapeGeometry, ShapeBufferGeometry };