├── .gitignore ├── LICENSE.md ├── README.md ├── index.js ├── package.json ├── render.png └── test ├── index.js ├── test.frag └── test.vert /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | *.log 4 | .DS_Store 5 | bundle.js 6 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2014 Mikko Haapoja 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 20 | OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # geo-arc 2 | 3 | ![render](./render.png) 4 | [![experimental](http://badges.github.io/stability-badges/dist/experimental.svg)](http://github.com/badges/stability-badges) 5 | 6 | Creates a 2d arc in 3d space. 7 | 8 | ## Usage 9 | 10 | [![NPM](https://nodei.co/npm/geo-arc.png)](https://www.npmjs.com/package/geo-arc) 11 | 12 | ### Example 13 | 14 | An example can be found at `./test/index.js`. You can run this test by calling: 15 | ``` 16 | $ npm test 17 | ``` 18 | 19 | A simple usage example with default values being passed as settings: 20 | ```javascript 21 | var geoArc = require('geo-arc'); 22 | 23 | // geo will be a Object will three properties: 24 | // positions - the vertices 25 | // cells - the indices to draw the arc 26 | // uvs - uv values for for the arc 27 | var geo = geoArc( { 28 | cellSize: 3, // 1 == points, 2 == lines, 3 == triangles 29 | x: 0, // x position of the center of the arc 30 | y: 0, // y position of the center of the arc 31 | z: 0, // z position of the center of the arc 32 | startRadian: 0, // start radian for the arc 33 | endRadian: 1.5, // end radian for the arc 34 | innerRadius: 40, // inner radius of the arc 35 | outerRadius: 200, // outside radius of the arc 36 | numBands: 2, // subdivision from inside out 37 | numSlices: 40, // subdivision along curve 38 | drawOutline: true // if cellSize == 2 draw only the outside of the shape 39 | }); 40 | ``` 41 | 42 | Generated uv values look like this: 43 | ![Generated UVs](https://cloud.githubusercontent.com/assets/171001/12681332/062c57fe-c6a6-11e5-98ea-548fd44504c7.png) 44 | 45 | ## License 46 | 47 | MIT, see [LICENSE.md](http://github.com/mikkoh/geoArc/blob/master/LICENSE.md) for details. 48 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = geoArc; 2 | 3 | function geoArc(options) { 4 | 5 | var geo = { 6 | positions: [], 7 | cells: [], 8 | uvs: [] 9 | }; 10 | 11 | options = options || {}; 12 | options.cellSize = options.cellSize || 3; 13 | options.x = options.x || 0; 14 | options.y = options.y || 0; 15 | options.z = options.z || 0; 16 | options.startRadian = options.startRadian || 0; 17 | options.endRadian = options.endRadian || Math.PI * 1.5; 18 | options.innerRadius = typeof options.innerRadius == 'number' ? options.innerRadius : 40; 19 | options.outerRadius = options.outerRadius || 200; 20 | options.numBands = options.numBands || 2; 21 | options.numSlices = options.numSlices || 40; 22 | options.drawOutline = options.drawOutline !== undefined ? options.drawOutline : true; 23 | 24 | createGeometry(options, geo.positions, geo.cells, geo.uvs); 25 | 26 | return geo; 27 | } 28 | 29 | function createGeometry(options, positions, cells, uvs) { 30 | 31 | var o = options; 32 | var idxSize = o.cellSize; 33 | var radDist = o.endRadian - o.startRadian; 34 | var numSlices = Math.floor(Math.abs(radDist) / (Math.PI * 2) * o.numSlices); 35 | var radInc = radDist / numSlices; 36 | var numBandIncs = (o.numBands == 1) ? 1 : o.numBands - 1; 37 | var bandInc = (o.outerRadius - o.innerRadius) / numBandIncs; 38 | var cRad, x, y, z, cRadius, curSlideIdx, prevSlideIdx; 39 | 40 | for(var i = 0, len = numSlices; i <= len; i++) { 41 | 42 | cRad = i * radInc + o.startRadian; 43 | prevSlideIdx = (i - 1) * o.numBands; 44 | curSlideIdx = i * o.numBands; 45 | 46 | for(var j = 0, lenJ = o.numBands; j < lenJ; j++) { 47 | 48 | cRadius = o.innerRadius + bandInc * j; 49 | 50 | x = Math.cos(cRad) * cRadius + o.x; 51 | y = o.y; 52 | z = Math.sin(cRad) * cRadius + o.z; 53 | 54 | positions.push([ x, y, z ]); 55 | uvs.push([i/numSlices, j/numBandIncs]) 56 | 57 | //if we've added in positions then we'll add cells 58 | if(idxSize == 1) { 59 | 60 | cells.push([ curSlideIdx + j ]); 61 | } else if(idxSize == 2) { 62 | 63 | if(i > 0 && j + 1 < lenJ) { 64 | 65 | cells.push( [ 66 | prevSlideIdx + j, 67 | curSlideIdx + j 68 | ]); 69 | 70 | cells.push( [ 71 | curSlideIdx + j + 1, 72 | prevSlideIdx + j + 1 73 | ]); 74 | 75 | if( !o.drawOutline ) { 76 | 77 | cells.push( [ 78 | curSlideIdx + j, 79 | curSlideIdx + j + 1 80 | ]); 81 | } 82 | } 83 | } else if(idxSize == 3) { 84 | 85 | if(i > 0 && j + 1 < lenJ) { 86 | 87 | cells.push( [ 88 | curSlideIdx + j, 89 | prevSlideIdx + j + 1, 90 | prevSlideIdx + j 91 | ]); 92 | 93 | cells.push( [ 94 | curSlideIdx + j, 95 | curSlideIdx + j + 1, 96 | prevSlideIdx + j + 1 97 | ]); 98 | } 99 | } 100 | } 101 | } 102 | 103 | //cap it off 104 | if(idxSize == 2) { 105 | 106 | // if it's going all the way around then we wont put the connecting line 107 | if( radDist % Math.PI * 2 != 0 ) { 108 | 109 | for(var j = 0, lenJ = o.numBands - 1; j < lenJ; j++) { 110 | 111 | cells.push([ 112 | curSlideIdx + j, 113 | curSlideIdx + j + 1 ]); 114 | } 115 | 116 | curSlideIdx = 0; 117 | 118 | for(var j = 0, lenJ = o.numBands - 1; j < lenJ; j++) { 119 | 120 | cells.push([ 121 | curSlideIdx + j, 122 | curSlideIdx + j + 1 ]); 123 | } 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "geo-arc", 3 | "version": "1.1.2", 4 | "description": "Creates a 2d arc in 3d space", 5 | "main": "index.js", 6 | "license": "MIT", 7 | "author": { 8 | "name": "Mikko Haapoja", 9 | "email": "me@mikkoh.com", 10 | "url": "https://github.com/mikkoh" 11 | }, 12 | "dependencies": {}, 13 | "devDependencies": { 14 | "gl-geometry": "^1.0.3", 15 | "gl-matrix": "^2.1.0", 16 | "gl-now": "^1.4.0", 17 | "gl-shader": "^4.0.1", 18 | "glslify": "^2.0.0", 19 | "mesh-combine": "^1.1.0", 20 | "wzrd": "^1.2.1" 21 | }, 22 | "browserify": { 23 | "transform": [ 24 | "glslify" 25 | ] 26 | }, 27 | "scripts": { 28 | "test": "open http://localhost:9966 && wzrd test/index.js" 29 | }, 30 | "keywords": [ 31 | "arc,geometry,generate,mesh,webgl,3d,model" 32 | ], 33 | "repository": { 34 | "type": "git", 35 | "url": "git://github.com/mikkoh/geo-arc.git" 36 | }, 37 | "homepage": "https://github.com/mikkoh/geo-arc", 38 | "bugs": { 39 | "url": "https://github.com/mikkoh/geo-arc/issues" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /render.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikkoh/geo-arc/d8695e234c82f3c3bb95fe2f378788df5e95dabc/render.png -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | var shell = require('gl-now')( { 2 | 3 | clearColor: [ 1, 1, 1, 1 ] 4 | }); 5 | var glslify = require('glslify'); 6 | var createShader = require('gl-shader'); 7 | var createGeometry = require('gl-geometry'); 8 | var meshCombine = require('mesh-combine'); 9 | var mat4 = require('gl-matrix').mat4; 10 | var geoArc = require('./..'); 11 | 12 | var rotation = 0; 13 | var cellSize = 3; 14 | var gl, geo, shader, model, projection, drawWith; 15 | 16 | 17 | shell.on( 'gl-init', function() { 18 | 19 | var allGeo = []; 20 | 21 | gl = shell.gl; 22 | 23 | switch( cellSize ) { 24 | 25 | case 1: 26 | drawWith = gl.POINTS; 27 | break; 28 | 29 | case 2: 30 | drawWith = gl.LINES; 31 | break; 32 | 33 | case 3: 34 | drawWith = gl.TRIANGLES; 35 | break; 36 | } 37 | 38 | allGeo.push(geoArc( { 39 | cellSize: cellSize, 40 | drawOutline: true, 41 | numSlices: 10 42 | })); 43 | 44 | allGeo.push(geoArc( { 45 | cellSize: cellSize, 46 | drawOutline: false, 47 | innerRadius: 150, 48 | y: 130, 49 | startRadian: Math.PI, 50 | endRadian: Math.PI * 1.75 51 | })); 52 | 53 | allGeo.push(geoArc( { 54 | cellSize: cellSize, 55 | drawOutline: false, 56 | innerRadius: 100, 57 | y: -130, 58 | startRadian: 0, 59 | endRadian: Math.PI * 2, 60 | numBands: 10 61 | })); 62 | 63 | 64 | geo = meshCombine( allGeo ); 65 | 66 | shader = createShader( 67 | gl, 68 | glslify(__dirname + '/test.vert'), 69 | glslify(__dirname + '/test.frag') 70 | ); 71 | 72 | mesh = createGeometry( gl ) 73 | .attr( 'positions', geo.positions ) 74 | .faces( geo.cells, { size: cellSize } ); 75 | }); 76 | 77 | shell.on( 'gl-render', function() { 78 | 79 | projection = mat4.create(); 80 | mat4.perspective( projection, Math.PI * 0.25, shell.width / shell.height, 0.1, 10000 ); 81 | 82 | model = mat4.create(); 83 | mat4.translate( model, model, [ 0, 0, -1000 ] ); 84 | mat4.rotateX( model, model, Math.PI * 0.1 ); 85 | mat4.rotateY( model, model, rotation += 0.005 ); 86 | 87 | shader.bind(); 88 | 89 | shader.uniforms.projection = projection; 90 | shader.uniforms.model = model; 91 | shader.uniforms.view = mat4.create(); 92 | 93 | shader.attributes.color = [ 0, 0, 0 ]; 94 | 95 | mesh.bind( shader ); 96 | mesh.draw( drawWith ); 97 | mesh.unbind(); 98 | }); 99 | -------------------------------------------------------------------------------- /test/test.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | void main() { 4 | if(gl_FrontFacing) { 5 | gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); 6 | } else { 7 | gl_FragColor = vec4( 0.0, 0.0, 1.0, 1.0 ); 8 | } 9 | } -------------------------------------------------------------------------------- /test/test.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 position; 2 | 3 | uniform mat4 projection; 4 | uniform mat4 view; 5 | uniform mat4 model; 6 | 7 | 8 | void main() { 9 | gl_Position = projection * view * model * vec4(position, 1.0); 10 | } --------------------------------------------------------------------------------