UNPKG

extrude-by-path

Version:

extrude a 2d shape along a 3d path to build a simplicial complex

75 lines (72 loc) 2.23 kB
var trmat = require('gl-vec3/transformMat4') var add = require('gl-vec3/add') var subtract = require('gl-vec3/subtract') var normalize = require('gl-vec3/normalize') var cross = require('gl-vec3/cross') var dot = require('gl-vec3/dot') var identity = require('gl-mat4/identity') var rotate = require('gl-mat4/rotate') var mat = [], v = [], axis = [] module.exports = function (opts) { var mesh = { positions: [], cells: [] } var path = opts.path var positions = opts.positions if (!positions) throw new Error('positions not provided') var edges = opts.edges if (!edges) throw new Error('edges not provided') var cells = opts.cells var closed = opts.closed var spl = positions.length, pl = path.length, sel = edges.length for (var i = 0; i < pl; i++) { var n = [0,0,1] if (closed) { subtract(v,path[(i-1+pl)%(pl-1)],path[(i+1)%(pl-1)]) } else if (i === 0) { subtract(v,path[i],path[i+1]) } else if (i === pl-1) { subtract(v,path[i-1],path[i]) } else { subtract(v,path[i-1],path[i+1]) } normalize(v,v) cross(axis,n,v) var angle = Math.acos(dot(n,v)) identity(mat) rotate(mat,mat,angle,axis) var twist = path[i][3] if (twist) rotate(mat,mat,twist,n) for (var j = 0; j < spl; j++) { var p = positions[j] var pt = [p[0],p[1],p[2]||0] trmat(pt, pt, mat) add(pt,pt,path[i]) mesh.positions.push(pt) } } for (var i = 0; i < pl-1; i++) { for (var j = 0; j < sel; j++) { var e = edges[j] mesh.cells.push([i*spl+e[0],i*spl+e[1],(i+1)*spl+e[0]]) mesh.cells.push([i*spl+e[1],(i+1)*spl+e[0],(i+1)*spl+e[1]]) } } if (cells && !closed && opts.startCap !== false && opts.caps !== false) { for (var i = 0; i < cells.length; i++) { var c = [], len = cells[i].length for (var j = 0; j < len; j++) { c.push(cells[i][j]) } mesh.cells.push(c) } } if (cells && !closed && opts.endCap !== false && opts.caps !== false) { for (var i = 0; i < cells.length; i++) { var c = [], len = cells[i].length for (var j = 0; j < len; j++) { c.push(cells[i][j] + (pl-1)*spl) } mesh.cells.push(c) } } return mesh }