예제 #1
0
void
plStepParticleSystem(PLparticles *ps, float dt)
{
  assert(ps != NULL);
  if (ps->enabled == false) return;

  size_t activeParticles = 0;
  for (size_t i = 0 ; i < ps->particleCount ; ++i) {
    if (ps->particles[i].active) {
      ps->particles[i].p += vf3_s_mul(ps->particles[i].v, dt) + vf3_s_mul(ps->obj->v, dt);
      ps->particles[i].age += dt;
      activeParticles++;

      if (ps->particles[i].age > ps->particles[i].lifeTime) {
        ps->particles[i].active = false;
        int_array_push(&ps->freeParticles, i);
        activeParticles --;
      }
    }
  }

  // Auto disable
  if (ps->autoDisable) {
    if (activeParticles == 0) {
      ps->enabled = false;
    }

    return;
  }

  // Not off or disabled, emitt new particles
  float newPartCount = ps->emissionRate * dt * (1.0 + rand_percent(10));
  float intPart;
  float frac = modff(newPartCount, &intPart);
  unsigned newParticles = (unsigned) intPart;

  // The fraction is handled with randomisation
  int rval = random() % 128;
  if ((float)rval/128.0f < frac) newParticles ++;

  for (unsigned i = 0 ; i < newParticles ; ++i) {
    if (ps->freeParticles.length > 0) {
      int i = int_array_remove(&ps->freeParticles, 0);
      ps->particles[i].active = true;
      ps->particles[i].age = 0.0;
      // Adjust lifetime by +-20 %
      ps->particles[i].lifeTime = ps->lifeTime + ps->lifeTime * rand_percent(20);
      ps->particles[i].p = v_q_rot(ps->p, ps->obj->q);
      ps->particles[i].v = v_q_rot(ps->v * vf3_set(rand_percent(10), rand_percent(10), rand_percent(10)), ps->obj->q);
      ps->particles[i].rgb = ps->rgb;
    } else {
      break;
    }
  }
}
예제 #2
0
파일: orbit.c 프로젝트: JohanOtto/openorbit
float3
pl_compute_gravity(pl_astrobody_t *a, pl_object_t *b)
{
  float3 dist = lwc_dist(&b->p, &a->obj.p);
  double r12 = vf3_abs_square(dist);
  float3 ndist = vf3_normalise(dist);
  float3 f12 = vf3_s_mul(ndist,
                         //-PL_G * (a->obj.m.m * b->m.m / r12));
                         -a->GM * b->m.m / r12);

  assert(isfinite(dist.x));
  assert(isfinite(dist.y));
  assert(isfinite(dist.z));

  assert(isfinite(ndist.x));
  assert(isfinite(ndist.y));
  assert(isfinite(ndist.z));

  assert(isfinite(r12));

  assert(isfinite(f12.x));
  assert(isfinite(f12.y));
  assert(isfinite(f12.z));

  return f12;
}
예제 #3
0
파일: orbit.c 프로젝트: JohanOtto/openorbit
void
pl_sys_update_current_pos(pl_system_t *sys, double dt)
{
  if (sys->parent) {
    double t = sim_time_get_jd();

    if (sys->orbitalBody->tUpdate > 0) {
      lwc_translate3fv(&sys->orbitalBody->obj.p,
                        vf3_s_mul(sys->orbitalBody->obj.v, dt));
      sys->orbitalBody->tUpdate --;
    } else {
      float3 newPos = plOrbitPosAtTime(sys->orbitalBody->kepler,
                                       sys->parent->orbitalBody->GM,
                                       t*PL_SEC_PER_DAY);

      float3 nextPos = plOrbitPosAtTime(sys->orbitalBody->kepler,
                                        sys->parent->orbitalBody->GM,
                                        t*PL_SEC_PER_DAY + (double)sys->orbitalBody->orbitFixationPeriod * dt);

      float3 vel = vf3_s_div(vf3_sub(nextPos, newPos),
                             (double)sys->orbitalBody->orbitFixationPeriod * dt);

      sys->orbitalBody->obj.p = sys->parent->orbitalBody->obj.p;
      lwc_translate3fv(&sys->orbitalBody->obj.p, newPos);

      sys->orbitalBody->obj.v = sys->parent->orbitalBody->obj.v + vel;
      // Reset tUpdate;
      sys->orbitalBody->tUpdate = sys->orbitalBody->orbitFixationPeriod;
    }
    sys->orbitalBody->obj.q = plSideralRotationAtTime(sys->orbitalBody, t);
  } else {
    lwc_set(&sys->orbitalBody->obj.p, 0.0, 0.0, 0.0);
  }
}
예제 #4
0
파일: mass.c 프로젝트: nforrester/openorbit
void
plMassRotateQ(PLmass *m, quaternion_t q)
{
  float3x3 mat;
  q_mf3_convert(mat, q);

  plMassRotateM(m, mat);
}


void
plMassAdd(PLmass * restrict md, const PLmass * restrict ms)
{
  float recip = 1.0f / (md->m + ms->m);

  float3 a = vf3_s_mul(md->cog, md->m);
  float3 b = vf3_s_mul(ms->cog, ms->m);
  float3 c = vf3_add(a, b);
  md->cog = vf3_s_mul(c, recip);

  md->m += ms->m;

  for (int i = 0 ; i < 3 ; ++ i) {
    md->I[i] = vf3_add(md->I[i], ms->I[i]);
  }
  mf3_inv2(md->I_inv, md->I);
}

void
plMassMod(PLmass *m, float newMass)
{