Example #1
0
  @Override
  protected void processRoofEditPoints(final List<? extends ReadOnlyVector3> wallUpperPoints) {
    final ReadOnlyVector3 center = getCenter();
    if (recalculateEditPoints) {
      recalculateEditPoints = false;
      points.get(0).set(toRelative(center));
      // if (editPointIndex == -1) {
      recalculateEditPoints = false;
      points.add(toRelative(getCenter()));
      final Vector3 hipDirection =
          container.getAbsPoint(2).subtractLocal(container.getAbsPoint(0)).normalizeLocal();
      Vector3 point1 =
          findFarthestIntersection(
              wallUpperPoints, center, center.add(hipDirection.multiply(-1000, null), null));
      Vector3 point2 =
          findFarthestIntersection(
              wallUpperPoints, center, center.add(hipDirection.multiply(1000, null), null));
      if (point1 == null) point1 = center.clone();
      if (point2 == null) point2 = center.clone();

      point1.addLocal(hipDirection.multiply(point1.distance(center) * 0.5, null));
      point2.addLocal(hipDirection.multiply(-point2.distance(center) * 0.5, null));
      points.get(1).set(toRelative(point1));
      points.get(2).set(toRelative(point2));

      computeHeight(wallUpperPoints);
      applyHeight();
      // }
    } else {
      applyHeight();
    }
  }
Example #2
0
  @Override
  public void apply(final double dt, final Particle particle, final int index) {
    if (_wanderRadius == 0 && _wanderDistance == 0 && _wanderJitter == 0) {
      return;
    }

    final Vector3 wanderTarget = _wanderTargets.get(index);

    wanderTarget.addLocal(calcNewJitter(), calcNewJitter(), calcNewJitter());
    wanderTarget.normalizeLocal();
    wanderTarget.multiplyLocal(_wanderRadius);

    _workVect.set(particle.getVelocity()).normalizeLocal().multiplyLocal(_wanderDistance);
    _workVect.addLocal(wanderTarget).normalizeLocal();
    _workVect.multiplyLocal(particle.getVelocity().length());
    particle.getVelocity().set(_workVect);
  }
Example #3
0
  /**
   * update position (using current position and velocity), color (interpolating between start and
   * end color), size (interpolating between start and end size), spin (using parent's spin speed)
   * and current age of particle. If this particle's age is greater than its lifespan, it is set to
   * status DEAD.
   *
   * <p>Note that this only changes the parameters of the Particle, not the geometry the particle is
   * associated with.
   *
   * @param secondsPassed number of seconds passed since last update.
   * @return true if this particle is not ALIVE (in other words, if it is ready to be reused.)
   */
  public boolean updateAndCheck(final double secondsPassed) {
    if (status != Status.Alive) {
      return true;
    }
    currentAge += secondsPassed * 1000; // add ms time to age
    if (currentAge > lifeSpan) {
      killParticle();
      return true;
    }

    final Vector3 temp = Vector3.fetchTempInstance();
    _position.addLocal(_velocity.multiply(secondsPassed * 1000f, temp));
    Vector3.releaseTempInstance(temp);

    // get interpolated values from appearance ramp:
    parent.getRamp().getValuesAtAge(currentAge, lifeSpan, currColor, values, parent);

    // interpolate colors
    final int verts = ParticleSystem.getVertsForParticleType(type);
    for (int x = 0; x < verts; x++) {
      BufferUtils.setInBuffer(
          currColor, parent.getParticleGeometry().getMeshData().getColorBuffer(), startIndex + x);
    }

    // check for tex animation
    final int newTexIndex = parent.getTexAnimation().getTexIndexAtAge(currentAge, lifeSpan, parent);
    // Update tex coords if applicable
    if (currentTexIndex != newTexIndex) {
      // Only supported in Quad type for now.
      if (ParticleType.Quad.equals(parent.getParticleType())) {
        // determine side
        final float side = (float) Math.sqrt(parent.getTexQuantity());
        int index = newTexIndex;
        if (index >= parent.getTexQuantity()) {
          index %= parent.getTexQuantity();
        }
        // figure row / col
        final float row = side - (int) (index / side) - 1;
        final float col = index % side;
        // set texcoords
        final float sU = col / side, eU = (col + 1) / side;
        final float sV = row / side, eV = (row + 1) / side;
        final FloatBuffer texs =
            parent.getParticleGeometry().getMeshData().getTextureCoords(0).getBuffer();
        texs.position(startIndex * 2);
        texs.put(eU).put(sV);
        texs.put(eU).put(eV);
        texs.put(sU).put(eV);
        texs.put(sU).put(sV);
        texs.clear();
      }
      currentTexIndex = newTexIndex;
    }

    return false;
  }
Example #4
0
  private BoundingVolume merge(
      final double otherRadius, final ReadOnlyVector3 otherCenter, final BoundingSphere store) {
    // check for infinite bounds... is so, return infinite bounds with center at origin
    if (Double.isInfinite(otherRadius) || Double.isInfinite(getRadius())) {
      store.setCenter(Vector3.ZERO);
      store.setRadius(Double.POSITIVE_INFINITY);
      return store;
    }

    final Vector3 diff = otherCenter.subtract(_center, _compVect1);
    final double lengthSquared = diff.lengthSquared();
    final double radiusDiff = otherRadius - getRadius();
    final double radiusDiffSqr = radiusDiff * radiusDiff;

    // if one sphere wholly contains the other
    if (radiusDiffSqr >= lengthSquared) {
      // if we contain the other
      if (radiusDiff <= 0.0) {
        store.setCenter(_center);
        store.setRadius(_radius);
        return store;
      }
      // else the other contains us
      else {
        store.setCenter(otherCenter);
        store.setRadius(otherRadius);
        return store;
      }
    }

    // distance between sphere centers
    final double length = Math.sqrt(lengthSquared);

    // init a center var using our center
    final Vector3 rCenter = _compVect2;
    rCenter.set(_center);

    // if our centers are at least a tiny amount apart from each other...
    if (length > MathUtils.EPSILON) {
      // place us between the two centers, weighted by radii
      final double coeff = (length + radiusDiff) / (2.0 * length);
      rCenter.addLocal(diff.multiplyLocal(coeff));
    }

    // set center on our resulting bounds
    store.setCenter(rCenter);

    // Set radius
    store.setRadius(0.5 * (length + getRadius() + otherRadius));
    return store;
  }
Example #5
0
 @Override
 public void apply(final double dt, final Particle particle, final int index) {
   final Vector3 pVelocity = particle.getVelocity();
   // determine if the particle is in the inner or outer zone
   final double pDist = particle.getPosition().distanceSquared(_swarmPoint);
   final Vector3 workVect = Vector3.fetchTempInstance();
   final Vector3 workVect2 = Vector3.fetchTempInstance();
   final Matrix3 workMat = Matrix3.fetchTempInstance();
   workVect.set(_swarmPoint).subtractLocal(particle.getPosition()).normalizeLocal();
   workVect2.set(pVelocity).normalizeLocal();
   if (pDist > _swarmRangeSQ) {
     // IN THE OUTER ZONE...
     // Determine if the angle between particle velocity and a vector to
     // the swarmPoint is less than the accepted deviance
     final double angle = workVect.smallestAngleBetween(workVect2);
     if (angle < _deviance) {
       // if it is, increase the speed speedBump over time
       if (pVelocity.lengthSquared() < maxSpeedSQ) {
         final double change = _speedBump * dt;
         workVect2.multiplyLocal(change); // where workVector2 = pVelocity.normalizeLocal()
         pVelocity.addLocal(workVect2);
       }
     } else {
       final Vector3 axis = workVect2.crossLocal(workVect);
       // if it is not, shift the velocity to bring it back in line
       if ((Double.doubleToLongBits(pVelocity.lengthSquared()) & 0x1d) != 0) {
         workMat.fromAngleAxis(_turnSpeed * dt, axis);
       } else {
         workMat.fromAngleAxis(-_turnSpeed * dt, axis);
       }
       workMat.applyPost(pVelocity, pVelocity);
     }
   } else {
     final Vector3 axis = workVect2.crossLocal(workVect);
     // IN THE INNER ZONE...
     // Alter the heading based on how fast we are going
     if ((index & 0x1f) != 0) {
       workMat.fromAngleAxis(_turnSpeed * dt, axis);
     } else {
       workMat.fromAngleAxis(-_turnSpeed * dt, axis);
     }
     workMat.applyPost(pVelocity, pVelocity);
   }
   Vector3.releaseTempInstance(workVect);
   Vector3.releaseTempInstance(workVect2);
   Matrix3.releaseTempInstance(workMat);
 }