Strange graphical glitches every time I change source code (solved)

#Solved
The issue seemed to be outside JME. Restarting my PC fixed it, I think.

Hi. The last few days I’ve been working on implementing an RTS-style camera controller. I still suffer for these strange glitches.

The glitches have an interesting pattern… everytime I change the source code, the glitches appear on the next run. However, if I re-run it a second time, they’re gone. Until I change the source code and cause JME to recompile some stuff.

What sorcery is this? Heres a video of the glitches: https://youtu.be/l1z-7MjsZIs

Towards the 50 second mark you see me realizing the pattern (first run after a compile causes glitch)

What sorcery is this… Anyway, if you want to help, here’s the source code. Tell me if there’s anything

I create a CameraNode, with my own RTSCameraControl script attached, like so:

    //reset camera location
    camera.setLocation(new Vector3f(0,0,0));
    
    //add a cameraNode, with the RTSCameraControl attached
    CameraNode cameraNode = new CameraNode("camera_main", camera);
    cameraNode.addControl(new RTSCameraControl());
    
    //register inputs for the camera control
    cameraNode.getControl(RTSCameraControl.class).registerInputs(inputManager);
    
    //add it
    rootNode.attachChild(cameraNode);

I also disable flycam with flyCam.setEnabled(false); of course.

Here’s the RTSCameraController class:

import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.input.InputManager;
import com.jme3.input.controls.ActionListener;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;

public class RTSCameraControl extends AbstractControl implements ActionListener {

    public static Vector3f down = new Vector3f(0, -1f, 0);

    private Geometry terrain;

    private boolean isMovingLeft;
    private boolean isMovingRight;
    private boolean isMovingUp;
    private boolean isMovingDown;

    private boolean isRotatingLeft;
    private boolean isRotatingRight;

    private boolean isZoomingIn;
    private boolean isZoomingOut;

    private Vector3f velocity = new Vector3f();
    private float accel = 5f;
    private float maxSpeed = 50f;

    public float minX = 0f;
    public float maxX = 200f;
    public float minZ = -10f;
    public float maxZ = 200f;

    public float zoom = 60f;
    public float minZoom = 10f;
    public float maxZoom = 200f;

    public float zoomVel = 0f;
    public float zoomAccel = 10f;
    public float zoomMaxSpeed = 100f;

    public float tilt = 75f / 180 * FastMath.PI;

    private float rotation = 0f;
    public float rotVel = 0f;
    public float rotAccel = 0.1f;
    public float rotMaxVel = 1f;

    @Override
    public void setSpatial(Spatial spatial) {
        super.setSpatial(spatial);
        spatial.setLocalTranslation(0f, maxZoom, -10f);
        spatial.setLocalRotation(new Quaternion().fromAngles(tilt, 0, 0));
    }

    public void setTerrain(Geometry terrain) {
        this.terrain = terrain;
    }

    @Override
    protected void controlUpdate(float tpf) {
        //detect terrain height
        float terrainHeight = 0f;
        if (terrain != null) {
            Ray ray = new Ray(spatial.getWorldTranslation(), down);
            CollisionResults results = new CollisionResults();
            terrain.collideWith(ray, results);
            CollisionResult result = results.getClosestCollision();
            if (result != null) {
                terrainHeight = result.getContactPoint().y;
            }
        }

        //reset rotation
        spatial.setLocalRotation(new Quaternion().fromAngles(0, 0, 0));

        //accelerate
        if (isMovingLeft) velocity.x += accel * tpf;
        if (isMovingRight) velocity.x -= accel * tpf;
        if (isMovingUp) velocity.z += accel * tpf;
        if (isMovingDown) velocity.z -= accel * tpf;

        if (isZoomingIn) zoomVel += zoomAccel * tpf;
        if (isZoomingOut) zoomVel -= zoomAccel * tpf;

        if (isRotatingLeft) rotVel += rotAccel * tpf;
        if (isRotatingRight) rotVel -= rotAccel * tpf;

        //clamp
        if (velocity.x > maxSpeed) velocity.x = maxSpeed;
        if (velocity.x < -maxSpeed) velocity.x = -maxSpeed;
        if (velocity.z > maxSpeed) velocity.z = maxSpeed;
        if (velocity.z < -maxSpeed) velocity.z = -maxSpeed;

        if (zoomVel > zoomMaxSpeed) zoomVel = zoomMaxSpeed;
        if (zoomVel < -zoomMaxSpeed) zoomVel = -zoomMaxSpeed;

        if (rotVel > rotMaxVel) rotVel = rotMaxVel;
        if (rotVel < -rotMaxVel) rotVel = -rotMaxVel;

        //zoom
        zoom += zoomVel;

        //clamp zoom value
        if (zoom > maxZoom) zoom = maxZoom;
        if (zoom < minZoom) zoom = minZoom;

        rotation += rotVel;

        //apply rotation
        spatial.rotate(0, rotation, 0);

        //move relative to Y rotation
        spatial.move(spatial.getLocalRotation().mult(velocity));

        //set Y location (height)
        Vector3f loc = spatial.getLocalTranslation();
        loc.setY(terrainHeight + zoom);

        //clamp position within bounds
        if (loc.x > maxX) loc.x = maxX;
        if (loc.x < minX) loc.x = minX;
        if (loc.z > maxZ) loc.z = maxZ;
        if (loc.z < minZ) loc.z = minZ;

        //apply tilt
        spatial.rotate(tilt, 0, 0);

        //apply friction
        velocity.interpolate(Vector3f.ZERO, 0.1f * tpf);
        rotVel = FastMath.interpolateLinear(0.1f * tpf, rotVel, 0f);
        zoomVel = FastMath.interpolateLinear(0.1f * tpf, zoomVel, 0f);

        //reset isZoom* variables
        isZoomingIn = isZoomingOut = false;
    }

    @Override
    protected void controlRender(RenderManager rm, ViewPort vp) {

    }

    public void registerInputs(InputManager inputManager) {
        inputManager.addListener(this, "camera.move_left", "camera.move_right", "camera.move_up", "camera.move_down", "camera.rotate_left", "camera.rotate_right", "camera.zoom_in", "camera.zoom_out");
    }

    public void onAction(String name, boolean isPressed, float tpf) {
        if (name.equals("camera.move_left")) isMovingLeft = isPressed;
        if (name.equals("camera.move_right")) isMovingRight = isPressed;
        if (name.equals("camera.move_up")) isMovingUp = isPressed;
        if (name.equals("camera.move_down")) isMovingDown = isPressed;

        if (name.equals("camera.rotate_left")) isRotatingLeft = isPressed;
        if (name.equals("camera.rotate_right")) isRotatingRight = isPressed;

        if (name.equals("camera.zoom_in")) isZoomingIn = isPressed;
        if (name.equals("camera.zoom_out")) isZoomingOut = isPressed;
    }

}