diff --git a/templates/UPlanetSector/images/earth1.jpg b/templates/UPlanetSector/images/earth1.jpg new file mode 100644 index 000000000..a1653b509 Binary files /dev/null and b/templates/UPlanetSector/images/earth1.jpg differ diff --git a/templates/UPlanetSector/images/sector0.jpg b/templates/UPlanetSector/images/sector0.jpg new file mode 100644 index 000000000..ab0e0754e Binary files /dev/null and b/templates/UPlanetSector/images/sector0.jpg differ diff --git a/templates/UPlanetSector/images/sector1.jpg b/templates/UPlanetSector/images/sector1.jpg new file mode 100644 index 000000000..2cc78e223 Binary files /dev/null and b/templates/UPlanetSector/images/sector1.jpg differ diff --git a/templates/UPlanetSector/images/sector2.jpg b/templates/UPlanetSector/images/sector2.jpg new file mode 100644 index 000000000..4acf9a778 Binary files /dev/null and b/templates/UPlanetSector/images/sector2.jpg differ diff --git a/templates/UPlanetSector/images/sector3.jpg b/templates/UPlanetSector/images/sector3.jpg new file mode 100644 index 000000000..0bab1cbbe Binary files /dev/null and b/templates/UPlanetSector/images/sector3.jpg differ diff --git a/templates/UPlanetSector/images/sphere.jpg b/templates/UPlanetSector/images/sphere.jpg new file mode 100644 index 000000000..186280b6f Binary files /dev/null and b/templates/UPlanetSector/images/sphere.jpg differ diff --git a/templates/UPlanetSector/index_fichiers/jquery.sector-3d.js b/templates/UPlanetSector/index_fichiers/jquery.sector-3d.js new file mode 100644 index 000000000..2c30aed12 --- /dev/null +++ b/templates/UPlanetSector/index_fichiers/jquery.sector-3d.js @@ -0,0 +1,851 @@ + +/* + jquery.earth3d.js + + jQuery ui plugin that allow you to draw a beautiful 3d spinning earth on canvas + + Author: Sebastien Drouyer + + Based on the amazing sphere.js plug of Sam Hasler + + Licensed under the MIT license (MIT-LICENSE.txt) + + http://sdrdis.github.com/jquery.earth-3d/ + + + + Depends: + ui.core.js + + + + + Options: + * texture: texture map used by the planet + + * sphere: rotation and size of the planet + + * defaultSpeed: default spinning speed of the planet + + * backToDefaultTime: time (in ms) to return by to default speed when planet is dragged + + * locations: locations to display on the planet: + * Each position must have a key, an alpha and delta position (or x and y if you want to display a static location). + Any additional key can be reached via callbacks functions + Example: + { + obj1: { + alpha: Math.PI / 4, + delta: 0, + name: 'location 1' + } + } + + * paths: paths and flights to display over the planet: + Each path must have a key, an origin and a destination. The values are the location's key. + You can, if you want to, define flights on these paths. + Each flight has a key, a destination (the location's key) and a position. + The position is the progress a fleet has made on its path. + Any additional key can be reach via callbacks functions. + Example: + { + path: { + origin: 'obj1', + destination: 'obj2', + flights: { + flight: { + position: 0.25, + destination: 'obj2', + name: 'Flight 1' + }, + flight2: { + position: 0.25, + destination: 'obj1', + name: 'Flight 2' + } + } + } + } + + * flightsCanvas: Dom element which is a canvas and where the flights and paths are drawn + + * dragElement: Dom element where we catch the mouse drag + + * locationsElement: Dom elements where the locations are drawn + + * flightsCanvasPosition: position of the flight canvas (can be use if you have some gap between your planet and your flights + + * pixelRadiusMultiplier: (TEMPORARY) used by the getSphereRadiusInPixel (see the functions) + + * onInitLocation: callback function which allows you to define what to do when the locations are initialized + * Parameters: + * location: location (coming from locations option) + * widget: earth3d widget object + + * onShowLocation: callback function which allows you to define what to do when a location becomes visible (was behind the planet and is now in front of it) + * Parameters: + * location: location (coming from locations option) + * x: 2d left position + * y: 2d top position + * widget: earth3d widget object + + * onRefreshLocation: callback function which allows you to define what to do when a location is refreshed (it moves) + * Parameters: + * location: location (coming from locations option) + * x: 2d left position + * y: 2d top position + * widget: earth3d widget object + + * onHideLocation: callback function which allows you to define what to do when a location becomes invisible (was in front of the planet and is now behind it) + * Parameters: + * location: location (coming from locations option) + * x: 2d left position + * y: 2d top position + * widget: earth3d widget object + + * onInitFlight: callback function which allows you to define what to do when the flights are initialized + * Parameters: + * flight: flight (coming from flights option) + * widget: earth3d widget object + + * onShowFlight: callback function which allows you to define what to do when a flight becomes visible (was behind the planet and is now in front of it) + * Parameters: + * flight: flight (coming from flights option) + * widget: earth3d widget object + + * onRefreshFlight: callback function which allows you to define what to do when a flight is refreshed (it moves) + * Parameters: + * flight: flight (coming from flights option) + * x: 2d left position + * y: 2d top position + * widget: earth3d widget object + + * onHideFlight: callback function which allows you to define what to do when a flight becomes invisible (was in front of the planet and is now behind it) + * Parameters: + * flight: flight (coming from flights option) + * widget: earth3d widget object + + + + + + + Functions + + * getSphereRadiusInPixel: function which allows you to get the sphere radius in pixel + /!| WARNING: this function needs to be refactored, since I didn't find out (my maths courses are far away) how to + get the exact value. I did a basic linear regression, but it is not exact, and you will have to change the pixelRadiusMultiplier + option to get the correct value + + * destroy: use this function when you want to destroy the object. It will throw a cancel animation frame, so the + CPU won't be used anymore. + + * changePaths: use this function when you want to update paths and flights (options on widget) + it will add the callback functions support + + */ +var earth3d; +(function($) { + $.widget('ui.earth3d', { + options: { + texture: '/ipfs/QmYnua8dERLaUw7mHb5RZnJCfShWXchMRbV1wzzcVSqJKT/sphere.jpg', + sphere: { + tilt: 0, + turn: 0, + r: 10 + }, + defaultSpeed: 20, + backToDefaultTime: 4000, + locations: { + }, + paths: { + }, + flightsCanvas: null, + dragElement: null, + locationsElement: null, + flightsCanvasPosition: { + x: 0, + y: 0 + }, + tiling: {horizontal: 1, vertical: 1}, + pixelRadiusMultiplier: 0.97, + onInitLocation: function(location, widget) { + var $elem = $('
'); + $elem.appendTo(widget.options.locationsElement); + $elem.click(function() { + alert('Clicked on ' + location.name + ' : ' + location.link ); + window.open( location.link, "AstroTab"); + }); + location.$element = $elem; + }, + onShowLocation: function(location, x, y) { + location.$element.show(); + }, + onRefreshLocation: function(location, x, y) { + //console.log(x, y); + location.$element.css({ + left: x, + top: y + }); + }, + onHideLocation: function(location, x, y) { + location.$element.hide(); + }, + onDeleteLocation: function(location) { + location.$element.remove(); + }, + onInitFlight: function(flight, widget) { + var $elem = $('
'); + $elem.appendTo(widget.options.locationsElement); + $elem.click(function() { + alert('Clicked on ' + flight.name); + + }); + flight.$element = $elem; + }, + onShowFlight: function(flight) { + flight.$element.show(); + }, + onRefreshFlight: function(flight, x, y, angle, widget) { + flight.$element.css({ + left: x, + top: y, + '-webkit-transform':'rotate(' + ((angle + Math.PI / 2) * 360 / (2 * Math.PI)) + 'deg)', + '-moz-transform':'rotate(' + ((angle + Math.PI / 2) * 360 / (2 * Math.PI)) + 'deg)', + '-o-transform':'rotate(' + ((angle + Math.PI / 2) * 360 / (2 * Math.PI)) + 'deg)' + }); + }, + onHideFlight: function(flight) { + flight.$element.hide(); + }, + onDeleteFlight: function(flight) { + flight.$element.remove(); + } + }, + earth: null, + posVar: 24 * 3600 * 1000, + lastMousePos: null, + lastSpeed: null, + lastTime: null, + lastTurnByTime: null, + textureWidth: null, + textureHeight: null, + obj: null, + flightsCtx: null, + renderAnimationFrameId: null, + mousePressed: null, + + _create: function() { + earth3d = this; + var self = this; + this.obj = $('div'); + if (this.options.flightsCanvas !== null) { + this.flightsCtx = this.options.flightsCanvas[0].getContext('2d'); + } + createSphere(this.element[0], this.options.texture, function(earth, textureWidth, textureHeight) { self._onSphereCreated(earth, textureWidth, textureHeight); }, this.options.tiling); + if (this.options.dragElement !== null) { + this.options.dragElement + .bind('mousedown vmousedown', function(e) { + self._mouseDragStart(e); + self.mousePressed = true; + }) + .bind('mouseup vmouseup', function(e) { + self._mouseDragStop(e); + self.mousePressed = false; + }) + .bind('mousemove vmousemove', function(e){ + if (self.mousePressed) { + self._mouseDrag(e); + } + }); + } + this._initLocations(); + this._initFlights(); + }, + + _initLocations: function() { + for (var key in this.options.locations) { + var location = this.options.locations[key]; + location.visible = true; + this.options.onInitLocation(location, this); + } + }, + + _initFlights: function() { + for (var key in this.options.paths) { + var path = this.options.paths[key]; + for (var key in path.flights) { + path.flights[key].visible = true; + this.options.onInitFlight(path.flights[key], this); + } + } + }, + + getSphereRadiusInPixel: function() { + return this.earth.getRadius() / 2; + }, + + _onSphereCreated: function(earth, textureWidth, textureHeight) { + var self = this; + this.textureWidth = textureWidth; + this.textureHeight = textureHeight; + this.earth = earth; + this.earth.init(this.options.sphere); + this.earth.turnBy = function(time) { return self._turnBy(time); }; + + var renderAnimationFrame = function(/* time */ time) { + /* time ~= +new Date // the unix time */ + earth.renderFrame(time); + self._renderAnimationFrame(time); + self.renderAnimationFrameId = window.requestAnimationFrame(renderAnimationFrame); + }; + this.renderAnimationFrameId = window.requestAnimationFrame(renderAnimationFrame); + }, + + destroy: function() { + window.cancelAnimationFrame(this.renderAnimationFrameId); + }, + + _renderAnimationFrame: function(time) { + + + var ry=90+this.options.sphere.tilt; + var rz=180+this.options.sphere.turn; + + var RY = (90-ry); + var RZ = (180-rz); + var RX = 0,RY,RZ; + + var rx=RX*Math.PI/180; + var ry=RY*Math.PI/180; + var rz=RZ*Math.PI/180; + //console.log(rx, ry, rz); + var r = this.getSphereRadiusInPixel(); + + var center = { + x: this.element.width() / 2, + y: this.element.height() / 2 + } + + for (var key in this.options.locations) { + var location = this.options.locations[key]; + + if (typeof location.delta === 'undefined') { + location.flatPosition = {x: location.x, y: location.y}; + this.options.onRefreshLocation(location, location.x, location.y, this); + continue; + } + + /* + WARNING: calculation of alphaAngle and deltaAngle is not exact + I had to create the _calibrated functions to modify the deltaAngle to make the result look good on + a spinning planet without rotation. It will totally bug with rotation! + * */ + var progression = (((this.posVar + this.textureWidth * location.delta / (2 * Math.PI)) % this.textureWidth) / this.textureWidth); + var alphaAngle = progression * 2 * Math.PI; + var deltaAngle = this._calibrated(progression, location.alpha) * 2 * Math.PI; + + + var objAlpha = ry + location.alpha - Math.sin(alphaAngle / 2) * 0.15 * (location.alpha - Math.PI / 2) / (Math.PI / 4); + var objDelta = rz + deltaAngle; + + var a = this._orbitalTo3d(objAlpha, objDelta, r); + + var flatPosition = this._orthographicProjection(a); + + if (a.x < 0 && !location.visible) { + this.options.onShowLocation(location, flatPosition.x, flatPosition.y, this); + } + if (a.x > 0 && location.visible) { + this.options.onHideLocation(location, flatPosition.x, flatPosition.y, this); + } + this.options.onRefreshLocation(location, flatPosition.x, flatPosition.y, this); + + location.visible = a.x < 0; + location.position = a; + location.flatPosition = flatPosition; + location.rAlpha = objAlpha; + location.rDelta = objDelta; + + } + + if (this.flightsCtx !== null) { + this.flightsCtx.clearRect(0, 0, this.options.flightsCanvas.width(), this.options.flightsCanvas.height()); + for (var key in this.options.paths) { + this._drawPath(this.options.paths[key], center, r); + } + } + }, + + + + _line_circle_intersection: function(A, B, C, r) { + var d = { + x: B.x - A.x, + y: B.y - A.y + }; + + var f = { + x: A.x - C.x, + y: A.y - C.y + }; + + var a = this._dot(d, d); + var b = 2 * this._dot(f, d); + var c = this._dot(f, f) - r * r; + + var discriminant = b * b - 4 * a * c; + if (discriminant < 0) { + return false; + } else { + discriminant = Math.sqrt(discriminant); + var t1 = (-b + discriminant) / (2 * a); + var t2 = (-b - discriminant) / (2 * a); + + + var sols = []; + + if (t1 >= 0 && t1 <= 1) { + sols.push({ + x:A.x + t1 * d.x, + y:A.y + t1 * d.y + }); + } + + if (t2 >= 0 && t2 <= 1) { + sols.push({ + x:A.x + t2 * d.x, + y:A.y + t2 * d.y + }); + } + + return sols; + } + }, + + _dot: function(A, B) { + return A.x * B.x + A.y * B.y; + }, + + _drawPath: function(path, center, r) { + + + var originLocation = this.options.locations[path.origin]; + var destinationLocation = this.options.locations[path.destination]; + + var dotSize = 50; + var spacing = 0.15; + + if (typeof originLocation.delta === 'undefined' || typeof destinationLocation.delta === 'undefined') { + var pathVisible = originLocation.visible && destinationLocation.visible; + if (pathVisible) { + + + var flatDistance = this._distance(originLocation.flatPosition, destinationLocation.flatPosition); + + var nb = flatDistance * 0.9 / 20; + // WARNING: we are drawing the paths on canvas, intensively using CPU. Could we gain by instead using SVG or the DOM ? + for (var i = 0; i < nb; i++) { + + + var fromFlatPosition = { + x: ((nb - i) / nb) * originLocation.flatPosition.x + (i / nb) * destinationLocation.flatPosition.x, + y: ((nb - i) / nb) * originLocation.flatPosition.y + (i / nb) * destinationLocation.flatPosition.y + }; + + var toFlatPosition = { + x: Math.max(((nb - (i + 1)) / nb), 0) * originLocation.flatPosition.x + Math.min(((i + 1) / nb), 1) * destinationLocation.flatPosition.x, + y: Math.max(((nb - (i + 1)) / nb), 0) * originLocation.flatPosition.y + Math.min(((i + 1) / nb), 1) * destinationLocation.flatPosition.y + }; + + var diff = { + x: fromFlatPosition.x - toFlatPosition.x, + y: fromFlatPosition.y - toFlatPosition.y, + z: fromFlatPosition.z - toFlatPosition.z + }; + + fromFlatPosition.x -= diff.x * spacing; + fromFlatPosition.y -= diff.y * spacing; + fromFlatPosition.z -= diff.z * spacing; + toFlatPosition.x += diff.x * spacing; + toFlatPosition.y += diff.y * spacing; + toFlatPosition.z += diff.z * spacing; + + + this.flightsCtx.lineWidth = 3; + this.flightsCtx.beginPath(); + this.flightsCtx.strokeStyle = 'rgba(255, 255, 255, 0.5)'; + this.flightsCtx.moveTo(fromFlatPosition.x + this.options.flightsCanvasPosition.x, fromFlatPosition.y + this.options.flightsCanvasPosition.y); + this.flightsCtx.lineTo(toFlatPosition.x + this.options.flightsCanvasPosition.x, toFlatPosition.y + this.options.flightsCanvasPosition.y); + this.flightsCtx.stroke(); + + } + + } + + + + for (var key in path.flights) { + var flight = path.flights[key]; + + var position = flight.destination == path.destination ? flight.position : (1 - flight.position); + + + var flightFlatPosition = { + x: (1 - position) * originLocation.flatPosition.x + position * destinationLocation.flatPosition.x, + y: (1 - position) * originLocation.flatPosition.y + position * destinationLocation.flatPosition.y + }; + + if (!flight.visible && pathVisible) { + this.options.onShowFlight(flight, this); + flight.visible = true; + } + + if (flight.visible && !pathVisible) { + this.options.onHideFlight(flight, this); + flight.visible = false; + } + + var angle = Math.atan2(destinationLocation.flatPosition.y - originLocation.flatPosition.y, destinationLocation.flatPosition.x - originLocation.flatPosition.x) + (flight.destination == path.destination ? 0 : Math.PI); + //console.log(flightAheadFlatPosition.y - flightFlatPosition.y); + + this.options.onRefreshFlight(flight, flightFlatPosition.x, flightFlatPosition.y, angle, this); + } + + + return; + } + + var locationsDistance = this._distance(originLocation.position, destinationLocation.position); + + + var middlePosition = { + x: 0, + y: 0, + z: 0 + }; + + + var radius = this._distance(originLocation.position, middlePosition); + + var originP = { + delta: Math.atan2((originLocation.position.y - middlePosition.y), (originLocation.position.x - middlePosition.x)), + alpha: Math.acos((originLocation.position.z - middlePosition.z) / radius) + }; + + var destinationP = { + delta: Math.atan2((destinationLocation.position.y - middlePosition.y), (destinationLocation.position.x - middlePosition.x)), + alpha: Math.acos((destinationLocation.position.z - middlePosition.z) / radius) + }; + + + + if (Math.abs(originP.delta - destinationP.delta) > Math.PI) { + if ((originP.delta - destinationP.delta) > Math.PI) { + originP.delta -= 2 * Math.PI; + } else { + originP.delta += 2 * Math.PI; + } + } + + if (path.sens) { + if (((originP.delta - destinationP.delta) > 0 ? 1 : -1) != path.sens) { + if (Math.abs(originP.delta - destinationP.delta) > Math.PI / 2) { + originP.delta += path.sens * 2 * Math.PI; + } + } + } else { + path.sens = (originP.delta - destinationP.delta) > 0 ? 1 : -1; + } + + + if (!path.nb) { + path.nb = Math.round(((locationsDistance / (2 * r)) * Math.PI * 2 * r + (1 - (locationsDistance / (2 * r))) * locationsDistance) / dotSize); + } + var nb = path.nb; + var maxDistance = 1.2; + for (var i = 0; i < nb; i++) { + var fromP = { + alpha: ((nb - i) / nb) * originP.alpha + (i / nb) * destinationP.alpha, + delta: ((nb - i) / nb) * originP.delta + (i / nb) * destinationP.delta + }; + + var toP = { + alpha: ((nb - 1 - i) / nb) * originP.alpha + ((i + 1) / nb) * destinationP.alpha, + delta: ((nb - 1 - i) / nb) * originP.delta + ((i + 1) / nb) * destinationP.delta + }; + //console.log(i, fromP.alpha, fromP.delta, toP.alpha, toP.delta); + + var fromPosition = this._orbitalTo3d(fromP.alpha, fromP.delta, -(Math.sin(Math.PI * i / nb) * (maxDistance - 1) + 1) * radius); + var toPosition = this._orbitalTo3d(toP.alpha, toP.delta, -(Math.sin(Math.PI * (i + 1) / nb) * (maxDistance - 1) + 1) * radius); + var diff = { + x: fromPosition.x - toPosition.x, + y: fromPosition.y - toPosition.y, + z: fromPosition.z - toPosition.z + }; + + + + fromPosition.x -= diff.x * spacing; + fromPosition.y -= diff.y * spacing; + fromPosition.z -= diff.z * spacing; + toPosition.x += diff.x * spacing; + toPosition.y += diff.y * spacing; + toPosition.z += diff.z * spacing; + + + fromPosition.x += middlePosition.x; + fromPosition.y += middlePosition.y; + fromPosition.z += middlePosition.z; + toPosition.x += middlePosition.x; + toPosition.y += middlePosition.y; + toPosition.z += middlePosition.z; + + + + var fromFlatPosition = this._orthographicProjection(fromPosition); + var toFlatPosition = this._orthographicProjection(toPosition); + + var fromDistanceCenter = this._distance(fromFlatPosition, center); + var toDistanceCenter = this._distance(toFlatPosition, center); + + var fromVisible = true; + var toVisible = true; + if (fromPosition.x > 0) { + if (fromDistanceCenter <= r) { + fromVisible = false; + } + } + + if (toPosition.x > 0) { + if (toDistanceCenter <= r) { + toVisible = false; + } + } + + //console.log(i, fromVisible, toVisible); + + if (!fromVisible && !toVisible) { + continue; + } + + if (!fromVisible) { + var intersection = this._line_circle_intersection(fromFlatPosition, toFlatPosition, center, r); + if (intersection.length == 0) { + continue; + } + fromFlatPosition = intersection[0]; + } + + if (!toVisible) { + var intersection = this._line_circle_intersection(fromFlatPosition, toFlatPosition, center, r); + if (intersection.length == 0) { + continue; + } + toFlatPosition = intersection[0]; + } + + + + this.flightsCtx.lineWidth = 3; + this.flightsCtx.beginPath(); + this.flightsCtx.strokeStyle = 'rgba(255, 255, 255, 0.5)'; + this.flightsCtx.moveTo(fromFlatPosition.x + this.options.flightsCanvasPosition.x, fromFlatPosition.y + this.options.flightsCanvasPosition.y); + this.flightsCtx.lineTo(toFlatPosition.x + this.options.flightsCanvasPosition.x, toFlatPosition.y + this.options.flightsCanvasPosition.y); + this.flightsCtx.stroke(); + + } + + for (var key in path.flights) { + var flight = path.flights[key]; + + var position = flight.destination == path.destination ? flight.position : (1 - flight.position); + var positionAhead = flight.destination == path.destination ? (flight.position + 0.01) : (1 - (flight.position + 0.01)); + + var flightP = { + alpha: (1 - position) * originP.alpha + position * destinationP.alpha, + delta: (1 - position) * originP.delta + position * destinationP.delta + }; + + var flightAheadP = { + alpha: (1 - positionAhead) * originP.alpha + positionAhead * destinationP.alpha, + delta: (1 - positionAhead) * originP.delta + positionAhead * destinationP.delta + }; + + var flightPosition = this._orbitalTo3d(flightP.alpha, flightP.delta, -(Math.sin(Math.PI * position) * (maxDistance - 1) + 1) * radius); + var flightAheadPosition = this._orbitalTo3d(flightAheadP.alpha, flightAheadP.delta, -(Math.sin(Math.PI * positionAhead) * (maxDistance - 1) + 1) * radius); + + flightPosition.x += middlePosition.x; + flightPosition.y += middlePosition.y; + flightPosition.z += middlePosition.z; + flightAheadPosition.x += middlePosition.x; + flightAheadPosition.y += middlePosition.y; + flightAheadPosition.z += middlePosition.z; + + var flightFlatPosition = this._orthographicProjection(flightPosition); + var flightAheadFlatPosition = this._orthographicProjection(flightAheadPosition); + + var flightDistanceCenter = this._distance(flightFlatPosition, center); + + if (!flight.visible && (flightPosition.x < 0 || flightDistanceCenter > r)) { + this.options.onShowFlight(flight, this); + flight.visible = true; + } + + if (flight.visible && (flightPosition.x > 0 && flightDistanceCenter < r)) { + this.options.onHideFlight(flight, this); + flight.visible = false; + } + + var angle = Math.atan2(flightAheadFlatPosition.y - flightFlatPosition.y, flightAheadFlatPosition.x - flightFlatPosition.x); + //console.log(flightAheadFlatPosition.y - flightFlatPosition.y); + + this.options.onRefreshFlight(flight, flightFlatPosition.x, flightFlatPosition.y, angle, this); + } + + }, + + _distance: function(A, B) { + if (A.z) { + return Math.sqrt( + (A.x - B.x) * (A.x - B.x) + + (A.y - B.y) * (A.y - B.y) + + (A.z - B.z) * (A.z - B.z) + ); + } else { + return Math.sqrt( + (A.x - B.x) * (A.x - B.x) + + (A.y - B.y) * (A.y - B.y) + ); + } + }, + + // WARNING: temporary function to make the locations look good on a spinning planet without rotation + _calibrated: function(x, alpha) { + var calib = 0.3 + 0.15 * Math.abs(alpha - Math.PI / 2) / (Math.PI / 4); + //console.log(calib); + var y = calib * (4 * (x - 0.5) * (x - 0.5) * (x - 0.5) + 0.5) + (1 - calib) * x; + return y; + }, + + + /* WARNING: + Obviously there is something wrong with _orbitalTo3d and _orthographicProjection, since + I can't get a descent display of locations when the planet is rotated. That's why I had to create the _calibrated + function in the first place. I didn't have time to look precisely into it, and I probably don't know enough math. + + I leaved the _3dProjection function I found on wikipedia but is not working. (I might not have correctly understood / write it) + */ + _orbitalTo3d: function(alpha, delta, r) { + return { + x: -r * Math.sin(alpha) * Math.cos(delta), + y: -r * Math.sin(alpha) * Math.sin(delta), + z: -r * Math.cos(alpha) + }; + }, + + _orthographicProjection: function(position) { + return {x: position.y + this.element.width() / 2, y: position.z + this.element.height() / 2}; + }, + + _3dProjection: function(a, c, delta, e) { + // Wikipedia is your friend :) : http://en.wikipedia.org/wiki/3D_projection + var d = {x: 0, y: 0, z: 0}; + d.x = Math.cos(delta.y) * (Math.sin(delta.z) * (a.y - c.y) + Math.cos(delta.z) * (a.x - c.x)) - Math.sin(delta.y) * (a.z - c.z); + d.y = Math.sin(delta.x) * (Math.cos(delta.y) * (a.z - c.z) + Math.sin(delta.y) * (Math.sin(delta.z) * (a.y - c.y) + Math.cos(delta.z) * (a.x - c.x))) + + Math.cos(delta.x) * (Math.cos(delta.z) * (a.y - c.y) - Math.sin(delta.z) * (a.x - c.x)) + d.z = Math.cos(delta.x) * (Math.cos(delta.y) * (a.z - c.z) + Math.sin(delta.y) * (Math.sin(delta.z) * (a.y - c.y) + Math.cos(delta.z) * (a.x - c.x))) + - Math.sin(delta.x) * (Math.cos(delta.z) * (a.y - c.y) - Math.sin(delta.z) * (a.x - c.x)); + + return { + x: d.z, //(d.x - e.x) * (e.y / d.y), + y: d.y //(d.z - e.z) * (e.y / d.y) + }; + }, + + _mouseDragStart: function(e) { + this.lastMousePos = e.clientX; + this.lastSpeed = null; + }, + + _mouseDrag: function(e) { + this.lastSpeed = (e.clientX - this.lastMousePos); + this.posVar = this.posVar - this.lastSpeed; + this.lastMousePos = e.clientX; + }, + _mouseDragStop: function(e) { + this.lastMousePos = null; + this.lastTime = null; + }, + + _turnBy: function(time) { + if (this.lastTurnByTime === null) { + this.lastTurnByTime = time; + } + var timeDiff = (time - this.lastTurnByTime) / 1000; + if (this.lastMousePos === null) { + if (this.lastSpeed !== null) { + if (this.lastTime === null) { + this.lastTime = time; + } + if (this.options.backToDefaultTime + this.lastTime - time < 0) { + this.lastSpeed = null; + } else { + var backToDef = (this.options.backToDefaultTime + this.lastTime - time) / this.options.backToDefaultTime; + this.posVar -= this.lastSpeed * backToDef + (this.options.defaultSpeed * timeDiff) * (1 - backToDef); + } + } else { + this.posVar -= this.options.defaultSpeed * timeDiff; + } + } + this.lastTurnByTime = time; + return this.posVar; + }, + + _getQBezierValue: function (t, p1, p2, p3) { + var iT = 1 - t; + return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3; + }, + + _getQBezierDerivation: function(t, p1, p2, p3) { + return (2 * p1 - 4 * p2 + 2 * p3) * t + 2 * p2 - 2 * p1; + }, + + _getQBezierAngle: function(startX, startY, cpX, cpY, endX, endY, position) { + var x = this._getQBezierDerivation(position, startX, cpX, endX); + var y = this._getQBezierDerivation(position, startY, cpY, endY); + return Math.atan2(y, x); + }, + + _getQuadraticCurvePoint: function(startX, startY, cpX, cpY, endX, endY, position) { + return { + x: this._getQBezierValue(position, startX, cpX, endX), + y: this._getQBezierValue(position, startY, cpY, endY), + angle: this._getQBezierAngle(startX, startY, cpX, cpY, endX, endY, position) + }; + }, + + changeLocations: function(locations) { + for (var key in this.options.locations) { + this.options.onDeleteLocation(this.options.locations[key], this); + } + this.options.locations = locations; + this._initLocations(); + }, + + changePaths: function(paths) { + for (var key in this.options.paths) { + var path = this.options.paths[key]; + for (var keyFlight in path.flights) { + var flight = path.flights[keyFlight]; + this.options.onDeleteFlight(flight, this); + } + } + this.options.paths = paths; + this._initFlights(); + } + + }); + +})($); + diff --git a/tools/GetGCAttributesFromG1PUB.sh b/tools/GetGCAttributesFromG1PUB.sh new file mode 100755 index 000000000..b891b22d2 --- /dev/null +++ b/tools/GetGCAttributesFromG1PUB.sh @@ -0,0 +1,105 @@ +#!/bin/bash +################################################################################ +# Author: Fred (support@qo-op.com) +# Version: 0.1 +# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/) +################################################################################ +################################################################################ +MY_PATH="`dirname \"$0\"`" # relative +MY_PATH="`( cd \"${MY_PATH}\" && pwd )`" # absolutized and normalized +. "${MY_PATH}/my.sh" + +QRCODE="$1" +MOATS="$2" +echo "#################################################" +echo "WARNING NOT TESTED. PASS A G1PUBKEY AS PARAMETER." +echo "################################################# +# GIVEN A PUBKEY - +# This program scan for presence in GChange & Cesium Elastic Search Databases +# So it detect attributes attached to actual key $QRCODE +#################################################" + +QRNS=$(${MY_PATH}/g1_to_ipfs.py ${QRCODE}) +[[ ! ${QRNS} ]] && echo "PROVIDED KEY IS NOT CONVERTIBLE." && exit 1 + +[[ ! ${MOATS} ]] && MOATS=$(date -u +"%Y%m%d%H%M%S%4N") +mkdir -p ~/.zen/tmp/${MOATS} + +VISITORCOINS=$(${MY_PATH}/COINScheck.sh ${QRCODE} | tail -n 1) +ZEN=$(echo "($VISITORCOINS - 1) * 10" | bc | cut -d '.' -f 1) + +## EMPTY WALLET ? PREPARE PALPE WELCOME +if [[ $VISITORCOINS == "null" ]]; then + PALPE=1 + echo "PALPE=1" +else + PALPE=0 +fi + +echo "VISITOR POSSESS ${VISITORCOINS} G1 / ${ZEN} ZEN" + +## GET G1 WALLET HISTORY +if [[ ${VISITORCOINS} != "null" && ${VISITORCOINS} -gt 0 ]]; then + + [[ ! -s ~/.zen/tmp/${MOATS}/${QRCODE}.g1history.json ]] \ + && ${MY_PATH}/timeout.sh -t 20 $MY_PATH/jaklis/jaklis.py history -p ${QRCODE} -j > ~/.zen/tmp/${MOATS}/${QRCODE}.g1history.json + + HISTOLNK=$myIPFS/ipfs/$(ipfs add -q ~/.zen/tmp/${MOATS}/${QRCODE}.g1history.json) + + echo "HISTORY" > ~/.zen/tmp/${MOATS}/response + echo "

Solde $VISITORCOINS Ǧ1

" >> ~/.zen/tmp/${MOATS}/response + +fi + +## SCAN GCHANGE + +[[ ! -s ~/.zen/tmp/${MOATS}/${QRCODE}.gchange.json ]] \ +&& ${MY_PATH}/timeout.sh -t 20 curl -s ${myDATA}/user/profile/${QRCODE} > ~/.zen/tmp/${MOATS}/${QRCODE}.gchange.json & + +GFOUND=$(cat ~/.zen/tmp/${MOATS}/${QRCODE}.gchange.json | jq -r '.found') +echo "FOUND IN GCHANGE+ ? $GFOUND" + +if [[ $GFOUND == "false" ]]; then + echo "NO GCHANGE YET. REDIRECT" >> ~/.zen/tmp/${MOATS}/response +else + [[ $VISITORCOINS == "null" ]] && PALPE=10 \ + && echo "~/.zen/tmp/${MOATS}/${QRCODE}.gchange.json CHECK : PALPE=10" +fi + +## SCAN CESIUM + +[[ ! -s ~/.zen/tmp/${MOATS}/${QRCODE}.gplus.json ]] \ +&& ${MY_PATH}/timeout.sh -t 10 curl -s ${myCESIUM}/user/profile/${QRCODE} > ~/.zen/tmp/${MOATS}/${QRCODE}.gplus.json 2>/dev/null & + +GCFOUND=$(cat ~/.zen/tmp/${MOATS}/${QRCODE}.gplus.json | jq -r '.found') +echo "FOUND IN CESIUM+ ? $GCFOUND" + +if [[ $GCFOUND == "false" ]]; then + echo "PAS DE COMPTE CESIUM POUR CETTE CLEF" >> ~/.zen/tmp/${MOATS}/response +else + echo "~/.zen/tmp/${MOATS}/${QRCODE}.gplus.json CHECK : PALPE=50" >> ~/.zen/tmp/${MOATS}/response +fi + +## CHECK IF GCHANGE IS LINKED TO "A DECLARED CESIUM" +CPLUS=$(cat ~/.zen/tmp/${MOATS}/${QRCODE}.gchange.json | jq -r '._source.pubkey' 2>/dev/null) +echo "CPLUS=$CPLUS" >> ~/.zen/tmp/${MOATS}/response +## SCAN GPUB CESIUM + + +##### DO WE HAVE A DIFFERENT KEY LINKED TO GCHANGE ?? +if [[ $CPLUS != "" && $CPLUS != 'null' && $CPLUS != $QRCODE ]]; then + + ## SCAN FOR CPLUS CESIUM + ACCOUNT + [[ ! -s ~/.zen/tmp/${MOATS}/${QRCODE}.cplus.json ]] \ + && ${MY_PATH}/timeout.sh -t 10 curl -s ${myCESIUM}/user/profile/${CPLUS} > ~/.zen/tmp/${MOATS}/${QRCODE}.cplus.json 2>/dev/null & + + CCFOUND=$(cat ~/.zen/tmp/${MOATS}/${QRCODE}.cplus.json | jq -r '.found') + + if [[ $CCFOUND == "false" ]]; then + echo "AUCUN CCPLUS : NO MEMBER LINK" >> ~/.zen/tmp/${MOATS}/response + else + CPLUSCOIN=$(${MY_PATH}/COINScheck.sh ${CPLUS} | tail -n 1) + echo "${QRCODE} IS LINKED TO MEMBER ${CPLUS} POSSESSING ${CPLUSCOIN} G1" >> ~/.zen/tmp/${MOATS}/response + + fi + +fi + +cat ~/.zen/tmp/${MOATS}/response