Libgdx First Person Camera Controller

I just started playing arround with 3D in libgdx. I already know how to draw basic Model, and I tried to play arround using CameraController. Now I want to create FirstPersonCameraor FirstPersonCameraController. I was thinking about expanding PerspectiveCameraand adding to it MyMovingObject target. MyMovingObjectwill contain x, y, z positionwhere yis a constant value, so I can’t move up/downat the moment. So my movement is significant in 2D. MyMovingObjectalso save left/right rotationrequired for moving direction/ xSpeed, zSpeed. But Playerit should also be able to look up and down, and this up / down rotation is not required for MyMovingObject, as it changes its appearance and other properties. So I'm not sure if I will go right.
I want to be able to move forward, left, right, back, using W,A,S,Dand rotate left and right with the mouse. I also want to look up and down with the mouse, as in most games First Person.
Should I use a different method without creating my own camera, expanding PerspectiveCamera? Or is this approach good, and I just need to keep the up / down rotation in MyMovingObject, as well, if it is only necessary for presentation?
Or would it be better to control the camera with W,A,S,D and mouseand update the position MyMovingObjectdepending on the camera position and rotation?
I hope you understand what I mean. This seems to be a little hard to explain (at least for me).

EDIT: Now I use Vector3 direction, Vector3 positionand Vector3 sizefor their NPC and the player. I calculate the speed by doing: xSpeed = direction.x / (direction.x + direction.z) * speed;the same for zSpeed. By doing this, I "filter" the y value from it, and get only a percentage of x and y. The only problem is that when I look straight up, xand zare 0. I could fix this using a UpVecotrthat turns when I do a "turn on a step". But how do I turn it? I need to rotate it around a side vector. Thanks

: (. ), " ". : if (direction.y < 0.9 && angle > 1) doPitchRotation(); else if (direction.y > -0.9 && angle < 1) doPitchRotation();, , , , , -0,9 y, . : - 0,9, Y, , . , ? Y-Axis , , ?

EDIT: . , upVector . Y- . upVector.

+4
3

, . . , , .

private int mouseX = 0;
private int mouseY = 0;
private float rotSpeed = 0.2f;

@Override
public boolean mouseMoved(int screenX, int screenY) {
    int magX = Math.abs(mouseX - screenX);
    int magY = Math.abs(mouseY - screenY);

    if (mouseX > screenX) {
        cam.rotate(Vector3.Y, 1 * magX * rotSpeed);
        cam.update();
    }

    if (mouseX < screenX) {
        cam.rotate(Vector3.Y, -1 * magX * rotSpeed);
        cam.update();
    }

    if (mouseY < screenY) {
        if (cam.direction.y > -0.965)
            cam.rotate(cam.direction.cpy().crs(Vector3.Y), -1 * magY * rotSpeed);
        cam.update();
    }

    if (mouseY > screenY) {

        if (cam.direction.y < 0.965)
            cam.rotate(cam.direction.cpy().crs(Vector3.Y), 1 * magY * rotSpeed);
        cam.update();
    }

    mouseX = screenX;
    mouseY = screenY;

    return false;
}

. , cam.direction.crs(cam.up). Vector3.cpy() Vector3 help, , Vector3.cpy() Vector3, . roll yaw cam.up Vector.

+4

, . , , . MovingObject Vector3 position, Vector3 direction, Vector3 size Vecotr3 upVector. Player MovingObject Mouse Keycontroll. MovingObject :

  • rotateYaw(float degrees): Vector3 direction arround Y-Axis (libgdx Vector3) → Simple
  • rotatePitch(float degrees): Vector3 direction arround: direction.cross(Vector3.Y), MovingObject, . , Pitch-Rotation upVector, upVector . , .
  • move(delta) MovingObject x,z, :

    if (direction.y == 1) {
      // You are looking straight up, no x,z direction, move in the opposite
      // direction of upVector
      xSpeed = upVector.x / (Math.abs(upVetor.x) + Math.abs(upVector.z)) * (-speed);
      zSpeed = upVector.z / (Math.abs(upVetor.x) + Math.abs(upVector.z)) * (-speed);
      position.add(xSpeed * delta, 0, ySpeed * delta);
    } else if (direction.y == -1) {
      // You are looking straight down, no x,z direction, move in the direction of
      // upVector
      xSpeed = upVector.x / (Math.abs(upVetor.x) + Math.abs(upVector.z)) * speed;
      zSpeed = upVector.z / (Math.abs(upVetor.x) + Math.abs(upVector.z)) * speed;
      position.add(xSpeed * delta, 0, ySpeed * delta);
    } else {
      // You are not looking straight up or down, so you have x,z direction. Use
      // that.
      xSpeed = direction.x / (Math.abs(direction.x) + Math.abs(direction.z)) * speed;
      zSpeed = direction.z / (Math.abs(direction.x) + Math.abs(direction.z)) * speed;
      position.add(xSpeed * delta, 0, ySpeed * delta);
    }
    

, , . , Pitch-Rotation /. , signum x z. , Pitch-Rotation, 90 . , , !

EDIT: . , , :

  • direction.cross(upVector) direction. ! reset .
  • Pitch : signum, , : , signum x signum z 0. , signum (). , , . , , , .
  • direction upVector , - !

, . - , , . , !

+2

, . . -, . . Y exis. , , fps. , .

// put into the create() method.
Gdx.input.setInputProcessor(new InputProcessor() {
        private int dragX, dragY;
        float rotateSpeed = 0.2f;
        // dont' forget to override other methods.
        @Override
        public boolean mouseMoved(int screenX, int screenY) {
            Vector3 direction = cam.direction.cpy();

            // rotating on the y axis
            float x = dragX -screenX;
            // change this Vector3.y with cam.up if you have a dynamic up.
            cam.rotate(Vector3.Y,x * rotateSpeed);

            // rotating on the x and z axis is different
            float y = (float) Math.sin( (double)(dragY -screenY)/180f);
            if (Math.abs(cam.direction.y + y * (rotateSpeed*5.0f))< 0.9) {
                cam.direction.y +=  y * (rotateSpeed*5.0f) ;
            }

            cam.update();
            dragX = screenX;
            dragY = screenY;
            return true;
        }

    });

. .
2: : Gdx.input.setCursorCatched(true);

: , , . W , forward true. forward . . , InputProcessor .
(X-Z-). , Y. .
, ​​ ( 90 ), 1.0f. Thus, there will be no loss of speed. To check this, I turned the camera up and down (moved the mouse forward and backward), but the x and z values ​​of the direction vector did not change. Therefore, when the y axis of the direction vector is eliminated, we have a 2d direction vector that does not affect the camera angle Y.

private void walking(float timeElapsed) {
        float speed = movementSpeed;
        if ((forward | back) & (right | left)) {
            speed /= Math.sqrt(2);
        }
        System.out.println(speed);
        if (forward) {
            Vector3 v = cam.direction.cpy();
            v.y = 0f;
            v.x *= speed * timeElapsed;
            v.z *= speed * timeElapsed;
            cam.translate(v);
            cam.update();
        }
        if (back) {
            Vector3 v = cam.direction.cpy();
            v.y = 0f;
            v.x = -v.x;
            v.z = -v.z;
            v.x *= speed * timeElapsed;
            v.z *= speed * timeElapsed;
            cam.translate(v);
            cam.update();
        }
        if (left) {
            Vector3 v = cam.direction.cpy();
            v.y = 0f;
            v.rotate(Vector3.Y, 90);
            v.x *= speed * timeElapsed;
            v.z *= speed * timeElapsed;
            cam.translate(v);
            cam.update();
        }
        if (right) {
            Vector3 v = cam.direction.cpy();
            v.y = 0f;
            v.rotate(Vector3.Y, -90);
            v.x *= speed * timeElapsed;
            v.z *= speed * timeElapsed;
            cam.translate(v);
            cam.update();

        }
    }
+2
source

Source: https://habr.com/ru/post/1527291/


All Articles