speck-renderer
Version:
Browser-based WebGL molecule renderer with the goal of producing figures that are as attractive as they are practical.
143 lines (117 loc) • 3.7 kB
JavaScript
;
var glm = require("./gl-matrix");
var elements = require("./elements");
var consts = require("./const");
function clamp(min, max, value) {
return Math.min(max, Math.max(min, value));
}
var newView = module.exports.new = function() {
return {
aspect: 1.0,
zoom: 0.125,
translation: {
x: 0.0,
y: 0.0
},
atomScale: 0.6,
relativeAtomScale: 1.0,
bondScale: 0.5,
rotation: glm.mat4.create(),
ao: 0.75,
aoRes: 256,
brightness: 0.5,
outline: 0.0,
spf: 32,
bonds: false,
bondThreshold: 1.2,
bondShade: 0.5,
atomShade: 0.5,
resolution: 768,
dofStrength: 0.0,
dofPosition: 0.5,
fxaa: 1
};
};
var center = module.exports.center = function(v, system, zoomRatio=1) {
var maxX = -Infinity;
var minX = Infinity;
var maxY = -Infinity;
var minY = Infinity;
for(var i = 0; i < system.atoms.length; i++) {
var a = system.atoms[i];
var r = elements[a.symbol].radius;
r = 2.5 * v.atomScale * (1 + (r - 1) * v.relativeAtomScale);
var p = glm.vec4.fromValues(a.x, a.y, a.z, 0);
glm.vec4.transformMat4(p, p, v.rotation);
maxX = Math.max(maxX, p[0] + r);
minX = Math.min(minX, p[0] - r);
maxY = Math.max(maxY, p[1] + r);
minY = Math.min(minY, p[1] - r);
}
var cx = minX + (maxX - minX) / 2.0;
var cy = minY + (maxY - minY) / 2.0;
v.translation.x = cx;
v.translation.y = cy;
var scale = Math.max(maxX - minX, maxY - minY);
v.zoom = zoomRatio/(scale * 1.01);
};
var override = module.exports.override = function(v, data) {
for (var key in data) {
v[key] = data[key];
}
resolve(v);
};
var clone = module.exports.clone = function(v) {
return deserialize(serialize(v));
};
var serialize = module.exports.serialize = function(v) {
return JSON.stringify(v);
};
var deserialize = module.exports.deserialize = function(v) {
v = JSON.parse(v);
v.rotation = glm.mat4.clone(v.rotation);
return v;
};
var resolve = module.exports.resolve = function(v) {
v.dofStrength = clamp(0, 1, v.dofStrength);
v.dofPosition = clamp(0, 1, v.dofPosition);
v.zoom = clamp(0.001, 2.0, v.zoom);
v.atomScale = clamp(0, 1, v.atomScale);
v.relativeAtomScale = clamp(0, 1, v.relativeAtomScale);
v.bondScale = clamp(0, 1, v.bondScale);
v.bondShade = clamp(0, 1, v.bondShade);
v.atomShade = clamp(0, 1, v.atomShade);
v.ao = clamp(0, 1, v.ao);
v.brightness = clamp(0, 1, v.brightness);
v.outline = clamp(0, 1, v.outline);
};
var translate = module.exports.translate = function(v, dx, dy) {
v.translation.x -= dx/(v.resolution * v.zoom);
v.translation.y += dy/(v.resolution * v.zoom);
resolve(v);
};
var rotate = module.exports.rotate = function(v, dx, dy) {
var m = glm.mat4.create();
glm.mat4.rotateY(m, m, dx * 0.005);
glm.mat4.rotateX(m, m, dy * 0.005);
glm.mat4.multiply(v.rotation, m, v.rotation);
resolve(v);
};
var getRect = module.exports.getRect = function(v) {
var width = 1.0/v.zoom;
var height = width/v.aspect;
var bottom = -height/2 + v.translation.y;
var top = height/2 + v.translation.y;
var left = -width/2 + v.translation.x;
var right = width/2 + v.translation.x;
return {
bottom: bottom,
top: top,
left: left,
right: right
};
};
var getBondRadius = module.exports.getBondRadius = function(v) {
return v.bondScale * v.atomScale *
(1 + (consts.MIN_ATOM_RADIUS - 1) * v.relativeAtomScale);
};