Spin Math 101

Hello all. I am hoping some folks can help me out with a little 3D math. This being my first 3D venture, this is probably pretty easy… feel free to snicker. :stuck_out_tongue:



I am wanting to redefine my mouse actions so that a scene will pivot around a single point. The environment I will be creating is a 3D ground map w/ a 2D sprite centered in the middle of the screen – this sprite will always remain in the middle and is what the scene should pivot around.



What I was planning is to write a KeySpinRightAction (and the 3 other directions) with a pivot which will reference the sprites location within the space. As the sprite moves, the camera moves accordingly and the sprite remains in the middle of the screen.



So I’m just wondering if anyone can help me with the math involved to spin that camera around? Thanks for any tips!

Hey, check out this thread:



http://www.mojomonkeycoding.com/jmeforum/viewtopic.php?t=874&postdays=0&postorder=asc&highlight=spherical+cartesian&start=15

Actually, the whole system your looking for is avialable on code review



I suggest you use the classes I posted, since DP’s still has some bugs in it.


since DP's still has some bugs in it


That is true. But my system is supposed to work for camera's not spatials. So If you were to change it to spatials. It would require alot of work.

Btw, i haven't had much time on the PC recently to fix the bugs in both the laser trail and the camera system and create joints in the physics system and find a way to combine jME's collision system with ODE's physics.

Il start on them towards the end of january as I have very important exams coming up and I have to revise for them.

DP

Thanks everyone! I checked out the code review post and did a whole bunch of copy/paste of DP’s code and got it mostly working. :wink: My vertical look (using keyboard or mouse) isn’t working, but I think that has been pointed out in the other post by simon56.



Thanks for the pointers, I’ll be sure to follow that thread for updates… I’ll probably post to this thread when I start running into more problems due to my ignorance.

Hello again all. I figure this is a better thread to ask in, then the code review thread, so as not to clutter things up.



I have been playing with the ThirdPersonHandler code (suggested to me, and linked, in this thread) and have gotten it to work the way I want it to – except two aspects.


  1. I can rotate left/right, but not up/down. From the thread it sounds like this is a known bug, but hasn’t been fixed yet – yes? I can always wait, the up/down is 1000x less important to me. :slight_smile:


  2. How can I alter the angle at which the camera looks at the Spatial it should follow? I’ve tinkered a bit with it, but the ThirdPersonHandler seems to overpower my efforts and always wants to look at the center of my Spatial (a BillboardNode). I have a ground node which I want to look down on at an angle – how can I go about telling the camera to follow my BillboardNode while looking at everything else from an angle?



    Thanks so much for everyones help!

This was why I suggested using the classes I posted instead.

"Boiler98" wrote:
From the thread it sounds like this is a known bug, but hasn't been fixed yet -- yes?
Yes.

@2: I guess you could invoke this method taken from CameraHandler, after you call CameraHandler.update(float):


   /**
    * Makes the camera face its target.
    */
   private void lookAtTarget() {
       dirVec.x = 0;
       dirVec.y = 0;
       dirVec.z = 0;
      
       dirVec.set(targetPos).subtractLocal(cameraPos).normalizeLocal();

       upVec.x = 0;
       upVec.y = 1;
       upVec.z = 0;
      
       leftVec = upVec.cross(dirVec).normalizeLocal();
       upVec = dirVec.cross(leftVec).normalizeLocal();

       cam.setAxes(leftVec, upVec, dirVec);
   }


Where cameraPos = Camera.getLocation(), and targetPos = getWorldTranslation() from the Spatial you want your camera to face.

Hope that helps :)

/Per

Thanks Per!



I guess I misunderstood your first post. You are DP are tossing stuff back and forth in that thread, I didn’t pay enough attention. :// I’ll go back in and look at your posts.



Thanks again!

Sorry Per… do you have any example code showing how to plug in your classes? Are they called from something similar to the "ThirdPersonHandler" class?


do you have any example code showing how to plug in your classes?

No, but I can make one :)


Are they called from something similar to the "ThirdPersonHandler" class?

Yes. Hold on a sec and I'll show you.

Ok, test up at: http://www.mojomonkeycoding.com/jmeforum/viewtopic.php?t=1134

Thanks Per! I’ll be checking out this evening! :slight_smile:

Thanks again Per – I checked out your example last night and it worked great – the general behavior and movements is exactly what I was looking for. But I did run into a “small problem”. :frowning:



When I swapped either (or both) your “player” or “ground” for mine, everything went crazy. My player is a BillboardNode with a single Quad in it, while my ground is a Node with lots of a TriMeshs in it. My guess (I guess a lot w/ this 3D stuff) is that it is having a Node put in there, best I could figure at this point.



I’m still looking through everything trying to see if I can’t trip over the cause. Do you have any ideas as to what it might be? Maybe I’m just not building my world correctly to begin with.



Thanks again!


everything went crazy

Please elaborate :D

Putting a Node as a target should work fine - I'm doing exactly that in one of my games.

If I just place a BillboardNode, in place of the Sphere, the sprite will "twitch". It will flip around a random axis almost every update. The code to my sprite is nothing special, but I included it below, just in case – in the test code, I just replace "Sphere" with "Sprite". It is just a test class too. :wink:



If I replace the ground reference with my ground Node, the same thing as above happens but much more so. The scene will zoom in/out and randomly flip around an axis.



What Java version did you use to build your system? I am using 1.5 right now, but can switch to your version just to check. Maybe there is something really funcky with 1.5.


public class Sprite extends BillboardNode {
  /** horizontal position of the sprite */
  private float x;
  /** vertical position of the sprite */
  private float y;

  /** horizontal velocity of the sprite */
  private float dx;
  /** vertical velocity of the sprite */
  private float dy;

  private Quad quadSprite;

  public Sprite(String s) {
    super(s);

    TextureState ts = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
    Texture texture = TextureManager.loadTexture("/home/nick/IdeaProjects/RPGSuite/data/blacksmith.png", Texture.MM_LINEAR, Texture.FM_LINEAR, true);
    ts.setTexture(texture);
    ts.setEnabled(true);

    //quadSprite = new Quad("sprite",
    //        ts.getTexture().getImage().getWidth() / 40,
    //        ts.getTexture().getImage().getHeight() / 40);
    quadSprite = new Quad("sprite",
            ts.getTexture().getImage().getWidth(),
            ts.getTexture().getImage().getHeight());

    //quadSprite.initialize(1, 1);
    //quadSprite.resize(1, 1);

    Vector2f[] texCoords = new Vector2f[4];
    texCoords[0] = new Vector2f(0, 1);
    texCoords[1] = new Vector2f(0, 0);
    texCoords[2] = new Vector2f(1, 0);
    texCoords[3] = new Vector2f(1, 1);
    quadSprite.setTextures(texCoords);
    quadSprite.setRenderState(ts);

    /** apply the alpha state to the texture */
    AlphaState as = DisplaySystem.getDisplaySystem().getRenderer().createAlphaState();
    as.setBlendEnabled(true);
    as.setSrcFunction(AlphaState.SB_SRC_ALPHA);
    as.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
    as.setTestEnabled(false);
    as.setEnabled(true);
    quadSprite.setRenderState(as);

    this.attachChild(quadSprite);
  }

  public float getVelocityX() {
    return dx;
  }

  public float getVelocityY() {
    return dy;
  }

  public float getX() {
    return x;
  }

  public float getY() {
    return y;
  }

  public void setVelocityX(float dx) {
    this.dx = dx;
  }

  public void setVelocityY(float dy) {
    this.dy = dy;
  }

  public void setX(float x) {
    this.x = x;
  }

  public void setY(float y) {
    this.y = y;
  }
}


What Java version did you use to build your system?

1.5, as you.

Hmm... I don't think there's anything wrong with your code, but it's hard to say... I guess BillboardNode - which tries to face the camera - could have some problems. Hold on a sec and I'll see what happens if I put a BillboardNode in my test.

Yupp, I got the same problem as you. It got fixed as soon as I moved the mouse (camera), or set the theta angle to anything else than 180 though. So BillboardNode seem to have a problem with a theta angle of 180 degrees :?



This doesn’t explain why you’r experiencing the same problem with you’r ground node though. It’s not moving or anything, right?



Anyway, I’ll try to add a more complex node or something in my test.

Updated the test with all the newness:

http://www.mojomonkeycoding.com/jmeforum/viewtopic.php?t=1134&start=15

Thanks again Per. I swear I tried altering the theta and moving the mouse the BillboardNode … guess not. :? But it does work – sweetness!



My ground geometry still causes problems, but it is a good bet it is pretty messy. I’m going to slowly build up a more complex environment over the next few days and see how it goes.



Thanks again!