Help with camera stuff

HI ,

I’ve just started learning xith3d - so im a total beginner
so far I have worked thru the getting started guide which is fine - I have loaded an .obj which contains my 3d “man” - i have added some geometric shapes to give some feature to the enviornment and have got my little
3d “man” walking around the scene.

its the camera feature that i fall short on - is there a tutorial out there that i can use or could someone help me with the code - what i want to do is have my camera a short distance from my Characters head and the camera follow my character as it moves around - but its important that the character can move freely so that the camera does not rotate with my character but just follows the character.

Cheers

Rmdire

would be cool if theres anyone with camera stuff sorted to make a camera package for the toolkit :slight_smile: would be tops… my cameras are atad shabby to say the least.

a tutorial get my +1 vote… would be smashing- then we would have all the camera stuff sorted…

Yep agree totally, theres a lot of questions about camera issues on the boards, and good beginner tutorials are hard to find.

Writing a college project using Xith3D myself and the most frustrating part is how hard it is to get tutorials.

The boards are great but i have a lot of fundamental questions about cameras and Xith3D in general.

rmdire, perhaps you will receive more targeted responses by posting code from your attempts and asking more direct questions.

In general, you would simply set the camera’s position whatever distance behind your character you prefer. Then, with each movement (from keystroke, mouse, etc.), you would transform both your character and your camera the same number of units so that, as your character moves in any direction, your camera mirrors. For character rotations, you obviously cannot simply rotate your camera, as you would no longer be looking at your character. I would suggest orbiting the camera around the character during character rotations. You can mathematically determiine the path of the camera based on an orbit radius equal to the target distance from character to camera.

:-[ :-/

Thanks for pointing this out wrightmf - you are quite right - so here goes.

view.getTransform.lookAt(new Vector3f(x,y,z)…)
this allows me to view the scene from xyz coords - right?

what i would like to do is get the xyz coords for the character transform
so i could pass these coords back and calculate the new view.

or am i going the wrong way about this.

I hope this makes sense and thanks for any help - its much appreciated -

My FPS camera class


import com.xith3d.scenegraph.TransformGroup;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;
import java.awt.event.KeyEvent;
import javax.vecmath.Vector3f;
import java.awt.AWTEvent;
import java.awt.Toolkit;
import java.awt.Robot;
import java.awt.Point;

public class Xith3DCamera
{
  private Vector3f  upVector          = new Vector3f(0f, 0f, 1f),
                    tempVector        = new Vector3f(0f, 0f,.0f),
                    viewVector        = new Vector3f(0f, 1f,.5f),
                    axisVector        = new Vector3f(0f, 0f, 0f),
                    strafeVector      = new Vector3f(0f, 0f, 0f),
                    positionVector    = new Vector3f(0f, 0f,.0f),
                    moveCameraVector  = new Vector3f(0f, 0f, 0f);

  private boolean   keys[]            = null,
                    frameActive       = false;

  private Point     mousePosition     = null,
                    componentPosition = null;

  private Robot     mouseRobot        = null;

  private float     currentRotX       =   0,
                    cameraSpeed       =  50,
                    frameInterval     =   0;

  private long      frameTime         =   0;

  private int       screenWidth       =   0,
                    screenHeight      =   0;

  Xith3DCamera(boolean keys[]){

    this.keys = keys;
    frameTime = System.currentTimeMillis();

    Toolkit.getDefaultToolkit().addAWTEventListener( new EventListener(),
                                                     AWTEvent.KEY_EVENT_MASK        |
                                                     AWTEvent.MOUSE_EVENT_MASK      |
                                                     AWTEvent.MOUSE_MOTION_EVENT_MASK);
    try{
      mouseRobot = new Robot();
    }
    catch(Exception e){}
  }

  public void setScreenSize(int width, int height){
    screenWidth   = width;
    screenHeight  = height;
    mousePosition = new Point(width>>1,height>>1);
  }

  public void positionCamera(float xPosition, float yPosition, float zPosition,
                             float xView    , float yView    , float zView    ,
                             float xUpVector, float yUpVector, float zUpVector){
    positionVector.set( xPosition, yPosition, zPosition);
    viewVector.set(     xView    , yView    , zView    );
    upVector.set(       xUpVector, yUpVector, zUpVector);
  }

  public void moveCamera(float speed){
    moveCameraVector.sub(viewVector, positionVector);
    moveCameraVector.normalize();

    positionVector.scaleAdd(speed, moveCameraVector, positionVector);
    viewVector.scaleAdd(    speed, moveCameraVector, viewVector    );
  }

  public void setViewByMouse(){
    float angleY  = 0f,
          angleZ  = 0f;

    int   middleX = screenWidth  >> 1,
          middleY = screenHeight >> 1;

    if( (mousePosition.x == middleX) && (mousePosition.y == middleY) )
      return;

    angleY = (float)( (middleX - mousePosition.x) ) / 500.0f;
    angleZ = (float)( (middleY - mousePosition.y) ) / 500.0f;

    if(frameActive)
      mouseRobot.mouseMove(componentPosition.x + middleX, componentPosition.y + middleY);

    currentRotX -= angleZ;

    if(currentRotX > 1.0f)
      currentRotX = 1.0f;
    else
      if(currentRotX < -1.0f)
        currentRotX = -1.0f;
      else{
        axisVector.sub(  viewVector, positionVector);
        axisVector.cross(axisVector, upVector      );
        axisVector.normalize();
        rotateView(angleZ, axisVector.x, axisVector.y, axisVector.z);
        rotateView(angleY, 0, 1, 0);
      }
  }

  private void rotateView(float angle, float x, float y, float z){
    tempVector.sub(viewVector, positionVector);

    float cosTheta         = FastTrig.cos(angle),
          sinTheta         = FastTrig.sin(angle),
          oneMinusCosTheta = 1f     -   cosTheta;

    viewVector.x  = (cosTheta + oneMinusCosTheta * x * x)      * tempVector.x;
    viewVector.x += (oneMinusCosTheta * x * y - z * sinTheta)  * tempVector.y;
    viewVector.x += (oneMinusCosTheta * x * z + y * sinTheta)  * tempVector.z;

    viewVector.y  = (oneMinusCosTheta * x * y + z * sinTheta)  * tempVector.x;
    viewVector.y += (cosTheta + oneMinusCosTheta * y * y)      * tempVector.y;
    viewVector.y += (oneMinusCosTheta * y * z - x * sinTheta)  * tempVector.z;

    viewVector.z  = (oneMinusCosTheta * x * z - y * sinTheta)  * tempVector.x;
    viewVector.z += (oneMinusCosTheta * y * z + x * sinTheta)  * tempVector.y;
    viewVector.z += (cosTheta + oneMinusCosTheta * z * z)      * tempVector.z;

    viewVector.add(positionVector);
  }

  private void strafeCamera(float speed){
    positionVector.x += strafeVector.x * speed;
    positionVector.z += strafeVector.z * speed;

    viewVector.x     += strafeVector.x * speed;
    viewVector.z     += strafeVector.z * speed;
  }

  private void elevateCamera(float speed){
    positionVector.y += upVector.y*speed;
    viewVector.y     += upVector.y*speed;
  }

  private void checkForMovement(){
    float speed = cameraSpeed * frameInterval;
    if(keys[KeyEvent.VK_UP       ] || keys['W']) moveCamera(    speed);
    if(keys[KeyEvent.VK_DOWN     ] || keys['S']) moveCamera(   -speed);
    if(keys[KeyEvent.VK_LEFT     ] || keys['A']) strafeCamera( -speed);
    if(keys[KeyEvent.VK_RIGHT    ] || keys['D']) strafeCamera(  speed);
    if(keys[KeyEvent.VK_PAGE_UP  ] || keys['E']) elevateCamera( speed);
    if(keys[KeyEvent.VK_PAGE_DOWN] || keys['Q']) elevateCamera(-speed);
  }

  public void update(long currentTime){

    frameInterval   = ((float)(currentTime - frameTime))/500f;
    frameTime       = currentTime;

    strafeVector.sub(  viewVector  , positionVector);
    strafeVector.cross(strafeVector, upVector);
    strafeVector.normalize();

    setViewByMouse();
    checkForMovement();
  }

  public void look(TransformGroup group){
    group.getTransform().lookAt(new Vector3f(positionVector),
                                new Vector3f(viewVector    ),
                                new Vector3f(upVector      ));
  }

  public Vector3f getPositionVector() { return positionVector;}
  public Vector3f getStrafeVector()   { return strafeVector  ;}
  public Vector3f getViewVector()     { return viewVector    ;}
  public Vector3f getUpVector()       { return upVector      ;}

  public boolean  getFrameState(){
    return frameActive;
  }

  public void setComponentPosition(int x, int y){
    if(componentPosition == null)
      componentPosition = new Point();

    componentPosition.setLocation(x,y);
  }

  public void setFrameState(boolean state){
    frameActive = state;
  }

  public void mouseMoved(MouseEvent me){
     mousePosition = me.getPoint();
  }

  private class EventListener implements AWTEventListener{

    public void eventDispatched(AWTEvent event){
      if(event instanceof MouseEvent){
        MouseEvent e = (MouseEvent) event;
        switch(e.getID()){
          case MouseEvent.MOUSE_MOVED: mouseMoved(e); break;
        }
      }
    }
  }
}

Hope this helps :stuck_out_tongue:

fu**** code layout >:(

Here’s the neat version :slight_smile:

Thank you JCD - my wow what a nice piece of code .
Just what im looking for - your help is much appreciated

when i get up to speed on these cameras i will try to write a tutorial and with everybodys help we can all benefit.

;D

thank you

rmdire

[quote]when i get up to speed on these cameras i will try to write a tutorial and with everybodys help we can all benefit.
[/quote]
If you or anyone else writes a tutorial, it can be included in the GSG of course (see instructions). This way new users will probably read it.

Well I thought tweaking the speed of my camera class is correctly and efficiently done.
Please point out any flaws as you go through it
:slight_smile:

Hi,

I’m very new to graphics programming and xith3d in particular, so forgive if this is a simple question.

This Xith3DCamera class seems exactly what I need but I’m having some trouble in using it.

I’m not sure how the keys array you pass in with the constructor works. Do you handle the key press event outside the class and set true/false for each key press??

Also, I’m not sure what value is supposed to be passed into the update method. I can see its some sort of frame counter but I’m not sure how to make it work.

This seems like a nice piece of code, its frustrating not being able to make it work.

Any help would be gratefully received…

I think it’s not going to be necessary because this in the construtor:


Toolkit.getDefaultToolkit().addAWTEventListener( new EventListener(), 
             AWTEvent.KEY_EVENT_MASK   | 
             AWTEvent.MOUSE_EVENT_MASK | 
             AWTEvent.MOUSE_MOTION_EVENT_MASK);

but I read through the code and couldn’t see any key event listener, so making your external listener would be better in this case.

Use


sun.misc.Perf.getPerf().highResCounter();

to get the variable ‘currentTime’,
and


sun.misc.Perf.getPerf().highResFrequency()>>1

to get the variable ‘updateFrequency’.

I hope this helps.
Reply for more help.

Alonzo

Worked a treat!

Thanks very much!!


 sun.misc.Perf.getPerf().highResCounter(); 

Be careful using the unsupported sun packages! They are not part of the Java spec and do not exist in all VM’s. For example, I don’t think the IBM or Apple JVM’s have that class.

While this is the simpler option, the best option is to get a cross platform high res timer (or use Java 1.5 - although this isn’t supported on OS X yet either).

Will.

its in the Apple one now :slight_smile: not sure about imb mind