提交 7ea23ec3 编写于 作者: M Michael Herzog 提交者: Mr.doob

New ShapeBufferGeometry (#9970)

* ShapeBufferGeometry: Initial commit

* ShapeBufferGeometry: Clean up
上级 7dcba9b7
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<base href="../../" />
<script src="list.js"></script>
<script src="page.js"></script>
<link type="text/css" rel="stylesheet" href="page.css" />
</head>
<body>
[page:BufferGeometry] &rarr;
<h1>[name]</h1>
<div class="desc">Creates an one-sided polygonal geometry from one or more path shapes.</div>
<iframe id="scene" src="scenes/geometry-browser.html#ShapeBufferGeometry"></iframe>
<script>
// iOS iframe auto-resize workaround
if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
var scene = document.getElementById( 'scene' );
scene.style.width = getComputedStyle( scene ).width;
scene.style.height = getComputedStyle( scene ).height;
scene.setAttribute( 'scrolling', 'no' );
}
</script>
<h2>Example</h2>
<code>
var x = 0, y = 0;
var heartShape = new THREE.Shape();
heartShape.moveTo( x + 5, y + 5 );
heartShape.bezierCurveTo( x + 5, y + 5, x + 4, y, x, y );
heartShape.bezierCurveTo( x - 6, y, x - 6, y + 7,x - 6, y + 7 );
heartShape.bezierCurveTo( x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19 );
heartShape.bezierCurveTo( x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7 );
heartShape.bezierCurveTo( x + 16, y + 7, x + 16, y, x + 10, y );
heartShape.bezierCurveTo( x + 7, y, x + 5, y + 5, x + 5, y + 5 );
var geometry = new THREE.ShapeBufferGeometry( heartShape );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var mesh = new THREE.Mesh( geometry, material ) ;
scene.add( mesh );
</code>
<h2>Constructor</h2>
<h3>[name]([page:Array shapes], [page:Integer curveSegments])</h3>
<div>
shapes — [page:Array] of shapes or a single [page:Shape shape].<br />
curveSegments - [page:Integer] - Number of segments per shape. Default is 12.
</div>
<h2>Source</h2>
[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
</body>
</html>
......@@ -12,7 +12,7 @@
<h1>[name]</h1>
<div class="desc">Creates a one-sided polygonal geometry from one or more path shapes. Similar to [page:ExtrudeGeometry].</div>
<div class="desc">Creates an one-sided polygonal geometry from one or more path shapes.</div>
<iframe id="scene" src="scenes/geometry-browser.html#ShapeGeometry"></iframe>
......@@ -37,16 +37,19 @@
<code>
var length = 16, width = 12;
var x = 0, y = 0;
var shape = new THREE.Shape();
shape.moveTo( 0,0 );
shape.lineTo( 0, width );
shape.lineTo( length, width );
shape.lineTo( length, 0 );
shape.lineTo( 0, 0 );
var heartShape = new THREE.Shape();
var geometry = new THREE.ShapeGeometry( shape );
heartShape.moveTo( x + 5, y + 5 );
heartShape.bezierCurveTo( x + 5, y + 5, x + 4, y, x, y );
heartShape.bezierCurveTo( x - 6, y, x - 6, y + 7,x - 6, y + 7 );
heartShape.bezierCurveTo( x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19 );
heartShape.bezierCurveTo( x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7 );
heartShape.bezierCurveTo( x + 16, y + 7, x + 16, y, x + 10, y );
heartShape.bezierCurveTo( x + 7, y, x + 5, y + 5, x + 5, y + 5 );
var geometry = new THREE.ShapeGeometry( heartShape );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var mesh = new THREE.Mesh( geometry, material ) ;
scene.add( mesh );
......@@ -55,39 +58,12 @@
<h2>Constructor</h2>
<h3>[name]([page:Array shapes], [page:Object options])</h3>
<div>
shapes — [page:Array] of shapes, or a single [page:Shape shape] <br />
options — Optional options [page:Object object]
<ul>
<li>curveSegments - [page:Integer] - Not used at the moment - defaults to 12</li>
<li>material - [page:Integer] - index of the material in a material list</li>
<li>UVGenerator - A UV generator, defaults to [page:ExtrudeGeometry]'s WorldUVGenerator</li>
</ul>
</div>
<h2>Methods</h2>
<h3>.addShapeList([page:Array shapes], [page:Object options]) [page:this]</h3>
<div>
shapes — [page:Array] of [page:Shape shapes] <br />
options — See options in constructor
</div>
<h3>[name]([page:Array shapes], [page:Integer curveSegments])</h3>
<div>
Adds a list of shapes to the geometry.
shapes — [page:Array] of shapes or a single [page:Shape shape].<br />
curveSegments - [page:Integer] - Number of segments per shape. Default is 12.
</div>
<h3>[method:null addShape]([page:Shape shape], [page:Object options])</h3>
<div>
shape — [page:Shape] <br />
options — See options in constructor
</div>
<div>
Adds a single shape to the geometry
</div>
<h2>Source</h2>
......
......@@ -63,6 +63,7 @@ var list = {
[ "PolyhedronGeometry", "api/geometries/PolyhedronGeometry" ],
[ "RingBufferGeometry", "api/geometries/RingBufferGeometry" ],
[ "RingGeometry", "api/geometries/RingGeometry" ],
[ "ShapeBufferGeometry", "api/geometries/ShapeBufferGeometry" ],
[ "ShapeGeometry", "api/geometries/ShapeGeometry" ],
[ "SphereBufferGeometry", "api/geometries/SphereBufferGeometry" ],
[ "SphereGeometry", "api/geometries/SphereGeometry" ],
......
......@@ -111,6 +111,20 @@ var CustomSinCurve = THREE.Curve.create(
);
// heart shape
var x = 0, y = 0;
var heartShape = new THREE.Shape();
heartShape.moveTo( x + 5, y + 5 );
heartShape.bezierCurveTo( x + 5, y + 5, x + 4, y, x, y );
heartShape.bezierCurveTo( x - 6, y, x - 6, y + 7,x - 6, y + 7 );
heartShape.bezierCurveTo( x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19 );
heartShape.bezierCurveTo( x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7 );
heartShape.bezierCurveTo( x + 16, y + 7, x + 16, y, x + 10, y );
heartShape.bezierCurveTo( x + 7, y, x + 5, y + 5, x + 5, y + 5 );
var guis = {
BoxBufferGeometry : function( mesh ) {
......@@ -1206,24 +1220,41 @@ var guis = {
ShapeGeometry: function( mesh ) {
var length = 16, width = 12;
var shape = new THREE.Shape();
shape.moveTo( 0,0 );
shape.lineTo( 0, width );
shape.lineTo( length, width );
shape.lineTo( length, 0 );
shape.lineTo( 0, 0 );
var data = {
segments : 12
};
function generateGeometry() {
updateGroupGeometry( mesh,
new THREE.ShapeGeometry( shape )
new THREE.ShapeGeometry( heartShape, data.segments )
);
}
var folder = gui.addFolder( 'THREE.ShapeGeometry' );
folder.add( data, 'segments', 1, 100 ).step( 1 ).onChange( generateGeometry );
generateGeometry();
},
ShapeBufferGeometry: function( mesh ) {
var data = {
segments : 12
};
function generateGeometry() {
updateGroupGeometry( mesh,
new THREE.ShapeBufferGeometry( heartShape, data.segments )
);
}
var folder = gui.addFolder( 'THREE.ShapeBufferGeometry' );
folder.add( data, 'segments', 1, 100 ).step( 1 ).onChange( generateGeometry );
generateGeometry();
......
......@@ -66,15 +66,18 @@
var loader = new THREE.TextureLoader();
var texture = loader.load( "textures/UV_Grid_Sm.jpg" );
// it's necessary to apply these settings in order to correctly display the texture on a shape geometry
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 0.008, 0.008 );
function addShape( shape, extrudeSettings, color, x, y, z, rx, ry, rz, s ) {
// flat shape with texture
// note: default UVs generated by ShapeGemoetry are simply the x- and y-coordinates of the vertices
// note: default UVs generated by ShapeBufferGemoetry are simply the x- and y-coordinates of the vertices
var geometry = new THREE.ShapeGeometry( shape );
var geometry = new THREE.ShapeBufferGeometry( shape );
var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { side: THREE.DoubleSide, map: texture } ) );
mesh.position.set( x, y, z - 175 );
......@@ -84,7 +87,7 @@
// flat shape
var geometry = new THREE.ShapeGeometry( shape );
var geometry = new THREE.ShapeBufferGeometry( shape );
var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { color: color, side: THREE.DoubleSide } ) );
mesh.position.set( x, y, z - 125 );
......
......@@ -27,6 +27,7 @@ export { PlaneGeometry } from './PlaneGeometry.js';
export { LatheGeometry } from './LatheGeometry.js';
export { LatheBufferGeometry } from './LatheBufferGeometry.js';
export { ShapeGeometry } from './ShapeGeometry.js';
export { ShapeBufferGeometry } from './ShapeBufferGeometry.js';
export { ExtrudeGeometry } from './ExtrudeGeometry.js';
export { EdgesGeometry } from './EdgesGeometry.js';
export { ConeGeometry } from './ConeGeometry.js';
......
import { BufferGeometry } from '../core/BufferGeometry';
import { Float32Attribute, Uint16Attribute, Uint32Attribute } from '../core/BufferAttribute';
import { ShapeUtils } from '../extras/ShapeUtils';
/**
* @author Mugen87 / https://github.com/Mugen87
*
* Creates a one-sided polygonal geometry from one or more shapes.
*
**/
function ShapeBufferGeometry( shapes, curveSegments ) {
BufferGeometry.call( this );
this.type = 'ShapeBufferGeometry';
this.parameters = {
shapes: shapes,
curveSegments: curveSegments
};
curveSegments = curveSegments || 12;
var vertices = [];
var normals = [];
var uvs = [];
var indices = [];
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.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );
this.addAttribute( 'position', Float32Attribute( vertices, 3 ) );
this.addAttribute( 'normal', Float32Attribute( normals, 3 ) );
this.addAttribute( 'uv', Float32Attribute( 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;
export { ShapeBufferGeometry };
import { Geometry } from '../core/Geometry';
import { Face3 } from '../core/Face3';
import { Vector3 } from '../math/Vector3';
import { ShapeUtils } from '../extras/ShapeUtils';
import { ExtrudeGeometry } from './ExtrudeGeometry';
import { ShapeBufferGeometry } from './ShapeBufferGeometry';
/**
* @author jonobr1 / http://jonobr1.com
*
* Creates a one-sided polygonal geometry from a path shape. Similar to
* ExtrudeGeometry.
* Creates a one-sided polygonal geometry from a path shape.
*
* parameters = {
*
* curveSegments: <int>, // number of points on the curves. NOT USED AT THE MOMENT.
*
* material: <int> // material index for front and back faces
* uvGenerator: <Object> // object that provides UV generator functions
*
* }
**/
function ShapeGeometry( shapes, options ) {
function ShapeGeometry( shapes, curveSegments ) {
Geometry.call( this );
this.type = 'ShapeGeometry';
if ( Array.isArray( shapes ) === false ) shapes = [ shapes ];
this.addShapeList( shapes, options );
this.computeFaceNormals();
}
ShapeGeometry.prototype = Object.create( Geometry.prototype );
ShapeGeometry.prototype.constructor = ShapeGeometry;
/**
* Add an array of shapes to THREE.ShapeGeometry.
*/
ShapeGeometry.prototype.addShapeList = function ( shapes, options ) {
for ( var i = 0, l = shapes.length; i < l; i ++ ) {
this.addShape( shapes[ i ], options );
}
return this;
};
/**
* Adds a shape to THREE.ShapeGeometry, based on THREE.ExtrudeGeometry.
*/
ShapeGeometry.prototype.addShape = function ( shape, options ) {
if ( options === undefined ) options = {};
var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
var material = options.material;
var uvgen = options.UVGenerator === undefined ? ExtrudeGeometry.WorldUVGenerator : options.UVGenerator;
//
var i, l, hole;
var shapesOffset = this.vertices.length;
var shapePoints = shape.extractPoints( curveSegments );
var vertices = shapePoints.shape;
var holes = shapePoints.holes;
var reverse = ! ShapeUtils.isClockWise( vertices );
if ( typeof curveSegments === 'object' ) {
if ( reverse ) {
console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );
vertices = vertices.reverse();
// Maybe we should also check if holes are in the opposite direction, just to be safe...
for ( i = 0, l = holes.length; i < l; i ++ ) {
hole = holes[ i ];
if ( ShapeUtils.isClockWise( hole ) ) {
holes[ i ] = hole.reverse();
}
}
reverse = false;
}
var faces = ShapeUtils.triangulateShape( vertices, holes );
// Vertices
for ( i = 0, l = holes.length; i < l; i ++ ) {
hole = holes[ i ];
vertices = vertices.concat( hole );
curveSegments = curveSegments.curveSegments;
}
//
this.parameters = {
shapes: shapes,
curveSegments: curveSegments
};
var vert, vlen = vertices.length;
var face, flen = faces.length;
this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );
this.mergeVertices();
for ( i = 0; i < vlen; i ++ ) {
vert = vertices[ i ];
this.vertices.push( new Vector3( vert.x, vert.y, 0 ) );
}
for ( i = 0; i < flen; i ++ ) {
face = faces[ i ];
var a = face[ 0 ] + shapesOffset;
var b = face[ 1 ] + shapesOffset;
var c = face[ 2 ] + shapesOffset;
this.faces.push( new Face3( a, b, c, null, null, material ) );
this.faceVertexUvs[ 0 ].push( uvgen.generateTopUV( this, a, b, c ) );
}
}
};
ShapeGeometry.prototype = Object.create( Geometry.prototype );
ShapeGeometry.prototype.constructor = ShapeGeometry;
export { ShapeGeometry };
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册