示例#1
0
  // ! Initializes a particle
  protected void initParticle(Particle particle) {
    // timeToLive
    // no negative life. prevent division by 0
    particle.timeToLive = mLife + mLifeVar * randomMinus1To1();
    particle.timeToLive = Math.max(0, particle.timeToLive);

    // position
    particle.pos.x = mSourcePosition.x + mPosVar.x * randomMinus1To1();
    particle.pos.y = mSourcePosition.y + mPosVar.y * randomMinus1To1();

    // Color
    int start;
    int r =
        Misc.clamp(
            Color.red(mStartColor) + (int) (Color.red(mStartColorVar) * randomMinus1To1()), 0, 255);
    int g =
        Misc.clamp(
            Color.green(mStartColor) + (int) (Color.green(mStartColorVar) * randomMinus1To1()),
            0,
            255);
    int b =
        Misc.clamp(
            Color.blue(mStartColor) + (int) (Color.blue(mStartColorVar) * randomMinus1To1()),
            0,
            255);
    int a =
        Misc.clamp(
            Color.alpha(mStartColor) + (int) (Color.alpha(mStartColorVar) * randomMinus1To1()),
            0,
            255);
    start = Color.argb(a, r, g, b);

    int end;
    r =
        Misc.clamp(
            Color.red(mEndColor) + (int) (Color.red(mEndColorVar) * randomMinus1To1()), 0, 255);
    g =
        Misc.clamp(
            Color.green(mEndColor) + (int) (Color.green(mEndColorVar) * randomMinus1To1()), 0, 255);
    b =
        Misc.clamp(
            Color.blue(mEndColor) + (int) (Color.blue(mEndColorVar) * randomMinus1To1()), 0, 255);
    a =
        Misc.clamp(
            Color.alpha(mEndColor) + (int) (Color.alpha(mEndColorVar) * randomMinus1To1()), 0, 255);
    end = Color.argb(a, r, g, b);

    particle.color = start;
    r = (int) ((Color.red(end) - Color.red(start)) / particle.timeToLive);
    g = (int) ((Color.green(end) - Color.green(start)) / particle.timeToLive);
    b = (int) ((Color.blue(end) - Color.blue(start)) / particle.timeToLive);
    a = (int) ((Color.alpha(end) - Color.alpha(start)) / particle.timeToLive);
    particle.deltaColor = new Colour(a, r, g, b);

    // size
    float startS = mStartSize + mStartSizeVar * randomMinus1To1();
    startS = Math.max(0, startS); // No negative value

    particle.size = startS;

    if (mEndSize < 0) {
      particle.deltaSize = 0;
    } else {
      float endS = mEndSize + mEndSizeVar * randomMinus1To1();
      endS = Math.max(0, endS); // No negative values
      particle.deltaSize = (endS - startS) / particle.timeToLive;
    }

    // rotation
    float startA = mStartSpin + mStartSpinVar * randomMinus1To1();
    float endA = mEndSpin + mEndSpinVar * randomMinus1To1();
    particle.rotation = startA;
    particle.deltaRotation = (endA - startA) / particle.timeToLive;

    if (mPositionType == PositionType.POSITION_GROUP) {
      particle.startPos = new Point();
    } else {
      particle.startPos = new Point(mPosition);
    }

    // direction
    double radians = Math.toRadians(mAngle + mAngleVar * randomMinus1To1());

    // Mode Gravity: A
    if (mEmitterMode == EmitterMode.MODE_GRAVITY) {
      Point v = new Point((float) Math.cos(radians), (float) Math.sin(radians));
      float s = modeA.speed + modeA.speedVar * randomMinus1To1();

      // direction
      particle.modeA.dir = Point.mult(v, s);

      // radial accel
      particle.modeA.radialAccel = modeA.radialAccel + modeA.radialAccelVar * randomMinus1To1();

      // tangential accel
      particle.modeA.tangentialAccel =
          modeA.tangentialAccel + modeA.tangentialAccelVar * randomMinus1To1();

    } else { // Mode Radius: B
      // Set the default diameter of the particle from the source position
      float startRadius = modeB.startRadius + modeB.startRadiusVar * randomMinus1To1();
      float endRadius = modeB.endRadius + modeB.endRadiusVar * randomMinus1To1();

      particle.modeB.radius = startRadius;

      if (modeB.endRadius < 0) {
        particle.modeB.deltaRadius = 0;
      } else {
        particle.modeB.deltaRadius = (endRadius - startRadius) / particle.timeToLive;
      }

      particle.modeB.angle = a;
      particle.modeB.degreesPerSecond =
          (float)
              Math.toRadians(modeB.rotatePerSecond + modeB.rotatePerSecondVar * randomMinus1To1());
    }
  }
示例#2
0
  public void update(float dt) {
    if (mIsActive && mEmissionRate > 0) {
      float rate = 1.0f / mEmissionRate;
      // issue #1201, prevent bursts of particles, due to too high emitCounter
      if (mParticleCount < mTotalParticles) {
        mEmitCounter += dt;
      }

      while (mParticleCount < mTotalParticles && mEmitCounter > rate) {
        this.addParticle();
        mEmitCounter -= rate;
      }

      mElapsed += dt;
      if (mDuration != -1 && mDuration < mElapsed) {
        this.stopEmitting();
      }
    }

    mParticleIdx = 0;

    if (mIsVisible) {
      boolean needInvalidate = mParticleIdx < mParticleCount;
      while (mParticleIdx < mParticleCount) {
        Particle p = mParticles[mParticleIdx];

        // life
        p.timeToLive -= dt;

        if (p.timeToLive > 0) {
          // Mode A: gravity, direction, tangential accel & radial accel
          if (mEmitterMode == EmitterMode.MODE_GRAVITY) {
            Point tmp, radial, tangential;

            // radial acceleration
            if (p.pos.x != 0 || p.pos.y != 0) {
              radial = Point.Normalize(p.pos);
            } else {
              radial = new Point();
            }
            tangential = radial;
            radial = Point.mult(radial, p.modeA.radialAccel);

            // tangential acceleration
            float newY = tangential.x;
            tangential.x = -tangential.y;
            tangential.y = newY;
            tangential.multBy(p.modeA.tangentialAccel);

            // (gravity + radial + tangential) * dt
            //                        tmp = Point.add(Point.add(radial, tangential), modeA.gravity);
            tmp = tangential;
            tmp.addBy(radial);
            tmp.addBy(modeA.gravity);
            tmp.multBy(dt);
            p.modeA.dir.addBy(tmp);
            p.pos.addBy(Point.mult(p.modeA.dir, dt));
          } else { // Mode B: radius movement
            // Update the angle and radius of the particle.
            p.modeB.angle += p.modeB.degreesPerSecond * dt;
            p.modeB.radius += p.modeB.deltaRadius * dt;

            p.pos.x = (float) (-Math.cos(p.modeB.angle) * p.modeB.radius);
            p.pos.y = (float) (-Math.sin(p.modeB.angle) * p.modeB.radius);
          }

          // color
          int r = Color.red(p.color) + (int) (p.deltaColor.r * dt);
          int g = Color.green(p.color) + (int) (p.deltaColor.g * dt);
          int b = Color.blue(p.color) + (int) (p.deltaColor.b * dt);
          int a = Color.alpha(p.color) + (int) (p.deltaColor.a * dt);
          p.color = Color.argb(a, r, g, b);

          // size
          p.size += (p.deltaSize * dt);
          p.size = Math.max(0, p.size);

          // angle
          p.rotation += (p.deltaRotation * dt);

          // update particle counter
          ++mParticleIdx;
        } else { // life < 0
          if (mParticleIdx != mParticleCount - 1) {
            mParticles[mParticleIdx].copy(mParticles[mParticleCount - 1]);
          }

          --mParticleCount;
        }
      } // while

      if (needInvalidate && null != mCallbackRef) {
        UpdateCallback callback = mCallbackRef.get();
        if (null != callback) {
          callback.needInvalidate();
        }
      }
    }
    postStep();
  }
  public void update(int anim, int time) {
    float dt = (float) viewer.getDelta() * 0.001F;
    float grav = AnimatedFloat.getValue(gravity, anim, time);
    float deaccel = AnimatedFloat.getValue(gravity2, anim, time);
    if (emitterType == 1 || emitterType == 2) {
      float rate = AnimatedFloat.getValue(emissionRate, anim, time);
      float life = AnimatedFloat.getValue(lifespan, anim, time);
      float toSpawn = 0.0F;
      if (life != 0.0F) toSpawn = (dt * rate) / life + spawnRemainder;
      else toSpawn = spawnRemainder;
      if (toSpawn < 1.0F) {
        spawnRemainder = toSpawn;
        if (spawnRemainder < 0.0F) spawnRemainder = 0.0F;
      } else {
        int spawnCount = (int) toSpawn;
        if (spawnCount + particles.size() > 1000) spawnCount = 1000 - particles.size();
        spawnRemainder = toSpawn - (float) spawnCount;
        float w = AnimatedFloat.getValue(areaWidth, anim, time) * 0.5F;
        float l = AnimatedFloat.getValue(areaLength, anim, time) * 0.5F;
        float speed = AnimatedFloat.getValue(emissionSpeed, anim, time);
        float var = AnimatedFloat.getValue(speedVariation, anim, time);
        float spread = AnimatedFloat.getValue(verticalRange, anim, time);
        float spread2 = AnimatedFloat.getValue(horizontalRange, anim, time);
        boolean en = true;
        int thisAnim = anim;
        if (thisAnim >= enabled.length) thisAnim = 0;
        if (enabled.length > 0 && enabled[thisAnim].used)
          en = enabled[thisAnim].getValue(time) != 0;
        if (en) {
          for (int i = 0; i < spawnCount; i++) {
            Particle p;
            if (emitterType == 1)
              p = PlaneEmitter.newParticle(this, anim, time, w, l, speed, var, spread, spread2);
            else p = SphereEmitter.newParticle(this, anim, time, w, l, speed, var, spread, spread2);
            particles.add(p);
          }
        }
      }
    }
    float speed = 1.0F;
    Vec3 t1 = new Vec3();
    Vec3 t2 = new Vec3();
    Vec3 t3 = new Vec3();
    Point4f d = new Point4f();
    Point4f c[] = new Point4f[3];
    for (int i = 0; i < 3; i++) c[i] = new Point4f();

    for (int i = 0; i < particles.size(); ) {
      Particle p = (Particle) particles.get(i);
      p.speed.add(
          Vec3.sub(Vec3.scale(p.down, grav * dt, t1), Vec3.scale(p.dir, deaccel * dt, t2), t3));
      if (slowdown > 0.0F) speed = (float) Math.exp(-1F * slowdown * p.life);
      p.pos.add(Vec3.scale(p.speed, speed * dt, t1));
      p.life += dt;
      float lifePos = p.life / p.maxLife;
      float s1 = size.data[0].x;
      float s2 = 0.0F;
      float s3 = 0.0F;
      if (size.data.length > 1) s2 = size.data[1].x;
      else s2 = s1;
      if (size.data.length > 2) s3 = size.data[2].x;
      else s3 = s2;
      p.size = lifeInterp(lifePos, 0.5F, s1 * scale.x, s2 * scale.y, s3 * scale.z);
      int limit = Math.min(3, color.data.length);
      for (int j = 0; j < limit; j++) {
        Point3f t = color.data[j];
        c[j].set(t.x / 255F, t.y / 255F, t.z / 255F, (float) transparency.data[j] / 32767F);
      }

      if (limit < 3) {
        Point3f t = color.data[limit - 1];
        for (int j = limit - 1; j < 3; j++)
          c[j].set(t.x / 255F, t.y / 255F, t.z / 255F, (float) transparency.data[j] / 32767F);
      }
      lifeInterp(lifePos, 0.5F, c[0], c[1], c[2], d);
      p.color.set(d);
      if (lifePos >= 1.0F) particles.remove(i);
      else i++;
    }
  }