mirror of
https://github.com/wahyd4/three.js.git
synced 2026-08-09 04:56:01 +10:00
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.
477 lines
16 KiB
HTML
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>
|