Пример #1
0
  /** GL_DrawParticles */
  void GL_DrawParticles(int num_particles) {
    float origin_x, origin_y, origin_z;

    Math3D.VectorScale(vup, 1.5f, up);
    Math3D.VectorScale(vright, 1.5f, right);

    GL_Bind(r_particletexture.texnum);
    GL11.glDepthMask(false); // no z buffering
    GL11.glEnable(GL11.GL_BLEND);
    GL_TexEnv(GL11.GL_MODULATE);

    GL11.glBegin(GL11.GL_TRIANGLES);

    FloatBuffer sourceVertices = particle_t.vertexArray;
    IntBuffer sourceColors = particle_t.colorArray;
    float scale;
    int color;
    for (int j = 0, i = 0; i < num_particles; i++) {
      origin_x = sourceVertices.get(j++);
      origin_y = sourceVertices.get(j++);
      origin_z = sourceVertices.get(j++);

      // hack a scale up to keep particles from disapearing
      scale =
          (origin_x - r_origin[0]) * vpn[0]
              + (origin_y - r_origin[1]) * vpn[1]
              + (origin_z - r_origin[2]) * vpn[2];

      scale = (scale < 20) ? 1 : 1 + scale * 0.004f;

      color = sourceColors.get(i);

      GL11.glColor4ub(
          (byte) ((color) & 0xFF),
          (byte) ((color >> 8) & 0xFF),
          (byte) ((color >> 16) & 0xFF),
          (byte) ((color >>> 24)));
      // first vertex
      GL11.glTexCoord2f(0.0625f, 0.0625f);
      GL11.glVertex3f(origin_x, origin_y, origin_z);
      // second vertex
      GL11.glTexCoord2f(1.0625f, 0.0625f);
      GL11.glVertex3f(origin_x + up[0] * scale, origin_y + up[1] * scale, origin_z + up[2] * scale);
      // third vertex
      GL11.glTexCoord2f(0.0625f, 1.0625f);
      GL11.glVertex3f(
          origin_x + right[0] * scale, origin_y + right[1] * scale, origin_z + right[2] * scale);
    }
    GL11.glEnd();

    GL11.glDisable(GL11.GL_BLEND);
    GL11.glColor4f(1, 1, 1, 1);
    GL11.glDepthMask(true); // back to normal Z buffering
    GL_TexEnv(GL11.GL_REPLACE);
  }
Пример #2
0
  /** R_DrawBeam */
  void R_DrawBeam(entity_t e) {
    oldorigin[0] = e.oldorigin[0];
    oldorigin[1] = e.oldorigin[1];
    oldorigin[2] = e.oldorigin[2];

    origin[0] = e.origin[0];
    origin[1] = e.origin[1];
    origin[2] = e.origin[2];

    normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
    normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
    normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];

    if (Math3D.VectorNormalize(normalized_direction) == 0.0f) return;

    Math3D.PerpendicularVector(perpvec, normalized_direction);
    Math3D.VectorScale(perpvec, e.frame / 2, perpvec);

    for (int i = 0; i < 6; i++) {
      Math3D.RotatePointAroundVector(
          start_points[i], normalized_direction, perpvec, (360.0f / NUM_BEAM_SEGS) * i);

      Math3D.VectorAdd(start_points[i], origin, start_points[i]);
      Math3D.VectorAdd(start_points[i], direction, end_points[i]);
    }

    GL11.glDisable(GL11.GL_TEXTURE_2D);
    GL11.glEnable(GL11.GL_BLEND);
    GL11.glDepthMask(false);

    float r = (d_8to24table[e.skinnum & 0xFF]) & 0xFF;
    float g = (d_8to24table[e.skinnum & 0xFF] >> 8) & 0xFF;
    float b = (d_8to24table[e.skinnum & 0xFF] >> 16) & 0xFF;

    r *= 1 / 255.0f;
    g *= 1 / 255.0f;
    b *= 1 / 255.0f;

    GL11.glColor4f(r, g, b, e.alpha);

    GL11.glBegin(GL11.GL_TRIANGLE_STRIP);

    float[] v;

    for (int i = 0; i < NUM_BEAM_SEGS; i++) {
      v = start_points[i];
      GL11.glVertex3f(v[0], v[1], v[2]);
      v = end_points[i];
      GL11.glVertex3f(v[0], v[1], v[2]);
      v = start_points[(i + 1) % NUM_BEAM_SEGS];
      GL11.glVertex3f(v[0], v[1], v[2]);
      v = end_points[(i + 1) % NUM_BEAM_SEGS];
      GL11.glVertex3f(v[0], v[1], v[2]);
    }
    GL11.glEnd();

    GL11.glEnable(GL11.GL_TEXTURE_2D);
    GL11.glDisable(GL11.GL_BLEND);
    GL11.glDepthMask(true);
  }
Пример #3
0
  /** Bmodel objects don't interact with each other, but push all box objects. */
  public static void SV_Physics_Pusher(edict_t ent) {
    float[] move = {0, 0, 0};
    float[] amove = {0, 0, 0};
    edict_t part, mv;

    // if not a team captain, so movement will be handled elsewhere
    if ((ent.flags & Defines.FL_TEAMSLAVE) != 0) return;

    // make sure all team slaves can move before commiting
    // any moves or calling any think functions
    // if the move is blocked, all moved objects will be backed out
    //	  retry:
    GameBase.pushed_p = 0;
    for (part = ent; part != null; part = part.teamchain) {
      if (part.velocity[0] != 0
          || part.velocity[1] != 0
          || part.velocity[2] != 0
          || part.avelocity[0] != 0
          || part.avelocity[1] != 0
          || part.avelocity[2] != 0) { // object
        // is
        // moving
        Math3D.VectorScale(part.velocity, Defines.FRAMETIME, move);
        Math3D.VectorScale(part.avelocity, Defines.FRAMETIME, amove);

        if (!SV_Push(part, move, amove)) break; // move was blocked
      }
    }
    if (GameBase.pushed_p > Defines.MAX_EDICTS)
      SV_GAME.PF_error(Defines.ERR_FATAL, "pushed_p > &pushed[MAX_EDICTS], memory corrupted");

    if (part != null) {
      // the move failed, bump all nextthink times and back out moves
      for (mv = ent; mv != null; mv = mv.teamchain) {
        if (mv.nextthink > 0) mv.nextthink += Defines.FRAMETIME;
      }

      // if the pusher has a "blocked" function, call it
      // otherwise, just stay in place until the obstacle is gone
      if (part.blocked != null) part.blocked.blocked(part, GameBase.obstacle);
    } else { // the move succeeded, so call all think functions
      for (part = ent; part != null; part = part.teamchain) {
        SV_RunThink(part);
      }
    }
  }
Пример #4
0
  /** Toss, bounce, and fly movement. When onground, do nothing. */
  public static void SV_Physics_Toss(edict_t ent) {

    trace_t trace;
    float[] move = {0, 0, 0};
    float backoff;
    edict_t slave;
    boolean wasinwater;
    boolean isinwater;
    float[] old_origin = {0, 0, 0};

    //	   regular thinking
    SV_RunThink(ent);

    // if not a team captain, so movement will be handled elsewhere
    if ((ent.flags & Defines.FL_TEAMSLAVE) != 0) return;

    if (ent.velocity[2] > 0) ent.groundentity = null;

    //	check for the groundentity going away
    if (ent.groundentity != null) if (!ent.groundentity.inuse) ent.groundentity = null;

    //	   if onground, return without moving
    if (ent.groundentity != null) return;

    Math3D.VectorCopy(ent.s.origin, old_origin);

    SV_CheckVelocity(ent);

    //	   add gravity
    if (ent.movetype != Defines.MOVETYPE_FLY && ent.movetype != Defines.MOVETYPE_FLYMISSILE)
      SV_AddGravity(ent);

    //	   move angles
    Math3D.VectorMA(ent.s.angles, Defines.FRAMETIME, ent.avelocity, ent.s.angles);

    //	   move origin
    Math3D.VectorScale(ent.velocity, Defines.FRAMETIME, move);
    trace = SV_PushEntity(ent, move);
    if (!ent.inuse) return;

    if (trace.fraction < 1) {
      if (ent.movetype == Defines.MOVETYPE_BOUNCE) backoff = 1.5f;
      else backoff = 1;

      GameBase.ClipVelocity(ent.velocity, trace.plane.normal, ent.velocity, backoff);

      // stop if on ground
      if (trace.plane.normal[2] > 0.7) {
        if (ent.velocity[2] < 60 || ent.movetype != Defines.MOVETYPE_BOUNCE) {
          ent.groundentity = trace.ent;
          ent.groundentity_linkcount = trace.ent.linkcount;
          Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);
          Math3D.VectorCopy(Globals.vec3_origin, ent.avelocity);
        }
      }

      // if (ent.touch)
      //	ent.touch (ent, trace.ent, &trace.plane, trace.surface);
    }

    //	   check for water transition
    wasinwater = (ent.watertype & Defines.MASK_WATER) != 0;
    ent.watertype = GameBase.gi.pointcontents.pointcontents(ent.s.origin);
    isinwater = (ent.watertype & Defines.MASK_WATER) != 0;

    if (isinwater) ent.waterlevel = 1;
    else ent.waterlevel = 0;

    if (!wasinwater && isinwater)
      GameBase.gi.positioned_sound(
          old_origin, ent, Defines.CHAN_AUTO, GameBase.gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0);
    else if (wasinwater && !isinwater)
      GameBase.gi.positioned_sound(
          ent.s.origin,
          ent,
          Defines.CHAN_AUTO,
          GameBase.gi.soundindex("misc/h2ohit1.wav"),
          1,
          1,
          0);

    //	   move teamslaves
    for (slave = ent.teamchain; slave != null; slave = slave.teamchain) {
      Math3D.VectorCopy(ent.s.origin, slave.s.origin);
      GameBase.gi.linkentity(slave);
    }
  }
Пример #5
0
  public static int SV_FlyMove(edict_t ent, float time, int mask) {
    edict_t hit;
    int bumpcount, numbumps;
    float[] dir = {0.0f, 0.0f, 0.0f};
    float d;
    int numplanes;
    float[][] planes = new float[MAX_CLIP_PLANES][3];
    float[] primal_velocity = {0.0f, 0.0f, 0.0f};
    float[] original_velocity = {0.0f, 0.0f, 0.0f};
    float[] new_velocity = {0.0f, 0.0f, 0.0f};
    int i, j;
    trace_t trace;
    float[] end = {0.0f, 0.0f, 0.0f};
    float time_left;
    int blocked;

    numbumps = 4;

    blocked = 0;
    Math3D.VectorCopy(ent.velocity, original_velocity);
    Math3D.VectorCopy(ent.velocity, primal_velocity);
    numplanes = 0;

    time_left = time;

    ent.groundentity = null;
    for (bumpcount = 0; bumpcount < numbumps; bumpcount++) {
      for (i = 0; i < 3; i++) end[i] = ent.s.origin[i] + time_left * ent.velocity[i];

      trace = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs, end, ent, mask);

      if (trace.allsolid) { // entity is trapped in another solid
        Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);
        return 3;
      }

      if (trace.fraction > 0) { // actually covered some distance
        Math3D.VectorCopy(trace.endpos, ent.s.origin);
        Math3D.VectorCopy(ent.velocity, original_velocity);
        numplanes = 0;
      }

      if (trace.fraction == 1) break; // moved the entire distance

      hit = trace.ent;

      if (trace.plane.normal[2] > 0.7) {
        blocked |= 1; // floor
        if (hit.solid == Defines.SOLID_BSP) {
          ent.groundentity = hit;
          ent.groundentity_linkcount = hit.linkcount;
        }
      }
      if (trace.plane.normal[2] == 0.0f) {
        blocked |= 2; // step
      }

      //
      //	   run the impact function
      //
      SV_Impact(ent, trace);
      if (!ent.inuse) break; // removed by the impact function

      time_left -= time_left * trace.fraction;

      // cliped to another plane
      if (numplanes >= MAX_CLIP_PLANES) { // this shouldn't
        // really happen
        Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);
        return 3;
      }

      Math3D.VectorCopy(trace.plane.normal, planes[numplanes]);
      numplanes++;

      //
      //	   modify original_velocity so it parallels all of the clip planes
      //
      for (i = 0; i < numplanes; i++) {
        GameBase.ClipVelocity(original_velocity, planes[i], new_velocity, 1);

        for (j = 0; j < numplanes; j++)
          if ((j != i) && !Math3D.VectorEquals(planes[i], planes[j])) {
            if (Math3D.DotProduct(new_velocity, planes[j]) < 0) break; // not ok
          }
        if (j == numplanes) break;
      }

      if (i != numplanes) { // go along this plane
        Math3D.VectorCopy(new_velocity, ent.velocity);
      } else { // go along the crease
        if (numplanes != 2) {
          //					gi.dprintf ("clip velocity, numplanes ==
          // %i\n",numplanes);
          Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);
          return 7;
        }
        Math3D.CrossProduct(planes[0], planes[1], dir);
        d = Math3D.DotProduct(dir, ent.velocity);
        Math3D.VectorScale(dir, d, ent.velocity);
      }

      //
      //	   if original velocity is against the original velocity, stop dead
      //	   to avoid tiny occilations in sloping corners
      //
      if (Math3D.DotProduct(ent.velocity, primal_velocity) <= 0) {
        Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);
        return blocked;
      }
    }

    return blocked;
  }