Tank movement

Posted By: 3run

Tank movement - 05/10/11 15:42

I need an idea, of how to make tank swing while shooting. It needs to swing depending on turret angle.
I understand that I need to play with tanks tilt and roll, but I don't have any ideas how to make this according to turret pan.
BTW, I use three different models, one for tank's base, one for turret's base and the last one for barrel.
Posted By: Schubido

Re: Tank movement - 05/10/11 15:58

Hi,

I think sin/cos should be a proper approach.
Untested as always ;-)

Code:
(pseudocode)

#define MOVE_UP 1
#define MOVE_DOWN 2

set
state_move = MOVE_UP;
in the fire function

movespeed = ... // appropriate factor for speed of movement
factor = ... // appropriate factor for intensity of movement


if (statemove) {
  tilt = cos(pan)*movepercent*factor;
  roll = sin(pan)*movepercent*factor;  // or -sin(...)??
}

if (statemove == MOVE_UP) {
  movepercent += time_step*movespeed;
  if (movepercent >= 100) state_move = MOVE_DOWN;
}
if (statemove == MOVE_DOWN) {
  movepercent -= time_step*movespeed;
  if (movepercent < 0) {
    statemove = 0;
    movepercent = 0;
    tilt = 0;
    roll = 0;
  }
}


Posted By: muffel

Re: Tank movement - 05/10/11 16:01

you have to know the right formulas to simulate the tank ( or a simpler model ). Then you have to write the code acording to this.
Things you should look for:
center of mass
forces
springs
That is just a rough idea i had. dont know wether it is correct

A simpler method would be:
to get the tilt rotaion axis of the turret according to the tilt angle choose a suiting value x. With this value you rotate the tank body at its mass center arround the horizontal axis of the touret. Additionally you lower the value of x over time so the rotation gets slower and slower. The rotation around this axis shold be clamped to some angles.
Posted By: 3run

Re: Tank movement - 05/10/11 18:10

muffel, I'm not going to make it so realistic grin and I'm not going to use physics, only C_MOVE
Schubido, please, could you explain a bit your script? laugh thank you for it
I've already done movement with shooting. I just need to make some visualizations laugh
Posted By: Schubido

Re: Tank movement - 05/11/11 09:02

Well, I can give it a try, but it might end up in a lot of "if you ..." because I dont know how you are doing movement and rotation yet.

Your question was ...
Quote:

... need to play with tanks tilt and roll, but I don't have any ideas how to make this according to turret pan.


So my guess is that tilt and roll for the tank can be calculated with sin and cos :

// factor = the angle for the swing movement
// should be a small movement, so something between 2° and 5° should be appropriate
tank.tilt = cos(turret.pan)*factor;
tank.roll = sin(turret.pan)*factor;
(btw I mixed up sin and cos in my first post and just corrected this)

So, if turret.pan = 0 then cos = 1 and sin = 0 => only tank.tilt movement,
if turret.pan = 90 then cos = 0 and sin = 1 => only tank.roll movement
if turret.pan = 180 then cos = -1 and sin = 0 => negative tank.tilt movement
...
and for other turret.pan values (e.g. 47°) it's a combination of tilt and roll

The rest of the example was just to make a smooth movement between zero and target angle and backwards.
This movement is not accelerated which should not be a problem because the whole activity should be less then 1 second (guess +0.5 sec would be good) and a quite small movement.

This should have been the easy part. But now the promised "if you ..."

If you already doing rotation (which I guess would be the case), then you need to do the "swing" rotation additionally. If you do rotation via just setting the pan - fine, just set tilt & roll as mentioned before. If you use c_rotate then you have to combine the rotations in you c_rotate call.
If you use c_rotate it also depends if you do the call with USE_AXIS, USE_AXISR or without.

Next ... the rotation could lead to a collision with the terrain. If you use an elliptic hull this might not matter for this small rotation.

Quote:

BTW, I use three different models, one for tank's base, one for turret's base and the last one for barrel.


If these three models fit together without changing the origin coordinates by code then the swing-rotation could be done for all three models the same way.
Depending on the way you are doing rotation currently it might be necessary to calculate the difference between the turret.pan and the tank.pan ...

Now, this "if ..." could be continued endlessly but I guess this would be useless.
So, if you got the idea and its suitable for your needs - fine.
If not, I would recommend to post your movement code here. Otherwise there are too many different ways foreward.



Posted By: 3run

Re: Tank movement - 05/15/11 11:54

OK, here is short example of my script:
Code:
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#define dist_x skill1
#define dist_y skill2
#define dist_z skill3
#define absdist_x skill4
#define absdist_y skill5
#define absdist_z skill6
#define force_x skill7
#define force_y skill8
#define force_z skill9
#define move_spd skill10
#define turn_spd skill11
#define armor skill99 // used for health
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ENTITY* turret;
ENTITY* body;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
function handle_size(ENTITY* ent,X,Y,Z)
{
	ent.scale_x = X;
	ent.scale_y = Y;
	ent.scale_z = Z;
}
function handle_gravity(ENTITY* ent)
{
	VECTOR temp;
	vec_set(temp.x,ent.x);
	temp.z -= 200;
	my.absdist_z = -c_trace(ent.x,temp.x,IGNORE_FLAG2|IGNORE_PASSABLE|USE_POLYGON|USE_BOX) - ent.min_z - 5;
}
function set_camera()
{
	camera.pan += ang(turret.pan - camera.pan) * time_step * 0.8; 
	camera.tilt = -90;
	camera.arc = 70;
	vec_set(camera.x,vector(my.x,my.y,my.z + 500));
}
function set_tank()
{
	VECTOR temp;
	proc_mode = PROC_LATE;
	body = ent_create("body.mdl",my.x,NULL); // body's model
	turret = ent_create("turret.mdl",my.x,NULL); // turret's model
	set(body,FLAG2);
	handle_size(body,1,1,1);
	set(turret,FLAG2);
	handle_size(turret,1,1,1);
	while(1)
	{
		vec_set(body.x,my.x);
		vec_set(body.pan,my.pan);
		body.tilt = 0;
		vec_for_bone(temp,body,"TURRET"); // bone's name
		vec_set(turret.x,temp.x);
		turret.pan -= 0.5 * mickey.x * time_step;
		turret.tilt = 0;
		wait(1);
	}
}
action tank()
{
	player = my;
	set(my,TRANSLUCENT|FLAG2);
	my.alpha = 5;
	handle_size(my,1,1,1);
	my.armor = 200; // health 
	my.move_spd = 10; 
	my.turn_spd = 10;
	set_tank(); // create tank parts
	while(my.armor > 0)
	{
		my.force_x = my.move_spd * (key_w - 0.8 * key_s) * time_step;
		accelerate(my.dist_x,my.force_x,0.8);
		my.force_y = 0; 
		my.force_z = 0;
		my.dist_y = 0;
		my.dist_z = 0;
		handle_gravity(my); // apply gravity
		my.pan += my.turn_spd * (key_a - key_d) * time_step;
		c_move(my,my.dist_x,my.absdist_x,IGNORE_PASSABLE|IGNORE_FLAG2|USE_POLYGON|GLIDE);
		set_camera(); // set camera position
		wait(1);
	}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


Posted By: Schubido

Re: Tank movement - 05/15/11 20:57

You could give this a try (untested)

Code:
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#define dist_x skill1
#define dist_y skill2
#define dist_z skill3
#define absdist_x skill4
#define absdist_y skill5
#define absdist_z skill6
#define force_x skill7
#define force_y skill8
#define force_z skill9
#define move_spd skill10
#define turn_spd skill11
#define armor skill99 // used for health
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ENTITY* turret;
ENTITY* body;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
function handle_size(ENTITY* ent,X,Y,Z)
{
	ent.scale_x = X;
	ent.scale_y = Y;
	ent.scale_z = Z;
}
function handle_gravity(ENTITY* ent)
{
	VECTOR temp;
	vec_set(temp.x,ent.x);
	temp.z -= 200;
	my.absdist_z = -c_trace(ent.x,temp.x,IGNORE_FLAG2|IGNORE_PASSABLE|USE_POLYGON|USE_BOX) - ent.min_z - 5;
}
function set_camera()
{
	camera.pan += ang(turret.pan - camera.pan) * time_step * 0.8; 
	camera.tilt = -90;
	camera.arc = 70;
	vec_set(camera.x,vector(my.x,my.y,my.z + 500));
}
function set_tank()
{
	VECTOR temp;
	proc_mode = PROC_LATE;
	body = ent_create("body.mdl",my.x,NULL); // body's model
	turret = ent_create("turret.mdl",my.x,NULL); // turret's model
	set(body,FLAG2);
	handle_size(body,1,1,1);
	set(turret,FLAG2);
	handle_size(turret,1,1,1);
	while(1)
	{
		vec_set(body.x,my.x);
////////////////////////////////////
//		vec_set(body.pan,my.pan);
////////////////////////////////////
		body.pan = my.pan;
////////////////////////////////////
//		body.tilt = 0;
////////////////////////////////////
		vec_for_bone(temp,body,"TURRET"); // bone's name
		vec_set(turret.x,temp.x);
		turret.pan -= 0.5 * mickey.x * time_step;
////////////////////////////////////
//		turret.tilt = 0;
////////////////////////////////////
		wait(1);
	}
}

////////////////////////////////////
#define SWING_UP 1
#define SWING_DOWN 2
#define SWING_ANGLE 5			// 5°
#define SWING_SPEED 0.12		// ~0.5 seconds (0.25 up + 0.25 down)
#define SwingPan skill30
#define SwingPercent skill31  // 0..1
int state_swing = 0;
////////////////////////////////////

action tank()
{
////////////////////////////////////
	var tilt, roll;
////////////////////////////////////
	
	player = my;
	set(my,TRANSLUCENT|FLAG2);
	my.alpha = 5;
	handle_size(my,1,1,1);
	my.armor = 200; // health 
	my.move_spd = 10; 
	my.turn_spd = 10;
	set_tank(); // create tank parts
	while(my.armor > 0)
	{
		my.force_x = my.move_spd * (key_w - 0.8 * key_s) * time_step;
		accelerate(my.dist_x,my.force_x,0.8);
		my.force_y = 0; 
		my.force_z = 0;
		my.dist_y = 0;
		my.dist_z = 0;
		handle_gravity(my); // apply gravity
		my.pan += my.turn_spd * (key_a - key_d) * time_step;
		c_move(my,my.dist_x,my.absdist_x,IGNORE_PASSABLE|IGNORE_FLAG2|USE_POLYGON|GLIDE);
		set_camera(); // set camera position

////////////////////////////////////		
		if (key_space) {		// fire
			my.SwingPan = turret.pan;
			state_swing = SWING_UP;
		}
		
		if (state_swing) {
			if (state_swing == SWING_UP) {
				my.SwingPercent += time_step * SWING_SPEED;
				if (my.SwingPercent >= 1) state_swing = SWING_DOWN;
			} else {
				my.SwingPercent -= time_step * SWING_SPEED;
				if (my.SwingPercent <= 0) state_swing = 0;
			}
			if (state_swing) {
  				tilt = cos(my.SwingPan)*my.SwingPercent*SWING_ANGLE;
  				roll = sin(my.SwingPan)*my.SwingPercent*SWING_ANGLE;  // or -sin(...)??
  				my.tilt = tilt;
  				my.roll = roll;
  				turret.tilt = tilt;
  				turret.roll = roll;
  				body.tilt = tilt;
  				body.roll = roll; 
  			} else {
  				my.tilt = 0;
  				my.roll = 0;
  				turret.tilt = 0;
  				turret.roll = 0;
  				body.tilt = 0;
  				body.roll = 0; 
			}
		}
////////////////////////////////////
		
		wait(1);
	}
}


© 2024 lite-C Forums