Math Lib Reorganization

* New header and source files.
* Still need a few tweaks before switching code to use them.
This commit is contained in:
2009-11-09 22:42:41 +00:00
parent 5935ef0049
commit 60ea745613
13 changed files with 6092 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: some of this file.
*
* ***** END GPL LICENSE BLOCK *****
* */
#ifndef BLI_MATH
#define BLI_MATH
/* Abbreviations:
*
* fl = float
* db = double
* v2 = vec2 = vector 2
* v3 = vec3 = vector 3
* v4 = vec4 = vector 4
* qt = quat = quaternion
* dq = dquat = dual quaternion
* m2 = mat2 = matrix 2x2
* m3 = mat3 = matrix 3x3
* m4 = mat4 = matrix 4x4
* eul = euler rotation
* eulO = euler with order
*
* Variable Names:
*
* f = single value
* a, b, c = vectors
* r = result vector
* A, B, C = matrices
* R = result matrix
*
*/
#include "BLI_math_base.h"
#include "BLI_math_color.h"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
#include "BLI_math_rotation.h"
#include "BLI_math_vector.h"
#endif /* BLI_MATH */

View File

@@ -0,0 +1,156 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: some of this file.
*
* ***** END GPL LICENSE BLOCK *****
* */
#ifndef BLI_MATH_BASE
#define BLI_MATH_BASE
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
#define _USE_MATH_DEFINES
#endif
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif
#ifndef M_SQRT2
#define M_SQRT2 1.41421356237309504880
#endif
#ifndef M_SQRT1_2
#define M_SQRT1_2 0.70710678118654752440
#endif
#ifndef M_1_PI
#define M_1_PI 0.318309886183790671538
#endif
#ifndef M_E
#define M_E 2.7182818284590452354
#endif
#ifndef M_LOG2E
#define M_LOG2E 1.4426950408889634074
#endif
#ifndef M_LOG10E
#define M_LOG10E 0.43429448190325182765
#endif
#ifndef M_LN2
#define M_LN2 0.69314718055994530942
#endif
#ifndef M_LN10
#define M_LN10 2.30258509299404568402
#endif
#ifndef sqrtf
#define sqrtf(a) ((float)sqrt(a))
#endif
#ifndef powf
#define powf(a, b) ((float)pow(a, b))
#endif
#ifndef cosf
#define cosf(a) ((float)cos(a))
#endif
#ifndef sinf
#define sinf(a) ((float)sin(a))
#endif
#ifndef acosf
#define acosf(a) ((float)acos(a))
#endif
#ifndef asinf
#define asinf(a) ((float)asin(a))
#endif
#ifndef atan2f
#define atan2f(a, b) ((float)atan2(a, b))
#endif
#ifndef tanf
#define tanf(a) ((float)tan(a))
#endif
#ifndef atanf
#define atanf(a) ((float)atan(a))
#endif
#ifndef floorf
#define floorf(a) ((float)floor(a))
#endif
#ifndef ceilf
#define ceilf(a) ((float)ceil(a))
#endif
#ifndef fabsf
#define fabsf(a) ((float)fabs(a))
#endif
#ifndef logf
#define logf(a) ((float)log(a))
#endif
#ifndef expf
#define expf(a) ((float)exp(a))
#endif
#ifndef fmodf
#define fmodf(a, b) ((float)fmod(a, b))
#endif
#ifdef WIN32
#ifndef FREE_WINDOWS
#define isnan(n) _isnan(n)
#define finite _finite
#endif
#endif
#ifndef SWAP
#define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; }
#endif
#ifndef CLAMP
#define CLAMP(a, b, c) if((a)<(b)) (a)=(b); else if((a)>(c)) (a)=(c)
#endif
/******************************* Float ******************************/
float sqrt3f(float f);
double sqrt3d(double d);
float saacosf(float f);
float saasinf(float f);
float sasqrtf(float f);
float saacos(float fac);
float saasin(float fac);
float sasqrt(float fac);
float interpf(float a, float b, float t);
float power_of_2(float f);
float shell_angle_to_dist(float angle);
#ifdef __cplusplus
}
#endif
#endif /* BLI_MATH_BASE */

View File

@@ -0,0 +1,66 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: some of this file.
*
* ***** END GPL LICENSE BLOCK *****
* */
#ifndef BLI_MATH_COLOR
#define BLI_MATH_COLOR
#ifdef __cplusplus
extern "C" {
#endif
#define BLI_CS_SMPTE 0
#define BLI_CS_REC709 1
#define BLI_CS_CIE 2
/******************* Conversion to RGB ********************/
void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b);
void hex_to_rgb(char *hexcol, float *r, float *g, float *b);
void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb);
void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb);
void xyz_to_rgb(float x, float y, float z, float *r, float *g, float *b, int colorspace);
void cpack_to_rgb(unsigned int col, float *r, float *g, float *b);
/***************** Conversion from RGB ********************/
void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv);
void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr);
void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv);
unsigned int rgb_to_cpack(float r, float g, float b);
unsigned int hsv_to_cpack(float h, float s, float v);
/************************** Other *************************/
int constrain_rgb(float *r, float *g, float *b);
void minmax_rgb(short c[3]);
#ifdef __cplusplus
}
#endif
#endif /* BLI_MATH_COLOR */

View File

@@ -0,0 +1,157 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: some of this file.
*
* ***** END GPL LICENSE BLOCK *****
* */
#ifndef BLI_MATH_GEOM
#define BLI_MATH_GEOM
#ifdef __cplusplus
extern "C" {
#endif
/********************************** Polygons *********************************/
void cent_tri_v3(float r[3], float a[3], float b[3], float c[3]);
void cent_quad_v3(float r[3], float a[3], float b[3], float c[3], float d[3]);
float normal_tri_v3(float r[3], float a[3], float b[3], float c[3]);
float normal_quad_v3(float r[3], float a[3], float b[3], float c[3], float d[3]);
float area_tri_v2(float a[2], float b[2], float c[2]);
float area_tri_v3(float a[3], float b[3], float c[3]);
float area_quad_v3(float a[3], float b[3], float c[3], float d[3]);
float area_poly_v3(int nr, float *verts, float normal[3]); // TODO float verts[][3]
/********************************* Distance **********************************/
float dist_to_line_v2(float p[2], float l1[2], float l2[2]);
float dist_to_line_segment_v2(float p[2], float l1[2], float l2[2]);
float dist_to_line_segment_v3(float p[3], float l1[3], float l2[3]);
float closest_to_line_v3(float r[3], float p[3], float l1[3], float l2[3]);
void closest_to_line_segment_v3(float r[3], float p[3], float l1[3], float l2[3]);
/******************************* Intersection ********************************/
/* TODO return values are not always first yet */
/* TODO int return value consistency */
/* line-line */
#define ISECT_LINE_LINE_COLINEAR -1
#define ISECT_LINE_LINE_NONE 0
#define ISECT_LINE_LINE_EXACT 1
#define ISECT_LINE_LINE_CROSS 2
short isect_line_line_v2(float a1[2], float a2[2], float b1[2], float b2[2]); // TODO return int
short isect_line_line_v2_short(short a1[2], short a2[2], short b1[2], short b2[2]); // TODO return int
/* Returns the number of point of interests
* 0 - lines are colinear
* 1 - lines are coplanar, i1 is set to intersection
* 2 - i1 and i2 are the nearest points on line 1 (v1, v2) and line 2 (v3, v4) respectively
* */
int isect_line_line_v3(float v1[3], float v2[3],
float v3[3], float v4[3], float i1[3], float i2[3]);
int isect_line_line_strict_v3(float v1[3], float v2[3],
float v3[3], float v4[3], float vi[3], float *lambda);
/* line/ray triangle */
int isect_line_tri_v3(float p1[3], float p2[3],
float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
int isect_ray_tri_v3(float p1[3], float d[3],
float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
int isect_ray_tri_threshold_v3(float p1[3], float d[3],
float v0[3], float v1[3], float v2[3], float *lambda, float *uv, float threshold);
/* point in polygon */
int isect_point_tri_v2(float p[2], float a[2], float b[2], float c[2]);
int isect_point_quad_v2(float p[2], float a[2], float b[2], float c[2], float d[2]);
int isect_point_tri_v2(float v1[2], float v2[2], float v3[2], float pt[2]);
int isect_point_tri_v2_int(int x1, int y1, int x2, int y2, int a, int b);
int isect_point_tri_prism_v3(float p[3], float v1[3], float v2[3], float v3[3]);
void isect_point_quad_uv_v2(float v0[2], float v1[2], float v2[2], float v3[2],
float pt[2], float *uv);
void isect_point_face_uv_v2(int isquad, float v0[2], float v1[2], float v2[2],
float v3[2], float pt[2], float *uv);
/* other */
int isect_sweeping_sphere_tri_v3(float p1[3], float p2[3], float radius,
float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint);
int isect_axial_line_tri_v3(int axis, float co1[3], float co2[3],
float v0[3], float v1[3], float v2[3], float *lambda);
int isect_aabb_aabb_v3(float min1[3], float max1[3], float min2[3], float max2[3]);
/****************************** Interpolation ********************************/
/* tri or quad, d can be NULL */
void interp_weights_face_v3(float w[4],
float a[3], float b[3], float c[3], float d[3], float p[3]);
void interp_weights_poly_v3(float w[], float v[][3], int n, float p[3]);
void interp_cubic_v3(float x[3], float v[3],
float x1[3], float v1[3], float x2[3], float v2[3], float t);
/***************************** View & Projection *****************************/
void lookat_m4(float mat[4][4], float vx, float vy,
float vz, float px, float py, float pz, float twist);
void polarview_m4(float mat[4][4], float dist, float azimuth,
float incidence, float twist);
void perspective_m4(float mat[4][4], float left, float right,
float bottom, float top, float nearClip, float farClip);
void orthographic_m4(float mat[4][4], float left, float right,
float bottom, float top, float nearClip, float farClip);
/********************************** Mapping **********************************/
void map_to_tube(float *u, float *v, float x, float y, float z);
void map_to_sphere(float *u, float *v, float x, float y, float z);
/********************************* Tangents **********************************/
typedef struct VertexTangent {
float tang[3], uv[2];
struct VertexTangent *next;
} VertexTangent;
float *find_vertex_tangent(VertexTangent *vtang, float *uv);
void sum_or_add_vertex_tangent(void *arena, VertexTangent **vtang,
float *tang, float *uv);
void tangent_from_uv(float *uv1, float *uv2, float *uv3,
float *co1, float *co2, float *co3, float *n, float *tang);
#ifdef __cplusplus
}
#endif
#endif /* BLI_MATH_GEOM */

View File

@@ -0,0 +1,165 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
* The Original Code is: some of this file.
*
* ***** END GPL LICENSE BLOCK *****
* */
#ifndef BLI_MATH_MATRIX
#define BLI_MATH_MATRIX
#ifdef __cplusplus
extern "C" {
#endif
/********************************* Init **************************************/
#define MAT4_UNITY {{ 1.0, 0.0, 0.0, 0.0},\
{ 0.0, 1.0, 0.0, 0.0},\
{ 0.0, 0.0, 1.0, 0.0},\
{ 0.0, 0.0, 0.0, 1.0}}
#define MAT3_UNITY {{ 1.0, 0.0, 0.0},\
{ 0.0, 1.0, 0.0},\
{ 0.0, 0.0, 1.0}}
void zero_m3(float *R); // TODO R[3][3]);
void zero_m4(float *R); // TODO R[4][4]);
void unit_m3(float R[3][3]);
void unit_m4(float R[4][4]);
void copy_m3_m3(float R[3][3], float A[3][3]);
void copy_m4_m4(float R[4][4], float A[4][4]);
void copy_m3_m4(float R[3][3], float A[4][4]);
void copy_m4_m3(float R[4][4], float A[3][3]);
void swap_m3m3(float A[3][3], float B[3][3]);
void swap_m4m4(float A[4][4], float B[4][4]);
/******************************** Arithmetic *********************************/
void add_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]);
void add_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]);
// TODO review mul order
void mul_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]);
void mul_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]);
void mul_m4_m3m4(float R[4][4], float A[3][3], float B[4][4]);
void mul_m4_m4m3(float R[4][4], float A[4][4], float B[3][3]);
void mul_m3_m3m4(float R[3][3], float A[3][3], float B[4][4]);
void mul_serie_m3(float R[3][3],
float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3],
float M5[3][3], float M6[3][3], float M7[3][3], float M8[3][3]);
void mul_serie_m4(float R[4][4],
float M1[4][4], float M2[4][4], float M3[4][4], float M4[4][4],
float M5[4][4], float M6[4][4], float M7[4][4], float M8[4][4]);
void mul_m4_v3(float M[4][4], float r[3]); // TODO order
void mul_v3_m4v3(float r[3], float M[4][4], float v[3]);
void mul_no_transl_m4v3(float M[4][4], float r[3]);
void mul_m4_v4(float M[4][4], float r[3]); // TODO order
void mul_project_m4_v4(float M[4][4], float r[3]); // TODO order
void mul_m3_v3(float M[3][3], float r[3]); // TODO order
void mul_transposed_m3_v3(float M[3][3], float r[3]); // TODO order
void mul_m3_v3_double(float M[3][3], double r[3]);
void mul_m3_fl(float *R, float f); // TODO R[3][3], float f);
void mul_m4_fl(float *R, float f); // TODO R[4][4], float f);
void mul_no_transl_m4_fl(float *R, float f); // TODO R[4][4], float f);
void invert_m3(float R[3][3]);
void invert_m3_m3(float R[3][3], float A[3][3]);
void invert_m4(float R[4][4]); // TODO does not exist
int invert_m4_m4(float R[4][4], float A[4][4]); // TODO return int
/****************************** Linear Algebra *******************************/
void transpose_m3(float R[3][3]);
void transpose_m4(float R[4][4]);
void normalize_m3(float R[3][3]);
void normalize_m4(float R[4][4]);
void orthogonalize_m3(float R[3][3], int axis);
void orthogonalize_m4(float R[4][4], int axis);
int is_orthogonal_m3(float mat[3][3]);
int is_orthogonal_m4(float mat[4][4]);
void adjoint_m3_m3(float R[3][3], float A[3][3]);
void adjoint_m4_m4(float R[4][4], float A[4][4]);
//float determinant_m2(float A[2][2]); // TODO params
//float determinant_m3(float A[3][3]); // TODO params
float determinant_m2(
float a, float b,
float c, float d);
float determinant_m3(
float a, float b, float c,
float d, float e, float f,
float g, float h, float i);
float determinant_m4(float A[4][4]);
/****************************** Transformations ******************************/
void scale_m3_fl(float R[3][3], float scale);
void scale_m4_fl(float R[4][4], float scale);
float mat3_to_scale(float M[3][3]);
float mat4_to_scale(float M[4][4]);
void size_to_mat3(float R[3][3], float size[3]);
void size_to_mat4(float R[4][4], float size[3]);
void mat3_to_size(float r[3], float M[3][3]);
void mat4_to_size(float r[3], float M[4][4]);
void translate_m4(float mat[4][4], float tx, float ty, float tz);
void rotate_m4(float mat[4][4], char axis, float angle);
void loc_eul_size_to_mat4(float R[4][4],
float loc[3], float eul[3], float size[3]);
void loc_eulO_size_to_mat4(float R[4][4],
float loc[3], float eul[3], float size[3], short order);
void loc_quat_size_to_mat4(float R[4][4],
float loc[3], float quat[4], float size[3]);
void blend_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], float t);
void blend_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], float t);
/*********************************** Other ***********************************/
void print_m3(char *str, float M[3][3]);
void print_m4(char *str, float M[3][4]);
#ifdef __cplusplus
}
#endif
#endif /* BLI_MATH_MATRIX */

View File

@@ -0,0 +1,172 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: some of this file.
*
* ***** END GPL LICENSE BLOCK *****
* */
#ifndef BLI_MATH_ROTATION
#define BLI_MATH_ROTATION
#ifdef __cplusplus
extern "C" {
#endif
#define RAD2DEG(_rad) ((_rad)*(180.0/M_PI))
#define DEG2RAD(_deg) ((_deg)*(M_PI/180.0))
/******************************** Quaternions ********************************/
/* stored in (w, x, y, z) order */
/* init */
void unit_qt(float q[4]);
void copy_qt_qt(float q[4], float a[4]);
/* arithmetic */
void mul_qt_qtqt(float q[4], float a[4], float b[4]);
void mul_qt_v3(float q[4], float r[3]); // TODO order
void mul_qt_fl(float q[4], float f);
void mul_fac_qt_fl(float q[4], float f);
void sub_qt_qtqt(float q[4], float a[4], float b[4]);
void invert_qt(float q[4]);
void conjugate_qt(float q[4]);
float dot_qtqt(float a[4], float b[4]);
void normalize_qt(float q[4]);
/* comparison */
int is_zero_qt(float q[4]);
/* interpolation */
void interp_qt_qtqt(float q[4], float a[4], float b[4], float t);
void add_qt_qtqt(float q[4], float a[4], float b[4], float t); // TODO name
/* conversion */
void quat_to_mat3(float mat[3][3], float q[4]);
void quat_to_mat4(float mat[4][4], float q[4]);
void mat3_to_quat(float q[4], float mat[3][3]);
void mat4_to_quat(float q[4], float mat[4][4]);
void tri_to_quat(float q[4], float a[3], float b[3], float c[3]);
void vec_to_quat(float q[4], float vec[3], short axis, short upflag);
void rotation_between_vecs_to_quat(float q[4], float v1[3], float v2[3]);
void Mat3ToQuat_is_ok(float wmat[][3], float *q); // TODO what is this?
/* other */
void print_qt(char *str, float q[4]);
/******************************** Axis Angle *********************************/
/* conversion */
void axis_angle_to_quat(float r[4], float axis[3], float angle);
void axis_angle_to_mat3(float R[3][3], float axis[3], float angle);
void axis_angle_to_mat4(float R[4][4], float axis[3], float angle);
void quat_to_axis_angle(float axis[3], float *angle, float q[4]);
void mat3_to_axis_angle(float axis[3], float *angle, float M[3][3]);
void mat4_to_axis_angle(float axis[3], float *angle, float M[4][4]);
/****************************** Vector/Rotation ******************************/
/* old axis angle code */
/* TODO: the following calls should probably be depreceated sometime */
/* conversion */
void mat3_to_vec_rot(float vec[3], float *phi, float mat[3][3]);
void mat4_to_vec_rot(float vec[3], float *phi, float mat[4][4]);
void vec_rot_to_quat(float quat[4], float vec[3], float phi); // TODO
void vec_rot_to_mat3(float mat[3][3], float vec[3], float phi);
void vec_rot_to_mat4(float mat[4][4], float vec[3], float phi);
/******************************** XYZ Eulers *********************************/
void eul_to_quat(float quat[4], float eul[3]);
void eul_to_mat3(float mat[3][3], float eul[3]);
void eul_to_mat4(float mat[4][4], float eul[3]);
void quat_to_eul(float eul[3], float quat[4]);
void mat3_to_eul(float eul[3], float mat[3][3]);
void mat4_to_eul(float eul[3], float mat[4][4]);
void compatible_eul(float eul[3], float old[3]);
void mat3_to_compatible_eul(float eul[3], float old[3], float mat[3][3]);
void rotate_eul(float eul[3], char axis, float angle);
/************************** Arbitrary Order Eulers ***************************/
/* warning: must match the eRotationModes in DNA_action_types.h
* order matters - types are saved to file. */
typedef enum eEulerRotationOrders {
EULER_ORDER_DEFAULT = 1, /* blender classic = XYZ */
EULER_ORDER_XYZ = 1,
EULER_ORDER_XZY,
EULER_ORDER_YXZ,
EULER_ORDER_YZX,
EULER_ORDER_ZXY,
EULER_ORDER_ZYX,
/* there are 6 more entries with dulpicate entries included */
} eEulerRotationOrders;
void eulO_to_quat(float quat[4], float eul[3], short order);
void eulO_to_mat3(float mat[3][3], float eul[3], short order);
void eulO_to_mat4(float mat[4][4], float eul[3], short order);
void eulO_to_axis_angle(float axis[3], float *angle, float eul[3], short order);
void eulO_to_gimbal_axis(float gmat[3][3], float eul[3], short order);
void quat_to_eulO(float eul[3], short order, float quat[4]);
void mat3_to_eulO(float eul[3], short order, float mat[3][3]);
void mat4_to_eulO(float eul[3], short order, float mat[4][4]);
void axis_angle_to_eulO(float eul[3], short order, float axis[3], float angle);
void mat3_to_compatible_eulO(float eul[3], float old[3], short order, float mat[3][3]);
void rotate_eulO(float eul[3], short order, char axis, float angle);
/******************************* Dual Quaternions ****************************/
typedef struct DualQuat {
float quat[4];
float trans[4];
float scale[4][4];
float scale_weight;
} DualQuat;
void copy_dq_dq(DualQuat *r, DualQuat *dq);
void normalize_dq(DualQuat *dq, float totw);
void add_weighted_dq_dq(DualQuat *r, DualQuat *dq, float weight);
void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq);
void mat4_to_dquat(DualQuat *r, float base[4][4], float M[4][4]);
void dquat_to_mat4(float R[4][4], DualQuat *dq);
#ifdef __cplusplus
}
#endif
#endif /* BLI_MATH_ROTATION */

View File

@@ -0,0 +1,140 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: some of this file.
*
* ***** END GPL LICENSE BLOCK *****
* */
#ifndef BLI_MATH_VECTOR
#define BLI_MATH_VECTOR
#ifdef __cplusplus
extern "C" {
#endif
#define MINLINE
//#define static inline
//#include "intern/math_vector_inline.h"
/************************************* Init ***********************************/
void zero_v2(float r[2]);
void zero_v3(float r[3]);
void copy_v2_v2(float r[2], float a[2]);
void copy_v3_v3(float r[3], float a[3]);
/********************************* Arithmetic ********************************/
void add_v2_v2(float r[2], float a[2]);
void add_v2_v2v2(float r[2], float a[2], float b[2]);
void add_v3_v3(float r[3], float a[3]);
void add_v3_v3v3(float r[3], float a[3], float b[3]);
void sub_v2_v2(float r[2], float a[2]);
void sub_v2_v2v2(float r[2], float a[2], float b[2]);
void sub_v3_v3(float r[3], float a[3]);
void sub_v3_v3v3(float r[3], float a[3], float b[3]);
void mul_v2_fl(float r[2], float f);
void mul_v3_fl(float r[3], float f);
void mul_v3_v3fl(float r[3], float a[3], float f);
void mul_v3_v3(float r[3], float a[3]);
void mul_v3_v3v3(float r[3], float a[3], float b[3]);
void negate_v3(float r[3]);
void negate_v3_v3(float r[3], float a[3]);
float dot_v2v2(float a[2], float b[2]);
float dot_v3v3(float a[3], float b[3]);
float cross_v2v2(float a[2], float b[2]);
void cross_v3_v3v3(float r[3], float a[3], float b[3]);
void star_m3_v3(float R[3][3],float a[3]);
/*********************************** Length **********************************/
float len_v2(float a[2]);
float len_v2v2(float a[2], float b[2]);
float len_v3(float a[3]);
float len_v3v3(float a[3], float b[3]);
float normalize_v2(float r[2]);
float normalize_v3(float r[3]);
/******************************* Interpolation *******************************/
void interp_v2_v2v2(float r[2], const float a[2], const float b[2], const float t); // TODO const
void interp_v2_v2v2v2(float r[2], const float a[2], const float b[2], const float c[3], const float t[3]); // TODO const
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t); // TODO const
void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3]); // TODO const
void mid_v3_v3v3(float r[3], float a[3], float b[3]);
/********************************* Comparison ********************************/
int is_zero_v3(float a[3]);
int equals_v3v3(float a[3], float b[3]);
int compare_v3v3(float a[3], float b[3], float limit);
int compare_len_v3v3(float a[3], float b[3], float limit);
int compare_v4v4(float a[4], float b[4], float limit);
/********************************** Angles ***********************************/
/* - angle with 2 arguments is angle between vector */
/* - angle with 3 arguments is angle between 3 points at the middle point */
/* - angle_normalized_* is faster equivalent if vectors are normalized */
float angle_v2v2(float a[2], float b[2]);
float angle_v2v2v2(float a[2], float b[2], float c[2]);
float angle_normalized_v2v2(float a[2], float b[2]);
float angle_v3v3(float a[2], float b[2]);
float angle_v3v3v3(float a[2], float b[2], float c[2]);
float angle_normalized_v3v3(float a[3], float b[3]);
/********************************* Geometry **********************************/
void project_v3_v3v3(float r[3], float p[3], float n[3]);
void reflect_v3_v3v3(float r[3], float v[3], float n[3]);
void ortho_basis_v3v3_v3(float r1[3], float r2[3], float a[3]);
void bisect_v3_v3v3v3(float r[3], float a[3], float b[3], float c[3]);
/*********************************** Other ***********************************/
void print_v2(char *str, float a[2]);
void print_v3(char *str, float a[3]);
void print_v4(char *str, float a[4]);
void normal_short_to_float_v3(float r[3], short n[3]);
void normal_float_to_short_v3(short r[3], float n[3]);
void minmax_v3_v3v3(float r[3], float min[3], float max[3]);
#ifdef __cplusplus
}
#endif
#endif /* BLI_MATH_VECTOR */

View File

@@ -0,0 +1,117 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: some of this file.
*
* ***** END GPL LICENSE BLOCK *****
* */
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "BLI_math.h"
/* A few small defines. Keep'em local! */
#define SMALL_NUMBER 1.e-8
#if 0
float sqrt3f(float f)
{
if(f==0.0) return 0;
if(f<0) return (float)(-exp(log(-f)/3));
else return (float)(exp(log(f)/3));
}
#endif
double sqrt3d(double d)
{
if(d==0.0) return 0;
if(d<0) return -exp(log(-d)/3);
else return exp(log(d)/3);
}
#if 0
float saacos(float fac)
{
if(fac<= -1.0f) return (float)M_PI;
else if(fac>=1.0f) return 0.0;
else return (float)acos(fac);
}
float saasin(float fac)
{
if(fac<= -1.0f) return (float)-M_PI/2.0f;
else if(fac>=1.0f) return (float)M_PI/2.0f;
else return (float)asin(fac);
}
float sasqrt(float fac)
{
if(fac<=0.0) return 0.0;
return (float)sqrt(fac);
}
float saacosf(float fac)
{
if(fac<= -1.0f) return (float)M_PI;
else if(fac>=1.0f) return 0.0f;
else return (float)acosf(fac);
}
float saasinf(float fac)
{
if(fac<= -1.0f) return (float)-M_PI/2.0f;
else if(fac>=1.0f) return (float)M_PI/2.0f;
else return (float)asinf(fac);
}
float sasqrtf(float fac)
{
if(fac<=0.0) return 0.0;
return (float)sqrtf(fac);
}
float interpf(float target, float origin, float fac)
{
return (fac*target) + (1.0f-fac)*origin;
}
#endif
/* useful to calculate an even width shell, by taking the angle between 2 planes.
* The return value is a scale on the offset.
* no angle between planes is 1.0, as the angle between the 2 planes approches 180d
* the distance gets very high, 180d would be inf, but this case isn't valid */
float shell_angle_to_dist(const float angle)
{
return (angle < SMALL_NUMBER) ? 1.0f : fabsf(1.0f / cosf(angle * (M_PI/180.0f)));
}
#if 0
/* used for zoom values*/
float power_of_2(float val)
{
return (float)pow(2, ceil(log(val) / log(2)));
}
#endif

View File

@@ -0,0 +1,313 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
* The Original Code is: some of this file.
*
* ***** END GPL LICENSE BLOCK *****
* */
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "BLI_math.h"
void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b)
{
int i;
float f, p, q, t;
h *= 360.0f;
if(s==0.0f) {
*r = v;
*g = v;
*b = v;
}
else {
if(h== 360.0f) h = 0.0f;
h /= 60.0f;
i = (int)floor(h);
f = h - i;
p = v*(1.0f-s);
q = v*(1.0f-(s*f));
t = v*(1.0f-(s*(1.0f-f)));
switch (i) {
case 0 :
*r = v;
*g = t;
*b = p;
break;
case 1 :
*r = q;
*g = v;
*b = p;
break;
case 2 :
*r = p;
*g = v;
*b = t;
break;
case 3 :
*r = p;
*g = q;
*b = v;
break;
case 4 :
*r = t;
*g = p;
*b = v;
break;
case 5 :
*r = v;
*g = p;
*b = q;
break;
}
}
}
void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv)
{
float y, u, v;
y= 0.299f*r + 0.587f*g + 0.114f*b;
u=-0.147f*r - 0.289f*g + 0.436f*b;
v= 0.615f*r - 0.515f*g - 0.100f*b;
*ly=y;
*lu=u;
*lv=v;
}
void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb)
{
float r, g, b;
r=y+1.140f*v;
g=y-0.394f*u - 0.581f*v;
b=y+2.032f*u;
*lr=r;
*lg=g;
*lb=b;
}
void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr)
{
float sr,sg, sb;
float y, cr, cb;
sr=255.0f*r;
sg=255.0f*g;
sb=255.0f*b;
y=(0.257f*sr)+(0.504f*sg)+(0.098f*sb)+16.0f;
cb=(-0.148f*sr)-(0.291f*sg)+(0.439f*sb)+128.0f;
cr=(0.439f*sr)-(0.368f*sg)-(0.071f*sb)+128.0f;
*ly=y;
*lcb=cb;
*lcr=cr;
}
void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb)
{
float r,g,b;
r=1.164f*(y-16.0f)+1.596f*(cr-128.0f);
g=1.164f*(y-16.0f)-0.813f*(cr-128.0f)-0.392f*(cb-128.0f);
b=1.164f*(y-16.0f)+2.017f*(cb-128.0f);
*lr=r/255.0f;
*lg=g/255.0f;
*lb=b/255.0f;
}
void hex_to_rgb(char *hexcol, float *r, float *g, float *b)
{
unsigned int ri, gi, bi;
if (hexcol[0] == '#') hexcol++;
if (sscanf(hexcol, "%02x%02x%02x", &ri, &gi, &bi)) {
*r = ri / 255.0f;
*g = gi / 255.0f;
*b = bi / 255.0f;
}
}
void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv)
{
float h, s, v;
float cmax, cmin, cdelta;
float rc, gc, bc;
cmax = r;
cmin = r;
cmax = (g>cmax ? g:cmax);
cmin = (g<cmin ? g:cmin);
cmax = (b>cmax ? b:cmax);
cmin = (b<cmin ? b:cmin);
v = cmax; /* value */
if (cmax != 0.0f)
s = (cmax - cmin)/cmax;
else {
s = 0.0f;
h = 0.0f;
}
if (s == 0.0f)
h = -1.0f;
else {
cdelta = cmax-cmin;
rc = (cmax-r)/cdelta;
gc = (cmax-g)/cdelta;
bc = (cmax-b)/cdelta;
if (r==cmax)
h = bc-gc;
else
if (g==cmax)
h = 2.0f+rc-bc;
else
h = 4.0f+gc-rc;
h = h*60.0f;
if (h < 0.0f)
h += 360.0f;
}
*ls = s;
*lh = h / 360.0f;
if(*lh < 0.0f) *lh= 0.0f;
*lv = v;
}
/*http://brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html */
void xyz_to_rgb(float xc, float yc, float zc, float *r, float *g, float *b, int colorspace)
{
switch (colorspace) {
case BLI_CS_SMPTE:
*r = (3.50570f * xc) + (-1.73964f * yc) + (-0.544011f * zc);
*g = (-1.06906f * xc) + (1.97781f * yc) + (0.0351720f * zc);
*b = (0.0563117f * xc) + (-0.196994f * yc) + (1.05005f * zc);
break;
case BLI_CS_REC709:
*r = (3.240476f * xc) + (-1.537150f * yc) + (-0.498535f * zc);
*g = (-0.969256f * xc) + (1.875992f * yc) + (0.041556f * zc);
*b = (0.055648f * xc) + (-0.204043f * yc) + (1.057311f * zc);
break;
case BLI_CS_CIE:
*r = (2.28783848734076f * xc) + (-0.833367677835217f * yc) + (-0.454470795871421f * zc);
*g = (-0.511651380743862f * xc) + (1.42275837632178f * yc) + (0.0888930017552939f * zc);
*b = (0.00572040983140966f * xc) + (-0.0159068485104036f * yc) + (1.0101864083734f * zc);
break;
}
}
/* we define a 'cpack' here as a (3 byte color code) number that can be expressed like 0xFFAA66 or so.
for that reason it is sensitive for endianness... with this function it works correctly
*/
unsigned int hsv_to_cpack(float h, float s, float v)
{
short r, g, b;
float rf, gf, bf;
unsigned int col;
hsv_to_rgb(h, s, v, &rf, &gf, &bf);
r= (short)(rf*255.0f);
g= (short)(gf*255.0f);
b= (short)(bf*255.0f);
col= ( r + (g*256) + (b*256*256) );
return col;
}
unsigned int rgb_to_cpack(float r, float g, float b)
{
int ir, ig, ib;
ir= (int)floor(255.0*r);
if(ir<0) ir= 0; else if(ir>255) ir= 255;
ig= (int)floor(255.0*g);
if(ig<0) ig= 0; else if(ig>255) ig= 255;
ib= (int)floor(255.0*b);
if(ib<0) ib= 0; else if(ib>255) ib= 255;
return (ir+ (ig*256) + (ib*256*256));
}
void cpack_to_rgb(unsigned int col, float *r, float *g, float *b)
{
*r= (float)((col)&0xFF);
*r /= 255.0f;
*g= (float)(((col)>>8)&0xFF);
*g /= 255.0f;
*b= (float)(((col)>>16)&0xFF);
*b /= 255.0f;
}
void minmax_rgb(short c[])
{
if(c[0]>255) c[0]=255;
else if(c[0]<0) c[0]=0;
if(c[1]>255) c[1]=255;
else if(c[1]<0) c[1]=0;
if(c[2]>255) c[2]=255;
else if(c[2]<0) c[2]=0;
}
/*If the requested RGB shade contains a negative weight for
one of the primaries, it lies outside the colour gamut
accessible from the given triple of primaries. Desaturate
it by adding white, equal quantities of R, G, and B, enough
to make RGB all positive. The function returns 1 if the
components were modified, zero otherwise.*/
int constrain_rgb(float *r, float *g, float *b)
{
float w;
/* Amount of white needed is w = - min(0, *r, *g, *b) */
w = (0 < *r) ? 0 : *r;
w = (w < *g) ? w : *g;
w = (w < *b) ? w : *b;
w = -w;
/* Add just enough white to make r, g, b all positive. */
if (w > 0) {
*r += w; *g += w; *b += w;
return 1; /* Color modified to fit RGB gamut */
}
return 0; /* Color within RGB gamut */
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,535 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
* The Original Code is: some of this file.
*
* ***** END GPL LICENSE BLOCK *****
* */
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "BLI_math.h"
/********************************** Init *************************************/
void zero_v2(float r[2])
{
r[0]= 0.0f;
r[1]= 0.0f;
}
void zero_v3(float r[3])
{
r[0]= 0.0f;
r[1]= 0.0f;
r[2]= 0.0f;
}
void copy_v2_v2(float r[2], float a[2])
{
r[0]= a[0];
r[1]= a[1];
}
void copy_v3_v3(float r[3], float a[3])
{
r[0]= a[0];
r[1]= a[1];
r[2]= a[2];
}
/********************************* Arithmetic ********************************/
void add_v2_v2(float *r, float *a)
{
r[0] += a[0];
r[1] += a[1];
}
void add_v2_v2v2(float *r, float *a, float *b)
{
r[0]= a[0] + b[0];
r[1]= a[1] + b[1];
}
void add_v3_v3(float *r, float *a)
{
r[0] += a[0];
r[1] += a[1];
r[1] += a[1];
}
void add_v3_v3v3(float *r, float *a, float *b)
{
r[0]= a[0] + b[0];
r[1]= a[1] + b[1];
r[2]= a[2] + b[2];
}
void sub_v2_v2(float *r, float *a)
{
r[0] -= a[0];
r[1] -= a[1];
}
void sub_v2_v2v2(float *r, float *a, float *b)
{
r[0]= a[0] - b[0];
r[1]= a[1] - b[1];
}
void sub_v3_v3(float *r, float *a)
{
r[0] -= a[0];
r[1] -= a[1];
r[1] -= a[1];
}
void sub_v3_v3v3(float *r, float *a, float *b)
{
r[0]= a[0] - b[0];
r[1]= a[1] - b[1];
r[2]= a[2] - b[2];
}
void mul_v2_fl(float *v1, float f)
{
v1[0]*= f;
v1[1]*= f;
}
void mul_v3_fl(float r[3], float f)
{
r[0] *= f;
r[1] *= f;
r[2] *= f;
}
void mul_v3_v3fl(float r[3], float a[3], float f)
{
r[0]= a[0]*f;
r[1]= a[1]*f;
r[2]= a[2]*f;
}
void mul_v3_v3(float r[3], float a[3])
{
r[0] *= a[0];
r[1] *= a[1];
r[2] *= a[2];
}
void mul_v3_v3v3(float *v, float *v1, float *v2)
{
v[0] = v1[0] * v2[0];
v[1] = v1[1] * v2[1];
v[2] = v1[2] * v2[2];
}
void negate_v3(float r[3])
{
r[0]= -r[0];
r[1]= -r[1];
r[2]= -r[2];
}
void negate_v3_v3(float r[3], float a[3])
{
r[0]= -a[0];
r[1]= -a[1];
r[2]= -a[2];
}
float dot_v2v2(float *a, float *b)
{
return a[0]*b[0] + a[1]*b[1];
}
float dot_v3v3(float a[3], float b[3])
{
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
}
void cross_v3_v3v3(float r[3], float a[3], float b[3])
{
r[0]= a[1]*b[2] - a[2]*b[1];
r[1]= a[2]*b[0] - a[0]*b[2];
r[2]= a[0]*b[1] - a[1]*b[0];
}
void star_m3_v3(float mat[][3], float *vec)
{
mat[0][0]= mat[1][1]= mat[2][2]= 0.0;
mat[0][1]= -vec[2];
mat[0][2]= vec[1];
mat[1][0]= vec[2];
mat[1][2]= -vec[0];
mat[2][0]= -vec[1];
mat[2][1]= vec[0];
}
/*********************************** Length **********************************/
float len_v2(float *v)
{
return (float)sqrt(v[0]*v[0] + v[1]*v[1]);
}
float len_v2v2(float *v1, float *v2)
{
float x, y;
x = v1[0]-v2[0];
y = v1[1]-v2[1];
return (float)sqrt(x*x+y*y);
}
float len_v3(float a[3])
{
return sqrtf(dot_v3v3(a, a));
}
float len_v3v3(float a[3], float b[3])
{
float d[3];
sub_v3_v3v3(d, b, a);
return len_v3(d);
}
float normalize_v2(float n[2])
{
float d;
d= n[0]*n[0]+n[1]*n[1];
if(d>1.0e-35f) {
d= (float)sqrt(d);
n[0]/=d;
n[1]/=d;
} else {
n[0]=n[1]= 0.0f;
d= 0.0f;
}
return d;
}
float normalize_v3(float n[3])
{
float d= dot_v3v3(n, n);
/* a larger value causes normalize errors in a
scaled down models with camera xtreme close */
if(d > 1.0e-35f) {
d= sqrtf(d);
mul_v3_fl(n, 1.0f/d);
}
else {
zero_v3(n);
d= 0.0f;
}
return d;
}
/******************************* Interpolation *******************************/
void interp_v2_v2v2(float *target, const float *a, const float *b, const float t)
{
const float s = 1.0f-t;
target[0]= s*a[0] + t*b[0];
target[1]= s*a[1] + t*b[1];
}
/* weight 3 2D vectors,
* 'w' must be unit length but is not a vector, just 3 weights */
void interp_v2_v2v2v2(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3])
{
p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2];
p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2];
}
void interp_v3_v3v3(float *target, const float *a, const float *b, const float t)
{
const float s = 1.0f-t;
target[0]= s*a[0] + t*b[0];
target[1]= s*a[1] + t*b[1];
target[2]= s*a[2] + t*b[2];
}
/* weight 3 vectors,
* 'w' must be unit length but is not a vector, just 3 weights */
void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
{
p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2];
p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2];
p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2];
}
void mid_v3_v3v3(float *v, float *v1, float *v2)
{
v[0]= 0.5f*(v1[0]+ v2[0]);
v[1]= 0.5f*(v1[1]+ v2[1]);
v[2]= 0.5f*(v1[2]+ v2[2]);
}
/********************************* Comparison ********************************/
int is_zero_v3(float *v)
{
return (v[0] == 0 && v[1] == 0 && v[2] == 0);
}
int equals_v3v3(float *v1, float *v2)
{
return ((v1[0]==v2[0]) && (v1[1]==v2[1]) && (v1[2]==v2[2]));
}
int compare_v3v3(float *v1, float *v2, float limit)
{
if(fabs(v1[0]-v2[0])<limit)
if(fabs(v1[1]-v2[1])<limit)
if(fabs(v1[2]-v2[2])<limit)
return 1;
return 0;
}
int compare_len_v3v3(float *v1, float *v2, float limit)
{
float x,y,z;
x=v1[0]-v2[0];
y=v1[1]-v2[1];
z=v1[2]-v2[2];
return ((x*x + y*y + z*z) < (limit*limit));
}
int compare_v4v4(float *v1, float *v2, float limit)
{
if(fabs(v1[0]-v2[0])<limit)
if(fabs(v1[1]-v2[1])<limit)
if(fabs(v1[2]-v2[2])<limit)
if(fabs(v1[3]-v2[3])<limit)
return 1;
return 0;
}
/********************************** Angles ***********************************/
/* Return the angle in radians between vecs 1-2 and 2-3 in radians
If v1 is a shoulder, v2 is the elbow and v3 is the hand,
this would return the angle at the elbow */
float angle_v3v3v3(float *v1, float *v2, float *v3)
{
float vec1[3], vec2[3];
sub_v3_v3v3(vec1, v2, v1);
sub_v3_v3v3(vec2, v2, v3);
normalize_v3(vec1);
normalize_v3(vec2);
return angle_normalized_v3v3(vec1, vec2);
}
float angle_v2v2v2(float *v1, float *v2, float *v3)
{
float vec1[2], vec2[2];
vec1[0] = v2[0]-v1[0];
vec1[1] = v2[1]-v1[1];
vec2[0] = v2[0]-v3[0];
vec2[1] = v2[1]-v3[1];
normalize_v2(vec1);
normalize_v2(vec2);
return angle_normalized_v2v2(vec1, vec2);
}
/* Return the shortest angle in radians between the 2 vectors */
float angle_v2v2(float *v1, float *v2)
{
float vec1[3], vec2[3];
copy_v3_v3(vec1, v1);
copy_v3_v3(vec2, v2);
normalize_v3(vec1);
normalize_v3(vec2);
return angle_normalized_v3v3(vec1, vec2);
}
float angle_normalized_v3v3(float *v1, float *v2)
{
/* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
if (dot_v3v3(v1, v2) < 0.0f) {
float vec[3];
vec[0]= -v2[0];
vec[1]= -v2[1];
vec[2]= -v2[2];
return (float)M_PI - 2.0f*(float)saasin(len_v3v3(vec, v1)/2.0f);
}
else
return 2.0f*(float)saasin(len_v3v3(v2, v1)/2.0f);
}
float angle_normalized_v2v2(float *v1, float *v2)
{
/* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
if (dot_v2v2(v1, v2) < 0.0f) {
float vec[2];
vec[0]= -v2[0];
vec[1]= -v2[1];
return (float)M_PI - 2.0f*saasin(len_v2v2(vec, v1)/2.0f);
}
else
return 2.0f*(float)saasin(len_v2v2(v2, v1)/2.0f);
}
/********************************* Geometry **********************************/
/* Project v1 on v2 */
void project_v3_v3v3(float *c, float *v1, float *v2)
{
float mul;
mul = dot_v3v3(v1, v2) / dot_v3v3(v2, v2);
c[0] = mul * v2[0];
c[1] = mul * v2[1];
c[2] = mul * v2[2];
}
/* Returns a vector bisecting the angle at v2 formed by v1, v2 and v3 */
void bisect_v3_v3v3v3(float *out, float *v1, float *v2, float *v3)
{
float d_12[3], d_23[3];
sub_v3_v3v3(d_12, v2, v1);
sub_v3_v3v3(d_23, v3, v2);
normalize_v3(d_12);
normalize_v3(d_23);
add_v3_v3v3(out, d_12, d_23);
normalize_v3(out);
}
/* Returns a reflection vector from a vector and a normal vector
reflect = vec - ((2 * DotVecs(vec, mirror)) * mirror)
*/
void reflect_v3_v3v3(float *out, float *v1, float *v2)
{
float vec[3], normal[3];
float reflect[3] = {0.0f, 0.0f, 0.0f};
float dot2;
copy_v3_v3(vec, v1);
copy_v3_v3(normal, v2);
normalize_v3(normal);
dot2 = 2 * dot_v3v3(vec, normal);
reflect[0] = vec[0] - (dot2 * normal[0]);
reflect[1] = vec[1] - (dot2 * normal[1]);
reflect[2] = vec[2] - (dot2 * normal[2]);
copy_v3_v3(out, reflect);
}
void ortho_basis_v3v3_v3(float *v1, float *v2, float *v)
{
const float f = (float)sqrt(v[0]*v[0] + v[1]*v[1]);
if (f < 1e-35f) {
// degenerate case
v1[0] = (v[2] < 0.0f) ? -1.0f : 1.0f;
v1[1] = v1[2] = v2[0] = v2[2] = 0.0f;
v2[1] = 1.0f;
}
else {
const float d= 1.0f/f;
v1[0] = v[1]*d;
v1[1] = -v[0]*d;
v1[2] = 0.0f;
v2[0] = -v[2]*v1[1];
v2[1] = v[2]*v1[0];
v2[2] = v[0]*v1[1] - v[1]*v1[0];
}
}
/*********************************** Other ***********************************/
void print_v2(char *str, float v[2])
{
printf("%s: %.3f %.3f\n", str, v[0], v[1]);
}
void print_v3(char *str, float v[3])
{
printf("%s: %.3f %.3f %.3f\n", str, v[0], v[1], v[2]);
}
void print_v4(char *str, float v[4])
{
printf("%s: %.3f %.3f %.3f %.3f\n", str, v[0], v[1], v[2], v[3]);
}
void normal_short_to_float_v3(float *out, short *in)
{
out[0] = in[0]*(1.0f/32767.0f);
out[1] = in[1]*(1.0f/32767.0f);
out[2] = in[2]*(1.0f/32767.0f);
}
void normal_float_to_short_v3(short *out, float *in)
{
out[0] = (short)(in[0]*32767.0f);
out[1] = (short)(in[1]*32767.0f);
out[2] = (short)(in[2]*32767.0f);
}
void minmax_v3_v3v3(float *min, float *max, float *vec)
{
if(min[0]>vec[0]) min[0]= vec[0];
if(min[1]>vec[1]) min[1]= vec[1];
if(min[2]>vec[2]) min[2]= vec[2];
if(max[0]<vec[0]) max[0]= vec[0];
if(max[1]<vec[1]) max[1]= vec[1];
if(max[2]<vec[2]) max[2]= vec[2];
}