UNPKG

biojs-vis-pdbviewer

Version:

A BioJS 2.0 component to view protein structures

483 lines (481 loc) 16.3 kB
Clazz.declarePackage ("J.g3d"); Clazz.load (["java.util.Hashtable"], "J.g3d.LineRenderer", ["java.lang.Float", "JU.BS", "JU.Logger"], function () { c$ = Clazz.decorateAsClass (function () { this.g3d = null; this.shader = null; this.lineBits = null; this.slope = 0; this.lineTypeX = false; this.nBits = 0; this.nCached = 0; this.nFound = 0; this.lineCache = null; this.slopeKey = null; this.x1t = 0; this.y1t = 0; this.z1t = 0; this.x2t = 0; this.y2t = 0; this.z2t = 0; this.cc1 = 0; this.cc2 = 0; Clazz.instantialize (this, arguments); }, J.g3d, "LineRenderer"); Clazz.prepareFields (c$, function () { this.lineCache = new java.util.Hashtable (); }); Clazz.makeConstructor (c$, function (g3d) { this.g3d = g3d; this.shader = g3d.shader; }, "J.g3d.Graphics3D"); Clazz.defineMethod (c$, "setLineBits", function (dx, dy) { this.slope = (dx != 0 ? dy / dx : dy >= 0 ? 3.4028235E38 : -3.4028235E38); this.lineTypeX = (this.slope <= 1 && this.slope >= -1); this.nBits = (this.lineTypeX ? this.g3d.getRenderWidth () : this.g3d.getRenderHeight ()); if (this.getCachedLine ()) return; this.lineBits = JU.BS.newN (this.nBits); dy = Math.abs (dy); dx = Math.abs (dx); if (dy > dx) { var t = dx; dx = dy; dy = t; }var twoDError = 0; var twoDx = dx + dx; var twoDy = dy + dy; for (var i = 0; i < this.nBits; i++) { twoDError += twoDy; if (twoDError > dx) { this.lineBits.set (i); twoDError -= twoDx; }} this.lineCache.put (this.slopeKey, this.lineBits); this.nCached++; }, "~N,~N"); Clazz.defineMethod (c$, "clearLineCache", function () { this.lineCache.clear (); this.nCached = 0; }); Clazz.defineMethod (c$, "plotLine", function (argbA, tScreenedA, argbB, tScreenedB, xA, yA, zA, xB, yB, zB, clipped) { this.x1t = xA; this.x2t = xB; this.y1t = yA; this.y2t = yB; this.z1t = zA; this.z2t = zB; if (clipped) switch (this.getTrimmedLine ()) { case 0: clipped = false; break; case 2: return; } this.plotLineClipped (argbA, tScreenedA, argbB, tScreenedB, xA, yA, zA, xB - xA, yB - yA, zB - zA, clipped, 0, 0); }, "~N,~B,~N,~B,~N,~N,~N,~N,~N,~N,~B"); Clazz.defineMethod (c$, "plotLineDelta", function (argbA, tScreenedA, argbB, tScreenedB, xA, yA, zA, dxBA, dyBA, dzBA, clipped) { this.x1t = xA; this.x2t = xA + dxBA; this.y1t = yA; this.y2t = yA + dyBA; this.z1t = zA; this.z2t = zA + dzBA; if (clipped) switch (this.getTrimmedLine ()) { case 2: return; case 0: clipped = false; break; } this.plotLineClipped (argbA, tScreenedA, argbB, tScreenedB, xA, yA, zA, dxBA, dyBA, dzBA, clipped, 0, 0); }, "~N,~B,~N,~B,~N,~N,~N,~N,~N,~N,~B"); Clazz.defineMethod (c$, "plotLineDeltaA", function (shades1, tScreened1, shades2, tScreened2, shadeIndex, xA, yA, zA, dxBA, dyBA, dzBA, clipped) { this.x1t = xA; this.x2t = xA + dxBA; this.y1t = yA; this.y2t = yA + dyBA; this.z1t = zA; this.z2t = zA + dzBA; if (clipped) switch (this.getTrimmedLine ()) { case 2: return; case 0: clipped = false; } this.plotLineClippedA (shades1, tScreened1, shades2, tScreened2, shadeIndex, xA, yA, zA, dxBA, dyBA, dzBA, clipped, 0, 0); }, "~A,~B,~A,~B,~N,~N,~N,~N,~N,~N,~N,~B"); Clazz.defineMethod (c$, "plotLineDeltaBits", function (shades1, tScreened1, shades2, tScreened2, shadeIndex, xA, yA, zA, dxBA, dyBA, dzBA, clipped) { this.x1t = xA; this.x2t = xA + dxBA; this.y1t = yA; this.y2t = yA + dyBA; this.z1t = zA; this.z2t = zA + dzBA; if (clipped && this.getTrimmedLine () == 2) return; this.plotLineClippedBits (shades1, tScreened1, shades2, tScreened2, shadeIndex, xA, yA, zA, dxBA, dyBA, dzBA, 0, 0); }, "~A,~B,~A,~B,~N,~N,~N,~N,~N,~N,~N,~B"); Clazz.defineMethod (c$, "plotDashedLine", function (argb, tScreened, run, rise, xA, yA, zA, xB, yB, zB, clipped) { this.x1t = xA; this.x2t = xB; this.y1t = yA; this.y2t = yB; this.z1t = zA; this.z2t = zB; if (clipped) switch (this.getTrimmedLine ()) { case 2: return; case 0: clipped = false; break; } this.plotLineClipped (argb, tScreened, argb, tScreened, xA, yA, zA, xB - xA, yB - yA, zB - zA, clipped, run, rise); }, "~N,~B,~N,~N,~N,~N,~N,~N,~N,~N,~B"); Clazz.defineMethod (c$, "getCachedLine", function () { this.slopeKey = Float.$valueOf (this.slope); if (!this.lineCache.containsKey (this.slopeKey)) return false; this.lineBits = this.lineCache.get (this.slopeKey); if (JU.Logger.debugging) { this.nFound++; if (this.nFound == 1000000) JU.Logger.debug ("nCached/nFound lines: " + this.nCached + " " + this.nFound); }return true; }); Clazz.defineMethod (c$, "getTrimmedLine", function () { this.cc1 = this.g3d.clipCode3 (this.x1t, this.y1t, this.z1t); this.cc2 = this.g3d.clipCode3 (this.x2t, this.y2t, this.z2t); if ((this.cc1 | this.cc2) == 0) return 0; var xLast = this.g3d.xLast; var yLast = this.g3d.yLast; var slab = this.g3d.slab; var depth = this.g3d.depth; do { if ((this.cc1 & this.cc2) != 0) return 2; var dx = this.x2t - this.x1t; var dy = this.y2t - this.y1t; var dz = this.z2t - this.z1t; if (this.cc1 != 0) { if ((this.cc1 & 8) != 0) { this.y1t += Clazz.floatToInt ((-this.x1t * dy) / dx); this.z1t += Clazz.floatToInt ((-this.x1t * dz) / dx); this.x1t = 0; } else if ((this.cc1 & 4) != 0) { this.y1t += Clazz.floatToInt (((xLast - this.x1t) * dy) / dx); this.z1t += Clazz.floatToInt (((xLast - this.x1t) * dz) / dx); this.x1t = xLast; } else if ((this.cc1 & 2) != 0) { this.x1t += Clazz.floatToInt ((-this.y1t * dx) / dy); this.z1t += Clazz.floatToInt ((-this.y1t * dz) / dy); this.y1t = 0; } else if ((this.cc1 & 1) != 0) { this.x1t += Clazz.floatToInt (((yLast - this.y1t) * dx) / dy); this.z1t += Clazz.floatToInt (((yLast - this.y1t) * dz) / dy); this.y1t = yLast; } else if ((this.cc1 & 32) != 0) { this.x1t += Clazz.floatToInt (((slab - this.z1t) * dx) / dz); this.y1t += Clazz.floatToInt (((slab - this.z1t) * dy) / dz); this.z1t = slab; } else { this.x1t += Clazz.floatToInt (((depth - this.z1t) * dx) / dz); this.y1t += Clazz.floatToInt (((depth - this.z1t) * dy) / dz); this.z1t = depth; }this.cc1 = this.g3d.clipCode3 (this.x1t, this.y1t, this.z1t); } else { if ((this.cc2 & 8) != 0) { this.y2t += Clazz.floatToInt ((-this.x2t * dy) / dx); this.z2t += Clazz.floatToInt ((-this.x2t * dz) / dx); this.x2t = 0; } else if ((this.cc2 & 4) != 0) { this.y2t += Clazz.floatToInt (((xLast - this.x2t) * dy) / dx); this.z2t += Clazz.floatToInt (((xLast - this.x2t) * dz) / dx); this.x2t = xLast; } else if ((this.cc2 & 2) != 0) { this.x2t += Clazz.floatToInt ((-this.y2t * dx) / dy); this.z2t += Clazz.floatToInt ((-this.y2t * dz) / dy); this.y2t = 0; } else if ((this.cc2 & 1) != 0) { this.x2t += Clazz.floatToInt (((yLast - this.y2t) * dx) / dy); this.z2t += Clazz.floatToInt (((yLast - this.y2t) * dz) / dy); this.y2t = yLast; } else if ((this.cc2 & 32) != 0) { this.x2t += Clazz.floatToInt (((slab - this.z2t) * dx) / dz); this.y2t += Clazz.floatToInt (((slab - this.z2t) * dy) / dz); this.z2t = slab; } else { this.x2t += Clazz.floatToInt (((depth - this.z2t) * dx) / dz); this.y2t += Clazz.floatToInt (((depth - this.z2t) * dy) / dz); this.z2t = depth; }this.cc2 = this.g3d.clipCode3 (this.x2t, this.y2t, this.z2t); }} while ((this.cc1 | this.cc2) != 0); return 1; }); Clazz.defineMethod (c$, "plotLineClipped", function (argb1, tScreened1, argb2, tScreened2, x, y, z, dx, dy, dz, clipped, run, rise) { var zbuf = this.g3d.zbuf; var width = this.g3d.getRenderWidth (); var runIndex = 0; if (run == 0) { rise = 2147483647; run = 1; }var offset = y * width + x; var offsetMax = this.g3d.bufferSize; var flipflop = (((x ^ y) & 1) != 0); var tScreened = tScreened1; var argb = argb1; if (argb != 0 && !clipped && offset >= 0 && offset < offsetMax && z < zbuf[offset] && (!tScreened || (flipflop = !flipflop))) { this.g3d.addPixel (offset, z, argb); }if (dx == 0 && dy == 0) { return; }var xIncrement = 1; var yOffsetIncrement = width; var x2 = x + dx; var y2 = y + dy; if (dx < 0) { dx = -dx; xIncrement = -1; }if (dy < 0) { dy = -dy; yOffsetIncrement = -width; }var twoDx = dx + dx; var twoDy = dy + dy; var zCurrentScaled = z << 10; if (dy <= dx) { var roundingFactor = dx - 1; if (dz < 0) roundingFactor = -roundingFactor; var zIncrementScaled = Clazz.doubleToInt (((dz << 10) + roundingFactor) / dx); var twoDxAccumulatedYError = 0; var n1 = Math.abs (x2 - this.x2t) - 1; var n2 = Math.abs (x2 - this.x1t) - 1; for (var n = dx - 1, nMid = Clazz.doubleToInt (n / 2); --n >= n1; ) { if (n == nMid) { tScreened = tScreened2; argb = argb2; if (argb == 0) return; }offset += xIncrement; zCurrentScaled += zIncrementScaled; twoDxAccumulatedYError += twoDy; if (twoDxAccumulatedYError > dx) { offset += yOffsetIncrement; twoDxAccumulatedYError -= twoDx; flipflop = !flipflop; }if (argb != 0 && n < n2 && offset >= 0 && offset < offsetMax && runIndex < rise && (!tScreened || (flipflop = !flipflop))) { var zCurrent = zCurrentScaled >> 10; if (zCurrent < zbuf[offset]) this.g3d.addPixel (offset, zCurrent, argb); }runIndex = (runIndex + 1) % run; } } else { var roundingFactor = dy - 1; if (dz < 0) roundingFactor = -roundingFactor; var zIncrementScaled = Clazz.doubleToInt (((dz << 10) + roundingFactor) / dy); var twoDyAccumulatedXError = 0; var n1 = Math.abs (y2 - this.y2t) - 1; var n2 = Math.abs (y2 - this.y1t) - 1; for (var n = dy - 1, nMid = Clazz.doubleToInt (n / 2); --n >= n1; ) { if (n == nMid) { tScreened = tScreened2; argb = argb2; if (argb == 0) return; }offset += yOffsetIncrement; zCurrentScaled += zIncrementScaled; twoDyAccumulatedXError += twoDx; if (twoDyAccumulatedXError > dy) { offset += xIncrement; twoDyAccumulatedXError -= twoDy; flipflop = !flipflop; }if (argb != 0 && n < n2 && offset >= 0 && offset < offsetMax && runIndex < rise && (!tScreened || (flipflop = !flipflop))) { var zCurrent = zCurrentScaled >> 10; if (zCurrent < zbuf[offset]) this.g3d.addPixel (offset, zCurrent, argb); }runIndex = (runIndex + 1) % run; } }}, "~N,~B,~N,~B,~N,~N,~N,~N,~N,~N,~B,~N,~N"); Clazz.defineMethod (c$, "plotLineClippedA", function (shades1, tScreened1, shades2, tScreened2, shadeIndex, x, y, z, dx, dy, dz, clipped, run, rise) { var zbuf = this.g3d.zbuf; var width = this.g3d.getRenderWidth (); var runIndex = 0; if (run == 0) { rise = 2147483647; run = 1; }var offset = y * width + x; var offsetMax = this.g3d.bufferSize; var shadeIndexUp = (shadeIndex < 63 ? shadeIndex + 1 : shadeIndex); var shadeIndexDn = (shadeIndex > 0 ? shadeIndex - 1 : shadeIndex); var argb1 = shades1[shadeIndex]; var argb1Up = shades1[shadeIndexUp]; var argb1Dn = shades1[shadeIndexDn]; var argb2 = shades2[shadeIndex]; var argb2Up = shades2[shadeIndexUp]; var argb2Dn = shades2[shadeIndexDn]; var argb = argb1; var tScreened = tScreened1; var flipflop = (((x ^ y) & 1) != 0); if (argb != 0 && !clipped && offset >= 0 && offset < offsetMax && z < zbuf[offset] && (!tScreened || (flipflop = !flipflop))) this.g3d.addPixel (offset, z, argb); if (dx == 0 && dy == 0) { return; }var xIncrement = 1; var yOffsetIncrement = width; var x2 = x + dx; var y2 = y + dy; if (dx < 0) { dx = -dx; xIncrement = -1; }if (dy < 0) { dy = -dy; yOffsetIncrement = -width; }var twoDx = dx + dx; var twoDy = dy + dy; var zCurrentScaled = z << 10; var argbUp = argb1Up; var argbDn = argb1Dn; if (dy <= dx) { var roundingFactor = dx - 1; if (dz < 0) roundingFactor = -roundingFactor; var zIncrementScaled = Clazz.doubleToInt (((dz << 10) + roundingFactor) / dx); var twoDxAccumulatedYError = 0; var n1 = Math.abs (x2 - this.x2t) - 1; var n2 = Math.abs (x2 - this.x1t) - 1; for (var n = dx - 1, nMid = Clazz.doubleToInt (n / 2); --n >= n1; ) { if (n == nMid) { argb = argb2; if (argb == 0) return; argbUp = argb2Up; argbDn = argb2Dn; tScreened = tScreened2; if (tScreened && !tScreened1) { var yT = Clazz.doubleToInt (offset / width); var xT = offset % width; flipflop = ((xT ^ yT) & 1) == 0; }}offset += xIncrement; zCurrentScaled += zIncrementScaled; twoDxAccumulatedYError += twoDy; if (twoDxAccumulatedYError > dx) { offset += yOffsetIncrement; twoDxAccumulatedYError -= twoDx; flipflop = !flipflop; }if (argb != 0 && n < n2 && offset >= 0 && offset < offsetMax && runIndex < rise && (!tScreened || (flipflop = !flipflop))) { var zCurrent = zCurrentScaled >> 10; if (zCurrent < zbuf[offset]) { var rand8 = this.shader.nextRandom8Bit (); this.g3d.addPixel (offset, zCurrent, rand8 < 85 ? argbDn : (rand8 > 170 ? argbUp : argb)); }}runIndex = (runIndex + 1) % run; } } else { var roundingFactor = dy - 1; if (dz < 0) roundingFactor = -roundingFactor; var zIncrementScaled = Clazz.doubleToInt (((dz << 10) + roundingFactor) / dy); var twoDyAccumulatedXError = 0; var n1 = Math.abs (y2 - this.y2t) - 1; var n2 = Math.abs (y2 - this.y1t) - 1; for (var n = dy - 1, nMid = Clazz.doubleToInt (n / 2); --n >= n1; ) { if (n == nMid) { argb = argb2; if (argb == 0) return; argbUp = argb2Up; argbDn = argb2Dn; tScreened = tScreened2; if (tScreened && !tScreened1) { var yT = Clazz.doubleToInt (offset / width); var xT = offset % width; flipflop = ((xT ^ yT) & 1) == 0; }}offset += yOffsetIncrement; zCurrentScaled += zIncrementScaled; twoDyAccumulatedXError += twoDx; if (twoDyAccumulatedXError > dy) { offset += xIncrement; twoDyAccumulatedXError -= twoDy; flipflop = !flipflop; }if (argb != 0 && n < n2 && offset >= 0 && offset < offsetMax && runIndex < rise && (!tScreened || (flipflop = !flipflop))) { var zCurrent = zCurrentScaled >> 10; if (zCurrent < zbuf[offset]) { var rand8 = this.g3d.shader.nextRandom8Bit (); this.g3d.addPixel (offset, zCurrent, rand8 < 85 ? argbDn : (rand8 > 170 ? argbUp : argb)); }}runIndex = (runIndex + 1) % run; } }}, "~A,~B,~A,~B,~N,~N,~N,~N,~N,~N,~N,~B,~N,~N"); Clazz.defineMethod (c$, "plotLineClippedBits", function (shades1, tScreened1, shades2, tScreened2, shadeIndex, x, y, z, dx, dy, dz, run, rise) { var zbuf = this.g3d.zbuf; var width = this.g3d.width; var runIndex = 0; if (run == 0) { rise = 2147483647; run = 1; }var shadeIndexUp = (shadeIndex < 63 ? shadeIndex + 1 : shadeIndex); var shadeIndexDn = (shadeIndex > 0 ? shadeIndex - 1 : shadeIndex); var argb1 = shades1[shadeIndex]; var argb1Up = shades1[shadeIndexUp]; var argb1Dn = shades1[shadeIndexDn]; var argb2 = shades2[shadeIndex]; var argb2Up = shades2[shadeIndexUp]; var argb2Dn = shades2[shadeIndexDn]; var tScreened = tScreened1; var flipflop = (((x ^ y) & 1) != 0); var offset = y * width + x; var offsetMax = this.g3d.bufferSize; var i0; var iMid; var i1; var i2; var iIncrement; var xIncrement; var yIncrement; var zIncrement; if (this.lineTypeX) { i0 = x; i1 = this.x1t; i2 = this.x2t; iMid = x + Clazz.doubleToInt (dx / 2); iIncrement = (dx >= 0 ? 1 : -1); xIncrement = iIncrement; yIncrement = (dy >= 0 ? width : -width); zIncrement = dz / Math.abs (dx); } else { i0 = y; i1 = this.y1t; i2 = this.y2t; iMid = y + Clazz.doubleToInt (dy / 2); iIncrement = (dy >= 0 ? 1 : -1); xIncrement = (dy >= 0 ? width : -width); yIncrement = (dx >= 0 ? 1 : -1); zIncrement = dz / Math.abs (dy); }var zFloat = z; var argb = argb1; var argbUp = argb1Up; var argbDn = argb1Dn; var isInWindow = false; for (var i = i0, iBits = i0; ; i += iIncrement, iBits += iIncrement) { if (i == i1) isInWindow = true; if (i == iMid) { argb = argb2; if (argb == 0) return; argbUp = argb2Up; argbDn = argb2Dn; tScreened = tScreened2; if (tScreened && !tScreened1) { var yT = Clazz.doubleToInt (offset / width); var xT = offset % width; flipflop = ((xT ^ yT) & 1) == 0; }}if (argb != 0 && isInWindow && offset >= 0 && offset < offsetMax && runIndex < rise && (!tScreened || (flipflop = !flipflop))) { if (zFloat < zbuf[offset]) { var rand8 = this.shader.nextRandom8Bit (); this.g3d.addPixel (offset, Clazz.floatToInt (zFloat), rand8 < 85 ? argbDn : (rand8 > 170 ? argbUp : argb)); }}if (i == i2) break; runIndex = (runIndex + 1) % run; offset += xIncrement; while (iBits < 0) iBits += this.nBits; if (this.lineBits.get (iBits % this.nBits)) offset += yIncrement; zFloat += zIncrement; } }, "~A,~B,~A,~B,~N,~N,~N,~N,~N,~N,~N,~N,~N"); Clazz.defineStatics (c$, "VISIBILITY_UNCLIPPED", 0, "VISIBILITY_CLIPPED", 1, "VISIBILITY_OFFSCREEN", 2); });