UNPKG

biojs-vis-pdbviewer

Version:

A BioJS 2.0 component to view protein structures

363 lines (361 loc) 12.1 kB
Clazz.declarePackage ("J.g3d"); Clazz.load (["J.g3d.G3DRenderer", "JU.P3", "$.V3"], "J.g3d.HermiteRenderer", ["JU.Lst", "$.P3i", "JU.Point3fi"], function () { c$ = Clazz.decorateAsClass (function () { this.g3d = null; this.pLeft = null; this.pRight = null; this.sLeft = null; this.sRight = null; this.pTopLeft = null; this.pTopRight = null; this.pBotLeft = null; this.pBotRight = null; this.a1 = null; this.a2 = null; this.b1 = null; this.b2 = null; this.c1 = null; this.c2 = null; this.d1 = null; this.d2 = null; this.T1 = null; this.T2 = null; this.depth1 = null; this.needToFill = null; Clazz.instantialize (this, arguments); }, J.g3d, "HermiteRenderer", null, J.g3d.G3DRenderer); Clazz.prepareFields (c$, function () { this.pLeft = new Array (16); this.pRight = new Array (16); this.sLeft = Clazz.newFloatArray (16, 0); this.sRight = Clazz.newFloatArray (16, 0); this.pTopLeft = new Array (16); this.pTopRight = new Array (16); this.pBotLeft = new Array (16); this.pBotRight = new Array (16); { for (var i = 16; --i >= 0; ) { this.pLeft[i] = new JU.P3i (); this.pRight[i] = new JU.P3i (); this.pTopLeft[i] = new JU.P3 (); this.pTopRight[i] = new JU.P3 (); this.pBotLeft[i] = new JU.P3 (); this.pBotRight[i] = new JU.P3 (); } }this.a1 = new JU.P3 (); this.a2 = new JU.P3 (); this.b1 = new JU.P3 (); this.b2 = new JU.P3 (); this.c1 = new JU.P3 (); this.c2 = new JU.P3 (); this.d1 = new JU.P3 (); this.d2 = new JU.P3 (); this.T1 = new JU.V3 (); this.T2 = new JU.V3 (); this.depth1 = new JU.V3 (); this.needToFill = Clazz.newBooleanArray (16, false); }); Clazz.makeConstructor (c$, function () { }); Clazz.overrideMethod (c$, "set", function (g3d) { this.g3d = g3d; return this; }, "J.api.JmolRendererInterface"); Clazz.defineMethod (c$, "renderHermiteRope", function (fill, tension, diameterBeg, diameterMid, diameterEnd, p0, p1, p2, p3) { if (p0.z == 1 || p1.z == 1 || p2.z == 1 || p3.z == 1) return; if (this.g3d.isClippedZ (p1.z) || this.g3d.isClippedZ (p2.z)) return; var x1 = p1.x; var y1 = p1.y; var z1 = p1.z; var x2 = p2.x; var y2 = p2.y; var z2 = p2.z; var xT1 = Clazz.doubleToInt (((x2 - p0.x) * tension) / 8); var yT1 = Clazz.doubleToInt (((y2 - p0.y) * tension) / 8); var zT1 = Clazz.doubleToInt (((z2 - p0.z) * tension) / 8); var xT2 = Clazz.doubleToInt (((p3.x - x1) * tension) / 8); var yT2 = Clazz.doubleToInt (((p3.y - y1) * tension) / 8); var zT2 = Clazz.doubleToInt (((p3.z - z1) * tension) / 8); this.sLeft[0] = 0; this.pLeft[0].setT (p1); this.sRight[0] = 1; this.pRight[0].setT (p2); var sp = 0; var dDiameterFirstHalf = 0; var dDiameterSecondHalf = 0; if (fill) { dDiameterFirstHalf = 2 * (diameterMid - diameterBeg); dDiameterSecondHalf = 2 * (diameterEnd - diameterMid); }do { var a = this.pLeft[sp]; var b = this.pRight[sp]; var dx = b.x - a.x; if (dx >= -1 && dx <= 1) { var dy = b.y - a.y; if (dy >= -1 && dy <= 1) { var s = this.sLeft[sp]; if (fill) { var d = (s < 0.5 ? diameterBeg + Clazz.floatToInt (dDiameterFirstHalf * s) : diameterMid + Clazz.floatToInt (dDiameterSecondHalf * (s - 0.5))); this.g3d.fillSphereI (d, a); } else { this.g3d.plotPixelClippedP3i (a); }--sp; continue; }}var s = (this.sLeft[sp] + this.sRight[sp]) / 2; var s2 = s * s; var s3 = s2 * s; var h1 = 2 * s3 - 3 * s2 + 1; var h2 = -2 * s3 + 3 * s2; var h3 = s3 - 2 * s2 + s; var h4 = s3 - s2; if (sp >= 15) break; var pMid = this.pRight[sp + 1]; pMid.x = Clazz.doubleToInt (h1 * x1 + h2 * x2 + h3 * xT1 + h4 * xT2); pMid.y = Clazz.doubleToInt (h1 * y1 + h2 * y2 + h3 * yT1 + h4 * yT2); pMid.z = Clazz.doubleToInt (h1 * z1 + h2 * z2 + h3 * zT1 + h4 * zT2); this.pRight[sp + 1] = this.pRight[sp]; this.sRight[sp + 1] = this.sRight[sp]; this.pRight[sp] = pMid; this.sRight[sp] = s; ++sp; this.pLeft[sp].setT (pMid); this.sLeft[sp] = s; } while (sp >= 0); }, "~B,~N,~N,~N,~N,JU.P3i,JU.P3i,JU.P3i,JU.P3i"); Clazz.defineMethod (c$, "renderHermiteRibbon", function (fill, border, tension, p0, p1, p2, p3, p4, p5, p6, p7, aspectRatio, fillType) { if (p0.z == 1 || p1.z == 1 || p2.z == 1 || p3.z == 1 || p4.z == 1 || p5.z == 1 || p6.z == 1 || p7.z == 1) return; if (!fill) { tension = Math.abs (tension); this.renderParallelPair (fill, tension, p0, p1, p2, p3, p4, p5, p6, p7); return; }var isRev = (tension < 0); if (isRev) tension = -tension; var ratio = 1 / aspectRatio; var x1 = p1.x; var y1 = p1.y; var z1 = p1.z; var x2 = p2.x; var y2 = p2.y; var z2 = p2.z; var xT1 = Clazz.doubleToInt (((x2 - p0.x) * tension) / 8); var yT1 = Clazz.doubleToInt (((y2 - p0.y) * tension) / 8); var zT1 = Clazz.doubleToInt (((z2 - p0.z) * tension) / 8); var xT2 = Clazz.doubleToInt (((p3.x - x1) * tension) / 8); var yT2 = Clazz.doubleToInt (((p3.y - y1) * tension) / 8); var zT2 = Clazz.doubleToInt (((p3.z - z1) * tension) / 8); JU.Point3fi.set2 (this.pTopLeft[0], p1); JU.Point3fi.set2 (this.pTopRight[0], p2); var x5 = p5.x; var y5 = p5.y; var z5 = p5.z; var x6 = p6.x; var y6 = p6.y; var z6 = p6.z; var xT5 = Clazz.doubleToInt (((x6 - p4.x) * tension) / 8); var yT5 = Clazz.doubleToInt (((y6 - p4.y) * tension) / 8); var zT5 = Clazz.doubleToInt (((z6 - p4.z) * tension) / 8); var xT6 = Clazz.doubleToInt (((p7.x - x5) * tension) / 8); var yT6 = Clazz.doubleToInt (((p7.y - y5) * tension) / 8); var zT6 = Clazz.doubleToInt (((p7.z - z5) * tension) / 8); JU.Point3fi.set2 (this.pBotLeft[0], p5); JU.Point3fi.set2 (this.pBotRight[0], p6); this.sLeft[0] = 0; this.sRight[0] = 1; this.needToFill[0] = true; var sp = 0; var closeEnd = false; do { var a = this.pTopLeft[sp]; var b = this.pTopRight[sp]; var dxTop = b.x - a.x; var dxTop2 = dxTop * dxTop; if (dxTop2 < 10) { var dyTop = b.y - a.y; var dyTop2 = dyTop * dyTop; if (dyTop2 < 10) { var c = this.pBotLeft[sp]; var d = this.pBotRight[sp]; var dxBot = d.x - c.x; var dxBot2 = dxBot * dxBot; if (dxBot2 < 8) { var dyBot = d.y - c.y; var dyBot2 = dyBot * dyBot; if (dyBot2 < 8) { if (border) { this.g3d.fillSphere (3, a); this.g3d.fillSphere (3, c); }if (this.needToFill[sp]) { if (aspectRatio > 0) { this.T1.sub2 (a, c); this.T1.scale (ratio); this.T2.sub2 (a, b); this.depth1.cross (this.T1, this.T2); this.depth1.scale (this.T1.length () / this.depth1.length ()); this.a1.add2 (a, this.depth1); this.a2.sub2 (a, this.depth1); this.b1.add2 (b, this.depth1); this.b2.sub2 (b, this.depth1); this.c1.add2 (c, this.depth1); this.c2.sub2 (c, this.depth1); this.d1.add2 (d, this.depth1); this.d2.sub2 (d, this.depth1); this.g3d.fillQuadrilateral (this.a1, this.b1, this.d1, this.c1); this.g3d.fillQuadrilateral (this.a2, this.b2, this.d2, this.c2); this.g3d.fillQuadrilateral (this.a1, this.b1, this.b2, this.a2); this.g3d.fillQuadrilateral (this.c1, this.d1, this.d2, this.c2); closeEnd = true; } else { if (fillType == 0) { if (isRev) this.g3d.fillQuadrilateral (c, d, b, a); else this.g3d.fillQuadrilateral (a, b, d, c); } else { if (isRev) { if (fillType != J.g3d.HermiteRenderer.isFront (a, b, d)) this.g3d.fillTriangle3f (a, b, d, false); if (fillType != J.g3d.HermiteRenderer.isFront (a, d, c)) this.g3d.fillTriangle3f (a, d, c, false); } else { if (fillType == J.g3d.HermiteRenderer.isFront (a, b, d)) this.g3d.fillTriangle3f (a, b, d, false); if (fillType == J.g3d.HermiteRenderer.isFront (a, d, c)) this.g3d.fillTriangle3f (a, d, c, false); }}}this.needToFill[sp] = false; }if (dxTop2 + dyTop2 < 2 && dxBot2 + dyBot2 < 2) { --sp; continue; }}}}}var s = (this.sLeft[sp] + this.sRight[sp]) / 2; var s2 = s * s; var s3 = s2 * s; var h1 = 2 * s3 - 3 * s2 + 1; var h2 = -2 * s3 + 3 * s2; var h3 = s3 - 2 * s2 + s; var h4 = s3 - s2; if (sp >= 15) break; var spNext = sp + 1; var pMidTop = this.pTopRight[spNext]; pMidTop.x = (h1 * x1 + h2 * x2 + h3 * xT1 + h4 * xT2); pMidTop.y = (h1 * y1 + h2 * y2 + h3 * yT1 + h4 * yT2); pMidTop.z = (h1 * z1 + h2 * z2 + h3 * zT1 + h4 * zT2); var pMidBot = this.pBotRight[spNext]; pMidBot.x = (h1 * x5 + h2 * x6 + h3 * xT5 + h4 * xT6); pMidBot.y = (h1 * y5 + h2 * y6 + h3 * yT5 + h4 * yT6); pMidBot.z = (h1 * z5 + h2 * z6 + h3 * zT5 + h4 * zT6); this.pTopRight[spNext] = this.pTopRight[sp]; this.pTopRight[sp] = pMidTop; this.pBotRight[spNext] = this.pBotRight[sp]; this.pBotRight[sp] = pMidBot; this.sRight[spNext] = this.sRight[sp]; this.sRight[sp] = s; this.needToFill[spNext] = this.needToFill[sp]; this.pTopLeft[spNext].setT (pMidTop); this.pBotLeft[spNext].setT (pMidBot); this.sLeft[spNext] = s; ++sp; } while (sp >= 0); if (closeEnd) { this.a1.z += 1; this.c1.z += 1; this.c2.z += 1; this.a2.z += 1; this.g3d.fillQuadrilateral (this.a1, this.c1, this.c2, this.a2); }}, "~B,~B,~N,JU.P3i,JU.P3i,JU.P3i,JU.P3i,JU.P3i,JU.P3i,JU.P3i,JU.P3i,~N,~N"); c$.isFront = Clazz.defineMethod (c$, "isFront", function (a, b, c) { J.g3d.HermiteRenderer.vAB.sub2 (b, a); J.g3d.HermiteRenderer.vAC.sub2 (c, a); J.g3d.HermiteRenderer.vAB.cross (J.g3d.HermiteRenderer.vAB, J.g3d.HermiteRenderer.vAC); return (J.g3d.HermiteRenderer.vAB.z < 0 ? -1 : 1); }, "JU.P3,JU.P3,JU.P3"); Clazz.defineMethod (c$, "renderParallelPair", function (fill, tension, p0, p1, p2, p3, p4, p5, p6, p7) { var endPoints = [p2, p1, p6, p5]; var points = new JU.Lst (); var whichPoint = 0; var numTopStrandPoints = 2; var numPointsPerSegment = 5.0; var interval = (1.0 / numPointsPerSegment); var currentInt = 0.0; var x1 = p1.x; var y1 = p1.y; var z1 = p1.z; var x2 = p2.x; var y2 = p2.y; var z2 = p2.z; var xT1 = Clazz.doubleToInt (((x2 - p0.x) * tension) / 8); var yT1 = Clazz.doubleToInt (((y2 - p0.y) * tension) / 8); var zT1 = Clazz.doubleToInt (((z2 - p0.z) * tension) / 8); var xT2 = Clazz.doubleToInt (((p3.x - x1) * tension) / 8); var yT2 = Clazz.doubleToInt (((p3.y - y1) * tension) / 8); var zT2 = Clazz.doubleToInt (((p3.z - z1) * tension) / 8); this.sLeft[0] = 0; this.pLeft[0].setT (p1); this.sRight[0] = 1; this.pRight[0].setT (p2); var sp = 0; for (var strands = 2; strands > 0; strands--) { if (strands == 1) { x1 = p5.x; y1 = p5.y; z1 = p5.z; x2 = p6.x; y2 = p6.y; z2 = p6.z; xT1 = Clazz.doubleToInt (((x2 - p4.x) * tension) / 8); yT1 = Clazz.doubleToInt (((y2 - p4.y) * tension) / 8); zT1 = Clazz.doubleToInt (((z2 - p4.z) * tension) / 8); xT2 = Clazz.doubleToInt (((p7.x - x1) * tension) / 8); yT2 = Clazz.doubleToInt (((p7.y - y1) * tension) / 8); zT2 = Clazz.doubleToInt (((p7.z - z1) * tension) / 8); this.sLeft[0] = 0; this.pLeft[0].setT (p5); this.sRight[0] = 1; this.pRight[0].setT (p6); sp = 0; }points.addLast (endPoints[whichPoint++]); currentInt = interval; do { var a = this.pLeft[sp]; var b = this.pRight[sp]; var dx = b.x - a.x; var dy = b.y - a.y; var dist2 = dx * dx + dy * dy; if (dist2 <= 2) { var s = this.sLeft[sp]; this.g3d.fillSphereI (3, a); if (s < 1.0 - currentInt) { var temp = new JU.P3i (); temp.setT (a); points.addLast (temp); currentInt += interval; if (strands == 2) { numTopStrandPoints++; }}--sp; } else { var s = (this.sLeft[sp] + this.sRight[sp]) / 2; var s2 = s * s; var s3 = s2 * s; var h1 = 2 * s3 - 3 * s2 + 1; var h2 = -2 * s3 + 3 * s2; var h3 = s3 - 2 * s2 + s; var h4 = s3 - s2; if (sp >= 15) break; var pMid = this.pRight[sp + 1]; pMid.x = Clazz.doubleToInt (h1 * x1 + h2 * x2 + h3 * xT1 + h4 * xT2); pMid.y = Clazz.doubleToInt (h1 * y1 + h2 * y2 + h3 * yT1 + h4 * yT2); pMid.z = Clazz.doubleToInt (h1 * z1 + h2 * z2 + h3 * zT1 + h4 * zT2); this.pRight[sp + 1] = this.pRight[sp]; this.sRight[sp + 1] = this.sRight[sp]; this.pRight[sp] = pMid; this.sRight[sp] = s; ++sp; this.pLeft[sp].setT (pMid); this.sLeft[sp] = s; }} while (sp >= 0); points.addLast (endPoints[whichPoint++]); } var size = points.size (); for (var top = 0; top < numTopStrandPoints && (top + numTopStrandPoints) < size; top++) this.g3d.drawLineAB (points.get (top), points.get (top + numTopStrandPoints)); }, "~B,~N,JU.P3i,JU.P3i,JU.P3i,JU.P3i,JU.P3i,JU.P3i,JU.P3i,JU.P3i"); c$.vAB = c$.prototype.vAB = new JU.V3 (); c$.vAC = c$.prototype.vAC = new JU.V3 (); });