Package advanced.puzzle

Source Code of advanced.puzzle.PuzzleFactory$MTComplexPolyClusterable

package advanced.puzzle;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.mt4j.MTApplication;
import org.mt4j.components.MTComponent;
import org.mt4j.components.TransformSpace;
import org.mt4j.components.bounds.BoundsZPlaneRectangle;
import org.mt4j.components.visibleComponents.shapes.AbstractShape;
import org.mt4j.components.visibleComponents.shapes.MTComplexPolygon;
import org.mt4j.components.visibleComponents.shapes.MTPolygon;
import org.mt4j.input.gestureAction.InertiaDragAction;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.lassoProcessor.IdragClusterable;
import org.mt4j.input.inputProcessors.componentProcessors.scaleProcessor.ScaleProcessor;
import org.mt4j.util.MT4jSettings;
import org.mt4j.util.MTColor;
import org.mt4j.util.math.ToolsMath;
import org.mt4j.util.math.Vector3D;
import org.mt4j.util.math.Vertex;
import org.mt4j.util.opengl.GLTexture;
import org.mt4j.util.xml.svg.SVGLoader;

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

public class PuzzleFactory {
  //TODO
  /*
   - show mini picture of original picture for orientation
   - snap pieces together? - how to break them apart again?
   - clusterable tiles?
   - if solved - set all tiles noStroke(true) to see image clearly
   */

  public enum TileSide{
    pinOut,
    pinIn,
    linear
  }
 
  private float tileHeight;
  private float tileWidth;
  private Vertex[] downUpOrderVerticalRightOut;
  private Vertex[] upDownOrderVerticalLeftOut;
  private Vertex[] downUpOrderVerticalLeftOut;
  private Vertex[] leftRightHorizontalUpOut;
  private Vertex[] rightLeftHorizontalUpOut;
  private Vertex[] rightLeftOrderHorizontalDownOut;
  private Vertex[] leftRightOrderHorizontalDownOut;
  private Vertex[] upDownOrderVerticalRightOut;
  private PImage image;
  private float horizontalTileCount;
  private PApplet app;
  private float verticalTileCount;
  public static String svgPath =  "advanced"+MTApplication.separator+"puzzle"+MTApplication.separator+"data"+MTApplication.separator ;
  public static String svgname = "knobOutRight.svg";
 
  public PuzzleFactory(MTApplication app) {
    this.app = app;
  }

//  public PuzzleFactory(PApplet app, float tileWidth, float tileHeight){
//
//  }
 
  private void init(float tileWidth, float tileHeight){
    this.tileWidth = tileWidth;
    this.tileHeight = tileHeight;
    initTiles();
  }
 
  private void init(PImage p, int horizontalTileCount){
//    if (MT4jSettings.getInstance().isOpenGlMode() && !(p instanceof GLTexture)){
//      GLTexture tex = new GLTexture(app, p);
//      this.image = tex;
//    }else{
//      this.image = p;
//    }
//   
//    this.horizontalTileCount = horizontalTileCount;
//    this.verticalTileCount = horizontalTileCount; //TODO
//    this.tileWidth = (float)p.width/horizontalTileCount;
//    this.tileHeight = (float)p.height/verticalTileCount;
//    initTiles();
    this.init(p, horizontalTileCount, horizontalTileCount);
  }
 
  private void init(PImage p, int horizontalTileCount, int verticalTileCount){
    if (MT4jSettings.getInstance().isOpenGlMode() && !(p instanceof GLTexture)){
      GLTexture tex = new GLTexture(app, p);
      this.image = tex;
    }else{
      this.image = p;
    }
   
    this.horizontalTileCount = horizontalTileCount;
    this.verticalTileCount = verticalTileCount; //TODO
    this.tileWidth = (float)p.width/(float)horizontalTileCount;
    this.tileHeight = (float)p.height/(float)verticalTileCount;
    initTiles();
  }
 
  private void initTiles(){
    SVGLoader l = new SVGLoader(app);
    MTComponent knob = l.loadSvg(svgPath + svgname);
    MTPolygon knobRight = (MTPolygon) knob.getChildByIndex(0).getChildByIndex(0);
    knobRight.setNoFill(false);
    knobRight.setUseDisplayList(false);
    float origHeight = knobRight.getHeightXY(TransformSpace.LOCAL);
   
    //Snap to upper left 0,0
    Vertex[] originalVerts = knobRight.getVerticesLocal();
    originalVerts = Vertex.translateArray(originalVerts, Vector3D.ZERO_VECTOR.getSubtracted(new Vector3D(originalVerts[0])));
   
    upDownOrderVerticalRightOut = Vertex.getDeepVertexArrayCopy(originalVerts);
    //Scale to desired height
    Vertex.scaleVectorArray(upDownOrderVerticalRightOut, Vector3D.ZERO_VECTOR, (1f/origHeight) * tileHeight, (1f/origHeight) * tileHeight, 1);
       
    downUpOrderVerticalRightOut = getInvertOrderCopy(upDownOrderVerticalRightOut);
//    MTPolygon p1 = new MTPolygon(getMTApplication(), downUpOrderVerticalRightOut);
//    getCanvas().addChild(p1);
   
    upDownOrderVerticalLeftOut = Vertex.getDeepVertexArrayCopy(upDownOrderVerticalRightOut);
    Vertex.scaleVectorArray(upDownOrderVerticalLeftOut, new Vector3D(0,origHeight/2f), -1, 1, 1);
//    MTPolygon p2 = new MTPolygon(getMTApplication(), vertsVerticalLeftOut);
//    getCanvas().addChild(p2);
   
    downUpOrderVerticalLeftOut = getInvertOrderCopy(upDownOrderVerticalLeftOut);
   
    leftRightHorizontalUpOut = Vertex.getDeepVertexArrayCopy(originalVerts);
    Vertex.rotateZVectorArray(leftRightHorizontalUpOut, Vector3D.ZERO_VECTOR, -90);
    //Scale to desired width
    Vertex.scaleVectorArray(leftRightHorizontalUpOut, Vector3D.ZERO_VECTOR, (1f/origHeight) * tileWidth, (1f/origHeight) * tileWidth, 1);
//    MTPolygon p3 = new MTPolygon(getMTApplication(), leftRightHorizontalUpOut);
//    getCanvas().addChild(p3);
   
    rightLeftHorizontalUpOut = getInvertOrderCopy(leftRightHorizontalUpOut);
   
    leftRightOrderHorizontalDownOut = Vertex.getDeepVertexArrayCopy(leftRightHorizontalUpOut);
    Vertex.scaleVectorArray(leftRightOrderHorizontalDownOut, new Vector3D(origHeight/2f,0), 1, -1, 1);
//    MTPolygon p4 = new MTPolygon(getMTApplication(), leftRightOrderHorizontalDownOut);
//    getCanvas().addChild(p4);
   
    rightLeftOrderHorizontalDownOut = getInvertOrderCopy(leftRightOrderHorizontalDownOut);
  }
 
 
  public AbstractShape[] createTiles(PImage p, int horizontalTileCount){
    return createTiles(p, horizontalTileCount, horizontalTileCount);
  }
 
  public AbstractShape[] createTiles(PImage p, int horizontalTileCount, int verticalTileCount){
    this.init(p, horizontalTileCount, verticalTileCount);
   
    List<AbstractShape> tiles = new ArrayList<AbstractShape>();
    TileSide[] sides = new TileSide[]{TileSide.pinIn, TileSide.pinOut};
   
    for (int i = 0; i < verticalTileCount; i++) {
      for (int j = 0; j < horizontalTileCount; j++) {
        TileSide top = TileSide.pinOut, right = TileSide.pinOut, bottom = TileSide.pinOut, left = TileSide.pinIn;
       
        //left und top have to be checked against the previous tiles, right and bottom can be random (if not linear)
        right = sides[Math.round(ToolsMath.getRandom(0, sides.length-1))];
        bottom = sides[Math.round(ToolsMath.getRandom(0, sides.length-1))];
       
        if (j == 0){
          //Left side has to be linear
          left = TileSide.linear;
         
          if (i == 0){
            //top side has to be linear
            top = TileSide.linear;
//            left = getFittingTileSideTo(getRightOfLeftTile(tiles, i, j));
          }else if (i == verticalTileCount -1){
            //Bottom side has to be linear
            bottom = TileSide.linear;
            top = getFittingTileSideTo(getBottomOfUpperTile(tiles, i, j));
//            left = getFittingTileSideTo(getRightOfLeftTile(tiles, i, j));
          }else{
            //in a middle vetical - up or bottom side have to have a pin
            top = getFittingTileSideTo(getBottomOfUpperTile(tiles, i, j));
//            left = getFittingTileSideTo(getRightOfLeftTile(tiles, i, j));
          }
        }else if (j == horizontalTileCount -1){
          right = TileSide.linear;
         
          //Right side has to be linear
          if (i == 0){
            //top side has to be linear
            top = TileSide.linear;
            left = getFittingTileSideTo(getRightOfLeftTile(tiles, i, j));
          }else if (i == verticalTileCount -1){
            //Bottom side has to be linear
            bottom = TileSide.linear;
            top = getFittingTileSideTo(getBottomOfUpperTile(tiles, i, j));
            left = getFittingTileSideTo(getRightOfLeftTile(tiles, i, j));
          }else{
            //in a middle vetical - up or bottom side have to have a pin
            top = getFittingTileSideTo(getBottomOfUpperTile(tiles, i, j));
            left = getFittingTileSideTo(getRightOfLeftTile(tiles, i, j));
          }
        }else{
          //in a middle horizontal, left or right side have to have a pin
         
          if (i == 0){
            //top side has to be linear
            top = TileSide.linear;
            left = getFittingTileSideTo(getRightOfLeftTile(tiles, i, j));
          }else if (i == verticalTileCount -1){
            //Bottom side has to be linear
            bottom = TileSide.linear;
            top = getFittingTileSideTo(getBottomOfUpperTile(tiles, i, j));
            left = getFittingTileSideTo(getRightOfLeftTile(tiles, i, j));
          }else{
            //in a middle vetical - up or bottom side have to have a pin
            top = getFittingTileSideTo(getBottomOfUpperTile(tiles, i, j));
            left = getFittingTileSideTo(getRightOfLeftTile(tiles, i, j));
          }
        }
       
        MTComplexPolygon tile = getPolygon(app, top, right, bottom, left, this.tileWidth, this.tileHeight);
        tile.setName(i + "" + j);
        tile.setUserData("i", i);
        tile.setUserData("j", j);
        tile.setUserData("top", top);
        tile.setUserData("right", right);
        tile.setUserData("bottom", bottom);
        tile.setUserData("left", left);
        //Create some default texture coords
        tile.setBounds(new BoundsZPlaneRectangle(tile));
        if (tile != null && tile.hasBounds() && tile.getBounds() instanceof BoundsZPlaneRectangle){
          BoundsZPlaneRectangle bounds = (BoundsZPlaneRectangle) tile.getBounds();
         
//          float width = bounds.getWidthXY(TransformSpace.LOCAL);
//          float height = bounds.getHeightXY(TransformSpace.LOCAL);
//          float upperLeftX = bounds.getVectorsLocal()[0].x;
//          float upperLeftY = bounds.getVectorsLocal()[0].y;
         
//          float upperLeftX = bounds.getVectorsLocal()[0].x  + j* tileWidth ;
//          float upperLeftY = bounds.getVectorsLocal()[0].y  + i * tileHeight;
          Vertex[] verts = tile.getVerticesLocal();
          for (int n = 0; n < verts.length; n++) {
            Vertex vertex = verts[n];
//            vertex.setTexCoordU((vertex.x-upperLeftX )/width);
//            vertex.setTexCoordV((vertex.y-upperLeftY)/height);
//            vertex.setTexCoordU((vertex.x - upperLeftX  + (j * tileWidth)) / p.width);
//            vertex.setTexCoordV((vertex.y - upperLeftY + (i * tileHeight)) / p.height);
           
            vertex.setTexCoordU((vertex.x  + (j * tileWidth)) / p.width);
            vertex.setTexCoordV((vertex.y  + (i * tileHeight)) / p.height);
           
            //System.out.println("TexU:" + vertex.getTexCoordU() + " TexV:" + vertex.getTexCoordV());
          }
          tile.getGeometryInfo().updateTextureBuffer(tile.isUseVBOs());
         
          //Set the texture
          tile.setTexture(p);
//          tile.setNoStroke(true);
//          tile.setStrokeColor(MTColor.GREY);
          tile.setStrokeColor(new MTColor(80,80,80));
          tile.setStrokeWeight(0.7f);
         
          tiles.add(tile);
        }
       
      }
    }
   
    return tiles.toArray(new AbstractShape[tiles.size()]);
  }
 
 
  private TileSide getBottomOfUpperTile(List<AbstractShape> list, int currentI, int currentJ){
    if (currentI-1 < 0){
      return TileSide.linear;
    }
    for (Iterator<AbstractShape> iterator = list.iterator(); iterator.hasNext();) {
      AbstractShape tile = (AbstractShape) iterator.next();
      int i = (Integer) tile.getUserData("i");
      int j = (Integer) tile.getUserData("j");
      if (i == currentI -1 && j == currentJ){
        return (TileSide) tile.getUserData("bottom");
      }
    }
    return TileSide.linear;
  }
 
  private TileSide getRightOfLeftTile(List<AbstractShape> list, int currentI, int currentJ){
    if (currentJ-1 < 0){
      return TileSide.linear;
    }
    for (Iterator<AbstractShape> iterator = list.iterator(); iterator.hasNext();) {
      AbstractShape tile = (AbstractShape) iterator.next();
      int i = (Integer) tile.getUserData("i");
      int j = (Integer) tile.getUserData("j");
      if (i == currentI && j == currentJ-1){
        return (TileSide) tile.getUserData("right");
      }
    }
    return TileSide.linear;
  }
 
  private TileSide getFittingTileSideTo(TileSide otherSide){
    TileSide fitting = TileSide.linear;
    switch (otherSide) {
    case linear:
      fitting = TileSide.linear;
      break;
    case pinIn:
      fitting = TileSide.pinOut;
      break;
    case pinOut:
      fitting = TileSide.pinIn;
      break;
    default:
      break;
    }
    return fitting;
  }
 
 
  public MTComplexPolyClusterable getPolygon(PApplet app, TileSide top, TileSide right, TileSide bottom, TileSide left, float tileWidth, float tileHeight){
    this.init(tileWidth, tileHeight);
    Vertex[] v = getTile(top, right, bottom, left);
    MTComplexPolyClusterable poly = new MTComplexPolyClusterable(app, v);
    poly.removeAllGestureEventListeners(ScaleProcessor.class);
    poly.addGestureListener(DragProcessor.class, new InertiaDragAction());
    return poly;
  }
 
  private class MTComplexPolyClusterable extends MTComplexPolygon implements IdragClusterable{
    public MTComplexPolyClusterable(PApplet app, Vertex[] vertices) {
      super(app, vertices);
    }

    public boolean isSelected() {
      return false;
    }

    public void setSelected(boolean selected) {
    }
   
  }
 
  private Vertex[] getTile(TileSide top, TileSide right, TileSide bottom, TileSide left){
    List<Vertex> list = new ArrayList<Vertex>();
   
    switch (top) {
    case linear:
      list.add(new Vertex(0,0));
      list.add(new Vertex(tileWidth, 0));
      break;
    case pinIn:
      addAll(Vertex.getDeepVertexArrayCopy(leftRightOrderHorizontalDownOut), list);
      break;
    case pinOut:
      addAll(Vertex.getDeepVertexArrayCopy(leftRightHorizontalUpOut), list);
      break;
    default:
      break;
    }
   
    switch (right) {
    case linear:
//      list.add(new Vertex(tileWidth,0));
      list.add(new Vertex(tileWidth, tileHeight));
      break;
    case pinIn:
      addAll(getCopyOffset(this.upDownOrderVerticalLeftOut, tileWidth, 0), list);
      break;
    case pinOut:
      addAll(getCopyOffset(this.upDownOrderVerticalRightOut, tileWidth, 0), list);
      break;
    default:
      break;
    }
   
   
    switch (bottom) {
    case linear:
//      list.add(new Vertex(tileWidth, tileHeight));
      list.add(new Vertex(0, tileHeight));
      break;
    case pinIn:
      addAll(getCopyOffset(this.rightLeftHorizontalUpOut, 0, tileHeight), list);
      break;
    case pinOut:
      addAll(getCopyOffset(this.rightLeftOrderHorizontalDownOut, 0, tileHeight), list);
      break;
    default:
      break;
    }
   
    switch (left) {
    case linear:
//      list.add(new Vertex(0, tileHeight));
      list.add(new Vertex(0, 0));
      break;
    case pinIn:
      addAll(Vertex.getDeepVertexArrayCopy(this.downUpOrderVerticalRightOut), list);
      break;
    case pinOut:
      addAll(Vertex.getDeepVertexArrayCopy(this.downUpOrderVerticalLeftOut), list);
      break;
    default:
      break;
    }
   
    return list.toArray(new Vertex[list.size()]);
  }
 
 
  private void addAll(Vertex[] vertices, List<Vertex> list){
    for (int i = 0; i < vertices.length; i++) {
      Vertex vertex = vertices[i];
      list.add(vertex);
    }
  }
 
 
  private Vertex[] getCopyOffset(Vertex[] verts, float xOffset, float yOffset){
    Vertex[] copy = new Vertex[verts.length];
//    Vertex[] copy = Vertex.getDeepVertexArrayCopy(verts);
    for (int i = 0; i < copy.length; i++) {
      copy[i] = (Vertex) new Vertex(verts[i]).addLocal(new Vertex(xOffset, yOffset));
    }
    return copy;
  }
 
  private Vertex[] getInvertOrderCopyOffset(Vertex[] verts, float xOffset, float yOffset){
    Vertex[] copy = new Vertex[verts.length];
//    Vertex[] copy = Vertex.getDeepVertexArrayCopy(verts);
    for (int i = 0; i < copy.length; i++) {
      copy[i] = (Vertex) new Vertex(verts[verts.length -i -1]).addLocal(new Vertex(xOffset, yOffset));
    }
    return copy;
  }
 
 
  private Vertex[] getInvertOrderCopy(Vertex[] verts){
    Vertex[] copy = new Vertex[verts.length];
//    Vertex[] copy = Vertex.getDeepVertexArrayCopy(verts);
    for (int i = 0; i < verts.length; i++) {
//      copy[i] = copy[copy.length -i -1];
      copy[i] = new Vertex(verts[verts.length -i -1]);
    }
    return copy;
  }
 
 
 

}
TOP

Related Classes of advanced.puzzle.PuzzleFactory$MTComplexPolyClusterable

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.