Package org.mt4j.components.visibleComponents.shapes

Source Code of org.mt4j.components.visibleComponents.shapes.MTRectangle

/***********************************************************************
* mt4j Copyright (c) 2008 - 2009, C.Ruff, Fraunhofer-Gesellschaft All rights reserved.
*   This program is free software: you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation, either version 3 of the License, or
*   (at your option) any later version.
*
*   This program 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 General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
***********************************************************************/
package org.mt4j.components.visibleComponents.shapes;

import org.mt4j.MTApplication;
import org.mt4j.components.TransformSpace;
import org.mt4j.components.bounds.BoundsZPlaneRectangle;
import org.mt4j.components.bounds.IBoundingShape;
import org.mt4j.util.MT4jSettings;
import org.mt4j.util.math.Vector3D;
import org.mt4j.util.math.Vertex;

import processing.core.PApplet;
import processing.core.PImage;

/**
* A simple rectangular shape.
*
* @author Christopher Ruff
*/
public class MTRectangle extends MTPolygon {
 
  /** The current anchor. */
  private PositionAnchor currentAnchor;
 
  // (if the rectangle is x or y, rotated, the boundsZPlaneRectangle wont work anymore as a boundingshape!)
  // actually it works..only wouldnt work if the local vertices arent lying on a z=0 parallel plane.
 
  /**
   * The Enum PositionAnchor.
   *
   * @author Christopher Ruff
   */
  public enum PositionAnchor{
   
    /** The LOWE r_ left. */
    LOWER_LEFT,
   
    /** The LOWE r_ right. */
    LOWER_RIGHT,
   
    /** The UPPE r_ left. */
    UPPER_LEFT,
   
    /** The CENTER. */
    CENTER
  }
 
  /**
   * Instantiates a new mT rectangle.
   *
   * @param texture the texture
   * @param applet the applet
   */
  public MTRectangle(PImage texture, PApplet applet) {
    this(0 ,0 ,0, texture.width, texture.height, applet);
   
    //To avoid errors if this is created in non opengl thread so the gl texture wont be created correctly when setting setTexture
    this.setUseDirectGL(false);

    if (applet instanceof MTApplication) {
      MTApplication app = (MTApplication) applet;
     
      if (MT4jSettings.getInstance().isOpenGlMode()){
        if (app.isRenderThreadCurrent()){
          this.setUseDirectGL(true);
        }else{
          //IF we are useing OpenGL, set useDirectGL to true
          //(=>creates OpenGL texture, draws with pure OpenGL commands)
          //in our main thread.
          app.invokeLater(new Runnable() {
            public void run() {
              setUseDirectGL(true);
            }
          });
        }
      }else{
        if (this.isUseDirectGL()){
          this.setUseDirectGL(false);
        }
      }
    }else{
      //Cant check if we are in renderthread -> dont use direct gl mode -> dont create Gl texture object
      if (this.isUseDirectGL()){
        this.setUseDirectGL(false);
      }
    }

//    //hm..this is for when we create textured rects in other threads
//    //, because when we init gl texture in other thread it breaks..
//    this.setUseDirectGL(false);
//
//    //IF we are useing OpenGL, set useDirectGL to true
//    //(=>creates OpenGL texture, draws with pure OpenGL commands)
//    //in our main thread.
//    if (MT4jSettings.getInstance().isOpenGlMode() && applet instanceof MTApplication){
//      MTApplication app = (MTApplication)applet;
//      app.invokeLater(new Runnable() {
//        public void run() {
//          if (!isUseDirectGL())
//            setUseDirectGL(true);
//        }
//      });
//    }

    this.setTexture(texture);
    this.setTextureEnabled(true);
  }
 
 
  /**
   * Instantiates a new mT rectangle with the upper left corner at 0,0,0
   *
   * @param width the width
   * @param height the height
   * @param pApplet the applet
   */
  public MTRectangle(float width, float height, PApplet pApplet) {
    this(new Vertex(0,0,0,0,0),width,height,pApplet);
  }
 
 
  /**
   * Instantiates a new mT rectangle.
   *
   * @param x the x
   * @param y the y
   * @param width the width
   * @param height the height
   * @param pApplet the applet
   */
  public MTRectangle(float x, float y, float width, float height, PApplet pApplet) {
    this(new Vertex(x,y,0,0,0),width,height,pApplet);
  }
 
  /**
   * Instantiates a new mT rectangle.
   *
   * @param x the x
   * @param y the y
   * @param z the z
   * @param width the width
   * @param height the height
   * @param pApplet the applet
   */
  public MTRectangle(float x, float y, float z, float width, float height, PApplet pApplet) {
    this(new Vertex(x,y,z,0,0),width,height,pApplet);
  }

 
  /**
   * Instantiates a new mT rectangle.
   *
   * @param upperLeft the upper left
   * @param width the width
   * @param height the height
   * @param pApplet the applet
   */
  public MTRectangle(Vertex upperLeft, float width, float height, PApplet pApplet) {
    super(new Vertex[]{
        new Vertex(upperLeft.x,      upperLeft.y,     upperLeft.z, 0, 0),
        new Vertex(upperLeft.x+width,   upperLeft.y,     upperLeft.z, 1, 0),
        new Vertex(upperLeft.x+width,   upperLeft.y+height, upperLeft.z, 1, 1),
        new Vertex(upperLeft.x,      upperLeft.y+height,  upperLeft.z, 0, 1),
        new Vertex(upperLeft.x,      upperLeft.y,    upperLeft.z, 0, 0)},
        pApplet);
   
    this.setName("unnamed rectangle");
    //
    this.setBoundsBehaviour(AbstractShape.BOUNDS_ONLY_CHECK);
   
    currentAnchor = PositionAnchor.CENTER;
  }

 
  /* (non-Javadoc)
   * @see org.mt4j.components.visibleComponents.shapes.MTPolygon#computeDefaultBounds()
   */
  @Override
  protected IBoundingShape computeDefaultBounds(){
    return new BoundsZPlaneRectangle(this);
  }
 
  /**
   * Gets the Position anchor.
   *
   * @return the anchor
   */
  public PositionAnchor getAnchor(){
    return this.currentAnchor;
  }
 
  /**
   * Sets the anchor. The Anchor determines which reference point
   * is used at set/getPosition(). The default anchor point is the rectangle's
   * center.
   *
   * @param anchor the new anchor
   */
  public void setAnchor(PositionAnchor anchor){
    this.currentAnchor = anchor;
  }
 
 
  /* (non-Javadoc)
   * @see org.mt4j.components.visibleComponents.shapes.AbstractShape#setPositionGlobal(org.mt4j.util.math.Vector3D)
   */
  @Override
  public void setPositionGlobal(Vector3D position) {
    switch (this.getAnchor()) {
    case CENTER:
      super.setPositionGlobal(position);
      break;
    case LOWER_LEFT:{
      Vertex[] vertices = this.getVerticesGlobal();
      Vertex lowerLeft = new Vertex(vertices[3]);
      this.translateGlobal(position.getSubtracted(lowerLeft));
    }break;
    case LOWER_RIGHT:{
      Vertex[] vertices = this.getVerticesGlobal();
      Vertex v = new Vertex(vertices[2]);
      this.translateGlobal(position.getSubtracted(v));
    }break;
    case UPPER_LEFT:{
      Vertex[] vertices = this.getVerticesGlobal();
      Vertex upperLeft = new Vertex(vertices[0]);
      this.translateGlobal(position.getSubtracted(upperLeft));
    }break;
    default:
      break;
    }
  }
 
  /* (non-Javadoc)
   * @see org.mt4j.components.visibleComponents.shapes.AbstractShape#setPositionRelativeToParent(org.mt4j.util.math.Vector3D)
   */
  @Override
  public void setPositionRelativeToParent(Vector3D position) {
    switch (this.getAnchor()) {
    case CENTER:
      super.setPositionRelativeToParent(position);
      break;
    case LOWER_LEFT:{
      Vertex[] vertices = this.getVerticesLocal();
      Vertex lowerLeft = new Vertex(vertices[3]);
      lowerLeft.transform(this.getLocalMatrix());
      this.translate(position.getSubtracted(lowerLeft), TransformSpace.RELATIVE_TO_PARENT);
    }break;
    case LOWER_RIGHT:{
      Vertex[] vertices = this.getVerticesLocal();
      Vertex v = new Vertex(vertices[2]);
      v.transform(this.getLocalMatrix());
      this.translate(position.getSubtracted(v), TransformSpace.RELATIVE_TO_PARENT);
    }break;
    case UPPER_LEFT:{
      Vertex[] vertices = this.getVerticesLocal();
      Vertex v = new Vertex(vertices[0]);
      v.transform(this.getLocalMatrix());
      this.translate(position.getSubtracted(v), TransformSpace.RELATIVE_TO_PARENT);
    }break;
    default:
      break;
    }
  }

 
  /**
   * Gets the position. The position is dependant on the
   * set PositionAnchor. The default is the PositionAnchor.CENTER.
   *
   * @param transformSpace the transform space
   * @return the position
   */
  public Vector3D getPosition(TransformSpace transformSpace){
    Vector3D v;
    switch (transformSpace) {
    case LOCAL:
      switch (this.getAnchor()) {
      case CENTER:
        return this.getCenterPointLocal();
      case LOWER_LEFT:
        return new Vector3D(this.getVerticesLocal()[3]);
      case LOWER_RIGHT:
        return new Vector3D(this.getVerticesLocal()[2]);
      case UPPER_LEFT:
        return new Vector3D(this.getVerticesLocal()[0]);
      default:
        break;
      }
      break;
    case RELATIVE_TO_PARENT:
      switch (this.getAnchor()) {
      case CENTER:
        return this.getCenterPointRelativeToParent();
      case LOWER_LEFT:
        v = new Vector3D(this.getVerticesLocal()[3]);
        v.transform(this.getLocalMatrix());
        return v;
      case LOWER_RIGHT:
        v = new Vector3D(this.getVerticesLocal()[2]);
        v.transform(this.getLocalMatrix());
        return v;
      case UPPER_LEFT:
        v = new Vector3D(this.getVerticesLocal()[0]);
        v.transform(this.getLocalMatrix());
        return v;
      default:
        break;
      }
      break;
    case GLOBAL:
      switch (this.getAnchor()) {
      case CENTER:
        return this.getCenterPointGlobal();
      case LOWER_LEFT:
        v = new Vector3D(this.getVerticesLocal()[3]);
        v.transform(this.getGlobalMatrix());
        return v;
      case LOWER_RIGHT:
        v = new Vector3D(this.getVerticesLocal()[2]);
        v.transform(this.getGlobalMatrix());
        return v;
      case UPPER_LEFT:
        v = new Vector3D(this.getVerticesLocal()[0]);
        v.transform(this.getGlobalMatrix());
        return v;
      default:
        break;
      }
      break;
    default:
      break;
    }
    return null;
  }
 

  /* (non-Javadoc)
   * @see org.mt4j.components.visibleComponents.shapes.MTPolygon#get2DPolygonArea()
   */
  @Override
  public double get2DPolygonArea() {
    return (getHeightXY(TransformSpace.RELATIVE_TO_PARENT)*getWidthXY(TransformSpace.RELATIVE_TO_PARENT));
  }

 
  /* (non-Javadoc)
   * @see org.mt4j.components.visibleComponents.shapes.MTPolygon#getCenterOfMass2DLocal()
   */
  @Override
  public Vector3D getCenterOfMass2DLocal() {
    Vertex[] v = this.getVerticesLocal();
    Vector3D center = new Vector3D(
        v[0].getX() + ((v[1].getX() - v[0].getX())/2),
        v[1].getY() + ((v[2].getY() - v[1].getY())/2),
        v[0].getZ());
    return center;
  }
 
 
  /* (non-Javadoc)
   * @see org.mt4j.components.visibleComponents.shapes.MTPolygon#getCenterPointLocal()
   */
  @Override
  public Vector3D getCenterPointLocal(){
    return this.getCenterOfMass2DLocal();
  }

 
  /**
   * Sets the size locally, meaning that not the transformation of the rectangle is changed, (as setSize/setWidth, scale etc. would do) but the vertices
   * of the rectangle themselves. This is useful if we dont want the rectangles children to be scaled as well, for example.
   * <br>Note: The scaling is done from the rectangles upper left corner - not the center!
   *
   * @param width the width
   * @param height the height
   */
  public void setSizeLocal(float width, float height){
    if (width > 0 && height > 0){
      Vertex[] v = this.getVerticesLocal();
      this.setVertices(new Vertex[]{
          new Vertex(v[0].x,      v[0].y,     v[0].z, v[0].getTexCoordU(), v[0].getTexCoordV(), v[0].getR(), v[0].getG(), v[0].getB(), v[0].getA()),
          new Vertex(v[0].x+width,   v[1].y,     v[1].z, v[1].getTexCoordU(), v[1].getTexCoordV(), v[1].getR(), v[1].getG(), v[1].getB(), v[1].getA()),
          new Vertex(v[0].x+width,   v[1].y+height,   v[2].z, v[2].getTexCoordU(), v[2].getTexCoordV(), v[2].getR(), v[2].getG(), v[2].getB(), v[2].getA()),
          new Vertex(v[3].x,      v[0].y+height,  v[3].z, v[3].getTexCoordU(), v[3].getTexCoordV(), v[3].getR(), v[3].getG(), v[3].getB(), v[3].getA()),
          new Vertex(v[4].x,      v[4].y,      v[4].z, v[4].getTexCoordU(), v[4].getTexCoordV(), v[4].getR(), v[4].getG(), v[4].getB(), v[4].getA()),
      });
    }
  }
 
 
  /**
   * Sets the height locally, meaning that not the transformation of the rectangle is changed, (as setSize/setWidth, scale etc. would do) but the vertices
   * of the rectangle themselves. This is useful if we dont want the rectangles children to be scaled as well, for example.
   * <br>Note: The scaling is done from the rectangles upper left corner - not the center!
   *
   * @param height the new height local
   */
  public void setHeightLocal(float height){
    Vertex[] v = this.getVerticesLocal();
    this.setVertices(new Vertex[]{
        new Vertex(v[0].x,  v[0].y,     v[0].z, v[0].getTexCoordU(), v[0].getTexCoordV(), v[0].getR(), v[0].getG(), v[0].getB(), v[0].getA()),
        new Vertex(v[1].x,   v[1].y,     v[1].z, v[1].getTexCoordU(), v[1].getTexCoordV(), v[1].getR(), v[1].getG(), v[1].getB(), v[1].getA()),
        new Vertex(v[2].x,   v[1].y+height,   v[2].z, v[2].getTexCoordU(), v[2].getTexCoordV(), v[2].getR(), v[2].getG(), v[2].getB(), v[2].getA()),
        new Vertex(v[3].x,  v[1].y+height,  v[3].z, v[3].getTexCoordU(), v[3].getTexCoordV(), v[3].getR(), v[3].getG(), v[3].getB(), v[3].getA()),
        new Vertex(v[4].x,  v[4].y,      v[4].z, v[4].getTexCoordU(), v[4].getTexCoordV(), v[4].getR(), v[4].getG(), v[4].getB(), v[4].getA()),
    });
  }
 
 
  /**
   * Sets the width locally, meaning that not the transformation of the rectangle is changed, (as setSize/setWidth, scale etc. would do) but the vertices
   * of the rectangle themselves. This is useful if we dont want the rectangles children to be scaled as well, for example.
   * <br>Note: The scaling is done from the rectangles upper left corner - not the center!
   * @param width the new width local
   */
  public void setWidthLocal(float width){
    if (width > 0){
      Vertex[] v = this.getVerticesLocal();
      this.setVertices(new Vertex[]{
          new Vertex(v[0].x,      v[0].y, v[0].z, v[0].getTexCoordU(), v[0].getTexCoordV(), v[0].getR(), v[0].getG(), v[0].getB(), v[0].getA()),
          new Vertex(v[0].x+width,   v[1].y, v[1].z, v[1].getTexCoordU(), v[1].getTexCoordV(), v[1].getR(), v[1].getG(), v[1].getB(), v[1].getA()),
          new Vertex(v[0].x+width,   v[2].y, v[2].z, v[2].getTexCoordU(), v[2].getTexCoordV(), v[2].getR(), v[2].getG(), v[2].getB(), v[2].getA()),
          new Vertex(v[3].x,      v[3].y,  v[3].z, v[3].getTexCoordU(), v[3].getTexCoordV(), v[3].getR(), v[3].getG(), v[3].getB(), v[3].getA()),
          new Vertex(v[4].x,      v[4].y,  v[4].z, v[4].getTexCoordU(), v[4].getTexCoordV(), v[4].getR(), v[4].getG(), v[4].getB(), v[4].getA()),
      });
    }
  }
 
  //TODO also overRide setSizeGlobal()!!
  //TODO setSize setzt obj space size nicht relative bis jetzt! einfach width vector transformen und length() holen!
 

}
TOP

Related Classes of org.mt4j.components.visibleComponents.shapes.MTRectangle

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.