package com.deadtroll.controller;
import java.util.ArrayList;
import java.util.List;
import com.deadtroll.model.BoundingBox;
import com.deadtroll.model.Circulo;
import com.deadtroll.model.Poligono;
import com.deadtroll.model.PoligonoFechado;
import com.deadtroll.model.Ponto2d;
import com.deadtroll.model.Spline;
import com.deadtroll.renderer.Renderable;
import com.deadtroll.util.GeomUtil;
import com.deadtroll.util.MathUtil;
/**
* Classe controller do trabalho03<br>
* Cont�m todos os m�todos para controle de desenho, sele��o e transforma��o dos objetos
*
*/
public class Trab03Controller {
public static final int MODO_SELECAO_POLIGONOS = 0;
public static final int MODO_SELECAO_VERTICES = 1;
public static final int MODO_ADICAO_VERTICES = 2;
public static final int MODO_REMOCAO_VERTICES = 3;
public static final int MODO_REMOCAO_POLIGONOS = 4;
public static final int MODO_ADICAO_CIRCULO = 5;
public static final int MODO_ADICAO_POLIGONO_ABERTO = 6;
public static final int MODO_ADICAO_POLIGONO_FECHADO = 7;
public static final int MODO_ADICAO_SPLINE = 8;
public static final int MODO_TRANSFORMACAO_TRANSLACAO = 0;
public static final int MODO_TRANSFORMACAO_ESCALA = 1;
public static final int MODO_TRANSFORMACAO_ROTACAO = 2;
private List<Renderable> objects;
private int modoCursor = MODO_ADICAO_VERTICES;
private int modoTransformacao = MODO_TRANSFORMACAO_TRANSLACAO;
private Ponto2d verticeSelecionado;
private Renderable objetoSelecionado;
private boolean movendoPoligono;
public Trab03Controller() {
objects = new ArrayList<Renderable>();
}
/**
* Adiciona um objeto no mundo
* @param objeto
*/
public void addObject(Renderable objeto) {
this.objects.add(objeto);
}
/**
* Retorna a lista de objetos do mundo
* @return
*/
public List<Renderable> getObjects() {
return objects;
}
/**
* Tenta selecionar um pol�gono, a partir de pontoSelecao
* @param pontoSelecao
* @return
*/
public boolean select(Ponto2d pontoSelecao) {
for (Renderable objeto : objects) {
if (objeto instanceof PoligonoFechado) {
if (GeomUtil.pontoEmPoligono(pontoSelecao, (PoligonoFechado)objeto)) {
selecionarObjeto(objeto);
return true;
}
} else {
BoundingBox bbox = objeto.getBoundingBox();
if (pontoSelecao.getX() > bbox.getMinXY().getX() &&
pontoSelecao.getX() < bbox.getMaxXY().getX() &&
pontoSelecao.getY() > bbox.getMinXY().getY() &&
pontoSelecao.getY() < bbox.getMaxXY().getY()) {
selecionarObjeto(objeto);
return true;
}
}
}
return false;
}
public void desmarcarObjetoSelecionado() {
if (this.objetoSelecionado != null) {
this.objetoSelecionado.setDestacarLinhas(false);
this.objetoSelecionado.setDestacarVertices(false);
this.objetoSelecionado.setDesenharBoundingBox(false);
this.objetoSelecionado.setDesenharPosXYCentro(false);
this.movendoPoligono = false;
}
}
private void selecionarObjeto(Renderable objeto) {
if (this.objetoSelecionado != objeto) {
if (this.objetoSelecionado != null) {
desmarcarObjetoSelecionado();
}
this.objetoSelecionado = objeto;
atualizarCentroTransformacoes();
} else {
this.movendoPoligono = true;
}
this.objetoSelecionado.setDestacarLinhas(true);
this.objetoSelecionado.setDestacarVertices(true);
this.objetoSelecionado.setDesenharBoundingBox(true);
this.objetoSelecionado.setDesenharPosXYCentro(true);
this.objetoSelecionado.setPontoMouseDrag(this.objetoSelecionado.getCentro());
}
public void atualizarCentroTransformacoes() {
if (this.objetoSelecionado != null) {
this.objetoSelecionado.updateBoundingBox();
this.objetoSelecionado.setCentroTransformacoes(objetoSelecionado.getCentro());
}
}
public boolean selecionarVertice(Ponto2d pontoCursor) {
for (Renderable objeto : objects) {
if (objeto instanceof Circulo) {
Ponto2d centro = ((Circulo)objeto).getCentro();
if (MathUtil.calcularDistancia(centro, pontoCursor) <= 1.5f) {
this.verticeSelecionado = centro;
return true;
}
} else {
List<Ponto2d> pontosObjeto = null;
if (objeto instanceof Spline) {
pontosObjeto = ((Spline)objeto).getPontosControleTransformacao();
} else {
pontosObjeto = objeto.getPontosTransformacoes();
}
int indicePonto = 0;
for (Ponto2d pontoObjeto : pontosObjeto) {
if (MathUtil.calcularDistancia(pontoObjeto, pontoCursor) <= 1.5f) {
if (objeto instanceof Poligono) {
Poligono poligono = (Poligono)objeto;
this.verticeSelecionado = poligono.getPontos().get(indicePonto);
} else if (objeto instanceof Spline) {
Spline spline = (Spline)objeto;
this.verticeSelecionado = spline.getPontosControle().get(indicePonto);
}
return true;
}
indicePonto++;
}
}
}
return false;
}
/**
* Aplica rota��o no sentido hor�rio<br>
* M�todo para uso com a rotina de teclado, com incremento padr�o
*/
public void aplicarRotacaoHor() {
if (this.objetoSelecionado != null) {
float rotacao = this.objetoSelecionado.getRotacao();
this.objetoSelecionado.setRotacao((rotacao - 5) % 360);
// atualizarVerticesControle();
}
}
/**
* Aplica rota��o no sentido anti-hor�rio<br>
* M�todo para uso com a rotina de teclado, com incremento padr�o
*/
public void aplicarRotacaoAntiHor() {
if (this.objetoSelecionado != null) {
float rotacao = this.objetoSelecionado.getRotacao();
this.objetoSelecionado.setRotacao((rotacao + 5) % 360);
// atualizarVerticesControle();
}
}
/**
* Aplica aumento na escala x e y do objeto<br>
* M�todo para uso com a rotina de teclado, com incremento padr�o
*/
public void aumentarEscala() {
if (this.objetoSelecionado != null) {
float escalaX = this.objetoSelecionado.getEscalaX() + 0.1f;
float escalaY = this.objetoSelecionado.getEscalaY() + 0.1f;
this.objetoSelecionado.setEscalaX(escalaX > 3.5f ? 3.5f : escalaX);
this.objetoSelecionado.setEscalaY(escalaY > 3.5f ? 3.5f : escalaY);
// atualizarVerticesControle();
}
}
/**
* Aplica decr�scimo na escala x e y do objeto<br>
* M�todo para uso com a rotina de teclado, com decr�scimo padr�o
*/
public void diminuirEscala() {
if (this.objetoSelecionado != null) {
float escalaX = this.objetoSelecionado.getEscalaX() - 0.1f;
float escalaY = this.objetoSelecionado.getEscalaY() - 0.1f;
this.objetoSelecionado.setEscalaX(escalaX < 0.1f ? 0.1f : escalaX);
this.objetoSelecionado.setEscalaY(escalaY < 0.1f ? 0.1f : escalaY);
// atualizarVerticesControle();
}
}
/**
* Aplica incremento na transla��o x<br>
* M�todo para uso com a rotina de teclado, com incremento padr�o
*/
public void aumentarTranslacaoX() {
if (this.objetoSelecionado != null) {
float translacaoX = this.objetoSelecionado.getTranslacaoX() + 1.0f;
//TODO: usar controle baseado no centro do objeto
this.objetoSelecionado.setTranslacaoX(translacaoX);
// atualizarVerticesControle();
}
}
/**
* Aplica decr�scimo na transla��o x<br>
* M�todo para uso com a rotina de teclado, com decr�scimo padr�o
*/
public void diminuirTranslacaoX() {
if (this.objetoSelecionado != null) {
float translacaoX = this.objetoSelecionado.getTranslacaoX() - 1.0f;
//TODO: usar controle baseado no centro do objeto
this.objetoSelecionado.setTranslacaoX(translacaoX);
// atualizarVerticesControle();
}
}
/**
* Aplica incremento na transla��o y<br>
* M�todo para uso com a rotina de teclado, com incremento padr�o
*/
public void aumentarTranslacaoY() {
if (this.objetoSelecionado != null) {
float translacaoY = this.objetoSelecionado.getTranslacaoY() + 1.0f;
//TODO: usar controle baseado no centro do objeto
this.objetoSelecionado.setTranslacaoY(translacaoY);
// atualizarVerticesControle();
}
}
/**
* Aplica decr�scimo na transla��o y<br>
* M�todo para uso com a rotina de teclado, com decr�scimo padr�o
*/
public void diminuirTranslacaoY() {
if (this.objetoSelecionado != null) {
float translacaoY = this.objetoSelecionado.getTranslacaoY() - 1.0f;
//TODO: usar controle baseado no centro do objeto
this.objetoSelecionado.setTranslacaoY(translacaoY);
// atualizarVerticesControle();
}
}
/**
* Retorna o pol�gono selecionado
* @return
*/
public Ponto2d getVerticeSelecionado() {
return verticeSelecionado;
}
/**
* Atribui o v�rtice selecionado
* @param verticeSelecionado
*/
public void setVerticeSelecionado(Ponto2d verticeSelecionado) {
this.verticeSelecionado = verticeSelecionado;
}
/**
* Retorna o objeto desenh�vel selecionado
* @return
*/
public Renderable getObjetoSelecionado() {
return objetoSelecionado;
}
/**
* Retorna o modo de opera��o do cursor
* @return
*/
public int getModoCursor() {
return modoCursor;
}
/**
* Informa o modo de opera��o do cursor<br>
* Utilizar valores definidos estaticamente no controller
* @param modoCursor
*/
public void setModoCursor(int modoCursor) {
this.modoCursor = modoCursor;
}
/**
* Retorna o modo de transforma��o dos pol�gonos
* @return
*/
public int getModoTransformacao() {
return modoTransformacao;
}
/**
* Informa o modo de transforma��o dos pol�gonos<br>
* Utilizar valores definidos estaticamente no controller
* @param modoTransformacao
*/
public void setModoTransformacao(int modoTransformacao) {
this.modoTransformacao = modoTransformacao;
}
public boolean modoSelecaoPoligonos() {
return this.modoCursor == MODO_SELECAO_POLIGONOS;
}
public boolean modoSelecaoVertices() {
return this.modoCursor == MODO_SELECAO_VERTICES;
}
public boolean modoAdicaoVertices() {
return this.modoCursor == MODO_ADICAO_VERTICES;
}
public boolean modoRemocaoVertices() {
return this.modoCursor == MODO_REMOCAO_VERTICES;
}
public boolean modoRemocaoPoligonos() {
return this.modoCursor == MODO_REMOCAO_POLIGONOS;
}
public boolean modoAdicaoCirculo() {
return this.modoCursor == MODO_ADICAO_CIRCULO;
}
public boolean modoAdicaoPoligonoAberto() {
return this.modoCursor == MODO_ADICAO_POLIGONO_ABERTO;
}
public boolean modoAdicaoPoligonoFechado() {
return this.modoCursor == MODO_ADICAO_POLIGONO_FECHADO;
}
public boolean modoAdicaoSpline() {
return this.modoCursor == MODO_ADICAO_SPLINE;
}
public boolean modoTransformacaoTranslacao() {
return this.modoTransformacao == MODO_TRANSFORMACAO_TRANSLACAO;
}
public boolean modoTransformacaoEscala() {
return this.modoTransformacao == MODO_TRANSFORMACAO_ESCALA;
}
public boolean modoTransformacaoRotacao() {
return this.modoTransformacao == MODO_TRANSFORMACAO_ROTACAO;
}
public void adicionarVertice(Ponto2d pontoVertice) {
if (this.objetoSelecionado != null) {
if (this.objetoSelecionado instanceof Poligono) {
((Poligono)this.objetoSelecionado).adicionarPonto(pontoVertice);
} else if (this.objetoSelecionado instanceof Spline) {
((Spline)this.objetoSelecionado).adicionarPonto(pontoVertice);
}
}
}
public void removerVerticeSelecionado() {
if (this.objetoSelecionado != null && this.verticeSelecionado != null) {
if (this.objetoSelecionado instanceof Circulo) {
this.objects.remove(this.objetoSelecionado);
this.objetoSelecionado = null;
} else if (this.objetoSelecionado instanceof Poligono) {
Poligono poligono = (Poligono)this.objetoSelecionado;
poligono.getPontos().remove(this.verticeSelecionado);
if (poligono.getPontos().size() == 0) {
this.objects.remove(this.objetoSelecionado);
this.objetoSelecionado = null;
}
} else if (this.objetoSelecionado instanceof Spline) {
Spline spline = (Spline)this.objetoSelecionado;
spline.getPontosControle().remove(this.verticeSelecionado);
if (spline.getPontosControle().size() == 0) {
this.objects.remove(this.objetoSelecionado);
this.objetoSelecionado = null;
}
}
this.verticeSelecionado = null;
}
}
public void removerPoligonoSelecionado() {
if (this.objetoSelecionado != null) {
this.objects.remove(this.objetoSelecionado);
this.movendoPoligono = false;
this.objetoSelecionado = null;
}
}
public String descricaoModoCursor() {
String modoCursor = "Modo do cursor: ";
switch (this.modoCursor) {
case MODO_SELECAO_POLIGONOS:
modoCursor += "Sele��o de pol�gonos";
break;
case MODO_SELECAO_VERTICES:
modoCursor += "Sele��o de v�rtices";
break;
case MODO_ADICAO_VERTICES:
modoCursor += "Adi��o de v�rtices";
break;
case MODO_REMOCAO_VERTICES:
modoCursor += "Remo��o de v�rtices";
break;
case MODO_REMOCAO_POLIGONOS:
modoCursor += "Remo��o de pol�gonos";
break;
case MODO_ADICAO_CIRCULO:
modoCursor += "Adi��o de c�rculos";
break;
case MODO_ADICAO_POLIGONO_ABERTO:
modoCursor += "Adi��o de pol�gonos abertos";
break;
case MODO_ADICAO_POLIGONO_FECHADO:
modoCursor += "Adi��o de pol�gonos fechados";
break;
case MODO_ADICAO_SPLINE:
modoCursor += "Adi��o de splines";
break;
default:
break;
}
return modoCursor;
}
public String descricaoModoTransformacao() {
String modoTransf = "Modo de transforma��o: ";
switch (this.modoTransformacao) {
case MODO_TRANSFORMACAO_TRANSLACAO:
modoTransf += "Transla��o: Use as teclas direcionais";
break;
case MODO_TRANSFORMACAO_ESCALA:
modoTransf += "Escala: use as teclas UP e DOWN";
break;
case MODO_TRANSFORMACAO_ROTACAO:
modoTransf += "Rota��o: use as teclas LEFT e RIGHT";
break;
default:
break;
}
return modoTransf;
}
public boolean movendoPoligono() {
return movendoPoligono;
}
public void setMovendoPoligono(boolean movendoPoligono) {
this.movendoPoligono = movendoPoligono;
}
public String getEstadoTransformacoes() {
if (this.objetoSelecionado != null) {
switch (this.modoTransformacao) {
case MODO_TRANSFORMACAO_TRANSLACAO:
return "Transla��o X: " + this.objetoSelecionado.getTranslacaoX() +
" Transla��o Y: " + this.objetoSelecionado.getTranslacaoY();
case MODO_TRANSFORMACAO_ESCALA:
return "Escala X: " + this.objetoSelecionado.getEscalaX() +
" Escala Y: " + this.objetoSelecionado.getEscalaY();
case MODO_TRANSFORMACAO_ROTACAO:
return "Rota��o: " + this.objetoSelecionado.getRotacao() + " graus";
default:
break;
}
}
return "Nenhum pol�gono selecionado.";
}
}