la rotación 3D en 2 direcciones?

Kris Rice:

Antecedentes

Estoy intentando crear un juego FPS en Java utilizando LWJGL 3.0. He creado una clase de cámara, que tiene una inclinación y orientación (no se utiliza rollo). La cámara en sí se extiende Entidad, ya que tiene un modelo. Este modelo me gustaría parece ser siempre "delante" de la cámara, donde la cámara está apuntando. Cada entidad tiene un método getTransformationMatrix()que devuelve una Matrix4f, que se pasa luego en el shader entidad.

Problema

Las necesidades modelo a punto en la dirección de la cámara, así como girar alrededor de la cámara, de tal manera que siempre está en frente. El objeto de esta situación es la mano a un arma de fuego, como se muestra en la foto de abajo.

introducir descripción de la imagen aquí

Mi intento

I am aware of basic trigonometry, so I got the object to rotate correctly for pitch and yaw, separately. This is my current implementation:

Yaw

@Override
public Matrix4f getTransformationMatrix() {
    modelX = getPosition().x + (radius * (float)Math.sin(Math.toRadians(getYaw())));
    modelZ = getPosition().z + (radius * (float)Math.cos(Math.toRadians(getYaw())));

    return Transform.createTransformationMatrix(new Vector3f(modelX, getPosition().y - 5, modelZ), new Vector3f(0, getYaw(), 0), getScale());
}

Pitch

@Override
public Matrix4f getTransformationMatrix() {
    modelZ = getPosition().z + (radius * (float)Math.sin(Math.toRadians(getPitch())));
    modelY = (getPosition().y - 5) + (radius * (float)Math.cos(Math.toRadians(getPitch())));

    return Transform.createTransformationMatrix(new Vector3f(getPosition().x, modelY, modelZ), new Vector3f(getPitch(), 0, 0), getScale());
}

I have done some research but I fear I have been stuck on this too long and need some fresh eyes. When I try to combine these 2 calculations, the model seems to move in the shape of a graph when looking at any yaw angle other than 0. Below is my attempt of combining these:

@Override
public Matrix4f getTransformationMatrix() {
    float zAxis = (radius * (float)Math.sin(Math.toRadians(getPitch())));
    modelY = (getPosition().y - 5) + (radius * (float)Math.cos(Math.toRadians(getPitch())));
    modelZ = getPosition().z + (zAxis * (float)Math.cos(Math.toRadians(getYaw())));
    modelX = getPosition().x + (radius * (float)Math.sin(Math.toRadians(getYaw())));

    return Transform.createTransformationMatrix(new Vector3f(modelX, modelY, modelZ), new Vector3f(getPitch(), getYaw(), 0), getScale());
}

The Transform.createTransformationMatrix() looks like the following:

public static Matrix4f createTransformationMatrix(Vector3f translation, Vector3f rotation, Vector3f scale) {
    transform3d = new Matrix4f();
    transform3d.setIdentity();
    Matrix4f.translate(translation, transform3d, transform3d);
    Matrix4f.rotate((float) Math.toRadians(rotation.x), new Vector3f(1, 0, 0), transform3d, transform3d);
    Matrix4f.rotate((float) Math.toRadians(rotation.y), new Vector3f(0, 1, 0), transform3d, transform3d);
    Matrix4f.rotate((float) Math.toRadians(rotation.z), new Vector3f(0, 0, 1), transform3d, transform3d);
    Matrix4f.scale(scale, transform3d, transform3d);
    return transform3d;
}

Thoughts

A friend suggested creating a unit vector that points in the direction of up, (ie. new Vector3f(0, 1, 0)) rotating the Vector by the pitch and yaw, then multiplying the Vector by the radius and adding it to the camera's position. I tried this, but I don't know how to rotate a Vector by an angle, and there seems to be no Vector3f.rotate() method in the slick-utils Vector3f class. Any help is is thoroughly appreciated as this has been giving me a headache for the past few days. Thanks!

Coronel Kittycannon :

What we normally do is, yes, take a unit-length vector and use it as our "axis". In 2D rotation we use an axis - the Z axis - all the time.

3D rotation

If you were to look at the axis, like in 2D, you would see something like this

2D rotation

Por lo tanto, para hacer girar un punto en 3D se puede utilizar una matriz o un vector. Recomiendo el vector primero para que pueda tener una idea de cómo funciona la rotación 3D. Sopla su mente!

Me pasaré el código de una clase de Vector3f theBennyBox. Si está interesado en obtener más de esta comprobación matemática a cabo theBennyBox en Youtube.

Vector3f

    public Vector3F rotate(float angle, Vector3F axis) {
    double a = Math.toRadians(angle / 2f);
    float hs = (float) Math.sin(a);
    float hc = (float) Math.cos(a);
    Vector4F r = new Vector4F(axis.getX() * hs, axis.getY() * hs, axis.getZ() * hs, hc);
    Vector4F rc = r.conjugate();
    r = r.multiplyAsQuat(this).multiplyAsQuat(rc);

    return new Vector3F(r.getX(), r.getY(), r.getZ());
    }

4f vector

    public Vector4F multiplyAsQuat(Vector3F v) {
    float o = -x * v.getX() - y * v.getY() - z * v.getZ();
    float a = w * v.getX() + y * v.getZ() - z * v.getY();
    float b = w * v.getY() + z * v.getX() - x * v.getZ();
    float c = w * v.getZ() + x * v.getY() - y * v.getX();

    return new Vector4F(a, b, c, o);
}

    public Vector4F conjugate() {
    return new Vector4F(-x, -y, -z, w);
}

    public Vector4F multiplyAsQuat(Vector4F qt) {

    float o = w * qt.getW() - x * qt.getX() - y * qt.getY() - z * qt.getZ();
    float a = x * qt.getW() + w * qt.getX() + y * qt.getZ() - z * qt.getY();
    float b = y * qt.getW() + w * qt.getY() + z * qt.getX() - x * qt.getZ();
    float c = z * qt.getW() + w * qt.getZ() + x * qt.getY() - y * qt.getX();

    return new Vector4F(a, b, c, o);
}

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=175808&siteId=1
Recomendado
Clasificación