mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-14 08:50:58 +00:00
54b4d589aa
This should make maintaining them a little easier. The copyright block in most of the new headers (execpt vector.h) reflect when the functions in the relevant header were first created.
194 lines
5 KiB
C
194 lines
5 KiB
C
/*
|
|
dual.h
|
|
|
|
Dual and dual-quaternion functions
|
|
|
|
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
|
|
|
|
Author: Bill Currie <bill@taniwha.org>
|
|
Date: 2012/5/1
|
|
|
|
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:
|
|
|
|
Free Software Foundation, Inc.
|
|
59 Temple Place - Suite 330
|
|
Boston, MA 02111-1307, USA
|
|
|
|
*/
|
|
|
|
#ifndef __QF_math_dual_h
|
|
#define __QF_math_dual_h
|
|
|
|
/** \defgroup mathlib_dual Dual and dual quaternion functions
|
|
\ingroup utils
|
|
*/
|
|
//@{
|
|
|
|
#include "QF/qtypes.h"
|
|
|
|
#define DualAdd(a,b,c) \
|
|
do { \
|
|
(c).r = (a).r + (b).r; \
|
|
(c).e = (a).e + (b).e; \
|
|
} while (0)
|
|
#define DualSubtract(a,b,c) \
|
|
do { \
|
|
(c).r = (a).r - (b).r; \
|
|
(c).e = (a).e - (b).e; \
|
|
} while (0)
|
|
#define DualNegate(a,b) \
|
|
do { \
|
|
(b).r = -(a).r; \
|
|
(b).e = -(a).e; \
|
|
} while (0)
|
|
#define DualConj(a,b) \
|
|
do { \
|
|
(b).r = (a).r; \
|
|
(b).e = -(a).e; \
|
|
} while (0)
|
|
#define DualMult(a,b,c) \
|
|
do { \
|
|
(c).e = (a).r * (b).e + (a).e * (b).r; \
|
|
(c).r = (a).r * (b).r; \
|
|
} while (0)
|
|
#define DualMultAdd(a,s,b,c) \
|
|
do { \
|
|
(c).r = (a).r + (s) * (b).r; \
|
|
(c).e = (a).e + (s) * (b).e; \
|
|
} while (0)
|
|
#define DualMultSub(a,s,b,c) \
|
|
do { \
|
|
(c).r = (a).r - (s) * (b).r; \
|
|
(c).e = (a).e - (s) * (b).e; \
|
|
} while (0)
|
|
#define DualNorm(a) ((a).r)
|
|
#define DualScale(a,b,c) \
|
|
do { \
|
|
(c).r = (a).r * (b); \
|
|
(c).e = (a).e * (b); \
|
|
} while (0)
|
|
#define DualCompCompare(x, op, y) ((x).r op (y).r) && ((x).e op (y).e)
|
|
#define DualCompare(x, y) DualCompCompare (x, ==, y)
|
|
#define DualIsZero(a) ((a).r == 0 && (a).e == 0)
|
|
#define DualIsUnit(a) (((a).r - 1) * ((a).r - 1) < 1e-6 && (a).e * (a).e < 1e-6)
|
|
#define DualSet(ar,ae,a) \
|
|
do { \
|
|
(a).ar = r; \
|
|
(a).er = r; \
|
|
} while (0)
|
|
#define DualZero(a) \
|
|
do { \
|
|
(a).e = (a).r = 0; \
|
|
} while (0)
|
|
#define DualBlend(d1,d2,b,d) \
|
|
do { \
|
|
(d).r = (d1).r * (1 - (b)) + (d2).r * (b); \
|
|
(d).e = (d1).e * (1 - (b)) + (d2).e * (b); \
|
|
} while (0)
|
|
#define DualExpand(d) (d).r, (d).e
|
|
|
|
#define DualQuatAdd(a,b,c) \
|
|
do { \
|
|
QuatAdd ((a).q0.q, (b).q0.q, (c).q0.q); \
|
|
QuatAdd ((a).qe.q, (b).qe.q, (c).qe.q); \
|
|
} while (0)
|
|
#define DualQuatSubtract(a,b,c) \
|
|
do { \
|
|
QuatSub ((a).q0.q, (b).q0.q, (c).q0.q); \
|
|
QuatSub ((a).qe.q, (b).qe.q, (c).qe.q); \
|
|
} while (0)
|
|
#define DualQuatNegate(a,b) \
|
|
do { \
|
|
QuatNegate ((a).q0.q, (b).q0.q); \
|
|
QuatNegate ((a).qe.q, (b).qe.q); \
|
|
} while (0)
|
|
#define DualQuatConjQ(a,b) \
|
|
do { \
|
|
QuatConj ((a).q0.q, (b).q0.q); \
|
|
QuatConj ((a).qe.q, (b).qe.q); \
|
|
} while (0)
|
|
#define DualQuatConjE(a,b) \
|
|
do { \
|
|
(b).q0 = (a).q0; \
|
|
QuatNegate ((a).qe.q, (b).qe.q); \
|
|
} while (0)
|
|
#define DualQuatConjQE(a,b) \
|
|
do { \
|
|
QuatConj ((a).q0.q, (b).q0.q); \
|
|
(b).qe.sv.s = -(a).qe.sv.s; \
|
|
VectorCopy ((a).qe.sv.v, (b).qe.sv.v); \
|
|
} while (0)
|
|
#define DualQuatMult(a,b,c) \
|
|
do { \
|
|
Quat_t t; \
|
|
QuatMult ((a).q0.q, (b).qe.q, t.q); \
|
|
QuatMult ((a).qe.q, (b).q0.q, (c).qe.q); \
|
|
QuatAdd (t.q, (c).qe.q, (c).qe.q); \
|
|
QuatMult ((a).q0.q, (b).q0.q, (c).q0.q); \
|
|
} while (0);
|
|
#define DualQuatMultAdd(a,s,b,c) \
|
|
do { \
|
|
QuatMultAdd ((a).q0.q, s, (b).q0.q, (c).q0.q); \
|
|
QuatMultAdd ((a).qe.q, s, (b).qe.q, (c).qe.q); \
|
|
} while (0)
|
|
#define DualQuatMultSub(a,s,b,c) \
|
|
do { \
|
|
QuatMultSub ((a).q0.q, s, (b).q0.q, (c).q0.q); \
|
|
QuatMultSub ((a).qe.q, s, (b).qe.q, (c).qe.q); \
|
|
} while (0)
|
|
#define DualQuatNorm(a,b) \
|
|
do { \
|
|
(b).r = QuatLength ((a).q0.q); \
|
|
(b).e = 2 * QDotProduct ((a).q0.q, (a).qe.q); \
|
|
} while (0)
|
|
#define DualQuatScale(a,b,c) \
|
|
do { \
|
|
QuatSub ((a).q0.q, (b), (c).q0.q); \
|
|
QuatSub ((a).qe.q, (b), (c).qe.q); \
|
|
} while (0)
|
|
#define DualQuatCompCompare(x, op, y) \
|
|
(QuatCompCompare ((x).q0.q, op, (y).q0.q) \
|
|
&&QuatCompCompare ((x).qe.q, op, (y).qe.q))
|
|
#define DualQuatCompare(x, y) DualQuatCompCompare (x, ==, y)
|
|
#define DualQuatIsZero(a) (QuatIsZero ((a).q0.q) && QuatIsZero ((a).qe.q))
|
|
#define DualQuatSetVect(vec, a) \
|
|
do { \
|
|
(a).q0.sv.s = 1; \
|
|
VectorZero ((a).q0.sv.v); \
|
|
(a).qe.sv.s = 0; \
|
|
VectorCopy (vec, (a).qe.sv.v); \
|
|
} while (0)
|
|
#define DualQuatRotTrans(rot, trans, dq) \
|
|
do { \
|
|
QuatCopy (rot, (dq).q0.q); \
|
|
(dq).qe.sv.s = 0; \
|
|
VectorScale (trans, 0.5, (dq).qe.sv.v); \
|
|
QuatMult ((dq).qe.q, (dq).q0.q, (dq).qe.q); \
|
|
} while (0)
|
|
#define DualQuatZero(a) \
|
|
do { \
|
|
QuatZero ((a).q0.q); \
|
|
QuatZero ((a).qe.q); \
|
|
} while (0)
|
|
#define DualQuatBlend(dq1,dq2,b,dq) \
|
|
do { \
|
|
QuatBlend ((dq1).q0.q, (dq2).q0.q, (b), (dq).q0.q); \
|
|
QuatBlend ((dq1).qe.q, (dq2).qe.q, (b), (dq).qe.q); \
|
|
} while (0)
|
|
#define DualQuatExpand(dq) QuatExpand ((dq).q0.q), QuatExpand ((dq).qe.q)
|
|
|
|
//@}
|
|
|
|
#endif // __QF_math_dual_h
|