7 #pragma warning(disable : 4244) // LordHavoc: MSVC++ 4 x86, double/float
8 #pragma warning(disable : 4305) // LordHavoc: MSVC++ 6 x86, double/float
11 const matrix4x4_t identitymatrix =
21 void Matrix4x4_Copy (matrix4x4_t *out, const matrix4x4_t *in)
26 void Matrix4x4_CopyRotateOnly (matrix4x4_t *out, const matrix4x4_t *in)
28 out->m[0][0] = in->m[0][0];
29 out->m[0][1] = in->m[0][1];
30 out->m[0][2] = in->m[0][2];
32 out->m[1][0] = in->m[1][0];
33 out->m[1][1] = in->m[1][1];
34 out->m[1][2] = in->m[1][2];
36 out->m[2][0] = in->m[2][0];
37 out->m[2][1] = in->m[2][1];
38 out->m[2][2] = in->m[2][2];
46 void Matrix4x4_CopyTranslateOnly (matrix4x4_t *out, const matrix4x4_t *in)
48 #ifdef MATRIX4x4_OPENGLORIENTATION
52 out->m[3][0] = in->m[0][3];
56 out->m[3][1] = in->m[1][3];
60 out->m[3][2] = in->m[2][3];
69 out->m[0][3] = in->m[0][3];
73 out->m[1][3] = in->m[1][3];
77 out->m[2][3] = in->m[2][3];
85 void Matrix4x4_Concat (matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4_t *in2)
87 #ifdef MATRIX4x4_OPENGLORIENTATION
88 out->m[0][0] = in1->m[0][0] * in2->m[0][0] + in1->m[1][0] * in2->m[0][1] + in1->m[2][0] * in2->m[0][2] + in1->m[3][0] * in2->m[0][3];
89 out->m[1][0] = in1->m[0][0] * in2->m[1][0] + in1->m[1][0] * in2->m[1][1] + in1->m[2][0] * in2->m[1][2] + in1->m[3][0] * in2->m[1][3];
90 out->m[2][0] = in1->m[0][0] * in2->m[2][0] + in1->m[1][0] * in2->m[2][1] + in1->m[2][0] * in2->m[2][2] + in1->m[3][0] * in2->m[2][3];
91 out->m[3][0] = in1->m[0][0] * in2->m[3][0] + in1->m[1][0] * in2->m[3][1] + in1->m[2][0] * in2->m[3][2] + in1->m[3][0] * in2->m[3][3];
92 out->m[0][1] = in1->m[0][1] * in2->m[0][0] + in1->m[1][1] * in2->m[0][1] + in1->m[2][1] * in2->m[0][2] + in1->m[3][1] * in2->m[0][3];
93 out->m[1][1] = in1->m[0][1] * in2->m[1][0] + in1->m[1][1] * in2->m[1][1] + in1->m[2][1] * in2->m[1][2] + in1->m[3][1] * in2->m[1][3];
94 out->m[2][1] = in1->m[0][1] * in2->m[2][0] + in1->m[1][1] * in2->m[2][1] + in1->m[2][1] * in2->m[2][2] + in1->m[3][1] * in2->m[2][3];
95 out->m[3][1] = in1->m[0][1] * in2->m[3][0] + in1->m[1][1] * in2->m[3][1] + in1->m[2][1] * in2->m[3][2] + in1->m[3][1] * in2->m[3][3];
96 out->m[0][2] = in1->m[0][2] * in2->m[0][0] + in1->m[1][2] * in2->m[0][1] + in1->m[2][2] * in2->m[0][2] + in1->m[3][2] * in2->m[0][3];
97 out->m[1][2] = in1->m[0][2] * in2->m[1][0] + in1->m[1][2] * in2->m[1][1] + in1->m[2][2] * in2->m[1][2] + in1->m[3][2] * in2->m[1][3];
98 out->m[2][2] = in1->m[0][2] * in2->m[2][0] + in1->m[1][2] * in2->m[2][1] + in1->m[2][2] * in2->m[2][2] + in1->m[3][2] * in2->m[2][3];
99 out->m[3][2] = in1->m[0][2] * in2->m[3][0] + in1->m[1][2] * in2->m[3][1] + in1->m[2][2] * in2->m[3][2] + in1->m[3][2] * in2->m[3][3];
100 out->m[0][3] = in1->m[0][3] * in2->m[0][0] + in1->m[1][3] * in2->m[0][1] + in1->m[2][3] * in2->m[0][2] + in1->m[3][3] * in2->m[0][3];
101 out->m[1][3] = in1->m[0][3] * in2->m[1][0] + in1->m[1][3] * in2->m[1][1] + in1->m[2][3] * in2->m[1][2] + in1->m[3][3] * in2->m[1][3];
102 out->m[2][3] = in1->m[0][3] * in2->m[2][0] + in1->m[1][3] * in2->m[2][1] + in1->m[2][3] * in2->m[2][2] + in1->m[3][3] * in2->m[2][3];
103 out->m[3][3] = in1->m[0][3] * in2->m[3][0] + in1->m[1][3] * in2->m[3][1] + in1->m[2][3] * in2->m[3][2] + in1->m[3][3] * in2->m[3][3];
105 out->m[0][0] = in1->m[0][0] * in2->m[0][0] + in1->m[0][1] * in2->m[1][0] + in1->m[0][2] * in2->m[2][0] + in1->m[0][3] * in2->m[3][0];
106 out->m[0][1] = in1->m[0][0] * in2->m[0][1] + in1->m[0][1] * in2->m[1][1] + in1->m[0][2] * in2->m[2][1] + in1->m[0][3] * in2->m[3][1];
107 out->m[0][2] = in1->m[0][0] * in2->m[0][2] + in1->m[0][1] * in2->m[1][2] + in1->m[0][2] * in2->m[2][2] + in1->m[0][3] * in2->m[3][2];
108 out->m[0][3] = in1->m[0][0] * in2->m[0][3] + in1->m[0][1] * in2->m[1][3] + in1->m[0][2] * in2->m[2][3] + in1->m[0][3] * in2->m[3][3];
109 out->m[1][0] = in1->m[1][0] * in2->m[0][0] + in1->m[1][1] * in2->m[1][0] + in1->m[1][2] * in2->m[2][0] + in1->m[1][3] * in2->m[3][0];
110 out->m[1][1] = in1->m[1][0] * in2->m[0][1] + in1->m[1][1] * in2->m[1][1] + in1->m[1][2] * in2->m[2][1] + in1->m[1][3] * in2->m[3][1];
111 out->m[1][2] = in1->m[1][0] * in2->m[0][2] + in1->m[1][1] * in2->m[1][2] + in1->m[1][2] * in2->m[2][2] + in1->m[1][3] * in2->m[3][2];
112 out->m[1][3] = in1->m[1][0] * in2->m[0][3] + in1->m[1][1] * in2->m[1][3] + in1->m[1][2] * in2->m[2][3] + in1->m[1][3] * in2->m[3][3];
113 out->m[2][0] = in1->m[2][0] * in2->m[0][0] + in1->m[2][1] * in2->m[1][0] + in1->m[2][2] * in2->m[2][0] + in1->m[2][3] * in2->m[3][0];
114 out->m[2][1] = in1->m[2][0] * in2->m[0][1] + in1->m[2][1] * in2->m[1][1] + in1->m[2][2] * in2->m[2][1] + in1->m[2][3] * in2->m[3][1];
115 out->m[2][2] = in1->m[2][0] * in2->m[0][2] + in1->m[2][1] * in2->m[1][2] + in1->m[2][2] * in2->m[2][2] + in1->m[2][3] * in2->m[3][2];
116 out->m[2][3] = in1->m[2][0] * in2->m[0][3] + in1->m[2][1] * in2->m[1][3] + in1->m[2][2] * in2->m[2][3] + in1->m[2][3] * in2->m[3][3];
117 out->m[3][0] = in1->m[3][0] * in2->m[0][0] + in1->m[3][1] * in2->m[1][0] + in1->m[3][2] * in2->m[2][0] + in1->m[3][3] * in2->m[3][0];
118 out->m[3][1] = in1->m[3][0] * in2->m[0][1] + in1->m[3][1] * in2->m[1][1] + in1->m[3][2] * in2->m[2][1] + in1->m[3][3] * in2->m[3][1];
119 out->m[3][2] = in1->m[3][0] * in2->m[0][2] + in1->m[3][1] * in2->m[1][2] + in1->m[3][2] * in2->m[2][2] + in1->m[3][3] * in2->m[3][2];
120 out->m[3][3] = in1->m[3][0] * in2->m[0][3] + in1->m[3][1] * in2->m[1][3] + in1->m[3][2] * in2->m[2][3] + in1->m[3][3] * in2->m[3][3];
124 void Matrix4x4_Transpose (matrix4x4_t *out, const matrix4x4_t *in1)
126 out->m[0][0] = in1->m[0][0];
127 out->m[0][1] = in1->m[1][0];
128 out->m[0][2] = in1->m[2][0];
129 out->m[0][3] = in1->m[3][0];
130 out->m[1][0] = in1->m[0][1];
131 out->m[1][1] = in1->m[1][1];
132 out->m[1][2] = in1->m[2][1];
133 out->m[1][3] = in1->m[3][1];
134 out->m[2][0] = in1->m[0][2];
135 out->m[2][1] = in1->m[1][2];
136 out->m[2][2] = in1->m[2][2];
137 out->m[2][3] = in1->m[3][2];
138 out->m[3][0] = in1->m[0][3];
139 out->m[3][1] = in1->m[1][3];
140 out->m[3][2] = in1->m[2][3];
141 out->m[3][3] = in1->m[3][3];
145 // Adapted from code contributed to Mesa by David Moore (Mesa 7.6 under SGI Free License B - which is MIT/X11-type)
146 int Matrix4x4_Invert_Full (matrix4x4_t *out, const matrix4x4_t *in1)
152 #ifdef MATRIX4x4_OPENGLORIENTATION
153 temp.m[0][0] = in1->m[1][1]*in1->m[2][2]*in1->m[3][3] - in1->m[1][1]*in1->m[2][3]*in1->m[3][2] - in1->m[2][1]*in1->m[1][2]*in1->m[3][3] + in1->m[2][1]*in1->m[1][3]*in1->m[3][2] + in1->m[3][1]*in1->m[1][2]*in1->m[2][3] - in1->m[3][1]*in1->m[1][3]*in1->m[2][2];
154 temp.m[1][0] = -in1->m[1][0]*in1->m[2][2]*in1->m[3][3] + in1->m[1][0]*in1->m[2][3]*in1->m[3][2] + in1->m[2][0]*in1->m[1][2]*in1->m[3][3] - in1->m[2][0]*in1->m[1][3]*in1->m[3][2] - in1->m[3][0]*in1->m[1][2]*in1->m[2][3] + in1->m[3][0]*in1->m[1][3]*in1->m[2][2];
155 temp.m[2][0] = in1->m[1][0]*in1->m[2][1]*in1->m[3][3] - in1->m[1][0]*in1->m[2][3]*in1->m[3][1] - in1->m[2][0]*in1->m[1][1]*in1->m[3][3] + in1->m[2][0]*in1->m[1][3]*in1->m[3][1] + in1->m[3][0]*in1->m[1][1]*in1->m[2][3] - in1->m[3][0]*in1->m[1][3]*in1->m[2][1];
156 temp.m[3][0] = -in1->m[1][0]*in1->m[2][1]*in1->m[3][2] + in1->m[1][0]*in1->m[2][2]*in1->m[3][1] + in1->m[2][0]*in1->m[1][1]*in1->m[3][2] - in1->m[2][0]*in1->m[1][2]*in1->m[3][1] - in1->m[3][0]*in1->m[1][1]*in1->m[2][2] + in1->m[3][0]*in1->m[1][2]*in1->m[2][1];
157 temp.m[0][1] = -in1->m[0][1]*in1->m[2][2]*in1->m[3][3] + in1->m[0][1]*in1->m[2][3]*in1->m[3][2] + in1->m[2][1]*in1->m[0][2]*in1->m[3][3] - in1->m[2][1]*in1->m[0][3]*in1->m[3][2] - in1->m[3][1]*in1->m[0][2]*in1->m[2][3] + in1->m[3][1]*in1->m[0][3]*in1->m[2][2];
158 temp.m[1][1] = in1->m[0][0]*in1->m[2][2]*in1->m[3][3] - in1->m[0][0]*in1->m[2][3]*in1->m[3][2] - in1->m[2][0]*in1->m[0][2]*in1->m[3][3] + in1->m[2][0]*in1->m[0][3]*in1->m[3][2] + in1->m[3][0]*in1->m[0][2]*in1->m[2][3] - in1->m[3][0]*in1->m[0][3]*in1->m[2][2];
159 temp.m[2][1] = -in1->m[0][0]*in1->m[2][1]*in1->m[3][3] + in1->m[0][0]*in1->m[2][3]*in1->m[3][1] + in1->m[2][0]*in1->m[0][1]*in1->m[3][3] - in1->m[2][0]*in1->m[0][3]*in1->m[3][1] - in1->m[3][0]*in1->m[0][1]*in1->m[2][3] + in1->m[3][0]*in1->m[0][3]*in1->m[2][1];
160 temp.m[3][1] = in1->m[0][0]*in1->m[2][1]*in1->m[3][2] - in1->m[0][0]*in1->m[2][2]*in1->m[3][1] - in1->m[2][0]*in1->m[0][1]*in1->m[3][2] + in1->m[2][0]*in1->m[0][2]*in1->m[3][1] + in1->m[3][0]*in1->m[0][1]*in1->m[2][2] - in1->m[3][0]*in1->m[0][2]*in1->m[2][1];
161 temp.m[0][2] = in1->m[0][1]*in1->m[1][2]*in1->m[3][3] - in1->m[0][1]*in1->m[1][3]*in1->m[3][2] - in1->m[1][1]*in1->m[0][2]*in1->m[3][3] + in1->m[1][1]*in1->m[0][3]*in1->m[3][2] + in1->m[3][1]*in1->m[0][2]*in1->m[1][3] - in1->m[3][1]*in1->m[0][3]*in1->m[1][2];
162 temp.m[1][2] = -in1->m[0][0]*in1->m[1][2]*in1->m[3][3] + in1->m[0][0]*in1->m[1][3]*in1->m[3][2] + in1->m[1][0]*in1->m[0][2]*in1->m[3][3] - in1->m[1][0]*in1->m[0][3]*in1->m[3][2] - in1->m[3][0]*in1->m[0][2]*in1->m[1][3] + in1->m[3][0]*in1->m[0][3]*in1->m[1][2];
163 temp.m[2][2] = in1->m[0][0]*in1->m[1][1]*in1->m[3][3] - in1->m[0][0]*in1->m[1][3]*in1->m[3][1] - in1->m[1][0]*in1->m[0][1]*in1->m[3][3] + in1->m[1][0]*in1->m[0][3]*in1->m[3][1] + in1->m[3][0]*in1->m[0][1]*in1->m[1][3] - in1->m[3][0]*in1->m[0][3]*in1->m[1][1];
164 temp.m[3][2] = -in1->m[0][0]*in1->m[1][1]*in1->m[3][2] + in1->m[0][0]*in1->m[1][2]*in1->m[3][1] + in1->m[1][0]*in1->m[0][1]*in1->m[3][2] - in1->m[1][0]*in1->m[0][2]*in1->m[3][1] - in1->m[3][0]*in1->m[0][1]*in1->m[1][2] + in1->m[3][0]*in1->m[0][2]*in1->m[1][1];
165 temp.m[0][3] = -in1->m[0][1]*in1->m[1][2]*in1->m[2][3] + in1->m[0][1]*in1->m[1][3]*in1->m[2][2] + in1->m[1][1]*in1->m[0][2]*in1->m[2][3] - in1->m[1][1]*in1->m[0][3]*in1->m[2][2] - in1->m[2][1]*in1->m[0][2]*in1->m[1][3] + in1->m[2][1]*in1->m[0][3]*in1->m[1][2];
166 temp.m[1][3] = in1->m[0][0]*in1->m[1][2]*in1->m[2][3] - in1->m[0][0]*in1->m[1][3]*in1->m[2][2] - in1->m[1][0]*in1->m[0][2]*in1->m[2][3] + in1->m[1][0]*in1->m[0][3]*in1->m[2][2] + in1->m[2][0]*in1->m[0][2]*in1->m[1][3] - in1->m[2][0]*in1->m[0][3]*in1->m[1][2];
167 temp.m[2][3] = -in1->m[0][0]*in1->m[1][1]*in1->m[2][3] + in1->m[0][0]*in1->m[1][3]*in1->m[2][1] + in1->m[1][0]*in1->m[0][1]*in1->m[2][3] - in1->m[1][0]*in1->m[0][3]*in1->m[2][1] - in1->m[2][0]*in1->m[0][1]*in1->m[1][3] + in1->m[2][0]*in1->m[0][3]*in1->m[1][1];
168 temp.m[3][3] = in1->m[0][0]*in1->m[1][1]*in1->m[2][2] - in1->m[0][0]*in1->m[1][2]*in1->m[2][1] - in1->m[1][0]*in1->m[0][1]*in1->m[2][2] + in1->m[1][0]*in1->m[0][2]*in1->m[2][1] + in1->m[2][0]*in1->m[0][1]*in1->m[1][2] - in1->m[2][0]*in1->m[0][2]*in1->m[1][1];
170 temp.m[0][0] = in1->m[1][1]*in1->m[2][2]*in1->m[3][3] - in1->m[1][1]*in1->m[3][2]*in1->m[2][3] - in1->m[1][2]*in1->m[2][1]*in1->m[3][3] + in1->m[1][2]*in1->m[3][1]*in1->m[2][3] + in1->m[1][3]*in1->m[2][1]*in1->m[3][2] - in1->m[1][3]*in1->m[3][1]*in1->m[2][2];
171 temp.m[0][1] = -in1->m[0][1]*in1->m[2][2]*in1->m[3][3] + in1->m[0][1]*in1->m[3][2]*in1->m[2][3] + in1->m[0][2]*in1->m[2][1]*in1->m[3][3] - in1->m[0][2]*in1->m[3][1]*in1->m[2][3] - in1->m[0][3]*in1->m[2][1]*in1->m[3][2] + in1->m[0][3]*in1->m[3][1]*in1->m[2][2];
172 temp.m[0][2] = in1->m[0][1]*in1->m[1][2]*in1->m[3][3] - in1->m[0][1]*in1->m[3][2]*in1->m[1][3] - in1->m[0][2]*in1->m[1][1]*in1->m[3][3] + in1->m[0][2]*in1->m[3][1]*in1->m[1][3] + in1->m[0][3]*in1->m[1][1]*in1->m[3][2] - in1->m[0][3]*in1->m[3][1]*in1->m[1][2];
173 temp.m[0][3] = -in1->m[0][1]*in1->m[1][2]*in1->m[2][3] + in1->m[0][1]*in1->m[2][2]*in1->m[1][3] + in1->m[0][2]*in1->m[1][1]*in1->m[2][3] - in1->m[0][2]*in1->m[2][1]*in1->m[1][3] - in1->m[0][3]*in1->m[1][1]*in1->m[2][2] + in1->m[0][3]*in1->m[2][1]*in1->m[1][2];
174 temp.m[1][0] = -in1->m[1][0]*in1->m[2][2]*in1->m[3][3] + in1->m[1][0]*in1->m[3][2]*in1->m[2][3] + in1->m[1][2]*in1->m[2][0]*in1->m[3][3] - in1->m[1][2]*in1->m[3][0]*in1->m[2][3] - in1->m[1][3]*in1->m[2][0]*in1->m[3][2] + in1->m[1][3]*in1->m[3][0]*in1->m[2][2];
175 temp.m[1][1] = in1->m[0][0]*in1->m[2][2]*in1->m[3][3] - in1->m[0][0]*in1->m[3][2]*in1->m[2][3] - in1->m[0][2]*in1->m[2][0]*in1->m[3][3] + in1->m[0][2]*in1->m[3][0]*in1->m[2][3] + in1->m[0][3]*in1->m[2][0]*in1->m[3][2] - in1->m[0][3]*in1->m[3][0]*in1->m[2][2];
176 temp.m[1][2] = -in1->m[0][0]*in1->m[1][2]*in1->m[3][3] + in1->m[0][0]*in1->m[3][2]*in1->m[1][3] + in1->m[0][2]*in1->m[1][0]*in1->m[3][3] - in1->m[0][2]*in1->m[3][0]*in1->m[1][3] - in1->m[0][3]*in1->m[1][0]*in1->m[3][2] + in1->m[0][3]*in1->m[3][0]*in1->m[1][2];
177 temp.m[1][3] = in1->m[0][0]*in1->m[1][2]*in1->m[2][3] - in1->m[0][0]*in1->m[2][2]*in1->m[1][3] - in1->m[0][2]*in1->m[1][0]*in1->m[2][3] + in1->m[0][2]*in1->m[2][0]*in1->m[1][3] + in1->m[0][3]*in1->m[1][0]*in1->m[2][2] - in1->m[0][3]*in1->m[2][0]*in1->m[1][2];
178 temp.m[2][0] = in1->m[1][0]*in1->m[2][1]*in1->m[3][3] - in1->m[1][0]*in1->m[3][1]*in1->m[2][3] - in1->m[1][1]*in1->m[2][0]*in1->m[3][3] + in1->m[1][1]*in1->m[3][0]*in1->m[2][3] + in1->m[1][3]*in1->m[2][0]*in1->m[3][1] - in1->m[1][3]*in1->m[3][0]*in1->m[2][1];
179 temp.m[2][1] = -in1->m[0][0]*in1->m[2][1]*in1->m[3][3] + in1->m[0][0]*in1->m[3][1]*in1->m[2][3] + in1->m[0][1]*in1->m[2][0]*in1->m[3][3] - in1->m[0][1]*in1->m[3][0]*in1->m[2][3] - in1->m[0][3]*in1->m[2][0]*in1->m[3][1] + in1->m[0][3]*in1->m[3][0]*in1->m[2][1];
180 temp.m[2][2] = in1->m[0][0]*in1->m[1][1]*in1->m[3][3] - in1->m[0][0]*in1->m[3][1]*in1->m[1][3] - in1->m[0][1]*in1->m[1][0]*in1->m[3][3] + in1->m[0][1]*in1->m[3][0]*in1->m[1][3] + in1->m[0][3]*in1->m[1][0]*in1->m[3][1] - in1->m[0][3]*in1->m[3][0]*in1->m[1][1];
181 temp.m[2][3] = -in1->m[0][0]*in1->m[1][1]*in1->m[2][3] + in1->m[0][0]*in1->m[2][1]*in1->m[1][3] + in1->m[0][1]*in1->m[1][0]*in1->m[2][3] - in1->m[0][1]*in1->m[2][0]*in1->m[1][3] - in1->m[0][3]*in1->m[1][0]*in1->m[2][1] + in1->m[0][3]*in1->m[2][0]*in1->m[1][1];
182 temp.m[3][0] = -in1->m[1][0]*in1->m[2][1]*in1->m[3][2] + in1->m[1][0]*in1->m[3][1]*in1->m[2][2] + in1->m[1][1]*in1->m[2][0]*in1->m[3][2] - in1->m[1][1]*in1->m[3][0]*in1->m[2][2] - in1->m[1][2]*in1->m[2][0]*in1->m[3][1] + in1->m[1][2]*in1->m[3][0]*in1->m[2][1];
183 temp.m[3][1] = in1->m[0][0]*in1->m[2][1]*in1->m[3][2] - in1->m[0][0]*in1->m[3][1]*in1->m[2][2] - in1->m[0][1]*in1->m[2][0]*in1->m[3][2] + in1->m[0][1]*in1->m[3][0]*in1->m[2][2] + in1->m[0][2]*in1->m[2][0]*in1->m[3][1] - in1->m[0][2]*in1->m[3][0]*in1->m[2][1];
184 temp.m[3][2] = -in1->m[0][0]*in1->m[1][1]*in1->m[3][2] + in1->m[0][0]*in1->m[3][1]*in1->m[1][2] + in1->m[0][1]*in1->m[1][0]*in1->m[3][2] - in1->m[0][1]*in1->m[3][0]*in1->m[1][2] - in1->m[0][2]*in1->m[1][0]*in1->m[3][1] + in1->m[0][2]*in1->m[3][0]*in1->m[1][1];
185 temp.m[3][3] = in1->m[0][0]*in1->m[1][1]*in1->m[2][2] - in1->m[0][0]*in1->m[2][1]*in1->m[1][2] - in1->m[0][1]*in1->m[1][0]*in1->m[2][2] + in1->m[0][1]*in1->m[2][0]*in1->m[1][2] + in1->m[0][2]*in1->m[1][0]*in1->m[2][1] - in1->m[0][2]*in1->m[2][0]*in1->m[1][1];
188 det = in1->m[0][0]*temp.m[0][0] + in1->m[1][0]*temp.m[0][1] + in1->m[2][0]*temp.m[0][2] + in1->m[3][0]*temp.m[0][3];
194 for (i = 0;i < 4;i++)
195 for (j = 0;j < 4;j++)
196 out->m[i][j] = temp.m[i][j] * det;
201 int Matrix4x4_Invert_Full (matrix4x4_t *out, const matrix4x4_t *in1)
214 #ifdef MATRIX4x4_OPENGLORIENTATION
215 r[0][0] = in1->m[0][0]; r[0][1] = in1->m[1][0]; r[0][2] = in1->m[2][0]; r[0][3] = in1->m[3][0];
216 r[0][4] = 1.0; r[0][5] = r[0][6] = r[0][7] = 0.0;
218 r[1][0] = in1->m[0][1]; r[1][1] = in1->m[1][1]; r[1][2] = in1->m[2][1]; r[1][3] = in1->m[3][1];
219 r[1][5] = 1.0; r[1][4] = r[1][6] = r[1][7] = 0.0;
221 r[2][0] = in1->m[0][2]; r[2][1] = in1->m[1][2]; r[2][2] = in1->m[2][2]; r[2][3] = in1->m[3][2];
222 r[2][6] = 1.0; r[2][4] = r[2][5] = r[2][7] = 0.0;
224 r[3][0] = in1->m[0][3]; r[3][1] = in1->m[1][3]; r[3][2] = in1->m[2][3]; r[3][3] = in1->m[3][3];
225 r[3][7] = 1.0; r[3][4] = r[3][5] = r[3][6] = 0.0;
227 r[0][0] = in1->m[0][0]; r[0][1] = in1->m[0][1]; r[0][2] = in1->m[0][2]; r[0][3] = in1->m[0][3];
228 r[0][4] = 1.0; r[0][5] = r[0][6] = r[0][7] = 0.0;
230 r[1][0] = in1->m[1][0]; r[1][1] = in1->m[1][1]; r[1][2] = in1->m[1][2]; r[1][3] = in1->m[1][3];
231 r[1][5] = 1.0; r[1][4] = r[1][6] = r[1][7] = 0.0;
233 r[2][0] = in1->m[2][0]; r[2][1] = in1->m[2][1]; r[2][2] = in1->m[2][2]; r[2][3] = in1->m[2][3];
234 r[2][6] = 1.0; r[2][4] = r[2][5] = r[2][7] = 0.0;
236 r[3][0] = in1->m[3][0]; r[3][1] = in1->m[3][1]; r[3][2] = in1->m[3][2]; r[3][3] = in1->m[3][3];
237 r[3][7] = 1.0; r[3][4] = r[3][5] = r[3][6] = 0.0;
240 if (fabs (r[3][0]) > fabs (r[2][0])) { temp = r[3]; r[3] = r[2]; r[2] = temp; }
241 if (fabs (r[2][0]) > fabs (r[1][0])) { temp = r[2]; r[2] = r[1]; r[1] = temp; }
242 if (fabs (r[1][0]) > fabs (r[0][0])) { temp = r[1]; r[1] = r[0]; r[0] = temp; }
246 m[1] = r[1][0] / r[0][0];
247 m[2] = r[2][0] / r[0][0];
248 m[3] = r[3][0] / r[0][0];
250 s = r[0][1]; r[1][1] -= m[1] * s; r[2][1] -= m[2] * s; r[3][1] -= m[3] * s;
251 s = r[0][2]; r[1][2] -= m[1] * s; r[2][2] -= m[2] * s; r[3][2] -= m[3] * s;
252 s = r[0][3]; r[1][3] -= m[1] * s; r[2][3] -= m[2] * s; r[3][3] -= m[3] * s;
254 s = r[0][4]; if (s) { r[1][4] -= m[1] * s; r[2][4] -= m[2] * s; r[3][4] -= m[3] * s; }
255 s = r[0][5]; if (s) { r[1][5] -= m[1] * s; r[2][5] -= m[2] * s; r[3][5] -= m[3] * s; }
256 s = r[0][6]; if (s) { r[1][6] -= m[1] * s; r[2][6] -= m[2] * s; r[3][6] -= m[3] * s; }
257 s = r[0][7]; if (s) { r[1][7] -= m[1] * s; r[2][7] -= m[2] * s; r[3][7] -= m[3] * s; }
259 if (fabs (r[3][1]) > fabs (r[2][1])) { temp = r[3]; r[3] = r[2]; r[2] = temp; }
260 if (fabs (r[2][1]) > fabs (r[1][1])) { temp = r[2]; r[2] = r[1]; r[1] = temp; }
264 m[2] = r[2][1] / r[1][1];
265 m[3] = r[3][1] / r[1][1];
266 r[2][2] -= m[2] * r[1][2];
267 r[3][2] -= m[3] * r[1][2];
268 r[2][3] -= m[2] * r[1][3];
269 r[3][3] -= m[3] * r[1][3];
271 s = r[1][4]; if (s) { r[2][4] -= m[2] * s; r[3][4] -= m[3] * s; }
272 s = r[1][5]; if (s) { r[2][5] -= m[2] * s; r[3][5] -= m[3] * s; }
273 s = r[1][6]; if (s) { r[2][6] -= m[2] * s; r[3][6] -= m[3] * s; }
274 s = r[1][7]; if (s) { r[2][7] -= m[2] * s; r[3][7] -= m[3] * s; }
276 if (fabs (r[3][2]) > fabs (r[2][2])) { temp = r[3]; r[3] = r[2]; r[2] = temp; }
280 m[3] = r[3][2] / r[2][2];
281 r[3][3] -= m[3] * r[2][3];
282 r[3][4] -= m[3] * r[2][4];
283 r[3][5] -= m[3] * r[2][5];
284 r[3][6] -= m[3] * r[2][6];
285 r[3][7] -= m[3] * r[2][7];
297 r[2][4] = s * (r[2][4] - r[3][4] * m[2]);
298 r[2][5] = s * (r[2][5] - r[3][5] * m[2]);
299 r[2][6] = s * (r[2][6] - r[3][6] * m[2]);
300 r[2][7] = s * (r[2][7] - r[3][7] * m[2]);
303 r[1][4] -= r[3][4] * m[1], r[1][5] -= r[3][5] * m[1];
304 r[1][6] -= r[3][6] * m[1], r[1][7] -= r[3][7] * m[1];
307 r[0][4] -= r[3][4] * m[0], r[0][5] -= r[3][5] * m[0];
308 r[0][6] -= r[3][6] * m[0], r[0][7] -= r[3][7] * m[0];
312 r[1][4] = s * (r[1][4] - r[2][4] * m[1]), r[1][5] = s * (r[1][5] - r[2][5] * m[1]);
313 r[1][6] = s * (r[1][6] - r[2][6] * m[1]), r[1][7] = s * (r[1][7] - r[2][7] * m[1]);
316 r[0][4] -= r[2][4] * m[0], r[0][5] -= r[2][5] * m[0];
317 r[0][6] -= r[2][6] * m[0], r[0][7] -= r[2][7] * m[0];
321 r[0][4] = s * (r[0][4] - r[1][4] * m[0]), r[0][5] = s * (r[0][5] - r[1][5] * m[0]);
322 r[0][6] = s * (r[0][6] - r[1][6] * m[0]), r[0][7] = s * (r[0][7] - r[1][7] * m[0]);
324 #ifdef MATRIX4x4_OPENGLORIENTATION
325 out->m[0][0] = r[0][4];
326 out->m[0][1] = r[1][4];
327 out->m[0][2] = r[2][4];
328 out->m[0][3] = r[3][4];
329 out->m[1][0] = r[0][5];
330 out->m[1][1] = r[1][5];
331 out->m[1][2] = r[2][5];
332 out->m[1][3] = r[3][5];
333 out->m[2][0] = r[0][6];
334 out->m[2][1] = r[1][6];
335 out->m[2][2] = r[2][6];
336 out->m[2][3] = r[3][6];
337 out->m[3][0] = r[0][7];
338 out->m[3][1] = r[1][7];
339 out->m[3][2] = r[2][7];
340 out->m[3][3] = r[3][7];
342 out->m[0][0] = r[0][4];
343 out->m[0][1] = r[0][5];
344 out->m[0][2] = r[0][6];
345 out->m[0][3] = r[0][7];
346 out->m[1][0] = r[1][4];
347 out->m[1][1] = r[1][5];
348 out->m[1][2] = r[1][6];
349 out->m[1][3] = r[1][7];
350 out->m[2][0] = r[2][4];
351 out->m[2][1] = r[2][5];
352 out->m[2][2] = r[2][6];
353 out->m[2][3] = r[2][7];
354 out->m[3][0] = r[3][4];
355 out->m[3][1] = r[3][5];
356 out->m[3][2] = r[3][6];
357 out->m[3][3] = r[3][7];
370 void Matrix4x4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1)
372 // we only support uniform scaling, so assume the first row is enough
373 // (note the lack of sqrt here, because we're trying to undo the scaling,
374 // this means multiplying by the inverse scale twice - squaring it, which
375 // makes the sqrt a waste of time)
377 double scale = 1.0 / (in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]);
379 double scale = 3.0 / sqrt
380 (in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]
381 + in1->m[1][0] * in1->m[1][0] + in1->m[1][1] * in1->m[1][1] + in1->m[1][2] * in1->m[1][2]
382 + in1->m[2][0] * in1->m[2][0] + in1->m[2][1] * in1->m[2][1] + in1->m[2][2] * in1->m[2][2]);
386 // invert the rotation by transposing and multiplying by the squared
387 // recipricol of the input matrix scale as described above
388 out->m[0][0] = in1->m[0][0] * scale;
389 out->m[0][1] = in1->m[1][0] * scale;
390 out->m[0][2] = in1->m[2][0] * scale;
391 out->m[1][0] = in1->m[0][1] * scale;
392 out->m[1][1] = in1->m[1][1] * scale;
393 out->m[1][2] = in1->m[2][1] * scale;
394 out->m[2][0] = in1->m[0][2] * scale;
395 out->m[2][1] = in1->m[1][2] * scale;
396 out->m[2][2] = in1->m[2][2] * scale;
398 #ifdef MATRIX4x4_OPENGLORIENTATION
399 // invert the translate
400 out->m[3][0] = -(in1->m[3][0] * out->m[0][0] + in1->m[3][1] * out->m[1][0] + in1->m[3][2] * out->m[2][0]);
401 out->m[3][1] = -(in1->m[3][0] * out->m[0][1] + in1->m[3][1] * out->m[1][1] + in1->m[3][2] * out->m[2][1]);
402 out->m[3][2] = -(in1->m[3][0] * out->m[0][2] + in1->m[3][1] * out->m[1][2] + in1->m[3][2] * out->m[2][2]);
404 // don't know if there's anything worth doing here
410 // invert the translate
411 out->m[0][3] = -(in1->m[0][3] * out->m[0][0] + in1->m[1][3] * out->m[0][1] + in1->m[2][3] * out->m[0][2]);
412 out->m[1][3] = -(in1->m[0][3] * out->m[1][0] + in1->m[1][3] * out->m[1][1] + in1->m[2][3] * out->m[1][2]);
413 out->m[2][3] = -(in1->m[0][3] * out->m[2][0] + in1->m[1][3] * out->m[2][1] + in1->m[2][3] * out->m[2][2]);
415 // don't know if there's anything worth doing here
423 void Matrix4x4_Interpolate (matrix4x4_t *out, matrix4x4_t *in1, matrix4x4_t *in2, double frac)
426 for (i = 0;i < 4;i++)
427 for (j = 0;j < 4;j++)
428 out->m[i][j] = in1->m[i][j] + frac * (in2->m[i][j] - in1->m[i][j]);
431 void Matrix4x4_Clear (matrix4x4_t *out)
434 for (i = 0;i < 4;i++)
435 for (j = 0;j < 4;j++)
439 void Matrix4x4_Accumulate (matrix4x4_t *out, matrix4x4_t *in, double weight)
442 for (i = 0;i < 4;i++)
443 for (j = 0;j < 4;j++)
444 out->m[i][j] += in->m[i][j] * weight;
447 void Matrix4x4_Normalize (matrix4x4_t *out, matrix4x4_t *in1)
449 // scale rotation matrix vectors to a length of 1
450 // note: this is only designed to undo uniform scaling
451 double scale = 1.0 / sqrt(in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]);
453 Matrix4x4_Scale(out, scale, 1);
456 void Matrix4x4_Normalize3 (matrix4x4_t *out, matrix4x4_t *in1)
460 // scale each rotation matrix vector to a length of 1
461 // intended for use after Matrix4x4_Interpolate or Matrix4x4_Accumulate
463 for (i = 0;i < 3;i++)
465 #ifdef MATRIX4x4_OPENGLORIENTATION
466 scale = sqrt(in1->m[i][0] * in1->m[i][0] + in1->m[i][1] * in1->m[i][1] + in1->m[i][2] * in1->m[i][2]);
469 out->m[i][0] *= scale;
470 out->m[i][1] *= scale;
471 out->m[i][2] *= scale;
473 scale = sqrt(in1->m[0][i] * in1->m[0][i] + in1->m[1][i] * in1->m[1][i] + in1->m[2][i] * in1->m[2][i]);
476 out->m[0][i] *= scale;
477 out->m[1][i] *= scale;
478 out->m[2][i] *= scale;
483 void Matrix4x4_Reflect (matrix4x4_t *out, double normalx, double normaly, double normalz, double dist, double axisscale)
492 p2[0] = p[0] * axisscale;
493 p2[1] = p[1] * axisscale;
494 p2[2] = p[2] * axisscale;
496 for (i = 0;i < 4;i++)
498 #ifdef MATRIX4x4_OPENGLORIENTATION
499 d = out->m[i][0] * p[0] + out->m[i][1] * p[1] + out->m[i][2] * p[2] + out->m[i][3] * p[3];
500 out->m[i][0] += p2[0] * d;
501 out->m[i][1] += p2[1] * d;
502 out->m[i][2] += p2[2] * d;
504 d = out->m[0][i] * p[0] + out->m[1][i] * p[1] + out->m[2][i] * p[2] + out->m[3][i] * p[3];
505 out->m[0][i] += p2[0] * d;
506 out->m[1][i] += p2[1] * d;
507 out->m[2][i] += p2[2] * d;
512 void Matrix4x4_CreateIdentity (matrix4x4_t *out)
532 void Matrix4x4_CreateTranslate (matrix4x4_t *out, double x, double y, double z)
534 #ifdef MATRIX4x4_OPENGLORIENTATION
571 void Matrix4x4_CreateRotate (matrix4x4_t *out, double angle, double x, double y, double z)
577 len = 1.0f / sqrt(len);
582 angle *= (-M_PI / 180.0);
586 #ifdef MATRIX4x4_OPENGLORIENTATION
587 out->m[0][0]=x * x + c * (1 - x * x);
588 out->m[1][0]=x * y * (1 - c) + z * s;
589 out->m[2][0]=z * x * (1 - c) - y * s;
591 out->m[0][1]=x * y * (1 - c) - z * s;
592 out->m[1][1]=y * y + c * (1 - y * y);
593 out->m[2][1]=y * z * (1 - c) + x * s;
595 out->m[0][2]=z * x * (1 - c) + y * s;
596 out->m[1][2]=y * z * (1 - c) - x * s;
597 out->m[2][2]=z * z + c * (1 - z * z);
604 out->m[0][0]=x * x + c * (1 - x * x);
605 out->m[0][1]=x * y * (1 - c) + z * s;
606 out->m[0][2]=z * x * (1 - c) - y * s;
608 out->m[1][0]=x * y * (1 - c) - z * s;
609 out->m[1][1]=y * y + c * (1 - y * y);
610 out->m[1][2]=y * z * (1 - c) + x * s;
612 out->m[2][0]=z * x * (1 - c) + y * s;
613 out->m[2][1]=y * z * (1 - c) - x * s;
614 out->m[2][2]=z * z + c * (1 - z * z);
623 void Matrix4x4_CreateScale (matrix4x4_t *out, double x)
643 void Matrix4x4_CreateScale3 (matrix4x4_t *out, double x, double y, double z)
663 void Matrix4x4_CreateFromQuakeEntity(matrix4x4_t *out, double x, double y, double z, double pitch, double yaw, double roll, double scale)
665 double angle, sr, sp, sy, cr, cp, cy;
669 angle = yaw * (M_PI*2 / 360);
672 angle = pitch * (M_PI*2 / 360);
675 angle = roll * (M_PI*2 / 360);
678 #ifdef MATRIX4x4_OPENGLORIENTATION
679 out->m[0][0] = (cp*cy) * scale;
680 out->m[1][0] = (sr*sp*cy+cr*-sy) * scale;
681 out->m[2][0] = (cr*sp*cy+-sr*-sy) * scale;
683 out->m[0][1] = (cp*sy) * scale;
684 out->m[1][1] = (sr*sp*sy+cr*cy) * scale;
685 out->m[2][1] = (cr*sp*sy+-sr*cy) * scale;
687 out->m[0][2] = (-sp) * scale;
688 out->m[1][2] = (sr*cp) * scale;
689 out->m[2][2] = (cr*cp) * scale;
696 out->m[0][0] = (cp*cy) * scale;
697 out->m[0][1] = (sr*sp*cy+cr*-sy) * scale;
698 out->m[0][2] = (cr*sp*cy+-sr*-sy) * scale;
700 out->m[1][0] = (cp*sy) * scale;
701 out->m[1][1] = (sr*sp*sy+cr*cy) * scale;
702 out->m[1][2] = (cr*sp*sy+-sr*cy) * scale;
704 out->m[2][0] = (-sp) * scale;
705 out->m[2][1] = (sr*cp) * scale;
706 out->m[2][2] = (cr*cp) * scale;
716 angle = yaw * (M_PI*2 / 360);
719 angle = pitch * (M_PI*2 / 360);
722 #ifdef MATRIX4x4_OPENGLORIENTATION
723 out->m[0][0] = (cp*cy) * scale;
724 out->m[1][0] = (-sy) * scale;
725 out->m[2][0] = (sp*cy) * scale;
727 out->m[0][1] = (cp*sy) * scale;
728 out->m[1][1] = (cy) * scale;
729 out->m[2][1] = (sp*sy) * scale;
731 out->m[0][2] = (-sp) * scale;
733 out->m[2][2] = (cp) * scale;
740 out->m[0][0] = (cp*cy) * scale;
741 out->m[0][1] = (-sy) * scale;
742 out->m[0][2] = (sp*cy) * scale;
744 out->m[1][0] = (cp*sy) * scale;
745 out->m[1][1] = (cy) * scale;
746 out->m[1][2] = (sp*sy) * scale;
748 out->m[2][0] = (-sp) * scale;
750 out->m[2][2] = (cp) * scale;
760 angle = yaw * (M_PI*2 / 360);
763 #ifdef MATRIX4x4_OPENGLORIENTATION
764 out->m[0][0] = (cy) * scale;
765 out->m[1][0] = (-sy) * scale;
768 out->m[0][1] = (sy) * scale;
769 out->m[1][1] = (cy) * scale;
774 out->m[2][2] = scale;
781 out->m[0][0] = (cy) * scale;
782 out->m[0][1] = (-sy) * scale;
785 out->m[1][0] = (sy) * scale;
786 out->m[1][1] = (cy) * scale;
791 out->m[2][2] = scale;
801 #ifdef MATRIX4x4_OPENGLORIENTATION
802 out->m[0][0] = scale;
807 out->m[1][1] = scale;
812 out->m[2][2] = scale;
819 out->m[0][0] = scale;
824 out->m[1][1] = scale;
829 out->m[2][2] = scale;
839 void Matrix4x4_ToVectors(const matrix4x4_t *in, float vx[3], float vy[3], float vz[3], float t[3])
841 #ifdef MATRIX4x4_OPENGLORIENTATION
870 void Matrix4x4_FromVectors(matrix4x4_t *out, const float vx[3], const float vy[3], const float vz[3], const float t[3])
872 #ifdef MATRIX4x4_OPENGLORIENTATION
873 out->m[0][0] = vx[0];
874 out->m[1][0] = vy[0];
875 out->m[2][0] = vz[0];
877 out->m[0][1] = vx[1];
878 out->m[1][1] = vy[1];
879 out->m[2][1] = vz[1];
881 out->m[0][2] = vx[2];
882 out->m[1][2] = vy[2];
883 out->m[2][2] = vz[2];
890 out->m[0][0] = vx[0];
891 out->m[0][1] = vy[0];
892 out->m[0][2] = vz[0];
894 out->m[1][0] = vx[1];
895 out->m[1][1] = vy[1];
896 out->m[1][2] = vz[1];
898 out->m[2][0] = vx[2];
899 out->m[2][1] = vy[2];
900 out->m[2][2] = vz[2];
909 void Matrix4x4_ToArrayDoubleGL(const matrix4x4_t *in, double out[16])
911 #ifdef MATRIX4x4_OPENGLORIENTATION
912 out[ 0] = in->m[0][0];
913 out[ 1] = in->m[0][1];
914 out[ 2] = in->m[0][2];
915 out[ 3] = in->m[0][3];
916 out[ 4] = in->m[1][0];
917 out[ 5] = in->m[1][1];
918 out[ 6] = in->m[1][2];
919 out[ 7] = in->m[1][3];
920 out[ 8] = in->m[2][0];
921 out[ 9] = in->m[2][1];
922 out[10] = in->m[2][2];
923 out[11] = in->m[2][3];
924 out[12] = in->m[3][0];
925 out[13] = in->m[3][1];
926 out[14] = in->m[3][2];
927 out[15] = in->m[3][3];
929 out[ 0] = in->m[0][0];
930 out[ 1] = in->m[1][0];
931 out[ 2] = in->m[2][0];
932 out[ 3] = in->m[3][0];
933 out[ 4] = in->m[0][1];
934 out[ 5] = in->m[1][1];
935 out[ 6] = in->m[2][1];
936 out[ 7] = in->m[3][1];
937 out[ 8] = in->m[0][2];
938 out[ 9] = in->m[1][2];
939 out[10] = in->m[2][2];
940 out[11] = in->m[3][2];
941 out[12] = in->m[0][3];
942 out[13] = in->m[1][3];
943 out[14] = in->m[2][3];
944 out[15] = in->m[3][3];
948 void Matrix4x4_FromArrayDoubleGL (matrix4x4_t *out, const double in[16])
950 #ifdef MATRIX4x4_OPENGLORIENTATION
951 out->m[0][0] = in[0];
952 out->m[0][1] = in[1];
953 out->m[0][2] = in[2];
954 out->m[0][3] = in[3];
955 out->m[1][0] = in[4];
956 out->m[1][1] = in[5];
957 out->m[1][2] = in[6];
958 out->m[1][3] = in[7];
959 out->m[2][0] = in[8];
960 out->m[2][1] = in[9];
961 out->m[2][2] = in[10];
962 out->m[2][3] = in[11];
963 out->m[3][0] = in[12];
964 out->m[3][1] = in[13];
965 out->m[3][2] = in[14];
966 out->m[3][3] = in[15];
968 out->m[0][0] = in[0];
969 out->m[1][0] = in[1];
970 out->m[2][0] = in[2];
971 out->m[3][0] = in[3];
972 out->m[0][1] = in[4];
973 out->m[1][1] = in[5];
974 out->m[2][1] = in[6];
975 out->m[3][1] = in[7];
976 out->m[0][2] = in[8];
977 out->m[1][2] = in[9];
978 out->m[2][2] = in[10];
979 out->m[3][2] = in[11];
980 out->m[0][3] = in[12];
981 out->m[1][3] = in[13];
982 out->m[2][3] = in[14];
983 out->m[3][3] = in[15];
987 void Matrix4x4_ToArrayDoubleD3D(const matrix4x4_t *in, double out[16])
989 #ifdef MATRIX4x4_OPENGLORIENTATION
990 out[ 0] = in->m[0][0];
991 out[ 1] = in->m[1][0];
992 out[ 2] = in->m[2][0];
993 out[ 3] = in->m[3][0];
994 out[ 4] = in->m[0][1];
995 out[ 5] = in->m[1][1];
996 out[ 6] = in->m[2][1];
997 out[ 7] = in->m[3][1];
998 out[ 8] = in->m[0][2];
999 out[ 9] = in->m[1][2];
1000 out[10] = in->m[2][2];
1001 out[11] = in->m[3][2];
1002 out[12] = in->m[0][3];
1003 out[13] = in->m[1][3];
1004 out[14] = in->m[2][3];
1005 out[15] = in->m[3][3];
1007 out[ 0] = in->m[0][0];
1008 out[ 1] = in->m[0][1];
1009 out[ 2] = in->m[0][2];
1010 out[ 3] = in->m[0][3];
1011 out[ 4] = in->m[1][0];
1012 out[ 5] = in->m[1][1];
1013 out[ 6] = in->m[1][2];
1014 out[ 7] = in->m[1][3];
1015 out[ 8] = in->m[2][0];
1016 out[ 9] = in->m[2][1];
1017 out[10] = in->m[2][2];
1018 out[11] = in->m[2][3];
1019 out[12] = in->m[3][0];
1020 out[13] = in->m[3][1];
1021 out[14] = in->m[3][2];
1022 out[15] = in->m[3][3];
1026 void Matrix4x4_FromArrayDoubleD3D (matrix4x4_t *out, const double in[16])
1028 #ifdef MATRIX4x4_OPENGLORIENTATION
1029 out->m[0][0] = in[0];
1030 out->m[1][0] = in[1];
1031 out->m[2][0] = in[2];
1032 out->m[3][0] = in[3];
1033 out->m[0][1] = in[4];
1034 out->m[1][1] = in[5];
1035 out->m[2][1] = in[6];
1036 out->m[3][1] = in[7];
1037 out->m[0][2] = in[8];
1038 out->m[1][2] = in[9];
1039 out->m[2][2] = in[10];
1040 out->m[3][2] = in[11];
1041 out->m[0][3] = in[12];
1042 out->m[1][3] = in[13];
1043 out->m[2][3] = in[14];
1044 out->m[3][3] = in[15];
1046 out->m[0][0] = in[0];
1047 out->m[0][1] = in[1];
1048 out->m[0][2] = in[2];
1049 out->m[0][3] = in[3];
1050 out->m[1][0] = in[4];
1051 out->m[1][1] = in[5];
1052 out->m[1][2] = in[6];
1053 out->m[1][3] = in[7];
1054 out->m[2][0] = in[8];
1055 out->m[2][1] = in[9];
1056 out->m[2][2] = in[10];
1057 out->m[2][3] = in[11];
1058 out->m[3][0] = in[12];
1059 out->m[3][1] = in[13];
1060 out->m[3][2] = in[14];
1061 out->m[3][3] = in[15];
1065 void Matrix4x4_ToArrayFloatGL(const matrix4x4_t *in, float out[16])
1067 #ifdef MATRIX4x4_OPENGLORIENTATION
1068 out[ 0] = in->m[0][0];
1069 out[ 1] = in->m[0][1];
1070 out[ 2] = in->m[0][2];
1071 out[ 3] = in->m[0][3];
1072 out[ 4] = in->m[1][0];
1073 out[ 5] = in->m[1][1];
1074 out[ 6] = in->m[1][2];
1075 out[ 7] = in->m[1][3];
1076 out[ 8] = in->m[2][0];
1077 out[ 9] = in->m[2][1];
1078 out[10] = in->m[2][2];
1079 out[11] = in->m[2][3];
1080 out[12] = in->m[3][0];
1081 out[13] = in->m[3][1];
1082 out[14] = in->m[3][2];
1083 out[15] = in->m[3][3];
1085 out[ 0] = in->m[0][0];
1086 out[ 1] = in->m[1][0];
1087 out[ 2] = in->m[2][0];
1088 out[ 3] = in->m[3][0];
1089 out[ 4] = in->m[0][1];
1090 out[ 5] = in->m[1][1];
1091 out[ 6] = in->m[2][1];
1092 out[ 7] = in->m[3][1];
1093 out[ 8] = in->m[0][2];
1094 out[ 9] = in->m[1][2];
1095 out[10] = in->m[2][2];
1096 out[11] = in->m[3][2];
1097 out[12] = in->m[0][3];
1098 out[13] = in->m[1][3];
1099 out[14] = in->m[2][3];
1100 out[15] = in->m[3][3];
1104 void Matrix4x4_FromArrayFloatGL (matrix4x4_t *out, const float in[16])
1106 #ifdef MATRIX4x4_OPENGLORIENTATION
1107 out->m[0][0] = in[0];
1108 out->m[0][1] = in[1];
1109 out->m[0][2] = in[2];
1110 out->m[0][3] = in[3];
1111 out->m[1][0] = in[4];
1112 out->m[1][1] = in[5];
1113 out->m[1][2] = in[6];
1114 out->m[1][3] = in[7];
1115 out->m[2][0] = in[8];
1116 out->m[2][1] = in[9];
1117 out->m[2][2] = in[10];
1118 out->m[2][3] = in[11];
1119 out->m[3][0] = in[12];
1120 out->m[3][1] = in[13];
1121 out->m[3][2] = in[14];
1122 out->m[3][3] = in[15];
1124 out->m[0][0] = in[0];
1125 out->m[1][0] = in[1];
1126 out->m[2][0] = in[2];
1127 out->m[3][0] = in[3];
1128 out->m[0][1] = in[4];
1129 out->m[1][1] = in[5];
1130 out->m[2][1] = in[6];
1131 out->m[3][1] = in[7];
1132 out->m[0][2] = in[8];
1133 out->m[1][2] = in[9];
1134 out->m[2][2] = in[10];
1135 out->m[3][2] = in[11];
1136 out->m[0][3] = in[12];
1137 out->m[1][3] = in[13];
1138 out->m[2][3] = in[14];
1139 out->m[3][3] = in[15];
1143 void Matrix4x4_ToArrayFloatD3D(const matrix4x4_t *in, float out[16])
1145 #ifdef MATRIX4x4_OPENGLORIENTATION
1146 out[ 0] = in->m[0][0];
1147 out[ 1] = in->m[1][0];
1148 out[ 2] = in->m[2][0];
1149 out[ 3] = in->m[3][0];
1150 out[ 4] = in->m[0][1];
1151 out[ 5] = in->m[1][1];
1152 out[ 6] = in->m[2][1];
1153 out[ 7] = in->m[3][1];
1154 out[ 8] = in->m[0][2];
1155 out[ 9] = in->m[1][2];
1156 out[10] = in->m[2][2];
1157 out[11] = in->m[3][2];
1158 out[12] = in->m[0][3];
1159 out[13] = in->m[1][3];
1160 out[14] = in->m[2][3];
1161 out[15] = in->m[3][3];
1163 out[ 0] = in->m[0][0];
1164 out[ 1] = in->m[0][1];
1165 out[ 2] = in->m[0][2];
1166 out[ 3] = in->m[0][3];
1167 out[ 4] = in->m[1][0];
1168 out[ 5] = in->m[1][1];
1169 out[ 6] = in->m[1][2];
1170 out[ 7] = in->m[1][3];
1171 out[ 8] = in->m[2][0];
1172 out[ 9] = in->m[2][1];
1173 out[10] = in->m[2][2];
1174 out[11] = in->m[2][3];
1175 out[12] = in->m[3][0];
1176 out[13] = in->m[3][1];
1177 out[14] = in->m[3][2];
1178 out[15] = in->m[3][3];
1182 void Matrix4x4_FromArrayFloatD3D (matrix4x4_t *out, const float in[16])
1184 #ifdef MATRIX4x4_OPENGLORIENTATION
1185 out->m[0][0] = in[0];
1186 out->m[1][0] = in[1];
1187 out->m[2][0] = in[2];
1188 out->m[3][0] = in[3];
1189 out->m[0][1] = in[4];
1190 out->m[1][1] = in[5];
1191 out->m[2][1] = in[6];
1192 out->m[3][1] = in[7];
1193 out->m[0][2] = in[8];
1194 out->m[1][2] = in[9];
1195 out->m[2][2] = in[10];
1196 out->m[3][2] = in[11];
1197 out->m[0][3] = in[12];
1198 out->m[1][3] = in[13];
1199 out->m[2][3] = in[14];
1200 out->m[3][3] = in[15];
1202 out->m[0][0] = in[0];
1203 out->m[0][1] = in[1];
1204 out->m[0][2] = in[2];
1205 out->m[0][3] = in[3];
1206 out->m[1][0] = in[4];
1207 out->m[1][1] = in[5];
1208 out->m[1][2] = in[6];
1209 out->m[1][3] = in[7];
1210 out->m[2][0] = in[8];
1211 out->m[2][1] = in[9];
1212 out->m[2][2] = in[10];
1213 out->m[2][3] = in[11];
1214 out->m[3][0] = in[12];
1215 out->m[3][1] = in[13];
1216 out->m[3][2] = in[14];
1217 out->m[3][3] = in[15];
1221 void Matrix4x4_ToArray12FloatGL(const matrix4x4_t *in, float out[12])
1223 #ifdef MATRIX4x4_OPENGLORIENTATION
1224 out[ 0] = in->m[0][0];
1225 out[ 1] = in->m[0][1];
1226 out[ 2] = in->m[0][2];
1227 out[ 3] = in->m[1][0];
1228 out[ 4] = in->m[1][1];
1229 out[ 5] = in->m[1][2];
1230 out[ 6] = in->m[2][0];
1231 out[ 7] = in->m[2][1];
1232 out[ 8] = in->m[2][2];
1233 out[ 9] = in->m[3][0];
1234 out[10] = in->m[3][1];
1235 out[11] = in->m[3][2];
1237 out[ 0] = in->m[0][0];
1238 out[ 1] = in->m[1][0];
1239 out[ 2] = in->m[2][0];
1240 out[ 3] = in->m[0][1];
1241 out[ 4] = in->m[1][1];
1242 out[ 5] = in->m[2][1];
1243 out[ 6] = in->m[0][2];
1244 out[ 7] = in->m[1][2];
1245 out[ 8] = in->m[2][2];
1246 out[ 9] = in->m[0][3];
1247 out[10] = in->m[1][3];
1248 out[11] = in->m[2][3];
1252 void Matrix4x4_FromArray12FloatGL(matrix4x4_t *out, const float in[12])
1254 #ifdef MATRIX4x4_OPENGLORIENTATION
1255 out->m[0][0] = in[0];
1256 out->m[0][1] = in[1];
1257 out->m[0][2] = in[2];
1259 out->m[1][0] = in[3];
1260 out->m[1][1] = in[4];
1261 out->m[1][2] = in[5];
1263 out->m[2][0] = in[6];
1264 out->m[2][1] = in[7];
1265 out->m[2][2] = in[8];
1267 out->m[3][0] = in[9];
1268 out->m[3][1] = in[10];
1269 out->m[3][2] = in[11];
1272 out->m[0][0] = in[0];
1273 out->m[1][0] = in[1];
1274 out->m[2][0] = in[2];
1276 out->m[0][1] = in[3];
1277 out->m[1][1] = in[4];
1278 out->m[2][1] = in[5];
1280 out->m[0][2] = in[6];
1281 out->m[1][2] = in[7];
1282 out->m[2][2] = in[8];
1284 out->m[0][3] = in[9];
1285 out->m[1][3] = in[10];
1286 out->m[2][3] = in[11];
1291 void Matrix4x4_ToArray12FloatD3D(const matrix4x4_t *in, float out[12])
1293 #ifdef MATRIX4x4_OPENGLORIENTATION
1294 out[ 0] = in->m[0][0];
1295 out[ 1] = in->m[1][0];
1296 out[ 2] = in->m[2][0];
1297 out[ 3] = in->m[3][0];
1298 out[ 4] = in->m[0][1];
1299 out[ 5] = in->m[1][1];
1300 out[ 6] = in->m[2][1];
1301 out[ 7] = in->m[3][1];
1302 out[ 8] = in->m[0][2];
1303 out[ 9] = in->m[1][2];
1304 out[10] = in->m[2][2];
1305 out[11] = in->m[3][2];
1307 out[ 0] = in->m[0][0];
1308 out[ 1] = in->m[0][1];
1309 out[ 2] = in->m[0][2];
1310 out[ 3] = in->m[0][3];
1311 out[ 4] = in->m[1][0];
1312 out[ 5] = in->m[1][1];
1313 out[ 6] = in->m[1][2];
1314 out[ 7] = in->m[1][3];
1315 out[ 8] = in->m[2][0];
1316 out[ 9] = in->m[2][1];
1317 out[10] = in->m[2][2];
1318 out[11] = in->m[2][3];
1322 void Matrix4x4_FromArray12FloatD3D(matrix4x4_t *out, const float in[12])
1324 #ifdef MATRIX4x4_OPENGLORIENTATION
1325 out->m[0][0] = in[0];
1326 out->m[1][0] = in[1];
1327 out->m[2][0] = in[2];
1328 out->m[3][0] = in[3];
1329 out->m[0][1] = in[4];
1330 out->m[1][1] = in[5];
1331 out->m[2][1] = in[6];
1332 out->m[3][1] = in[7];
1333 out->m[0][2] = in[8];
1334 out->m[1][2] = in[9];
1335 out->m[2][2] = in[10];
1336 out->m[3][2] = in[11];
1342 out->m[0][0] = in[0];
1343 out->m[0][1] = in[1];
1344 out->m[0][2] = in[2];
1345 out->m[0][3] = in[3];
1346 out->m[1][0] = in[4];
1347 out->m[1][1] = in[5];
1348 out->m[1][2] = in[6];
1349 out->m[1][3] = in[7];
1350 out->m[2][0] = in[8];
1351 out->m[2][1] = in[9];
1352 out->m[2][2] = in[10];
1353 out->m[2][3] = in[11];
1361 void Matrix4x4_FromOriginQuat(matrix4x4_t *m, double ox, double oy, double oz, double x, double y, double z, double w)
1363 #ifdef MATRIX4x4_OPENGLORIENTATION
1364 m->m[0][0]=1-2*(y*y+z*z);m->m[1][0]= 2*(x*y-z*w);m->m[2][0]= 2*(x*z+y*w);m->m[3][0]=ox;
1365 m->m[0][1]= 2*(x*y+z*w);m->m[1][1]=1-2*(x*x+z*z);m->m[2][1]= 2*(y*z-x*w);m->m[3][1]=oy;
1366 m->m[0][2]= 2*(x*z-y*w);m->m[1][2]= 2*(y*z+x*w);m->m[2][2]=1-2*(x*x+y*y);m->m[3][2]=oz;
1367 m->m[0][3]= 0 ;m->m[1][3]= 0 ;m->m[2][3]= 0 ;m->m[3][3]=1;
1369 m->m[0][0]=1-2*(y*y+z*z);m->m[0][1]= 2*(x*y-z*w);m->m[0][2]= 2*(x*z+y*w);m->m[0][3]=ox;
1370 m->m[1][0]= 2*(x*y+z*w);m->m[1][1]=1-2*(x*x+z*z);m->m[1][2]= 2*(y*z-x*w);m->m[1][3]=oy;
1371 m->m[2][0]= 2*(x*z-y*w);m->m[2][1]= 2*(y*z+x*w);m->m[2][2]=1-2*(x*x+y*y);m->m[2][3]=oz;
1372 m->m[3][0]= 0 ;m->m[3][1]= 0 ;m->m[3][2]= 0 ;m->m[3][3]=1;
1376 // LordHavoc: I got this code from:
1377 //http://www.doom3world.org/phpbb2/viewtopic.php?t=2884
1378 void Matrix4x4_FromDoom3Joint(matrix4x4_t *m, double ox, double oy, double oz, double x, double y, double z)
1380 double w = 1.0 - (x*x+y*y+z*z);
1381 w = w > 0.0 ? -sqrt(w) : 0.0;
1382 #ifdef MATRIX4x4_OPENGLORIENTATION
1383 m->m[0][0]=1-2*(y*y+z*z);m->m[1][0]= 2*(x*y-z*w);m->m[2][0]= 2*(x*z+y*w);m->m[3][0]=ox;
1384 m->m[0][1]= 2*(x*y+z*w);m->m[1][1]=1-2*(x*x+z*z);m->m[2][1]= 2*(y*z-x*w);m->m[3][1]=oy;
1385 m->m[0][2]= 2*(x*z-y*w);m->m[1][2]= 2*(y*z+x*w);m->m[2][2]=1-2*(x*x+y*y);m->m[3][2]=oz;
1386 m->m[0][3]= 0 ;m->m[1][3]= 0 ;m->m[2][3]= 0 ;m->m[3][3]=1;
1388 m->m[0][0]=1-2*(y*y+z*z);m->m[0][1]= 2*(x*y-z*w);m->m[0][2]= 2*(x*z+y*w);m->m[0][3]=ox;
1389 m->m[1][0]= 2*(x*y+z*w);m->m[1][1]=1-2*(x*x+z*z);m->m[1][2]= 2*(y*z-x*w);m->m[1][3]=oy;
1390 m->m[2][0]= 2*(x*z-y*w);m->m[2][1]= 2*(y*z+x*w);m->m[2][2]=1-2*(x*x+y*y);m->m[2][3]=oz;
1391 m->m[3][0]= 0 ;m->m[3][1]= 0 ;m->m[3][2]= 0 ;m->m[3][3]=1;
1395 void Matrix4x4_Blend (matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4_t *in2, double blend)
1397 double iblend = 1 - blend;
1398 out->m[0][0] = in1->m[0][0] * iblend + in2->m[0][0] * blend;
1399 out->m[0][1] = in1->m[0][1] * iblend + in2->m[0][1] * blend;
1400 out->m[0][2] = in1->m[0][2] * iblend + in2->m[0][2] * blend;
1401 out->m[0][3] = in1->m[0][3] * iblend + in2->m[0][3] * blend;
1402 out->m[1][0] = in1->m[1][0] * iblend + in2->m[1][0] * blend;
1403 out->m[1][1] = in1->m[1][1] * iblend + in2->m[1][1] * blend;
1404 out->m[1][2] = in1->m[1][2] * iblend + in2->m[1][2] * blend;
1405 out->m[1][3] = in1->m[1][3] * iblend + in2->m[1][3] * blend;
1406 out->m[2][0] = in1->m[2][0] * iblend + in2->m[2][0] * blend;
1407 out->m[2][1] = in1->m[2][1] * iblend + in2->m[2][1] * blend;
1408 out->m[2][2] = in1->m[2][2] * iblend + in2->m[2][2] * blend;
1409 out->m[2][3] = in1->m[2][3] * iblend + in2->m[2][3] * blend;
1410 out->m[3][0] = in1->m[3][0] * iblend + in2->m[3][0] * blend;
1411 out->m[3][1] = in1->m[3][1] * iblend + in2->m[3][1] * blend;
1412 out->m[3][2] = in1->m[3][2] * iblend + in2->m[3][2] * blend;
1413 out->m[3][3] = in1->m[3][3] * iblend + in2->m[3][3] * blend;
1417 void Matrix4x4_Transform (const matrix4x4_t *in, const float v[3], float out[3])
1419 #ifdef MATRIX4x4_OPENGLORIENTATION
1420 out[0] = v[0] * in->m[0][0] + v[1] * in->m[1][0] + v[2] * in->m[2][0] + in->m[3][0];
1421 out[1] = v[0] * in->m[0][1] + v[1] * in->m[1][1] + v[2] * in->m[2][1] + in->m[3][1];
1422 out[2] = v[0] * in->m[0][2] + v[1] * in->m[1][2] + v[2] * in->m[2][2] + in->m[3][2];
1424 out[0] = v[0] * in->m[0][0] + v[1] * in->m[0][1] + v[2] * in->m[0][2] + in->m[0][3];
1425 out[1] = v[0] * in->m[1][0] + v[1] * in->m[1][1] + v[2] * in->m[1][2] + in->m[1][3];
1426 out[2] = v[0] * in->m[2][0] + v[1] * in->m[2][1] + v[2] * in->m[2][2] + in->m[2][3];
1430 void Matrix4x4_Transform4 (const matrix4x4_t *in, const float v[4], float out[4])
1432 #ifdef MATRIX4x4_OPENGLORIENTATION
1433 out[0] = v[0] * in->m[0][0] + v[1] * in->m[1][0] + v[2] * in->m[2][0] + v[3] * in->m[3][0];
1434 out[1] = v[0] * in->m[0][1] + v[1] * in->m[1][1] + v[2] * in->m[2][1] + v[3] * in->m[3][1];
1435 out[2] = v[0] * in->m[0][2] + v[1] * in->m[1][2] + v[2] * in->m[2][2] + v[3] * in->m[3][2];
1436 out[3] = v[0] * in->m[0][3] + v[1] * in->m[1][3] + v[2] * in->m[2][3] + v[3] * in->m[3][3];
1438 out[0] = v[0] * in->m[0][0] + v[1] * in->m[0][1] + v[2] * in->m[0][2] + v[3] * in->m[0][3];
1439 out[1] = v[0] * in->m[1][0] + v[1] * in->m[1][1] + v[2] * in->m[1][2] + v[3] * in->m[1][3];
1440 out[2] = v[0] * in->m[2][0] + v[1] * in->m[2][1] + v[2] * in->m[2][2] + v[3] * in->m[2][3];
1441 out[3] = v[0] * in->m[3][0] + v[1] * in->m[3][1] + v[2] * in->m[3][2] + v[3] * in->m[3][3];
1445 void Matrix4x4_Transform3x3 (const matrix4x4_t *in, const float v[3], float out[3])
1447 #ifdef MATRIX4x4_OPENGLORIENTATION
1448 out[0] = v[0] * in->m[0][0] + v[1] * in->m[1][0] + v[2] * in->m[2][0];
1449 out[1] = v[0] * in->m[0][1] + v[1] * in->m[1][1] + v[2] * in->m[2][1];
1450 out[2] = v[0] * in->m[0][2] + v[1] * in->m[1][2] + v[2] * in->m[2][2];
1452 out[0] = v[0] * in->m[0][0] + v[1] * in->m[0][1] + v[2] * in->m[0][2];
1453 out[1] = v[0] * in->m[1][0] + v[1] * in->m[1][1] + v[2] * in->m[1][2];
1454 out[2] = v[0] * in->m[2][0] + v[1] * in->m[2][1] + v[2] * in->m[2][2];
1458 void Matrix4x4_TransformPositivePlane(const matrix4x4_t *in, float x, float y, float z, float d, float *o)
1460 #ifdef MATRIX4x4_OPENGLORIENTATION
1461 o[0] = x * in->m[0][0] + y * in->m[1][0] + z * in->m[2][0];
1462 o[1] = x * in->m[0][1] + y * in->m[1][1] + z * in->m[2][1];
1463 o[2] = x * in->m[0][2] + y * in->m[1][2] + z * in->m[2][2];
1464 o[3] = d + (x * in->m[3][0] + y * in->m[3][1] + z * in->m[3][2]);
1466 o[0] = x * in->m[0][0] + y * in->m[0][1] + z * in->m[0][2];
1467 o[1] = x * in->m[1][0] + y * in->m[1][1] + z * in->m[1][2];
1468 o[2] = x * in->m[2][0] + y * in->m[2][1] + z * in->m[2][2];
1469 o[3] = d + (x * in->m[0][3] + y * in->m[1][3] + z * in->m[2][3]);
1473 void Matrix4x4_TransformStandardPlane(const matrix4x4_t *in, float x, float y, float z, float d, float *o)
1475 #ifdef MATRIX4x4_OPENGLORIENTATION
1476 o[0] = x * in->m[0][0] + y * in->m[1][0] + z * in->m[2][0];
1477 o[1] = x * in->m[0][1] + y * in->m[1][1] + z * in->m[2][1];
1478 o[2] = x * in->m[0][2] + y * in->m[1][2] + z * in->m[2][2];
1479 o[3] = d - (x * in->m[3][0] + y * in->m[3][1] + z * in->m[3][2]);
1481 o[0] = x * in->m[0][0] + y * in->m[0][1] + z * in->m[0][2];
1482 o[1] = x * in->m[1][0] + y * in->m[1][1] + z * in->m[1][2];
1483 o[2] = x * in->m[2][0] + y * in->m[2][1] + z * in->m[2][2];
1484 o[3] = d - (x * in->m[0][3] + y * in->m[1][3] + z * in->m[2][3]);
1489 void Matrix4x4_SimpleUntransform (const matrix4x4_t *in, const float v[3], float out[3])
1492 #ifdef MATRIX4x4_OPENGLORIENTATION
1493 t[0] = v[0] - in->m[3][0];
1494 t[1] = v[1] - in->m[3][1];
1495 t[2] = v[2] - in->m[3][2];
1496 out[0] = t[0] * in->m[0][0] + t[1] * in->m[0][1] + t[2] * in->m[0][2];
1497 out[1] = t[0] * in->m[1][0] + t[1] * in->m[1][1] + t[2] * in->m[1][2];
1498 out[2] = t[0] * in->m[2][0] + t[1] * in->m[2][1] + t[2] * in->m[2][2];
1500 t[0] = v[0] - in->m[0][3];
1501 t[1] = v[1] - in->m[1][3];
1502 t[2] = v[2] - in->m[2][3];
1503 out[0] = t[0] * in->m[0][0] + t[1] * in->m[1][0] + t[2] * in->m[2][0];
1504 out[1] = t[0] * in->m[0][1] + t[1] * in->m[1][1] + t[2] * in->m[2][1];
1505 out[2] = t[0] * in->m[0][2] + t[1] * in->m[1][2] + t[2] * in->m[2][2];
1511 void Matrix4x4_ConcatTranslate (matrix4x4_t *out, double x, double y, double z)
1513 matrix4x4_t base, temp;
1515 Matrix4x4_CreateTranslate(&temp, x, y, z);
1516 Matrix4x4_Concat(out, &base, &temp);
1520 void Matrix4x4_ConcatRotate (matrix4x4_t *out, double angle, double x, double y, double z)
1522 matrix4x4_t base, temp;
1524 Matrix4x4_CreateRotate(&temp, angle, x, y, z);
1525 Matrix4x4_Concat(out, &base, &temp);
1529 void Matrix4x4_ConcatScale (matrix4x4_t *out, double x)
1531 matrix4x4_t base, temp;
1533 Matrix4x4_CreateScale(&temp, x);
1534 Matrix4x4_Concat(out, &base, &temp);
1538 void Matrix4x4_ConcatScale3 (matrix4x4_t *out, double x, double y, double z)
1540 matrix4x4_t base, temp;
1542 Matrix4x4_CreateScale3(&temp, x, y, z);
1543 Matrix4x4_Concat(out, &base, &temp);
1546 void Matrix4x4_OriginFromMatrix (const matrix4x4_t *in, float *out)
1548 #ifdef MATRIX4x4_OPENGLORIENTATION
1549 out[0] = in->m[3][0];
1550 out[1] = in->m[3][1];
1551 out[2] = in->m[3][2];
1553 out[0] = in->m[0][3];
1554 out[1] = in->m[1][3];
1555 out[2] = in->m[2][3];
1559 double Matrix4x4_ScaleFromMatrix (const matrix4x4_t *in)
1561 // we only support uniform scaling, so assume the first row is enough
1562 return sqrt(in->m[0][0] * in->m[0][0] + in->m[0][1] * in->m[0][1] + in->m[0][2] * in->m[0][2]);
1565 void Matrix4x4_SetOrigin (matrix4x4_t *out, double x, double y, double z)
1567 #ifdef MATRIX4x4_OPENGLORIENTATION
1578 void Matrix4x4_AdjustOrigin (matrix4x4_t *out, double x, double y, double z)
1580 #ifdef MATRIX4x4_OPENGLORIENTATION
1591 void Matrix4x4_Scale (matrix4x4_t *out, double rotatescale, double originscale)
1593 out->m[0][0] *= rotatescale;
1594 out->m[0][1] *= rotatescale;
1595 out->m[0][2] *= rotatescale;
1596 out->m[1][0] *= rotatescale;
1597 out->m[1][1] *= rotatescale;
1598 out->m[1][2] *= rotatescale;
1599 out->m[2][0] *= rotatescale;
1600 out->m[2][1] *= rotatescale;
1601 out->m[2][2] *= rotatescale;
1602 #ifdef MATRIX4x4_OPENGLORIENTATION
1603 out->m[3][0] *= originscale;
1604 out->m[3][1] *= originscale;
1605 out->m[3][2] *= originscale;
1607 out->m[0][3] *= originscale;
1608 out->m[1][3] *= originscale;
1609 out->m[2][3] *= originscale;