point to target slowly

Posted By: MMike

point to target slowly - 05/02/08 00:18

Ok i have a spaceship, and i want to click go there.
The thing is that ordinary script will face the target instantanely, and its not real.
It should acellerate and then rotate slowly , while moving, and then end on the target point.

Of course spaceship doesn't do the PAn movement, they will roll and till, the roll and till together give the movement, of course i can fake it, but well thats other thing.

Right now i can work with pan so be simpler.

So anyidea? how to do the smotth movement?
i have

vec_set(temp,p1.x); // p1 = target
vec_set(my_angle,p1.x); // my angle , calculate angle
vec_sub(temp,my_angle);
vec_to_angle(my_angle,temp); // now my angle has the pointing target angle

// AT THIS PART i can't directly set my angles to that target, it must be slowly added till it reaches the right angle, though, if spaceship is acelleratin, and rotating slowly, it will get a different toward target angle.. that must be calculated again, see where i get?
//var myspeed is from 0 to 2 maximum, and has inertia already.
c_move(me,vector(-myspeed,0,0),nullvector,GLIDE); // speed up



c_rotate(me,vector(my_angle.x,my_angle.tilt,my_angle.roll),USE_AXIS|GLIDE);
Posted By: tompo

Re: point to target slowly - 05/02/08 04:23

try something like this:

 Code:
var my_angle[3];
var my_target[3];
define _speed,skill1; //turning's speed

function actor_turnto(angle)
{
	angle = ang(angle - MY.PAN);
	if (angle > 10) {temp = my._speed;}
	else{
		if(angle < -10){temp = -my._speed;}
		else{temp = my._speed * angle *0.1;}
		}
	MY.PAN += temp * time_step *2;
}

//in ship's action in while loop add
vec_diff(temp,my_target,my.pos);
result = vec_to_angle(my_angle,temp);
actor_turnto(my_angle.PAN);


 Quote:
c_move(me,vector(-myspeed,0,0),nullvector,GLIDE); // speed up

why your ship going in wrong direction, not forward?
Posted By: MMike

Re: point to target slowly - 05/02/08 12:05

Im not sure yet, why i did that, but, it seeams that when i get the angle to the target, my ship flip and then it would move backwards, lol. So i guess i modeled my model wrong, and i just did that small correction for testing.

About your code, changing the pan , will rotate it correctly? i mean, the x pos will pointing for the new pan or relative? thats why i use c_rotate.
Posted By: MMike

Re: point to target slowly - 05/02/08 14:16

while(1){
vec_diff(temp,p1.x,my.x); // get target(p1) and my angle
result = vec_to_angle(my_angle,temp);
rotate_speed = 0.5; // this will simulate a bit of inertia

if(my.pan<my_angle.pan){c_rotate(me,vector(rotate_speed,0,0),USE_AXIS|GLIDE);}
if(my.pan>my_angle.pan){c_rotate(me,vector(-rotate_speed,0,0),USE_AXIS|GLIDE);}
if(my.tilt<my_angle.tilt){c_rotate(me,vector(0,rotate_speed,0),USE_AXIS|GLIDE);}
if(my.tilt>my_angle.tilt){c_rotate(me,vector(0,-rotate_speed,0),USE_AXIS|GLIDE);}
if(my.roll<my_angle.roll){c_rotate(me,vector(0,0,rotate_speed),USE_AXIS|GLIDE);}
if(my.roll>my_angle.roll){c_rotate(me,vector(0,0,-rotate_speed),USE_AXIS|GLIDE);}


it works well, but.. sometimes it will go in a weird way, if angle becomes negative or positive..
i know that if angle is > 360 i can consider it 0 º but if <360 it can be 0 º too this will confuse the math here, i guess..

So i don't know if i should use relative or absolute rotation.. and if have to say pan%=360 or not :S


Posted By: MMike

Re: point to target slowly - 05/05/08 21:42

Tompo can you explain your script. :S it does not use c_rotate, and i need collision .
Posted By: sydan

Re: point to target slowly - 05/06/08 20:04

I have this proble mas well its a huge draw back and Im sorry to say that I haven't managed to find a solution yet either. My method works byt checking to see if the target angle is bigger or smaller that the current angle and then turning according;y but this doesn't work over the 0 - 360 boundary! So I'm stuck too. Are there any crazy experts who have a fool proof answer to what seems like a global question?
Posted By: MMike

Re: point to target slowly - 05/06/08 21:09

yes my problem is that my pan sometimes get like this..

0.. 180.. -180.. 0 thats the range, so i have to convert..
if angle<0 add 360.. Ok now i have 0.. to 360 range degree..

Now, im in the 4th day that i work hard in many solution, but all them have some kind of fail point.

So im checking angle for all the 4^4 possibilities..
4 quadrants, and the 4 interactions between them.

i can post my code if it work.
But this is really a math big exercice.
Posted By: MMike

Re: [DONE-SUB]point to target slowly - 05/07/08 14:26

Ok i finally got this to work after somedays of testing and working hard.

To get a point to target that is really optimized to turn the shortest angle between my angle and target angle, i had to break the angles in quadrants, and study all possibilites and write a formula for them.
//quadrant here means...Quartenion!!
 Code:
var my_q; //my angle quadrant or quartenion
var target_q; //target quadrant
var comp; // complementar angle to best short angle calculations
var d_sign; //rotate direction
var d_count; // how much we need to rotate to get to the target

function turn_target {
  var ang_temp[3];
  vec_diff(ang_temp,p1.x,my.x);  
  vec_to_angle(my_angle.pan,ang_temp); turn my_angle vector
  if(my_angle.pan<0){my_angle.pan+=360;} //convert angle to 360 range if needed
  
/// HERE i assign the target quadrant
if(my_angle.pan<=360 && my_angle.pan>270){target_q=4;}
if(my_angle.pan<=270 && my_angle.pan>180){target_q=3;}
if(my_angle.pan<=180 && my_angle.pan>90){target_q=2;}
if(my_angle.pan<=90 && my_angle.pan>=0){target_q=1;}

//Here i'll assign in which my angle quadrant is
if(my.pan<=360 && my.pan>270){my_q=4;}
if(my.pan<=270 && my.pan>180){my_q=3;}
if(my.pan<=180 && my.pan>90){my_q=2;}
if(my.pan<=90 && my.pan>=0){my_q=1;}

// Here i set the complement angle constrain to 360 range
comp%=360;
comp=my_angle.pan+180; // complement angle = my angle + 180 

// if my angle is within the target (+/-2) no need to calculate , otherwise calculate:
if(!(my.pan<(my_angle+2) && my.pan>(my_angle-2)) ){
//if the target quadrant is different from the my angle quadrant
if(target_q!=my_q){
// Now calculate all the quadrant interactions and possibilites.
//adjacents quadrant - simple - done
if(target_q==1 && my_q==2){d_sign=-1;d_count=my.pan-my_angle.pan;}else{if(my_q==1 && target_q==2){d_sign=1;d_count=my_angle.pan-my.pan;}}
if(target_q==2 && my_q==3){d_sign=-1;d_count=my.pan-my_angle.pan;}else{if(my_q==2 && target_q==3){d_sign=1;d_count=my_angle.pan-my.pan;}}
if(target_q==3 && my_q==4){d_sign=-1;d_count=my.pan-my_angle.pan;}else{if(my_q==3 && target_q==4){d_sign=1;d_count=my_angle.pan-my.pan;}}
if(target_q==4 && my_q==1){d_sign=-1;d_count=360-(my_angle.pan-my.pan);}else{if(my_q==4 && target_q==1){d_sign=1;d_count=360-(my.pan-my_angle.pan);}}


if(target_q==2 && my_q==4){
if(my.pan<comp){d_sign=-1;d_count=my.pan-my_angle.pan;   } //manual complement -done 
if(my.pan>comp){d_sign=1;d_count=360-(my.pan-my_angle.pan); } //manual complement - done
}else
{if(my_q==2 && target_q==4){
if(my.pan<comp){d_sign=-1; d_count=360-(my_angle.pan-my.pan); } //manual complement - done
if(my.pan>comp){d_sign=1; d_count=my_angle.pan-my.pan; } //manual complement - done
}}

if(target_q==3 && my_q==1){
if(my.pan<comp){d_sign=-1; d_count=360-(my_angle.pan-my.pan); } //manual complement - done
if(my.pan>comp){d_sign=1; d_count=my_angle.pan-my.pan; } //manual complement - done
}else
{if(my_q==3 && target_q==1){
if(my.pan<comp){d_sign=-1; d_count=my.pan-my_angle.pan; } //manual complement - done
if(my.pan>comp){d_sign=1; d_count=360-(my.pan-my_angle.pan); } //manual complement -done
}}

}else{if(my.pan>my_angle.pan){d_count=my.pan-my_angle.pan; d_sign=-1;}else{d_sign=1; d_count=my_angle.pan-my.pan;}}
}

 
// D_Count stores how much we still need to rotate, for the shortest angle
if(d_count>0){ 

// Now rotate the my pan, to that angle...
if(d_sign==1){c_rotate(me,vector(rotate_speed,0,0),USE_AXIS|GLIDE);}
if(d_sign==-1){c_rotate(me,vector(-rotate_speed,0,0),USE_AXIS|GLIDE);}
d_count-=rotate_speed;
if(my.pan<0){my.pan+=360;} //convert angle to 360 range here, due to c_rotate mutation ( c_rotate tranform my pan in a -180: 180 range and not 0..360
}else{d_count=0;}
}



Thats all... Hope i helped.. this toooke alot of work.. believe
Posted By: sydan

Re: [DONE-SUB]point to target slowly - 05/07/08 16:44

Woaw okay I see if it works with me. Thanks for the code! I bet it to alot by the looks of the calcualtions!!!
Posted By: MMike

Re: [DONE-SUB]point to target slowly - 05/07/08 16:47

this is just for pan yet!

Oh and the p1.x is the pointer to the point..
I used
entity* p1;

and then assign the target the p1=me command.
Posted By: testDummy

Re: [DONE-SUB]point to target slowly - 05/07/08 19:25

see: ang function in manual?
see: quaternions contribution thread (Lite-C)?
 Code:
/************************************
vfPan2
	ex-dump
	_vSrc: src pos (my.x)
	_vDest: dest pos (your.x, player.x, etc.)
	_3Step: 
		[_iPAN] = entity pan
		[_iSTEP] = turn step (multiplied by time)
	_vTmp: a temp vector 

	use:
		my.pan += vfPan2(my.x, player.x, vector(my.pan, 3.15, 0), temp);
			or
		temp.pan = vfPan2(my.x, player.x, vector(my.pan, 3.15, 0), temp);
		temp.tilt = 0; temp.roll = 0;
		c_rotate(me,temp,ignore_passable + ignore_passents + ignore_me + glide);
*************************************/
function vfPan2(&_vSrc ,&_vDest, &_3Step, &_vTmp) {
	//vec_set(_vTmp, nullvector);
	vec_diff(_vTmp, _vDest, _vSrc);
	vec_to_angle(_vTmp, _vTmp);
	_vTmp[0] = ang(_vTmp[0] - _3Step[iPAN]);
	_vTmp[1] = abs(_vTmp[0]);
	//if (_vTmp[1] < 0.10) {
		//return(_vTmp[0]);
	//}
	_vTmp[2] = ang(min(_vTmp[1], time * _3Step[iSTEP]) * sign(_vTmp[0]));
	return(_vTmp[2]);
}

Posted By: MMike

Re: [DONE-SUB]point to target slowly - 05/07/08 19:38

i don't understand c-lite too much. :S just some command i recognize.. but what that command does?
Posted By: testDummy

Re: [DONE-SUB]point to target slowly - 05/07/08 22:08

clarification, or worse:
The posted code, which might not work at all, but did seem to for something, is not Lite-C. It is C-Script, for rotating an entity toward a point, gradually, with no overshoot, but only for pan, ...or maybe it's alphabet soup instead.
(Function vf (vector function) Pan2 (pan to) is supposed to be similar to the above function actor_turnto?)

quoting manual for function ang (should be a command for C-Script and Lite-C):
 Quote:

ang(x)
Shifts the angle x into the -180 .. +180 range by adding or subtracting a multiple of 360 degrees. Often useful for calculating angle differences.
Returns:
Same angle, shifted into the -180 .. +180 range.


A thread in category Lite-C contributions is referred to for Lite-C and quaternions.
Perhaps there was a misunderstanding here, and the information offered is irrelevant.
'My' knowledge on many topics is very limited.

Posted By: MMike

Re: [DONE-SUB]point to target slowly - 05/07/08 22:55

I apreciate your code help, now about the ang(x) im confused..

the ang(x) didn't worked for me, because when the angle is for example 351.. it will return -45 .. and i just want positive number so i have to do:
if(angle<0){angle+=360;}

i will check if your code works
Posted By: mpdeveloper_B

Re: [DONE-SUB]point to target slowly - 05/23/08 23:11

i should have posted this before, but i suppose this can help you:
Code:
FUNCTION rotate_entity_(rotate_angle,rotate_speed)
{
	IF (my.pan == rotate_angle) { return; }
	result = ang(rotate_angle - my.pan);
	IF (result > 0) { my.pan += rotate_speed * time_step; }
	IF (result < 0) { my.pan -= rotate_speed * time_step; }
	IF (ang(rotate_angle - my.pan) < 0 && result > 0) { my.pan = rotate_angle; }
	IF (ang(rotate_angle - my.pan) > 0 && result < 0) { my.pan = rotate_angle; }
}

this is how you would use it:
Code:
vec_set (temp, you.x);
vec_sub (temp, my.x);
vec_to_angle (temp_pan, temp);
rotate_entity_(temp_pan,turn_speed_);
///if you want to keep tilt at 0, just add "my.tilt = 0;" right here


if you'd prefer to use c_rotate, then use this one:

Code:
FUNCTION rotate_entity_(rotate_angle,rotate_speed)
{
	var r;
	IF (my.pan == rotate_angle) { return; }
	r = ang(rotate_angle - my.pan);
	IF (r > 0) { c_rotate(me, vector(rotate_speed*time_step,0,0), ignore_passable); }
	IF (r < 0) { c_rotate(me, vector(-rotate_speed*time_step,0,0), ignore_passable); }
	IF (ang(rotate_angle - my.pan) < 0 && r > 0) { my.pan = rotate_angle; }
	IF (ang(rotate_angle - my.pan) > 0 && r < 0) { my.pan = rotate_angle; }
}

© 2023 lite-C Forums