/*
JWildfire - an image and animation processor written in Java
Copyright (C) 1995-2011 Andreas Maschke
This 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 software 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 software;
if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jwildfire.transform;
import java.util.HashMap;
import org.jwildfire.base.Property;
import org.jwildfire.base.PropertyCategory;
import org.jwildfire.base.PropertyMin;
import org.jwildfire.image.WFImage;
public class CubeTransformer extends Mesh3DTransformer {
@Property(category = PropertyCategory.PRIMARY, description = "Size of the cube")
@PropertyMin(1.0)
private double size = 120.0;
@Override
protected void transformMesh(Mesh3D pMesh3D, int pImageWidth, int pImageHeight) {
int pCount = pMesh3D.getPCount();
double x[] = pMesh3D.getX();
double y[] = pMesh3D.getY();
double z[] = pMesh3D.getZ();
double size = this.size;
if (size < 1.0)
size = 1.0;
double xmin = x[0], xmax = xmin;
double ymin = y[0], ymax = ymin;
for (int i = 0; i < pCount; i++) {
if (x[i] < xmin)
xmin = x[i];
else if (x[i] > xmax)
xmax = x[i];
if (y[i] < ymin)
ymin = y[i];
else if (y[i] > ymax)
ymax = y[i];
}
double xsize = xmax - xmin;
double ysize = ymax - ymin;
HashMap<Integer, Integer> pointDestination = new HashMap<Integer, Integer>();
// 1 | 2 | 3
// ---------
// 4 | 5 | 6
// / ---
// / 5 / | behind: 3
// ----/ | left: 4
// | 1 | 2/ bottom: 6
// | | /
// ----
if (xsize > ysize) {
double areaWidth = xsize / 3.0;
double areaHeight = ysize / 2.0;
double xScale = size / areaWidth;
double yScale = size / areaHeight;
double x0 = xmin;
double x1 = x0 + areaWidth;
double x2 = x1 + areaWidth;
//double x3 = xmax;
double y0 = ymin;
double y1 = y0 + areaHeight;
//double y2 = ymax;
double xTrans1 = areaWidth;
double yTrans1 = areaHeight / 2.0;
double zTrans1 = -size / 2.0;
double xTrans2 = 0;
double yTrans2 = areaHeight / 2.0;
double zTrans2 = -size / 2.0;
double xTrans3 = -areaWidth;
double yTrans3 = areaHeight / 2.0;
double zTrans3 = -size / 2.0;
double xTrans4 = areaWidth;
double yTrans4 = -areaHeight / 2.0;
double zTrans4 = -size / 2.0;
double xTrans5 = 0;
double yTrans5 = -areaHeight / 2.0;
double zTrans5 = -size / 2.0;
double xTrans6 = -areaWidth;
double yTrans6 = -areaHeight / 2.0;
double zTrans6 = -size / 2.0;
for (int i = 0; i < pCount; i++) {
double xx = x[i];
double yy = y[i];
double zz = z[i];
if (xx <= x1) {
// 1
if (yy <= y1) {
xx = (xx + xTrans1) * xScale;
yy = (yy + yTrans1) * yScale;
zz = zz + zTrans1;
x[i] = xx;
y[i] = yy;
z[i] = zz;
pointDestination.put(Integer.valueOf(i), Integer.valueOf(1));
}
// 4
else {
xx = (xx + xTrans4) * xScale;
yy = (yy + yTrans4) * yScale;
zz = zz + zTrans4;
x[i] = zz;
y[i] = yy;
z[i] = -xx;
pointDestination.put(Integer.valueOf(i), Integer.valueOf(4));
}
}
else if ((xx > x1) && (xx <= x2)) {
// 2
if (yy <= y1) {
xx = (xx + xTrans2) * xScale;
yy = (yy + yTrans2) * yScale;
zz = zz + zTrans2;
x[i] = -zz;
y[i] = yy;
z[i] = xx;
pointDestination.put(Integer.valueOf(i), Integer.valueOf(2));
}
// 5
else {
xx = (xx + xTrans5) * xScale;
yy = (yy + yTrans5) * yScale;
zz = zz + zTrans5;
x[i] = xx;
y[i] = zz;
z[i] = -yy;
pointDestination.put(Integer.valueOf(i), Integer.valueOf(5));
}
}
else /*if (xx > x2) */{
// 3
if (yy <= y1) {
xx = (xx + xTrans3) * xScale;
yy = (yy + yTrans3) * yScale;
zz = zz + zTrans3;
x[i] = -xx;
y[i] = yy;
z[i] = -zz;
pointDestination.put(Integer.valueOf(i), Integer.valueOf(3));
}
// 6
else {
xx = (xx + xTrans6) * xScale;
yy = (yy + yTrans6) * yScale;
zz = zz + zTrans6;
x[i] = xx;
y[i] = -zz;
z[i] = yy;
pointDestination.put(Integer.valueOf(i), Integer.valueOf(6));
}
}
}
}
// 1 | 2
// -----
// 3 | 4
// -----
// 5 | 6
// / ---
// / 5 / | behind: 3
// ----/ | left: 6
// | 1 | 2/ bottom: 4
// | | /
// ----
else {
double areaWidth = xsize / 2.0;
double areaHeight = ysize / 3.0;
double xScale = size / areaWidth;
double yScale = size / areaHeight;
double x0 = xmin;
double x1 = x0 + areaWidth;
//double x2 = xmax;
double y0 = ymin;
double y1 = y0 + areaHeight;
double y2 = y1 + areaHeight;
// double y3 = ymax;
double xTrans1 = areaWidth / 2.0;
double yTrans1 = areaHeight;
double zTrans1 = -size / 2.0;
double xTrans2 = -areaWidth / 2.0;
double yTrans2 = areaHeight;
double zTrans2 = -size / 2.0;
double xTrans3 = areaWidth / 2.0;
double yTrans3 = 0.0;
double zTrans3 = -size / 2.0;
double xTrans4 = -areaWidth / 2.0;
double yTrans4 = 0.0;
double zTrans4 = -size / 2.0;
double xTrans5 = areaWidth / 2.0;
double yTrans5 = -areaHeight;
double zTrans5 = -size / 2.0;
double xTrans6 = -areaWidth / 2.0;
double yTrans6 = -areaHeight;
double zTrans6 = -size / 2.0;
for (int i = 0; i < pCount; i++) {
double xx = x[i];
double yy = y[i];
double zz = z[i];
if (xx <= x1) {
// 1
if (yy <= y1) {
xx = (xx + xTrans1) * xScale;
yy = (yy + yTrans1) * yScale;
zz = zz + zTrans1;
x[i] = xx;
y[i] = yy;
z[i] = zz;
pointDestination.put(Integer.valueOf(i), Integer.valueOf(1));
}
// 3
else if ((yy > y1) && (yy <= y2)) {
xx = (xx + xTrans3) * xScale;
yy = (yy + yTrans3) * yScale;
zz = zz + zTrans3;
x[i] = -xx;
y[i] = yy;
z[i] = -zz;
pointDestination.put(Integer.valueOf(i), Integer.valueOf(3));
}
// 5
else /*if (yy > y2)*/{
xx = (xx + xTrans5) * xScale;
yy = (yy + yTrans5) * yScale;
zz = zz + zTrans5;
x[i] = xx;
y[i] = zz;
z[i] = -yy;
pointDestination.put(Integer.valueOf(i), Integer.valueOf(5));
}
}
else /*if(xx>x1)*/{
// 2
if (yy <= y1) {
xx = (xx + xTrans2) * xScale;
yy = (yy + yTrans2) * yScale;
zz = zz + zTrans2;
x[i] = -zz;
y[i] = yy;
z[i] = xx;
pointDestination.put(Integer.valueOf(i), Integer.valueOf(2));
}
// 4
else if ((yy > y1) && (yy <= y2)) {
xx = (xx + xTrans4) * xScale;
yy = (yy + yTrans4) * yScale;
zz = zz + zTrans4;
x[i] = xx;
y[i] = -zz;
z[i] = yy;
pointDestination.put(Integer.valueOf(i), Integer.valueOf(4));
}
// 6
else /*if (yy > y2)*/{
xx = (xx + xTrans6) * xScale;
yy = (yy + yTrans6) * yScale;
zz = zz + zTrans6;
x[i] = zz;
y[i] = yy;
z[i] = -xx;
pointDestination.put(Integer.valueOf(i), Integer.valueOf(6));
}
}
}
}
// remove unused/illegal faces
int p1[] = pMesh3D.getPP1();
int p2[] = pMesh3D.getPP2();
int p3[] = pMesh3D.getPP3();
int color[] = pMesh3D.getColor();
int fCount = pMesh3D.getFCount();
int newFCount = 0;
int newP1[] = new int[fCount];
int newP2[] = new int[fCount];
int newP3[] = new int[fCount];
int newColor[] = color != null ? new int[fCount] : null;
for (int i = 0; i < fCount; i++) {
int dest1 = pointDestination.get(Integer.valueOf(p1[i]));
int dest2 = pointDestination.get(Integer.valueOf(p2[i]));
if (dest1 != dest2)
continue;
int dest3 = pointDestination.get(Integer.valueOf(p3[i]));
if (dest2 != dest3)
continue;
newP1[newFCount] = p1[i];
newP2[newFCount] = p2[i];
newP3[newFCount] = p3[i];
if (newColor != null) {
newColor[newFCount] = color[i];
}
newFCount++;
}
pMesh3D.setFCount(newFCount);
pMesh3D.setPP1(newP1);
pMesh3D.setPP2(newP2);
pMesh3D.setPP3(newP3);
pMesh3D.setColor(newColor);
}
@Override
public void initDefaultParams(WFImage pImg) {
super.initDefaultParams(pImg);
int width = pImg.getImageWidth();
int height = pImg.getImageHeight();
double rr = Math.sqrt(width * width + height * height);
size = Math.round(rr / (3.0 * Math.sqrt(2.0)));
zoom = 1.0;
ambient = 0.40;
alpha = 25.0;
beta = -35.0;
}
public double getSize() {
return size;
}
public void setSize(double size) {
this.size = size;
}
}