223 lines
4.1 KiB
JavaScript
223 lines
4.1 KiB
JavaScript
|
/**
|
||
|
* @author jonobr1 / http://jonobr1.com
|
||
|
* @author Mugen87 / https://github.com/Mugen87
|
||
|
*/
|
||
|
|
||
|
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 () {
|
||
|
|
||
|
var data = Geometry.prototype.toJSON.call( this );
|
||
|
|
||
|
var 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
|
||
|
|
||
|
var indices = [];
|
||
|
var vertices = [];
|
||
|
var normals = [];
|
||
|
var uvs = [];
|
||
|
|
||
|
// helper variables
|
||
|
|
||
|
var groupStart = 0;
|
||
|
var groupCount = 0;
|
||
|
|
||
|
// allow single and array values for "shapes" parameter
|
||
|
|
||
|
if ( Array.isArray( shapes ) === false ) {
|
||
|
|
||
|
addShape( shapes );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
for ( var 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.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||
|
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
||
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
||
|
|
||
|
|
||
|
// helper functions
|
||
|
|
||
|
function addShape( shape ) {
|
||
|
|
||
|
var i, l, shapeHole;
|
||
|
|
||
|
var indexOffset = vertices.length / 3;
|
||
|
var points = shape.extractPoints( curveSegments );
|
||
|
|
||
|
var shapeVertices = points.shape;
|
||
|
var shapeHoles = points.holes;
|
||
|
|
||
|
// check direction of vertices
|
||
|
|
||
|
if ( ShapeUtils.isClockWise( shapeVertices ) === false ) {
|
||
|
|
||
|
shapeVertices = shapeVertices.reverse();
|
||
|
|
||
|
// also check if holes are in the opposite direction
|
||
|
|
||
|
for ( i = 0, l = shapeHoles.length; i < l; i ++ ) {
|
||
|
|
||
|
shapeHole = shapeHoles[ i ];
|
||
|
|
||
|
if ( ShapeUtils.isClockWise( shapeHole ) === true ) {
|
||
|
|
||
|
shapeHoles[ i ] = shapeHole.reverse();
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
var faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );
|
||
|
|
||
|
// join vertices of inner and outer paths to a single array
|
||
|
|
||
|
for ( i = 0, l = shapeHoles.length; i < l; i ++ ) {
|
||
|
|
||
|
shapeHole = shapeHoles[ i ];
|
||
|
shapeVertices = shapeVertices.concat( shapeHole );
|
||
|
|
||
|
}
|
||
|
|
||
|
// vertices, normals, uvs
|
||
|
|
||
|
for ( i = 0, l = shapeVertices.length; i < l; i ++ ) {
|
||
|
|
||
|
var 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 ( i = 0, l = faces.length; i < l; i ++ ) {
|
||
|
|
||
|
var face = faces[ i ];
|
||
|
|
||
|
var a = face[ 0 ] + indexOffset;
|
||
|
var b = face[ 1 ] + indexOffset;
|
||
|
var 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 () {
|
||
|
|
||
|
var data = BufferGeometry.prototype.toJSON.call( this );
|
||
|
|
||
|
var shapes = this.parameters.shapes;
|
||
|
|
||
|
return toJSON( shapes, data );
|
||
|
|
||
|
};
|
||
|
|
||
|
//
|
||
|
|
||
|
function toJSON( shapes, data ) {
|
||
|
|
||
|
data.shapes = [];
|
||
|
|
||
|
if ( Array.isArray( shapes ) ) {
|
||
|
|
||
|
for ( var i = 0, l = shapes.length; i < l; i ++ ) {
|
||
|
|
||
|
var shape = shapes[ i ];
|
||
|
|
||
|
data.shapes.push( shape.uuid );
|
||
|
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
data.shapes.push( shapes.uuid );
|
||
|
|
||
|
}
|
||
|
|
||
|
return data;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
export { ShapeGeometry, ShapeBufferGeometry };
|