cogl/matrix: Move inverse calculation to cogl-graphene.c
This special precision-bearing calculation will be used in other places, so better share them all here. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1439
This commit is contained in:
parent
3e0c961b76
commit
db23ee5829
@ -3166,7 +3166,8 @@ ensure_valid_actor_transform (ClutterActor *actor)
|
|||||||
|
|
||||||
CLUTTER_ACTOR_GET_CLASS (actor)->apply_transform (actor, &priv->transform);
|
CLUTTER_ACTOR_GET_CLASS (actor)->apply_transform (actor, &priv->transform);
|
||||||
priv->has_inverse_transform =
|
priv->has_inverse_transform =
|
||||||
cogl_matrix_get_inverse (&priv->transform, &priv->inverse_transform);
|
cogl_graphene_matrix_get_inverse (&priv->transform,
|
||||||
|
&priv->inverse_transform);
|
||||||
|
|
||||||
priv->transform_valid = TRUE;
|
priv->transform_valid = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2070,8 +2070,8 @@ clutter_stage_set_perspective (ClutterStage *stage,
|
|||||||
priv->perspective.aspect,
|
priv->perspective.aspect,
|
||||||
priv->perspective.z_near,
|
priv->perspective.z_near,
|
||||||
priv->perspective.z_far);
|
priv->perspective.z_far);
|
||||||
cogl_matrix_get_inverse (&priv->projection,
|
cogl_graphene_matrix_get_inverse (&priv->projection,
|
||||||
&priv->inverse_projection);
|
&priv->inverse_projection);
|
||||||
|
|
||||||
_clutter_stage_dirty_projection (stage);
|
_clutter_stage_dirty_projection (stage);
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||||
|
@ -274,3 +274,38 @@ cogl_graphene_matrix_project_points (const graphene_matrix_t *matrix,
|
|||||||
n_points);
|
n_points);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
cogl_graphene_matrix_get_inverse (const graphene_matrix_t *matrix,
|
||||||
|
graphene_matrix_t *inverse)
|
||||||
|
{
|
||||||
|
graphene_matrix_t scaled;
|
||||||
|
graphene_matrix_t m;
|
||||||
|
gboolean invertible;
|
||||||
|
float pivot = G_MAXFLOAT;
|
||||||
|
float v[16];
|
||||||
|
float scale;
|
||||||
|
|
||||||
|
graphene_matrix_init_from_matrix (&m, matrix);
|
||||||
|
graphene_matrix_to_float (&m, v);
|
||||||
|
|
||||||
|
pivot = MIN (pivot, v[0]);
|
||||||
|
pivot = MIN (pivot, v[5]);
|
||||||
|
pivot = MIN (pivot, v[10]);
|
||||||
|
pivot = MIN (pivot, v[15]);
|
||||||
|
scale = 1.f / pivot;
|
||||||
|
|
||||||
|
graphene_matrix_init_scale (&scaled, scale, scale, scale);
|
||||||
|
|
||||||
|
/* Float precision is a limiting factor */
|
||||||
|
graphene_matrix_multiply (&m, &scaled, &m);
|
||||||
|
|
||||||
|
invertible = graphene_matrix_inverse (&m, inverse);
|
||||||
|
|
||||||
|
if (invertible)
|
||||||
|
graphene_matrix_multiply (&scaled, inverse, inverse);
|
||||||
|
else
|
||||||
|
graphene_matrix_init_identity (inverse);
|
||||||
|
|
||||||
|
return invertible;
|
||||||
|
}
|
||||||
|
@ -163,6 +163,21 @@ cogl_graphene_matrix_project_points (const graphene_matrix_t *matrix,
|
|||||||
void *points_out,
|
void *points_out,
|
||||||
int n_points);
|
int n_points);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_graphene_matrix_get_inverse:
|
||||||
|
* @matrix: A 4x4 transformation matrix
|
||||||
|
* @inverse: (out): The destination for a 4x4 inverse transformation matrix
|
||||||
|
*
|
||||||
|
* Gets the inverse transform of a given matrix and uses it to initialize
|
||||||
|
* a new #graphene_matrix_t.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the inverse was successfully calculated or %FALSE
|
||||||
|
* for degenerate transformations that can't be inverted (in this case the
|
||||||
|
* @inverse matrix will simply be initialized with the identity matrix)
|
||||||
|
*/
|
||||||
|
COGL_EXPORT gboolean
|
||||||
|
cogl_graphene_matrix_get_inverse (const graphene_matrix_t *matrix,
|
||||||
|
graphene_matrix_t *inverse);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "cogl-config.h"
|
#include "cogl-config.h"
|
||||||
|
|
||||||
#include "cogl-context-private.h"
|
#include "cogl-context-private.h"
|
||||||
|
#include "cogl-graphene.h"
|
||||||
#include "cogl-matrix-stack.h"
|
#include "cogl-matrix-stack.h"
|
||||||
#include "cogl-framebuffer-private.h"
|
#include "cogl-framebuffer-private.h"
|
||||||
#include "cogl-object-private.h"
|
#include "cogl-object-private.h"
|
||||||
@ -411,9 +412,9 @@ cogl_matrix_stack_get_inverse (CoglMatrixStack *stack,
|
|||||||
graphene_matrix_t *internal = cogl_matrix_stack_get (stack, &matrix);
|
graphene_matrix_t *internal = cogl_matrix_stack_get (stack, &matrix);
|
||||||
|
|
||||||
if (internal)
|
if (internal)
|
||||||
return cogl_matrix_get_inverse (internal, inverse);
|
return cogl_graphene_matrix_get_inverse (internal, inverse);
|
||||||
else
|
else
|
||||||
return cogl_matrix_get_inverse (&matrix, inverse);
|
return cogl_graphene_matrix_get_inverse (&matrix, inverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In addition to writing the stack matrix into the give @matrix
|
/* In addition to writing the stack matrix into the give @matrix
|
||||||
|
@ -67,61 +67,6 @@ cogl_debug_matrix_print (const graphene_matrix_t *matrix)
|
|||||||
_cogl_matrix_prefix_print ("", matrix);
|
_cogl_matrix_prefix_print ("", matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Compute inverse of a transformation matrix.
|
|
||||||
*
|
|
||||||
* @mat pointer to a graphene_matrix_t structure. The matrix inverse will be
|
|
||||||
* stored in the graphene_matrix_t::inv attribute.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE for success, %FALSE for failure (\p singular matrix).
|
|
||||||
*
|
|
||||||
* Calls the matrix inversion function in inv_mat_tab corresponding to the
|
|
||||||
* given matrix type. In case of failure, updates the MAT_FLAG_SINGULAR flag,
|
|
||||||
* and copies the identity matrix into graphene_matrix_t::inv.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline gboolean
|
|
||||||
calculate_inverse (const graphene_matrix_t *matrix,
|
|
||||||
graphene_matrix_t *inverse)
|
|
||||||
{
|
|
||||||
graphene_matrix_t scaled;
|
|
||||||
graphene_matrix_t m;
|
|
||||||
gboolean invertible;
|
|
||||||
float pivot = G_MAXFLOAT;
|
|
||||||
float v[16];
|
|
||||||
float scale;
|
|
||||||
|
|
||||||
graphene_matrix_init_from_matrix (&m, matrix);
|
|
||||||
graphene_matrix_to_float (&m, v);
|
|
||||||
|
|
||||||
pivot = MIN (pivot, v[0]);
|
|
||||||
pivot = MIN (pivot, v[5]);
|
|
||||||
pivot = MIN (pivot, v[10]);
|
|
||||||
pivot = MIN (pivot, v[15]);
|
|
||||||
scale = 1.f / pivot;
|
|
||||||
|
|
||||||
graphene_matrix_init_scale (&scaled, scale, scale, scale);
|
|
||||||
|
|
||||||
/* Float precision is a limiting factor */
|
|
||||||
graphene_matrix_multiply (&m, &scaled, &m);
|
|
||||||
|
|
||||||
invertible = graphene_matrix_inverse (&m, inverse);
|
|
||||||
|
|
||||||
if (invertible)
|
|
||||||
graphene_matrix_multiply (&scaled, inverse, inverse);
|
|
||||||
else
|
|
||||||
graphene_matrix_init_identity (inverse);
|
|
||||||
|
|
||||||
return invertible;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
cogl_matrix_get_inverse (const graphene_matrix_t *matrix,
|
|
||||||
graphene_matrix_t *inverse)
|
|
||||||
{
|
|
||||||
return calculate_inverse (matrix, inverse);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_matrix_rotate (graphene_matrix_t *matrix,
|
cogl_matrix_rotate (graphene_matrix_t *matrix,
|
||||||
float angle,
|
float angle,
|
||||||
|
@ -485,24 +485,6 @@ cogl_matrix_copy (const graphene_matrix_t *matrix);
|
|||||||
COGL_EXPORT void
|
COGL_EXPORT void
|
||||||
cogl_matrix_free (graphene_matrix_t *matrix);
|
cogl_matrix_free (graphene_matrix_t *matrix);
|
||||||
|
|
||||||
/**
|
|
||||||
* cogl_matrix_get_inverse:
|
|
||||||
* @matrix: A 4x4 transformation matrix
|
|
||||||
* @inverse: (out): The destination for a 4x4 inverse transformation matrix
|
|
||||||
*
|
|
||||||
* Gets the inverse transform of a given matrix and uses it to initialize
|
|
||||||
* a new #graphene_matrix_t.
|
|
||||||
*
|
|
||||||
* Return value: %TRUE if the inverse was successfully calculated or %FALSE
|
|
||||||
* for degenerate transformations that can't be inverted (in this case the
|
|
||||||
* @inverse matrix will simply be initialized with the identity matrix)
|
|
||||||
*
|
|
||||||
* Since: 1.2
|
|
||||||
*/
|
|
||||||
COGL_EXPORT gboolean
|
|
||||||
cogl_matrix_get_inverse (const graphene_matrix_t *matrix,
|
|
||||||
graphene_matrix_t *inverse);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_matrix_is_identity:
|
* cogl_matrix_is_identity:
|
||||||
* @matrix: A #graphene_matrix_t
|
* @matrix: A #graphene_matrix_t
|
||||||
|
Loading…
x
Reference in New Issue
Block a user