mutter/cogl/cogl-vector.h
Robert Bragg fa22ee0e8d math: Adds an experimental cogl_vector3_* API
This adds a math utility API for handling 3 component, single precision
float vectors with the following; mostly self explanatory functions:

cogl_vector3_init
cogl_vector3_init_zero
cogl_vector3_equal
cogl_vector3_equal_with_epsilon
cogl_vector3_copy
cogl_vector3_free
cogl_vector3_invert
cogl_vector3_add
cogl_vector3_subtract
cogl_vector3_multiply_scalar
cogl_vector3_divide_scalar
cogl_vector3_normalize
cogl_vector3_magnitude
cogl_vector3_cross_product
cogl_vector3_dot_product
cogl_vector3_distance

Since the API is experimental you will need to define
COGL_ENABLE_EXPERIMENTAL_API before including cogl.h if you want to use
the API.
2010-05-20 17:18:24 +01:00

368 lines
9.7 KiB
C

/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2008,2009,2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors:
* Robert Bragg <robert@linux.intel.com>
*/
#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cogl/cogl.h> can be included directly."
#endif
#ifndef __COGL_VECTOR_H
#define __COGL_VECTOR_H
#include <glib.h>
G_BEGIN_DECLS
/**
* SECTION:cogl-vector
* @short_description: Functions for handling single precision float
* vectors.
*
* This exposes a utility API that can be used for basic manipulation of 3
* component float vectors.
*/
typedef struct
{
/* FIXME: add sse alignment constraint? */
float x;
float y;
float z;
} CoglVector3;
#if 0
typedef struct
{
/* FIXME: add sse alignment constraint? */
float x;
float y;
float z;
float w;
} CoglVector4;
#endif
/**
* cogl_vector3_init:
* @vector: The CoglVector3 you want to initialize
* @x: The x component
* @y: The y component
* @z: The z component
*
* Initializes a 3 component, single precision float vector which can
* then be manipulated with the cogl_vector convenience APIs. Vectors
* can also be used in places where a "point" is often desired.
*
* Since: 1.4
* Stability: Unstable
*/
void
cogl_vector3_init (CoglVector3 *vector, float x, float y, float z);
/**
* cogl_vector3_init_zero:
* @vector: The CoglVector3 you want to initialize
*
* Initializes a 3 component, single precision float vector with zero
* for each component.
*
* Since: 1.4
* Stability: Unstable
*/
void
cogl_vector3_init_zero (CoglVector3 *vector);
/**
* cogl_vector3_equal:
* @v1: The first CoglVector3 you want to compare
* @v2: The second CoglVector3 you want to compare
*
* Compares the components of two vectors and returns TRUE if they are
* the same.
*
* The comparison of the components is done with the '==' operator
* such that -0 is considered equal to 0, but otherwise there is no
* fuzziness such as an epsilon to consider vectors that are
* essentially identical except for some minor precision error
* differences due to the way they have been manipulated.
*
* Returns: TRUE if the vectors are equal else FALSE.
*
* Since: 1.4
* Stability: Unstable
*/
gboolean
cogl_vector3_equal (gconstpointer v1, gconstpointer v2);
/**
* cogl_vector3_equal_with_epsilon:
* @vector0: The first CoglVector3 you want to compare
* @vector1: The second CoglVector3 you want to compare
* @epsilon: The allowable difference between components to still be
* considered equal
*
* Compares the components of two vectors using the given epsilon and
* returns TRUE if they are the same, using an internal epsilon for
* comparing the floats.
*
* Each component is compared against the epsilon value in this way:
* |[
* if (fabsf (vector0->x - vector1->x) < epsilon)
* ]|
*
* Returns: TRUE if the vectors are equal else FALSE.
*
* Since: 1.4
* Stability: Unstable
*/
gboolean
cogl_vector3_equal_with_epsilon (const CoglVector3 *vector0,
const CoglVector3 *vector1,
float epsilon);
/**
* cogl_vector3_copy:
* @vector: The CoglVector3 you want to copy
*
* Allocates a new #CoglVector3 structure on the heap initializing the
* components from the given @vector and returns a pointer to the newly
* allocated vector. You should free the memory using
* cogl_vector3_free()
*
* Returns: A newly allocated #CoglVector3.
*
* Since: 1.4
* Stability: Unstable
*/
CoglVector3 *
cogl_vector3_copy (const CoglVector3 *vector);
/**
* cogl_vector3_free:
* @vector: The CoglVector3 you want to free
*
* Frees a #CoglVector3 that was previously allocated with
* cogl_vector_copy()
*
* Since: 1.4
* Stability: Unstable
*/
void
cogl_vector3_free (CoglVector3 *vector);
/**
* cogl_vector3_invert:
* @vector: The CoglVector3 you want to manipulate
*
* Inverts/negates all the components of the given @vector.
*
* Since: 1.4
* Stability: Unstable
*/
void
cogl_vector3_invert (CoglVector3 *vector);
/**
* cogl_vector3_add:
* @result: Where you want the result written
* @a: The first vector operand
* @b: The second vector operand
*
* Adds each of the corresponding components in vectors @a and @b
* storing the results in @result.
*
* Since: 1.4
* Stability: Unstable
*/
void
cogl_vector3_add (CoglVector3 *result,
const CoglVector3 *a,
const CoglVector3 *b);
/**
* cogl_vector3_subtract:
* @result: Where you want the result written
* @a: The first vector operand
* @b: The second vector operand
*
* Subtracts each of the corresponding components in vector @b from
* @a storing the results in @result.
*
* Since: 1.4
* Stability: Unstable
*/
void
cogl_vector3_subtract (CoglVector3 *result,
const CoglVector3 *a,
const CoglVector3 *b);
/**
* cogl_vector3_multiply_scalar:
* @vector: The CoglVector3 you want to manipulate
* @scalar: The scalar you want to multiply the vector components by
*
* Multiplies each of the @vector components by the given scalar.
*
* Since: 1.4
* Stability: Unstable
*/
void
cogl_vector3_multiply_scalar (CoglVector3 *vector,
float scalar);
/**
* cogl_vector3_divide_scalar:
* @vector: The CoglVector3 you want to manipulate
* @scalar: The scalar you want to divide the vector components by
*
* Divides each of the @vector components by the given scalar.
*
* Since: 1.4
* Stability: Unstable
*/
void
cogl_vector3_divide_scalar (CoglVector3 *vector,
float scalar);
/**
* cogl_vector3_normalize:
* @vector: The CoglVector3 you want to manipulate
*
* Updates the vector so it is a "unit vector" such that the
* @vector<!-- -->s magnitude or length is equal to 1.
*
* Since: 1.4
* Stability: Unstable
*/
void
cogl_vector3_normalize (CoglVector3 *vector);
/**
* cogl_vector3_magnitude:
* @vector: The CoglVector3 you want the magnitude for
*
* Calculates the scalar magnitude or length of @vector.
*
* Returns: The magnitude of @vector.
*
* Since: 1.4
* Stability: Unstable
*/
float
cogl_vector3_magnitude (const CoglVector3 *vector);
/**
* cogl_vector3_cross_product:
* @result: Where you want the result written
* @u: Your first CoglVector3
* @v: Your second CoglVector3
*
* Calculates the cross product between the two vectors @u and @v.
*
* The cross product is a vector perpendicular to both @u and @v. This
* can be useful for calculating the normal of a polygon by creating
* two vectors in its plane using the polygons vertices and taking
* their cross product.
*
* If the two vectors are parallel then the cross product is 0.
*
* You can use a right hand rule to determine which direction the
* perpendicular vector will point: If you place the two vectors tail,
* to tail and imagine grabbing the perpendicular line that extends
* through the common tail with your right hand such that you fingers
* rotate in the direction from @u to @v then the resulting vector
* points along your extended thumb.
*
* Returns: The cross product between two vectors @u and @v.
*
* Since: 1.4
* Stability: Unstable
*/
void
cogl_vector3_cross_product (CoglVector3 *result,
const CoglVector3 *u,
const CoglVector3 *v);
/**
* cogl_vector3_dot_product:
* @a: Your first CoglVector3
* @b: Your second CoglVector3
*
* Calculates the dot product of the two #CoglVector3<!-- -->s. This
* can be used to determine the magnitude of one vector projected onto
* another. (for example a surface normal)
*
* For example if you have a polygon with a given normal vector and
* some other point for which you want to calculate its distance from
* the polygon, you can create a vector between one of the polygon
* vertices and that point and use the dot product to calculate the
* magnitude for that vector but projected onto the normal of the
* polygon. This way you don't just get the distance from the point to
* the edge of the polygon you get the distance from the point to the
* nearest part of the polygon.
*
* <note>If you don't use a unit length normal in the above example
* then you would then also have to divide the result by the magnitude
* of the normal</note>
*
* The dot product is calculated as:
* |[
* (a->x * b->x + a->y * b->y + a->z * b->z)
* ]|
*
* For reference, the dot product can also be calculated from the
* angle between two vectors as:
* |[
* |a||b|cos𝜃
* ]|
*
* Returns: The dot product of two vectors.
*
* Since: 1.4
* Stability: Unstable
*/
float
cogl_vector3_dot_product (const CoglVector3 *a, const CoglVector3 *b);
/**
* cogl_vector3_distance:
* @a: The first point
* @b: The second point
*
* If you consider the two given vectors as (x,y,z) points instead
* then this will compute the distance between those two points.
*
* Returns: The distance between two points given as @CoglVector3<!-- -->s
*
* Since: 1.4
* Stability: Unstable
*/
float
cogl_vector3_distance (const CoglVector3 *a, const CoglVector3 *b);
G_END_DECLS
#endif /* __COGL_VECTOR_H */