primitive-sphere
Version:
a sphere mesh with normals, texture coordinates and indices
79 lines (63 loc) • 2.18 kB
JavaScript
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
}
}