コード例 #1
0
ファイル: cogl-matrix-stack.c プロジェクト: rib/cogl
CoglBool
cogl_matrix_stack_get_inverse (CoglMatrixStack *stack,
                                CoglMatrix *inverse)
{
  CoglMatrix matrix;
  CoglMatrix *internal = cogl_matrix_stack_get (stack, &matrix);

  if (internal)
    return cogl_matrix_get_inverse (internal, inverse);
  else
    return cogl_matrix_get_inverse (&matrix, inverse);
}
コード例 #2
0
ファイル: rig-renderer.c プロジェクト: sanyaade-mobiledev/rig
void
rig_camera_update_view (RigEngine *engine, RutEntity *camera, CoglBool shadow_pass)
{
  RutCamera *camera_component =
    rut_entity_get_component (camera, RUT_COMPONENT_TYPE_CAMERA);
  CoglMatrix transform;
  CoglMatrix inverse_transform;
  CoglMatrix view;

  /* translate to z_2d and scale */
  if (!shadow_pass)
    view = engine->main_view;
  else
    view = engine->identity;

  /* apply the camera viewing transform */
  rut_graphable_get_transform (camera, &transform);
  cogl_matrix_get_inverse (&transform, &inverse_transform);
  cogl_matrix_multiply (&view, &view, &inverse_transform);

  if (shadow_pass)
    {
      CoglMatrix flipped_view;
      cogl_matrix_init_identity (&flipped_view);
      cogl_matrix_scale (&flipped_view, 1, -1, 1);
      cogl_matrix_multiply (&flipped_view, &flipped_view, &view);
      rut_camera_set_view_transform (camera_component, &flipped_view);
    }
  else
    rut_camera_set_view_transform (camera_component, &view);
}
コード例 #3
0
ファイル: rig-renderer.c プロジェクト: sanyaade-mobiledev/rig
static void
get_light_modelviewprojection (const CoglMatrix *model_transform,
                               RutEntity  *light,
                               const CoglMatrix *light_projection,
                               CoglMatrix *light_mvp)
{
  const CoglMatrix *light_transform;
  CoglMatrix light_view;

  /* TODO: cache the bias * light_projection * light_view matrix! */

  /* Move the unit engine from [-1,1] to [0,1], column major order */
  float bias[16] = {
    .5f, .0f, .0f, .0f,
    .0f, .5f, .0f, .0f,
    .0f, .0f, .5f, .0f,
    .5f, .5f, .5f, 1.f
  };

  light_transform = rut_entity_get_transform (light);
  cogl_matrix_get_inverse (light_transform, &light_view);

  cogl_matrix_init_from_array (light_mvp, bias);
  cogl_matrix_multiply (light_mvp, light_mvp, light_projection);
  cogl_matrix_multiply (light_mvp, light_mvp, &light_view);

  cogl_matrix_multiply (light_mvp, light_mvp, model_transform);
}
コード例 #4
0
ファイル: cogl-matrix-stack.c プロジェクト: nobled/clutter
gboolean
_cogl_matrix_stack_get_inverse (CoglMatrixStack *stack,
                                CoglMatrix      *inverse)
{
  CoglMatrixState *state;

  state = _cogl_matrix_stack_top_mutable (stack, TRUE);

  return cogl_matrix_get_inverse (&state->matrix, inverse);
}
コード例 #5
0
ファイル: rut-camera.c プロジェクト: cee1/rig
const CoglMatrix *
rut_camera_get_inverse_view_transform (RutCamera *camera)
{
  if (camera->inverse_view_age == camera->view_age)
    return &camera->inverse_view;

  if (!cogl_matrix_get_inverse (&camera->view,
                                &camera->inverse_view))
    return NULL;

  camera->inverse_view_age = camera->view_age;
  return &camera->inverse_view;
}
コード例 #6
0
ファイル: rut-camera.c プロジェクト: cee1/rig
const CoglMatrix *
rut_camera_get_inverse_projection (RutCamera *camera)
{
  const CoglMatrix *projection;

  if (camera->inverse_projection_age == camera->projection_age)
    return &camera->inverse_projection;

  projection = rut_camera_get_projection (camera);

  if (!cogl_matrix_get_inverse (projection,
                                &camera->inverse_projection))
    return NULL;

  camera->inverse_projection_age = camera->projection_age;
  return &camera->inverse_projection;
}
コード例 #7
0
ファイル: rut-button.c プロジェクト: cee1/rig
static RutInputEventStatus
_rut_button_input_cb (RutInputRegion *region,
                      RutInputEvent *event,
                      void *user_data)
{
  RutButton *button = user_data;

  if(rut_input_event_get_type (event) == RUT_INPUT_EVENT_TYPE_MOTION &&
     rut_motion_event_get_action (event) == RUT_MOTION_EVENT_ACTION_DOWN)
    {
      RutShell *shell = button->ctx->shell;
      ButtonGrabState *state = g_slice_new (ButtonGrabState);
      const CoglMatrix *view;

      state->button = button;
      state->camera = rut_input_event_get_camera (event);
      view = rut_camera_get_view_transform (state->camera);
      state->transform = *view;
      rut_graphable_apply_transform (button, &state->transform);
      if (!cogl_matrix_get_inverse (&state->transform,
                                    &state->inverse_transform))
        {
          g_warning ("Failed to calculate inverse of button transform\n");
          g_slice_free (ButtonGrabState, state);
          return RUT_INPUT_EVENT_STATUS_UNHANDLED;
        }

      rut_shell_grab_input (shell,
                            state->camera,
                            _rut_button_grab_input_cb,
                            state);
      //button->grab_x = rut_motion_event_get_x (event);
      //button->grab_y = rut_motion_event_get_y (event);

      button->state = BUTTON_STATE_ACTIVE;
      rut_shell_queue_redraw (button->ctx->shell);

      return RUT_INPUT_EVENT_STATUS_HANDLED;
    }

  return RUT_INPUT_EVENT_STATUS_UNHANDLED;
}
コード例 #8
0
ファイル: mash-light.c プロジェクト: clutter-project/mash
/**
 * mash_light_set_direction_uniform:
 * @light: The #MashLight which is generating the shader
 * @uniform_location: The location of the uniform
 * @direction_in: The untransformed direction uniform
 *
 * This is a convenience intended to be used within
 * mash_light_update_uniforms() to help set uniforms. It
 * should not generally need to be called by an application unless it
 * is implementing its own lighting algorithms.
 *
 * This is intended to help when setting a direction
 * uniform. @direction_in should be an untransformed array of 3 floats
 * representing a vector. The vector will be transformed into eye
 * space according to the inverse transposed matrix of @light so that
 * it won't change direction for non-uniform scaling transformations.
 */
void
mash_light_set_direction_uniform (MashLight *light,
                                  CoglHandle program,
                                  int uniform_location,
                                  const float *direction_in)
{
  float light_direction[4];
  CoglMatrix matrix, inverse_matrix;
  float magnitude;

  memcpy (light_direction, direction_in, sizeof (light_direction));

  mash_light_get_modelview_matrix (light, &matrix);

  /* To safely transform the direction when the matrix might not be
     orthogonal we need the transposed inverse matrix */

  cogl_matrix_get_inverse (&matrix, &inverse_matrix);
  transpose_matrix (&inverse_matrix, &matrix);

  cogl_matrix_transform_point (&matrix,
                               light_direction + 0,
                               light_direction + 1,
                               light_direction + 2,
                               light_direction + 3);

  /* Normalize the light direction */
  magnitude = sqrtf ((light_direction[0] * light_direction[0])
                     + (light_direction[1] * light_direction[1])
                     + (light_direction[2] * light_direction[2]));
  light_direction[0] /= magnitude;
  light_direction[1] /= magnitude;
  light_direction[2] /= magnitude;

  cogl_program_set_uniform_float (program,
                                  uniform_location,
                                  3, 1,
                                  light_direction);
}
コード例 #9
0
ファイル: rig-renderer.c プロジェクト: sanyaade-mobiledev/rig
static void
get_normal_matrix (const CoglMatrix *matrix,
                   float *normal_matrix)
{
  CoglMatrix inverse_matrix;

  /* Invert the matrix */
  cogl_matrix_get_inverse (matrix, &inverse_matrix);

  /* Transpose it while converting it to 3x3 */
  normal_matrix[0] = inverse_matrix.xx;
  normal_matrix[1] = inverse_matrix.xy;
  normal_matrix[2] = inverse_matrix.xz;

  normal_matrix[3] = inverse_matrix.yx;
  normal_matrix[4] = inverse_matrix.yy;
  normal_matrix[5] = inverse_matrix.yz;

  normal_matrix[6] = inverse_matrix.zx;
  normal_matrix[7] = inverse_matrix.zy;
  normal_matrix[8] = inverse_matrix.zz;
}
コード例 #10
0
ファイル: rig-selection-tool.c プロジェクト: cee1/rig
bool
map_window_coords_to_overlay_coord (RutCamera *camera, /* 2d ui camera */
                                    RutObject *overlay, /* camera-view overlay */
                                    float *x,
                                    float *y)
{
  CoglMatrix transform;
  CoglMatrix inverse_transform;

  rut_graphable_get_modelview (overlay, camera, &transform);

  if (!cogl_matrix_get_inverse (&transform, &inverse_transform))
    return FALSE;

  rut_camera_unproject_coord (camera,
                              &transform,
                              &inverse_transform,
                              0, /* object_coord_z */
                              x,
                              y);

  return TRUE;
}
コード例 #11
0
ファイル: clutter-util.c プロジェクト: collinss/muffin
/*< private >
 * clutter_util_matrix_decompose:
 * @src: the matrix to decompose
 * @scale_p: (out caller-allocates): return location for a vertex containing
 *   the scaling factors
 * @shear_p: (out) (array length=3): return location for an array of 3
 *   elements containing the skew factors (XY, XZ, and YZ respectively)
 * @rotate_p: (out caller-allocates): return location for a vertex containing
 *   the Euler angles
 * @translate_p: (out caller-allocates): return location for a vertex
 *   containing the translation vector
 * @perspective_p: (out caller-allocates: return location for a 4D vertex
 *   containing the perspective
 *
 * Decomposes a #ClutterMatrix into the transformations that compose it.
 *
 * This code is based on the matrix decomposition algorithm as published in
 * the CSS Transforms specification by the W3C CSS working group, available
 * at http://www.w3.org/TR/css3-transforms/.
 *
 * The algorithm, in turn, is based on the "unmatrix" method published in
 * "Graphics Gems II, edited by Jim Arvo", which is available at:
 * http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c
 *
 * Return value: %TRUE if the decomposition was successful, and %FALSE
 *   if the matrix is singular
 */
gboolean
_clutter_util_matrix_decompose (const ClutterMatrix *src,
                                ClutterVertex       *scale_p,
                                float                shear_p[3],
                                ClutterVertex       *rotate_p,
                                ClutterVertex       *translate_p,
                                ClutterVertex4      *perspective_p)
{
  CoglMatrix matrix = *src;
  CoglMatrix perspective;
  ClutterVertex4 vertex_tmp;
  ClutterVertex row[3], pdum;
  int i, j;

#define XY_SHEAR        0
#define XZ_SHEAR        1
#define YZ_SHEAR        2
#define MAT(m,r,c)      ((float *)(m))[(c) * 4 + (r)]

  /* normalize the matrix */
  if (matrix.ww == 0.f)
    return FALSE;

  for (i = 0; i < 4; i++)
    {
      for (j = 0; j < 4; j++)
        {
          MAT (&matrix, j, i) /= MAT (&matrix, 3, 3);
        }
    }

  /* perspective is used to solve for perspective, but it also provides
   * an easy way to test for singularity of the upper 3x3 component
   */
  perspective = matrix;

  /* transpose */
  MAT (&perspective, 3, 0) = 0.f;
  MAT (&perspective, 3, 1) = 0.f;
  MAT (&perspective, 3, 2) = 0.f;
  MAT (&perspective, 3, 3) = 1.f;

  if (_clutter_util_matrix_determinant (&perspective) == 0.f)
    return FALSE;

  if (MAT (&matrix, 3, 0) != 0.f ||
      MAT (&matrix, 3, 1) != 0.f ||
      MAT (&matrix, 3, 2) != 0.f)
    {
      CoglMatrix perspective_inv;
      ClutterVertex4 p;

      vertex_tmp.x = MAT (&matrix, 3, 0);
      vertex_tmp.y = MAT (&matrix, 3, 1);
      vertex_tmp.z = MAT (&matrix, 3, 2);
      vertex_tmp.w = MAT (&matrix, 3, 3);

      /* solve the equation by inverting perspective... */
      cogl_matrix_get_inverse (&perspective, &perspective_inv);

      /* ... and multiplying vertex_tmp by the inverse */
      _clutter_util_matrix_transpose_vector4_transform (&perspective_inv,
                                                        &vertex_tmp,
                                                        &p);

      *perspective_p = p;

      /* clear the perspective part */
      MAT (&matrix, 3, 0) = 0.0f;
      MAT (&matrix, 3, 1) = 0.0f;
      MAT (&matrix, 3, 2) = 0.0f;
      MAT (&matrix, 3, 3) = 1.0f;
    }
  else
    {
      /* no perspective */
      perspective_p->x = 0.0f;
      perspective_p->y = 0.0f;
      perspective_p->z = 0.0f;
      perspective_p->w = 1.0f;
    }

  /* translation */
  translate_p->x = MAT (&matrix, 0, 3);
  MAT (&matrix, 0, 3) = 0.f;
  translate_p->y = MAT (&matrix, 1, 3);
  MAT (&matrix, 1, 3) = 0.f;
  translate_p->z = MAT (&matrix, 2, 3);
  MAT (&matrix, 2, 3) = 0.f;

  /* scale and shear; we split the upper 3x3 matrix into rows */
  for (i = 0; i < 3; i++)
    {
      row[i].x = MAT (&matrix, i, 0);
      row[i].y = MAT (&matrix, i, 1);
      row[i].z = MAT (&matrix, i, 2);
    }

  /* compute scale.x and normalize the first row */
  scale_p->x = _clutter_util_vertex_length (&row[0]);
  _clutter_util_vertex_normalize (&row[0]);

  /* compute XY shear and make the second row orthogonal to the first */
  shear_p[XY_SHEAR] = _clutter_util_vertex_dot (&row[0], &row[1]);
  _clutter_util_vertex_combine (&row[1], &row[0],
                                1.0, -shear_p[XY_SHEAR],
                                &row[1]);

  /* compute the Y scale and normalize the second row */
  scale_p->y = _clutter_util_vertex_length (&row[1]);
  _clutter_util_vertex_normalize (&row[1]);
  shear_p[XY_SHEAR] /= scale_p->y;

  /* compute XZ and YZ shears, orthogonalize the third row */
  shear_p[XZ_SHEAR] = _clutter_util_vertex_dot (&row[0], &row[2]);
  _clutter_util_vertex_combine (&row[2], &row[0],
                                1.0, -shear_p[XZ_SHEAR],
                                &row[2]);

  shear_p[YZ_SHEAR] = _clutter_util_vertex_dot (&row[1], &row[2]);
  _clutter_util_vertex_combine (&row[2], &row[1],
                                1.0, -shear_p[YZ_SHEAR],
                                &row[2]);

  /* get the Z scale and normalize the third row*/
  scale_p->z = _clutter_util_vertex_length (&row[2]);
  _clutter_util_vertex_normalize (&row[2]);
  shear_p[XZ_SHEAR] /= scale_p->z;
  shear_p[YZ_SHEAR] /= scale_p->z;

  /* at this point, the matrix (inside row[]) is orthonormal.
   * check for a coordinate system flip; if the determinant
   * is -1, then negate the matrix and scaling factors
   */
  _clutter_util_vertex_cross (&row[1], &row[2], &pdum);
  if (_clutter_util_vertex_dot (&row[0], &pdum) < 0.f)
    {
      scale_p->x *= -1.f;

      for (i = 0; i < 3; i++)
        {
          row[i].x *= -1.f;
          row[i].y *= -1.f;
          row[i].z *= -1.f;
        }
    }

  /* now get the rotations out */
  rotate_p->y = asinf (-row[0].z);
  if (cosf (rotate_p->y) != 0.f)
    {
      rotate_p->x = atan2f (row[1].z, row[2].z);
      rotate_p->z = atan2f (row[0].y, row[0].x);
    }
  else
    {
      rotate_p->x = atan2f (-row[2].x, row[1].y);
      rotate_p->z = 0.f;
    }

#undef XY_SHEAR
#undef XZ_SHEAR
#undef YZ_SHEAR
#undef MAT

  return TRUE;
}