1 /* TSI 2023.xmo */
2 /*******************************************************************************
3  * Copyright (c) 2023 Think Silicon Single Member PC
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this header file and/or associated documentation files to use, copy,
7  * modify, merge, publish, distribute, sublicense, and/or sell copies of the
8  * Materials, and to permit persons to whom the Materials are furnished to do
9  * so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Materials.
13  *
14  * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
15  * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX
16  * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT:
17  *   https://think-silicon.com/products/software/nemagfx-api
18  *
19  *  The software is provided 'as is', without warranty of any kind, express or
20  *  implied, including but not limited to the warranties of merchantability,
21  *  fitness for a particular purpose and noninfringement. In no event shall
22  *  Think Silicon Single Member PC be liable for any claim, damages or other
23  *  liability, whether in an action of contract, tort or otherwise, arising
24  *  from, out of or in connection with the software or the use or other dealings
25  *  in the software.
26  ******************************************************************************/
27 
28 
29 #ifndef NEMA_MATRIX4X4_H__
30 #define NEMA_MATRIX4X4_H__
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 typedef float nema_matrix4x4_t[4][4];
37 
38 
39 /** \brief Load a 4x4 Identity Matrix
40  *
41  * \param m Matrix to be loaded
42  *
43  */
44 void nema_mat4x4_load_identity(nema_matrix4x4_t m);
45 
46 /** \brief Multiply two 4x4 matrices
47  *
48  * \param m Result Matrix
49  * \param m_l Left operand
50  * \param m_r Right operand
51  *
52  */
53 void nema_mat4x4_mul(nema_matrix4x4_t  m,
54                      nema_matrix4x4_t  m_l,
55                      nema_matrix4x4_t  m_r);
56 
57 
58 void nema_mat4x4_copy(nema_matrix4x4_t m_l,
59                  nema_matrix4x4_t m_r);
60 
61 /** \brief Multiply a 4x1 vector with a 4x4 matrix
62  *
63  * \param m Matrix to be multiplied
64  * \param x Vector first element
65  * \param y Vector second element
66  * \param z Vector third element
67  * \param w Vector forth element
68  *
69  */
70 void nema_mat4x4_mul_vec(nema_matrix4x4_t m, float *x, float *y, float *z, float *w);
71 
72 // ------------------------------------------------------------------------------------
73 // Object Transformation - ModelView Matrix
74 // Object Coordinates to Eye Coordinates
75 // ------------------------------------------------------------------------------------
76 
77 /** \brief Apply translate transformation
78  *
79  * \param m Matrix to apply transformation
80  * \param tx X translation factor
81  * \param ty Y translation factor
82  * \param tz Z translation factor
83  *
84  */
85 void nema_mat4x4_translate(nema_matrix4x4_t m, float tx, float ty, float tz);
86 
87 /** \brief Apply scale transformation
88  *
89  * \param m Matrix to apply transformation
90  * \param sx X scaling factor
91  * \param sy Y scaling factor
92  * \param sz Z scaling factor
93  *
94  */
95 void nema_mat4x4_scale(nema_matrix4x4_t m, float sx, float sy, float sz);
96 
97 /** \brief Apply rotate transformation around X axis
98  *
99  * \param m Matrix to apply transformation
100  * \param angle_degrees Angle to rotate in degrees
101  *
102  */
103 void nema_mat4x4_rotate_X    (nema_matrix4x4_t m, float angle_degrees);
104 
105 /** \brief Apply rotate transformation around Y axis
106  *
107  * \param m Matrix to apply transformation
108  * \param angle_degrees Angle to rotate in degrees
109  *
110  */
111 void nema_mat4x4_rotate_Y    (nema_matrix4x4_t m, float angle_degrees);
112 
113 /** \brief Apply rotate transformation around Z axis
114  *
115  * \param m Matrix to apply transformation
116  * \param angle_degrees Angle to rotate in degrees
117  *
118  */
119 void nema_mat4x4_rotate_Z    (nema_matrix4x4_t m, float angle_degrees);
120 
121 // ------------------------------------------------------------------------------------
122 // Scene Transformation/Frustum - Projection Matrix
123 // Eye Coordinates to Clip Coordinates
124 // ------------------------------------------------------------------------------------
125 
126 /** \brief Set up a perspective projection matrix
127  *
128  * \param m A 4x4 Matrix
129  * \param fovy_degrees Field of View in degrees
130  * \param aspect Aspect ratio that determines the field of view in the x direction.
131  * \param nearVal Distance from the viewer to the near clipping plane (always positive)
132  * \param farVal Distance from the viewer to the far clipping plane (always positive)
133  *
134  */
135 void nema_mat4x4_load_perspective(nema_matrix4x4_t m, float fovy_degrees, float aspect,
136                                   float nearVal, float farVal);
137 
138 
139 /** \brief Set up a Right Hand perspective projection matrix
140  *
141  * \param m A 4x4 Matrix
142  * \param fovy_degrees Field of View in degrees
143  * \param aspect Aspect ratio that determines the field of view in the x direction.
144  * \param nearVal Distance from the viewer to the near clipping plane (always positive)
145  * \param farVal Distance from the viewer to the far clipping plane (always positive)
146  *
147  */
148 void nema_mat4x4_load_perspective_rh(nema_matrix4x4_t m, float fovy_degrees, float aspect,
149                                   float nearVal, float farVal);
150 
151 /** \brief Set up an orthographic projection matrix
152  *
153  * \param m A 4x4 Matrix
154  * \param left   Left vertical clipping plane
155  * \param right  Right vertical clipping plane
156  * \param bottom bottom horizontal clipping plane
157  * \param top    Top horizontal clipping plane
158  * \param nearVal Distance from the viewer to the near clipping plane (always positive)
159  * \param farVal Distance from the viewer to the far clipping plane (always positive)
160  *
161  */
162 void nema_mat4x4_load_ortho(nema_matrix4x4_t m,
163                             float left,    float right,
164                             float bottom,  float top,
165                             float nearVal, float farVal);
166 
167 /** \brief Set up a 2D orthographic projection matrix
168  *
169  * \param m A 4x4 Matrix
170  * \param left   Left vertical clipping plane
171  * \param right  Right vertical clipping plane
172  * \param bottom bottom horizontal clipping plane
173  * \param top    Top horizontal clipping plane
174  *
175  */
176 void nema_mat4x4_load_ortho_2d(nema_matrix4x4_t m,
177                                float left,   float right,
178                                float bottom, float top);
179 
180 /** \brief Set up a Right Hand view matrix.
181  *
182  * \param m A 4x4 Matrix
183  * \param eye_x   Eye position x.
184  * \param eye_y   Eye position y.
185  * \param eye_z   Eye position z.
186  * \param center_x   Center x to look at
187  * \param center_y   Center y to look at
188  * \param center_z   Center z to look at
189  * \param up_x   Up vector x. (Usually 0)
190  * \param up_y   Up vector y. (Usually 1)
191  * \param up_z   Up vector z. (Usually 0)
192  *
193  */
194 void nema_mat4x4_look_at_rh(nema_matrix4x4_t m,
195                         float eye_x, float eye_y, float eye_z,
196                         float center_x, float center_y, float center_z,
197                         float up_x, float up_y, float up_z);
198 
199 // ------------------------------------------------------------------------------------
200 // Clip Coordinates to Window Coordinates
201 // ------------------------------------------------------------------------------------
202 
203 /** \brief Convenience Function to calculate window coordinates from object coordinates
204  *
205  * \param mvp Model, View and Projection Matrix
206  * \param x_orig Window top left X coordinate
207  * \param y_orig Window top left Y coordinate
208  * \param width Window width
209  * \param height Window height
210  * \param nearVal Distance from the viewer to the near clipping plane (always positive)
211  * \param farVal Distance from the viewer to the far clipping plane (always positive)
212  * \param x X object coordinate
213  * \param y Y object coordinate
214  * \param z Z object coordinate
215  * \param w W object coordinate
216  * \return 1 if vertex is outside frustum (should be clipped)
217  *
218  */
219 int nema_mat4x4_obj_to_win_coords(nema_matrix4x4_t mvp,
220                                    float x_orig,  float y_orig,
221                                    int width, int height,
222                                    float nearVal, float farVal,
223                                    float *x,
224                                    float *y,
225                                    float *z,
226                                    float *w);
227 
228 #ifdef __cplusplus
229 }
230 #endif
231 
232 #endif
233