Comparing version 2.0.0-alpha5 to 2.0.0-alpha6
@@ -152,5 +152,5 @@ 'use strict'; | ||
* | ||
* @param {number} x The X coordinate. | ||
* @param {number} y The Y coordinate. | ||
* @return {object} The point coordinates in the frame of the graph. | ||
* @param {number} x - The X coordinate. | ||
* @param {number} y - The Y coordinate. | ||
* @return {object} The point coordinates in the frame of the graph. | ||
*/ | ||
@@ -174,5 +174,5 @@ | ||
* | ||
* @param {number} x The X coordinate. | ||
* @param {number} y The Y coordinate. | ||
* @return {object} The point coordinates in the frame of the graph. | ||
* @param {number} x - The X coordinate. | ||
* @param {number} y - The Y coordinate. | ||
* @return {object} - The point coordinates in the frame of the graph. | ||
*/ | ||
@@ -202,5 +202,5 @@ | ||
* | ||
* @param {number} x The X coordinate. | ||
* @param {number} y The Y coordinate. | ||
* @return {object} The point coordinates in the frame of the display. | ||
* @param {number} x - The X coordinate. | ||
* @param {number} y - The Y coordinate. | ||
* @return {object} - The point coordinates in the frame of the display. | ||
*/ | ||
@@ -223,2 +223,27 @@ | ||
/** | ||
* Method returning the abstract rectangle containing the graph according | ||
* to the camera's state. | ||
* | ||
* @return {object} - The view's rectangle. | ||
*/ | ||
}, { | ||
key: 'viewRectangle', | ||
value: function viewRectangle() { | ||
var widthVect = this.abstractDisplayToGraph(this.width, 0), | ||
heightVect = this.abstractDisplayToGraph(0, this.height), | ||
centerVect = this.abstractDisplayToGraph(this.width / 2, this.height / 2), | ||
marginX = this.abstractDisplayToGraph(this.width / 4, 0).x, | ||
marginY = this.abstractDisplayToGraph(0, this.height / 4, 0).y; | ||
return { | ||
x1: this.x - centerVect.x - marginX, | ||
y1: this.y - centerVect.y - marginY, | ||
x2: this.x - centerVect.x + marginX + widthVect.x, | ||
y2: this.y - centerVect.y - marginY + widthVect.y, | ||
height: Math.sqrt(Math.pow(heightVect.x, 2) + Math.pow(heightVect.y + 2 * marginY, 2)) | ||
}; | ||
} | ||
/** | ||
* Method used to set the camera's state. | ||
@@ -225,0 +250,0 @@ * |
@@ -6,11 +6,2 @@ 'use strict'; | ||
}); | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /** | ||
* Sigma.js Captor Utils | ||
* ====================== | ||
* | ||
* Miscellenous helper functions related to the captors. | ||
*/ | ||
exports.getX = getX; | ||
@@ -48,2 +39,8 @@ exports.getY = getY; | ||
*/ | ||
/** | ||
* Sigma.js Captor Utils | ||
* ====================== | ||
* | ||
* Miscellenous helper functions related to the captors. | ||
*/ | ||
function getY(e) { | ||
@@ -135,7 +132,7 @@ if (typeof e.offsetY !== 'undefined') return e.offsetY; | ||
function getWheelDelta(e) { | ||
if (_typeof(e.wheelDelta) !== undefined) return e.wheelDelta; | ||
if (typeof e.wheelDelta !== 'undefined') return e.wheelDelta; | ||
if (_typeof(e.detail) !== undefined) return -e.detail; | ||
if (typeof e.detail !== 'undefined') return -e.detail; | ||
throw new Error('sigma/captors/utils.getDelta: could not extract delta from event.'); | ||
} |
{ | ||
"name": "sigma", | ||
"version": "2.0.0-alpha5", | ||
"version": "2.0.0-alpha6", | ||
"description": "A JavaScript library dedicated to graph drawing.", | ||
@@ -76,5 +76,4 @@ "homepage": "http://sigmajs.org", | ||
"events": "^1.1.1", | ||
"gl-matrix": "^2.3.2", | ||
"graphology-utils": "^1.1.1" | ||
} | ||
} |
166
quadtree.js
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -12,2 +12,3 @@ Object.defineProperty(exports, "__esModule", { | ||
/* eslint no-nested-ternary: 0 */ | ||
/* eslint no-constant-condition: 0 */ | ||
/** | ||
@@ -29,5 +30,5 @@ * Sigma.js Quad Tree Class | ||
// TODO: be sure we can handle cases overcoming boundaries (because of size) or use a max | ||
// TODO: be sure we can handle cases overcoming boundaries (because of size) or use a maxed size | ||
// TODO: decide whether to store at leaf level or at medium levels (frustum vs. hover) | ||
// TODO: filtering unwanted labels beforehand through the filter function | ||
@@ -74,6 +75,10 @@ /** | ||
function rectangleCollidesWithQuad(x1, y1, w, qx, qy, qw, qh) { | ||
function squareCollidesWithQuad(x1, y1, w, qx, qy, qw, qh) { | ||
return x1 < qx + qw && x1 + w > qx && y1 < qy + qh && y1 + w > qy; | ||
} | ||
function rectangleCollidesWithQuad(x1, y1, w, h, qx, qy, qw, qh) { | ||
return x1 < qx + qw && x1 + w > qx && y1 < qy + qh && y1 + h > qy; | ||
} | ||
function pointIsInQuad(x, y, qx, qy, qw, qh) { | ||
@@ -147,11 +152,7 @@ var xmp = qx + qw / 2, | ||
// [block, level] | ||
// TODO: does not require a stack if sticking with mid-level containers | ||
var stack = [0, 0]; | ||
var level = 0, | ||
block = 0; | ||
while (stack.length) { | ||
var level = stack.pop(); | ||
while (true) { | ||
var block = stack.pop(); | ||
// If we reached max level | ||
@@ -169,9 +170,9 @@ if (level >= maxLevel) { | ||
var collidingWithTopLeft = rectangleCollidesWithQuad(x1, y1, w, data[topLeftBlock + X_OFFSET], data[topLeftBlock + Y_OFFSET], data[topLeftBlock + WIDTH_OFFSET], data[topLeftBlock + HEIGHT_OFFSET]); | ||
var collidingWithTopLeft = squareCollidesWithQuad(x1, y1, w, data[topLeftBlock + X_OFFSET], data[topLeftBlock + Y_OFFSET], data[topLeftBlock + WIDTH_OFFSET], data[topLeftBlock + HEIGHT_OFFSET]); | ||
var collidingWithTopRight = rectangleCollidesWithQuad(x1, y1, w, data[topRightBlock + X_OFFSET], data[topRightBlock + Y_OFFSET], data[topRightBlock + WIDTH_OFFSET], data[topRightBlock + HEIGHT_OFFSET]); | ||
var collidingWithTopRight = squareCollidesWithQuad(x1, y1, w, data[topRightBlock + X_OFFSET], data[topRightBlock + Y_OFFSET], data[topRightBlock + WIDTH_OFFSET], data[topRightBlock + HEIGHT_OFFSET]); | ||
var collidingWithBottomLeft = rectangleCollidesWithQuad(x1, y1, w, data[bottomLeftBlock + X_OFFSET], data[bottomLeftBlock + Y_OFFSET], data[bottomLeftBlock + WIDTH_OFFSET], data[bottomLeftBlock + HEIGHT_OFFSET]); | ||
var collidingWithBottomLeft = squareCollidesWithQuad(x1, y1, w, data[bottomLeftBlock + X_OFFSET], data[bottomLeftBlock + Y_OFFSET], data[bottomLeftBlock + WIDTH_OFFSET], data[bottomLeftBlock + HEIGHT_OFFSET]); | ||
var collidingWithBottomRight = rectangleCollidesWithQuad(x1, y1, w, data[bottomRightBlock + X_OFFSET], data[bottomRightBlock + Y_OFFSET], data[bottomRightBlock + WIDTH_OFFSET], data[bottomRightBlock + HEIGHT_OFFSET]); | ||
var collidingWithBottomRight = squareCollidesWithQuad(x1, y1, w, data[bottomRightBlock + X_OFFSET], data[bottomRightBlock + Y_OFFSET], data[bottomRightBlock + WIDTH_OFFSET], data[bottomRightBlock + HEIGHT_OFFSET]); | ||
@@ -181,6 +182,6 @@ var collisions = collidingWithTopLeft + collidingWithTopRight + collidingWithBottomLeft + collidingWithBottomRight; | ||
// If we don't have at least a collision, there is an issue | ||
if (collisions === 0) throw new Error("sigma/quadtree.insertNode: no collision (level: " + level + ", key: " + key + ", x: " + x + ", y: " + y + ", size: " + size + ")."); | ||
if (collisions === 0) throw new Error('sigma/quadtree.insertNode: no collision (level: ' + level + ', key: ' + key + ', x: ' + x + ', y: ' + y + ', size: ' + size + ').'); | ||
// If we have 3 collisions, we have a geometry problem obviously | ||
if (collisions === 3) throw new Error("sigma/quadtree.insertNode: 3 impossible collisions (level: " + level + ", key: " + key + ", x: " + x + ", y: " + y + ", size: " + size + ")."); | ||
if (collisions === 3) throw new Error('sigma/quadtree.insertNode: 3 impossible collisions (level: ' + level + ', key: ' + key + ', x: ' + x + ', y: ' + y + ', size: ' + size + ').'); | ||
@@ -190,4 +191,35 @@ // If we have more that one collision, we stop here and store the node | ||
if (collisions > 1) { | ||
// NOTE: this is a nice way to optimize for hover, but not for frustum | ||
// since it requires to uniq the collected nodes | ||
// if (collisions < 4) { | ||
// // If we intersect two quads, we place the node in those two | ||
// if (collidingWithTopLeft) { | ||
// containers[topLeftBlock] = containers[topLeftBlock] || []; | ||
// containers[topLeftBlock].push(key); | ||
// } | ||
// if (collidingWithTopRight) { | ||
// containers[topRightBlock] = containers[topRightBlock] || []; | ||
// containers[topRightBlock].push(key); | ||
// } | ||
// if (collidingWithBottomLeft) { | ||
// containers[bottomLeftBlock] = containers[bottomLeftBlock] || []; | ||
// containers[bottomLeftBlock].push(key); | ||
// } | ||
// if (collidingWithBottomRight) { | ||
// containers[bottomRightBlock] = containers[bottomRightBlock] || []; | ||
// containers[bottomRightBlock].push(key); | ||
// } | ||
// } | ||
// else { | ||
// // Else we keep the node where it is to avoid more pointless computations | ||
// containers[block] = containers[block] || []; | ||
// containers[block].push(key); | ||
// } | ||
containers[block] = containers[block] || []; | ||
containers[block].push(key); | ||
return; | ||
@@ -199,12 +231,58 @@ } else { | ||
// Else we recurse into the correct quads | ||
if (collidingWithTopLeft) stack.push(topLeftBlock, level); | ||
if (collidingWithTopLeft) block = topLeftBlock; | ||
if (collidingWithTopRight) stack.push(topRightBlock, level); | ||
if (collidingWithTopRight) block = topRightBlock; | ||
if (collidingWithBottomLeft) stack.push(bottomLeftBlock, level); | ||
if (collidingWithBottomLeft) block = bottomLeftBlock; | ||
if (collidingWithBottomRight) stack.push(bottomRightBlock, level); | ||
if (collidingWithBottomRight) block = bottomRightBlock; | ||
} | ||
} | ||
function getNodesInAxisAlignedRectangleArea(maxLevel, data, containers, x1, y1, w, h) { | ||
// [block, level] | ||
var stack = [0, 0]; | ||
var collectedNodes = []; | ||
var container = void 0; | ||
while (stack.length) { | ||
var level = stack.pop(), | ||
block = stack.pop(); | ||
// Collecting nodes | ||
container = containers[block]; | ||
if (container) collectedNodes.push.apply(collectedNodes, container); | ||
// If we reached max level | ||
if (level >= maxLevel) continue; | ||
var topLeftBlock = 4 * block + BLOCKS, | ||
topRightBlock = 4 * block + 2 * BLOCKS, | ||
bottomLeftBlock = 4 * block + 3 * BLOCKS, | ||
bottomRightBlock = 4 * block + 4 * BLOCKS; | ||
var collidingWithTopLeft = rectangleCollidesWithQuad(x1, y1, w, h, data[topLeftBlock + X_OFFSET], data[topLeftBlock + Y_OFFSET], data[topLeftBlock + WIDTH_OFFSET], data[topLeftBlock + HEIGHT_OFFSET]); | ||
var collidingWithTopRight = rectangleCollidesWithQuad(x1, y1, w, h, data[topRightBlock + X_OFFSET], data[topRightBlock + Y_OFFSET], data[topRightBlock + WIDTH_OFFSET], data[topRightBlock + HEIGHT_OFFSET]); | ||
var collidingWithBottomLeft = rectangleCollidesWithQuad(x1, y1, w, h, data[bottomLeftBlock + X_OFFSET], data[bottomLeftBlock + Y_OFFSET], data[bottomLeftBlock + WIDTH_OFFSET], data[bottomLeftBlock + HEIGHT_OFFSET]); | ||
var collidingWithBottomRight = rectangleCollidesWithQuad(x1, y1, w, h, data[bottomRightBlock + X_OFFSET], data[bottomRightBlock + Y_OFFSET], data[bottomRightBlock + WIDTH_OFFSET], data[bottomRightBlock + HEIGHT_OFFSET]); | ||
if (collidingWithTopLeft) stack.push(topLeftBlock, level + 1); | ||
if (collidingWithTopRight) stack.push(topRightBlock, level + 1); | ||
if (collidingWithBottomLeft) stack.push(bottomLeftBlock, level + 1); | ||
if (collidingWithBottomRight) stack.push(bottomRightBlock, level + 1); | ||
} | ||
return collectedNodes; | ||
} | ||
/** | ||
@@ -214,9 +292,11 @@ * QuadTree class. | ||
* @constructor | ||
* @param {Graph} graph - A graph instance. | ||
* @param {object} boundaries - The graph boundaries. | ||
*/ | ||
var QuadTree = function () { | ||
function QuadTree(boundaries) { | ||
function QuadTree(params) { | ||
_classCallCheck(this, QuadTree); | ||
params = params || {}; | ||
// Allocating the underlying byte array | ||
@@ -227,8 +307,12 @@ var L = Math.pow(4, MAX_LEVEL); | ||
this.containers = {}; | ||
this.cache = null; | ||
this.lastRectangle = null; | ||
if (boundaries) this.resize(boundaries); | ||
if (params.boundaries) this.resize(params.boundaries); | ||
if (typeof params.filter === 'function') this.nodeFilter = params.filter; | ||
} | ||
_createClass(QuadTree, [{ | ||
key: "add", | ||
key: 'add', | ||
value: function add(key, x, y, size) { | ||
@@ -240,3 +324,3 @@ insertNode(MAX_LEVEL, this.data, this.containers, key, x, y, size); | ||
}, { | ||
key: "resize", | ||
key: 'resize', | ||
value: function resize(boundaries) { | ||
@@ -254,3 +338,3 @@ this.clear(); | ||
}, { | ||
key: "clear", | ||
key: 'clear', | ||
value: function clear() { | ||
@@ -262,3 +346,3 @@ this.containers = {}; | ||
}, { | ||
key: "point", | ||
key: 'point', | ||
value: function point(x, y) { | ||
@@ -281,2 +365,28 @@ var nodes = []; | ||
} | ||
}, { | ||
key: 'rectangle', | ||
value: function rectangle(x1, y1, x2, y2, height) { | ||
var lr = this.lastRectangle; | ||
if (lr && x1 === lr.x1 && x2 === lr.x2 && y1 === lr.y1 && y2 === lr.y2 && height === lr.height) { | ||
return this.cache; | ||
} | ||
this.lastRectangle = { | ||
x1: x1, | ||
y1: y1, | ||
x2: x2, | ||
y2: y2, | ||
height: height | ||
}; | ||
// Is the rectangle axis aligned? | ||
if (!isAxisAligned(x1, y1, x2, y2)) throw new Error('sigma/quadtree.rectangle: shifted view is not yet implemented.'); | ||
var collectedNodes = getNodesInAxisAlignedRectangleArea(MAX_LEVEL, this.data, this.containers, x1, y1, Math.abs(x1 - x2) || Math.abs(y1 - y2), height); | ||
this.cache = collectedNodes; | ||
return this.cache; | ||
} | ||
}]); | ||
@@ -283,0 +393,0 @@ |
@@ -9,4 +9,2 @@ 'use strict'; | ||
var _glMatrix = require('gl-matrix'); | ||
var _renderer = require('../../renderer'); | ||
@@ -28,3 +26,3 @@ | ||
var _node = require('./programs/node'); | ||
var _node = require('./programs/node.fast'); | ||
@@ -72,2 +70,9 @@ var _node2 = _interopRequireDefault(_node); | ||
/** | ||
* Defaults. | ||
*/ | ||
var DEFAULT_SETTINGS = { | ||
hideEdgesOnMove: false | ||
}; | ||
/** | ||
* Main class. | ||
@@ -82,8 +87,12 @@ * | ||
function WebGLRenderer(container) { | ||
function WebGLRenderer(container, settings) { | ||
_classCallCheck(this, WebGLRenderer); | ||
// Validating | ||
var _this = _possibleConstructorReturn(this, (WebGLRenderer.__proto__ || Object.getPrototypeOf(WebGLRenderer)).call(this)); | ||
settings = settings || {}; | ||
_this.settings = (0, _utils.assign)({}, DEFAULT_SETTINGS, settings); | ||
// Validating | ||
if (!(container instanceof HTMLElement)) throw new Error('sigma/renderers/webgl: container should be an html element.'); | ||
@@ -475,3 +484,3 @@ | ||
// TODO: Optimize this to be save a loop and one object | ||
// TODO: Optimize this to be save a loop and one object, by using a reversed assign | ||
var displayData = (0, _utils.assign)({}, data, rescaledData); | ||
@@ -486,2 +495,4 @@ | ||
nodeProgram.bufferData(this.contexts.nodes, this.nodeArray); | ||
var edgeProgram = this.edgePrograms.def; | ||
@@ -513,2 +524,4 @@ | ||
edgeProgram.bufferData(this.contexts.edges, this.edgeArray, this.edgeIndicesArray); | ||
return this; | ||
@@ -724,8 +737,4 @@ } | ||
var cameraState = this.camera.getState(), | ||
cameraMatrix = (0, _utils3.matrixFromCamera)(cameraState); | ||
cameraMatrix = (0, _utils3.matrixFromCamera)(cameraState, { width: this.width, height: this.height }); | ||
var translation = _glMatrix.mat3.fromTranslation(_glMatrix.mat3.create(), [this.width / 2, this.height / 2]); | ||
_glMatrix.mat3.multiply(cameraMatrix, translation, cameraMatrix); | ||
var program = void 0, | ||
@@ -749,24 +758,40 @@ gl = void 0; | ||
// Drawing edges | ||
gl = this.contexts.edges; | ||
program = this.edgePrograms.def; | ||
if (!this.settings.hideEdgesOnMove || !this.camera.isAnimated()) { | ||
gl = this.contexts.edges; | ||
program = this.edgePrograms.def; | ||
program.render(gl, this.edgeArray, { | ||
matrix: cameraMatrix, | ||
width: this.width, | ||
height: this.height, | ||
ratio: cameraState.ratio, | ||
edgesPowRatio: 0.5, | ||
scalingRatio: WEBGL_OVERSAMPLING_RATIO, | ||
indices: this.edgeIndicesArray | ||
}); | ||
program.render(gl, this.edgeArray, { | ||
matrix: cameraMatrix, | ||
width: this.width, | ||
height: this.height, | ||
ratio: cameraState.ratio, | ||
edgesPowRatio: 0.5, | ||
scalingRatio: WEBGL_OVERSAMPLING_RATIO, | ||
indices: this.edgeIndicesArray | ||
}); | ||
} | ||
// Finding visible nodes to display their labels | ||
var visibleNodes = void 0; | ||
if (cameraState.ratio >= 1) { | ||
// Camera is unzoomed so no need to ask the quadtree for visible nodes | ||
visibleNodes = this.sigma.getGraph().nodes(); | ||
} else { | ||
// Let's ask the quadtree | ||
var viewRectangle = this.camera.viewRectangle(); | ||
visibleNodes = this.quadtree.rectangle(viewRectangle.x1, viewRectangle.y1, viewRectangle.x2, viewRectangle.y2, viewRectangle.height); | ||
} | ||
// Drawing labels | ||
// TODO: POW RATIO is currently default 0.5 and harcoded | ||
var nodes = this.sigma.getGraph().nodes(), | ||
context = this.contexts.labels; | ||
var context = this.contexts.labels; | ||
var sizeRatio = Math.pow(cameraState.ratio, 0.5); | ||
for (var i = 0, l = nodes.length; i < l; i++) { | ||
var data = this.nodeDataCache[nodes[i]]; | ||
for (var i = 0, l = visibleNodes.length; i < l; i++) { | ||
var data = this.nodeDataCache[visibleNodes[i]]; | ||
@@ -854,25 +879,2 @@ var _camera$graphToDispla = this.camera.graphToDisplay(data.x, data.y), | ||
// If we did not render in this frame yet | ||
// if (!this.wasRenderedInThisFrame) { | ||
// // Do we need to process data? | ||
// if (this.needToProcess || this.needToSoftProcess) | ||
// this.process(this.needToSoftProcess); | ||
// // Resetting state | ||
// this.renderFrame = null; | ||
// this.needToProcess = false; | ||
// this.needToSoftProcess = false; | ||
// this.render(); | ||
// this.wasRenderedInThisFrame = true; | ||
// requestAnimationFrame(() => { | ||
// this.wasRenderedInThisFrame = false; | ||
// }); | ||
// return this; | ||
// } | ||
// A frame is already scheduled | ||
@@ -879,0 +881,0 @@ if (this.renderFrame) return this; |
@@ -41,9 +41,25 @@ 'use strict'; | ||
function EdgeFastProgram() { | ||
function EdgeFastProgram(gl) { | ||
_classCallCheck(this, EdgeFastProgram); | ||
var _this = _possibleConstructorReturn(this, (EdgeFastProgram.__proto__ || Object.getPrototypeOf(EdgeFastProgram)).call(this)); | ||
// Initializing buffers | ||
var _this = _possibleConstructorReturn(this, (EdgeFastProgram.__proto__ || Object.getPrototypeOf(EdgeFastProgram)).call(this, gl, _edgeFastVert2.default, _edgeFastFrag2.default)); | ||
_this.vertexShaderSource = _edgeFastVert2.default; | ||
_this.fragmentShaderSource = _edgeFastFrag2.default; | ||
_this.buffer = gl.createBuffer(); | ||
gl.bindBuffer(gl.ARRAY_BUFFER, _this.buffer); | ||
var program = _this.program; | ||
// Locations | ||
_this.colorLocation = gl.getAttribLocation(program, 'a_color'); | ||
_this.positionLocation = gl.getAttribLocation(program, 'a_position'); | ||
_this.resolutionLocation = gl.getUniformLocation(program, 'u_resolution'); | ||
_this.matrixLocation = gl.getUniformLocation(program, 'u_matrix'); | ||
// Bindings | ||
gl.enableVertexAttribArray(_this.positionLocation); | ||
gl.enableVertexAttribArray(_this.colorLocation); | ||
gl.vertexAttribPointer(_this.positionLocation, 2, gl.FLOAT, false, EdgeFastProgram.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 0); | ||
gl.vertexAttribPointer(_this.colorLocation, 1, gl.FLOAT, false, EdgeFastProgram.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 8); | ||
return _this; | ||
@@ -78,2 +94,7 @@ } | ||
}, { | ||
key: 'bufferData', | ||
value: function bufferData(gl, array) { | ||
gl.bufferData(gl.ARRAY_BUFFER, array, gl.DYNAMIC_DRAW); | ||
} | ||
}, { | ||
key: 'render', | ||
@@ -84,21 +105,5 @@ value: function render(gl, array, params) { | ||
// Attribute locations | ||
var colorLocation = gl.getAttribLocation(program, 'a_color'), | ||
positionLocation = gl.getAttribLocation(program, 'a_position'), | ||
resolutionLocation = gl.getUniformLocation(program, 'u_resolution'), | ||
matrixLocation = gl.getUniformLocation(program, 'u_matrix'); | ||
gl.uniform2f(this.resolutionLocation, params.width, params.height); | ||
gl.uniformMatrix3fv(this.matrixLocation, false, params.matrix); | ||
var buffer = gl.createBuffer(); | ||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | ||
gl.bufferData(gl.ARRAY_BUFFER, array, gl.DYNAMIC_DRAW); | ||
gl.uniform2f(resolutionLocation, params.width, params.height); | ||
gl.uniformMatrix3fv(matrixLocation, false, params.matrix); | ||
gl.enableVertexAttribArray(positionLocation); | ||
gl.enableVertexAttribArray(colorLocation); | ||
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, EdgeFastProgram.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 0); | ||
gl.vertexAttribPointer(colorLocation, 1, gl.FLOAT, false, EdgeFastProgram.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 8); | ||
// TODO: use gl line thickness | ||
@@ -105,0 +110,0 @@ gl.lineWidth(3); |
@@ -81,2 +81,12 @@ 'use strict'; | ||
gl.vertexAttribPointer(_this.colorLocation, 1, gl.FLOAT, false, EdgeProgram.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 20); | ||
// Enabling the OES_element_index_uint extension | ||
// NOTE: on older GPUs, this means that really large graphs won't | ||
// have all their edges rendered. But it seems that the | ||
// `OES_element_index_uint` is quite everywhere so we'll handle | ||
// the potential issue if it really arises. | ||
var extension = gl.getExtension('OES_element_index_uint'); | ||
_this.canUse32BitsIndices = !!extension; | ||
_this.IndicesArray = _this.canUse32BitsIndices ? Uint32Array : Uint16Array; | ||
_this.indicesType = _this.canUse32BitsIndices ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT; | ||
return _this; | ||
@@ -156,3 +166,3 @@ } | ||
var indices = new Uint16Array(size); | ||
var indices = new this.IndicesArray(size); | ||
@@ -171,2 +181,12 @@ for (var i = 0, c = 0; i < size; i += 4) { | ||
}, { | ||
key: 'bufferData', | ||
value: function bufferData(gl, array, indicesArray) { | ||
// Vertices data | ||
gl.bufferData(gl.ARRAY_BUFFER, array, gl.DYNAMIC_DRAW); | ||
// Indices data | ||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicesArray, gl.STATIC_DRAW); | ||
} | ||
}, { | ||
key: 'render', | ||
@@ -177,5 +197,2 @@ value: function render(gl, array, params) { | ||
// Buffer data | ||
gl.bufferData(gl.ARRAY_BUFFER, array, gl.DYNAMIC_DRAW); | ||
// Binding uniforms | ||
@@ -187,7 +204,4 @@ gl.uniform2f(this.resolutionLocation, params.width, params.height); | ||
// Buffering indices data | ||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, params.indices, gl.STATIC_DRAW); | ||
// Drawing: | ||
gl.drawElements(gl.TRIANGLES, params.indices.length, gl.UNSIGNED_SHORT, 0); | ||
gl.drawElements(gl.TRIANGLES, params.indices.length, this.indicesType, 0); | ||
} | ||
@@ -194,0 +208,0 @@ }]); |
@@ -42,9 +42,30 @@ 'use strict'; | ||
function NodeProgramFast() { | ||
function NodeProgramFast(gl) { | ||
_classCallCheck(this, NodeProgramFast); | ||
var _this = _possibleConstructorReturn(this, (NodeProgramFast.__proto__ || Object.getPrototypeOf(NodeProgramFast)).call(this)); | ||
// Initializing buffers | ||
var _this = _possibleConstructorReturn(this, (NodeProgramFast.__proto__ || Object.getPrototypeOf(NodeProgramFast)).call(this, gl, _nodeFastVert2.default, _nodeFastFrag2.default)); | ||
_this.vertexShaderSource = _nodeFastVert2.default; | ||
_this.fragmentShaderSource = _nodeFastFrag2.default; | ||
_this.buffer = gl.createBuffer(); | ||
gl.bindBuffer(gl.ARRAY_BUFFER, _this.buffer); | ||
var program = _this.program; | ||
// Locations | ||
_this.positionLocation = gl.getAttribLocation(program, 'a_position'); | ||
_this.sizeLocation = gl.getAttribLocation(program, 'a_size'); | ||
_this.colorLocation = gl.getAttribLocation(program, 'a_color'); | ||
_this.resolutionLocation = gl.getUniformLocation(program, 'u_resolution'); | ||
_this.matrixLocation = gl.getUniformLocation(program, 'u_matrix'); | ||
_this.ratioLocation = gl.getUniformLocation(program, 'u_ratio'); | ||
_this.scaleLocation = gl.getUniformLocation(program, 'u_scale'); | ||
// Bindings | ||
gl.enableVertexAttribArray(_this.positionLocation); | ||
gl.enableVertexAttribArray(_this.sizeLocation); | ||
gl.enableVertexAttribArray(_this.colorLocation); | ||
gl.vertexAttribPointer(_this.positionLocation, 2, gl.FLOAT, false, NodeProgramFast.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 0); | ||
gl.vertexAttribPointer(_this.sizeLocation, 1, gl.FLOAT, false, NodeProgramFast.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 8); | ||
gl.vertexAttribPointer(_this.colorLocation, 1, gl.FLOAT, false, NodeProgramFast.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 12); | ||
return _this; | ||
@@ -64,2 +85,7 @@ } | ||
}, { | ||
key: 'bufferData', | ||
value: function bufferData(gl, array) { | ||
gl.bufferData(gl.ARRAY_BUFFER, array, gl.DYNAMIC_DRAW); | ||
} | ||
}, { | ||
key: 'render', | ||
@@ -70,28 +96,7 @@ value: function render(gl, array, params) { | ||
// Attribute locations | ||
var positionLocation = gl.getAttribLocation(program, 'a_position'), | ||
sizeLocation = gl.getAttribLocation(program, 'a_size'), | ||
colorLocation = gl.getAttribLocation(program, 'a_color'), | ||
resolutionLocation = gl.getUniformLocation(program, 'u_resolution'), | ||
matrixLocation = gl.getUniformLocation(program, 'u_matrix'), | ||
ratioLocation = gl.getUniformLocation(program, 'u_ratio'), | ||
scaleLocation = gl.getUniformLocation(program, 'u_scale'); | ||
gl.uniform2f(this.resolutionLocation, params.width, params.height); | ||
gl.uniform1f(this.ratioLocation, 1 / Math.pow(params.ratio, params.nodesPowRatio)); | ||
gl.uniform1f(this.scaleLocation, params.scalingRatio); | ||
gl.uniformMatrix3fv(this.matrixLocation, false, params.matrix); | ||
var buffer = gl.createBuffer(); | ||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | ||
gl.bufferData(gl.ARRAY_BUFFER, array, gl.DYNAMIC_DRAW); | ||
gl.uniform2f(resolutionLocation, params.width, params.height); | ||
gl.uniform1f(ratioLocation, 1 / Math.pow(params.ratio, params.nodesPowRatio)); | ||
gl.uniform1f(scaleLocation, params.scalingRatio); | ||
gl.uniformMatrix3fv(matrixLocation, false, params.matrix); | ||
gl.enableVertexAttribArray(positionLocation); | ||
gl.enableVertexAttribArray(sizeLocation); | ||
gl.enableVertexAttribArray(colorLocation); | ||
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, NodeProgramFast.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 0); | ||
gl.vertexAttribPointer(sizeLocation, 1, gl.FLOAT, false, NodeProgramFast.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 8); | ||
gl.vertexAttribPointer(colorLocation, 1, gl.FLOAT, false, NodeProgramFast.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 12); | ||
gl.drawArrays(gl.POINTS, 0, array.length / NodeProgramFast.ATTRIBUTES); | ||
@@ -98,0 +103,0 @@ } |
@@ -10,3 +10,3 @@ 'use strict'; | ||
var _glMatrix = require('gl-matrix'); | ||
var _matrices = require('./matrices'); | ||
@@ -24,5 +24,3 @@ /** | ||
// TODO: this is heavy for what we do with it | ||
var RGBA_TEST_REGEX = /^\s*rgba?\s*\(/; | ||
@@ -74,3 +72,3 @@ var RGBA_EXTRACT_REGEX = /^\s*rgba?\s*\(\s*([0-9]*)\s*,\s*([0-9]*)\s*,\s*([0-9]*)\s*(,.*)?\)\s*$/; | ||
// TODO: it's possible to optimize this drastically! | ||
function matrixFromCamera(state) { | ||
function matrixFromCamera(state, dimensions) { | ||
var angle = state.angle, | ||
@@ -80,12 +78,18 @@ ratio = state.ratio, | ||
y = state.y; | ||
var width = dimensions.width, | ||
height = dimensions.height; | ||
var matrix = _glMatrix.mat3.create(), | ||
scale = _glMatrix.mat3.fromScaling(_glMatrix.mat3.create(), [1 / ratio, 1 / ratio]), | ||
rotation = _glMatrix.mat3.fromRotation(_glMatrix.mat3.create(), -angle), | ||
translation = _glMatrix.mat3.fromTranslation(_glMatrix.mat3.create(), [-x, -y]); | ||
var matrix = (0, _matrices.identity)(); | ||
_glMatrix.mat3.multiply(matrix, scale, rotation); | ||
_glMatrix.mat3.multiply(matrix, matrix, translation); | ||
var scaling = (0, _matrices.scale)((0, _matrices.identity)(), 1 / ratio), | ||
rotation = (0, _matrices.rotate)((0, _matrices.identity)(), -angle), | ||
translation = (0, _matrices.translate)((0, _matrices.identity)(), -x, -y), | ||
dimensionTranslation = (0, _matrices.translate)((0, _matrices.identity)(), width / 2, height / 2); | ||
(0, _matrices.multiply)(matrix, scaling); | ||
(0, _matrices.multiply)(matrix, rotation); | ||
(0, _matrices.multiply)(matrix, translation); | ||
matrix = (0, _matrices.multiply)(dimensionTranslation, matrix); | ||
return matrix; | ||
@@ -92,0 +96,0 @@ } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2
39
389771
6055
- Removedgl-matrix@^2.3.2
- Removedgl-matrix@2.8.1(transitive)