Files
three.js/examples/webgl_geometry_shapes.html
T
alteredq 81b60ea2f6 All WebGL examples working with array-less materials.
Noticeable difference: can't anymore assign Material references to faces directly - "face.materials" became "face.materialIndex". Materials have to go to "geometry.materials" array (to which "face.materialIndex" points). This is necessary to allow run-time changing of face materials (this indirection used to be done by arrays).

Some casualties:

- multi-materials example, this functionality isn't possible anymore
- had to simplify LOD Text examples as LODs don't handle groups (used to fake multi-materials)
- multi-materials sphere in materials example can't have faces with undefined materials (this may be fixable I guess, when there'll be some real use-case)
- scene format still has materials arrays, only the last material will be used (except when there are face materials, then materials from JSON will be used, as before)

Other renderers and their corresponding examples were not touched yet.

WebGLRenderer still needs some prettification, some things don't make sense anymore without arrays, code can be cleaned up further.
2011-10-21 06:18:59 +02:00

477 lines
16 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<title>three.js webgl - geometry - shapes</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<canvas id="debug" style="position:absolute; left:100px"></canvas>
<script src="../build/Three.js"></script>
<script src="js/RequestAnimationFrame.js"></script>
<script src="js/Stats.js"></script>
<script>
var container, stats;
var camera, scene, renderer;
var text, plane;
var targetRotation = 0;
var targetRotationOnMouseDown = 0;
var mouseX = 0;
var mouseXOnMouseDown = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = 'Simple procedurally generated 3D shapes example by <a href="http://www.lab4games.net/zz85/blog">zz85</a><br/>Drag to spin';
container.appendChild( info );
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.y = 150;
camera.position.z = 500;
scene = new THREE.Scene();
var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 0, 1 );
light.position.normalize();
scene.add( light );
parent = new THREE.Object3D();
parent.position.y = 50;
scene.add( parent );
function addGeometry( geometry, points, spacedPoints, color, x, y, z, rx, ry, rz, s ) {
// 3d shape
var mesh = THREE.SceneUtils.createMultiMaterialObject( geometry, [ new THREE.MeshLambertMaterial( { color: color } ), new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, transparent: true } ) ] );
mesh.position.set( x, y, z - 75 );
mesh.rotation.set( rx, ry, rz );
mesh.scale.set( s, s, s );
parent.add( mesh );
// solid line
var line = new THREE.Line( points, new THREE.LineBasicMaterial( { color: color, linewidth: 2 } ) );
line.position.set( x, y, z + 25 );
line.rotation.set( rx, ry, rz );
line.scale.set( s, s, s );
parent.add( line );
// transparent line from real points
var line = new THREE.Line( points, new THREE.LineBasicMaterial( { color: color, opacity: 0.5 } ) );
line.position.set( x, y, z + 75 );
line.rotation.set( rx, ry, rz );
line.scale.set( s, s, s );
parent.add( line );
// vertices from real points
var pgeo = THREE.GeometryUtils.clone( points );
var particles = new THREE.ParticleSystem( pgeo, new THREE.ParticleBasicMaterial( { color: color, size: 2, opacity: 0.75 } ) );
particles.position.set( x, y, z + 75 );
particles.rotation.set( rx, ry, rz );
particles.scale.set( s, s, s );
parent.add( particles );
// transparent line from equidistance sampled points
var line = new THREE.Line( spacedPoints, new THREE.LineBasicMaterial( { color: color, opacity: 0.2 } ) );
line.position.set( x, y, z + 100 );
line.rotation.set( rx, ry, rz );
line.scale.set( s, s, s );
parent.add( line );
// equidistance sampled points
var pgeo = THREE.GeometryUtils.clone( spacedPoints );
var particles2 = new THREE.ParticleSystem( pgeo, new THREE.ParticleBasicMaterial( { color: color, size: 2, opacity: 0.5 } ) );
particles2.position.set( x, y, z + 100 );
particles2.rotation.set( rx, ry, rz );
particles2.scale.set( s, s, s );
parent.add( particles2 );
}
var extrudeSettings = { amount: 20, bevelEnabled: true, bevelSegments: 2, steps: 2 }; // bevelSegments: 2, steps: 2 , bevelSegments: 5, bevelSize: 8, bevelThickness:5,
// California
var californiaPts = [];
californiaPts.push( new THREE.Vector2 ( 610, 320 ) );
californiaPts.push( new THREE.Vector2 ( 450, 300 ) );
californiaPts.push( new THREE.Vector2 ( 392, 392 ) );
californiaPts.push( new THREE.Vector2 ( 266, 438 ) );
californiaPts.push( new THREE.Vector2 ( 190, 570 ) );
californiaPts.push( new THREE.Vector2 ( 190, 600 ) );
californiaPts.push( new THREE.Vector2 ( 160, 620 ) );
californiaPts.push( new THREE.Vector2 ( 160, 650 ) );
californiaPts.push( new THREE.Vector2 ( 180, 640 ) );
californiaPts.push( new THREE.Vector2 ( 165, 680 ) );
californiaPts.push( new THREE.Vector2 ( 150, 670 ) );
californiaPts.push( new THREE.Vector2 ( 90, 737 ) );
californiaPts.push( new THREE.Vector2 ( 80, 795 ) );
californiaPts.push( new THREE.Vector2 ( 50, 835 ) );
californiaPts.push( new THREE.Vector2 ( 64, 870 ) );
californiaPts.push( new THREE.Vector2 ( 60, 945 ) );
californiaPts.push( new THREE.Vector2 ( 300, 945 ) );
californiaPts.push( new THREE.Vector2 ( 300, 743 ) );
californiaPts.push( new THREE.Vector2 ( 600, 473 ) );
californiaPts.push( new THREE.Vector2 ( 626, 425 ) );
californiaPts.push( new THREE.Vector2 ( 600, 370 ) );
californiaPts.push( new THREE.Vector2 ( 610, 320 ) );
var californiaShape = new THREE.Shape( californiaPts );
var california3d = new THREE.ExtrudeGeometry( californiaShape, { amount: 20 } );
var californiaPoints = californiaShape.createPointsGeometry();
var californiaSpacedPoints = californiaShape.createSpacedPointsGeometry( 100 );
// Triangle
var triangleShape = new THREE.Shape();
triangleShape.moveTo( 80, 20 );
triangleShape.lineTo( 40, 80 );
triangleShape.lineTo( 120, 80 );
triangleShape.lineTo( 80, 20 ); // close path
var triangle3d = triangleShape.extrude( extrudeSettings );
var trianglePoints = triangleShape.createPointsGeometry();
var triangleSpacedPoints = triangleShape.createSpacedPointsGeometry();
// Heart
var x = 0, y = 0;
var heartShape = new THREE.Shape(); // From http://blog.burlock.org/html5/130-paths
heartShape.moveTo( x + 25, y + 25 );
heartShape.bezierCurveTo( x + 25, y + 25, x + 20, y, x, y );
heartShape.bezierCurveTo( x - 30, y, x - 30, y + 35,x - 30,y + 35 );
heartShape.bezierCurveTo( x - 30, y + 55, x - 10, y + 77, x + 25, y + 95 );
heartShape.bezierCurveTo( x + 60, y + 77, x + 80, y + 55, x + 80, y + 35 );
heartShape.bezierCurveTo( x + 80, y + 35, x + 80, y, x + 50, y );
heartShape.bezierCurveTo( x + 35, y, x + 25, y + 25, x + 25, y + 25 );
var heart3d = heartShape.extrude( extrudeSettings );
var heartPoints = heartShape.createPointsGeometry();
var heartSpacedPoints = heartShape.createSpacedPointsGeometry();
//heartShape.debug( document.getElementById("debug") );
// Square
var sqLength = 80;
var squareShape = new THREE.Shape();
squareShape.moveTo( 0,0 );
squareShape.lineTo( 0, sqLength );
squareShape.lineTo( sqLength, sqLength );
squareShape.lineTo( sqLength, 0 );
squareShape.lineTo( 0, 0 );
var square3d = squareShape.extrude( extrudeSettings );
var squarePoints = squareShape.createPointsGeometry();
var squareSpacedPoints = squareShape.createSpacedPointsGeometry();
// Rectangle
var rectLength = 120, rectWidth = 40;
var rectShape = new THREE.Shape();
rectShape.moveTo( 0,0 );
rectShape.lineTo( 0, rectWidth );
rectShape.lineTo( rectLength, rectWidth );
rectShape.lineTo( rectLength, 0 );
rectShape.lineTo( 0, 0 );
var rect3d = rectShape.extrude( extrudeSettings );
var rectPoints = rectShape.createPointsGeometry();
var rectSpacedPoints = rectShape.createSpacedPointsGeometry();
// Rounded rectangle
var roundedRectShape = new THREE.Shape();
roundedRect( roundedRectShape, 0, 0, 50, 50, 20 );
var roundedRect3d = roundedRectShape.extrude( extrudeSettings );
var roundedRectPoints = roundedRectShape.createPointsGeometry();
var roundedRectSpacedPoints = roundedRectShape.createSpacedPointsGeometry();
function roundedRect( ctx, x, y, width, height, radius ){
ctx.moveTo( x, y + radius );
ctx.lineTo( x, y + height - radius );
ctx.quadraticCurveTo( x, y + height, x + radius, y + height );
ctx.lineTo( x + width - radius, y + height) ;
ctx.quadraticCurveTo( x + width, y + height, x + width, y + height - radius );
ctx.lineTo( x + width, y + radius );
ctx.quadraticCurveTo( x + width, y, x + width - radius, y );
ctx.lineTo( x + radius, y );
ctx.quadraticCurveTo( x, y, x, y + radius );
}
// Circle
var circleRadius = 40;
var circleShape = new THREE.Shape();
circleShape.moveTo( 0, circleRadius );
circleShape.quadraticCurveTo( circleRadius, circleRadius, circleRadius, 0 );
circleShape.quadraticCurveTo( circleRadius, -circleRadius, 0, -circleRadius );
circleShape.quadraticCurveTo( -circleRadius, -circleRadius, -circleRadius, 0 );
circleShape.quadraticCurveTo( -circleRadius, circleRadius, 0, circleRadius );
var circle3d = circleShape.extrude( extrudeSettings );
var circlePoints = circleShape.createPointsGeometry();
var circleSpacedPoints = circleShape.createSpacedPointsGeometry();
// Fish
x = y = 0;
var fishShape = new THREE.Shape();
fishShape.moveTo(x,y);
fishShape.quadraticCurveTo(x + 50, y - 80, x + 90, y - 10);
fishShape.quadraticCurveTo(x + 100, y - 10, x + 115, y - 40);
fishShape.quadraticCurveTo(x + 115, y, x + 115, y + 40);
fishShape.quadraticCurveTo(x + 100, y + 10, x + 90, y + 10);
fishShape.quadraticCurveTo(x + 50, y + 80, x, y);
var fish3d = fishShape.extrude( extrudeSettings );
var fishPoints = fishShape.createPointsGeometry();
var fishSpacedPoints = fishShape.createSpacedPointsGeometry();
// Arc circle
var arcShape = new THREE.Shape();
arcShape.moveTo( 0, 0 );
arcShape.arc( 10, 10, 40, 0, Math.PI*2, false );
var holePath = new THREE.Path();
holePath.moveTo( 0, 0 );
holePath.arc( 10, 10, 10, 0, Math.PI*2, true );
arcShape.holes.push( holePath );
var arc3d = arcShape.extrude( extrudeSettings );
var arcPoints = arcShape.createPointsGeometry();
var arcSpacedPoints = arcShape.createSpacedPointsGeometry();
// Smiley
var smileyShape = new THREE.Shape();
smileyShape.moveTo( 0, 0 );
smileyShape.arc( 40, 40, 40, 0, Math.PI*2, false );
var smileyEye1Path = new THREE.Path();
smileyEye1Path.moveTo( 0, 0 );
smileyEye1Path.arc( 25, 20, 10, 0, Math.PI*2, true );
smileyShape.holes.push( smileyEye1Path );
var smileyEye2Path = new THREE.Path();
smileyEye2Path.moveTo( 0, 0 );
smileyEye2Path.arc( 55, 20, 10, 0, Math.PI*2, true );
smileyShape.holes.push( smileyEye2Path );
var smileyMouthPath = new THREE.Path();
// ugly box mouth
// smileyMouthPath.moveTo( 20, 40 );
// smileyMouthPath.lineTo( 60, 40 );
// smileyMouthPath.lineTo( 60, 60 );
// smileyMouthPath.lineTo( 20, 60 );
// smileyMouthPath.lineTo( 20, 40 );
smileyMouthPath.moveTo( 20, 40 );
smileyMouthPath.quadraticCurveTo( 40, 60, 60, 40 );
smileyMouthPath.bezierCurveTo( 70, 45, 70, 50, 60, 60 );
smileyMouthPath.quadraticCurveTo( 40, 80, 20, 60 );
smileyMouthPath.quadraticCurveTo( 5, 50, 20, 40 );
smileyShape.holes.push( smileyMouthPath );
var smiley3d = smileyShape.extrude( extrudeSettings );
var smileyPoints = smileyShape.createPointsGeometry();
var smileySpacedPoints = smileyShape.createSpacedPointsGeometry();
// Spline shape + path extrusion
var splinepts = [];
splinepts.push( new THREE.Vector2 ( 350, 100 ) );
splinepts.push( new THREE.Vector2 ( 400, 450 ) );
splinepts.push( new THREE.Vector2 ( -140, 350 ) );
splinepts.push( new THREE.Vector2 ( 0, 0 ) );
var splineShape = new THREE.Shape( );
splineShape.moveTo( 0, 0 );
splineShape.splineThru( splinepts );
//splineShape.debug( document.getElementById("debug") );
var extrudePath = new THREE.Path();
extrudePath.moveTo( 0, 0 );
extrudePath.lineTo( 10, 10 );
extrudePath.quadraticCurveTo( 80, 60, 160, 10 );
extrudePath.quadraticCurveTo( 240, -40, 320, 10 );
extrudeSettings.extrudePath = extrudePath;
extrudeSettings.bevelEnabled = false;
var splineShape3d = splineShape.extrude( extrudeSettings );
var splinePoints = splineShape.createPointsGeometry( );
var splineSpacedPoints = splineShape.createSpacedPointsGeometry( );
addGeometry( california3d, californiaPoints, californiaSpacedPoints, 0xffaa00, -300, -100, 0, 0, 0, 0, 0.25 );
addGeometry( triangle3d, trianglePoints, triangleSpacedPoints, 0xffee00, -180, 0, 0, 0, 0, 0, 1 );
addGeometry( roundedRect3d, roundedRectPoints, roundedRectSpacedPoints, 0x005500, -150, 150, 0, 0, 0, 0, 1 );
addGeometry( square3d, squarePoints, squareSpacedPoints, 0x0055ff, 150, 100, 0, 0, 0, 0, 1 );
addGeometry( heart3d, heartPoints, heartSpacedPoints, 0xff1100, 0, 100, 0, Math.PI, 0, 0, 1 );
addGeometry( circle3d, circlePoints, circleSpacedPoints, 0x00ff11, 120, 250, 0, 0, 0, 0, 1 );
addGeometry( fish3d, fishPoints, fishSpacedPoints, 0x222222, -60, 200, 0, 0, 0, 0, 1 );
addGeometry( splineShape3d, splinePoints, splineSpacedPoints, 0x888888, -50, -100, -50, 0, 0, 0, 0.2 );
addGeometry( arc3d, arcPoints, arcSpacedPoints, 0xbb4422, 150, 0, 0, 0, 0, 0, 1 );
addGeometry( smiley3d, smileyPoints, smileySpacedPoints, 0xee00ff, -270, 250, 0, Math.PI, 0, 0, 1 );
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
}
//
function onDocumentMouseDown( event ) {
event.preventDefault();
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'mouseout', onDocumentMouseOut, false );
mouseXOnMouseDown = event.clientX - windowHalfX;
targetRotationOnMouseDown = targetRotation;
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
}
function onDocumentMouseUp( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentMouseOut( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentTouchStart( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
targetRotationOnMouseDown = targetRotation;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
}
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
parent.rotation.y += ( targetRotation - parent.rotation.y ) * 0.05;
renderer.render( scene, camera );
}
</script>
</body>
</html>