X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=plugins%2Fsenslabmap%2Fstatic%2Fjs%2Fviewer3D.js;h=33ae659e481f92b14e89d040246d3854c9d0fc8b;hb=6a0470f524345a768a9878d3ec5d953208ede5c5;hp=cf70e812cb4ff786bc73f87674bda0942e056655;hpb=d384e4b10bf9ba67f610bef72cf0e5b2dd747baf;p=unfold.git diff --git a/plugins/senslabmap/static/js/viewer3D.js b/plugins/senslabmap/static/js/viewer3D.js index cf70e812..33ae659e 100644 --- a/plugins/senslabmap/static/js/viewer3D.js +++ b/plugins/senslabmap/static/js/viewer3D.js @@ -1,17 +1,8 @@ - -// Various global variables -var mouseX = 0, mouseY = 0, - camera, scene, renderer, projector; -var sTestEventType = 'mousedown'; -//var window3DWidth = window.innerWidth * 0.8; -//var window3DHeight=window.innerHeight*0.75; -var window3DWidth, window3DHeight; -var offX, offY; +// Various global variables +var mouseX = 0, mouseY = 0, camera, scene, renderer, projector; + // Camera parameters -phi = -100, theta = 0, distance = 150; -var rcount = 0; -// Text display -var info, nodelist, help; +var phi = -100, theta = 0, distance = 130; // graphical nodes var objects = []; @@ -21,322 +12,331 @@ var selectedNodes = []; var div3d, nodebox, infobox; -function init() { - var particles, particle; - - // jordan : modifier document.getElementById - div3d = jQuery('#div3d'); - nodebox = jQuery('#nodebox'); - infobox = jQuery('#infobox'); - titlebox = jQuery('#titlebox'); - // offset also - var offset = div3d.offset(); - offY = offset.top; - offX = offset.left; - - titlebox.innerHTML = 'Grenoble Site ' + nodes_gre.length + " nodes"; - infobox.innerHTML = 'Node info : '; - - nodebox.value = ""; - - camera = new THREE.PerspectiveCamera(75, window3DWidth / window3DHeight, 1, 10000); - - scene = new THREE.Scene(); +function onResize() { + renderer.setSize(div3d.offsetWidth, div3d.offsetHeight); + camera.aspect = div3d.offsetWidth / div3d.offsetHeight; + camera.updateProjectionMatrix(); + myrender(); +} - renderer = new THREE.CanvasRenderer(); +function getCenter(nodes) { + var xmin = 0, ymin = 0, zmin = 0; + var xmax = 0, ymax = 0, zmax = 0; + + for (var i = 0; i < nodes.length; i++) { + if (nodes[i][1] > xmax) xmax = nodes[i][1]; + if (nodes[i][1] < xmin) xmin = nodes[i][1]; + if (nodes[i][2] > ymax) ymax = nodes[i][2]; + if (nodes[i][2] < ymin) ymin = nodes[i][2]; + if (nodes[i][3] > zmax) zmax = nodes[i][3]; + if (nodes[i][3] < zmin) zmin = nodes[i][3]; + } + return {x: (xmax + xmin) / 2, y: (ymax + ymin) / 2, z: (zmax + zmin) / 2}; +} - // jordan XXX div3d.appendChild(renderer.domElement); - div3d.append(renderer.domElement); +function debugaxis(axisLength) { + var v = function(x, y, z) { + return new THREE.Vertex(new THREE.Vector3(x, y, z)); + } + + var createAxis = function (p1, p2, color) { + var lineGeometry = new THREE.Geometry(); + var lineMat = new THREE.LineBasicMaterial({ color: color, lineWidth: 2 }); + lineGeometry.vertices.push(p1, p2); + var line = new THREE.Line(lineGeometry, lineMat); + scene.add(line); + } + + createAxis(v(0, 0, 0), v(axisLength, 0, 0), 0xFF0000); + createAxis(v(0, 0, 0), v(0, axisLength, 0), 0x00FF00); + createAxis(v(0, 0, 0), v(0, 0, axisLength), 0x0000FF); +}; - window.addEventListener('resize', set3dsize, false); - scene.add(camera); - set3dsize(); +function drawNodes(nodes) { + var geometry = new THREE.Geometry(); + var center = getCenter(nodes); + + onResize(); + for (var i = 0; i < nodes.length; i++) { + var material = new THREE.ParticleCanvasMaterial({ + color: 0xffffff, + program: function (context) { + context.beginPath(); + context.arc(0, 0, 1, 0, Math.PI * 2, true); + context.closePath(); + context.fill(); + } + }); + var particle = new THREE.Particle(material); + particle.name = nodes[i][0]; + particle.position.x = nodes[i][1] - center.x; + particle.position.y = nodes[i][2] - center.y; + particle.position.z = nodes[i][3] - center.z; + particle.uid = nodes[i][4]; + particle.state = nodes[i][5]; + particle.position.multiplyScalar(10); + particle.scale.x = particle.scale.y = 1; + scene.add(particle); + + var vertex = new THREE.Vertex(particle.position); + geometry.vertices.push(vertex); + objects.push(particle) - - var PI2 = Math.PI * 2; - var geometry = new THREE.Geometry(); - - // let's find the center of the nodes - xmin = ymin = zmin = 0; - xmax = ymax = zmax = 0; - - for (var i = 0; i < nodes_gre.length; i++) { - if (nodes_gre[i][1] > xmax) xmax = nodes_gre[i][1]; - if (nodes_gre[i][1] < xmin) xmin = nodes_gre[i][1]; - if (nodes_gre[i][2] > ymax) ymax = nodes_gre[i][2]; - if (nodes_gre[i][2] < ymin) ymin = nodes_gre[i][2]; - if (nodes_gre[i][3] > zmax) zmax = nodes_gre[i][3]; - if (nodes_gre[i][3] < zmin) zmin = nodes_gre[i][3]; - } - - xcenter = (xmax + xmin) / 2; - ycenter = (ymax + ymin) / 2; - zcenter = (zmax + zmin) / 2; - - // display nodes as TREE particles - for (var i = 0; i < nodes_gre.length; i++) { - material = new THREE.ParticleCanvasMaterial({ - color: 0xffffff, - program: function (context) { - context.beginPath(); - context.arc(0, 0, 1, 0, PI2, true); - context.closePath(); - context.fill(); - } - }); - particle = new THREE.Particle(material); - particle.name = nodes_gre[i][0]; - particle.position.x = nodes_gre[i][1] - xcenter; - particle.position.y = nodes_gre[i][2] - ycenter; - particle.position.z = nodes_gre[i][3] - zcenter; - particle.position.multiplyScalar(10); - particle.scale.x = particle.scale.y = 1; - scene.add(particle); - v = new THREE.Vertex(particle.position); - geometry.vertices.push(v); - objects.push(particle) - } - debugaxis(10); - // a projector is needed to find which node is under the mouse - projector = new THREE.Projector(); - - nodebox.onkeyup = parseNodebox; - // set mouse event handlers // TODO jordan - document.onmousedown = OnMouseDown; - document.onmouseup = OnMouseUp; - document.onmousemove = displayNodeInfo; - if (window.addEventListener) - /** DOMMouseScroll is for mozilla. */ - window.addEventListener('DOMMouseScroll', wheel, false); - /** IE/Opera. */ - window.onmousewheel = document.onmousewheel = wheel; myrender(); + } } -function set3dsize() { - // jordan - var offset = div3d.offset(); - offY = offset.top; - offX = offset.left; - window3DWidth = div3d.width(); - window3DHeight = div3d.height(); - renderer.setSize(window3DWidth, window3DHeight); - - camera.aspect = window3DWidth / window3DHeight; - camera.updateProjectionMatrix(); - - myrender(); +function init(nodes) { + div3d = document.getElementById('div3d'); + nodebox = document.getElementById('nodebox'); + infobox = document.getElementById('infobox'); + + infobox.innerHTML = 'Node info : '; + nodebox.value = ""; + + camera = new THREE.PerspectiveCamera(75, div3d.offsetWidth / div3d.offsetHeight, 1, 10000); + scene = new THREE.Scene(); + renderer = new THREE.CanvasRenderer(); + projector = new THREE.Projector(); + + div3d.appendChild(renderer.domElement); + + window.addEventListener('resize', onResize, false); + scene.add(camera); + + nodebox.onkeyup = parseNodebox; + + div3d.onmousedown = OnMouseDown; + div3d.onmouseup = OnMouseUp; + div3d.onmousemove = displayNodeInfo; + if (div3d.addEventListener) { + div3d.addEventListener('DOMMouseScroll', wheel, false); // mozilla + } + div3d.onmousewheel = wheel; // IE & Opera } function sortfunction(a, b) { - return (a - b) //causes an array to be sorted numerically and ascending + return (a - b) //causes an array to be sorted numerically and ascending } // factorize the expanded list in selectedNode to produce dash intervals // 1,2,3,5,9 -> 1-3,5,9 function factorize() { - var fact = []; - var previous = 0; - var intervalStart = 0; - selectedNodes.sort(sortfunction); - for (j = 0; j < selectedNodes.length; j++) { - if (intervalStart) { - // we are in an interval - if (selectedNodes[j] == previous + 1) { - // interval grows - previous += 1; - } else { - // end of interval - fact.push(intervalStart + "-" + previous); - intervalStart = 0; - previous = selectedNodes[j]; - } - } else { - // we are not in an interval - if (selectedNodes[j] == previous + 1) { - // let's begin an interval - intervalStart = previous; - previous += 1; - } else { - if (previous) fact.push(previous); - previous = selectedNodes[j]; - } - } - } // for end - // at the end of the loop, two cases - // we were still in an interval, then add it to the result - // we were not in an interval, then add the last selectednode (previous) + var fact = []; + var previous = 0; + var intervalStart = 0; + selectedNodes.sort(sortfunction); + for (j = 0; j < selectedNodes.length; j++) { if (intervalStart) { + // we are in an interval + if (selectedNodes[j] == previous + 1) { + // interval grows + previous += 1; + } else { + // end of interval fact.push(intervalStart + "-" + previous); + intervalStart = 0; + previous = selectedNodes[j]; + } } else { - if (previous) fact.push(previous); + // we are not in an interval + if (selectedNodes[j] == previous + 1) { + // let's begin an interval + intervalStart = previous; + previous += 1; + } else { + if (previous) { + fact.push(previous); + } + previous = selectedNodes[j]; + } } - return fact; + } // for end + // at the end of the loop, two cases + // we were still in an interval, then add it to the result + // we were not in an interval, then add the last selectednode (previous) + if (intervalStart) { + fact.push(intervalStart + "-" + previous); + } else if (previous) { + fact.push(previous); + } + return fact; } // expand a list of nodes containing dash intervals // 1-3,5,9 -> 1,2,3,5,9 -function expand(factExp) { - exp = []; - for (i = 0; i < factExp.length; i++) { - dashExpression = factExp[i].split("-"); - if (dashExpression.length == 2) { - for (j = parseInt(dashExpression[0]); j < (parseInt(dashExpression[1]) + 1); j++) - exp.push(j); - } else exp.push(parseInt(factExp[i])); +function expand(input) { + var factorized = input.split(","); + var expanded = []; + for (var i = 0; i < factorized.length; i++) { + var d = factorized[i].split("-"); + if (d.length == 2) { + for (var j = parseInt(d[0]); j < parseInt(d[1]) + 1; j++) { + expanded.push(j); + } + } else { + expanded.push(parseInt(factorized[i])); + } + } + expanded.sort(sortfunction); + for (var i = 1; i < expanded.length; i++) { + if (expanded[i] == expanded[i - 1]) { + expanded.splice(i--, 1); } - exp.sort(sortfunction); - for (var i = 1; i < exp.length; i++) { if (exp[i] == exp[i - 1]) { exp.splice(i--, 1); } } - return exp; + } + return expanded; } function parseNodebox() { - input = nodebox.value; - selectedNodes = expand(input.split(",")); - myrender(); + selectedNodes = expand(nodebox.value); + myrender(); } -function debugaxis(axisLength) { - //Shorten the vertex function - function v(x, y, z) { - return new THREE.Vertex(new THREE.Vector3(x, y, z)); - } - - //Create axis (point1, point2, colour) - function createAxis(p1, p2, color) { - var line, lineGeometry = new THREE.Geometry(), - lineMat = new THREE.LineBasicMaterial({ color: color, lineWidth: 2 }); - lineGeometry.vertices.push(p1, p2); - line = new THREE.Line(lineGeometry, lineMat); - scene.add(line); - } - - createAxis(v(0, 0, 0), v(axisLength, 0, 0), 0xFF0000); - createAxis(v(0, 0, 0), v(0, axisLength, 0), 0x00FF00); - createAxis(v(0, 0, 0), v(0, 0, axisLength), 0x0000FF); -}; - // set the camera position according two angles theta and phi and the distance // and display the scene function myrender() { - //infobox.innerHTML = " Cam Pos = " + camera.position.x + "," + camera.position.y + "," + camera.position.z - // + " - " + theta + "," + phi + ","+ distance; - //infobox.innerHTML = selectedNodes; - camera.position.x = distance * Math.sin(theta * Math.PI / 360) * Math.cos(phi * Math.PI / 360); - camera.position.y = distance * Math.sin(this.phi * Math.PI / 360); - camera.position.z = distance * Math.cos(this.theta * Math.PI / 360) * Math.cos(this.phi * Math.PI / 360); - camera.lookAt(scene.position); - camera.updateMatrix(); - - for (i = 0; i < objects.length; i++) - if (selectedNodes.indexOf(objects[i].name) != -1) objects[i].material.color.setHex(0xff0000); - else objects[i].material.color.setHex(0xffffff); - renderer.render(scene, camera); + camera.position.x = distance * Math.sin(theta * Math.PI / 360) * Math.cos(phi * Math.PI / 360); + camera.position.y = distance * Math.sin(this.phi * Math.PI / 360); + camera.position.z = distance * Math.cos(this.theta * Math.PI / 360) * Math.cos(this.phi * Math.PI / 360); + camera.lookAt(scene.position); + camera.updateMatrix(); + + for (i = 0; i < objects.length; i++) { + if (selectedNodes.indexOf(objects[i].name) != -1) { + objects[i].material.color.setHex(0x0099CC); + } else { + if (objects[i].state == "Busy") { + objects[i].material.color.setHex(0x9943BE); + } else if (objects[i].state == "Alive") { + objects[i].material.color.setHex(0x7FFF00); + } else { + objects[i].material.color.setHex(0xFF3030); + } + } + } + renderer.render(scene, camera); } -// rigthbutton is used for rotations +// rigthbutton is used for rotations function onDocumentMouseMoveRot(event) { - NewmouseX = event.clientX; - NewmouseY = event.clientY; - DeltaX = NewmouseX - mouseX; - DeltaY = NewmouseY - mouseY; - - mouseX = NewmouseX; - mouseY = NewmouseY; - - theta -= DeltaX; - phi += DeltaY; - if (phi > 180) phi = 180; - if (phi < -180) phi = -180; - myrender(); + var NewmouseX = event.clientX; + var NewmouseY = event.clientY; + var DeltaX = NewmouseX - mouseX; + var DeltaY = NewmouseY - mouseY; + + mouseX = NewmouseX; + mouseY = NewmouseY; + + theta -= DeltaX; + phi += DeltaY; + if (phi > 180) phi = 180; + if (phi < -180) phi = -180; + myrender(); } // mousewheel is used for zoom function Zoom(delta) { - distance += delta * 5; - myrender(); + distance += delta * 5; + myrender(); } // return the graphical node under the mouse function findNodeUnderMouse(event) { - var vector = new THREE.Vector3(((event.clientX - offX) / window3DWidth) * 2 - 1, -((event.clientY - offY) / window3DHeight) * 2 + 1, 0.5); - projector.unprojectVector(vector, camera); - var ray = new THREE.Ray(camera.position, vector.subSelf(camera.position).normalize()); - var intersects = ray.intersectObjects(objects); - if (intersects.length > 0) { - return intersects[0]; - } else return null; + var x, y, z; + + event.preventDefault(); + + x = ((event.clientX - div3d.offsetLeft) / div3d.offsetWidth) * 2 - 1; + y = -((event.clientY - div3d.offsetTop) / div3d.offsetHeight) * 2 + 1; + z = 0.5; + + var vector = new THREE.Vector3(x, y, z); + projector.unprojectVector(vector, camera); + + var ray = new THREE.Ray(camera.position, vector.subSelf(camera.position).normalize()); + var intersects = ray.intersectObjects(objects); + + if (intersects.length > 0) { + return intersects[0]; + } else { + return null; + } } // display some info of the node under the mouse function displayNodeInfo(e) { - obj = findNodeUnderMouse(e); - if (obj) infobox.innerHTML = 'Node info : number ' + obj.object.name + " with id " + nodes_gre[obj.object.id][4]; - // else infobox.innerHTML = e.clientX + "," + e.clientY + " - " + offX + "," + offY; + obj = findNodeUnderMouse(e); + if (obj) { + infobox.innerHTML = 'Node info : number ' + obj.object.name + " with id " + obj.object.uid; + } } // select/unselect nodes function toggleNode(obj) { - nodeId = obj.object.name; - i = selectedNodes.indexOf(nodeId); - if (i == -1) selectedNodes.push(nodeId); - else selectedNodes.splice(i, 1); - nodebox.value = factorize().join(","); - myrender(); + var nodeId = obj.object.name; + var index = selectedNodes.indexOf(nodeId); + + if (index == -1) { + selectedNodes.push(nodeId); + } else { + selectedNodes.splice(index, 1); + } + nodebox.value = factorize().join(","); + myrender(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Mouse handling functions // function OnMouseDown(e) { - var clickType = 'LEFT'; - if (e.type != sTestEventType) return true + var clickType = 'LEFT'; + if (e.type != 'mousedown') return true if (e.which) { - if (e.which == 3) clickType = 'RIGHT'; - if (e.which == 2) clickType = 'MIDDLE'; - //infobox.innerHTML = clickType + " - Cam Pos = " + camera.position.x + "," + camera.position.y + "," + camera.position.z; + if (e.which == 3) clickType = 'RIGHT'; + if (e.which == 2) clickType = 'MIDDLE'; + //infobox.innerHTML = clickType + " - Cam Pos = " + camera.position.x + "," + camera.position.y + "," + camera.position.z; } mouseX = e.clientX; - mouseY = e.clientY; - if (clickType == 'RIGHT') { - document.onmousemove = onDocumentMouseMoveRot; - } - if (clickType == 'LEFT') { - obj = findNodeUnderMouse(e); - if (obj != null) toggleNode(obj); - } + mouseY = e.clientY; + if (clickType == 'RIGHT') { + document.onmousemove = onDocumentMouseMoveRot; + } + if (clickType == 'LEFT') { + obj = findNodeUnderMouse(e); + if (obj != null) toggleNode(obj); + } } function OnMouseUp(e) { - document.onmousemove = displayNodeInfo; + document.onmousemove = displayNodeInfo; } // This function was taken here : http://www.adomas.org/javascript-mouse-wheel/ // Event handler for mouse wheel event. function wheel(event) { - var delta = 0; - if (!event) /* For IE. */ - event = window.event; - if (event.wheelDelta) { /* IE/Opera. */ - delta = event.wheelDelta / 120; - } else if (event.detail) { /** Mozilla case. */ - /** In Mozilla, sign of delta is different than in IE. - * Also, delta is multiple of 3. - */ - delta = -event.detail / 3; - } - /** If delta is nonzero, handle it. - * Basically, delta is now positive if wheel was scrolled up, - * and negative, if wheel was scrolled down. - */ - if (delta) - Zoom(delta); - /** Prevent default actions caused by mouse wheel. - * That might be ugly, but we handle scrolls somehow - * anyway, so don't bother here.. - */ - if (event.preventDefault) - event.preventDefault(); - event.returnValue = false; -} + var delta = 0; + if (!event) /* For IE. */ + event = window.event; + if (event.wheelDelta) { /* IE/Opera. */ + delta = event.wheelDelta / 120; + } else if (event.detail) { /** Mozilla case. */ + /** In Mozilla, sign of delta is different than in IE. + * Also, delta is multiple of 3. + */ + delta = -event.detail / 3; + } + /** If delta is nonzero, handle it. + * Basically, delta is now positive if wheel was scrolled up, + * and negative, if wheel was scrolled down. + */ + if (delta) + Zoom(delta); + /** Prevent default actions caused by mouse wheel. + * That might be ugly, but we handle scrolls somehow + * anyway, so don't bother here.. + */ + if (event.preventDefault) + event.preventDefault(); + event.returnValue = false; +}