Jump to content

3D Camera Maths Calc (Probably a hard question)


12p

Recommended Posts

I don't know how to explain this, exactly...

It's complex for me.

So I will just say:

I want the camera to move as in TrackMania Nations Forever (while on stunts, check 0:10)

BUT without using a FPS mode.

I've got my script working this way:

mta-screen_2011-12-01_16-07-25.png

mta-screen_2011-12-01_16-07-17.png

So, can I fix it?

Here's my code if you can add some improvement/wanna have it lol (I was planning to make this script public, as a Race Addon)

function getPointFromDistanceRotation ( x, y, dist, angle ) 
    --Function made by "robhol" 
    local a = math.rad ( 90 + angle ) 
    local dx = math.cos ( a ) * dist 
    local dy = math.sin ( a ) * dist 
    return x + dx, y + dy 
end 
  
player = getLocalPlayer ( ) 
  
--This script will only work while using vehicles! 
function setTrackmaniaCamera ( ) 
    if not isPedInVehicle ( player ) then  
        if getCameraTarget ( ) ~= player then setCameraTarget ( player, player ) end 
        return 
    end 
    local v = getPedOccupiedVehicle ( player ) 
    local px, py, pz = getElementPosition ( v ) 
    local prx, pry, prz = getElementRotation ( v ) 
     
    local csx, csy = getPointFromDistanceRotation ( px, py, 10, prz - 180 ) 
    local csz = getPointFromDistanceRotation ( pz, px, 10, pry - 30 ) 
     
    local ctx, cty = getPointFromDistanceRotation ( px, py, 5, prz ) 
    local ctz      = getPointFromDistanceRotation ( pz, px, 10, prx - 180 ) 
    setCameraMatrix ( csx, csy, csz, ctx, cty, ctz, -pry ) 
    return true 
end 
addEventHandler ( "onClientPreRender", getRootElement ( ), setTrackmaniaCamera ) 

NOTE: Yes, I made a Race DM map and called it that way xD

Link to comment

why dont you just use getElementMatrix, if you want the camera to stay behind the player?

edit: like this.

addEventHandler("onClientPreRender", getRootElement(), 
function() 
    local vehicle = getPedOccupiedVehicle(getLocalPlayer()) 
    if not vehicle then 
        if(getCameraTarget() ~= getLocalPlayer())then 
            setCameraTarget(getLocalPlayer()) 
        end 
        return 
    end 
    local tarX, tarY, tarZ = getElementPosition(vehicle) 
    tarZ = tarZ + 0.5 
    -- get position 13 units and 1 unit behind the vehicle. 
    local camX, camY, camZ = getRotatedPosition(vehicle, 0, -13, 1) 
    setCameraMatrix(camX, camY, camZ, tarX, tarY, tarZ) 
end) 
  
function getRotatedPosition(element, distX, distY, distZ) 
    if not element or not isElement(element) then return end 
    local matrix = getElementMatrix(element) 
    if not matrix then return end 
    local offX = distX * matrix[1][1] + distY * matrix[2][1] + distZ * matrix[3][1] + 1 * matrix[4][1] 
    local offY = distX * matrix[1][2] + distY * matrix[2][2] + distZ * matrix[3][2] + 1 * matrix[4][2] 
    local offZ = distX * matrix[1][3] + distY * matrix[2][3] + distZ * matrix[3][3] + 1 * matrix[4][3] 
    return offX, offY, offZ 
end 

Edited by Guest
Link to comment

if You want a stiff camera forced behind the vehicle, than use getElementMatrix function

You may also want to set the vehicle x rotation as “roll” in setCameraMatrix function...

as for the “camera ai”, I think its possible, but I don't know how hard can it be...

Note: math used in tropez link is the same as used in getElementMatrix function, I know – I've created a serverside getElementMatrix ;)

Link to comment

as for the “camera ai”, I think its possible, but I don't know how hard can it be...

i have managed to make it, however it is not perfect.

that is, checking doesn't centre of screen collide is very simple, i did it, but checking all four corners and doing proper maths to zoom camera in isn't easy at all.

i used freecam res as original source, and edited it quite a bit

PS: camera can be seen in viewtopic.php?f=98&t=37648&p=387866#p387866

Link to comment

If you dont want a stiff camera, you can make the offset change depending on vehicle velocity. so it faces the inverted direction of the velocity direction.

you can use this for smoother camera:

(note: if you dont want the camera to jump too much when changing direction, then get new value and old value and interpolate between the values with setCameraMatrix, for smooth animation.)

local maxDist = 13 
  
addEventHandler("onClientPreRender", getRootElement(), 
function() 
    local vehicle = getPedOccupiedVehicle(getLocalPlayer()) 
    if not vehicle then return end 
    local tarX, tarY, tarZ = getElementPosition(vehicle) 
    tarZ = tarZ + 1 
    local velX, velY, velZ = getElementVelocity(vehicle) 
    local rotX, rotY, rotZ = getElementRotation(vehicle) 
    local vel3D = (velX^2+velY^2+velZ^2)^0.5 
    if(vel3D == 0)then 
        local camX, camY, camZ = getRotatedPosition(vehicle, 0, -maxDist, 1.5) 
        --setCameraMatrix(camX, camY, camZ, tarX, tarY, tarZ) 
        return 
    end 
    local relX = velX / vel3D 
    local relY = velY / vel3D 
    local relZ = velZ / vel3D 
    local camX, camY, camZ = tarX, tarY, tarZ 
    camX, camY, camZ = camX-relX*maxDist, camY-relY*maxDist, camZ-relZ*maxDist+1.5 
    local hit, hitX, hitY, hitZ = processLineOfSight(tarX, tarY, tarZ, camX, camY, camZ, true, false, false, true, false, true, true, true) 
    local rot = 0 
    if hit and (rotX >= 45 and rotX <= 360-45)then 
        rot = 180 
        camX, camY, camZ = getRotatedPosition(vehicle, 0, 0, 1.5) 
        camX, camY, camZ = camX-relX*maxDist, camY-relY*maxDist, camZ-relZ*maxDist 
    else 
        rot = -rotY 
    end 
    setCameraMatrix(camX, camY, camZ, tarX, tarY, tarZ, rot) 
end) 
  
function getRotatedPosition(element, distX, distY, distZ) 
    if not element or not isElement(element) then return end 
    local matrix = getElementMatrix(element) 
    if not matrix then return end 
    local offX = distX * matrix[1][1] + distY * matrix[2][1] + distZ * matrix[3][1] + 1 * matrix[4][1] 
    local offY = distX * matrix[1][2] + distY * matrix[2][2] + distZ * matrix[3][2] + 1 * matrix[4][2] 
    local offZ = distX * matrix[1][3] + distY * matrix[2][3] + distZ * matrix[3][3] + 1 * matrix[4][3] 
    return offX, offY, offZ 
end 

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...