[Include] Rotations.inc
#1

Rotations

This include gives you the possibility to convert rotations

Installation and reference

GitHub

Download

Version 2.0
Version 1.2
Reply
#2

You and the maths.. My god xd

Good work
Reply
#3

My god, nice maths. You can really help me with exams joking but really nice maths.
Reply
#4

Translation and Rotation function for RotationMatrix added

New functions
PHP Code:
// AroundRelPoint
RotMatrixMatrixAroundRelPoint(Floatmatrix1[4][4], FloatoXFloatoYFloatoZFloatmatrix2[4][4])
RotMatrixQuatAroundRelPoint(Floatmatrix[4][4], FloatoXFloatoYFloatoZFloatwFloatxFloatyFloatz)
RotMatrixEulerAroundRelPoint(Floatmatrix[4][4], FloatoXFloatoYFloatoZFloatrXFloatrYFloatrZeulermodemode euler_samp)
RotMatrixAxisAroundRelPoint(Floatmatrix1[4][4], FloatoXFloatoYFloatoZFloatangleFloataXFloataYFloataZ)
// AroundPoint
RotMatrixMatrixAroundPoint(Floatmatrix1[4][4], FloatxFloatyFloatzFloatmatrix2[4][4])
RotMatrixQuatAroundPoint(Floatmatrix[4][4], FloatxFloatyFloatzFloatwFloatqXFloatqYFloatqZ)
RotMatrixEulerAroundPoint(Floatmatrix[4][4], FloatxFloatyFloatzFloatrXFloatrYFloatrZeulermodemode euler_samp)
RotMatrixAxisAroundPoint(Floatmatrix1[4][4], FloatxFloatyFloatzFloatangleFloataXFloataYFloataZ)
// TranslateMatrix
TranslateMatrix(Floatmatrix[4][4], FloatxFloatyFloatz)
// RotateMatrix
RotateMatrixWithMatrix(Floatmatrix1[4][4], Floatmatrix2[4][4])
RotateMatrixWithQuat(Floatmatrix[4][4], FloatwFloatxFloatyFloatz)
RotateMatrixWithEuler(Floatmatrix[4][4], FloatrXFloatrYFloatrZeulermodemode euler_samp)
RotateMatrixWithAxisAngle(Floatmatrix[4][4], FloatangleFloataXFloataYFloataZ)
// GetTranslationMatrix
GetTranslationMatrix(Floatmatrix[4][4], FloatxFloatyFloatz
Reply
#5

Hmm... Wasn't there a lot more comments on this thread? I know I had a discussion about this include here and said how badass it was...
Reply
#6

Quote:
Originally Posted by Crayder
View Post
Hmm... Wasn't there a lot more comments on this thread? I know I had a discussion about this include here and said how badass it was...
Never was but thanks anyways, maybe another thread, 3DTryg from AbyssMorgan ?

I still get this feeling that this include isn't very user friendly but I am not sure how to accomplish a more compact structure within pawn
Reply
#7

Quote:
Originally Posted by Nero_3D
View Post
Never was but thanks anyways, maybe another thread, 3DTryg from AbyssMorgan ?
YES! Lol...

Quote:
Originally Posted by Nero_3D
View Post
I still get this feeling that this include isn't very user friendly but I am not sure how to accomplish a more compact structure within pawn
I think it is user friendly, but it's just not something the majority of the people here are going to use. It's extremely useful for those who know what it is though. I've already used it quite a bit.
Reply
#8

3DTryg.inc partly uses rotations.inc (Internal) I suspect that this include useful for more advanced developers.
Typically create a function that is easy to use by anyone (Not including programmers from my country XD).
Reply
#9

I am trying to create graffiti object in front of another graffiti object (graffiti tagged), but I don't know how to get position in front of object relative to object's rotation (rx, ry, rz). My actual code

Code:
new Float:lGraffitiX, Float:lGraffitiY, Float:lGraffitiZ, Float:lGraffitiRX, Float:lGraffitiRY, Float:lGraffitiRZ;
GetDynamicObjectPos(Graffiti[tagid][graffiti_object], lGraffitiX, lGraffitiY, lGraffitiZ);
GetDynamicObjectRot(Graffiti[tagid][graffiti_object], lGraffitiRX, lGraffitiRY, lGraffitiRZ);
Use(lGraffitiX, lGraffitiY, lGraffitiZ, lGraffitiRX, lGraffitiRY, lGraffitiRZ, lGraffitiX, lGraffitiY, lGraffitiZ);
Graffiti[tagid][graffiti_object_made] = CreateDynamicObject(18659, lGraffitiX, lGraffitiY, lGraffitiZ, lGraffitiRX, lGraffitiRY, lGraffitiRZ, .interiorid = 0);

Use(Float:oX, Float:oY, Float:oZ, Float:rX, Float:rY, Float:rZ, &Float:x, &Float:y, &Float:z)
{
	new 
    Float: matrix[4][4] 
; 
// Get rotation Matrix from Euler 
GetRotationMatrixFromEuler(matrix, rX, rY, rZ); 
// Rotate matrix around relative point of object 
// 0.0, 0.0, 1.0 = relative point = 1.0 above object center 
// 5.0, 0.0, 0.0 = euler rotation = 5.0 degress in rX direction 
RotMatrixEulerAroundRelPoint(matrix, 0.0, 0.0, 1.0, 5.0, 0.0, 0.0); 
// Getting relative point, 0.0, 0.0, 0.0, 1.0 = offsets x, y, z and translation 
// because we only need the translation we set, x, y, z offsets to 0.0 
MatrixRotate(matrix, 0.0, 0.0, 0.0, 1.0, oX, oY, oZ); 
x = oX;
y = oY;
z = oZ;
}
It works only with one angle, see image below. Grove tag should cover another tag. On the wall it works, but on the ground it does not. Any ideas?

https://i.imgur.com/3DXKHt7.jpg

//EDIT

Done it, I used wrong function. Working code

Code:
GetQuatFromEuler(rx, ry, rz, qw, qx, qy, qz);
QuatRotate(qw, qx, qy, qz, -0.05, 0.0, 0.0, x, y, z);
//use x, y, z
Reply
#10

Quote:
Originally Posted by ball
View Post
Done it, I used wrong function. Working code

Code:
GetQuatFromEuler(rx, ry, rz, qw, qx, qy, qz);
QuatRotate(qw, qx, qy, qz, -0.05, 0.0, 0.0, x, y, z);
//use x, y, z
That is excatly what EulerRotate does

Also one thing to note, normally +oY would be in front of a vehicle (facing north)
But for objects it matters in which direction they look without rotation (If facing North, +oY is the front, East = +oX, South = -oY, West = -oX)
Reply
#11

Added GetVehicleObjectPositionOffset / GetVehicleObjectPositionWorld to calculate the position and rotation from a normal object to an attached object / vice versa

PHP код:
GetVehicleObjectPositionWorld(vehicleidFloatatt_XFloatatt_YFloatatt_ZFloatatt_rotXFloatatt_rotYFloatatt_rotZ, &FloatX, &FloatY, &FloatZ, &FloatrotX, &FloatrotY, &FloatrotZ)
GetVehicleObjectPositionOffset(vehicleidFloatXFloatYFloatZFloatrotXFloatrotYFloatrotZ, &Floatatt_X, &Floatatt_Y, &Floatatt_Z, &Floatatt_rotX, &Floatatt_rotY, &Floatatt_rotZ
Well, I didn't intend to add functions for special cases but putting these in the example section would be copy and paste
Reply
#12

Do you know how you can get the right rotations of world objects? Like if i copy and paste the world objects from sa-mp map editor it sometimes returns the wrong rotations.
Reply
#13

Quote:
Originally Posted by Admigo
Посмотреть сообщение
Do you know how you can get the right rotations of world objects? Like if i copy and paste the world objects from sa-mp map editor it sometimes returns the wrong rotations.
Somtimes?, than it is a bug in map editor?, first I would ask JernejL if he knows something about that and why it hasn't been fixed
Getting the right result from a false one is nearly impossible if you don't know how the right one from the false one differ
Reply
#14

How to make an adequate GetXYInFrontOfPlayer using this library?
Reply
#15

Quote:
Originally Posted by kennydalglish
Посмотреть сообщение
How to make an adequate GetXYInFrontOfPlayer using this library?
Wrong lib this is library for Rotations/Quaretnions/3D Offsets

You need 3DTryg.inc for coordinates / rotations / vectors / arc / areas / offset
PHP код:
GetPointInFront2D(Float:x,Float:y,Float:rz,Float:radius,&Float:tx,&Float:ty); 
GetPointInFront3D(Float:x,Float:y,Float:z,Float:rx,Float:rz,Float:radius,&Float:tx,&Float:ty,&Float:tz); 
Float:GetPointInFrontOfPlayer(playerid,&Float:tx,&Float:ty,Float:radius);
Float:GetPointInFrontOfCamera2D(playerid,&Float:tx,&Float:ty,Float:radius);
GetPointInFrontOfCamera3D(playerid,&Float:tx,&Float:ty,&Float:tz,Float:radius,&Float:rx=0.0,&Float:rz=0.0); 
Float:GetPointInFrontOfVehicle2D(vehicleid,&Float:tx,&Float:ty,Float:radius); 
GetPointInFrontOfVehicle3D(vehicleid,&Float:tx,&Float:ty,&Float:tz,Float:radius,&Float:rx=0.0,&Float:rz=0.0); 
Reply
#16

Quote:
Originally Posted by kennydalglish
Посмотреть сообщение
How to make an adequate GetXYInFrontOfPlayer using this library?
AbyssMorgan is correct, it is not the main purpose of this include
But to answer your question you could use any "Rotate" function
Quote:

MatrixRotate(Float: matrix[4][4], Float: oX, Float: oY, Float: oZ, Float: oT, & Float: X, & Float: Y, & Float: Z)
QuatRotate(Float: w, Float: x, Float: y, Float: z, Float: oX, Float: oY, Float: oZ, & Float: X, & Float: Y, & Float: Z)
EulerRotate(Float: rX, Float: rY, Float: rZ, Float: oX, Float: oY, Float: oZ, & Float: X, & Float: Y, & Float: Z, eulermode: mode = euler_samp)
AxisAngleRotate(Float: angle, Float: aX, Float: aY, Float: aZ, Float: oX, Float: oY, Float: oZ, & Float: X, & Float: Y, & Float: Z)

For players I would suggest EulerRotate because there is only GetPlayerFacingAngle
PHP код:
new FloatXFloatYFloatZ;
GetPlayerPos(playeridXYZ);
new 
FloatrZ// the only angle you can get is rZ
GetPlayerFacingAngle(playeridrZ); // use 0.0 for rX and rY
// oX (right vector offset) = 0.0, oY (front vector offset) = 5.0, oZ (up vector offset) = 0.0
EulerRotate(0.00.0rZ0.05.00.0XYZ);
// X, Y, Z should now be 5 units before the player 
Anyway this inlude is overkill if you only need GetXYInFrontOfPlayer, actually it would be slower because it takes rX and rY in the calculation, so there is no optimisation if only rZ is present
Just search for GetXYInFrontOfPlayer, it has been asked / posted thousand times
Reply
#17

Xmm, anyway, you can go outside the landfill. For a reason that I do not understand. How can I fix it?

https://www.youtube.com/watch?v=ZakA...ature=*********

Quote:
Originally Posted by Nero_3D
Посмотреть сообщение
AbyssMorgan is correct, it is not the main purpose of this include
But to answer your question you could use any "Rotate" function

For players I would suggest EulerRotate because there is only GetPlayerFacingAngle
PHP код:
new FloatXFloatYFloatZ;
GetPlayerPos(playeridXYZ);
new 
FloatrZ// the only angle you can get is rZ
GetPlayerFacingAngle(playeridrZ); // use 0.0 for rX and rY
// oX (right vector offset) = 0.0, oY (front vector offset) = 5.0, oZ (up vector offset) = 0.0
EulerRotate(0.00.0rZ0.05.00.0XYZ);
// X, Y, Z should now be 5 units before the player 
Anyway this inlude is overkill if you only need GetXYInFrontOfPlayer, actually it would be slower because it takes rX and rY in the calculation, so there is no optimisation if only rZ is present
Just search for GetXYInFrontOfPlayer, it has been asked / posted thousand times
Reply
#18

Quote:
Originally Posted by kennydalglish
Посмотреть сообщение
Xmm, anyway, you can go outside the landfill. For a reason that I do not understand. How can I fix it?

https://www.youtube.com/watch?v=ZakA...ature=*********
Well, it is a bug in your code, no clue how you use GetXYInFrontOfPlayer to determine if the player is outside or not but the correct solution for your problem would be to check if the player is inside a polygon
Refer to IsPlayerInPolygon, it can be found in 3DTryg, it is based on ray-casting (wiki)
Still remember that RyDeR`posted the function and ****** said, it has been here for years XD
Reply
#19

Hey. I tried to make the function of tilting through the timer, but it still does not work correctly. Can you help me?
PHP код:
SetPlayerTimerEx(playerid"@@CheckPlayerInPolygons"250, -1,  "d"playerid); 
PHP код:
@@CheckPlayerInPolygons(const playerid);
@@
CheckPlayerInPolygons(const playerid)
{
    new 
Floatx_pos,
        
Floaty_pos,
        
Floatz_pos;
    
GetPlayerPos(playeridx_posy_posz_pos);
    if(!
IsPointInPolygon(x_posy_pos,     {                        42.0,2336.0,
        -
1327.0,2601.0,
        -
1349.0,2675.0,
        -
1397.0,2712.0,
        -
1435.0,2728.0,
        -
1501.0,2737.0,
        -
1560.0,2740.0,
        -
1627.0,2734.0,
        -
1653.0,2718.0,
        -
1639.0,2654.0,
        -
1610.0,2604.0,
        -
1604.0,2547.0,
        -
1596.0,2499.0,
        -
1474.0,2486.0,
        -
1406.0,2521.0,
        -
1337.0,2523.0,
        -
1327.0,2601.0}))
    {
        new 
FloatXFloatYFloatZ;
        
GetPlayerPos(playeridXYZ);
        new 
FloatrZ// the only angle you can get is rZ
        
GetPlayerFacingAngle(playeridrZ); // use 0.0 for rX and rY
        // oX (right vector offset) = 0.0, oY (front vector offset) = 5.0, oZ (up vector offset) = 0.0
        
EulerRotate(0.00.0rZ0.0, -5.00.0XYZ);
        
// X, Y, Z should now be 5 units before the player
        
SetPlayerPos(playeridXYZ);      
    }

Anyway, you can go beyond the polygon

Quote:
Originally Posted by Nero_3D
Посмотреть сообщение
Well, it is a bug in your code, no clue how you use GetXYInFrontOfPlayer to determine if the player is outside or not but the correct solution for your problem would be to check if the player is inside a polygon
Refer to IsPlayerInPolygon, it can be found in 3DTryg, it is based on ray-casting (wiki)
Still remember that RyDeR`posted the function and ****** said, it has been here for years XD
Reply
#20

I have a small problem with GetRotationMatrixFromEuler.

I'm trying to calculate a quaternion based on z angle (direction) and the surface angle (rx and ry) to apply correct rotations to an NPC Vehicle.

What I do is getting the rotation matrix for the facing angle, and if the surface isn't flat I further rotate the matrix with the x and y rotation.

After that I get the Matrix as Quaternion to use with FCNPC_SetQuaternion.

Код:
new Float:matrix[4][4];
GetRotationMatrixFromEuler(matrix, 0.0, 0.0, rz, euler_samp);
RotateMatrixWithEuler(matrix, surface_rx, surface_ry, 0.0, euler_samp);

GetQuatFromMatrix(matrix, qw, qx, qy, qz);
This works perfectly fine, except when the facing angle is 180.0 (or very close to it). If it's 180.0, the z angle of the returned quaternion is 0.0.

I've removed RotateMatrixWithEuler for testing, however it still happened so it's not that part.

I'm pretty sure that it isn't an issue with FCNPC as I was using another method before which worked (the quaternion is almost the same, except the z angle under these circumstances).

I'm not sure if I'm doing something wrong, but the fact that it works for all other scenarios tells me it should be correct.

Do you have an idea what it could be?

EDIT: I'm now converting the Matrix to Euler angles, and the Euler Angles to a Quaternion. This extra step fixed it.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)