From 6ffe91a1e0dcb29f1351a11e01b6b8a70599a73f Mon Sep 17 00:00:00 2001 From: div0 Date: Thu, 5 Feb 2009 11:35:49 +0000 Subject: [PATCH] refactoring of portal transforms code to be generally usable; use it to make the grenade smoke come out of the red thing on the grenade model git-svn-id: svn://svn.icculus.org/nexuiz/trunk@5754 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/client/projectile.qc | 67 ++++++++++++++------ data/qcsrc/common/util.qc | 50 +++++++++++++++ data/qcsrc/common/util.qh | 8 +++ data/qcsrc/server/portals.qc | 105 +++----------------------------- data/qcsrc/server/w_seeker.qc | 14 ++--- 5 files changed, 125 insertions(+), 119 deletions(-) diff --git a/data/qcsrc/client/projectile.qc b/data/qcsrc/client/projectile.qc index c465a898b..3e75e0443 100644 --- a/data/qcsrc/client/projectile.qc +++ b/data/qcsrc/client/projectile.qc @@ -1,3 +1,6 @@ +.float spawntime; +.vector trail_oldorigin; + void SUB_Null() { } @@ -13,8 +16,11 @@ void SUB_Stop() .float gravity; .float snd_looping; -void Projectile_DrawTrail(vector from, vector to) +void Projectile_DrawTrail(vector to) { + vector from; + from = self.trail_oldorigin; + self.trail_oldorigin = to; switch(self.cnt) { case PROJECTILE_ROCKET: @@ -61,35 +67,57 @@ void Projectile_DrawTrail(vector from, vector to) void Projectile_Draw() { - vector oldorg; - - oldorg = self.origin; + vector rot; + vector trailorigin; if(self.count & 0x80) { //self.move_flags &~= FL_ONGROUND; Movetype_Physics(TRUE); - self.angles = vectoangles(self.velocity); + if(!(self.move_flags & FL_ONGROUND)) + self.angles = vectoangles(self.velocity); } else { InterpolateOrigin_Do(); } - Projectile_DrawTrail(oldorg, self.origin); + if(!(self.move_flags & FL_ONGROUND)) + { + rot = '0 0 0'; + switch(self.cnt) + { + case PROJECTILE_GRENADE: + rot = '-750 0 0'; + break; + case PROJECTILE_GRENADE_BOUNCING: + rot = '0 -750 0'; + break; + case PROJECTILE_HOOKBOMB: + rot = '0 1000 0'; + break; + default: + break; + } + self.angles = AnglesTransform_Multiply(self.angles, rot * (time - self.spawntime)); + + fixedmakevectors(self.angles); + + trailorigin = self.origin; + switch(self.cnt) + { + case PROJECTILE_GRENADE: + case PROJECTILE_GRENADE_BOUNCING: + trailorigin += v_right * 1 + v_forward * -10; + break; + default: + break; + } + Projectile_DrawTrail(trailorigin); + } switch(self.cnt) { - case PROJECTILE_GRENADE: - self.angles -= '750 0 0' * time; - break; - case PROJECTILE_GRENADE_BOUNCING: - if(!(self.move_flags & FL_ONGROUND)) - self.angles += '100 150 100' * time; - break; - case PROJECTILE_HOOKBOMB: - self.angles = '0 500 0' * time; - break; case PROJECTILE_BULLET_GLOWING: R_AddDynamicLight(self.origin, 50, '1 1 0'); break; @@ -120,7 +148,7 @@ void Ent_RemoveProjectile() if(self.count & 0x80) { tracebox(self.origin, self.mins, self.maxs, self.origin + self.velocity * 0.05, MOVE_NORMAL, self); - Projectile_DrawTrail(self.origin, trace_endpos); + Projectile_DrawTrail(trace_endpos); } } @@ -153,7 +181,10 @@ void Ent_Projectile() // sv_gameplayfix_delayprojectiles if(!self.move_time) + { self.move_time = time + ticrate; + self.spawntime = time + ticrate; + } else self.move_time = max(self.move_time, time); @@ -175,6 +206,8 @@ void Ent_Projectile() self.move_origin = self.origin; self.move_velocity = self.velocity; } + + self.trail_oldorigin = self.origin; } if(f & 2) diff --git a/data/qcsrc/common/util.qc b/data/qcsrc/common/util.qc index c32e7a001..cfc2b6c3e 100644 --- a/data/qcsrc/common/util.qc +++ b/data/qcsrc/common/util.qc @@ -1307,3 +1307,53 @@ float boxesoverlap(vector m1, vector m2, vector m3, vector m4) {return m2_x >= m // requires the same, but is a stronger condition float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) {return smins_x >= bmins_x && smaxs_x <= bmaxs_x && smins_y >= bmins_y && smaxs_y <= bmaxs_y && smins_z >= bmins_z && smaxs_z <= bmaxs_z;}; + +#ifndef MENUQC +// angles transforms +// angles in fixedmakevectors/fixedvectoangles space +vector AnglesTransform_Apply(vector transform, vector v) +{ + fixedmakevectors(transform); + return v_forward * v_x + + v_right * (-v_y) + + v_up * v_z; +} + +vector AnglesTransform_Multiply(vector t1, vector t2) +{ + vector m_forward, m_up; + fixedmakevectors(t2); m_forward = v_forward; m_up = v_up; + m_forward = AnglesTransform_Apply(t1, m_forward); m_up = AnglesTransform_Apply(t1, m_up); + return fixedvectoangles2(m_forward, m_up); +} + +vector AnglesTransform_Invert(vector transform) +{ + vector i_forward, i_up; + fixedmakevectors(transform); + // we want angles that turn v_forward into '1 0 0', v_right into '0 1 0' and v_up into '0 0 1' + // but these are orthogonal unit vectors! + // so to invert, we can simply fixedvectoangles the TRANSPOSED matrix + // TODO is this always -transform? + i_forward_x = v_forward_x; + i_forward_y = -v_right_x; + i_forward_z = v_up_x; + i_up_x = v_forward_z; + i_up_y = -v_right_z; + i_up_z = v_up_z; + return fixedvectoangles2(i_forward, i_up); +} + +vector AnglesTransform_TurnDirection(vector transform) +{ + // turn 180 degrees around v_up + // changes in-direction to out-direction + fixedmakevectors(transform); + return fixedvectoangles2(-1 * v_forward, 1 * v_up); +} + +vector AnglesTransform_Divide(vector to_transform, vector from_transform) +{ + return AnglesTransform_Multiply(to_transform, AnglesTransform_Invert(from_transform)); +} +#endif diff --git a/data/qcsrc/common/util.qh b/data/qcsrc/common/util.qh index f420156ec..384db5868 100644 --- a/data/qcsrc/common/util.qh +++ b/data/qcsrc/common/util.qh @@ -135,3 +135,11 @@ string rgb_to_hexcolor(vector rgb); float boxesoverlap(vector m1, vector m2, vector m3, vector m4); float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs); + +#ifndef MENUQC +vector AnglesTransform_Apply(vector transform, vector v); +vector AnglesTransform_Multiply(vector t1, vector t2); +vector AnglesTransform_Invert(vector transform); +vector AnglesTransform_TurnDirection(vector transform); +vector AnglesTransform_Divide(vector to_transform, vector from_transform); +#endif diff --git a/data/qcsrc/server/portals.qc b/data/qcsrc/server/portals.qc index ecb217f7a..df94ada0e 100644 --- a/data/qcsrc/server/portals.qc +++ b/data/qcsrc/server/portals.qc @@ -6,63 +6,6 @@ .float portal_wants_to_vanish; .float portal_activatetime; -vector Portal_Transform_Apply(vector transform, vector v) -{ - fixedmakevectors(transform); - return v_forward * v_x - + v_right * (-v_y) - + v_up * v_z; -} - -vector Portal_Transform_Multiply(vector t1, vector t2) -{ - vector m_forward, m_up; - fixedmakevectors(t2); m_forward = v_forward; m_up = v_up; - m_forward = Portal_Transform_Apply(t1, m_forward); m_up = Portal_Transform_Apply(t1, m_up); - return fixedvectoangles2(m_forward, m_up); -} - -vector Portal_Transform_Invert(vector transform) -{ - vector i_forward, i_up; - fixedmakevectors(transform); - // we want angles that turn v_forward into '1 0 0', v_right into '0 1 0' and v_up into '0 0 1' - // but these are orthogonal unit vectors! - // so to invert, we can simply fixedvectoangles the TRANSPOSED matrix - // TODO is this always -transform? - i_forward_x = v_forward_x; - i_forward_y = -v_right_x; - i_forward_z = v_up_x; - i_up_x = v_forward_z; - i_up_y = -v_right_z; - i_up_z = v_up_z; -#ifdef DEBUG - vector v; - v = fixedvectoangles2(i_forward, i_up); - print("Transform: ", vtos(transform), "\n"); - print("Inverted: ", vtos(v), "\n"); - print("Verify: ", vtos(Portal_Transform_Multiply(v, transform)), "\n"); - fixedmakevectors(Portal_Transform_Multiply(v, transform)); - print("Verify: ", vtos(v_forward), "\n"); - print("Verify: ", vtos(v_right), "\n"); - print("Verify: ", vtos(v_up), "\n"); -#endif - return fixedvectoangles2(i_forward, i_up); -} - -vector Portal_Transform_TurnDirection(vector transform) -{ - // turn 180 degrees around v_up - // changes in-direction to out-direction - fixedmakevectors(transform); - return fixedvectoangles2(-1 * v_forward, 1 * v_up); -} - -vector Portal_Transform_Divide(vector to_transform, vector from_transform) -{ - return Portal_Transform_Multiply(to_transform, Portal_Transform_Invert(from_transform)); -} - float PlayerEdgeDistance(entity p, vector v) { vector vbest; @@ -94,8 +37,8 @@ float Portal_TeleportPlayer(entity teleporter, entity player) transform = teleporter.portal_transform; to = teleporter.enemy.origin; - to = to + Portal_Transform_Apply(teleporter.portal_transform, player.origin - from); - newvel = Portal_Transform_Apply(transform, player.velocity); + to = to + AnglesTransform_Apply(teleporter.portal_transform, player.origin - from); + newvel = AnglesTransform_Apply(transform, player.velocity); // this now is INSIDE the plane... can't use that // shift it out @@ -144,13 +87,13 @@ float Portal_TeleportPlayer(entity teleporter, entity player) ang = player.v_angle; /* ang_x = bound(-89, mod(-ang_x + 180, 360) - 180, 89); - ang = Portal_Transform_Multiply(transform, ang); + ang = AnglesTransform_Multiply(transform, ang); */ // PLAYERS use different math ang_x = -ang_x; - //print("reference: ", vtos(Portal_Transform_Multiply(transform, ang)), "\n"); + //print("reference: ", vtos(AnglesTransform_Multiply(transform, ang)), "\n"); fixedmakevectors(ang); old_forward = v_forward; @@ -159,9 +102,9 @@ float Portal_TeleportPlayer(entity teleporter, entity player) old_yawforward = v_forward; // their aiming directions are portalled... - new_forward = Portal_Transform_Apply(transform, old_forward); - new_up = Portal_Transform_Apply(transform, old_up); - new_yawforward = Portal_Transform_Apply(transform, old_yawforward); + new_forward = AnglesTransform_Apply(transform, old_forward); + new_up = AnglesTransform_Apply(transform, old_up); + new_yawforward = AnglesTransform_Apply(transform, old_yawforward); // but now find a new sense of direction // this is NOT easy! @@ -193,11 +136,11 @@ float Portal_TeleportPlayer(entity teleporter, entity player) else { ang = player.angles; - ang = Portal_Transform_Multiply(transform, player.angles); + ang = AnglesTransform_Multiply(transform, player.angles); } // factor -1 allows chaining portals, but may be weird - player.right_vector = -1 * Portal_Transform_Apply(transform, player.right_vector); + player.right_vector = -1 * AnglesTransform_Apply(transform, player.right_vector); if(player.flagcarried) DropFlag(player.flagcarried, player, world); @@ -383,35 +326,7 @@ void Portal_Disconnect(entity teleporter, entity destination) void Portal_Connect(entity teleporter, entity destination) { - teleporter.portal_transform = Portal_Transform_Divide(Portal_Transform_TurnDirection(destination.angles), teleporter.angles); - -#ifdef DEBUG - { - // let's verify the transform - vector in_f, in_r, in_u; - vector out_f, out_r, out_u; - fixedmakevectors(teleporter.angles); - in_f = v_forward; - in_r = v_right; - in_u = v_up; - print("teleporter: ", vtos(in_f), " ", vtos(in_r), " ", vtos(in_u), "\n"); - fixedmakevectors(destination.angles); - out_f = v_forward; - out_r = v_right; - out_u = v_up; - print("dest: ", vtos(out_f), " ", vtos(out_r), " ", vtos(out_u), "\n"); - // INTENDED TRANSFORM: - // in_f -> -out_f - // in_r -> -out_r - // in_u -> +out_u - print("FORWARD: ", vtos(in_f), " -> ", vtos(Portal_Transform_Apply(teleporter.portal_transform, in_f)), ", should be", vtos(-1 * out_f), "\n"); - print("RIGHT: ", vtos(in_r), " -> ", vtos(Portal_Transform_Apply(teleporter.portal_transform, in_r)), ", should be", vtos(-1 * out_r), "\n"); - print("UP: ", vtos(in_u), " -> ", vtos(Portal_Transform_Apply(teleporter.portal_transform, in_u)), ", should be", vtos(out_u), "\n"); - - te_lightning3(world, teleporter.origin, teleporter.origin + in_r * 1000); - te_lightning3(world, destination.origin, destination.origin + out_r * 1000); - } -#endif + teleporter.portal_transform = AnglesTransform_Divide(AnglesTransform_TurnDirection(destination.angles), teleporter.angles); teleporter.enemy = destination; destination.enemy = teleporter; diff --git a/data/qcsrc/server/w_seeker.qc b/data/qcsrc/server/w_seeker.qc index afe5214cb..2e2349475 100644 --- a/data/qcsrc/server/w_seeker.qc +++ b/data/qcsrc/server/w_seeker.qc @@ -247,13 +247,6 @@ void Seeker_Vollycontroler_Think() self = oldself; } -void Seeker_Tag_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) -{ - self.health = self.health - damage; - if (self.health <= 0) - self.think (); -} - void Seeker_Tag_Explode () { //if(other==self.owner) @@ -263,6 +256,13 @@ void Seeker_Tag_Explode () remove (self); } +void Seeker_Tag_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) +{ + self.health = self.health - damage; + if (self.health <= 0) + Seeker_Tag_Explode(); +} + void Seeker_Tag_Think() { remove(self); -- 2.39.2