You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.1 KiB

package visualiser.layout;
import javafx.geometry.Point3D;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.MeshView;
import javafx.scene.shape.Shape3D;
import javafx.scene.shape.TriangleMesh;
import visualiser.utils.PerlinNoiseGenerator;
/**
* Creates a SeaSurface
*/
public class SeaSurface extends Subject3D {
private static Image image;
/**
* Sea Surface Constructor
*
* @param size size of the sea surface (has to be square for simplicity's sake)
* @param freq frequency the perlin noise is to be generated at
*/
public SeaSurface(int size, double freq) {
super(createSurface(size, freq), 0);
image = new Image(getClass().getClassLoader().getResourceAsStream("images/skybox/ThickCloudsWaterDown2048.png"));
}
/**
* Creates the sea surface
* @param size size of sea noise array.
* @param freq frequency of sea noise array.
* @return The sea surface.
*/
private static Shape3D createSurface(int size, double freq) {
float[][] noiseArray = PerlinNoiseGenerator.createNoise(size, freq);
Image diffuseMap = createImage(noiseArray.length, noiseArray); //image
PhongMaterial material = new PhongMaterial();
material.setDiffuseColor(Color.web("#FFFFFF"));
material.setSpecularColor(Color.web("#000000"));
material.setDiffuseMap(diffuseMap);
Plane3D seaPlane = new Plane3D(noiseArray.length, noiseArray.length, 10, 10);
MeshView seaSurface = new MeshView(seaPlane);
seaSurface.setMaterial(material);
seaSurface.setMouseTransparent(true);
seaSurface.toFront();
return seaSurface;
}
/**
* Create texture for uv mapping
*
* @param size size of the image to make
* @param noise array of noise
* @return image that is created
*/
private static Image createImage(double size, float[][] noise) {
int width = (int) size;
int height = (int) size;
WritableImage wr = new WritableImage(width, height);
PixelWriter pw = wr.getPixelWriter();
//interpolate colours based on noise
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
float value = noise[x][y];
double gray = normalizeValue(value, -.5, .5, 0., 1.);
gray = clamp(gray, 0, 1);
//values to interpolate on
Color brightBlue = new Color(0.06, 0.5, .78, 1);
Color lightBlue = new Color(0.15, 0.68, .88, 1);
Color lighterBlue = new Color(0.28, 0.73, .91, 1);
Color colour = Color.WHITE.interpolate(brightBlue, gray).interpolate(lighterBlue, gray).interpolate(lightBlue, gray);
pw.setColor(x, y, colour);
}
}
return wr;
}
/**
* Nomalises the values so that the colours are correct
*
* @param value value to normalise
* @param min current min
* @param max current max
* @param newMin new min
* @param newMax new max
* @return returns normalised value
*/
private static double normalizeValue(double value, double min, double max, double newMin, double newMax) {
return (value - min) * (newMax - newMin) / (max - min) + newMin;
}
/**
* clamps a value between a min and max
*
* @param value value to clamp
* @param min minimum value it can be
* @param max maximum value it can be
* @return result after clamp
*/
private static double clamp(double value, double min, double max) {
if (Double.compare(value, min) < 0)
return min;
if (Double.compare(value, max) > 0)
return max;
return value;
}
/**
* Prevent rescaling of sea surface
*
* @param scale ignored
*/
@Override
public void setScale(double scale) {
}
}