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