All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jmol.util.GData Maven / Gradle / Ivy

There is a newer version: 14.31.10
Show newest version
package org.jmol.util;


import javajs.awt.Font;
import javajs.awt.GenericPlatform;
import javajs.util.AU;
import javajs.util.M3;
import javajs.util.P3;
import javajs.util.T3;
import javajs.util.V3;


import org.jmol.api.JmolGraphicsInterface;
import org.jmol.api.JmolRendererInterface;
import org.jmol.c.STER;
import org.jmol.viewer.Viewer;

public class GData implements JmolGraphicsInterface {

  public GenericPlatform apiPlatform;
  public boolean translucentCoverOnly;
  public boolean currentlyRendering;
  public boolean antialiasEnabled;
  
  protected int windowWidth, windowHeight;
  protected int displayMinX, displayMaxX, displayMinY, displayMaxY;
  protected int displayMinX2, displayMaxX2, displayMinY2, displayMaxY2;
  protected boolean antialiasThisFrame;

  protected boolean inGreyscaleMode;

  protected short[] changeableColixMap = new short[16];
  
  protected Object backgroundImage;
  
  protected int newWindowWidth, newWindowHeight;
  protected boolean newAntialiasing;

  public int bgcolor;  
  public int xLast, yLast;
  public int slab, depth;
  public int width, height;
  public int ambientOcclusion;

  protected short colixCurrent;
  public int argbCurrent;
  protected int ht3; // ht * 3, for cylinders
  public boolean isPass2;
  protected int textY;
  
  public int bufferSize;

  public Shader shader;

  protected Viewer vwr;

  public final static byte ENDCAPS_NONE = 0;
  public final static byte ENDCAPS_HIDDEN = 1; // no cap, but interior
  public final static byte ENDCAPS_FLAT = 2;
  public final static byte ENDCAPS_SPHERICAL = 3;
  public final static byte ENDCAPS_OPEN_TO_SPHERICAL = 4;
  public final static byte ENDCAPS_FLAT_TO_SPHERICAL = 5;
  
  /**
   * It is possible to instantiate this class with no Graphics3D. 
   * This will happen in the case of WebGL. 
   */
  public GData() {
    shader = new Shader();
  }
  
  public void initialize(Viewer vwr, GenericPlatform apiPlatform) {
    this.vwr = vwr;
    this.apiPlatform = apiPlatform;
  }

  /**
   * clipping from the front and the back
   *

* the plane is defined as a percentage from the back of the image to the * front *

* for depth values: *

    *
  • 0 means 100% is shown *
  • 25 means the back 25% is not shown *
  • 50 means the back half is not shown *
  • 100 means that nothing is shown *
*

* * @param depthValue * rear clipping percentage [0,100] */ public void setDepth(int depthValue) { depth = depthValue < 0 ? 0 : depthValue; } /** * clipping from the front and the back *

* the plane is defined as a percentage from the back of the image to the * front *

* For slab values: *

    *
  • 100 means 100% is shown *
  • 75 means the back 75% is shown *
  • 50 means the back half is shown *
  • 0 means that nothing is shown *
*

* * @param slabValue * front clipping percentage [0,100] */ @Override public void setSlab(int slabValue) { slab = Math.max(0, slabValue); } /** * @param zSlab * for zShade * @param zDepth * for zShade * @param zPower */ @Override public void setSlabAndZShade(int slab, int depth,int zSlab, int zDepth, int zPower) { setSlab(slab); setDepth(depth); } protected Object graphicsForMetrics; public final static int EXPORT_RAYTRACER = 2; public final static int EXPORT_CARTESIAN = 1; public final static int EXPORT_NOT = 0; public void setAmbientOcclusion(int value) { ambientOcclusion = value; } /** * is full scene / oversampling antialiasing in effect * * @return the answer */ @Override public boolean isAntialiased() { return antialiasThisFrame; } public short getChangeableColix(int id, int argb) { if (id >= changeableColixMap.length) changeableColixMap = AU.arrayCopyShort(changeableColixMap, id + 16); if (changeableColixMap[id] == 0) changeableColixMap[id] = C.getColix(argb); return (short) (id | C.CHANGEABLE_MASK); } public void changeColixArgb(int id, int argb) { if (id < changeableColixMap.length && changeableColixMap[id] != 0) changeableColixMap[id] = C.getColix(argb); } public int getColorArgbOrGray(short colix) { if (colix < 0) colix = changeableColixMap[colix & C.UNMASK_CHANGEABLE_TRANSLUCENT]; return (inGreyscaleMode ? C.getArgbGreyscale(colix) : C.getArgb(colix)); } public int[] getShades(short colix) { if (colix < 0) colix = changeableColixMap[colix & C.UNMASK_CHANGEABLE_TRANSLUCENT]; return (inGreyscaleMode ? shader.getShadesG(colix) : shader .getShades(colix)); } /** * controls greyscale rendering * * @param greyscaleMode * Flag for greyscale rendering */ public void setGreyscaleMode(boolean greyscaleMode) { this.inGreyscaleMode = greyscaleMode; } public int getSpecularPower() { return shader.specularPower; } /** * fractional distance to white for specular dot * * @param val */ public synchronized void setSpecularPower(int val) { if (val < 0) { setSpecularExponent(-val); return; } if (shader.specularPower == val) return; shader.specularPower = val; shader.intenseFraction = val / 100f; shader.flushCaches(); } public int getSpecularPercent() { return shader.specularPercent; } /** * sf in I = df * (N dot L) + sf * (R dot V)^p not a percent of anything, * really * * @param val */ public synchronized void setSpecularPercent(int val) { if (shader.specularPercent == val) return; shader.specularPercent = val; shader.specularFactor = val / 100f; shader.flushCaches(); } public int getSpecularExponent() { return shader.specularExponent; } /** * log_2(p) in I = df * (N dot L) + sf * (R dot V)^p for faster calculation of * shades * * @param val */ public synchronized void setSpecularExponent(int val) { if (shader.specularExponent == val) return; shader.specularExponent = val; shader.phongExponent = (int) Math.pow(2, val); shader.usePhongExponent = false; shader.flushCaches(); } public int getPhongExponent() { return shader.phongExponent; } /** * p in I = df * (N dot L) + sf * (R dot V)^p * * @param val */ public synchronized void setPhongExponent(int val) { if (shader.phongExponent == val && shader.usePhongExponent) return; shader.phongExponent = val; float x = (float) (Math.log(val) / Math.log(2)); shader.usePhongExponent = (x != (int) x); if (!shader.usePhongExponent) shader.specularExponent = (int) x; shader.flushCaches(); } public int getDiffusePercent() { return shader.diffusePercent; } /** * df in I = df * (N dot L) + sf * (R dot V)^p * * @param val */ public synchronized void setDiffusePercent(int val) { if (shader.diffusePercent == val) return; shader.diffusePercent = val; shader.diffuseFactor = val / 100f; shader.flushCaches(); } public int getAmbientPercent() { return shader.ambientPercent; } /** * fractional distance from black for ambient color * * @param val */ public synchronized void setAmbientPercent(int val) { if (shader.ambientPercent == val) return; shader.ambientPercent = val; shader.ambientFraction = val / 100f; shader.flushCaches(); } public boolean getSpecular() { return shader.specularOn; } public synchronized void setSpecular(boolean val) { if (shader.specularOn == val) return; shader.specularOn = val; shader.flushCaches(); } public void setCel(boolean val) { shader.setCel(val, shader.celPower, bgcolor); } public boolean getCel() { return shader.celOn; } public int getCelPower() { return shader.celPower; } public void setCelPower(int celPower) { shader.setCel(shader.celOn || shader.celPower == 0, celPower, bgcolor); } public V3 getLightSource() { return shader.lightSource; } public boolean isClipped3(int x, int y, int z) { // this is the one that could be augmented with slabPlane return (x < 0 || x >= width || y < 0 || y >= height || z < slab || z > depth); } public boolean isClipped(int x, int y) { return (x < 0 || x >= width || y < 0 || y >= height); } @Override public boolean isInDisplayRange(int x, int y) { return (x >= displayMinX && x < displayMaxX && y >= displayMinY && y < displayMaxY); } @Override public boolean isClippedXY(int diameter, int x, int y) { int r = (diameter + 1) >> 1; return (x < -r || x >= width + r || y < -r || y >= height + r); } public boolean isClippedZ(int z) { return (z != Integer.MIN_VALUE && (z < slab || z > depth)); } final public static int yGT = 1; final public static int yLT = 2; final public static int xGT = 4; final public static int xLT = 8; final public static int zGT = 16; final public static int zLT = 32; final public static int HUGE = -1; public int clipCode3(int x, int y, int z) { int code = 0; if (x < 0) code |= (x < displayMinX2 ? HUGE : xLT); else if (x >= width) code |= (x > displayMaxX2 ? HUGE : xGT); if (y < 0) code |= (y < displayMinY2 ? HUGE : yLT); else if (y >= height) code |= (y > displayMaxY2 ? HUGE : yGT); if (z < slab) code |= zLT; else if (z > depth) // note that this is .GT., not .GE. code |= zGT; return code; } public int clipCode(int z) { int code = 0; if (z < slab) code |= zLT; else if (z > depth) // note that this is .GT., not .GE. code |= zGT; return code; } /* *************************************************************** * fontID stuff * a fontID is a byte that contains the size + the face + the style * ***************************************************************/ public Font getFont3D(float fontSize) { return Font.createFont3D(Font.FONT_FACE_SANS, Font.FONT_STYLE_PLAIN, fontSize, fontSize, apiPlatform, graphicsForMetrics); } public Font getFont3DFS(String fontFace, float fontSize) { return Font.createFont3D(Font.getFontFaceID(fontFace), Font.FONT_STYLE_PLAIN, fontSize, fontSize, apiPlatform, graphicsForMetrics); } public byte getFontFidFS(String fontFace, float fontSize) { return getFont3DFSS(fontFace, "Bold", fontSize).fid; } public Font getFont3DFSS(String fontFace, String fontStyle, float fontSize) { int iStyle = Font.getFontStyleID(fontStyle); if (iStyle < 0) iStyle = 0; return Font.createFont3D(Font.getFontFaceID(fontFace), iStyle, fontSize, fontSize, apiPlatform, graphicsForMetrics); } public Font getFont3DScaled(Font font, float scale) { // TODO: problem here is that we are assigning a bold font, then not DEassigning it float newScale = font.fontSizeNominal * scale; return (newScale == font.fontSize ? font : Font.createFont3D( font.idFontFace, font.idFontStyle, newScale, font.fontSizeNominal, apiPlatform, graphicsForMetrics)); } public byte getFontFid(float fontSize) { return getFont3D(fontSize).fid; } /** * @param TF */ public void setBackgroundTransparent(boolean TF) { } /** * sets background color to the specified argb value * * @param argb an argb value with alpha channel */ public void setBackgroundArgb(int argb) { bgcolor = argb; setCel(shader.celOn); // background of Jmol transparent in front of certain applications (VLC Player) // when background [0,0,1]. } public void setBackgroundImage(Object image) { backgroundImage = image; } public void setWindowParameters(int width, int height, boolean antialias) { setWinParams(width, height, antialias); } protected void setWinParams(int width, int height, boolean antialias) { newWindowWidth = width; newWindowHeight = height; newAntialiasing = antialias; } public void setNewWindowParametersForExport() { windowWidth = newWindowWidth; windowHeight = newWindowHeight; setWidthHeight(false); } protected void setWidthHeight(boolean isAntialiased) { width = windowWidth; height = windowHeight; if (isAntialiased) { width <<= 1; height <<= 1; } xLast = width - 1; yLast = height - 1; displayMinX = -(width >> 1); displayMaxX = width - displayMinX; displayMinY = -(height >> 1); displayMaxY = height - displayMinY; displayMinX2 = displayMinX<<2; displayMaxX2 = displayMaxX<<2; displayMinY2 = displayMinY<<2; displayMaxY2 = displayMaxY<<2; ht3 = height * 3; bufferSize = width * height; } /** * @param stereoRotationMatrix * @param translucentMode * @param isImageWrite * @param renderLow TODO */ public void beginRendering(M3 stereoRotationMatrix, boolean translucentMode, boolean isImageWrite, boolean renderLow) { } public void endRendering() { } public void snapshotAnaglyphChannelBytes() { } /** * @param isImageWrite * @return image object */ public Object getScreenImage(boolean isImageWrite) { return null; } public void releaseScreenImage() { } /** * @param stereoMode * @param stereoColors */ public void applyAnaglygh(STER stereoMode, int[] stereoColors) { } /** * @param antialias * @return true if need a second (translucent) pass */ public boolean setPass2(boolean antialias) { return false; } public void destroy() { } public void clearFontCache() { } public void drawQuadrilateralBits(JmolRendererInterface jmolRenderer, short colix, P3 screenA, P3 screenB, P3 screenC, P3 screenD) { //mesh only -- translucency has been checked jmolRenderer.drawLineBits(colix, colix, screenA, screenB); jmolRenderer.drawLineBits(colix, colix, screenB, screenC); jmolRenderer.drawLineBits(colix, colix, screenC, screenD); jmolRenderer.drawLineBits(colix, colix, screenD, screenA); } public void drawTriangleBits(JmolRendererInterface renderer, P3 screenA, short colixA, P3 screenB, short colixB, P3 screenC, short colixC, int check) { // primary method for mapped Mesh if ((check & 1) == 1) renderer.drawLineBits(colixA, colixB, screenA, screenB); if ((check & 2) == 2) renderer.drawLineBits(colixB, colixC, screenB, screenC); if ((check & 4) == 4) renderer.drawLineBits(colixC, colixA, screenC, screenA); } /** * @param x * @param y * @param z * @param image * @param jmolRenderer * @param bgcolix * @param width * @param height * */ public void plotImage(int x, int y, int z, Object image, JmolRendererInterface jmolRenderer, short bgcolix, int width, int height) { } /** * @param x * @param y * @param z * @param colorArgbOrGray * @param bgColor TODO * @param text * @param font3d * @param jmolRenderer * */ public void plotText(int x, int y, int z, int colorArgbOrGray, int bgColor, String text, Font font3d, JmolRendererInterface jmolRenderer) { } /** * @param jmolRenderer */ public void renderBackground(JmolRendererInterface jmolRenderer) { } /** * @param font3d */ public void setFont(Font font3d) { } /** * @param fid */ public void setFontFid(byte fid) { } public int argbNoisyUp, argbNoisyDn; public void setColor(int argb) { argbCurrent = argbNoisyUp = argbNoisyDn = argb; } /** * @param colix * @return TRUE if correct pass (translucent or opaque) */ public boolean setC(short colix) { return true; } /** * @param normix * @return true if front */ public boolean isDirectedTowardsCamera(short normix) { // normix < 0 means a double sided normix, so always visible return (normix < 0) || (transformedVectors[normix].z > 0); } /** * JavaScript won't really have an integer here after integer division. * So we need to round it to the integer between it and zero. * * @param a * @return number closest to zero */ public static int roundInt(int a) { /** * @z2sNative * * return a < 0 ? Math.ceil(a) : Math.floor(a); * */ { return a; } } public void clear() { // only in Graphics3D } @Override public void renderAllStrings(Object jmolRenderer) { // only in Graphics3D } /** * @param tok */ public void addRenderer(int tok) { // needed for JavaScript implementation to avoid unnecessary core loading } /** * Used by Navigator, BioShapeRenderer, and DrawRenderer * * @param tension * @param p0 * @param p1 * @param p2 * @param p3 * @param p4 * @param list * @param index0 * @param n * @param isPt */ public static void getHermiteList(int tension, T3 p0, T3 p1, T3 p2, T3 p3, T3 p4, T3[] list, int index0, int n, boolean isPt) { //always deliver ONE MORE than one might expect, to provide a normal int nPoints = n + 1; float fnPoints = n - 1; float x1 = p1.x, y1 = p1.y, z1 = p1.z; float x2 = p2.x, y2 = p2.y, z2 = p2.z; float xT1 = ((x2 - p0.x) * tension) / 8; float yT1 = ((y2 - p0.y) * tension) / 8; float zT1 = ((z2 - p0.z) * tension) / 8; float xT2 = ((p3.x - x1) * tension) / 8; float yT2 = ((p3.y - y1) * tension) / 8; float zT2 = ((p3.z - z1) * tension) / 8; float xT3 = ((p4.x - x2) * tension) / 8; float yT3 = ((p4.y - y2) * tension) / 8; float zT3 = ((p4.z - z2) * tension) / 8; list[index0] = p1; for (int i = 0; i < nPoints; i++) { double s = i / fnPoints; if (i == nPoints - 1) { x1 = x2; y1 = y2; z1 = z2; x2 = p3.x; y2 = p3.y; z2 = p3.z; xT1 = xT2; yT1 = yT2; zT1 = zT2; xT2 = xT3; yT2 = yT3; zT2 = zT3; s -= 1; } double s2 = s * s; double s3 = s2 * s; double h1 = 2 * s3 - 3 * s2 + 1; double h2 = -2 * s3 + 3 * s2; double h3 = s3 - 2 * s2 + s; double h4 = s3 - s2; float x = (float) (h1 * x1 + h2 * x2 + h3 * xT1 + h4 * xT2); float y = (float) (h1 * y1 + h2 * y2 + h3 * yT1 + h4 * yT2); float z = (float) (h1 * z1 + h2 * z2 + h3 * zT1 + h4 * zT2); list[index0 + i] = (isPt ? P3.new3(x, y, z) : V3.new3(x, y, z)); } } public void setTextPosition(int y) { textY = y; } public int getTextPosition() { return textY; } protected V3[] transformedVectors = new V3[normixCount]; public V3[] getTransformedVertexVectors() { return transformedVectors; } protected static short normixCount = Normix.getNormixCount(); protected Font currentFont; public Font getFont3DCurrent() { return currentFont; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy