Jump to content

Positioning sticker on vehicle with cursor


Recommended Posts

I want to move the sticker which is placed on the vehicle with mouse.

At the moment I use the cursor's x,y position to set the sticker's x,y position inside the onClientRender event:

local cursorX,cursorY = getCursorPosition()

stickers[selectedStickerID][1] = cursorX * 1024 -- stickers is a table the first key is the sticker's x position (the 1024 is the UV-Map size which applied to the car)
stickers[selectedStickerID][2] = cursorY * 1024 -- the second key is the sticker's y position

but currently the moving is very strange... 

if the camera is looking on top of the car then the sticker moves as expected but for example if the camera is looking at the front of the car, if I move the mouse forwards the sticker moves backwards and so on as shown in the video below.

so I think I need to calculate the x,y position from the cursor (getCursorPosition) the camera (getCameraMatrix) and maybe the vehicle position (getElementPosition) together (?) I tried to play a bit in that way too but that was even worse

Here is a video to better understand what the problem is:

https://streamable.com/dssr52

Edited by thund3rbird23
Link to comment

first gets the cursor position, the camera matrix, and the vehicle position. Then, it calculates the sticker's X position by subtracting the camera's X translation from the cursor's X position, and adding the vehicle's X position. Similarly, it calculates the sticker's Y position by subtracting the camera's Y translation from the cursor's Y position, and adding the vehicle's Y position.
 




local cursorX, cursorY = getCursorPosition()
local cameraMatrix = getCameraMatrix()
local vehiclePosition = getElementPosition(vehicle)

local stickerX = cursorX * 1024 - cameraMatrix[12] + vehiclePosition[0]
local stickerY = cursorY * 1024 - cameraMatrix[13] + vehiclePosition[1]

stickers[selectedStickerID][1] = stickerX
stickers[selectedStickerID][2] = stickerY

 

Link to comment
16 hours ago, Trust aka Tiffergan said:

first gets the cursor position, the camera matrix, and the vehicle position. Then, it calculates the sticker's X position by subtracting the camera's X translation from the cursor's X position, and adding the vehicle's X position. Similarly, it calculates the sticker's Y position by subtracting the camera's Y translation from the cursor's Y position, and adding the vehicle's Y position.
 




local cursorX, cursorY = getCursorPosition()
local cameraMatrix = getCameraMatrix()
local vehiclePosition = getElementPosition(vehicle)

local stickerX = cursorX * 1024 - cameraMatrix[12] + vehiclePosition[0]
local stickerY = cursorY * 1024 - cameraMatrix[13] + vehiclePosition[1]

stickers[selectedStickerID][1] = stickerX
stickers[selectedStickerID][2] = stickerY

 

What are the 12th and 13th indexes for?

The getCameraMatrix function return only 8 number and you can't index them  because they are just numbers. Do you mean the x,y coords given by the getCameraMatrix function?

So, like this?:

local cursorX, cursorY = getCursorPosition()
local cameraX, cameraY = getCameraMatrix()
local vehicleX, vehicleY = getElementPosition(vehicle)

local stickerX = cursorX * 1024 - cameraX + vehicleX
local stickerY = cursorY * 1024 - cameraY + vehicleY

stickers[selectedStickerID][1] = stickerX
stickers[selectedStickerID][2] = stickerY


I tried that but got the same result, the sticker is moving perfectly forward and backward direction only if the camera is looking at the roof of the car (just like in the video)

I think I need to play with the vehicle's center position too somehow, when I moving the cursor or something like that?! Because if you're looking at the top of the vehicle then the camera is looking exactly at the middle of the vehicle, isn't it? 

Edited by thund3rbird23
Link to comment

My suggestion:

Use getCameraMatrix to get the x, y, z position of camera.

Use getWorldFromScreenPosition on position of the cursor, with depth being the maximum distance you want to reach, to get the cursor's 3D position at that distance.

Use processLineOfSight between camera and cursor coordinates to find the 3D position of the vehicle's surface point where the cursor is pointing.

Transform that surface point from world coordinate space to vehicle's local coordinate space with the help of getElementMatrix. This one is a bit tricky since the element matrix allows transforming from local to world space easily, using matrix x vector multiplication, but doing the opposite (world to local) requires multiplying the inverse of that matrix by vector, and there doesn't seem to be a built-in function for calculating the inverse of a matrix in MTA. I could do that in Lua, since it's not very complicated, but still easy enough to make a mistake.

Luckily, the vehicles have a scale of 1 and no shearing transformations (unless some glitch with Monster truck wheels occurs which does exactly that kind of crap to other vehicles), which makes the rotation matrix (the 3x3 part of element matrix) orthogonal, which in turn makes its inverse equal to transpose.

This is my attempt to transform the coordinates:

-- wx, wy, wz are the coordinates in world space

local m = getElementMatrix(vehicle)

local rx, ry, rz = wx-m[4][1], wy-m[4][2], wz = m[4][3]

local lx = m[1][1]*rx + m[1][2]*ry + m[1][3]*rz
local ly = m[2][1]*rx + m[2][2]*ry + m[2][3]*rz
local lz = m[3][1]*rx + m[3][2]*ry + m[3][3]*rz

Unless I screwed something up, lx, ly, lz should be wx, wy, wz relative to the vehicle. By transforming the cursor's 3D position like that, you can get the cursor's position with respect to the vehicle, which sounds like what you need.

  • Confused 2
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...