cameraNode bug

Howdy cowboys,

this here is our situation. (plz update CVS first).



check this code out, and see for yourself (make sure to rotate camera to see bug). Copy/Paste first, then enjoy!



import com.jme.app.SimpleGame;
import com.jme.effects.ParticleController;
import com.jme.effects.ParticleSystem;
import com.jme.image.Texture;
import com.jme.input.InputController;
import com.jme.input.InputSystem;
import com.jme.input.NodeController;
import com.jme.intersection.CollisionDetection;
import com.jme.intersection.CollisionResults;
import com.jme.math.Line;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Box;
import com.jme.scene.CameraNode;
import com.jme.scene.Controller;
import com.jme.scene.Node;
import com.jme.scene.Text;
import com.jme.scene.TriMesh;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.TextureManager;
import com.jme.util.Timer;

/**
 * @author Ahmed
 */
public class TestParticleSystem2 extends SimpleGame {

   private ParticleSystem ps;
   private ParticleController pc;

   private Node root;

   private Camera cam;
   private CameraNode camNode;

   private Timer timer;
   private InputController input;

   private Text fps, col;
   
   private TriMesh box;

   public static void main(String[] args) {
      TestParticleSystem2 app = new TestParticleSystem2();
      app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
      app.start();
   }

   protected void update(float interpolation) {
      timer.update();
      input.update(timer.getTimePerFrame() * 10);

      fps.print("FPS: " + (int)timer.getFrameRate());
      root.updateWorldData(timer.getTimePerFrame() * 10);

      CollisionResults cs = new CollisionResults();
      CollisionDetection.hasCollision(ps, root, cs);

      if (cs.getNumber() > 0) {
         col.print("Collided:  YES");
      }else if (cs.getNumber() <= 0) {
         col.print("Collided:  NO");
      }

   }

   protected void render(float interpolation) {
      display.getRenderer().clearBuffers();
      display.getRenderer().draw(root);
   }

   protected void initSystem() {
      try {
         display = DisplaySystem.getDisplaySystem(properties.getRenderer());
         display.createWindow(
            properties.getWidth(),
            properties.getHeight(),
            properties.getDepth(),
            properties.getFreq(),
            properties.getFullscreen());

         cam =
            display.getRenderer().getCamera(
               properties.getWidth(),
               properties.getHeight());
      } catch (JmeException e) {
         e.printStackTrace();
         System.exit(1);
      }

      display.getRenderer().setBackgroundColor(new ColorRGBA(0, 0, 0, 1));

      cam.setFrustum(1f, 1000f, -0.55f, 0.55f, 0.4125f, -0.4125f);

      Vector3f loc = new Vector3f(10, 0, 0);
      Vector3f left = new Vector3f(0, -1, 0);
      Vector3f up = new Vector3f(0, 0, 1f);
      Vector3f dir = new Vector3f(-1, 0, 0);
      cam.setFrame(loc, left, up, dir);

      display.getRenderer().setCamera(cam);
      
      camNode = new CameraNode(cam);

      timer = Timer.getTimer(properties.getRenderer());
      input = new NodeController(this, camNode, properties.getRenderer());
      input.setMouseSpeed(0.2f);
      input.setKeySpeed(1f);

      InputSystem.createInputSystem(properties.getRenderer());
   }

   protected void initGame() {
      root = new Node();

      AlphaState as1 = display.getRenderer().getAlphaState();
      as1.setBlendEnabled(true);
      as1.setSrcFunction(AlphaState.SB_SRC_ALPHA);
      as1.setDstFunction(AlphaState.DB_ONE);
      as1.setTestEnabled(true);
      as1.setTestFunction(AlphaState.TF_GREATER);
      as1.setEnabled(true);

      TextureState ts = display.getRenderer().getTextureState();
      ts.setTexture(
         TextureManager.loadTexture(
            "data/texture/snowflake.png",
            Texture.MM_LINEAR,
            Texture.FM_LINEAR,
            true));
      ts.setEnabled(true);

      TextureState font = display.getRenderer().getTextureState();
      font.setTexture(
         TextureManager.loadTexture(
            "data/Font/font.png",
            Texture.MM_LINEAR,
            Texture.FM_LINEAR,
            true));
      font.setEnabled(true);

      ps = new ParticleSystem(1000);
      ps.setStartColor(new ColorRGBA(1f, 1f, 1f, 0.9f));
      ps.setEndColor(new ColorRGBA(1f, 1f, 1f, 0.1f));
      ps.setStartSize(0.2f);
      ps.setEndSize(0.1f);
      ps.setGravity(new Vector3f(0, -50, 0));
      ps.setSpeed(1f);
      ps.setFriction(3f);
      ps.setFade(0.01f);
      ps.useGeometry(true);
      ps.setGeometry(new Line(new Vector3f(-25, 0, 0), new Vector3f(25, 0, 0)));
      ps.setLocalTranslation(new Vector3f(0, 5, 10));

      pc = new ParticleController(ps);
      pc.setRepeatType(Controller.RT_WRAP);
      ps.addController(pc);
      ps.setRenderState(as1);
      ps.setRenderState(ts);
      ps.setName("Particle System");

      fps = new Text("");
      fps.setRenderState(as1);
      fps.setRenderState(font);
      fps.setName("FPS Counter");
      
      col = new Text("");
      col.setLocalTranslation(new Vector3f(0, 20, 0));
      col.setRenderState(as1);
      col.setRenderState(font);
      col.setName("Collisions");
      
      Vector3f max = new Vector3f(0.1f, 0.1f, 0.1f);
      Vector3f min = new Vector3f(-0.1f, -0.1f, -0.1f);
      box = new Box(min.mult(10), max.mult(10));
      box.setLocalTranslation(new Vector3f(-0.5f, 0, 0));
      box.setName("Box");
      
      camNode.attachChild(ps);
      camNode.setLocalTranslation(new Vector3f(0, 0, -75));

      root.attachChild(fps);
      root.attachChild(col);
      root.attachChild(box);
      root.attachChild(camNode);
      root.updateGeometricState(0.0f, true);

   }

   protected void reinit() {
   }

   protected void cleanup() {
   }
}

also, notice the speed of the snow as it drops when you are not moving the camera, compared to when you are moving the camera.



on my machine, you get a DROP in fps when you move (as you expect) but the snow gets ALOT faster.

Ok, running the second test. I think I see the problem. The snow flakes are not billboarding correctly. :’(



I also noticed the speed increasing. I’ll try to figure out what is going on with that. Overall though, the demo is cool, I just need to polish a few things to make it work better.



I’ll let you know what I find out, as soon as I find it out. :slight_smile:

P.S. There is now a compiler error in TestParticleSystem, where update is not defined for ParticleSystem. I’m assuming you forgot to commit the new version of TestParticleSystem.

Strange. I have a gut feeling, however, that the rather odd behaviour is not a bug in CameraNode. I’m rather hard put to back up my statement until I take a closer look - and that won’t be until tomorrow. A quick question, though: aren’t the particles supposed to be billboarded? If so, why can I rotate the camera such that I see the snowflakes right on their edge?







edit: Blast. My post was kinda late. Ah well.

Ok, I think I have isolated the problem. First of all, because the particle system is a child of the camera node, it turns with the camera. Which doesn’t look right when a snow flake follows you :slight_smile: This rotation of the camera is propogated to each flake, which means the flake will still be facing the camera, but in the controller a rotation by the camera’s rotation is added, effectively turning the flake twice as much. Now this is difficult, because that works great when the particle system doesn’t have the camera as it’s parent. I’m experimenting with a couple fixes, one, if the parent is an instance of CameraNode, don’t rotate with it. As to why it’s speeding up, I’m not sure.

Ok, I put a fix into CVS. Let me know what you think about that? you’ll also see why snow will need to use a plane for generation rather than a line. :slight_smile:

sorry for the delayed post, but yes, i forgot to commit the new source. Il update first, the commit the new source to the first particle test.



cheers

hate to break it to ya, but it still doesn’t work! Ive commited a new test under jmetest.effects.TestParticleSystem2.



You can still see the particles from their side. :frowning:

Ok, looking into it.

You set always rotate to true in the test. We don’t want it to always rotate. I removed that line and it works. I recommitted the test.

because if you dont set it to true, this happens:



Correct. That’s why you probably don’t want to use a line to handle snow…

but it isn’t a line, its a rectangle! So i should extend the triangle back behind the camera some?

but I dont want the player to see where the particles are being generated though! If teh player was to rotate too much upwards, they are able to see where the particles are being generated!



You could provide some clouds i suppose, but isn’t a skybox infinitely high up!



oh man, i seriously need a holiday!

That’s the rectangle? Ok, looking at the source now…



You made the rectangle very odd shaped. It’s very long and narrow.



Ahhhh… it’s on it’s side. We want it lying flat above us…



make y a constant value, and it’ sweep across the x/z plane.

tried that…i even went extravegant and used:



ps.setGeometry(
   new Rectangle(
      new Vector3f(-25, -2, -50),
      new Vector3f(25, -2, -50),
      new Vector3f(25, -2, 50)));



but you can still see where the particles are being generated! you can see em pop out of nothing, go up a tiny amount, and rush down due to gravity.

hmm...am i missing something?

Well, the particles has to be generated from some where at some time… However, there are plenty of things you can tweak to make it look better. Only make the x,z values random for initial velocity, so they don’t go up before going down. Make them higher up with a longer life span. This is where extending the controllers to make specific controllers comes in. Perhaps it’s time for a SnowController. I’ve been sitting here for about 15 minutes and just playing with the particle generation attributes have made a pretty good looking snow fall. It just requires playing with the inputs.

aaah, so we cant have that magic thing we had before where the snow is generated just above the camera, whatever the rotation is?



awsome, could you post your inputs here, because thats the best snow ive managed to make it fall. :slight_smile:

The snow is being generated just above the camera. But you are making it generate from a huge rectangle, so that huge rectangle (which is always just above the camera) can be seen. You can make the rectangle very small, the throw the particles to the side. You can make it a point generater. You can put the rectangle higher, and the particles live longer. You can do many different things here. One thing I would DEFINATELY recommend is to make whatever you use to generate them smaller and don’t use 1000 particles. That’s total overkill.