Screen flickers when rotating the camera

Hi,



I'm a beginner here and while trying to focus my camera towards a moving object, the screen flickers between the original view and the view pointing towards the said object. All (I think) I do is to call the



cam.lookAt(focusPoint.getWorldTranslation(), cam.getUp());



in the simpleUpdate() method. Can someone give me a clue? (Most of the code comes from the physics ragdoll test class)



The code is below, the cam.lookAt method is in the adjustView method called in the init and in the simpleUpdate:



package com.copycatz.balldrop.prototype;

import static com.copycatz.balldrop.util.SpatialUtils.color;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.copycatz.balldrop.props.Swing;
import com.jme.input.InputHandler;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.input.action.InputAction; import com.jme.input.action.InputActionEvent;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.shape.GeoSphere;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.material.Material;
import com.jmex.physics.util.SimplePhysicsGame;

/**
 * @author Ky Vinh
 *
 */
public class BallDrop1 extends SimplePhysicsGame {

   private Swing slide;

   private Node focusPoint;

   /*
    * (non-Javadoc)
    *
    * @see com.jme.app.BaseSimpleGame#simpleInitGame()
    */
   @Override
   protected void simpleInitGame() {
      addSimpleSlide();
      configurePhysicsPicker();
      registerDropBallAction();
      adjustCameraView();
   }

   private void registerDropBallAction() {

      InputAction createAction = new InputAction() {
         public void performAction(InputActionEvent evt) {
            if (evt == null || evt.getTriggerPressed()) {
               focusPoint = addDroppingBall();
            }
         }
      };
      input.addAction(createAction, InputHandler.DEVICE_KEYBOARD,
            KeyInput.KEY_SPACE, InputHandler.AXIS_NONE, false);

   }

   private Node addDroppingBall() {

      DynamicPhysicsNode ballNode = getPhysicsSpace().createDynamicNode();
      rootNode.attachChild(ballNode);

      GeoSphere ball = new GeoSphere("droppingball", true, 2);
      ballNode.attachChild(ball);
      ballNode.generatePhysicsGeometry();

      ballNode.setLocalScale(0.75f);
      ballNode.setMaterial(Material.GRANITE);
      color(ballNode, display, new ColorRGBA(0.5f, 0.5f, 0.9f, 0.3f));
      ballNode.computeMass();
      ballNode.getLocalTranslation().y += 3;
      ballNode.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);

      rootNode.updateWorldData(0);
      rootNode.updateGeometricState(0, false);
      rootNode.updateRenderState();

      return ballNode;
   }

   @Override
   protected void simpleUpdate() {

      slide.update();

      adjustCameraView();

      /*
       * rootNode.updateWorldData(0); rootNode.updateGeometricState(0, false);
       * rootNode.updateRenderState();
       */
   }

   private void addSimpleSlide() {

      slide = new Swing(getPhysicsSpace(), 20);
      color(slide, display, new ColorRGBA(0.9f, 0.9f, 0.3f, 1));
      rootNode.attachChild(slide);

   }

   private void adjustCameraView() {

      if (focusPoint != null) {
         // [b]The line below makes the screen flicker[/b]
         cam.lookAt(focusPoint.getWorldTranslation(), cam.getUp());
         // cam.getLocation().y = focusPoint.getLocalTranslation().y;
         // cam.update();
      } else {
         // cam.getLocation().x -= 10;
         // cam.getLocation().y += 10;
         // cam.getLocation().z += 10;
         cam.lookAt(slide.getWorldTranslation(), new Vector3f(0, 1, 0));
      }

   }

   public static void main(String[] args) {
      Logger.getLogger("").setLevel(Level.WARNING);
      final BallDrop1 app = new BallDrop1();
      // app.setDialogBehaviour(AbstractGame.ALWAYS_SHOW_PROPS_DIALOG);
      new Thread() {
         @Override
         public void run() {
            app.start();
         }
      }.start();
   }

   private void configurePhysicsPicker() {
      cameraInputHandler.setEnabled(false);
      // new PhysicsPicker(input, rootNode, getPhysicsSpace(), true);
      MouseInput.get().setCursorVisible(true);
   }
}

You didn't send your Swing class and the color() method. I couldn't compile and test here.

sorry, they are very simple classes so I left them behind:



Swing.java:



/**
 *
 */
package com.copycatz.balldrop.props;

import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.Joint;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.RotationalJointAxis;
import com.jmex.physics.material.Material;

/**
 * @author Ky Vinh
 *
 */
public class Swing extends Node {

   private static final long serialVersionUID = 1L;

   private final DynamicPhysicsNode slideNode;

   private final RotationalJointAxis rotAxis;

   public Swing(PhysicsSpace physicsSpace, float length) {
      slideNode = physicsSpace.createDynamicNode();
      slideNode.setAffectedByGravity(false);
      this.attachChild(slideNode);

      final Box slide = new Box("slide", new Vector3f(), 1f, 0.1f, length / 2);
      slideNode.attachChild(slide);
      slideNode.setMaterial(Material.WOOD);

      Quaternion rollABit = new Quaternion();
      rollABit.fromAngleAxis(FastMath.PI / 8, new Vector3f(0, 0, 1));
      rollABit.fromAngleAxis(FastMath.PI / 16, new Vector3f(1, 0, 0));
      slideNode.setLocalRotation(rollABit);
      slideNode.generatePhysicsGeometry();
      slideNode.computeMass();

      // now create a joint for fastening and controlling the slide
      // (see TestMarble.java)
      final Joint joint = physicsSpace.createJoint();
      // rotation around the X-axis
      rotAxis = joint.createRotationalAxis();
      rotAxis.setDirection(new Vector3f(1, 0, 0));
      rotAxis.setAvailableAcceleration(100000);
      rotAxis.setDesiredVelocity(1);
      rotAxis.setPositionMaximum(FastMath.PI / 8);
      rotAxis.setPositionMinimum(-FastMath.PI / 8);
      joint.attach(slideNode);

   }

   public void update() {

      if (rotAxis.getPosition() >= rotAxis.getPositionMaximum()
            || rotAxis.getPosition() <= rotAxis.getPositionMinimum()) {
         rotAxis.setDesiredVelocity(rotAxis.getDesiredVelocity() * -1);
      }

      /*
       * // DOES NOT WORK !!! // rotate this slide a bit Quaternion rollABit =
       * new Quaternion(); rollABit.fromAngleAxis(FastMath.PI / 256, new
       * Vector3f(0, 1, 0)); slideNode.setLocalRotation(rollABit);
       * slideNode.updateGeometricState(0, false);
       * slideNode.updateRenderState();
       */
   }
}



and the color method:


/**
 *
 */
package com.copycatz.balldrop.util;

import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Spatial;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.MaterialState;
import com.jme.system.DisplaySystem;

/**
 * @author Ky Vinh
 *
 */
public class SpatialUtils {

   /**
    * Little helper method to color a spatial.
    *
    * @param spatial
    *

… and when you press the space bar, the screen will start flickering between the original camera direction and the one set in adjustCameraView. Why would that be?

I don’t know anything about phisics, but this piece of code is quite strange in a default base jME application.



new Thread() {

    @Override

    public void run() {

        app.start();

    }

}.start();




Doesn’t it?

Yes and no… You can have that if you want, it wouldn't help, and certainly it will hinder you alittle bit by creating another thread. Perhaps that came from programming in C/C++ in which is customary to launch a thread to do all the application logic.

That new thread is important to have the -Xss flag of the vm applied (the main thread never has an altered stack size).

Yes, removing that thread thing does not change the problem, unfortunately. Maybe I have to create a separate camera node instead of using the one setup by SimpleGame…

Uhmmm!



What I guessed is because the kind of problem, you described, behaves as if 2 different pieces of code want to take controll of the camera during each loop iteration. The first piece of code says to the camera

Just out of curiosity, does this problem is also associated with low FPS? The reason why I ask, is because some camera nodes (particularly ChaseCamera) have been known to have numerical instabilities in updates. Search the forums if that is so.

Ender said:

What I guessed is because the kind of problem, you described, behaves as if 2 different pieces of code want to take controll of the camera during each loop iteration. The first piece of code says to the camera
kyvinh said:
Thanks Ender, but removing that thread code does not fix things.


Yes, yes! ;) I saw you already said it in a previous post.

kyvinh said:
But I just saw that BaseSimpleGame uses a FirstPersonHandler (with the cam as a parameter) that might interfere with my code that rotates the camera... that might be it.


You should probably extends directly BaseGame. As done in the FlagRush tutorial. To be sure you control directly everything.