PDA

View Full Version : Rotation issue



serthy
5th October 2013, 16:18
Hey,

I aligned a model onto the ground and i can't figure out, how to rotate this model on its local axis a specific angle.470
For example how do i rotate the Block 90 on its yaw axis? ( 0 , 90 , 0 )

IzNoGoD
5th October 2013, 16:44
http://en.wikipedia.org/wiki/Rotation_matrix

serthy
5th October 2013, 16:50
I would like to do it without matrices/quaternions, since its CoD2...

I'll update later

serthy
6th October 2013, 13:25
damnit, i tried shitload, but nothing seems to work -.-

http://pastebin.com/cmGuVssn


i wish i had sth like this finished yesterday, but nothing

doYawRotation( alignedAngles , desiredAngles )
{
aF = anglesToForward( ( alignedAngles[0] , desiredAngles[1] , alignedAngles[2] ) );
aR = anglesToRight( ( alignedAngles[0] , desiredAngles[1] , alignedAngles[2] ) );

yaw = desiredAngles[1];
pitch = alignedAngles[0];
roll = alignedAngles[2];

return ( pitch , yaw , roll );
}

serthy
7th October 2013, 19:31
Iznogod helped me via xfire last eve.

we broke it down to this:

angles = vectorToAngles( playerForward - vectorScale( objectUp , vectorDot( objectUp , playerForward ) ) );

since the vector's z-value returned by vectorToAngles() stays always at 0 the alignment is only on the horizontal plane.

is there a way to recompute this missing roll-value?

kung foo man
11th October 2013, 10:11
Just found this old function, don't remember where I initially found it:



orientToNormal( normal )
{
hor_normal = ( normal[ 0 ], normal[ 1 ], 0 );
hor_length = length( hor_normal );

if ( !hor_length )
return( 0, 0, 0 );

hor_dir = vectornormalize( hor_normal );
neg_height = normal[ 2 ] * - 1;
tangent = ( hor_dir[ 0 ] * neg_height, hor_dir[ 1 ] * neg_height, hor_length );
plant_angle = vectortoangles( tangent );

//println("^6hor_normal is ", hor_normal);
//println("^6hor_length is ", hor_length);
//println("^6hor_dir is ", hor_dir);
//println("^6neg_height is ", neg_height);
//println("^6tangent is ", tangent);
//println("^6plant_angle is ", plant_angle);

return plant_angle;
}


Dunno which yaw angle it computes though

serthy
14th October 2013, 22:05
goddamn i still fail on this... i got it to align it on 3 sides, but the fourth is still ... WRONG...

code so far..:

a = vectorToAngles( vectorNormalize( playerForward - vectorScale( tankUp , vectorDot( tankUp , playerForward ) ) ) ); //this projects the playerForward to the tanks x/y-plane
r = vectorToAngles( tankUp - towerUp );
tower rotateTo( ( a[0] , a[1] , r[0] ) , 0.1, 0 , 0 );

i dont get it... lol why only on 3 sides?!

green: tank angles
blue: tower angles
pink: player forward
yellow: projected player forward on tanks xy plane
numbers: r[0]
478

kung foo man
14th October 2013, 22:35
Would like to try it out, but no git repository in sight ;P

serthy
15th October 2013, 08:31
ill release it asap

serthy
15th October 2013, 17:51
480
i call it TANKTRESS ... :cool:
call on map start before any wait statements:

init()
{
level.killtube = true;

if( level.killtube )
{
level.model_body[0] = "xmodel/furniture_bedmattress1";
level.model_tower[0] = "xmodel/prop_barrel_benzin";
level.model_gun[0] = "xmodel/weapon_30cal";
level.model_track[0] = "xmodel/tag_origin";
level.model_track_scroll[0] = "xmodel/tag_origin";
}
else
{
level.model_body[0] = "xmodel/serthy_tank_a_body";
level.model_tower[0] = "xmodel/serthy_tank_a_tower";
level.model_gun[0] = "xmodel/serthy_tank_a_gun";
level.model_track[0] = "xmodel/serthy_tank_a_track";
level.model_track_scroll[0] = "xmodel/serthy_tank_a_track_scroll";
}

precacheModel( level.model_body[0] );
precacheModel( level.model_tower[0] );
precacheModel( level.model_gun[0] );
precacheModel( level.model_track[0] );
precacheModel( level.model_track_scroll[0] );

if( level.killtube )
{
level.model_body[1] = "xmodel/furniture_bedmattress1";
level.model_tower[1] = "xmodel/prop_barrel_benzin";
level.model_gun[1] = "xmodel/weapon_30cal";
level.model_track[1] = "xmodel/tag_origin";
level.model_track_scroll[1] = "xmodel/tag_origin";
}
else
{
level.model_body[1] = "xmodel/serthy_tank_b_body";
level.model_tower[1] = "xmodel/serthy_tank_b_tower";
level.model_gun[1] = "xmodel/serthy_tank_b_gun";
level.model_track[1] = "xmodel/serthy_tank_b_track";
level.model_track_scroll[1] = "xmodel/serthy_tank_b_track_scroll";
}

precacheModel( level.model_body[1] );
precacheModel( level.model_tower[1] );
precacheModel( level.model_gun[1] );
precacheModel( level.model_track[1] );
precacheModel( level.model_track_scroll[1] );

spawns = getEntArray( "mp_tdm_spawn" , "classname" );

for( i = 0 ; isDefined( spawns ) && i < spawns.size && i < 15 ; i++ )
{
level thread spawnTank( spawns[i].origin );
}
}

spawnTank( pos )
{
wait( 1.0 );

tank = spawn( "script_model" , pos + ( 0 , 0 , 0 ) );
tank.body = spawn( "script_model" , pos + ( 0 , 0 , 0 ) );
tank.tower = spawn( "script_model" , pos + ( 0 , 0 , 0 ) );
tank.gun = spawn( "script_model" , pos + ( 60 , 0 , 80 ) );

if( level.killtube )
tank.gun.origin = pos + ( 10 , 0 , 30 );

tank.typeID = randomInt( 2 );

tank setModel( level.model_track[tank.typeID] );
tank.body setModel( level.model_body[tank.typeID] );
tank.tower setModel( level.model_tower[tank.typeID] );
tank.gun setModel( level.model_gun[tank.typeID] );

tank.gun linkTo( tank.tower );

tank.vehicleType = "tank";
tank.targetname = "vehicle";

tank.speed = 0;
tank.maxSpeed = 30;
tank.minSpeed = -10;
tank.gear = 1;
tank.maxHealth = 200;
tank.health = tank.maxHealth;

tank.anglesF = anglesToForward( tank.angles );
tank.anglesR = anglesToRight( tank.angles );
tank.anglesU = anglesToUp( tank.angles );

tank thread tankTriggerLogic();
tank thread tankLogic();
}

tankTriggerLogic()
{
trigger = spawn( "trigger_radius" , self.origin , 0 , 200 , 200 );
trigger enableLinkTo();
trigger linkTo( self );

self.trigger = trigger;

trigger endon( "death" );

while( isDefined( self ) )
{
trigger waittill( "trigger" , player );

if( !isDefined( player ) || !isPlayer( player ) || !isAlive( player ) || !player useButtonPressed() )
continue;
else if( isDefined( player.vehicle ) || isDefined( self.driver ) || isDefined( player.isBot ) )
continue;

self thread attachPlayer( player );
}

trigger unLink();

trigger notify( "death" );

wait( 0.05 );

if( isDefined( trigger ) )
trigger delete();
}

monitorPlayer()
{
self endon( "disconenct" );
self endon( "exitVehicle" );

self waittill( "killed_player" );

assert( isDefined( self.vehicle ) );

self.vehicle detachPlayer( self );
}

attachPlayer( player )
{
player endon( "disconenct" );
player endon( "killed_player" );

if( !isDefined( self.driver ) )
{
self.driver = player;

player setOrigin( self.origin + ( 0 , 0 , 70 ) );
player linkTo( self );
player disableWeapon();
player.vehicle = self;

player hide();
player setModel( "" );

player setClientCvar( "cg_thirdperson" , 1 );
player setClientCvar( "cg_thirdpersonrange" , 200 );
player setClientCvar( "cg_thirdpersonangle" , 0 );

player thread monitorPlayer();
}
else
{
return iPrintLn( "Tank tried to attach player as driver while having a driver!" );
}
}

detachPlayer( player )
{
player endon( "disconenct" );

wait( 0.05 );

player unlink();
player enableWeapon();

player setClientCvar( "cg_thirdperson" , 0 );

//if( isDefined( player.pers["savedmodel"] ) );
// player loadModel( player.pers["savedmodel"] );

player.vehicle = undefined;

self.driver = undefined;

player notify( "exitVehicle" );
}

checkCollission( trace )
{
if( trace["fraction"] == 1 )
return false;

if( isDefined( trace["entity"] ) )
{
if( isPlayer( trace["entity"] ) )
trace["entity"] suicide();

return false;
}

return true;
}

vectorScale( v , s )
{
return ( v[0] * s , v[1] * s , v[2] * s );
}

tankLogic()
{
self endon( "death" );
self endon( "destroyed" );

speedTreshold = 3;
timeStep = 0.1;

for( i = 0 ; true ; i++ )
{
wait( timeStep / 2 );

self.anglesF = anglesToForward( self.angles );
self.anglesR = anglesToRight( self.angles );
self.anglesU = anglesToUp( self.angles );

self.nextAngles = self.angles;

buttonMelee = false;
buttonAttack = false;
buttonUse = false;

pitch = undefined;

desiredDir = self.angles;

if( !isDefined( self.driver ) )
{
if( self.speed != 0 )
{
if( self.speed > 0 )
self.speed -= 1;
else
self.speed += 1;
}
}
else
{
buttonMelee = self.driver meleeButtonPressed();
buttonAttack = self.driver attackButtonPressed();
buttonUse = self.driver useButtonPressed();

if( buttonMelee )
{
if( buttonUse )
{
if( self.speed > 0 )
{
self.speed -= 6;

if( self.speed < 0 )
self.speed = 0;
}
else
self.speed -= 1;
}
else
{
self.speed += 2;
}
}
else
{
if( self.speed * self.gear < speedTreshold )
self.speed = 0;
else
self.speed -= ( self.gear * 1 );
}
}

if( self.speed > self.maxSpeed )
self.speed = self.maxSpeed;
else if( self.speed < self.minSpeed )
self.speed = self.minSpeed;

self.gear = 1;

if( self.speed < 0 )
self.gear = -1;

if( ( self.speed * self.gear >= speedTreshold ) || buttonAttack && i % 2 == 0 )
{
s = vectorScale( self.anglesR , 60 );
f = vectorScale( self.anglesF , 100 + self.speed );
b = vectorScale( self.anglesF , -70 );
h = ( 0 , 0 , 164 );

flt = bulletTrace( self.origin + f - s + h , self.origin + f - s - h , false , self );
frt = bulletTrace( self.origin + f + s + h , self.origin + f + s - h , false , self );
bt = bulletTrace( self.origin + b + h , self.origin + b - h , false , self );

diff = frt["position"] - flt["position"];
nextPos = flt["position"] + vectorScale( diff , 0.5 ) - vectorScale( self.anglesF , 100 );

playerDir = self.driver getPlayerAngles();

if( buttonAttack )
desiredDir = playerDir;

yaw = desiredDir[1] - self.angles[1];

while( yaw < -180 )
yaw += 360;
while( yaw > 180 )
yaw -= 360;

pitch = vectorToAngles( flt["position"] + vectorScale( diff , 0.5 ) - bt["position"] );
yaw = self.angles[1] + ( yaw * 15 / 180 );
roll = vectorToAngles( diff );

if( ( self.speed * self.gear >= speedTreshold ) || buttonAttack )
{
self.nextAngles = ( pitch[0] , yaw , roll[0] );

self rotateTo( self.nextAngles , timeStep , 0 , 0 );
self.body rotateTo( self.nextAngles , timeStep , 0 , 0 );

self moveTo( nextPos + ( 0 , 0 , 1 ) , timeStep , 0 , 0 );
self.tower moveTo( nextPos + ( 0 , 0 , 1 ) , timeStep , 0 , 0 );
self.body moveTo( nextPos + ( 0 , 0 , 1 ) , timeStep , 0 , 0 );

if( self.model != level.model_track_scroll[self.typeID] )
self setModel( level.model_track_scroll[self.typeID] );
}
}
else
{
if( self.model != level.model_track[self.typeID] )
self setModel( level.model_track[self.typeID] );
}

if( isDefined( self.driver ) )
{
pa = self.driver getPlayerAngles();
pu = anglesToUp( pa );
pr = anglesToRight( pa );
pf = anglesToForward( pa );

ta = self.nextAngles;
tu = anglesToUp( ta );
tr = anglesToRight( ta );
tf = anglesToForward( ta );

sa = self.tower.angles;
su = anglesToUp( sa );
sr = anglesToRight( sa );
sf = anglesToForward( sa );

//project playerdir onto tanks xy plane
//a = vectorToAngles( pf - vectorScale( tu , vectorDot( tu , pf ) ) );

d = vectorDot( tu , pf );

a = sf;

if( d < 0.98 && d > -0.98 )
a = vectorNormalize( pf - vectorScale( tu , d ) );

dbgHeight = 64;
dbgLength = 60;

if( level.killtube )
{
dbgHeight = 0;
dbgLength = 30;
}

line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( a , dbgLength ) , ( 1 , 0 , 1 ) );
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( pf , dbgLength ) , ( 1 , 1 , 0 ) );

line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( tu , dbgLength ) , ( 0 , 1 , 0 ) );
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( tf , dbgLength ) , ( 0 , 1 , 0 ) );
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( tr , dbgLength ) , ( 0 , 1 , 0 ) );

//line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( tf , 0 - dbgLength ) , ( 0 , 1 , 0 ) );
//line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( tr , 0 - dbgLength ) , ( 0 , 1 , 0 ) );

line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( su , dbgLength ) , ( 0 , 0 , 1 ) );
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( sf , dbgLength ) , ( 0 , 0 , 1 ) );
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( sr , dbgLength ) , ( 0 , 0 , 1 ) );

//line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( sf , 0 - dbgLength ) , ( 0 , 0 , 1 ) );
//line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( sr , 0 - dbgLength ) , ( 0 , 0 , 1 ) );

r = sa[2];

if( vectorDot( tu , su ) < 0.999 )
{
r = vectorToAngles( vectorNormalize( tu - su ) );
r = r[0];
}

while( r < -180 )
r += 360;
while( r > 180 )
r -= 360;

a = vectorToAngles( a );
a = ( a[0] , a[1] , r );

if( i % 2 == 0 )
self.tower rotateTo( a , timeStep , 0 , 0 );

}
}
}

sign( x )
{
if( x < 0 )
return -1;

return 1;
}

vectorcross(a,b)
{
return ( a[1] * b[2] - b[1] * a[2] , a[2] * b[0] - b[2] * a[0] , a[0] * b[1] - b[0] * a[1] );
}

sqrt( x )
{
y = x;

for( z = x / 4 ; abs( z - y ) >= 0.001 ; y = ( ( z + ( x / z ) ) / 2 ) )
{
z = y;
}

return y;
}

abs( x )
{
if( x < 0 )
x = 0 - x;

return x;
}

aTan2( y,x) {
coeff_1 = 3.14159265359 / 4;
coeff_2 = 3 * coeff_1;
abs_y = abs(y);

if (x >= 0 ) {
r = (x - abs_y) / (x + abs_y);
angle = coeff_1 - coeff_1 * r;
} else {
r = (x + abs_y) / (abs_y - x);
angle = coeff_2 - coeff_1 * r;
}
if(y < 0)
angle *= -1;

return angle;
}


Hold [F] for to drive
Hold [F + Melee] to break/ drive backwards
Hold [Attack] to align the Tanktress to the current direction

serthy
18th October 2013, 21:13
it might be solved using this:


pf = anglesToForward( driver getPlayerAngles() );
tu = anglesToUp( self.angles );
sr = anglesToRight( tower.angles );
a1 = vectorToAngles( pf - vectorScale( tu , vectorDot( tu , pf ) ) );
a2 = vectorToAngles( sr - vectorScale( tu , vectorDot( tu , sr ) ) );

tower rotateTo( ( a1[0] , a1[1] , a2[0] ) , timeStep , 0 , 0 );

serthy
19th October 2013, 15:46
.

►►► http://www.youtube.com/watch?v=UOOqMKkkc8o ◄◄◄

Ni3ls
19th October 2013, 17:19
Fucking awesome!

YuriJurek
19th October 2013, 22:01
Wow, that's amazing ! keep it up! wish you would release it on some server !