Jump to content

[help] camera roll


xxMANxx

Recommended Posts

I am doing First Person Perspective. When camera roll = 0, everything works fine. But if the camera roll is not equal to 0, then the camera also rotates as if the camera roll is 0.

principle:
 

addEventHandler ('onClientCursorMove',root, freecamMouse)
function freecamMouse (cX,cY,aX,aY)
	-- how far have we moved the mouse from the screen center?
	local width, height = guiGetScreenSize()
	aX = aX - width / 2 
	aY = aY - height / 2
	
	rotX = rotX + aX * mouseSensitivity * 0.01745
	rotY = rotY - aY * mouseSensitivity * 0.01745

end

addEventHandler ('onClientPreRender', root, updateCamera)

function updateCamera()
  local camPosXr, camPosYr, camPosZr = getPedBonePosition (localPlayer, 6)
  local camPosXl, camPosYl, camPosZl = getPedBonePosition (localPlayer, 7)
  local camPosX, camPosY, camPosZ = (camPosXr + camPosXl) / 2, (camPosYr + camPosYl) / 2, (camPosZr + camPosZl) / 2

  		-- note the vehicle rotation
		if inVehicle then
			local rx,ry,rz = getElementRotation(getPedOccupiedVehicle(localPlayer))
			
			roll = -ry
			if rx > 90 and rx < 270 then
				roll = ry - 180
			end
			
			if not wasInVehicle then
				rotX = rotX + math.rad(rz) 
				if rotY > -PI/15 then 
					rotY = -PI/15 
				end
			end
			
			cameraAngleX = rotX - math.rad(rz)
			cameraAngleY = rotY + math.rad(rx)
			
		else
			roll = 0
			cameraAngleX = rotX
			cameraAngleY = rotY
		end
		
  
	--Taken from the freecam resource made by eAi

  -- work out an angle in radians based on the number of pixels the cursor has moved (ever)

  local freeModeAngleZ = math.sin(cameraAngleY)
  local freeModeAngleY = math.cos(cameraAngleY) * math.cos(cameraAngleX)
  local freeModeAngleX = math.cos(cameraAngleY) * math.sin(cameraAngleX)

  -- calculate a target based on the current position and an offset based on the angle
  local camTargetX = camPosX + freeModeAngleX * 100
  local camTargetY = camPosY + freeModeAngleY * 100
  local camTargetZ = camPosZ + freeModeAngleZ * 100

  -- Work out the distance between the target and the camera (should be 100 units)
  local camAngleX = camPosX - camTargetX
  local camAngleY = camPosY - camTargetY
  local camAngleZ = 0 -- we ignore this otherwise our vertical angle affects how fast you can strafe

  -- Calulcate the length of the vector
  local angleLength = math.sqrt(camAngleX*camAngleX+camAngleY*camAngleY+camAngleZ*camAngleZ)

  -- Normalize the vector, ignoring the Z axis, as the camera is stuck to the XY plane (it can't roll)
  local camNormalizedAngleX = camAngleX / angleLength
  local camNormalizedAngleY = camAngleY / angleLength
  local camNormalizedAngleZ = 0

  -- We use this as our rotation vector
  local normalAngleX = 0
  local normalAngleY = 0
  local normalAngleZ = 1

  -- Perform a cross product with the rotation vector and the normalzied angle
  local normalX = (camNormalizedAngleY * normalAngleZ - camNormalizedAngleZ * normalAngleY)
  local normalY = (camNormalizedAngleZ * normalAngleX - camNormalizedAngleX * normalAngleZ)
  local normalZ = (camNormalizedAngleX * normalAngleY - camNormalizedAngleY * normalAngleX)

  -- Update the target based on the new camera position (again, otherwise the camera kind of sways as the target is out by a frame)
  camTargetX = camPosX + freeModeAngleX * 100
  camTargetY = camPosY + freeModeAngleY * 100
  camTargetZ = camPosZ + freeModeAngleZ * 100

  -- Set the new camera position and target
  setCameraMatrix (camPosX, camPosY, camPosZ, camTargetX, camTargetY, camTargetZ, roll, fov)
end

pER3aU28Olo.jpg

I think need something like that.
but I don’t know how to do this, because the parameter "roll" in setCameraMatrix rotates only “visually” and not the coordinate system

Link to comment
  • Moderators
On 07/10/2019 at 06:25, xxMANxx said:

the problem on video

 

This might help you: (based on these examples)

function createMatrix(x, y, z, rx, ry, rz)
    rx, ry, rz = math.rad(rx), math.rad(ry), math.rad(rz)
    local matrix = {}
    matrix[1] = {}
    matrix[1][1] = math.cos(rz)*math.cos(ry) - math.sin(rz)*math.sin(rx)*math.sin(ry)
    matrix[1][2] = math.cos(ry)*math.sin(rz) + math.cos(rz)*math.sin(rx)*math.sin(ry)
    matrix[1][3] = -math.cos(rx)*math.sin(ry)
    matrix[1][4] = 1
    
    matrix[2] = {}
    matrix[2][1] = -math.cos(rx)*math.sin(rz)
    matrix[2][2] = math.cos(rz)*math.cos(rx)
    matrix[2][3] = math.sin(rx)
    matrix[2][4] = 1
	
    matrix[3] = {}
    matrix[3][1] = math.cos(rz)*math.sin(ry) + math.cos(ry)*math.sin(rz)*math.sin(rx)
    matrix[3][2] = math.sin(rz)*math.sin(ry) - math.cos(rz)*math.cos(ry)*math.sin(rx)
    matrix[3][3] = math.cos(rx)*math.cos(ry)
    matrix[3][4] = 1
	
    matrix[4] = {}
    matrix[4][1], matrix[4][2], matrix[4][3] = x, y, z
    matrix[4][4] = 1
	
    return matrix
end

function getPositionFromMatrixOffset(m, offX, offY, offZ)
    local x = offX * m[1][1] + offY * m[2][1] + offZ * m[3][1] + m[4][1]  -- Apply transform
    local y = offX * m[1][2] + offY * m[2][2] + offZ * m[3][2] + m[4][2]
    local z = offX * m[1][3] + offY * m[2][3] + offZ * m[3][3] + m[4][3]
    return x, y, z                               -- Return the transformed point
end

 

With this you can calculate from every orientation the matrix and offset positions.

Feel free to apply a different rotation value, so that the offset is also turning.

 

Optional method: (but might not be 100% accurate)

Between 2 positions in front of you can rotate the camera, see:

https://wiki.multitheftauto.com/wiki/InterpolateBetween

 

I hope this will make you see the light, it did for me when doing complex 3D calculations.

:thumbleft:

 

 

 

 

Edited by IIYAMA
  • Thanks 1
Link to comment
19 hours ago, IIYAMA said:

 

This might help you: (based on these examples)


function createMatrix(x, y, z, rx, ry, rz)
    rx, ry, rz = math.rad(rx), math.rad(ry), math.rad(rz)
    local matrix = {}
    matrix[1] = {}
    matrix[1][1] = math.cos(rz)*math.cos(ry) - math.sin(rz)*math.sin(rx)*math.sin(ry)
    matrix[1][2] = math.cos(ry)*math.sin(rz) + math.cos(rz)*math.sin(rx)*math.sin(ry)
    matrix[1][3] = -math.cos(rx)*math.sin(ry)
    matrix[1][4] = 1
    
    matrix[2] = {}
    matrix[2][1] = -math.cos(rx)*math.sin(rz)
    matrix[2][2] = math.cos(rz)*math.cos(rx)
    matrix[2][3] = math.sin(rx)
    matrix[2][4] = 1
	
    matrix[3] = {}
    matrix[3][1] = math.cos(rz)*math.sin(ry) + math.cos(ry)*math.sin(rz)*math.sin(rx)
    matrix[3][2] = math.sin(rz)*math.sin(ry) - math.cos(rz)*math.cos(ry)*math.sin(rx)
    matrix[3][3] = math.cos(rx)*math.cos(ry)
    matrix[3][4] = 1
	
    matrix[4] = {}
    matrix[4][1], matrix[4][2], matrix[4][3] = x, y, z
    matrix[4][4] = 1
	
    return matrix
end

function getPositionFromMatrixOffset(m)
    local x = offX * m[1][1] + offY * m[2][1] + offZ * m[3][1] + m[4][1]  -- Apply transform
    local y = offX * m[1][2] + offY * m[2][2] + offZ * m[3][2] + m[4][2]
    local z = offX * m[1][3] + offY * m[2][3] + offZ * m[3][3] + m[4][3]
    return x, y, z                               -- Return the transformed point
end

 

With this you can calculate from every orientation the matrix and offset positions.

Feel free to apply a different rotation value, so that the offset is also turning.

 

Optional method: (but might not be 100% accurate)

Between 2 positions in front of you can rotate the camera, see:

https://wiki.multitheftauto.com/wiki/InterpolateBetween

 

I hope this will make you see the light, it did for me when doing complex 3D calculations.

:thumbleft:

 

 

 

 

thanks for help, I'll try to understand
  • Like 1
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...