Example #1
0
pl_system_t*
pl_new_root_system(pl_world_t *world, const char *name, double m,
                   double gm, double obliquity, double siderealPeriod,
                   double eqRadius, double flattening)
{
  assert(world);

  pl_system_t *sys = smalloc(sizeof(pl_system_t));
  obj_array_init(&sys->orbits);
  obj_array_init(&sys->astroObjs);
  obj_array_init(&sys->rigidObjs);

  sys->name = strdup(name);
  sys->world = world;
  sys->parent = NULL;

  lwcoord_t p;
  lwc_set(&p, 0.0, 0.0, 0.0);
  quaternion_t q = q_rot(1.0, 0.0, 0.0, DEG_TO_RAD(obliquity));

  sys->orbitalBody = pl_new_obj(world, name, m, gm, &p, q, siderealPeriod, obliquity,
                              eqRadius, flattening);
  sys->orbitalBody->kepler = NULL;

  world->rootSys = sys;
  pl_sys_set_current_pos(sys);
  return sys;
}
Example #2
0
static float sol_test_body(float dt,
                           float T[3], float V[3],
                           const struct v_ball *up,
                           const struct s_vary *vary,
                           const struct v_body *bp)
{
    float U[3], O[3], E[4], W[3], u;

    const struct b_node *np = vary->base->nv + bp->base->ni;

    sol_body_p(O, vary, bp, 0.0f);
    sol_body_v(W, vary, bp, dt);
    sol_body_e(E, vary, bp, 0.0f);

    /*
     * For rotating bodies, rather than rotate every normal and vertex
     * of the body, we temporarily pretend the ball is rotating and
     * moving about a static body.
     */

    /*
     * Linear velocity of a point rotating about the origin:
     * v = w x p
     */

    if (E[0] != 1.0f || sol_body_w(vary, bp))
    {
        /* The body has a non-identity orientation or it is rotating. */

        struct v_ball ball;
        float e[4], p0[3], p1[3];
        const float z[3] = { 0 };

        /* First, calculate position at start and end of time interval. */

        v_sub(p0, up->p, O);
        v_cpy(p1, p0);
        q_conj(e, E);
        q_rot(p0, e, p0);

        v_mad(p1, p1, up->v, dt);
        v_mad(p1, p1, W, -dt);
        sol_body_e(e, vary, bp, dt);
        q_conj(e, e);
        q_rot(p1, e, p1);

        /* Set up ball struct with values relative to body. */

        ball = *up;

        v_cpy(ball.p, p0);

        /* Calculate velocity from start/end positions and time. */

        v_sub(ball.v, p1, p0);
        v_scl(ball.v, ball.v, 1.0f / dt);

        if ((u = sol_test_node(dt, U, &ball, vary->base, np, z, z)) < dt)
        {
            /* Compute the final orientation. */

            sol_body_e(e, vary, bp, u);

            /* Return world space coordinates. */

            q_rot(T, e, U);
            v_add(T, O, T);

            /* Move forward. */

            v_mad(T, T, W, u);

            /* Express "non-ball" velocity. */

            q_rot(V, e, ball.v);
            v_sub(V, up->v, V);

            dt = u;
        }
    }
    else
    {
        if ((u = sol_test_node(dt, U, up, vary->base, np, O, W)) < dt)
        {
            v_cpy(T, U);
            v_cpy(V, W);
            dt = u;
        }
    }
    return dt;
}