Unique velocity to scale on 2 different vectors///Sorry if i post here,but i didn't receive any answer

1bytecharhaterxxx

New member
Joined
Jan 17, 2021
Messages
8
i'm really getting mad to implement a movement system on my engine,i really need to help to understand how this is usually done cause i'm a beginner what i've done so far is this :
//////+Z UP///-Y FRONT////-X RIGHT
//////FRONT_BACK
VEC3 delta_front,delta_right,delta_y,delta_x,delta_xy;
core_ptr->mov->delta_accel = RUN_ACCEL * core_ptr->timer->delta_t;
core_ptr->mov->delta_friction = pow(RUN_FRICTION,core_ptr->timer->delta_t);
///////////FRONT
vec3_quat_multiply(delta_front,core_ptr->cam->inv_orientation,FRONT_VEC);
vec3_scale(delta_y,delta_front,core_ptr->mov->y_vel);
//////////////////RIGHT
vec3_quat_multiply(delta_right,core_ptr->cam->inv_orientation,RIGHT_VEC);
vec3_scale(delta_x,delta_right,core_ptr->mov->x_vel);

delta_xy[0] = delta_y[0] + delta_x[0];
delta_xy[1] = delta_y[1] + delta_x[1];
core_ptr->cam->cam_pos[0] += delta_xy[0];
core_ptr->cam->cam_pos[1] += delta_xy[1];

if((key_is_pressed(core_ptr,core_ptr->kbd->move_front)) == 1 )
{
core_ptr->mov->y_vel -= core_ptr->mov->delta_accel;
}
if((key_is_pressed(core_ptr,core_ptr->kbd->move_back)) == 1 )
{
core_ptr->mov->y_vel += core_ptr->mov->delta_accel;
}
if((key_is_pressed(core_ptr,core_ptr->kbd->move_right)) == 1 )
{
core_ptr->mov->x_vel -= core_ptr->mov->delta_accel;
}
if((key_is_pressed(core_ptr,core_ptr->kbd->move_left)) == 1 )
{
core_ptr->mov->x_vel += core_ptr->mov->delta_accel;
}

core_ptr->mov->x_vel *= core_ptr->mov->delta_friction;
core_ptr->mov->y_vel *= core_ptr->mov->delta_friction;
printf("X VELOCITY = %lf\n",core_ptr->mov->x_vel );
printf("y VELOCITY = %lf\n",core_ptr->mov->y_vel );

So,basically this is working,the problem i'm facing btw is that when i press for example front+right,the speed is a lot higher cause it sums the 2 velocities,so i have double max speed and double accel...i really want to keep updating the positions togheter to let the friction always kickin in,but i didnt find any easy solution to this problem,ideally i would have only a single velocity,and i would update the 2 vectors accordinly but i have no idea i'm just lost...i hope someone is so gentle to help me with the math theory :/ bye
 
i'm really getting mad to implement a movement system on my engine,i really need to help to understand how this is usually done cause i'm a beginner what i've done so far is this :
//////+Z UP///-Y FRONT////-X RIGHT
//////FRONT_BACK
VEC3 delta_front,delta_right,delta_y,delta_x,delta_xy;
core_ptr->mov->delta_accel = RUN_ACCEL * core_ptr->timer->delta_t;
core_ptr->mov->delta_friction = pow(RUN_FRICTION,core_ptr->timer->delta_t);
///////////FRONT
vec3_quat_multiply(delta_front,core_ptr->cam->inv_orientation,FRONT_VEC);
vec3_scale(delta_y,delta_front,core_ptr->mov->y_vel);
//////////////////RIGHT
vec3_quat_multiply(delta_right,core_ptr->cam->inv_orientation,RIGHT_VEC);
vec3_scale(delta_x,delta_right,core_ptr->mov->x_vel);

delta_xy[0] = delta_y[0] + delta_x[0];
delta_xy[1] = delta_y[1] + delta_x[1];
core_ptr->cam->cam_pos[0] += delta_xy[0];
core_ptr->cam->cam_pos[1] += delta_xy[1];

if((key_is_pressed(core_ptr,core_ptr->kbd->move_front)) == 1 )
{
core_ptr->mov->y_vel -= core_ptr->mov->delta_accel;
}
if((key_is_pressed(core_ptr,core_ptr->kbd->move_back)) == 1 )
{
core_ptr->mov->y_vel += core_ptr->mov->delta_accel;
}
if((key_is_pressed(core_ptr,core_ptr->kbd->move_right)) == 1 )
{
core_ptr->mov->x_vel -= core_ptr->mov->delta_accel;
}
if((key_is_pressed(core_ptr,core_ptr->kbd->move_left)) == 1 )
{
core_ptr->mov->x_vel += core_ptr->mov->delta_accel;
}

core_ptr->mov->x_vel *= core_ptr->mov->delta_friction;
core_ptr->mov->y_vel *= core_ptr->mov->delta_friction;
printf("X VELOCITY = %lf\n",core_ptr->mov->x_vel );
printf("y VELOCITY = %lf\n",core_ptr->mov->y_vel );

So,basically this is working,the problem i'm facing btw is that when i press for example front+right,the speed is a lot higher cause it sums the 2 velocities,so i have double max speed and double accel...i really want to keep updating the positions togheter to let the friction always kickin in,but i didnt find any easy solution to this problem,ideally i would have only a single velocity,and i would update the 2 vectors accordinly but i have no idea i'm just lost...i hope someone is so gentle to help me with the math theory :/ bye
Let's say your velocity vector is (0,1). What should it be after pressing "right"? Do you want to increase x and reduce y by delta? Or y should become 0 and x 1+delta?
I would apply vector rotation, but it's not clear what you want to happen on turns.
 
Let's say your velocity vector is (0,1). What should it be after pressing "right"? Do you want to increase x and reduce y by delta? Or y should become 0 and x 1+delta?
I would apply vector rotation, but it's not clear what you want to happen on turns.

Hi thank you for the interest really...btw yes one solution would be to level each velocity but i don't think it's the correct approach cause for example if i press forward and right (i would press each button in a different time)it wouldn't be an equal accel on both axis,what i'm thinking is to just use a single velocity but then i get confused on how update each vector with the exact amount of accel without calculating it on the run(so in the moment when i press the button to calculate the exact orientation)...so in my dream it would be i press forward-right i have a single vector a single velocity and i apply to it a simplified friction...but i have no idea how to do it,i saw a lot of tutorials usually updating on the run each orientation to the pos(so like press w apply accell apply friction to the front or right vec)and if no button pressed apply friction,but i wonder if there is another approach mathematically,i hope you understood my words,i'm not so good in english xd
 
Hi thank you for the interest really...btw yes one solution would be to level each velocity but i don't think it's the correct approach cause for example if i press forward and right (i would press each button in a different time)it wouldn't be an equal accel on both axis,what i'm thinking is to just use a single velocity but then i get confused on how update each vector with the exact amount of accel without calculating it on the run(so in the moment when i press the button to calculate the exact orientation)...so in my dream it would be i press forward-right i have a single vector a single velocity and i apply to it a simplified friction...but i have no idea how to do it,i saw a lot of tutorials usually updating on the run each orientation to the pos(so like press w apply accell apply friction to the front or right vec)and if no button pressed apply friction,but i wonder if there is another approach mathematically,i hope you understood my words,i'm not so good in english xd
Ok, so every iteration you want to do a single adjustment.
I would try this:
1. add a variable for delta vector, initialized it with zeros.
2. in your "if" statements instead of adjusting x and y in core_ptr->mov adjust the delta vector
3. make magnitude of the delta vector equal to delta so that your speed doesn't increase too much. It's done by multiplying x and y by delta/M, where M is the current magnitude
4. add delta vector to core_ptr->mov

In your example of forward & right press the delta vector initially will be at 45 degrees and too long. But when we adjust its magnitude it will become the same length as in single forward press.
 
Ok, so every iteration you want to do a single adjustment.
I would try this:
1. add a variable for delta vector, initialized it with zeros.
2. in your "if" statements instead of adjusting x and y in core_ptr->mov adjust the delta vector
3. make magnitude of the delta vector equal to delta so that your speed doesn't increase too much. It's done by multiplying x and y by delta/M, where M is the current magnitude
4. add delta vector to core_ptr->mov

In your example of forward & right press the delta vector initially will be at 45 degrees and too long. But when we adjust its magnitude it will become the same length as in single forward press.

hi thank you again this is making sense but i'm a bit lost so little example:
vec3_init(core_ptr->mov->delta_try,0.0f,0.0f,0.0f); ///delta_try is the delta vector :D

if((key_is_pressed(core_ptr,core_ptr->kbd->move_front)) == 1 )
{
core_ptr->mov->delta_try[1] -= core_ptr->mov->delta_accel;
}
if((key_is_pressed(core_ptr,core_ptr->kbd->move_left)) == 1 )
{
core_ptr->mov->delta_try[0] += core_ptr->mov->delta_accel;
}

now make the length of delta_vector equal to delta?you mean equal to the 2 vectors?to the delta accel like averaging it?
in my code i get the actual orientation like this (i get them from a 3x3 rotation matrix and rotate around global defined axis like 0 -1 0 / -1 0 0):

vec3_quat_multiply(delta_front,core_ptr->cam->inv_orientation,FRONT_VEC);
vec3_quat_multiply(delta_right,core_ptr->cam->inv_orientation,RIGHT_VEC);
 
hi thank you again this is making sense but i'm a bit lost so little example:
vec3_init(core_ptr->mov->delta_try,0.0f,0.0f,0.0f); ///delta_try is the delta vector :D

if((key_is_pressed(core_ptr,core_ptr->kbd->move_front)) == 1 )
{
core_ptr->mov->delta_try[1] -= core_ptr->mov->delta_accel;
}
if((key_is_pressed(core_ptr,core_ptr->kbd->move_left)) == 1 )
{
core_ptr->mov->delta_try[0] += core_ptr->mov->delta_accel;
}

now make the length of delta_vector equal to delta?you mean equal to the 2 vectors?to the delta accel like averaging it?
in my code i get the actual orientation like this (i get them from a 3x3 rotation matrix and rotate around global defined axis like 0 -1 0 / -1 0 0):

vec3_quat_multiply(delta_front,core_ptr->cam->inv_orientation,FRONT_VEC);
vec3_quat_multiply(delta_right,core_ptr->cam->inv_orientation,RIGHT_VEC);
In the attached photo the left diagram shows what happens now (if I understand your code correctly). When you press forward and right you add delta to x component of your velocity vector AND to y component. This is equivalent to adding vector F and vector R to the velocity vector. This is also equivalent to adding vector F+R to your velocity vector. As you can see the vector F+R has greater magnitude than F or R. That's why your speed increases faster in this scenario compared to pressing forward only or right only.

The right diagram shows what I suggested. First, you initialize the delta vector depending on what's pressed. Then you make its magnitude equal to delta. Then you add the delta vector to the velocity vector.
 

Attachments

  • vec.jpg
    vec.jpg
    211 KB · Views: 2
In the attached photo the left diagram shows what happens now (if I understand your code correctly). When you press forward and right you add delta to x component of your velocity vector AND to y component. This is equivalent to adding vector F and vector R to the velocity vector. This is also equivalent to adding vector F+R to your velocity vector. As you can see the vector F+R has greater magnitude than F or R. That's why your speed increases faster in this scenario compared to pressing forward only or right only.

The right diagram shows what I suggested. First, you initialize the delta vector depending on what's pressed. Then you make its magnitude equal to delta. Then you add the delta vector to the velocity vector.

Hi thank you,i didn't understand initially,but it was really simple i can't believe i'm so stupid,i cleaned up my code a little and abstracted everything to get the exact moment when you press forward and right togheter so from there i did this :

////FRONT
core_ptr->cam->cam_front[2] = 0.0f;
vec3_normalize(core_ptr->cam->cam_front);
front[0] = core_ptr->cam->cam_front[0];
front[1] = core_ptr->cam->cam_front[1];
vec2_scale(delta_y,front,dir_xy[1]*core_ptr->mov->delta_accel);

//////RIGHT
core_ptr->cam->cam_right[2] = 0.0f;
vec3_normalize(core_ptr->cam->cam_right);
right[0] = core_ptr->cam->cam_right[0];
right[1] = core_ptr->cam->cam_right[1];
vec2_scale(delta_x,right,dir_xy[0]*core_ptr->mov->delta_accel);

FLOAT mag_y = sqrtf((delta_y[0] * delta_y[0]) + (delta_y[1] * delta_y[1]));
FLOAT mag_x = sqrtf((delta_x[0] * delta_x[0]) + (delta_x[1] * delta_x[1]));
delta_xy[0] = delta_y[0] + delta_x[0];
delta_xy[1] = delta_y[1] + delta_x[1];
FLOAT mega_mag = sqrtf((delta_xy[0] * delta_xy[0]) + (delta_xy[1] * delta_xy[1]));

delta_xy[0] *= mag_x/mega_mag;
delta_xy[1] *= mag_y/mega_mag;
FLOAT final_mag = sqrtf((delta_xy[0] * delta_xy[0]) + (delta_xy[1] * delta_xy[1]));

printf(" Y = %f\n X = %f\n MEGA_MAG = %f\n FINAL_MAG = %f \n",mag_y,mag_x,mega_mag,final_mag);
core_ptr->cam->cam_pos[0] += delta_xy[0];
core_ptr->cam->cam_pos[1] += delta_xy[1];

EXAMPLE OUTPUT FROM CONSOLE:::

Y = 20.000000
X = 20.000000
MEGA_MAG = 28.284269
FINAL_MAG = 20.000000
Y = 32.000000
X = 32.000000
MEGA_MAG = 45.254833
FINAL_MAG = 31.999998
Y = 20.000000
X = 20.000000
MEGA_MAG = 28.284269
FINAL_MAG = 20.000000

and you were right,now the delta magnitude is equal to the single magnitude of one of the vecs....now i try to add friction and the rest and to apply a single velocity i hope i will be able to do it if not prepare to be stalked again :D <3
 
Hi,so basically now i can move with the same accell like you said by multiplying and dividing for the single magnitude,i'm able to apply my simplified friction to 2 velocities(yes i think that to have 2 velocities is the best option),and when i move frontrightvecs i level the 2 velocities(i just put the slower one to the same amount of the higher)...problems i'm having:
the major problem is that when i decelerate using this kind of friction,the 2 velocities are not equal,and they never trully reach 0 in a reasonable amout of time = i need a lot of computations and caps to achieve the right result,so probably i must rewrite my code to be the most framerate independent possible;
for the rest,just applying for example gravity i can use the vertical velocity, and for jump i can simply store the 2 velocities,the direction,the 2 vecs and im ok(i mean the decelerating problem is still there also in the jump cause it's the same xd):
this is simply what i do when i'm accellerating :
if(core_ptr->mov->y_vel < 0.0f)
{
core_ptr->mov->x_vel = (core_ptr->mov->y_vel * -1)* dir_xy[0];
}
else
{
core_ptr->mov->x_vel = core_ptr->mov->y_vel * dir_xy[0];
}
when i decelerate i can't level the 2 velocities,cause if i have for example vel_x 0.0000002, and vel_y -230.034f,the vel_x is not zero and also putting into a cap like if <> 0.0002 or something there is always this behaviour....imagine that i have a completely framerate indipendent system,im moving back(that is my positive y velocity) and right(that is my negative x velocity)....what happens is that for example when i release my buttons (the releasing is not in the same moment,the velocities are different) so i like decelerate in different directions with different velocities and the movement is not uniform : like one of the vel is 0 so after i decelerated in every axis with uniform accell,i start to decelerate only on one axis = glitch
sorry if i harass you but you're my master now xd if you don't want to stress yourself with this and don't want to answer is ok don't worry hugs
 
Hi thank you,i didn't understand initially,but it was really simple i can't believe i'm so stupid,i cleaned up my code a little and abstracted everything to get the exact moment when you press forward and right togheter so from there i did this :

////FRONT
core_ptr->cam->cam_front[2] = 0.0f;
vec3_normalize(core_ptr->cam->cam_front);
front[0] = core_ptr->cam->cam_front[0];
front[1] = core_ptr->cam->cam_front[1];
vec2_scale(delta_y,front,dir_xy[1]*core_ptr->mov->delta_accel);

//////RIGHT
core_ptr->cam->cam_right[2] = 0.0f;
vec3_normalize(core_ptr->cam->cam_right);
right[0] = core_ptr->cam->cam_right[0];
right[1] = core_ptr->cam->cam_right[1];
vec2_scale(delta_x,right,dir_xy[0]*core_ptr->mov->delta_accel);

FLOAT mag_y = sqrtf((delta_y[0] * delta_y[0]) + (delta_y[1] * delta_y[1]));
FLOAT mag_x = sqrtf((delta_x[0] * delta_x[0]) + (delta_x[1] * delta_x[1]));
delta_xy[0] = delta_y[0] + delta_x[0];
delta_xy[1] = delta_y[1] + delta_x[1];
FLOAT mega_mag = sqrtf((delta_xy[0] * delta_xy[0]) + (delta_xy[1] * delta_xy[1]));

delta_xy[0] *= mag_x/mega_mag;
delta_xy[1] *= mag_y/mega_mag;
FLOAT final_mag = sqrtf((delta_xy[0] * delta_xy[0]) + (delta_xy[1] * delta_xy[1]));

printf(" Y = %f\n X = %f\n MEGA_MAG = %f\n FINAL_MAG = %f \n",mag_y,mag_x,mega_mag,final_mag);
core_ptr->cam->cam_pos[0] += delta_xy[0];
core_ptr->cam->cam_pos[1] += delta_xy[1];

EXAMPLE OUTPUT FROM CONSOLE:::

Y = 20.000000
X = 20.000000
MEGA_MAG = 28.284269
FINAL_MAG = 20.000000
Y = 32.000000
X = 32.000000
MEGA_MAG = 45.254833
FINAL_MAG = 31.999998
Y = 20.000000
X = 20.000000
MEGA_MAG = 28.284269
FINAL_MAG = 20.000000

and you were right,now the delta magnitude is equal to the single magnitude of one of the vecs....now i try to add friction and the rest and to apply a single velocity i hope i will be able to do it if not prepare to be stalked again :D <3
Yes, friction adjustment should be applied to the magnitude of the velocity vector (vec2_scale?), not to the x and y components.
 
Top