animationjavafxuv-mappingjavafx-3d

How to animate texture coordinates in javafx


Is there some kind of animation for liquid surfaces that mimics waves by animating uvcoordinates like in the picture below? Can this method be recreated in the JavaFX framework?

enter image description here


Solution

  • animating by replacing textcoordinate values

    animating normals

    Animating by replacing texture coordinate values . In this aproach , an integer property changes its value over time with the help of timeline object . there is a listener that will trigger an update in texture u and v coordinate values every time integer property changes . The result will remap normalmap over time bringing a sense of motion.

    As you can see the animation only moves in one direction . even if the normal map is seamless tile texture ; this animation is not . it will be reset every 20 seconds . this aproach need improvements , but it's a good starting point I think.

    This is a single javafx functional javafx app you can try

    normal map file is at this page

    App.java

    public class App extends Application {
    
        private final float[] uvCoords = {3, 0, 3, 3, 0, 0, 0, 3};
        private final IntegerProperty keyCycle = new SimpleIntegerProperty();
    
        @Override
        public void start(Stage stage) {
            PerspectiveCamera camera = new PerspectiveCamera(true);
            camera.setTranslateZ(-8);
            camera.setTranslateY(10);
            camera.setRotationAxis(Rotate.X_AXIS);
            camera.setRotate(45);
            PointLight pointLight = new PointLight(Color.LIGHTYELLOW);
    
            pointLight.setTranslateZ(-2.5);
            pointLight.setTranslateY(-1.5);
            pointLight.setRotationAxis(Rotate.Y_AXIS);
    
            pointLight.setQuadraticAttenuation(0.1);
            MeshView meshView = makeMeshView();
            PhongMaterial material = new PhongMaterial(new Color(0, 1, 1, 0.5));
            material.setSpecularColor(Color.LIGHTYELLOW);
            material.setSpecularPower(512);
    
            Image image = new Image("normal.jpg");
            material.setBumpMap(image);
            meshView.setMaterial(material);
    
            makeCycle();
    
            keyCycle.addListener(e -> {
    
                float add = keyCycle.getValue() / 30000f;
    
                TriangleMesh mesh = (TriangleMesh) meshView.getMesh();
                for (int i = 0; i < uvCoords.length; i++) {
                    uvCoords[i] += add;
    
                }
                mesh.getTexCoords().set(0, uvCoords, 0, uvCoords.length);
    
            });
    
            Group group3d = new Group(camera, meshView, pointLight);
            Scene scene = new Scene(group3d, 640, 480, true, SceneAntialiasing.BALANCED);
            scene.setCamera(camera);
            scene.setFill(Color.PERU);
            stage.setTitle("Animating uv coordinates in javafx");
            stage.setScene(scene);
            stage.show();
        }
    
        public static void main(String[] args) {
            launch();
        }
    
        private MeshView makeMeshView() {
            TriangleMesh mesh = new TriangleMesh();
    
            MeshView mv = new MeshView(mesh);
            mesh.getPoints().addAll(-3, -3, 0, 3, -3, 0, -3, 3, 0, 3, 3, 0);
            mesh.getTexCoords().addAll(uvCoords);
            mesh.getFaces().addAll(0, 0, 3, 3, 1, 1, 0, 0, 2, 2, 3, 3);
            return mv;
        }
    
        private void makeCycle() {
    
            KeyValue start = new KeyValue(keyCycle, 0, Interpolator.LINEAR);
    
            KeyValue end = new KeyValue(keyCycle, 24 * 20, Interpolator.LINEAR);
            KeyFrame kf = new KeyFrame(Duration.seconds(20), start, end);
    
            Timeline tm = new Timeline(kf);
            tm.setCycleCount(100);
            tm.play();
    
        }
    
    }