1 /* Public domain */
2
3 /*
4 * Operations on m*n matrices (including sparse matrices)
5 */
6 typedef struct m_matrix_ops {
7 const char *name;
8
9 M_Real *(*GetElement)(void *M, Uint i, Uint j);
10 M_Real (*Get)(void *M, Uint i, Uint j);
11 int (*Resize)(void *M, Uint m, Uint n);
12 void (*FreeMatrix)(void *M);
13 void *(*NewMatrix)(Uint m, Uint n);
14
15 void (*SetIdentity)(void *M);
16 void (*SetZero)(void *M);
17 void *(*Transpose)(const void *M);
18 int (*Copy)(void *dst, const void *src);
19 void *(*Dup)(const void *A);
20 void *(*Add)(const void *A, const void *B);
21 int (*Addv)(void *A, const void *B);
22 void *(*DirectSum)(const void *A, const void *B);
23 void *(*Mul)(const void *A, const void *B);
24 int (*Mulv)(const void *A, const void *B, void *AB);
25 void *(*EntMul)(const void *A, const void *B);
26 int (*EntMulv)(const void *A, const void *B, void *AB);
27 int (*Compare)(const void *A, const void *B, M_Real *d);
28 int (*Trace)(M_Real *t, const void *A);
29
30 void *(*Read)(AG_DataSource *ds);
31 void (*Write)(AG_DataSource *ds, const void *M);
32 void (*ToFloats)(float *fv, const void *M);
33 void (*ToDoubles)(double *dv, const void *M);
34 void (*FromFloats)(void *M, const float *fv);
35 void (*FromDoubles)(void *M, const double *dv);
36
37 void *(*GaussJordan)(const void *A, void *b);
38 int (*FactorizeLU)(void *A);
39 void (*BacksubstLU)(void *A, void *b);
40 void (*MNAPreorder)(void *A);
41 void (*AddToDiag)(void *A, M_Real g);
42 } M_MatrixOps;
43
44 /*
45 * Operations on 4x4 matrices.
46 */
47 typedef struct m_matrix_ops44 {
48 const char *name;
49
50 M_Matrix44 (*Zero)(void);
51 void (*Zerov)(M_Matrix44 *A);
52 M_Matrix44 (*Identity)(void);
53 void (*Identityv)(M_Matrix44 *A);
54 M_Matrix44 (*Transpose)(M_Matrix44 A);
55 M_Matrix44 (*Transposep)(const M_Matrix44 *A);
56 void (*Transposev)(M_Matrix44 *A);
57
58 M_Matrix44 (*Invert)(M_Matrix44 A);
59 int (*InvertElim)(M_Matrix44 A, M_Matrix44 *Ainv);
60
61 M_Matrix44 (*Mult)(M_Matrix44 A, M_Matrix44 B);
62 void (*Multv)(M_Matrix44 *A, const M_Matrix44 *B);
63 M_Vector4 (*MultVector)(M_Matrix44 A, M_Vector4 x);
64 M_Vector4 (*MultVectorp)(const M_Matrix44 *A, const M_Vector4 *x);
65 void (*MultVectorv)(M_Vector4 *x, const M_Matrix44 *A);
66
67 void (*Copy)(M_Matrix44 *dst, const M_Matrix44 *src);
68 void (*ToFloats)(float *flts, const M_Matrix44 *A);
69 void (*ToDoubles)(double *dbls, const M_Matrix44 *A);
70 void (*FromFloats)(M_Matrix44 *A, const float *flts);
71 void (*FromDoubles)(M_Matrix44 *A, const double *dbls);
72
73 void (*RotateAxis)(M_Matrix44 *A, M_Real theta, M_Vector3 axis);
74 void (*OrbitAxis)(M_Matrix44 *A, M_Vector3 center, M_Vector3 axis,
75 M_Real theta);
76 void (*RotateEul)(M_Matrix44 *A, M_Real pitch, M_Real roll,
77 M_Real yaw);
78 void (*RotateI)(M_Matrix44 *A, M_Real theta);
79 void (*RotateJ)(M_Matrix44 *A, M_Real theta);
80 void (*RotateK)(M_Matrix44 *A, M_Real theta);
81
82 void (*Translatev)(M_Matrix44 *A, M_Vector3 v);
83 void (*Translate)(M_Matrix44 *A, M_Real x, M_Real y, M_Real z);
84 void (*TranslateX)(M_Matrix44 *A, M_Real c);
85 void (*TranslateY)(M_Matrix44 *A, M_Real c);
86 void (*TranslateZ)(M_Matrix44 *A, M_Real c);
87
88 void (*Scale)(M_Matrix44 *A, M_Real x, M_Real y, M_Real z,
89 M_Real w);
90 void (*UniScale)(M_Matrix44 *A, M_Real c);
91 } M_MatrixOps44;
92
93 /* Debug macros */
94 #ifdef AG_DEBUG
95 # define M_ENTRY_EXISTS(A,i,j) \
96 ((i) >= 0 && (i) < (A)->m && (j) >= 0 && (j) < (A)->n)
97 # define M_ASSERT_COMPAT_MATRICES(A, B, ret) \
98 do { \
99 if (MROWS(A) != MROWS(B) || \
100 MCOLS(A) != MCOLS(B)) { \
101 AG_SetError("Incompatible matrices"); \
102 return (ret); \
103 } \
104 } while (0)
105 # define M_ASSERT_MULTIPLIABLE_MATRICES(A, B, ret) \
106 do { \
107 if (MROWS(A) != MROWS(B) || \
108 MCOLS(A) != MCOLS(B)) { \
109 AG_SetError("Incompatible matrices"); \
110 return (ret); \
111 } \
112 } while (0)
113 # define M_ASSERT_SQUARE_MATRIX(A, ret) \
114 do { \
115 if (MROWS(A) != MCOLS(A)) { \
116 AG_SetError("Incompatible matrices"); \
117 return (ret); \
118 } \
119 } while (0)
120 #else
121 # define M_ENTRY_EXISTS(A,i,j) 1
122 # define M_ASSERT_COMPAT_MATRICES(A, B, ret)
123 # define M_ASSERT_MULTIPLIABLE_MATRICES(A, B, ret)
124 # define M_ASSERT_SQUARE_MATRIX(A, ret)
125 #endif
126
127 /* Backends */
128 __BEGIN_DECLS
129 extern const M_MatrixOps *mMatOps;
130 extern const M_MatrixOps44 *mMatOps44;
131 __END_DECLS
132
133 #include <agar/math/m_matrix_fpu.h>
134 #include <agar/math/m_matrix44_fpu.h>
135 #include <agar/math/m_matrix44_sse.h>
136 #include <agar/math/m_matrix_sparse.h>
137
138 /* Operations on m*n matrices. */
139 #define M_New mMatOps->NewMatrix
140 #define M_Free mMatOps->FreeMatrix
141 #define M_Resize mMatOps->Resize
142 #define M_Get mMatOps->Get
143 #define M_GetElement mMatOps->GetElement
144 #define M_SetIdentity mMatOps->SetIdentity
145 #define M_SetZero mMatOps->SetZero
146 #define M_Transpose mMatOps->Transpose
147 #define M_Copy mMatOps->Copy
148 #define M_Dup mMatOps->Dup
149 #define M_Add mMatOps->Add
150 #define M_Addv mMatOps->Addv
151 #define M_DirectSum mMatOps->DirectSum
152 #define M_Mul mMatOps->Mul
153 #define M_Mulv mMatOps->Mulv
154 #define M_EntMul mMatOps->EntMul
155 #define M_EntMulv mMatOps->EntMulv
156 #define M_Compare mMatOps->Compare
157 #define M_Trace mMatOps->Trace
158 #define M_ReadMatrix mMatOps->Read
159 #define M_WriteMatrix mMatOps->Write
160 #define M_ToFloats mMatOps->ToFloats
161 #define M_ToDoubles mMatOps->ToDoubles
162 #define M_FromFloats mMatOps->FromFloats
163 #define M_FromDoubles mMatOps->FromDoubles
164 #define M_GaussJordan mMatOps->GaussJordan
165 #define M_FactorizeLU mMatOps->FactorizeLU
166 #define M_BacksubstLU mMatOps->BacksubstLU
167 #define M_MNAPreorder mMatOps->MNAPreorder
168 #define M_AddToDiag mMatOps->AddToDiag
169
170 /* Operations on 4x4 matrices. */
171 #define M_MatZero44 mMatOps44->Zero
172 #define M_MatZero44v mMatOps44->Zerov
173 #define M_MatIdentity44 mMatOps44->Identity
174 #define M_MatIdentity44v mMatOps44->Identityv
175 #define M_MatTranspose44 mMatOps44->Transpose
176 #define M_MatTranspose44p mMatOps44->Transposep
177 #define M_MatTranspose44v mMatOps44->Transposev
178 #define M_MatInvertElim44 mMatOps44->InvertElim
179 #define M_MatMultVector44 mMatOps44->MultVector
180 #define M_MatMultVector44p mMatOps44->MultVectorp
181 #define M_MatMultVector44v mMatOps44->MultVectorv
182 #define M_MatCopy44 mMatOps44->Copy
183 #define M_MatToFloats44 mMatOps44->ToFloats
184 #define M_MatToDoubles44 mMatOps44->ToDoubles
185 #define M_MatFromFloats44 mMatOps44->FromFloats
186 #define M_MatFromDoubles44 mMatOps44->FromDoubles
187 #define M_MatRotateAxis44 mMatOps44->RotateAxis
188 #define M_MatOrbitAxis44 mMatOps44->OrbitAxis
189 #define M_MatRotateEul44 mMatOps44->RotateEul
190 #define M_MatRotate44I mMatOps44->RotateI
191 #define M_MatRotate44J mMatOps44->RotateJ
192 #define M_MatRotate44K mMatOps44->RotateK
193 #define M_MatTranslate44v mMatOps44->Translatev
194 #define M_MatTranslate44 mMatOps44->Translate
195 #define M_MatTranslate44X mMatOps44->TranslateX
196 #define M_MatTranslate44Y mMatOps44->TranslateY
197 #define M_MatTranslate44Z mMatOps44->TranslateZ
198 #define M_MatScale44 mMatOps44->Scale
199 #define M_MatUniScale44 mMatOps44->UniScale
200 #if defined(INLINE_SSE)
201 # define M_MatInvert44 M_MatrixInvert44_SSE
202 # define M_MatMult44 M_MatrixMult44_SSE
203 # define M_MatMult44v M_MatrixMult44v_SSE
204 #else /* !INLINE_SSE */
205 # define M_MatInvert44 mMatOps44->Invert
206 # define M_MatMult44 mMatOps44->Mult
207 # define M_MatMult44v mMatOps44->Multv
208 #endif /* INLINE_SSE */
209
210 __BEGIN_DECLS
211 void M_MatrixInitEngine(void);
212 M_Matrix44 M_ReadMatrix44(AG_DataSource *);
213 void M_ReadMatrix44v(AG_DataSource *, M_Matrix44 *);
214 void M_WriteMatrix44(AG_DataSource *, const M_Matrix44 *);
215
216 /* Return 1 if the given matrix is square. */
217 static __inline__ int
M_IsSquare(const M_Matrix * M)218 M_IsSquare(const M_Matrix *M)
219 {
220 return (M->m == M->n);
221 }
222 static __inline__ void
M_Set(M_Matrix * M,Uint i,Uint j,M_Real val)223 M_Set(M_Matrix *M, Uint i, Uint j, M_Real val)
224 {
225 M_Real *v = M_GetElement(M, i,j);
226 *v = val;
227 }
228 __END_DECLS
229