1
\$\begingroup\$

I'm currently reverse engineering a video game where what's rendered on the screen depends on the proximity of the player avatar to the camera. As such, for my freecam to work properly, I need to bring the player avatar along with the camera.

Since I can't yet find how the player avatar is rendered to the screen, the next best thing I can think to do is to place the player avatar behind the camera at all times (I suppose essentially like making the player avatar orbit the camera, but always be behind it).

I just can't quite pin down how to make this happen.

The values I have are as follows:

Player Avatar:

  • X
  • Y (Up/Down)
  • Z

Camera:

  • X
  • Y (Up/Down)
  • Z
  • Pitch (In degrees natively, but converted to radians for my calculations)
  • Yaw (In degrees natively, but converted to radians for my calculations)

World Orientation:

To get my camera to move forward in the direction I'm pointing my mouse when pressing the Y key, these are the calculations I'm using (code is in Lua):

--//Camera XYZ values
local camCoordX = readFloat("[cameraBase]+990") --Camera X
local camCoordY = readFloat("[cameraBase]+994") --Camera Y
local camCoordZ = readFloat("[cameraBase]+998") --Camera Z


--//Camera pitch and yaw
local pitch = math.rad(readFloat("[cameraBase]+1540")) --Pitch
local yaw = math.rad(readFloat("[cameraBase]+1544")) --Yaw

--//Sine and cosine calculations
local sinOfYaw = math.sin(yaw) --Sine of Yaw
local cosOfYaw = math.cos(yaw) --Cosine of Yaw
local sinOfPitch = math.sin(pitch) --Sine of Pitch
local cosOfPitch = math.cos(pitch) --Cosine of Pitch


--//If Y key is pressed, write new camera XYZ values accordingly
if isKeyPressed(VK_Y) then
    writeFloat("[cameraBase]+990", camCoordX + (sinOfYaw * speed))
    writeFloat("[cameraBase]+994", camCoordY - (sinOfPitch * speed))
    writeFloat("[cameraBase]+998", camCoordZ + (cosOfYaw * speed))
end

Based on that information, is it feasible for me to accomplish placing the player avatar behind the camera at all times based on rotation? I'm open to other suggestions or options as well. Thank you for any help you can offer!

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Here's what I'd do, basically the opposite of what you're already doing to move your camera but instead of adding, subtracting so that you move in the opposite direction of the camera. Gonna use C++ code as that's what I have this code written for already.

vec3 Subtract(vec3 src, vec3 dst)
{
    vec3 diff;
    diff.x = src.x - dst.x;
    diff.y = src.y - dst.y;
    diff.z = src.z - dst.z;
    return diff;
}

float DegreeToRadian(float degree)
{
    return degree * (PI / 180);
}

vec3 GetNewAvatarPosition(vec3 currAngle, vec3 cameraPOS, float dist)
{
    vec3 d;

    d.x = cosf(DegreeToRadian(currAngle.x - 90)) * dist;
    d.y = sinf(DegreeToRadian(currAngle.x - 90)) * dist;
    d.z = sinf(DegreeToRadian(currAngle.y)) * dist;

    vec3 newAvatarPOS = Subtract(cameraPOS, d);

    return newAvatarPOS;
}

//Psuedo code:
avatar.pos = GetNewAvatarPosition(camera.angle, camera.pos, 3);
avatar.angle = camera.angle;

That would move your avatar 3 units behind the camera

The proper way to do this would be to use matrix multiplication, multiply the 3d coords of the camera (as a vec4) by a translation matrix (vec4x4). Looks like this:

enter image description here

Courtesy of Wikipedia's Euclidean Geometry Translation page. You would just change the first three "1"s to 3 to move a distance of 3

\$\endgroup\$

You must log in to answer this question.

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