/*
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 org.jwildfire.base.Property;
import org.jwildfire.base.PropertyMin;
import org.jwildfire.image.WFImage;
import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
public class Magnet3DTransformer extends Mesh3DTransformer {
public enum Shape {
SHARP, SMOOTH
}
@Property(description = "Strength of the effect")
@PropertyMin(0.0)
private double strength = 1.0;
@Property(description = "X-coordinate of the source point")
private double srcX = 400.0;
@Property(description = "Y-coordinate of the source point")
private double srcY = 400.0;
@Property(description = "Z-coordinate of the source point")
private double srcZ = 0.0;
@Property(description = "X-coordinate of the destination")
private double dstX = 400.0;
@Property(description = "Y-coordinate of the destination")
private double dstY = 400.0;
@Property(description = "Z-coordinate of the destination")
private double dstZ = 100.0;
@Property(description = "Shape of the effect", editorClass = ShapeEditor.class)
private Shape shape = Shape.SMOOTH;
@Override
protected void transformMesh(Mesh3D pMesh3D, int pImageWidth, int pImageHeight) {
int width = pImageWidth;
int height = pImageHeight;
int pCount = pMesh3D.getPCount();
double x[] = pMesh3D.getX();
double y[] = pMesh3D.getY();
double z[] = pMesh3D.getZ();
double srcX = this.srcX - (double) width / 2.0;
double srcY = this.srcY - (double) height / 2.0;
double srcZ = 0.0 - this.srcZ;
double dstX = this.dstX - (double) width / 2.0;
double dstY = this.dstY - (double) height / 2.0;
double dstZ = 0.0 - this.dstZ;
double strength = this.strength;
strength = strength * 0.001;
if (strength < 0.0)
strength = 0.0 - strength;
if ((Math.abs(srcX - dstX) < 0.000001) && (Math.abs(srcY - dstY) < 0.000001)
&& (Math.abs(srcZ - dstZ) < 0.000001))
return;
if (shape == Shape.SHARP) {
for (int i = 0; i < pCount; i++) {
double dx = x[i] - srcX;
double dy = y[i] - srcY;
double dz = z[i] - srcZ;
double dr = Math.sqrt(dx * dx + dy * dy + dz * dz);
if (dr < 0.00001)
dr = 0.00001;
double F = Math.exp(-dr * dr * strength);
dx = x[i] - dstX;
dy = y[i] - dstY;
dz = z[i] - dstZ;
x[i] -= dx * F;
y[i] -= dy * F;
z[i] -= dz * F;
}
}
else {
dstX = srcX + srcX - dstX;
dstY = srcY + srcY - dstY;
dstZ = srcZ + srcZ - dstZ;
for (int i = 0; i < pCount; i++) {
double dx = x[i] - srcX;
double dy = y[i] - srcY;
double dz = z[i] - srcZ;
double dr = Math.sqrt(dx * dx + dy * dy + dz * dz);
if (dr < 0.00001)
dr = 0.00001;
double F = Math.exp(-dr * dr * strength);
dx = x[i] - dstX;
dy = y[i] - dstY;
dz = z[i] - dstZ;
x[i] += dx * F;
y[i] += dy * F;
z[i] += dz * F;
}
}
}
@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);
srcX = Math.round((double) width / 2.2);
srcY = Math.round((double) height / 2.4);
srcZ = 0.0;
dstX = Math.round((double) width / 2.2);
dstY = Math.round((double) height / 2.4);
dstZ = Math.round(rr / 10);
strength = 0.5;
shape = Shape.SMOOTH;
alpha = 10.0;
beta = 70.0;
}
public double getStrength() {
return strength;
}
public void setStrength(double strength) {
this.strength = strength;
}
public double getSrcX() {
return srcX;
}
public void setSrcX(double srcX) {
this.srcX = srcX;
}
public double getSrcY() {
return srcY;
}
public void setSrcY(double srcY) {
this.srcY = srcY;
}
public double getSrcZ() {
return srcZ;
}
public void setSrcZ(double srcZ) {
this.srcZ = srcZ;
}
public double getDstX() {
return dstX;
}
public void setDstX(double dstX) {
this.dstX = dstX;
}
public double getDstY() {
return dstY;
}
public void setDstY(double dstY) {
this.dstY = dstY;
}
public double getDstZ() {
return dstZ;
}
public void setDstZ(double dstZ) {
this.dstZ = dstZ;
}
public Shape getShape() {
return shape;
}
public void setShape(Shape shape) {
this.shape = shape;
}
public static class ShapeEditor extends ComboBoxPropertyEditor {
public ShapeEditor() {
super();
setAvailableValues(new Shape[] { Shape.SMOOTH, Shape.SHARP });
}
}
}