UNPKG

primitive-capsule

Version:

A minimal capsule geometry for 3D rendering, including normals, UVs and cell indices (faces).

70 lines (56 loc) 2.1 kB
function createCapsule(radius, height, numSubdivisionsHeight, numSegments) { if (radius === undefined) radius = 0.5; if (height === undefined) height = radius * 2; if (numSubdivisionsHeight === undefined) numSubdivisionsHeight = 12; if (numSegments === undefined) numSegments = 12; var positions = []; var normals = []; var uvs = []; var cells = []; function calculateRing(segments, r, y, dy) { var segIncr = 1.0 / ( segments - 1 ); for( var s = 0; s < segments; s++ ) { var x = -Math.cos( (Math.PI * 2) * s * segIncr ) * r; var z = Math.sin( (Math.PI * 2) * s * segIncr ) * r; positions.push([radius * x, radius * y + height * dy, radius * z]) normals.push([x, y, z]) var u = (s * segIncr); var v = 0.5 - ((radius * y + height * dy) / (2.0 * radius + height)); uvs.push([u, 1.0 - v]); } } var ringsBody = numSubdivisionsHeight + 1; var ringsTotal = numSubdivisionsHeight + ringsBody; var bodyIncr = 1.0 / ( ringsBody - 1 ); var ringIncr = 1.0 / ( numSubdivisionsHeight - 1 ); for( var r = 0; r < numSubdivisionsHeight / 2; r++ ) { calculateRing( numSegments, Math.sin( Math.PI * r * ringIncr), Math.sin( Math.PI * ( r * ringIncr - 0.5 ) ), -0.5 ); } for( var r = 0; r < ringsBody; r++ ) { calculateRing( numSegments, 1.0, 0.0, r * bodyIncr - 0.5); } for( var r = numSubdivisionsHeight / 2; r < numSubdivisionsHeight; r++ ) { calculateRing( numSegments, Math.sin( Math.PI * r * ringIncr), Math.sin( Math.PI * ( r * ringIncr - 0.5 ) ), +0.5); } for( var r = 0; r < ringsTotal - 1; r++ ) { for( var s = 0; s < numSegments - 1; s++ ) { cells.push([ (r * numSegments + ( s + 0 )), (r * numSegments + ( s + 1 )), (( r + 1 ) * numSegments + ( s + 1 )) ]); cells.push([ (r * numSegments + s), (( r + 1 ) * numSegments + ( s + 1 )), (( r + 1 ) * numSegments + ( s + 0 )) ]) } } return { positions: positions, normals: normals, uvs: uvs, cells: cells } } module.exports = createCapsule;