├── .gitignore ├── .npmignore ├── LICENSE.md ├── README.md ├── demo ├── Material.frag ├── Material.vert ├── SolidColor.frag ├── SolidColor.vert ├── main.js └── package.json ├── index.js ├── package.json └── thumb.png /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | *.log 4 | .DS_Store 5 | bundle.js 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | bundle.js 5 | test 6 | test.js 7 | demo/ 8 | .npmignore 9 | LICENSE.md 10 | thumb.png 11 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2015 Marcin Ignac 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 | ![](thumb.png) 2 | 3 | # primitive-rounded-cube 4 | 5 | [![stable](http://badges.github.io/stability-badges/dist/stable.svg)](http://github.com/badges/stability-badges) 6 | 7 | A rounded cube geometry for 3D rendering, including normals, UVs and cell indices (faces). 8 | 9 | ## Usage 10 | 11 | [![NPM](https://nodei.co/npm/primitive-rounded-cube.png)](https://www.npmjs.com/package/primitive-rounded-cube) 12 | 13 | #### `mesh = createRoundedCube([sx, sy, sz, nx, ny, nz, r])` 14 | 15 | Parameters: 16 | `sx` - size x, defaults to 1 17 | `sy` - size y, defaults to `sx` 18 | `sz` - size z, defaults to `sx` 19 | `nx` - num subdivisions on x axis, defaults to 1 20 | `ny` - num subdivisions on y axis, defaults to `sx` 21 | `nz` - num subdivisions on z axis, defaults to `sx` 22 | `r` - rounded corner/edge radius, defaults to 0 23 | 24 | ## Example 25 | 26 | ```javascript 27 | var createRoundedCube = require('primitive-rounded-cube'); 28 | var cube = createRoundedCube(1, 1, 1, 20, 20, 20, 0.1); 29 | ``` 30 | 31 | `cube` will have the following structure: 32 | 33 | ``` 34 | { 35 | positions: [ [x, y, z], [x, y, z], ... ], 36 | cells: [ [a, b, c], [a, b, c], ... ], 37 | uvs: [ [u, v], [u, v], ... ], 38 | normals: [ [x, y, z], [x, y, z], ... ] 39 | } 40 | ``` 41 | 42 | ## Demo 43 | 44 | Download or clone this repo and run: 45 | 46 | ``` 47 | cd demo 48 | npm install 49 | npm start 50 | ``` 51 | 52 | ## License 53 | 54 | MIT, see [LICENSE.md](http://github.com/vorg/primitive-rounded-cube/blob/master/LICENSE.md) for details. 55 | -------------------------------------------------------------------------------- /demo/Material.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | varying vec2 vTexCoord0; 6 | 7 | uniform sampler2D uTexture; 8 | 9 | void main() { 10 | gl_FragColor = texture2D(uTexture, vTexCoord0 * 5.0); 11 | gl_FragColor *= vec4(vTexCoord0, 0.0, 1.0); 12 | } 13 | -------------------------------------------------------------------------------- /demo/Material.vert: -------------------------------------------------------------------------------- 1 | attribute vec4 aPosition; 2 | attribute vec2 aTexCoord0; 3 | 4 | uniform mat4 uProjectionMatrix; 5 | uniform mat4 uViewMatrix; 6 | uniform mat4 uModelMatrix; 7 | 8 | varying vec2 vTexCoord0; 9 | 10 | void main() { 11 | vTexCoord0 = aTexCoord0; 12 | gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * aPosition; 13 | } 14 | -------------------------------------------------------------------------------- /demo/SolidColor.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | uniform vec4 uColor; 6 | 7 | void main() { 8 | gl_FragColor = uColor; 9 | } 10 | -------------------------------------------------------------------------------- /demo/SolidColor.vert: -------------------------------------------------------------------------------- 1 | attribute vec4 aPosition; 2 | 3 | uniform mat4 uProjectionMatrix; 4 | uniform mat4 uViewMatrix; 5 | uniform mat4 uModelMatrix; 6 | 7 | varying vec2 vTexCoord0; 8 | 9 | void main() { 10 | gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * aPosition; 11 | } 12 | -------------------------------------------------------------------------------- /demo/main.js: -------------------------------------------------------------------------------- 1 | var Window = require('pex-sys/Window'); 2 | var Mat4 = require('pex-math/Mat4'); 3 | var Vec3 = require('pex-math/Vec3'); 4 | var glslify = require('glslify-promise'); 5 | var createCube = require('primitive-cube'); 6 | var createRoundedCube = require('../index.js'); 7 | var computeEdges = require('geom-edges'); 8 | var computeNormals = require('normals').vertexNormals; 9 | 10 | function tryify(f) { 11 | return function() { 12 | var self = this; 13 | try { 14 | f.bind(self)(); 15 | } 16 | catch(e) { 17 | console.log(e); 18 | console.log(e.stack); 19 | process.exit(-1); 20 | } 21 | } 22 | } 23 | 24 | Window.create({ 25 | settings: { 26 | width: 1024, 27 | height: 576 28 | }, 29 | resources: { 30 | vert: { glsl: glslify(__dirname + '/Material.vert') }, 31 | frag: { glsl: glslify(__dirname + '/Material.frag') }, 32 | solidColorVert: { glsl: glslify(__dirname + '/SolidColor.vert') }, 33 | solidColorFrag: { glsl: glslify(__dirname + '/SolidColor.frag') } 34 | }, 35 | init: tryify(function() { 36 | var ctx = this.getContext(); 37 | 38 | this.model = Mat4.create(); 39 | 40 | this.projection = Mat4.perspective( 41 | Mat4.create(), 42 | 45, 43 | this.getAspectRatio(), 44 | 0.001, 45 | 10.0 46 | ); 47 | 48 | this.view = Mat4.create(); 49 | 50 | Mat4.lookAt(this.view, [0, 1, 3], [0, 0, 0], [0, 1, 0]); 51 | 52 | ctx.setProjectionMatrix(this.projection); 53 | ctx.setViewMatrix(this.view); 54 | ctx.setModelMatrix(this.model); 55 | 56 | var res = this.getResources(); 57 | 58 | this.program = ctx.createProgram(res.vert, res.frag); 59 | this.solidColorProgram = ctx.createProgram(res.solidColorVert, res.solidColorFrag); 60 | 61 | var bbox = createCube(1.0); 62 | 63 | this.bboxMesh = ctx.createMesh([ 64 | { data: bbox.positions, location: ctx.ATTRIB_POSITION }, 65 | { data: bbox.normals, location: ctx.ATTRIB_NORMAL }, 66 | { data: bbox.uvs, location: ctx.ATTRIB_TEX_COORD_0 }, 67 | ], { data: computeEdges(bbox.cells) }, ctx.LINES); 68 | 69 | var g = createRoundedCube(1, 1, 1, 20, 20, 20, 0.1); 70 | 71 | this.mesh = ctx.createMesh([ 72 | { data: g.positions, location: ctx.ATTRIB_POSITION }, 73 | { data: g.normals, location: ctx.ATTRIB_NORMAL }, 74 | { data: g.uvs, location: ctx.ATTRIB_TEX_COORD_0 }, 75 | ], { data: g.cells }, ctx.TRIANGLES); 76 | 77 | this.meshWireframe = ctx.createMesh([ 78 | { data: g.positions, location: ctx.ATTRIB_POSITION }, 79 | ], { data: computeEdges(g.cells) }, ctx.LINES); 80 | 81 | var img = new Uint8Array([ 82 | 0xff, 0xff, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 83 | 0xcc, 0xcc, 0xcc, 0xff, 0xff, 0xff, 0xff, 0xff 84 | ]); 85 | 86 | this.tex = ctx.createTexture2D(img, 2, 2, { 87 | repeat: true, 88 | minFilter: ctx.NEAREST, 89 | magFilter: ctx.NEAREST 90 | }) 91 | }), 92 | 93 | draw: function() { 94 | var ctx = this.getContext(); 95 | ctx.setClearColor(1, 1, 1, 1); 96 | ctx.clear(ctx.COLOR_BIT | ctx.DEPTH_BIT); 97 | ctx.setDepthTest(true); 98 | 99 | ctx.bindTexture(this.tex, 0); 100 | ctx.bindProgram(this.program); 101 | this.program.setUniform('uTexture', 0); 102 | 103 | Mat4.rotate(this.model, Math.PI/1000, [0, 1, 0]); 104 | ctx.setModelMatrix(this.model); 105 | 106 | ctx.bindMesh(this.mesh); 107 | ctx.drawMesh(); 108 | 109 | ctx.bindProgram(this.solidColorProgram); 110 | this.solidColorProgram.setUniform('uColor', [1,1,1,1]); 111 | ctx.pushModelMatrix(); 112 | ctx.scale([1.01,1.01,1.01]) 113 | ctx.bindMesh(this.meshWireframe); 114 | ctx.drawMesh(); 115 | ctx.popModelMatrix(); 116 | 117 | ctx.bindProgram(this.solidColorProgram); 118 | this.solidColorProgram.setUniform('uColor', [1,0,0,1]); 119 | ctx.pushModelMatrix(); 120 | ctx.scale([1.02,1.02,1.02]) 121 | ctx.bindMesh(this.bboxMesh); 122 | ctx.drawMesh(); 123 | ctx.popModelMatrix(); 124 | } 125 | }) 126 | -------------------------------------------------------------------------------- /demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo", 3 | "version": "0.0.0", 4 | "description": "A pritimive-cube demo", 5 | "main": "main.js", 6 | "scripts": { 7 | "start": "beefy main.js --open -- -i plask -g glslify-promise/transform" 8 | }, 9 | "author": { 10 | "name": "Marcin Ignac", 11 | "email": "marcin.ignac@gmail.com", 12 | "url": "https://github.com/vorg" 13 | }, 14 | "license": "MIT", 15 | "devDependencies": { 16 | "beefy": "^2.1.5" 17 | }, 18 | "dependencies": { 19 | "geom-edges": "^1.2.0", 20 | "glslify-promise": "^1.0.1", 21 | "normals": "^1.0.1", 22 | "pex-context": "git://github.com/variablestudio/pex-context", 23 | "pex-io": "git://github.com/variablestudio/pex-io", 24 | "pex-math": "git://github.com/variablestudio/pex-math", 25 | "pex-sys": "git://github.com/variablestudio/pex-sys" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var createCube = require('primitive-cube'); 2 | var Vec3 = require('pex-math/Vec3'); 3 | 4 | function createRoundedCube(sx, sy, sz, nx, ny, nz, radius) { 5 | if (sx === undefined) sx = 1.0; 6 | if (sy === undefined) sy = sx; 7 | if (sz === undefined) sz = sx; 8 | 9 | if (nx === undefined) nx = 1.0; 10 | if (ny === undefined) ny = nx; 11 | if (nz === undefined) nz = nx; 12 | 13 | if (radius == undefined) radius = 0; 14 | 15 | var rx = sx / 2.0; 16 | var ry = sy / 2.0; 17 | var rz = sz / 2.0; 18 | 19 | var cube = createCube(sx, sy, sz, nx, ny, nz); 20 | 21 | var positions = cube.positions; 22 | var normals = cube.normals; 23 | 24 | var tmp = [0,0,0]; 25 | for(var i=0; i rx - radius) { 34 | inner[0] = rx - radius; 35 | } 36 | 37 | if (pos[1] < -ry + radius) { 38 | inner[1] = -ry + radius; 39 | } 40 | else if (pos[1] > ry - radius) { 41 | inner[1] = ry - radius; 42 | } 43 | 44 | if (pos[2] < -rz + radius) { 45 | inner[2] = -rz + radius; 46 | } 47 | else if (pos[2] > rz - radius) { 48 | inner[2] = rz - radius; 49 | } 50 | 51 | Vec3.set(normal, pos); 52 | Vec3.sub(normal, inner); 53 | Vec3.normalize(normal); 54 | 55 | Vec3.set(pos, inner); 56 | Vec3.set(tmp, normal); 57 | Vec3.scale(tmp, radius); 58 | Vec3.add(pos, tmp); 59 | } 60 | 61 | return cube; 62 | } 63 | 64 | module.exports = createRoundedCube; 65 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "primitive-rounded-cube", 3 | "version": "1.0.2", 4 | "description": "A rounded cube geometry for 3D rendering, including normals, UVs and cell indices (faces).", 5 | "main": "index.js", 6 | "license": "MIT", 7 | "author": { 8 | "name": "Marcin Ignac", 9 | "email": "marcin.ignac@gmail.com", 10 | "url": "https://github.com/vorg" 11 | }, 12 | "dependencies": { 13 | "pex-math": "^1.0.0", 14 | "primitive-cube": "^2.0.0" 15 | }, 16 | "devDependencies": {}, 17 | "scripts": { 18 | "test": "node test.js" 19 | }, 20 | "keywords": [ 21 | "3d", 22 | "simplicial", 23 | "complex", 24 | "primitive", 25 | "geometry", 26 | "geom", 27 | "cube", 28 | "webgl" 29 | ], 30 | "repository": { 31 | "type": "git", 32 | "url": "git://github.com/vorg/primitive-rounded-cube.git" 33 | }, 34 | "homepage": "https://github.com/vorg/primitive-rounded-cube", 35 | "bugs": { 36 | "url": "https://github.com/vorg/primitive-rounded-cube/issues" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vorg/primitive-rounded-cube/140f9c18168f0e39c093b6ae56bde4b5008a3257/thumb.png --------------------------------------------------------------------------------