]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into mirceakitsune/func_train_beizer_curve
authorRudolf Polzer <divverent@xonotic.org>
Thu, 24 May 2012 08:41:01 +0000 (10:41 +0200)
committerRudolf Polzer <divverent@xonotic.org>
Thu, 24 May 2012 08:41:01 +0000 (10:41 +0200)
1  2 
qcsrc/server/g_subs.qc

diff --combined qcsrc/server/g_subs.qc
index 1676e3cb1cab94f9c15b2a180575f40ea562b90d,df63a70bb85d4f01578823b1b4ea3ceaba48f8ce..464312b8da89e44be372c02b3b5de9286c091508
@@@ -2,6 -2,7 +2,6 @@@ void SUB_Null() {
  float SUB_True() { return 1; }
  float SUB_False() { return 0; }
  
 -void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove;
  void()  SUB_CalcMoveDone;
  void() SUB_CalcAngleMoveDone;
  //void() SUB_UseTargets;
@@@ -170,7 -171,6 +170,7 @@@ void SUB_CalcMoveDone (void
                self.think1 ();
  }
  
 +.float bezier_turn;
  void SUB_CalcMove_controller_think (void)
  {
        entity oldself;
  
                traveltime = self.animstate_endtime - self.animstate_starttime;
                phasepos = (nexttick - self.animstate_starttime) / traveltime; // range: [0, 1]
 -              if(self.platmovetype != 1)
 +              if(!self.platmovetype)
 +                      self.platmovetype = 2; // default
 +              switch(self.platmovetype)
                {
 -                      phasepos = 3.14159265 + (phasepos * 3.14159265); // range: [pi, 2pi]
 -                      phasepos = cos(phasepos); // cos [pi, 2pi] is in [-1, 1]
 -                      phasepos = phasepos + 1; // correct range to [0, 2]
 -                      phasepos = phasepos / 2; // correct range to [0, 1]
 +                      case 1: // linear
 +                              break;
 +                      case 2: // cosine
 +                              /* old version, good for mathematical reference
 +                              phasepos = 3.14159265 + (phasepos * 3.14159265); // range: [pi, 2pi]
 +                              phasepos = cos(phasepos); // cos [pi, 2pi] is in [-1, 1]
 +                              phasepos = phasepos + 1; // correct range to [0, 2]
 +                              phasepos = phasepos / 2; // correct range to [0, 1]
 +                              */
 +
 +                              phasepos = (1 - cos(phasepos * 3.14159265)) / 2;
 +                              break;
 +                      case 3: // inverted cosine
 +                              phasepos = acos(1 - phasepos * 2) / 3.14159265;
 +                              break;
 +                      case 4: // half cosine
 +                              phasepos = (1 - cos(phasepos * (3.14159265 / 2)));
 +                              break;
 +                      case 5: // inverted half cosine
 +                              phasepos = sin(phasepos * (3.14159265 / 2));
 +                              break;
                }
                nextpos = self.origin + (delta * phasepos) + (delta2 * phasepos * phasepos);
                // derivative: delta + 2 * delta2 * phasepos (e.g. for angle positioning)
                        veloc = veloc * (1 / sys_frametime); // so it arrives for the next frame
                }
                self.owner.velocity = veloc;
 +              if(self.owner.bezier_turn)
 +              {
 +                      vector vel;
 +                      vel = delta + 2 * delta2 * phasepos;
 +                      vel_z = -vel_z; // invert z velocity
 +                      vel = vectoangles(vel);
 +                      self.owner.angles = vel;
 +              }
                self.nextthink = nexttick;
        } else {
                // derivative: delta + 2 * delta2 (e.g. for angle positioning)
@@@ -256,7 -229,6 +256,7 @@@ void SUB_CalcMove_controller_setbezier 
  
        controller.destvec = 2 * control; // control point
        controller.destvec2 = dest - 2 * control; // quadratic part required to reach end point
 +      // also: initial d/dphasepos origin = 2 * control, final speed = 2 * (dest - control)
  }
  
  void SUB_CalcMove_controller_setlinear (entity controller, vector org, vector dest)
        controller.destvec2 = '0 0 0';
  }
  
 -void SUB_CalcMove_Bezier (vector tcontrol, vector tdest, float tspeed, void() func)
 +float TSPEED_TIME = -1;
 +float TSPEED_LINEAR = 0;
 +float TSPEED_START = 1;
 +float TSPEED_END = 2;
 +// TODO average too?
 +
 +void SUB_CalcMove_Bezier (vector tcontrol, vector tdest, float tspeedtype, float tspeed, void() func)
  {
        float   traveltime;
        entity controller;
        self.finaldest = tdest;
        self.think = SUB_CalcMoveDone;
  
 -      if(tspeed > 0) // positive: start speed
 -              traveltime = 2 * vlen(tcontrol - self.origin) /  tspeed;
 -      else // negative: end speed
 -              traveltime = 2 * vlen(tcontrol - tdest)       / -tspeed;
 +      switch(tspeedtype)
 +      {
 +              default:
 +              case TSPEED_START:
 +                      traveltime = 2 * vlen(tcontrol - self.origin) / tspeed;
 +                      break;
 +              case TSPEED_END:
 +                      traveltime = 2 * vlen(tcontrol - tdest)       / tspeed;
 +                      break;
 +              case TSPEED_LINEAR:
 +                      traveltime = vlen(tdest - self.origin)        / tspeed;
 +                      break;
 +              case TSPEED_TIME:
 +                      traveltime = tspeed;
 +                      break;
 +      }
  
        if (traveltime < 0.1) // useless anim
        {
        self = self.owner;
  }
  
 -void SUB_CalcMove (vector tdest, float tspeed, void() func)
 +void SUB_CalcMove (vector tdest, float tspeedtype, float tspeed, void() func)
  {
        vector  delta;
        float   traveltime;
        }
  
        delta = tdest - self.origin;
 -      traveltime = vlen (delta) / tspeed;
 +
 +      switch(tspeedtype)
 +      {
 +              default:
 +              case TSPEED_START:
 +              case TSPEED_END:
 +              case TSPEED_LINEAR:
 +                      traveltime = vlen (delta) / tspeed;
 +                      break;
 +              case TSPEED_TIME:
 +                      traveltime = tspeed;
 +                      break;
 +      }
  
        // Very short animations don't really show off the effect
        // of controlled animation, so let's just use linear movement.
        // Alternatively entities can choose to specify non-controlled movement.
          // The only currently implemented alternative movement is linear (value 1)
 -      if (traveltime < 0.15 || self.platmovetype == 1)
 +      if (traveltime < 0.15 || self.platmovetype < 2)
        {
                self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division
                self.nextthink = self.ltime + traveltime;
        }
  
        // now just run like a bezier curve...
 -      SUB_CalcMove_Bezier((self.origin + tdest) * 0.5, tdest, tspeed, func);
 +      SUB_CalcMove_Bezier((self.origin + tdest) * 0.5, tdest, tspeedtype, tspeed, func);
  }
  
 -void SUB_CalcMoveEnt (entity ent, vector tdest, float tspeed, void() func)
 +void SUB_CalcMoveEnt (entity ent, vector tdest, float tspeedtype, float tspeed, void() func)
  {
        entity  oldself;
  
        oldself = self;
        self = ent;
  
 -      SUB_CalcMove (tdest, tspeed, func);
 +      SUB_CalcMove (tdest, tspeedtype, tspeed, func);
  
        self = oldself;
  }
@@@ -417,7 -359,7 +417,7 @@@ void SUB_CalcAngleMoveDone (void
  }
  
  // FIXME: I fixed this function only for rotation around the main axes
 -void SUB_CalcAngleMove (vector destangle, float tspeed, void() func)
 +void SUB_CalcAngleMove (vector destangle, float tspeedtype, float tspeed, void() func)
  {
        vector  delta;
        float   traveltime;
        self.angles_y -= 360 * floor((self.angles_y - destangle_y) / 360 + 0.5);
        self.angles_z -= 360 * floor((self.angles_z - destangle_z) / 360 + 0.5);
        delta = destangle - self.angles;
 -      traveltime = vlen (delta) / tspeed;
 +
 +      switch(tspeedtype)
 +      {
 +              default:
 +              case TSPEED_START:
 +              case TSPEED_END:
 +              case TSPEED_LINEAR:
 +                      traveltime = vlen (delta) / tspeed;
 +                      break;
 +              case TSPEED_TIME:
 +                      traveltime = tspeed;
 +                      break;
 +      }
  
        self.think1 = func;
        self.finalangle = destangle;
        self.nextthink = self.ltime + traveltime;
  }
  
 -void SUB_CalcAngleMoveEnt (entity ent, vector destangle, float tspeed, void() func)
 +void SUB_CalcAngleMoveEnt (entity ent, vector destangle, float tspeedtype, float tspeed, void() func)
  {
        entity  oldself;
  
        oldself = self;
        self = ent;
  
 -      SUB_CalcAngleMove (destangle, tspeed, func);
 +      SUB_CalcAngleMove (destangle, tspeedtype, tspeed, func);
  
        self = oldself;
  }
@@@ -568,10 -498,11 +568,11 @@@ void WarpZone_tracebox_antilag (entity 
        tracebox_antilag_force_wz(source, v1, mi, ma, v2, nomonst, forent, lag, TRUE);
  }
  
- float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomonsters, entity forent) // returns the number of traces done, for benchmarking
+ float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomonsters, entity forent, float stopatentity) // returns the number of traces done, for benchmarking
  {
        vector pos, dir, t;
        float nudge;
+       entity stopentity;
  
        //nudge = 2 * cvar("collision_impactnudge"); // why not?
        nudge = 0.5;
                        dprint("  trace distance is ", ftos(vlen(pos - trace_endpos)), "\n");
                }
  
+               stopentity = trace_ent;
                if(trace_startsolid)
                {
                        // we started inside solid.
                                // t is still inside solid? bad
                                // force advance, then, and retry
                                pos = t + dir * nudge;
+                               // but if we hit an entity, stop RIGHT before it
+                               if(stopatentity && stopentity)
+                               {
+                                       trace_ent = stopentity;
+                                       trace_endpos = t;
+                                       trace_fraction = ((trace_endpos - v1) * dir) / ((v2 - v1) * dir);
+                                       return c;
+                               }
                        }
                        else
                        {
        }
  }
  
- void traceline_inverted (vector v1, vector v2, float nomonsters, entity forent)
+ void traceline_inverted (vector v1, vector v2, float nomonsters, entity forent, float stopatentity)
  {
- #if 0
-       vector pos, dir, t;
-       float nudge;
-       //nudge = 2 * cvar("collision_impactnudge"); // why not?
-       nudge = 0.5;
-       dir = normalize(v2 - v1);
-       pos = v1 + dir * nudge;
-       for(;;)
-       {
-               if((pos - v1) * dir >= (v2 - v1) * dir)
-               {
-                       // went too far
-                       trace_fraction = 1;
-                       return;
-               }
-               traceline(pos, v2, nomonsters, forent);
-               if(trace_startsolid)
-               {
-                       // we started inside solid.
-                       // then trace from endpos to pos
-                       t = trace_endpos;
-                       traceline(t, pos, nomonsters, forent);
-                       if(trace_startsolid)
-                       {
-                               // t is inside solid? bad
-                               // force advance, then
-                               pos = pos + dir * nudge;
-                       }
-                       else
-                       {
-                               // we actually LEFT solid!
-                               trace_fraction = ((trace_endpos - v1) * dir) / ((v2 - v1) * dir);
-                               return;
-                       }
-               }
-               else
-               {
-                       // pos is outside solid?!? but why?!? never mind, just return it.
-                       trace_endpos = pos;
-                       trace_fraction = ((trace_endpos - v1) * dir) / ((v2 - v1) * dir);
-                       return;
-               }
-       }
- #else
-       tracebox_inverted(v1, '0 0 0', '0 0 0', v2, nomonsters, forent);
+       tracebox_inverted(v1, '0 0 0', '0 0 0', v2, nomonsters, forent, stopatentity);
  }
  
  /*