UNPKG

primitive-sphere

Version:

a sphere mesh with normals, texture coordinates and indices

79 lines (63 loc) 2.18 kB
var identity = require('gl-mat4/identity') var rotateY = require('gl-mat4/rotateY') var rotateZ = require('gl-mat4/rotateZ') var scale = require('gl-vec3/scale') var transformMat4 = require('gl-vec3/transformMat4') var normalize = require('gl-vec3/normalize') var matRotY = identity([]) var matRotZ = identity([]) var up = [0, 1, 0] var tmpVec3 = [0, 0, 0] module.exports = primitiveSphere function primitiveSphere (radius, opt) { opt = opt || {} radius = typeof radius !== 'undefined' ? radius : 1 var segments = typeof opt.segments !== 'undefined' ? opt.segments : 32 var totalZRotationSteps = 2 + segments var totalYRotationSteps = 2 * totalZRotationSteps var indices = [] var positions = [] var normals = [] var uvs = [] for (var zRotationStep = 0; zRotationStep <= totalZRotationSteps; zRotationStep++) { var normalizedZ = zRotationStep / totalZRotationSteps var angleZ = (normalizedZ * Math.PI) for (var yRotationStep = 0; yRotationStep <= totalYRotationSteps; yRotationStep++) { var normalizedY = yRotationStep / totalYRotationSteps var angleY = normalizedY * Math.PI * 2 identity(matRotZ) rotateZ(matRotZ, matRotZ, -angleZ) identity(matRotY) rotateY(matRotY, matRotY, angleY) transformMat4(tmpVec3, up, matRotZ) transformMat4(tmpVec3, tmpVec3, matRotY) scale(tmpVec3, tmpVec3, -radius) positions.push(tmpVec3.slice()) normalize(tmpVec3, tmpVec3) normals.push(tmpVec3.slice()) uvs.push([ normalizedY, normalizedZ ]) } if (zRotationStep > 0) { var verticesCount = positions.length var firstIndex = verticesCount - 2 * (totalYRotationSteps + 1) for (; (firstIndex + totalYRotationSteps + 2) < verticesCount; firstIndex++) { indices.push([ firstIndex, firstIndex + 1, firstIndex + totalYRotationSteps + 1 ]) indices.push([ firstIndex + totalYRotationSteps + 1, firstIndex + 1, firstIndex + totalYRotationSteps + 2 ]) } } } return { cells: indices, positions: positions, normals: normals, uvs: uvs } }