Package org.jmol.shapebio

Source Code of org.jmol.shapebio.RocketsRenderer

/* $RCSfile$
* $Author: hansonr $
* $Date: 2007-03-11 14:30:16 -0500 (Sun, 11 Mar 2007) $
* $Revision: 7068 $
*
* Copyright (C) 2003-2005  The Jmol Development Team
*
* Contact: jmol-developers@lists.sf.net
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/

package org.jmol.shapebio;

import org.jmol.g3d.Graphics3D;
import org.jmol.modelsetbio.AminoPolymer;
import org.jmol.modelsetbio.Helix;
import org.jmol.modelsetbio.Monomer;
import org.jmol.modelsetbio.ProteinStructure;
import org.jmol.modelsetbio.Sheet;
import org.jmol.viewer.JmolConstants;

import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

public class RocketsRenderer extends BioShapeRenderer {

  private final static float MIN_CONE_HEIGHT = 0.05f;

  protected boolean renderArrowHeads;

  protected void renderBioShape(BioShape bioShape) {
    if (!(bioShape.bioPolymer instanceof AminoPolymer))
      return;
    boolean val = !viewer.getRocketBarrelFlag();
    if (renderArrowHeads != val) {
      bioShape.falsifyMesh();
      renderArrowHeads = val;
    }
    calcRopeMidPoints(false);   
    calcScreenControlPoints(cordMidPoints);
    controlPoints = cordMidPoints;
    render1();
    viewer.freeTempPoints(cordMidPoints);
  }

  protected Point3f[] cordMidPoints;

  protected boolean isSheet(int i) {
    return structureTypes[i] == JmolConstants.PROTEIN_STRUCTURE_SHEET;
  }

  protected void calcRopeMidPoints(boolean isNewStyle) {
    int midPointCount = monomerCount + 1;
    cordMidPoints = viewer.allocTempPoints(midPointCount);
    ProteinStructure proteinstructurePrev = null;
    Point3f point;
    for (int i = 0; i < monomerCount; ++i) {
      point = cordMidPoints[i];
      Monomer residue = monomers[i];
      if (isNewStyle && renderArrowHeads) {
          point.set(controlPoints[i]);
      } else if (isHelix(i) ||  !isNewStyle && isSheet(i)) {
        ProteinStructure proteinstructure = residue.getProteinStructure();
        point.set(i - 1 != proteinstructure.getMonomerIndex() ?
            proteinstructure.getAxisStartPoint() :
            proteinstructure.getAxisEndPoint());
        proteinstructurePrev = proteinstructure;
      } else {
        if (proteinstructurePrev != null)
          point.set(proteinstructurePrev.getAxisEndPoint());
        else {
          point.set(controlPoints[i]);       
        }
        proteinstructurePrev = null;
      }
    }
    point = cordMidPoints[monomerCount];
    if (proteinstructurePrev != null)
      point.set(proteinstructurePrev.getAxisEndPoint());
    else {
      point.set(controlPoints[monomerCount]);       
    }
  }

  protected void render1() {
    tPending = false;
    for (int i = bsVisible.nextSetBit(0); i >= 0; i = bsVisible
        .nextSetBit(i + 1)) {
      Monomer monomer = monomers[i];
      if (isHelix(i) || isSheet(i)) {
        renderSpecialSegment(monomer, getLeadColix(i), mads[i]);
      } else {
        renderPending();
        renderHermiteConic(i, true);
      }
    }
    renderPending();
  }

  protected void renderSpecialSegment(Monomer monomer, short thisColix, short thisMad) {
    ProteinStructure proteinstructure = monomer.getProteinStructure();
    if (tPending) {
      if (proteinstructure == proteinstructurePending && thisMad == mad
          && thisColix == colix
          && proteinstructure.getIndex(monomer) == endIndexPending + 1) {
        ++endIndexPending;
        return;
      }
      renderPending();
    }
    proteinstructurePending = proteinstructure;
    startIndexPending = endIndexPending = proteinstructure.getIndex(monomer);
    colix = thisColix;
    mad = thisMad;
    tPending = true;
  }

  protected boolean tPending;
  private ProteinStructure proteinstructurePending;
  private int startIndexPending;
  private int endIndexPending;

  protected void renderPending() {
    if (!tPending)
      return;
    Point3f[] segments = proteinstructurePending.getSegments();
    boolean tEnd = (endIndexPending == proteinstructurePending
        .getMonomerCount() - 1);
    if (proteinstructurePending instanceof Helix)
      renderPendingRocketSegment(endIndexPending, segments[startIndexPending],
          segments[endIndexPending], segments[endIndexPending + 1], tEnd);
    else if (proteinstructurePending instanceof Sheet)
      renderPendingSheet(segments[startIndexPending],
          segments[endIndexPending], segments[endIndexPending + 1], tEnd);
    tPending = false;
  }

  private Point3f screenA = new Point3f();
  private Point3f screenB = new Point3f();
  private Point3f screenC = new Point3f();

  private void renderPendingRocketSegment(int i, Point3f pointStart,
                                          Point3f pointBeforeEnd,
                                          Point3f pointEnd, boolean tEnd) {
    viewer.transformPoint(pointStart, screenA);
    viewer.transformPoint(pointEnd, screenB);
    int zMid = (int) Math.floor((screenA.z + screenB.z) / 2f);
    int diameter = viewer.scaleToScreen(zMid, mad);
    if (tEnd && renderArrowHeads) {
      viewer.transformPoint(pointBeforeEnd, screenC);
      if (g3d.setColix(colix)) {
        if (pointBeforeEnd.distance(pointEnd) <= MIN_CONE_HEIGHT)
          g3d.fillCylinderBits(Graphics3D.ENDCAPS_FLAT, diameter, screenB,
              screenC);
        else
          renderCone(i, pointBeforeEnd, pointEnd, screenC, screenB);
      }
      if (startIndexPending == endIndexPending)
        return;
      Point3f t = screenB;
      screenB = screenC;
      screenC = t;
    }
    if (g3d.setColix(colix))
      g3d.fillCylinderBits(Graphics3D.ENDCAPS_FLAT, diameter, screenA, screenB);
  }

  private void renderPendingSheet(Point3f pointStart, Point3f pointBeforeEnd,
                          Point3f pointEnd, boolean tEnd) {
    if (!g3d.setColix(colix))
      return;
    if (tEnd && renderArrowHeads) {
      drawArrowHeadBox(pointBeforeEnd, pointEnd);
      drawBox(pointStart, pointBeforeEnd);
    } else {
      drawBox(pointStart, pointEnd);
    }
  }

  private final static byte[] boxFaces =
  {
    0, 1, 3, 2,
    0, 2, 6, 4,
    0, 4, 5, 1,
    7, 5, 4, 6,
    7, 6, 2, 3,
    7, 3, 1, 5 };

  private final Point3f[] corners = new Point3f[8];
  private final Point3f[] screenCorners = new Point3f[8];
  {
    for (int i = 8; --i >= 0; ) {
      screenCorners[i] = new Point3f();
      corners[i] = new Point3f();
    }
  }

  private final Point3f pointTipOffset = new Point3f();

  private final Vector3f scaledWidthVector = new Vector3f();
  private final Vector3f scaledHeightVector = new Vector3f();

  private final static byte arrowHeadFaces[] =
  {0, 1, 3, 2,
   0, 4, 5, 2,
   1, 4, 5, 3};

  void buildBox(Point3f pointCorner, Vector3f scaledWidthVector,
                Vector3f scaledHeightVector, Vector3f lengthVector) {
    for (int i = 8; --i >= 0; ) {
      Point3f corner = corners[i];
      corner.set(pointCorner);
      if ((i & 1) != 0)
        corner.add(scaledWidthVector);
      if ((i & 2) != 0)
        corner.add(scaledHeightVector);
      if ((i & 4) != 0)
        corner.add(lengthVector);
      viewer.transformPoint(corner, screenCorners[i]);
    }
  }

  void buildArrowHeadBox(Point3f pointCorner, Vector3f scaledWidthVector,
                         Vector3f scaledHeightVector, Point3f pointTip) {
    for (int i = 4; --i >= 0; ) {
      Point3f corner = corners[i];
      corner.set(pointCorner);
      if ((i & 1) != 0)
        corner.add(scaledWidthVector);
      if ((i & 2) != 0)
        corner.add(scaledHeightVector);
      viewer.transformPoint(corner, screenCorners[i]);
    }
    corners[4].set(pointTip);
    viewer.transformPoint(pointTip, screenCorners[4]);
    corners[5].add(pointTip, scaledHeightVector);
    viewer.transformPoint(corners[5], screenCorners[5]);
  }

  private final Vector3f lengthVector = new Vector3f();
  private final Point3f pointCorner = new Point3f();

  void drawBox(Point3f pointA, Point3f pointB) {
    Sheet sheet = (Sheet)proteinstructurePending;
    float scale = mad / 1000f;
    scaledWidthVector.set(sheet.getWidthUnitVector());
    scaledWidthVector.scale(scale);
    scaledHeightVector.set(sheet.getHeightUnitVector());
    scaledHeightVector.scale(scale / 4);
    pointCorner.add(scaledWidthVector, scaledHeightVector);
    pointCorner.scaleAdd(-0.5f, pointA);
    lengthVector.sub(pointB, pointA);
    buildBox(pointCorner, scaledWidthVector,
             scaledHeightVector, lengthVector);
    for (int i = 0; i < 6; ++i) {
      int i0 = boxFaces[i * 4];
      int i1 = boxFaces[i * 4 + 1];
      int i2 = boxFaces[i * 4 + 2];
      int i3 = boxFaces[i * 4 + 3];
      g3d.fillQuadrilateral(screenCorners[i0],
                              screenCorners[i1],
                              screenCorners[i2],
                              screenCorners[i3]);
    }
  }

  void drawArrowHeadBox(Point3f base, Point3f tip) {
    Sheet sheet = (Sheet)proteinstructurePending;
    float scale = mad / 1000f;
    scaledWidthVector.set(sheet.getWidthUnitVector());
    scaledWidthVector.scale(scale * 1.25f);
    scaledHeightVector.set(sheet.getHeightUnitVector());
    scaledHeightVector.scale(scale / 3);
    pointCorner.add(scaledWidthVector, scaledHeightVector);
    pointCorner.scaleAdd(-0.5f, base);
    pointTipOffset.set(scaledHeightVector);
    pointTipOffset.scaleAdd(-0.5f, tip);
    buildArrowHeadBox(pointCorner, scaledWidthVector,
                      scaledHeightVector, pointTipOffset);
    g3d.fillTriangle(screenCorners[0],
                     screenCorners[1],
                     screenCorners[4]);
    g3d.fillTriangle(screenCorners[2],
                     screenCorners[3],
                     screenCorners[5]);
    for (int i = 0; i < 12; i += 4) {
      int i0 = arrowHeadFaces[i];
      int i1 = arrowHeadFaces[i + 1];
      int i2 = arrowHeadFaces[i + 2];
      int i3 = arrowHeadFaces[i + 3];
      g3d.fillQuadrilateral(screenCorners[i0],
                              screenCorners[i1],
                              screenCorners[i2],
                              screenCorners[i3]);
    }
  } 
}
TOP

Related Classes of org.jmol.shapebio.RocketsRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.