|
- // IE9
- if (typeof console === "undefined") {
- var console = {
- log: function(logMsg) {}
- };
- }
-
- var controls, renderer, raycaster, scene, info, nodeGeometry, selection;
- var mouse = {
- "x": 0,
- "y": 0
- };
- var materials = {};
- var curveProperties = {
- splineDensity: 30,
- curvature: 10
- };
- var camera;
- var qubits;
-
- // Run on startup
- window.onload = init;
-
- // Add a curved edge between two points
- function makeEdge(e) {
- // Make the geometry of the curve
- var a = new THREE.Vector3(e.start[0], e.start[1], e.start[2]);
- var b = new THREE.Vector3(e.end[0], e.end[1], e.end[2]);
- var length = new THREE.Vector3().subVectors(a, b).length();
- var bend = new THREE.Vector3(length / curveProperties.curvature, length / curveProperties.curvature, 0);
- var mid = new THREE.Vector3().add(a).add(b).multiplyScalar(0.5).add(bend);
- var spline = new THREE.CatmullRomCurve3([a, mid, b]);
- var geometry = new THREE.Geometry();
- var splinePoints = spline.getPoints(curveProperties.splineDensity);
- Array.prototype.push.apply(geometry.vertices, splinePoints);
-
- // Make the actual Object3d thing
- var line = new THREE.Line(geometry, materials.edge);
- return line;
- }
-
- function makeQubits() {
- qubitGeometry = new THREE.Geometry();
- qubitGeometry.labels = [];
- var vertex = new THREE.Vector3(0, 0, 0);
- qubitGeometry.vertices.push(vertex);
- particles = new THREE.Points(qubitGeometry, materials.qubit);
- return particles;
- }
-
- // Clear the whole scene
- function makeScene() {
- // Scene, controls, camera and so on
- var myScene = new THREE.Scene();
-
- // Materials
- var lineStyle = {
- color: "gray",
- transparent: false,
- linewidth: 1
- };
- materials.edge = new THREE.LineBasicMaterial(lineStyle);
-
- var pointStyle = {
- color: "0xcccccc",
- size: 0.1,
- map: materials.sprite,
- alphaTest: 0.5,
- transparent: true,
- };
- materials.point = new THREE.PointsMaterial(pointStyle);
-
- var qubitStyle = {
- size: 0.6,
- map: materials.sprite,
- alphaTest: 0.5,
- transparent: true,
- color: "red"
- };
- materials.qubit = new THREE.PointsMaterial(qubitStyle);
-
- // Build all the edges
- //var edgeGroup = new THREE.Object3D();
-
- qubits = makeQubits();
- myScene.add(qubits);
-
- // Build all the nodes
- nodeGeometry = new THREE.Geometry();
- nodeGeometry.labels = [];
- for (var i = 0; i < 10; ++i) {
- for (var j = 0; j < 10; ++j) {
- var vertex = new THREE.Vector3(i - 5, j - 5, 0);
- nodeGeometry.vertices.push(vertex);
- nodeGeometry.labels.push("Click to add a qubit at (" + i + ", " + j + ")");
- }
- }
-
- var particles = new THREE.Points(nodeGeometry, materials.point);
-
- var grid = makeGrid(10, 10, "lightgray");
- myScene.add(grid);
-
- // Add the above stuff into the scene and return
- //myScene.add(edgeGroup);
- myScene.add(particles);
- return myScene;
- }
-
- // Gets a reference to the node nearest to the mouse cursor
- function nearestNode() {
- raycaster.setFromCamera(mouse, camera);
- for (var i = 0; i < nodeGeometry.vertices.length; ++i) {
- if (raycaster.ray.distanceSqToPoint(nodeGeometry.vertices[i]) < 0.01) {
- return i;
- }
- }
- return undefined;
- }
-
- // Find out: what is the mouse pointing at?
- function checkIntersections() {
- var new_selection = nearestNode();
- if (new_selection != selection) {
- selection = new_selection;
- info.className = selection ? "visible" : "hidden";
- info.innerHTML = selection ? nodeGeometry.labels[new_selection] : info.innerHTML;
- render();
- }
- }
-
- // Make a grid
- function makeGrid(side, n, color) {
- var markers = new THREE.Object3D();
- var gridStyle = {
- color: color,
- transparent: true,
- linewidth: 1,
- opacity: 0.5
- };
- var material = new THREE.LineBasicMaterial(gridStyle);
- for (var i = -n / 2; i < n / 2; ++i) {
- var geometry = new THREE.Geometry();
- geometry.vertices.push(new THREE.Vector3(side * i / n, -side / 2, 0));
- geometry.vertices.push(new THREE.Vector3(side * i / n, side / 2, 0));
- var line = new THREE.Line(geometry, material);
- var line90 = line.clone();
- line90.rotation.z = Math.PI / 2;
- markers.add(line);
- markers.add(line90);
- }
- return markers;
- }
-
- // Handle mouse movement
- function onMouseMove(event) {
- mouse.wasClick = false;
- mouse.absx = event.clientX;
- mouse.absy = event.clientY;
- mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
- mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
- w = 200;
- h = 15;
- info.style.top = mouse.absy - h - 40 + "px";
- info.style.left = mouse.absx - w / 2 + "px";
- checkIntersections();
- }
-
- function onClick(event){
- if (!selection){return;}
- console.log(nodeGeometry.vertices[selection]);
- qubits.geometry.dynamic = true;
- qubits.geometry.vertices.push(nodeGeometry.vertices[selection].clone());
- qubits.geometry.verticesNeedUpdate = true;
- }
-
- // Render the current frame to the screen
- function render() {
- renderer.render(scene, camera);
- }
-
- // This is the main control loop
- function loopForever() {
- controls.update();
- requestAnimationFrame(loopForever);
- }
-
-
- // This just organises kickoff
- function startMainLoop() {
- scene = makeScene();
- renderer.domElement.addEventListener("mousemove", onMouseMove, false);
- renderer.domElement.addEventListener("click", onClick, false);
- controls.addEventListener("change", render);
- loopForever();
- }
-
-
- // Called on startup
- function init() {
- // Measure things, get references
- var width = window.innerWidth;
- var height = window.innerHeight;
- info = document.getElementById("infoholder");
-
- materials.sprite = new THREE.Texture(document.getElementById("ball"));
- materials.sprite.needsUpdate = true;
-
- // Renderer
- renderer = new THREE.WebGLRenderer({
- antialias: true
- });
- renderer.setSize(width, height);
- renderer.setClearColor(0xffffff, 1);
- document.querySelector("body").appendChild(renderer.domElement);
-
- // Camera, controls, raycaster
- camera = new THREE.PerspectiveCamera(45, width / height, 0.3, 100);
- controls = new THREE.OrbitControls(camera);
- raycaster = new THREE.Raycaster();
-
- // Center the camera
- controls.center.set(0, 0, 0);
- controls.rotateSpeed = 0.2;
- camera.position.set(0, 0, 20);
-
- // Start polling
- setInterval(poll, 1000);
-
- // Run
- startMainLoop();
- }
|