UNPKG

molstar

Version:

A comprehensive macromolecular library.

119 lines 5.8 kB
/** * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> * @author David Sehnal <david.sehnal@gmail.com> */ import { Vec3 } from '../../../../mol-math/linear-algebra'; import { ChunkedArray } from '../../../../mol-data/util'; var normalVector = Vec3(); var surfacePoint = Vec3(); var controlPoint = Vec3(); var u = Vec3(); var v = Vec3(); function add2AndScale2(out, a, b, sa, sb) { out[0] = (a[0] * sa) + (b[0] * sb); out[1] = (a[1] * sa) + (b[1] * sb); out[2] = (a[2] * sa) + (b[2] * sb); } function add3AndScale2(out, a, b, c, sa, sb) { out[0] = (a[0] * sa) + (b[0] * sb) + c[0]; out[1] = (a[1] * sa) + (b[1] * sb) + c[1]; out[2] = (a[2] * sa) + (b[2] * sb) + c[2]; } // avoiding namespace lookup improved performance in Chrome (Aug 2020) var v3fromArray = Vec3.fromArray; var v3normalize = Vec3.normalize; var v3negate = Vec3.negate; var v3copy = Vec3.copy; var v3cross = Vec3.cross; var caAdd3 = ChunkedArray.add3; var CosSinCache = new Map(); function getCosSin(radialSegments) { if (!CosSinCache.has(radialSegments)) { var cos = []; var sin = []; for (var j = 0; j < radialSegments; ++j) { var t = 2 * Math.PI * j / radialSegments; cos[j] = Math.cos(t); sin[j] = Math.sin(t); } CosSinCache.set(radialSegments, { cos: cos, sin: sin }); } return CosSinCache.get(radialSegments); } export function addTube(state, controlPoints, normalVectors, binormalVectors, linearSegments, radialSegments, widthValues, heightValues, startCap, endCap) { var currentGroup = state.currentGroup, vertices = state.vertices, normals = state.normals, indices = state.indices, groups = state.groups; var vertexCount = vertices.elementCount; var _a = getCosSin(radialSegments), cos = _a.cos, sin = _a.sin; for (var i = 0; i <= linearSegments; ++i) { var i3 = i * 3; v3fromArray(u, normalVectors, i3); v3fromArray(v, binormalVectors, i3); v3fromArray(controlPoint, controlPoints, i3); var width = widthValues[i]; var height = heightValues[i]; for (var j = 0; j < radialSegments; ++j) { add3AndScale2(surfacePoint, u, v, controlPoint, height * cos[j], width * sin[j]); if (radialSegments === 2) { v3copy(normalVector, v); v3normalize(normalVector, normalVector); if (j !== 0 || i % 2 === 0) v3negate(normalVector, normalVector); } else { add2AndScale2(normalVector, u, v, width * cos[j], height * sin[j]); } v3normalize(normalVector, normalVector); caAdd3(vertices, surfacePoint[0], surfacePoint[1], surfacePoint[2]); caAdd3(normals, normalVector[0], normalVector[1], normalVector[2]); } } for (var i = 0; i < linearSegments; ++i) { for (var j = 0; j < radialSegments; ++j) { caAdd3(indices, vertexCount + i * radialSegments + (j + 1) % radialSegments, vertexCount + (i + 1) * radialSegments + (j + 1) % radialSegments, vertexCount + i * radialSegments + j); caAdd3(indices, vertexCount + (i + 1) * radialSegments + (j + 1) % radialSegments, vertexCount + (i + 1) * radialSegments + j, vertexCount + i * radialSegments + j); } } if (startCap) { var offset = 0; var centerVertex = vertices.elementCount; v3fromArray(u, normalVectors, offset); v3fromArray(v, binormalVectors, offset); v3fromArray(controlPoint, controlPoints, offset); v3cross(normalVector, v, u); caAdd3(vertices, controlPoint[0], controlPoint[1], controlPoint[2]); caAdd3(normals, normalVector[0], normalVector[1], normalVector[2]); var width = widthValues[0]; var height = heightValues[0]; vertexCount = vertices.elementCount; for (var i = 0; i < radialSegments; ++i) { add3AndScale2(surfacePoint, u, v, controlPoint, height * cos[i], width * sin[i]); caAdd3(vertices, surfacePoint[0], surfacePoint[1], surfacePoint[2]); caAdd3(normals, normalVector[0], normalVector[1], normalVector[2]); caAdd3(indices, vertexCount + (i + 1) % radialSegments, vertexCount + i, centerVertex); } } if (endCap) { var offset = linearSegments * 3; var centerVertex = vertices.elementCount; v3fromArray(u, normalVectors, offset); v3fromArray(v, binormalVectors, offset); v3fromArray(controlPoint, controlPoints, offset); v3cross(normalVector, u, v); caAdd3(vertices, controlPoint[0], controlPoint[1], controlPoint[2]); caAdd3(normals, normalVector[0], normalVector[1], normalVector[2]); var width = widthValues[linearSegments]; var height = heightValues[linearSegments]; vertexCount = vertices.elementCount; for (var i = 0; i < radialSegments; ++i) { add3AndScale2(surfacePoint, u, v, controlPoint, height * cos[i], width * sin[i]); caAdd3(vertices, surfacePoint[0], surfacePoint[1], surfacePoint[2]); caAdd3(normals, normalVector[0], normalVector[1], normalVector[2]); caAdd3(indices, vertexCount + i, vertexCount + (i + 1) % radialSegments, centerVertex); } } var addedVertexCount = (linearSegments + 1) * radialSegments + (startCap ? radialSegments + 1 : 0) + (endCap ? radialSegments + 1 : 0); ChunkedArray.addRepeat(groups, addedVertexCount, currentGroup); } //# sourceMappingURL=tube.js.map