|
| 1 | +<!doctype html> |
| 2 | +<html lang="en"> |
| 3 | +<head> |
| 4 | + <title>Polyhedra (Three.js)</title> |
| 5 | + <meta charset="utf-8"> |
| 6 | + <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> |
| 7 | + <link rel=stylesheet href="css/base.css"/> |
| 8 | +</head> |
| 9 | +<body> |
| 10 | + |
| 11 | +<script src="js/Three58.js"></script> |
| 12 | +<script src="js/Detector.js"></script> |
| 13 | + |
| 14 | +<script src="js/TrackballControls.js"></script> |
| 15 | + |
| 16 | +<script src="js/polyhedra.js"></script> |
| 17 | + |
| 18 | +<div id="ThreeJS" style="position: absolute; left:0px; top:0px"></div> |
| 19 | +<script> |
| 20 | +/* |
| 21 | + Three.js "tutorials by example" |
| 22 | + Author: Lee Stemkoski |
| 23 | + Date: July 2013 (three.js v59dev) |
| 24 | + */ |
| 25 | + |
| 26 | +// MAIN |
| 27 | + |
| 28 | +// standard global variables |
| 29 | +var container, scene, camera, renderer, controls, stats; |
| 30 | + |
| 31 | +// var clock = new THREE.Clock(); |
| 32 | + |
| 33 | +// custom global variables |
| 34 | +var mesh; |
| 35 | + |
| 36 | +init(); |
| 37 | +animate(); |
| 38 | + |
| 39 | +// FUNCTIONS |
| 40 | +function init() |
| 41 | +{ |
| 42 | + // SCENE |
| 43 | + scene = new THREE.Scene(); |
| 44 | + // CAMERA |
| 45 | + var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight; |
| 46 | + var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000; |
| 47 | + camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR); |
| 48 | + scene.add(camera); |
| 49 | + camera.position.set(0,150,400); |
| 50 | + camera.lookAt(scene.position); |
| 51 | + // RENDERER |
| 52 | + if ( Detector.webgl ) |
| 53 | + renderer = new THREE.WebGLRenderer( {antialias:true} ); |
| 54 | + else |
| 55 | + renderer = new THREE.CanvasRenderer(); |
| 56 | + renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); |
| 57 | + container = document.getElementById( 'ThreeJS' ); |
| 58 | + container.appendChild( renderer.domElement ); |
| 59 | + // CONTROLS |
| 60 | + controls = new THREE.TrackballControls( camera, renderer.domElement ); |
| 61 | + controls.noPan = true; |
| 62 | + // LIGHT |
| 63 | + var light = new THREE.PointLight(0xffffff); |
| 64 | + // light.position.set(100,250,100); |
| 65 | + light.position = camera.position; |
| 66 | + scene.add(light); |
| 67 | + var light = new THREE.PointLight(0x888888); |
| 68 | + light.position.set(-100,-250,-100); |
| 69 | + scene.add(light); |
| 70 | + |
| 71 | + // SKYBOX |
| 72 | + var skyBoxGeometry = new THREE.CubeGeometry( 10000, 10000, 10000 ); |
| 73 | + var skyBoxMaterial = new THREE.MeshBasicMaterial( { color: 0xccccff, side: THREE.BackSide } ); |
| 74 | + var skyBox = new THREE.Mesh( skyBoxGeometry, skyBoxMaterial ); |
| 75 | + scene.add(skyBox); |
| 76 | + |
| 77 | + //////////// |
| 78 | + // CUSTOM // |
| 79 | + //////////// |
| 80 | + |
| 81 | + this.polyhedronMesh = polyhedronDataToMesh( POLYHEDRA.TruncatedIcosidodecahedron ); |
| 82 | + polyhedronMesh.scale.multiplyScalar(0.90); |
| 83 | + scene.add(polyhedronMesh); |
| 84 | + |
| 85 | + // SPRITE GUI? |
| 86 | + var ballTexture = THREE.ImageUtils.loadTexture( 'images/redball.png' ); |
| 87 | + var ballMaterial = new THREE.SpriteMaterial( { color: 0x0000ff, map: ballTexture, useScreenCoordinates: true, alignment: THREE.SpriteAlignment.bottomLeft } ); |
| 88 | + var sprite = new THREE.Sprite( ballMaterial ); |
| 89 | + sprite.position.set( 5, window.innerHeight - 5, 0 ); |
| 90 | + sprite.scale.set( 128, 128, 1.0 ); // imageWidth, imageHeight |
| 91 | + scene.add( sprite ); |
| 92 | + |
| 93 | + |
| 94 | + |
| 95 | + |
| 96 | +} // end of function init() |
| 97 | + |
| 98 | +var faces; |
| 99 | + |
| 100 | +function displayMesh(mesh) |
| 101 | +{ |
| 102 | +scene.remove(polyhedronMesh); |
| 103 | +polyhedronMesh = mesh; |
| 104 | +scene.add(polyhedronMesh); |
| 105 | +} |
| 106 | + |
| 107 | +function polyhedronDataToMesh(data) |
| 108 | +{ |
| 109 | + var polyhedron = new THREE.Object3D(); |
| 110 | + |
| 111 | + //var chromeTexture = new THREE.ImageUtils.loadTexture( 'images/Chrome.png' ); |
| 112 | + //var chromeMaterial = new THREE.MeshBasicMaterial( { color:0x999900, map: chromeTexture} ); |
| 113 | + |
| 114 | + // convert vertex data to THREE.js vectors |
| 115 | + var vertex = [] |
| 116 | + for (var i = 0; i < data.vertex.length; i++) |
| 117 | + vertex.push( new THREE.Vector3( data.vertex[i][0], data.vertex[i][1], data.vertex[i][2] ).multiplyScalar(100) ); |
| 118 | + |
| 119 | + // render vertices as spheres |
| 120 | + var vertexGeometry = new THREE.SphereGeometry( 6, 12, 6 ); |
| 121 | + var vertexMaterial = new THREE.MeshLambertMaterial( { color: 0x222244 } ); |
| 122 | + var mesh = new THREE.Mesh( vertexGeometry, vertexMaterial ); |
| 123 | + |
| 124 | + var vertexAmalgam = new THREE.Geometry(); |
| 125 | + for (var i = 0; i < data.vertex.length; i++) |
| 126 | + { |
| 127 | + var vMesh = mesh.clone(); |
| 128 | + vMesh.position = vertex[i]; |
| 129 | + THREE.GeometryUtils.merge( vertexAmalgam, vMesh ); |
| 130 | + // polyhedron.add(vMesh); |
| 131 | + } |
| 132 | + var vertexMesh = new THREE.Mesh( vertexAmalgam, vertexMaterial ); |
| 133 | + polyhedron.add( vertexMesh ); |
| 134 | + |
| 135 | + // convert edge data to cylinders |
| 136 | + var edgeMaterial = new THREE.MeshLambertMaterial( {color: 0x666666} ); |
| 137 | + var edgeAmalgam = new THREE.Geometry(); |
| 138 | + for (var i = 0; i < data.edge.length; i++) |
| 139 | + { |
| 140 | + var index0 = data.edge[i][0]; |
| 141 | + var index1 = data.edge[i][1]; |
| 142 | + var eMesh = cylinderMesh( vertex[index0], vertex[index1], edgeMaterial ); |
| 143 | + THREE.GeometryUtils.merge( edgeAmalgam, eMesh ); |
| 144 | + // polyhedron.add(eMesh); |
| 145 | + //var outline = eMesh.clone(); |
| 146 | + //outline.setMaterial( new THREE.MeshBasicMaterial({color:0x000000, side:THREE.BackSide}) ); |
| 147 | + //outline.scale.x = outline.scale.z = 1.5; |
| 148 | + //scene.add(outline); |
| 149 | + } |
| 150 | + var edgeMesh = new THREE.Mesh( edgeAmalgam, edgeMaterial ); |
| 151 | + polyhedron.add( edgeMesh ); |
| 152 | + // convert face data to a single (triangulated) geometry |
| 153 | + var faceMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff, vertexColors: THREE.FaceColors }); //, side: THREE.DoubleSide transparent:true, opacity:0.8 } ); |
| 154 | + var faceColors = |
| 155 | + { |
| 156 | + // cc0000 663300 cccc00 00cc00 0000cc 660066 brown-663300 |
| 157 | + 3: new THREE.Color( 0xcc0000 ), |
| 158 | + 4: new THREE.Color( 0x00cc00 ), |
| 159 | + 5: new THREE.Color( 0x0000cc ), |
| 160 | + 6: new THREE.Color( 0xcccc00 ), |
| 161 | + 7: new THREE.Color( 0x999999 ), |
| 162 | + 8: new THREE.Color( 0x990099 ), |
| 163 | + 9: new THREE.Color( 0xff6600 ), |
| 164 | + 10: new THREE.Color( 0x6666ff ) |
| 165 | + }; |
| 166 | + |
| 167 | + var geometry = new THREE.Geometry(); |
| 168 | + geometry.vertices = vertex; |
| 169 | + var faceIndex = 0; |
| 170 | + for (var faceNum = 0; faceNum < data.face.length; faceNum++) |
| 171 | + { |
| 172 | + for (var i = 0; i < data.face[faceNum].length - 2; i++) |
| 173 | + { |
| 174 | + geometry.faces[faceIndex] = new THREE.Face3( data.face[faceNum][0], data.face[faceNum][i+1], data.face[faceNum][i+2] ); |
| 175 | + geometry.faces[faceIndex].color = faceColors[data.face[faceNum].length]; |
| 176 | + faceIndex++; |
| 177 | + } |
| 178 | + } |
| 179 | + |
| 180 | + geometry.computeFaceNormals(); |
| 181 | + geometry.computeVertexNormals(); |
| 182 | + |
| 183 | + faces = new THREE.Mesh(geometry, faceMaterial); |
| 184 | + polyhedron.add(faces); |
| 185 | + return polyhedron; |
| 186 | +} |
| 187 | + |
| 188 | +function cylinderMesh(point1, point2, material) |
| 189 | +{ |
| 190 | + var direction = new THREE.Vector3().subVectors(point2, point1); |
| 191 | + var arrow = new THREE.ArrowHelper(direction.clone().normalize(), point1); |
| 192 | + var rotation = new THREE.Vector3().setEulerFromQuaternion(arrow.quaternion); |
| 193 | + var edgeGeometry = new THREE.CylinderGeometry( 2, 2, direction.length(), 8, 4 ); |
| 194 | + var edge = new THREE.Mesh(edgeGeometry, material); |
| 195 | + edge.position = new THREE.Vector3().addVectors(point1, direction.multiplyScalar(0.5)); |
| 196 | + edge.rotation = rotation; |
| 197 | + return edge; |
| 198 | + |
| 199 | + // the result should align with: |
| 200 | + // scene.add( new THREE.ArrowHelper( direction.clone().normalize(), point1, direction.length()) ); |
| 201 | +} |
| 202 | + |
| 203 | +function animate() |
| 204 | +{ |
| 205 | + requestAnimationFrame( animate ); |
| 206 | + render(); |
| 207 | + update(); |
| 208 | +} |
| 209 | + |
| 210 | +function update() |
| 211 | +{ |
| 212 | + if (camera.position.length() < 150) //console.log(1234); |
| 213 | + camera.position.setLength(150); |
| 214 | + if (camera.position.length() > 400) |
| 215 | + camera.position.setLength(400); |
| 216 | + |
| 217 | + controls.update(); |
| 218 | +} |
| 219 | + |
| 220 | +function render() |
| 221 | +{ |
| 222 | + renderer.render( scene, camera ); |
| 223 | +} |
| 224 | + |
| 225 | +</script> |
| 226 | + |
| 227 | +<!-- override dat.gui styles --> |
| 228 | +<style>.dg .property-name { width: 95% }</style> |
| 229 | + |
| 230 | +</body> |
| 231 | +</html> |
0 commit comments