#endif
typedef struct {
+ float x, y;
+} cgm_vec2;
+
+typedef struct {
float x, y, z;
} cgm_vec3;
static inline void cgm_vlerp(cgm_vec3 *res, const cgm_vec3 *a, const cgm_vec3 *b, float t);
+#define cgm_velem(vptr, idx) ((&(vptr)->x)[idx])
+
/* --- operations on cgm_vec4 --- */
static inline void cgm_wcons(cgm_vec4 *v, float x, float y, float z, float w);
static inline void cgm_wmul_m3v4(cgm_vec4 *v, const float *m); /* (m still 16 floats) */
static inline void cgm_wmul_v4m3(cgm_vec4 *v, const float *m); /* (m still 16 floats) */
+static inline float cgm_wdot(const cgm_vec4 *a, const cgm_vec4 *b);
+
static inline float cgm_wlength(const cgm_vec4 *v);
static inline float cgm_wlength_sq(const cgm_vec4 *v);
static inline float cgm_wdist(const cgm_vec4 *a, const cgm_vec4 *b);
static inline void cgm_wlerp(cgm_vec4 *res, const cgm_vec4 *a, const cgm_vec4 *b, float t);
+#define cgm_welem(vptr, idx) ((&(vptr)->x)[idx])
+
/* --- operations on quaternions --- */
static inline void cgm_qcons(cgm_quat *q, float x, float y, float z, float w);
static inline void cgm_qconjugate(cgm_quat *q);
static inline void cgm_qinvert(cgm_quat *q);
-static inline void cgm_qrotation(cgm_quat *q, const cgm_vec3 *axis, float angle);
-static inline void cgm_qrotate(cgm_quat *q, const cgm_vec3 *axis, float angle);
+static inline void cgm_qrotation(cgm_quat *q, float angle, float x, float y, float z);
+static inline void cgm_qrotate(cgm_quat *q, float angle, float x, float y, float z);
static inline void cgm_qslerp(cgm_quat *res, const cgm_quat *a, const cgm_quat *b, float t);
static inline void cgm_qlerp(cgm_quat *res, const cgm_quat *a, const cgm_quat *b, float t);
+#define cgm_qelem(qptr, idx) ((&(qptr)->x)[idx])
+
/* --- operations on matrices --- */
static inline void cgm_mcopy(float *dest, const float *src);
static inline void cgm_mzero(float *m);
static inline float cgm_smoothstep(float a, float b, float x);
static inline float cgm_lerp(float a, float b, float t);
static inline float cgm_bezier(float a, float b, float c, float d, float t);
+static inline float cgm_bspline(float a, float b, float c, float d, float t);
+static inline float cgm_spline(float a, float b, float c, float d, float t);
static inline void cgm_discrand(cgm_vec3 *v, float rad);
static inline void cgm_sphrand(cgm_vec3 *v, float rad);
return (a * omt3) + (b * f * omt) + (c * f * t) + (d * t3);
}
+static inline float cgm_bspline(float a, float b, float c, float d, float t)
+{
+ static const float mat[] = {
+ -1, 3, -3, 1,
+ 3, -6, 0, 4,
+ -3, 3, 3, 1,
+ 1, 0, 0, 0
+ };
+ cgm_vec4 tmp, qfact;
+ float tsq = t * t;
+
+ cgm_wcons(&qfact, tsq * t, tsq, t, 1.0f);
+ cgm_wcons(&tmp, a, b, c, d);
+ cgm_wmul_m4v4(&tmp, mat);
+ cgm_wscale(&tmp, 1.0f / 6.0f);
+ return cgm_wdot(&tmp, &qfact);
+}
+
+static inline float cgm_spline(float a, float b, float c, float d, float t)
+{
+ static const float mat[] = {
+ -1, 2, -1, 0,
+ 3, -5, 0, 2,
+ -3, 4, 1, 0,
+ 1, -1, 0, 0
+ };
+ cgm_vec4 tmp, qfact;
+ float tsq = t * t;
+
+ cgm_wcons(&qfact, tsq * t, tsq, t, 1.0f);
+ cgm_wcons(&tmp, a, b, c, d);
+ cgm_wmul_m4v4(&tmp, mat);
+ cgm_wscale(&tmp, 1.0f / 6.0f);
+ return cgm_wdot(&tmp, &qfact);
+}
+
static inline void cgm_discrand(cgm_vec3 *pt, float rad)
{
float theta = 2.0f * M_PI * (float)rand() / RAND_MAX;
}
}
-static inline void cgm_qrotation(cgm_quat *q, const cgm_vec3 *axis, float angle)
+static inline void cgm_qrotation(cgm_quat *q, float angle, float x, float y, float z)
{
float hangle = angle * 0.5f;
float sin_ha = sin(hangle);
q->w = cos(hangle);
- q->x = axis->x * sin_ha;
- q->y = axis->y * sin_ha;
- q->z = axis->z * sin_ha;
+ q->x = x * sin_ha;
+ q->y = y * sin_ha;
+ q->z = z * sin_ha;
}
-static inline void cgm_qrotate(cgm_quat *q, const cgm_vec3 *axis, float angle)
+static inline void cgm_qrotate(cgm_quat *q, float angle, float x, float y, float z)
{
cgm_quat qrot;
- cgm_qrotation(&qrot, axis, angle);
+ cgm_qrotation(&qrot, angle, x, y, z);
cgm_qmul(q, &qrot);
}