UNPKG

molstar

Version:

A comprehensive macromolecular library.

119 lines (118 loc) 6.88 kB
"use strict"; /** * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.addFixedCountDashedCylinder = exports.addDoubleCylinder = exports.addCylinder = exports.addSimpleCylinder = void 0; var linear_algebra_1 = require("../../../../mol-math/linear-algebra"); var mesh_builder_1 = require("../mesh-builder"); var primitive_1 = require("../../../primitive/primitive"); var cylinder_1 = require("../../../primitive/cylinder"); var prism_1 = require("../../../primitive/prism"); var polygon_1 = require("../../../primitive/polygon"); var util_1 = require("../../../../mol-data/util"); var cylinderMap = new Map(); var up = linear_algebra_1.Vec3.create(0, 1, 0); var tmpCylinderDir = (0, linear_algebra_1.Vec3)(); var tmpCylinderMatDir = (0, linear_algebra_1.Vec3)(); var tmpCylinderCenter = (0, linear_algebra_1.Vec3)(); var tmpCylinderMat = (0, linear_algebra_1.Mat4)(); var tmpCylinderMatRot = (0, linear_algebra_1.Mat4)(); var tmpCylinderScale = (0, linear_algebra_1.Vec3)(); var tmpCylinderStart = (0, linear_algebra_1.Vec3)(); var tmpUp = (0, linear_algebra_1.Vec3)(); function setCylinderMat(m, start, dir, length, matchDir) { linear_algebra_1.Vec3.setMagnitude(tmpCylinderMatDir, dir, length / 2); linear_algebra_1.Vec3.add(tmpCylinderCenter, start, tmpCylinderMatDir); // ensure the direction used to create the rotation is always pointing in the same // direction so the triangles of adjacent cylinder will line up if (matchDir) linear_algebra_1.Vec3.matchDirection(tmpUp, up, tmpCylinderMatDir); else linear_algebra_1.Vec3.copy(tmpUp, up); linear_algebra_1.Vec3.set(tmpCylinderScale, 1, length, 1); linear_algebra_1.Vec3.makeRotation(tmpCylinderMatRot, tmpUp, tmpCylinderMatDir); linear_algebra_1.Mat4.scale(m, tmpCylinderMatRot, tmpCylinderScale); return linear_algebra_1.Mat4.setTranslation(m, tmpCylinderCenter); } var tmpPropValues = new Int32Array(9); function getCylinderPropsKey(props) { var _a, _b, _c, _d, _e, _f, _g, _h, _j; tmpPropValues[0] = Math.round(1000 * ((_a = props.radiusTop) !== null && _a !== void 0 ? _a : cylinder_1.DefaultCylinderProps.radiusTop)); tmpPropValues[1] = Math.round(1000 * ((_b = props.radiusBottom) !== null && _b !== void 0 ? _b : cylinder_1.DefaultCylinderProps.radiusBottom)); tmpPropValues[2] = Math.round(1000 * ((_c = props.height) !== null && _c !== void 0 ? _c : cylinder_1.DefaultCylinderProps.height)); tmpPropValues[3] = (_d = props.radialSegments) !== null && _d !== void 0 ? _d : cylinder_1.DefaultCylinderProps.radialSegments; tmpPropValues[4] = (_e = props.heightSegments) !== null && _e !== void 0 ? _e : cylinder_1.DefaultCylinderProps.heightSegments; tmpPropValues[5] = ((_f = props.topCap) !== null && _f !== void 0 ? _f : cylinder_1.DefaultCylinderProps.topCap) ? 1 : 0; tmpPropValues[6] = ((_g = props.bottomCap) !== null && _g !== void 0 ? _g : cylinder_1.DefaultCylinderProps.bottomCap) ? 1 : 0; tmpPropValues[7] = Math.round(1000 * ((_h = props.thetaStart) !== null && _h !== void 0 ? _h : cylinder_1.DefaultCylinderProps.thetaStart)); tmpPropValues[8] = Math.round(1000 * ((_j = props.thetaLength) !== null && _j !== void 0 ? _j : cylinder_1.DefaultCylinderProps.thetaLength)); return (0, util_1.hashFnv32a)(tmpPropValues); } function getCylinder(props) { var key = getCylinderPropsKey(props); var cylinder = cylinderMap.get(key); if (cylinder === undefined) { if (props.radialSegments && props.radialSegments <= 4) { var sideCount = Math.max(3, props.radialSegments); var prism = (0, prism_1.Prism)((0, polygon_1.polygon)(sideCount, true, props.radiusTop), props); cylinder = (0, primitive_1.transformPrimitive)(prism, linear_algebra_1.Mat4.rotX90); } else { cylinder = (0, cylinder_1.Cylinder)(props); } cylinderMap.set(key, cylinder); } return cylinder; } function addSimpleCylinder(state, start, end, props) { var d = linear_algebra_1.Vec3.distance(start, end); linear_algebra_1.Vec3.sub(tmpCylinderDir, end, start); setCylinderMat(tmpCylinderMat, start, tmpCylinderDir, d, false); mesh_builder_1.MeshBuilder.addPrimitive(state, tmpCylinderMat, getCylinder(props)); } exports.addSimpleCylinder = addSimpleCylinder; function addCylinder(state, start, end, lengthScale, props) { var d = linear_algebra_1.Vec3.distance(start, end) * lengthScale; linear_algebra_1.Vec3.sub(tmpCylinderDir, end, start); setCylinderMat(tmpCylinderMat, start, tmpCylinderDir, d, true); mesh_builder_1.MeshBuilder.addPrimitive(state, tmpCylinderMat, getCylinder(props)); } exports.addCylinder = addCylinder; function addDoubleCylinder(state, start, end, lengthScale, shift, props) { var d = linear_algebra_1.Vec3.distance(start, end) * lengthScale; var cylinder = getCylinder(props); linear_algebra_1.Vec3.sub(tmpCylinderDir, end, start); // positivly shifted cylinder linear_algebra_1.Vec3.add(tmpCylinderStart, start, shift); setCylinderMat(tmpCylinderMat, tmpCylinderStart, tmpCylinderDir, d, true); mesh_builder_1.MeshBuilder.addPrimitive(state, tmpCylinderMat, cylinder); // negativly shifted cylinder linear_algebra_1.Vec3.sub(tmpCylinderStart, start, shift); setCylinderMat(tmpCylinderMat, tmpCylinderStart, tmpCylinderDir, d, true); mesh_builder_1.MeshBuilder.addPrimitive(state, tmpCylinderMat, cylinder); } exports.addDoubleCylinder = addDoubleCylinder; function addFixedCountDashedCylinder(state, start, end, lengthScale, segmentCount, props) { var s = Math.floor(segmentCount / 2); var step = 1 / segmentCount; // automatically adjust length so links/bonds that are rendered as two half cylinders // have evenly spaced dashed cylinders if (lengthScale < 1) { var bias = lengthScale / 2 / segmentCount; lengthScale += segmentCount % 2 === 1 ? bias : -bias; } var d = linear_algebra_1.Vec3.distance(start, end) * lengthScale; var cylinder = getCylinder(props); linear_algebra_1.Vec3.sub(tmpCylinderDir, end, start); for (var j = 0; j < s; ++j) { var f = step * (j * 2 + 1); linear_algebra_1.Vec3.setMagnitude(tmpCylinderDir, tmpCylinderDir, d * f); linear_algebra_1.Vec3.add(tmpCylinderStart, start, tmpCylinderDir); setCylinderMat(tmpCylinderMat, tmpCylinderStart, tmpCylinderDir, d * step, false); mesh_builder_1.MeshBuilder.addPrimitive(state, tmpCylinderMat, cylinder); } } exports.addFixedCountDashedCylinder = addFixedCountDashedCylinder;