function _generateLinkAttributes(portal, resonator, color, resonatorPercent) {
  resonatorPercent = resonatorPercent === undefined ? 1 : Math.max(Math.min(resonatorPercent, 1), 0);
  var values = new Float32Array(_size * _chunkSize);
  var dist = Math.sqrt(
    (resonator[0] - portal[0]) * (resonator[0] - portal[0]) +
    (resonator[1] - portal[1]) * (resonator[1] - portal[1])
  );
  var f4 = (2 / 30) * dist,
    f5 = 0.9 + 0.1 * resonatorPercent,
    f6 = 0.65 + 0.35 * resonatorPercent,
    f8 = 0.1 + 0.3 * resonatorPercent;
  var cl = vec4.lerp(vec4.create(), baseColor, color, 0.1 + resonatorPercent * 0.85);
  cl[3] = 0.75 + 0.25 * resonatorPercent * cl[3];
  var vec = vec3.fromValues(resonator[0], 0, resonator[1]);
  vec3.subtract(vec, vec, vec3.fromValues(portal[0], 0, portal[1]));
  var right = vec3.cross(vec3.create(), vec, up);
  vec3.normalize(right, right);
  var step = _len * 2;
  var f10 = 5.0 * ((portal[0] + portal[1]) - Math.floor(portal[0] + portal[1]));
  for(var i = 0; i < _len; i++)
  {
    var f11 = j[i],
      f12 = portal[0] + f11 * vec[0],
      f13 = portal[1] + f11 * vec[2],
      f14 = portalBaseOffset + f11 * (resonatorMidOffset - portalBaseOffset) + f5 * k[i],
      f15 = f6 * l[i],
      f16 = f11 * f4;
    fillChunk(values, (i * 2) + 0, f12 + f15 * right[0], f14, f13 + f15 * right[2], 0.0, f16 + f10, up, f8, cl);
    fillChunk(values, (i * 2) + 1, f12 - f15 * right[0], f14, f13 - f15 * right[2], 1.0, f16 + f10, up, f8, cl);
    fillChunk(values, step + (i * 2) + 0, f12, f14 + f15, f13, 0.0, f16 + f10, right, f8, cl);
    fillChunk(values, step + (i * 2) + 1, f12, f14 - f15, f13, 1.0, f16 + f10, right, f8, cl);
  }
  return values;
}
Ejemplo n.º 2
0
  /**
   *
   */
  update() {
    let modelObject = this.emitter.modelObject;
    let dt = modelObject.model.viewer.frameTime * 0.001;
    let location = this.location;
    let worldLocation = locationHeap;
    let velocity = this.velocity;

    this.health -= dt;

    velocity[2] -= this.gravity * dt;

    vec3.scaleAndAdd(location, location, velocity, dt);

    vec3.copy(worldLocation, location);

    let lifeFactor = (modelObject.lifeSpan - this.health) / modelObject.lifeSpan;
    let timeMiddle = modelObject.timeMiddle;
    let intervals = modelObject.intervals;
    let factor;
    let firstColor;
    let head = this.head;
    let interval;

    if (lifeFactor < timeMiddle) {
      factor = lifeFactor / timeMiddle;

      firstColor = 0;

      if (head) {
        interval = intervals[0];
      } else {
        interval = intervals[2];
      }
    } else {
      factor = (lifeFactor - timeMiddle) / (1 - timeMiddle);

      firstColor = 1;

      if (head) {
        interval = intervals[1];
      } else {
        interval = intervals[3];
      }
    }

    factor = Math.min(factor, 1);

    let start = interval[0];
    let end = interval[1];
    let repeat = interval[2];
    let scaling = modelObject.scaling;
    let colors = modelObject.colors;
    let scale = lerp(scaling[firstColor], scaling[firstColor + 1], factor);
    let left;
    let top;
    let right;
    let bottom;
    let instance = this.emitterView.instance;

    // If this is a team colored emitter, get the team color tile from the atlas.
    // Otherwise do normal texture atlas handling.
    if (modelObject.teamColored) {
      let teamColor = instance.teamColor;

      left = teamColor % 4;
      top = (teamColor / 4) | 0;
      right = left + 1;
      bottom = top + 1;
    } else {
      let columns = modelObject.dimensions[0];
      let index = 0;
      let spriteCount = end - start;

      if (spriteCount) {
        // Repeating speeds up the sprite animation, which makes it effectively run N times in its interval.
        // E.g. if repeat is 4, the sprite animation will be seen 4 times, and thus also run 4 times as fast.
        index = start + Math.floor(spriteCount * repeat * factor) % spriteCount;
      }

      left = index % columns;
      top = (index / columns) | 0;
      right = left + 1;
      bottom = top + 1;
    }

    vec4.lerp(colorHeap, colors[firstColor], colors[firstColor + 1], factor);

    let a = colorHeap[3];

    this.lta = uint8ToUint24(right, bottom, a);
    this.lba = uint8ToUint24(left, bottom, a);
    this.rta = uint8ToUint24(right, top, a);
    this.rba = uint8ToUint24(left, top, a);
    this.rgb = uint8ToUint24(colorHeap[0], colorHeap[1], colorHeap[2]);

    let camera = instance.scene.camera;
    let vectors;

    // Choose between a default rectangle or billboarded one
    if (modelObject.xYQuad) {
      vectors = camera.vectors;
    } else {
      vectors = camera.billboardedVectors;
    }

    let vertices = this.vertices;
    let nodeScale = this.nodeScale;

    let scalex = scale * nodeScale[0];
    let scaley = scale * nodeScale[1];
    let scalez = scale * nodeScale[2];

    if (head) {
      // If this is a model space emitter, the particle location is in local space, so convert it now to world space.
      if (modelObject.modelSpace) {
        vec3.transformMat4(worldLocation, worldLocation, this.node.worldMatrix);
      }

      let px = worldLocation[0];
      let py = worldLocation[1];
      let pz = worldLocation[2];

      let pv1 = vectors[0];
      let pv2 = vectors[1];
      let pv3 = vectors[2];
      let pv4 = vectors[3];

      vertices[0] = px + pv1[0] * scalex;
      vertices[1] = py + pv1[1] * scaley;
      vertices[2] = pz + pv1[2] * scalez;
      vertices[3] = px + pv2[0] * scalex;
      vertices[4] = py + pv2[1] * scaley;
      vertices[5] = pz + pv2[2] * scalez;
      vertices[6] = px + pv3[0] * scalex;
      vertices[7] = py + pv3[1] * scaley;
      vertices[8] = pz + pv3[2] * scalez;
      vertices[9] = px + pv4[0] * scalex;
      vertices[10] = py + pv4[1] * scaley;
      vertices[11] = pz + pv4[2] * scalez;
    } else {
      let tailLength = modelObject.tailLength;
      let offsetx = tailLength * velocity[0] * 1;
      let offsety = tailLength * velocity[1] * 1;
      let offsetz = tailLength * velocity[2] * 1;

      // The start and end of the tail.
      let start = [worldLocation[0] - offsetx, worldLocation[1] - offsety, worldLocation[2] - offsetz];
      let end = [worldLocation[0], worldLocation[1], worldLocation[2]];

      // If this is a model space emitter, the start and end are is in local space, so convert them to world space.
      if (modelObject.modelSpace) {
        vec3.transformMat4(start, start, this.node.worldMatrix);
        vec3.transformMat4(end, end, this.node.worldMatrix);
      }

      let startx = start[0];
      let starty = start[1];
      let startz = start[2];
      let endx = end[0];
      let endy = end[1];
      let endz = end[2];

      // Get the normal to the tail in camera space.
      // This allows to build a 2D rectangle around the 3D tail.
      let tail = [endx - startx, endy - starty, endz - startz];
      vec3.normalize(tail, tail);
      let normal = vec3.cross([], camera.billboardedVectors[6], tail);
      vec3.normalize(normal, normal);

      let normalX = normal[0] * scalex;
      let normalY = normal[1] * scaley;
      let normalZ = normal[2] * scalez;

      vertices[0] = startx - normalX;
      vertices[1] = starty - normalY;
      vertices[2] = startz - normalZ;

      vertices[6] = endx + normalX;
      vertices[7] = endy + normalY;
      vertices[8] = endz + normalZ;

      vertices[3] = endx - normalX;
      vertices[4] = endy - normalY;
      vertices[5] = endz - normalZ;

      vertices[9] = startx + normalX;
      vertices[10] = starty + normalY;
      vertices[11] = startz + normalZ;
    }
  }