You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
822 lines
20 KiB
822 lines
20 KiB
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Three.js Geometry Browser</title>
|
|
<link rel="shortcut icon" href="../../files/favicon.ico" />
|
|
<link rel="stylesheet" type="text/css" href="../../files/main.css">
|
|
<style>
|
|
canvas {
|
|
display: block;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
#newWindow {
|
|
display: block;
|
|
position: absolute;
|
|
bottom: 0.3em;
|
|
left: 0.5em;
|
|
color: #fff;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- Import maps polyfill -->
|
|
<!-- Remove this when import maps will be widely supported -->
|
|
<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
|
|
|
|
<script type="importmap">
|
|
{
|
|
"imports": {
|
|
"three": "../../build/three.module.js",
|
|
"three/addons/": "../../examples/jsm/"
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<a id='newWindow' href='./geometry-browser.html' target='_blank'>Open in New Window</a>
|
|
|
|
<script type="module">
|
|
import {
|
|
BoxGeometry,
|
|
BufferGeometry,
|
|
CapsuleGeometry,
|
|
CircleGeometry,
|
|
Color,
|
|
ConeGeometry,
|
|
Curve,
|
|
CylinderGeometry,
|
|
DodecahedronGeometry,
|
|
DoubleSide,
|
|
ExtrudeGeometry,
|
|
Float32BufferAttribute,
|
|
Group,
|
|
IcosahedronGeometry,
|
|
LatheGeometry,
|
|
LineSegments,
|
|
LineBasicMaterial,
|
|
Mesh,
|
|
MeshPhongMaterial,
|
|
OctahedronGeometry,
|
|
PerspectiveCamera,
|
|
PlaneGeometry,
|
|
PointLight,
|
|
RingGeometry,
|
|
Scene,
|
|
Shape,
|
|
ShapeGeometry,
|
|
SphereGeometry,
|
|
TetrahedronGeometry,
|
|
TorusGeometry,
|
|
TorusKnotGeometry,
|
|
TubeGeometry,
|
|
Vector2,
|
|
Vector3,
|
|
WireframeGeometry,
|
|
WebGLRenderer
|
|
} from 'three';
|
|
|
|
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
|
|
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
|
|
|
const twoPi = Math.PI * 2;
|
|
|
|
class CustomSinCurve extends Curve {
|
|
|
|
constructor( scale = 1 ) {
|
|
|
|
super();
|
|
|
|
this.scale = scale;
|
|
|
|
}
|
|
|
|
getPoint( t, optionalTarget = new Vector3() ) {
|
|
|
|
const tx = t * 3 - 1.5;
|
|
const ty = Math.sin( 2 * Math.PI * t );
|
|
const tz = 0;
|
|
|
|
return optionalTarget.set( tx, ty, tz ).multiplyScalar( this.scale );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function updateGroupGeometry( mesh, geometry ) {
|
|
|
|
mesh.children[ 0 ].geometry.dispose();
|
|
mesh.children[ 1 ].geometry.dispose();
|
|
|
|
mesh.children[ 0 ].geometry = new WireframeGeometry( geometry );
|
|
mesh.children[ 1 ].geometry = geometry;
|
|
|
|
// these do not update nicely together if shared
|
|
|
|
}
|
|
|
|
// heart shape
|
|
|
|
const x = 0, y = 0;
|
|
|
|
const heartShape = new 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 );
|
|
|
|
const guis = {
|
|
|
|
BoxGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
width: 15,
|
|
height: 15,
|
|
depth: 15,
|
|
widthSegments: 1,
|
|
heightSegments: 1,
|
|
depthSegments: 1
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new BoxGeometry(
|
|
data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.BoxGeometry' );
|
|
|
|
folder.add( data, 'width', 1, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'height', 1, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'depth', 1, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'widthSegments', 1, 10 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'heightSegments', 1, 10 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'depthSegments', 1, 10 ).step( 1 ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
CapsuleGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
radius: 5,
|
|
length: 5,
|
|
capSegments: 10,
|
|
radialSegments: 20
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new CapsuleGeometry( data.radius, data.length, data.capSegments, data.radialSegments ),
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.CapsuleGeometry' );
|
|
|
|
folder.add( data, 'radius', 1, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'length', 1, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'capSegments', 1, 32 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'radialSegments', 1, 64 ).step( 1 ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
CylinderGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
radiusTop: 5,
|
|
radiusBottom: 5,
|
|
height: 10,
|
|
radialSegments: 8,
|
|
heightSegments: 1,
|
|
openEnded: false,
|
|
thetaStart: 0,
|
|
thetaLength: twoPi
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new CylinderGeometry(
|
|
data.radiusTop,
|
|
data.radiusBottom,
|
|
data.height,
|
|
data.radialSegments,
|
|
data.heightSegments,
|
|
data.openEnded,
|
|
data.thetaStart,
|
|
data.thetaLength
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.CylinderGeometry' );
|
|
|
|
folder.add( data, 'radiusTop', 0, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'radiusBottom', 0, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'height', 1, 50 ).onChange( generateGeometry );
|
|
folder.add( data, 'radialSegments', 3, 64 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'heightSegments', 1, 64 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'openEnded' ).onChange( generateGeometry );
|
|
folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
|
|
folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
|
|
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
ConeGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
radius: 5,
|
|
height: 10,
|
|
radialSegments: 8,
|
|
heightSegments: 1,
|
|
openEnded: false,
|
|
thetaStart: 0,
|
|
thetaLength: twoPi
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new ConeGeometry(
|
|
data.radius,
|
|
data.height,
|
|
data.radialSegments,
|
|
data.heightSegments,
|
|
data.openEnded,
|
|
data.thetaStart,
|
|
data.thetaLength
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.ConeGeometry' );
|
|
|
|
folder.add( data, 'radius', 0, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'height', 1, 50 ).onChange( generateGeometry );
|
|
folder.add( data, 'radialSegments', 3, 64 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'heightSegments', 1, 64 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'openEnded' ).onChange( generateGeometry );
|
|
folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
|
|
folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
|
|
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
CircleGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
radius: 10,
|
|
segments: 32,
|
|
thetaStart: 0,
|
|
thetaLength: twoPi
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new CircleGeometry(
|
|
data.radius, data.segments, data.thetaStart, data.thetaLength
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.CircleGeometry' );
|
|
|
|
folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
|
|
folder.add( data, 'segments', 0, 128 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
|
|
folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
DodecahedronGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
radius: 10,
|
|
detail: 0
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new DodecahedronGeometry(
|
|
data.radius, data.detail
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.DodecahedronGeometry' );
|
|
|
|
folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
|
|
folder.add( data, 'detail', 0, 5 ).step( 1 ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
IcosahedronGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
radius: 10,
|
|
detail: 0
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new IcosahedronGeometry(
|
|
data.radius, data.detail
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.IcosahedronGeometry' );
|
|
|
|
folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
|
|
folder.add( data, 'detail', 0, 5 ).step( 1 ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
LatheGeometry: function ( mesh ) {
|
|
|
|
const points = [];
|
|
|
|
for ( let i = 0; i < 10; i ++ ) {
|
|
|
|
points.push( new Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) );
|
|
|
|
}
|
|
|
|
const data = {
|
|
segments: 12,
|
|
phiStart: 0,
|
|
phiLength: twoPi
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
const geometry = new LatheGeometry(
|
|
points, data.segments, data.phiStart, data.phiLength
|
|
);
|
|
|
|
updateGroupGeometry( mesh, geometry );
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.LatheGeometry' );
|
|
|
|
folder.add( data, 'segments', 1, 30 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'phiStart', 0, twoPi ).onChange( generateGeometry );
|
|
folder.add( data, 'phiLength', 0, twoPi ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
OctahedronGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
radius: 10,
|
|
detail: 0
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new OctahedronGeometry(
|
|
data.radius, data.detail
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.OctahedronGeometry' );
|
|
|
|
folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
|
|
folder.add( data, 'detail', 0, 5 ).step( 1 ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
PlaneGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
width: 10,
|
|
height: 10,
|
|
widthSegments: 1,
|
|
heightSegments: 1
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new PlaneGeometry(
|
|
data.width, data.height, data.widthSegments, data.heightSegments
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.PlaneGeometry' );
|
|
|
|
folder.add( data, 'width', 1, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'height', 1, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'widthSegments', 1, 30 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'heightSegments', 1, 30 ).step( 1 ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
RingGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
innerRadius: 5,
|
|
outerRadius: 10,
|
|
thetaSegments: 8,
|
|
phiSegments: 8,
|
|
thetaStart: 0,
|
|
thetaLength: twoPi
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new RingGeometry(
|
|
data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.RingGeometry' );
|
|
|
|
folder.add( data, 'innerRadius', 1, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'outerRadius', 1, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'thetaSegments', 1, 30 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'phiSegments', 1, 30 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
|
|
folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
SphereGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
radius: 15,
|
|
widthSegments: 32,
|
|
heightSegments: 16,
|
|
phiStart: 0,
|
|
phiLength: twoPi,
|
|
thetaStart: 0,
|
|
thetaLength: Math.PI
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new SphereGeometry(
|
|
data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.SphereGeometry' );
|
|
|
|
folder.add( data, 'radius', 1, 30 ).onChange( generateGeometry );
|
|
folder.add( data, 'widthSegments', 3, 64 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'heightSegments', 2, 32 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'phiStart', 0, twoPi ).onChange( generateGeometry );
|
|
folder.add( data, 'phiLength', 0, twoPi ).onChange( generateGeometry );
|
|
folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
|
|
folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
TetrahedronGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
radius: 10,
|
|
detail: 0
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new TetrahedronGeometry(
|
|
data.radius, data.detail
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.TetrahedronGeometry' );
|
|
|
|
folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
|
|
folder.add( data, 'detail', 0, 5 ).step( 1 ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
TorusGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
radius: 10,
|
|
tube: 3,
|
|
radialSegments: 16,
|
|
tubularSegments: 100,
|
|
arc: twoPi
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new TorusGeometry(
|
|
data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.TorusGeometry' );
|
|
|
|
folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
|
|
folder.add( data, 'tube', 0.1, 10 ).onChange( generateGeometry );
|
|
folder.add( data, 'radialSegments', 2, 30 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'tubularSegments', 3, 200 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'arc', 0.1, twoPi ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
TorusKnotGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
radius: 10,
|
|
tube: 3,
|
|
tubularSegments: 64,
|
|
radialSegments: 8,
|
|
p: 2,
|
|
q: 3
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new TorusKnotGeometry(
|
|
data.radius, data.tube, data.tubularSegments, data.radialSegments,
|
|
data.p, data.q
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.TorusKnotGeometry' );
|
|
|
|
folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
|
|
folder.add( data, 'tube', 0.1, 10 ).onChange( generateGeometry );
|
|
folder.add( data, 'tubularSegments', 3, 300 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'radialSegments', 3, 20 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'p', 1, 20 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'q', 1, 20 ).step( 1 ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
TubeGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
segments: 20,
|
|
radius: 2,
|
|
radialSegments: 8
|
|
};
|
|
|
|
const path = new CustomSinCurve( 10 );
|
|
|
|
function generateGeometry() {
|
|
|
|
updateGroupGeometry( mesh,
|
|
new TubeGeometry( path, data.segments, data.radius, data.radialSegments, false )
|
|
);
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.TubeGeometry' );
|
|
|
|
folder.add( data, 'segments', 1, 100 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'radius', 1, 10 ).onChange( generateGeometry );
|
|
folder.add( data, 'radialSegments', 1, 20 ).step( 1 ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
ShapeGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
segments: 12
|
|
};
|
|
|
|
function generateGeometry() {
|
|
|
|
const geometry = new ShapeGeometry( heartShape, data.segments );
|
|
geometry.center();
|
|
|
|
updateGroupGeometry( mesh, geometry );
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.ShapeGeometry' );
|
|
folder.add( data, 'segments', 1, 100 ).step( 1 ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
},
|
|
|
|
ExtrudeGeometry: function ( mesh ) {
|
|
|
|
const data = {
|
|
steps: 2,
|
|
depth: 16,
|
|
bevelEnabled: true,
|
|
bevelThickness: 1,
|
|
bevelSize: 1,
|
|
bevelOffset: 0,
|
|
bevelSegments: 1
|
|
};
|
|
|
|
const length = 12, width = 8;
|
|
|
|
const shape = new Shape();
|
|
shape.moveTo( 0, 0 );
|
|
shape.lineTo( 0, width );
|
|
shape.lineTo( length, width );
|
|
shape.lineTo( length, 0 );
|
|
shape.lineTo( 0, 0 );
|
|
|
|
function generateGeometry() {
|
|
|
|
const geometry = new ExtrudeGeometry( shape, data );
|
|
geometry.center();
|
|
|
|
updateGroupGeometry( mesh, geometry );
|
|
|
|
}
|
|
|
|
const folder = gui.addFolder( 'THREE.ExtrudeGeometry' );
|
|
|
|
folder.add( data, 'steps', 1, 10 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'depth', 1, 20 ).onChange( generateGeometry );
|
|
folder.add( data, 'bevelThickness', 1, 5 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'bevelSize', 0, 5 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'bevelOffset', - 4, 5 ).step( 1 ).onChange( generateGeometry );
|
|
folder.add( data, 'bevelSegments', 1, 5 ).step( 1 ).onChange( generateGeometry );
|
|
|
|
generateGeometry();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
function chooseFromHash( mesh ) {
|
|
|
|
const selectedGeometry = window.location.hash.substring( 1 ) || 'TorusGeometry';
|
|
|
|
if ( guis[ selectedGeometry ] !== undefined ) {
|
|
|
|
guis[ selectedGeometry ]( mesh );
|
|
|
|
}
|
|
|
|
if ( selectedGeometry === 'TextGeometry' ) {
|
|
|
|
return { fixed: true };
|
|
|
|
}
|
|
|
|
//No configuration options
|
|
return {};
|
|
|
|
}
|
|
|
|
//
|
|
|
|
const selectedGeometry = window.location.hash.substring( 1 );
|
|
|
|
if ( guis[ selectedGeometry ] !== undefined ) {
|
|
|
|
document.getElementById( 'newWindow' ).href += '#' + selectedGeometry;
|
|
|
|
}
|
|
|
|
const gui = new GUI();
|
|
|
|
const scene = new Scene();
|
|
scene.background = new Color( 0x444444 );
|
|
|
|
const camera = new PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 50 );
|
|
camera.position.z = 30;
|
|
|
|
const renderer = new WebGLRenderer( { antialias: true } );
|
|
renderer.setPixelRatio( window.devicePixelRatio );
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
document.body.appendChild( renderer.domElement );
|
|
|
|
const orbit = new OrbitControls( camera, renderer.domElement );
|
|
orbit.enableZoom = false;
|
|
|
|
const lights = [];
|
|
lights[ 0 ] = new PointLight( 0xffffff, 1, 0 );
|
|
lights[ 1 ] = new PointLight( 0xffffff, 1, 0 );
|
|
lights[ 2 ] = new PointLight( 0xffffff, 1, 0 );
|
|
|
|
lights[ 0 ].position.set( 0, 200, 0 );
|
|
lights[ 1 ].position.set( 100, 200, 100 );
|
|
lights[ 2 ].position.set( - 100, - 200, - 100 );
|
|
|
|
scene.add( lights[ 0 ] );
|
|
scene.add( lights[ 1 ] );
|
|
scene.add( lights[ 2 ] );
|
|
|
|
const group = new Group();
|
|
|
|
const geometry = new BufferGeometry();
|
|
geometry.setAttribute( 'position', new Float32BufferAttribute( [], 3 ) );
|
|
|
|
const lineMaterial = new LineBasicMaterial( { color: 0xffffff, transparent: true, opacity: 0.5 } );
|
|
const meshMaterial = new MeshPhongMaterial( { color: 0x156289, emissive: 0x072534, side: DoubleSide, flatShading: true } );
|
|
|
|
group.add( new LineSegments( geometry, lineMaterial ) );
|
|
group.add( new Mesh( geometry, meshMaterial ) );
|
|
|
|
const options = chooseFromHash( group );
|
|
|
|
scene.add( group );
|
|
|
|
function render() {
|
|
|
|
requestAnimationFrame( render );
|
|
|
|
if ( ! options.fixed ) {
|
|
|
|
group.rotation.x += 0.005;
|
|
group.rotation.y += 0.005;
|
|
|
|
}
|
|
|
|
renderer.render( scene, camera );
|
|
|
|
}
|
|
|
|
window.addEventListener( 'resize', function () {
|
|
|
|
camera.aspect = window.innerWidth / window.innerHeight;
|
|
camera.updateProjectionMatrix();
|
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
|
}, false );
|
|
|
|
render();
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|