'use strict' module.exports = createErrorBars var createBuffer = require('gl-buffer') var createVAO = require('gl-vao') var createShader = require('./shaders/index') var IDENTITY = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1] function ErrorBars(gl, buffer, vao, shader) { this.gl = gl this.shader = shader this.buffer = buffer this.vao = vao this.pixelRatio = 1 this.bounds = [[ Infinity, Infinity, Infinity], [-Infinity,-Infinity,-Infinity]] this.clipBounds = [[-Infinity,-Infinity,-Infinity], [ Infinity, Infinity, Infinity]] this.lineWidth = [1,1,1] this.capSize = [10,10,10] this.lineCount = [0,0,0] this.lineOffset = [0,0,0] this.opacity = 1 this.hasAlpha = false } var proto = ErrorBars.prototype proto.isOpaque = function() { return !this.hasAlpha } proto.isTransparent = function() { return this.hasAlpha } proto.drawTransparent = proto.draw = function(cameraParams) { var gl = this.gl var uniforms = this.shader.uniforms this.shader.bind() var view = uniforms.view = cameraParams.view || IDENTITY var projection = uniforms.projection = cameraParams.projection || IDENTITY uniforms.model = cameraParams.model || IDENTITY uniforms.clipBounds = this.clipBounds uniforms.opacity = this.opacity var cx = view[12] var cy = view[13] var cz = view[14] var cw = view[15] var isOrtho = cameraParams._ortho || false var orthoFix = (isOrtho) ? 2 : 1 // double up padding for orthographic ticks & labels var pixelScaleF = orthoFix * this.pixelRatio * (projection[3]*cx + projection[7]*cy + projection[11]*cz + projection[15]*cw) / gl.drawingBufferHeight this.vao.bind() for(var i=0; i<3; ++i) { gl.lineWidth(this.lineWidth[i] * this.pixelRatio) uniforms.capSize = this.capSize[i] * pixelScaleF if (this.lineCount[i]) { gl.drawArrays(gl.LINES, this.lineOffset[i], this.lineCount[i]) } } this.vao.unbind() } function updateBounds(bounds, point) { for(var i=0; i<3; ++i) { bounds[0][i] = Math.min(bounds[0][i], point[i]) bounds[1][i] = Math.max(bounds[1][i], point[i]) } } var FACE_TABLE = (function(){ var table = new Array(3) for(var d=0; d<3; ++d) { var row = [] for(var j=1; j<=2; ++j) { for(var s=-1; s<=1; s+=2) { var u = (j+d) % 3 var y = [0,0,0] y[u] = s row.push(y) } } table[d] = row } return table })() function emitFace(verts, x, c, d) { var offsets = FACE_TABLE[d] for(var i=0; i 0) { var x = p.slice() x[j] += e[1][j] verts.push(p[0], p[1], p[2], c[0], c[1], c[2], c[3], 0, 0, 0, x[0], x[1], x[2], c[0], c[1], c[2], c[3], 0, 0, 0) updateBounds(this.bounds, x) vertexCount += 2 + emitFace(verts, x, c, j) } } this.lineCount[j] = vertexCount - this.lineOffset[j] } this.buffer.update(verts) } } proto.dispose = function() { this.shader.dispose() this.buffer.dispose() this.vao.dispose() } function createErrorBars(options) { var gl = options.gl var buffer = createBuffer(gl) var vao = createVAO(gl, [ { buffer: buffer, type: gl.FLOAT, size: 3, offset: 0, stride: 40 }, { buffer: buffer, type: gl.FLOAT, size: 4, offset: 12, stride: 40 }, { buffer: buffer, type: gl.FLOAT, size: 3, offset: 28, stride: 40 } ]) var shader = createShader(gl) shader.attributes.position.location = 0 shader.attributes.color.location = 1 shader.attributes.offset.location = 2 var result = new ErrorBars(gl, buffer, vao, shader) result.update(options) return result }