0
\$\begingroup\$

I'm working on a 3d project in Libgdx. I've got a camera flying around in 3d space, being controlled with touch. Works great, moves forward and backward, strafes, full 360 look around with no gimbal lock.

But, I want my player to be able to see what they're holding. So I've added a "hands" model instance, which I'll change out depending on what is being held. I've positioned the model in front on the camera, which works fine.

But then whenever I try to call a transform.setToRotation, it sets the rotation, but moves the position back to 0,0,0. Does anyone know why this is happening? Here's my camera update code:

public void updateCamera()
{
    // left right look
    camDir.set(cam.direction); 
    cam.rotate(cam.up , deltaX);

    // up down
    tempVec.set(camDir.crs(cam.up), deltaY);
    cam.rotate(tempVec);    
    cam.update();

    // move forward 
    cam.position.add(forwardTemp.set(cam.direction).scl(deltaForward));
    cam.update();

    // strafe
    strafeTemp.set(cam.direction);
    strafeTemp.rotate(cam.up, 90);  
    cam.position.add(strafeTemp.scl(deltaStrafe));
    cam.update();
    
    // move tool hands to match
    handPos.set(cam.position);
    handPos.add(forwardTemp.set(cam.direction).scl(1.5f));
    handInst.transform.setToTranslation(handPos);

    handInst.transform.setToRotation(cam.direction, Vector3.X);     
} // end updateCamera
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

If you look at the documentation for setToRotation you'll see this:

public Matrix4 setToRotation(Vector3 v1, Vector3 v2)

Set the matrix to a rotation matrix between two vectors.

Parameters:

  • v1 - The base vector
  • v2 - The target vector

Note that this does not say "adds a rotation to an existing matrix while preserving its translation, scale, and shear." It says that it sets (replaces) the value of the variable with a rotation matrix (ie. a matrix that is pure rotation and nothing else).

So the method is doing exactly what it promised to do, you're just using the wrong method for the task you want to achieve.

It looks like you want something more like:

// Do this first so that we rotate around our local origin/pivot.
handInst.transform.setToRotation(cam.direction, Vector3.X);  

// No "To" - we're folding a translation into the existing matrix.
handInst.transform.setTranslation(handPos);  
\$\endgroup\$
4
  • \$\begingroup\$ That's amazing, thanks! Fixes that problem. I see another though, if I can ask on the same thread. I can't get my model's rotation to match the camera's direction. If I understand correctly, SetToRotation uses the vector you want to point to, and the face to point there. But my camera is spinning around in full 3d space, and I don't think grabbing Vector3.X, or Y, or Z accounts for that. Is there a modelInstance equivalent of camera.up or camera.direction? I can't seem to find one. \$\endgroup\$ May 27, 2021 at 15:32
  • \$\begingroup\$ Again, that's not what the documentation says it does. It gives you a matrix that rotates the first vector to point toward the second vector. If you want your model's local x direction to point in the camera's facing direction, you probably want these two arguments in the opposite order. You might also want to use a different method to control your twist around the model's x axis. \$\endgroup\$
    – DMGregory
    May 27, 2021 at 15:42
  • \$\begingroup\$ Whoops. That was dumb of me. Swapped those two arguments, now it looks great. Still twists as I look around, as you alluded to, which I'm gonna have to solve, but the model faces out, just like it should. Thank you, very, very much. \$\endgroup\$ May 27, 2021 at 15:54
  • \$\begingroup\$ Note that I've never written a Java program in my life - this is just from taking the time to read the documentation. So I recommend making that your first stop the next time you run into trouble. \$\endgroup\$
    – DMGregory
    May 27, 2021 at 15:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .