gl-geometry
Advanced tools
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
+160
| var createCamera = require('canvas-orbit-camera') | ||
| var mat4 = require('gl-matrix').mat4 | ||
| var pack = require('array-pack-2d') | ||
| var unindex = require('unindex-mesh') | ||
| var faceNormals = require('face-normals') | ||
| var createContext = require('gl-context') | ||
| var ndarray = require('ndarray') | ||
| var normals = require('normals') | ||
| var glslify = require('glslify') | ||
| var bunny = require('bunny') | ||
| var createShader = require('gl-shader') | ||
| var parseOBJ = require('parse-wavefront-obj') | ||
| var fs = require('fs') | ||
| var createGeom = require('../') | ||
| var clear = require('gl-clear')({ | ||
| color: [0xF0 / 255, 0xF1 / 255, 0xF2 / 255, 1], | ||
| depth: true, | ||
| stencil: false | ||
| }) | ||
| // handles simplicial complexes with cells/positions properties | ||
| var scPos = bunny | ||
| var scNor = normals.vertexNormals(bunny.cells, bunny.positions) | ||
| createExample(scPos, scNor).title = 'Simplicial Complex' | ||
| // handles Float32Arrays | ||
| var uiPos = unindex(bunny.positions, bunny.cells) | ||
| var uiNor = faceNormals(uiPos) | ||
| createExample(uiPos, uiNor).title = 'Unindexed Mesh, Float32Arrays' | ||
| // handles (flat) ndarrays | ||
| var ndPos = ndarray(uiPos, [uiPos.length]) | ||
| var ndNor = ndarray(uiNor, [uiNor.length]) | ||
| createExample(ndPos, ndNor).title = 'Flat ndarrays' | ||
| // also supports .faces() method | ||
| createExample(scPos.positions, scNor, scPos.cells).title = '.faces(), Last Call' | ||
| // also supports .faces() method with packed data | ||
| createExample(pack(scPos.positions), scNor, pack(scPos.cells)).title = '.faces(), Packed Data' | ||
| // .faces(), order-independant | ||
| createExample(scPos.positions, scNor, scPos.cells, {facesFirst: true}).title = '.faces(), First Call' | ||
| createAttributeUpdateExample().title = 'Attribute Update' | ||
| function createExample (pos, norm, cells, options) { | ||
| options = options || { } | ||
| var canvas = document.body.appendChild(document.createElement('canvas')) | ||
| var gl = createContext(canvas, render) | ||
| var camera = createCamera(canvas) | ||
| if (options.zoom) camera.distance /= options.zoom | ||
| var projection = mat4.create() | ||
| var shader = createShader(gl, | ||
| glslify('./test.vert'), | ||
| glslify('./test.frag') | ||
| ) | ||
| canvas.width = 300 | ||
| canvas.height = 300 | ||
| canvas.style.margin = '1em' | ||
| var geom = createGeom(gl) | ||
| if (cells && options.facesFirst) geom.faces(cells) | ||
| geom | ||
| .attr('position', pos) | ||
| .attr('normal', norm) | ||
| if (cells && !options.facesFirst) geom.faces(cells) | ||
| function render () { | ||
| if (options.update) { | ||
| options.update(geom) | ||
| } | ||
| var width = canvas.width | ||
| var height = canvas.height | ||
| gl.bindFramebuffer(gl.FRAMEBUFFER, null) | ||
| if (!options.noculling) gl.enable(gl.CULL_FACE) | ||
| gl.enable(gl.DEPTH_TEST) | ||
| gl.viewport(0, 0, width, height) | ||
| clear(gl) | ||
| geom.bind(shader) | ||
| shader.attributes.position.location = 0 | ||
| shader.uniforms.uView = camera.view() | ||
| shader.uniforms.uProjection = mat4.perspective(projection | ||
| , Math.PI / 4 | ||
| , width / height | ||
| , 0.001 | ||
| , 10000 | ||
| ) | ||
| geom.draw() | ||
| geom.unbind() | ||
| camera.tick() | ||
| } | ||
| return canvas | ||
| } | ||
| function createAttributeUpdateExample () { | ||
| var anim = parsePC2(fs.readFileSync(__dirname + '/basicCloth.pc2')) | ||
| var obj = parseOBJ(fs.readFileSync(__dirname + '/basicCloth.obj')) | ||
| var norms = normals.vertexNormals(obj.cells, obj.positions) | ||
| var startDate = Date.now() | ||
| var currentFrame = 0 | ||
| function update (geom) { | ||
| // Pick appropriate frame (24fps) | ||
| var delta_ms = Date.now() - startDate | ||
| var newFrame = Math.floor(24 * delta_ms / 1000) % anim.frames.length | ||
| // Update geometry on frame change | ||
| if (newFrame !== currentFrame) { | ||
| currentFrame = newFrame | ||
| var framePosition = anim.frames[currentFrame] | ||
| geom.attr('position', framePosition) | ||
| geom.attr('normal', normals.vertexNormals(obj.cells, framePosition)) | ||
| } | ||
| } | ||
| return createExample(obj, norms, null, {noculling: true, update: update, zoom: 4}) | ||
| } | ||
| // Basic parser implemented using informations from | ||
| // http://mattebb.com/projects/bpython/pointcache/export_pc2.py | ||
| function parsePC2 (buf) { | ||
| var pc2 = {} | ||
| // Read header | ||
| pc2.numPoints = buf.readUInt32LE(16) // Number of points per sample | ||
| pc2.startFrame = buf.readFloatLE(20) // First sampled frame | ||
| pc2.sampleRate = buf.readFloatLE(24) // How frequently to sample (or skip) the frames | ||
| pc2.numSamples = buf.readUInt32LE(28) // How many samples are stored in this file | ||
| // Read data | ||
| var off = 32 | ||
| pc2.frames = [] | ||
| for (var f = pc2.startFrame; f < pc2.startFrame + pc2.numSamples; f += pc2.sampleRate) { | ||
| var frame = [] | ||
| for (var i = 0; i < pc2.numPoints; i++) { | ||
| var point = [] | ||
| for (var j = 0; j < 3; j++) { | ||
| point.push(buf.readFloatLE(off)) | ||
| off += 4 | ||
| } | ||
| frame.push(point) | ||
| } | ||
| pc2.frames.push(frame) | ||
| } | ||
| return pc2 | ||
| } |
Sorry, the diff of this file is not supported yet
+14
-9
@@ -57,3 +57,3 @@ var normalize = require('./normalize') | ||
| this._index = normalize(this.gl | ||
| this._index = normalize.create(this.gl | ||
| , attr | ||
@@ -78,2 +78,14 @@ , size | ||
| opts = opts || {} | ||
| var size = opts.size || 3 | ||
| // Is this a known attribute (ie, an update)? | ||
| var keyIndex = this._keys.indexOf(name) | ||
| if (keyIndex > -1) { | ||
| var toUpdate = this._attributes[keyIndex].buffer | ||
| var offset = opts.offset || undefined | ||
| normalize.update(toUpdate, attr, size, 'float32', offset) | ||
| this._attrLength = toUpdate.length / size / 4 | ||
| return this | ||
| } | ||
| this._dirty = true | ||
@@ -83,5 +95,4 @@ | ||
| var first = !this._attributes.length | ||
| var size = opts.size || 3 | ||
| var attribute = normalize(gl, attr, size, gl.ARRAY_BUFFER, 'float32') | ||
| var attribute = normalize.create(gl, attr, size, gl.ARRAY_BUFFER, 'float32') | ||
| if (!attribute) { | ||
@@ -105,8 +116,2 @@ throw new Error( | ||
| this._attrLength = length | ||
| } else | ||
| if (this._attrLength !== length) { | ||
| throw new Error( | ||
| 'Unexpected discrepancy in attributes size (was ' + this._attrLength + | ||
| ', now ' + length + ')' | ||
| ) | ||
| } | ||
@@ -113,0 +118,0 @@ |
+34
-15
@@ -7,9 +7,36 @@ var pack = require('array-pack-2d') | ||
| module.exports = normalize | ||
| module.exports.create = create | ||
| module.exports.update = update | ||
| function normalize (gl, attr, size, mode, type) { | ||
| function create (gl, attr, size, mode, type) { | ||
| // if we get a gl-buffer | ||
| if (attr.handle instanceof WebGLBuffer) { | ||
| return { | ||
| buffer: attr, | ||
| length: attr.length / size / 4 | ||
| } | ||
| } | ||
| var arr = normalize(attr, size, type) | ||
| return { | ||
| buffer: createBuffer(gl, arr.data, mode), | ||
| length: arr.length | ||
| } | ||
| } | ||
| function update (buffer, attr, size, type, offset) { | ||
| // if we get a gl-buffer | ||
| if (attr.handle instanceof WebGLBuffer) { | ||
| throw new Error('Unhandled update case: WebGLBuffer') | ||
| } | ||
| var arr = normalize(attr, size, type) | ||
| buffer.update(arr.data, offset) | ||
| } | ||
| function normalize (attr, size, type) { | ||
| // if we get a nested 2D array | ||
| if (Array.isArray(attr) && Array.isArray(attr[0])) { | ||
| return { | ||
| buffer: createBuffer(gl, pack(attr, type), mode), | ||
| data: pack(attr, type), | ||
| length: attr.length | ||
@@ -22,3 +49,3 @@ } | ||
| return { | ||
| buffer: createBuffer(gl, pack(attr, type), mode), | ||
| data: pack(attr, type), | ||
| length: (attr.length * attr[0].length) / size | ||
@@ -31,3 +58,3 @@ } | ||
| return { | ||
| buffer: createBuffer(gl, new (dtype(type))(attr), mode), | ||
| data: new (dtype(type))(attr), | ||
| length: attr.length / size | ||
@@ -37,14 +64,6 @@ } | ||
| // if we get a gl-buffer | ||
| if (attr.handle instanceof WebGLBuffer) { | ||
| return { | ||
| buffer: attr, | ||
| length: attr.length / size / 4 | ||
| } | ||
| } | ||
| // if we get an ndarray | ||
| if (isnd(attr)) { | ||
| return { | ||
| buffer: createBuffer(gl, attr, mode), | ||
| data: attr, | ||
| length: ndlength(attr.shape) / size | ||
@@ -61,3 +80,3 @@ } | ||
| return { | ||
| buffer: createBuffer(gl, attr, mode), | ||
| data: attr, | ||
| length: attr.length / size | ||
@@ -64,0 +83,0 @@ } |
+5
-3
| { | ||
| "name": "gl-geometry", | ||
| "version": "3.0.1", | ||
| "version": "3.1.0", | ||
| "description": "A flexible wrapper for gl-vao and gl-buffer that you can use to set up renderable WebGL geometries from a variety of different formats.", | ||
| "main": "index.js", | ||
| "scripts": { | ||
| "start": "budo test.js --open -- -t glslify", | ||
| "start": "budo test/test.js --open -- -t glslify -t brfs", | ||
| "test": "standard" | ||
@@ -40,3 +40,5 @@ }, | ||
| "standard": "^5.4.1", | ||
| "unindex-mesh": "0.0.0" | ||
| "unindex-mesh": "0.0.0", | ||
| "parse-wavefront-obj": "^1.0.1", | ||
| "brfs": "^1.4.3" | ||
| }, | ||
@@ -43,0 +45,0 @@ "repository": { |
+11
-2
@@ -17,3 +17,3 @@ # gl-geometry [](http://github.com/badges/stability-badges) | ||
| Define a new attribute value, for example using a simplicial complex: | ||
| Define or update an attribute value, for example using a simplicial complex: | ||
@@ -59,5 +59,14 @@ ``` javascript | ||
| ``` | ||
| You can specify `opt.size` for the vertex size, defaults to 3. | ||
| You can update attribute values by calling `attr` again with the same `name`: | ||
| * By default the entire contents of the associated `gl-buffer` are replaced by | ||
| `data`; the buffer will be resized accordingly. | ||
| * Alternatively, you can pass `opt.offset` to copy `data` into the current | ||
| buffer at a specific offset (in bytes). In this case, the buffer cannot be | ||
| resized. | ||
| ### geom.faces(values[, opt]) ### | ||
@@ -64,0 +73,0 @@ |
Sorry, the diff of this file is not supported yet
-94
| var createCamera = require('canvas-orbit-camera') | ||
| var mat4 = require('gl-matrix').mat4 | ||
| var pack = require('array-pack-2d') | ||
| var unindex = require('unindex-mesh') | ||
| var faceNormals = require('face-normals') | ||
| var createContext = require('gl-context') | ||
| var ndarray = require('ndarray') | ||
| var normals = require('normals') | ||
| var glslify = require('glslify') | ||
| var bunny = require('bunny') | ||
| var createShader = require('gl-shader') | ||
| var createGeom = require('./') | ||
| var clear = require('gl-clear')({ | ||
| color: [0xF0 / 255, 0xF1 / 255, 0xF2 / 255, 1], | ||
| depth: true, | ||
| stencil: false | ||
| }) | ||
| // handles simplicial complexes with cells/positions properties | ||
| var scPos = bunny | ||
| var scNor = normals.vertexNormals(bunny.cells, bunny.positions) | ||
| createExample(scPos, scNor).title = 'Simplicial Complex' | ||
| // handles Float32Arrays | ||
| var uiPos = unindex(bunny.positions, bunny.cells) | ||
| var uiNor = faceNormals(uiPos) | ||
| createExample(uiPos, uiNor).title = 'Unindexed Mesh, Float32Arrays' | ||
| // handles (flat) ndarrays | ||
| var ndPos = ndarray(uiPos, [uiPos.length]) | ||
| var ndNor = ndarray(uiNor, [uiNor.length]) | ||
| createExample(ndPos, ndNor).title = 'Flat ndarrays' | ||
| // also supports .faces() method | ||
| createExample(scPos.positions, scNor, scPos.cells).title = '.faces(), Last Call' | ||
| // also supports .faces() method with packed data | ||
| createExample(pack(scPos.positions), scNor, pack(scPos.cells)).title = '.faces(), Packed Data' | ||
| // .faces(), order-independant | ||
| createExample(scPos.positions, scNor, scPos.cells, true).title = '.faces(), First Call' | ||
| function createExample (pos, norm, cells, facesFirst) { | ||
| var canvas = document.body.appendChild(document.createElement('canvas')) | ||
| var gl = createContext(canvas, render) | ||
| var camera = createCamera(canvas) | ||
| var projection = mat4.create() | ||
| var shader = createShader(gl, | ||
| glslify('./test.vert'), | ||
| glslify('./test.frag') | ||
| ) | ||
| canvas.width = 300 | ||
| canvas.height = 300 | ||
| canvas.style.margin = '1em' | ||
| var geom = createGeom(gl) | ||
| if (cells && facesFirst) geom.faces(cells) | ||
| geom | ||
| .attr('position', pos) | ||
| .attr('normal', norm) | ||
| if (cells && !facesFirst) geom.faces(cells) | ||
| function render () { | ||
| var width = canvas.width | ||
| var height = canvas.height | ||
| gl.bindFramebuffer(gl.FRAMEBUFFER, null) | ||
| gl.enable(gl.CULL_FACE) | ||
| gl.enable(gl.DEPTH_TEST) | ||
| gl.viewport(0, 0, width, height) | ||
| clear(gl) | ||
| geom.bind(shader) | ||
| shader.attributes.position.location = 0 | ||
| shader.uniforms.uView = camera.view() | ||
| shader.uniforms.uProjection = mat4.perspective(projection | ||
| , Math.PI / 4 | ||
| , width / height | ||
| , 0.001 | ||
| , 10000 | ||
| ) | ||
| geom.draw() | ||
| geom.unbind() | ||
| camera.tick() | ||
| } | ||
| return canvas | ||
| } |
Sorry, the diff of this file is not supported yet
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
167608
1026.93%11
22.22%339
27.44%140
6.87%16
14.29%1
Infinity%