1use crate::{ffi, Box, Euler, Point, Point3D, Quad, Quaternion, Ray, Rect, Sphere, Vec3, Vec4};
6use glib::translate::*;
7
8glib::wrapper! {
9 pub struct Matrix(BoxedInline<ffi::graphene_matrix_t>);
10
11 match fn {
12 copy => |ptr| glib::gobject_ffi::g_boxed_copy(ffi::graphene_matrix_get_type(), ptr as *mut _) as *mut ffi::graphene_matrix_t,
13 free => |ptr| glib::gobject_ffi::g_boxed_free(ffi::graphene_matrix_get_type(), ptr as *mut _),
14 type_ => || ffi::graphene_matrix_get_type(),
15 }
16}
17
18impl Matrix {
19 #[doc(alias = "graphene_matrix_decompose")]
20 pub fn decompose(&self) -> Option<(Vec3, Vec3, Quaternion, Vec3, Vec4)> {
21 unsafe {
22 let mut translate = Vec3::uninitialized();
23 let mut scale = Vec3::uninitialized();
24 let mut rotate = Quaternion::uninitialized();
25 let mut shear = Vec3::uninitialized();
26 let mut perspective = Vec4::uninitialized();
27 let ret = ffi::graphene_matrix_decompose(
28 self.to_glib_none().0,
29 translate.to_glib_none_mut().0,
30 scale.to_glib_none_mut().0,
31 rotate.to_glib_none_mut().0,
32 shear.to_glib_none_mut().0,
33 perspective.to_glib_none_mut().0,
34 );
35 if ret {
36 Some((translate, scale, rotate, shear, perspective))
37 } else {
38 None
39 }
40 }
41 }
42
43 #[doc(alias = "graphene_matrix_determinant")]
44 pub fn determinant(&self) -> f32 {
45 unsafe { ffi::graphene_matrix_determinant(self.to_glib_none().0) }
46 }
47
48 #[doc(alias = "graphene_matrix_equal")]
49 fn equal(&self, b: &Matrix) -> bool {
50 unsafe { ffi::graphene_matrix_equal(self.to_glib_none().0, b.to_glib_none().0) }
51 }
52
53 #[doc(alias = "graphene_matrix_equal_fast")]
54 pub fn equal_fast(&self, b: &Matrix) -> bool {
55 unsafe { ffi::graphene_matrix_equal_fast(self.to_glib_none().0, b.to_glib_none().0) }
56 }
57
58 #[doc(alias = "graphene_matrix_get_row")]
59 #[doc(alias = "get_row")]
60 pub fn row(&self, index_: u32) -> Vec4 {
61 unsafe {
62 let mut res = Vec4::uninitialized();
63 ffi::graphene_matrix_get_row(self.to_glib_none().0, index_, res.to_glib_none_mut().0);
64 res
65 }
66 }
67
68 #[doc(alias = "graphene_matrix_get_value")]
69 #[doc(alias = "get_value")]
70 pub fn value(&self, row: u32, col: u32) -> f32 {
71 unsafe { ffi::graphene_matrix_get_value(self.to_glib_none().0, row, col) }
72 }
73
74 #[doc(alias = "graphene_matrix_get_x_scale")]
75 #[doc(alias = "get_x_scale")]
76 pub fn x_scale(&self) -> f32 {
77 unsafe { ffi::graphene_matrix_get_x_scale(self.to_glib_none().0) }
78 }
79
80 #[doc(alias = "graphene_matrix_get_x_translation")]
81 #[doc(alias = "get_x_translation")]
82 pub fn x_translation(&self) -> f32 {
83 unsafe { ffi::graphene_matrix_get_x_translation(self.to_glib_none().0) }
84 }
85
86 #[doc(alias = "graphene_matrix_get_y_scale")]
87 #[doc(alias = "get_y_scale")]
88 pub fn y_scale(&self) -> f32 {
89 unsafe { ffi::graphene_matrix_get_y_scale(self.to_glib_none().0) }
90 }
91
92 #[doc(alias = "graphene_matrix_get_y_translation")]
93 #[doc(alias = "get_y_translation")]
94 pub fn y_translation(&self) -> f32 {
95 unsafe { ffi::graphene_matrix_get_y_translation(self.to_glib_none().0) }
96 }
97
98 #[doc(alias = "graphene_matrix_get_z_scale")]
99 #[doc(alias = "get_z_scale")]
100 pub fn z_scale(&self) -> f32 {
101 unsafe { ffi::graphene_matrix_get_z_scale(self.to_glib_none().0) }
102 }
103
104 #[doc(alias = "graphene_matrix_get_z_translation")]
105 #[doc(alias = "get_z_translation")]
106 pub fn z_translation(&self) -> f32 {
107 unsafe { ffi::graphene_matrix_get_z_translation(self.to_glib_none().0) }
108 }
109
110 #[doc(alias = "graphene_matrix_interpolate")]
111 #[must_use]
112 pub fn interpolate(&self, b: &Matrix, factor: f64) -> Matrix {
113 unsafe {
114 let mut res = Matrix::uninitialized();
115 ffi::graphene_matrix_interpolate(
116 self.to_glib_none().0,
117 b.to_glib_none().0,
118 factor,
119 res.to_glib_none_mut().0,
120 );
121 res
122 }
123 }
124
125 #[doc(alias = "graphene_matrix_inverse")]
126 pub fn inverse(&self) -> Option<Matrix> {
127 unsafe {
128 let mut res = Matrix::uninitialized();
129 let ret = ffi::graphene_matrix_inverse(self.to_glib_none().0, res.to_glib_none_mut().0);
130 if ret {
131 Some(res)
132 } else {
133 None
134 }
135 }
136 }
137
138 #[doc(alias = "graphene_matrix_is_2d")]
139 pub fn is_2d(&self) -> bool {
140 unsafe { ffi::graphene_matrix_is_2d(self.to_glib_none().0) }
141 }
142
143 #[doc(alias = "graphene_matrix_is_backface_visible")]
144 pub fn is_backface_visible(&self) -> bool {
145 unsafe { ffi::graphene_matrix_is_backface_visible(self.to_glib_none().0) }
146 }
147
148 #[doc(alias = "graphene_matrix_is_identity")]
149 pub fn is_identity(&self) -> bool {
150 unsafe { ffi::graphene_matrix_is_identity(self.to_glib_none().0) }
151 }
152
153 #[doc(alias = "graphene_matrix_is_singular")]
154 pub fn is_singular(&self) -> bool {
155 unsafe { ffi::graphene_matrix_is_singular(self.to_glib_none().0) }
156 }
157
158 #[doc(alias = "graphene_matrix_multiply")]
159 #[must_use]
160 pub fn multiply(&self, b: &Matrix) -> Matrix {
161 unsafe {
162 let mut res = Matrix::uninitialized();
163 ffi::graphene_matrix_multiply(
164 self.to_glib_none().0,
165 b.to_glib_none().0,
166 res.to_glib_none_mut().0,
167 );
168 res
169 }
170 }
171
172 #[doc(alias = "graphene_matrix_near")]
173 pub fn near(&self, b: &Matrix, epsilon: f32) -> bool {
174 unsafe { ffi::graphene_matrix_near(self.to_glib_none().0, b.to_glib_none().0, epsilon) }
175 }
176
177 #[doc(alias = "graphene_matrix_normalize")]
178 #[must_use]
179 pub fn normalize(&self) -> Matrix {
180 unsafe {
181 let mut res = Matrix::uninitialized();
182 ffi::graphene_matrix_normalize(self.to_glib_none().0, res.to_glib_none_mut().0);
183 res
184 }
185 }
186
187 #[doc(alias = "graphene_matrix_perspective")]
188 #[must_use]
189 pub fn perspective(&self, depth: f32) -> Matrix {
190 unsafe {
191 let mut res = Matrix::uninitialized();
192 ffi::graphene_matrix_perspective(
193 self.to_glib_none().0,
194 depth,
195 res.to_glib_none_mut().0,
196 );
197 res
198 }
199 }
200
201 #[doc(alias = "graphene_matrix_print")]
202 pub fn print(&self) {
203 unsafe {
204 ffi::graphene_matrix_print(self.to_glib_none().0);
205 }
206 }
207
208 #[doc(alias = "graphene_matrix_project_point")]
209 pub fn project_point(&self, p: &Point) -> Point {
210 unsafe {
211 let mut res = Point::uninitialized();
212 ffi::graphene_matrix_project_point(
213 self.to_glib_none().0,
214 p.to_glib_none().0,
215 res.to_glib_none_mut().0,
216 );
217 res
218 }
219 }
220
221 #[doc(alias = "graphene_matrix_project_rect")]
222 pub fn project_rect(&self, r: &Rect) -> Quad {
223 unsafe {
224 let mut res = Quad::uninitialized();
225 ffi::graphene_matrix_project_rect(
226 self.to_glib_none().0,
227 r.to_glib_none().0,
228 res.to_glib_none_mut().0,
229 );
230 res
231 }
232 }
233
234 #[doc(alias = "graphene_matrix_project_rect_bounds")]
235 pub fn project_rect_bounds(&self, r: &Rect) -> Rect {
236 unsafe {
237 let mut res = Rect::uninitialized();
238 ffi::graphene_matrix_project_rect_bounds(
239 self.to_glib_none().0,
240 r.to_glib_none().0,
241 res.to_glib_none_mut().0,
242 );
243 res
244 }
245 }
246
247 #[doc(alias = "graphene_matrix_rotate")]
248 pub fn rotate(&mut self, angle: f32, axis: &Vec3) {
249 unsafe {
250 ffi::graphene_matrix_rotate(self.to_glib_none_mut().0, angle, axis.to_glib_none().0);
251 }
252 }
253
254 #[doc(alias = "graphene_matrix_rotate_euler")]
255 pub fn rotate_euler(&mut self, e: &Euler) {
256 unsafe {
257 ffi::graphene_matrix_rotate_euler(self.to_glib_none_mut().0, e.to_glib_none().0);
258 }
259 }
260
261 #[doc(alias = "graphene_matrix_rotate_quaternion")]
262 pub fn rotate_quaternion(&mut self, q: &Quaternion) {
263 unsafe {
264 ffi::graphene_matrix_rotate_quaternion(self.to_glib_none_mut().0, q.to_glib_none().0);
265 }
266 }
267
268 #[doc(alias = "graphene_matrix_rotate_x")]
269 pub fn rotate_x(&mut self, angle: f32) {
270 unsafe {
271 ffi::graphene_matrix_rotate_x(self.to_glib_none_mut().0, angle);
272 }
273 }
274
275 #[doc(alias = "graphene_matrix_rotate_y")]
276 pub fn rotate_y(&mut self, angle: f32) {
277 unsafe {
278 ffi::graphene_matrix_rotate_y(self.to_glib_none_mut().0, angle);
279 }
280 }
281
282 #[doc(alias = "graphene_matrix_rotate_z")]
283 pub fn rotate_z(&mut self, angle: f32) {
284 unsafe {
285 ffi::graphene_matrix_rotate_z(self.to_glib_none_mut().0, angle);
286 }
287 }
288
289 #[doc(alias = "graphene_matrix_scale")]
290 pub fn scale(&mut self, factor_x: f32, factor_y: f32, factor_z: f32) {
291 unsafe {
292 ffi::graphene_matrix_scale(self.to_glib_none_mut().0, factor_x, factor_y, factor_z);
293 }
294 }
295
296 #[doc(alias = "graphene_matrix_skew_xy")]
297 pub fn skew_xy(&mut self, factor: f32) {
298 unsafe {
299 ffi::graphene_matrix_skew_xy(self.to_glib_none_mut().0, factor);
300 }
301 }
302
303 #[doc(alias = "graphene_matrix_skew_xz")]
304 pub fn skew_xz(&mut self, factor: f32) {
305 unsafe {
306 ffi::graphene_matrix_skew_xz(self.to_glib_none_mut().0, factor);
307 }
308 }
309
310 #[doc(alias = "graphene_matrix_skew_yz")]
311 pub fn skew_yz(&mut self, factor: f32) {
312 unsafe {
313 ffi::graphene_matrix_skew_yz(self.to_glib_none_mut().0, factor);
314 }
315 }
316
317 #[doc(alias = "graphene_matrix_to_2d")]
318 pub fn to_2d(&self) -> Option<(f64, f64, f64, f64, f64, f64)> {
319 unsafe {
320 let mut xx = std::mem::MaybeUninit::uninit();
321 let mut yx = std::mem::MaybeUninit::uninit();
322 let mut xy = std::mem::MaybeUninit::uninit();
323 let mut yy = std::mem::MaybeUninit::uninit();
324 let mut x_0 = std::mem::MaybeUninit::uninit();
325 let mut y_0 = std::mem::MaybeUninit::uninit();
326 let ret = ffi::graphene_matrix_to_2d(
327 self.to_glib_none().0,
328 xx.as_mut_ptr(),
329 yx.as_mut_ptr(),
330 xy.as_mut_ptr(),
331 yy.as_mut_ptr(),
332 x_0.as_mut_ptr(),
333 y_0.as_mut_ptr(),
334 );
335 if ret {
336 Some((
337 xx.assume_init(),
338 yx.assume_init(),
339 xy.assume_init(),
340 yy.assume_init(),
341 x_0.assume_init(),
342 y_0.assume_init(),
343 ))
344 } else {
345 None
346 }
347 }
348 }
349
350 #[doc(alias = "graphene_matrix_transform_bounds")]
351 pub fn transform_bounds(&self, r: &Rect) -> Rect {
352 unsafe {
353 let mut res = Rect::uninitialized();
354 ffi::graphene_matrix_transform_bounds(
355 self.to_glib_none().0,
356 r.to_glib_none().0,
357 res.to_glib_none_mut().0,
358 );
359 res
360 }
361 }
362
363 #[doc(alias = "graphene_matrix_transform_box")]
364 pub fn transform_box(&self, b: &Box) -> Box {
365 unsafe {
366 let mut res = Box::uninitialized();
367 ffi::graphene_matrix_transform_box(
368 self.to_glib_none().0,
369 b.to_glib_none().0,
370 res.to_glib_none_mut().0,
371 );
372 res
373 }
374 }
375
376 #[doc(alias = "graphene_matrix_transform_point")]
377 pub fn transform_point(&self, p: &Point) -> Point {
378 unsafe {
379 let mut res = Point::uninitialized();
380 ffi::graphene_matrix_transform_point(
381 self.to_glib_none().0,
382 p.to_glib_none().0,
383 res.to_glib_none_mut().0,
384 );
385 res
386 }
387 }
388
389 #[doc(alias = "graphene_matrix_transform_point3d")]
390 pub fn transform_point3d(&self, p: &Point3D) -> Point3D {
391 unsafe {
392 let mut res = Point3D::uninitialized();
393 ffi::graphene_matrix_transform_point3d(
394 self.to_glib_none().0,
395 p.to_glib_none().0,
396 res.to_glib_none_mut().0,
397 );
398 res
399 }
400 }
401
402 #[doc(alias = "graphene_matrix_transform_ray")]
403 pub fn transform_ray(&self, r: &Ray) -> Ray {
404 unsafe {
405 let mut res = Ray::uninitialized();
406 ffi::graphene_matrix_transform_ray(
407 self.to_glib_none().0,
408 r.to_glib_none().0,
409 res.to_glib_none_mut().0,
410 );
411 res
412 }
413 }
414
415 #[doc(alias = "graphene_matrix_transform_rect")]
416 pub fn transform_rect(&self, r: &Rect) -> Quad {
417 unsafe {
418 let mut res = Quad::uninitialized();
419 ffi::graphene_matrix_transform_rect(
420 self.to_glib_none().0,
421 r.to_glib_none().0,
422 res.to_glib_none_mut().0,
423 );
424 res
425 }
426 }
427
428 #[doc(alias = "graphene_matrix_transform_sphere")]
429 pub fn transform_sphere(&self, s: &Sphere) -> Sphere {
430 unsafe {
431 let mut res = Sphere::uninitialized();
432 ffi::graphene_matrix_transform_sphere(
433 self.to_glib_none().0,
434 s.to_glib_none().0,
435 res.to_glib_none_mut().0,
436 );
437 res
438 }
439 }
440
441 #[doc(alias = "graphene_matrix_transform_vec3")]
442 pub fn transform_vec3(&self, v: &Vec3) -> Vec3 {
443 unsafe {
444 let mut res = Vec3::uninitialized();
445 ffi::graphene_matrix_transform_vec3(
446 self.to_glib_none().0,
447 v.to_glib_none().0,
448 res.to_glib_none_mut().0,
449 );
450 res
451 }
452 }
453
454 #[doc(alias = "graphene_matrix_transform_vec4")]
455 pub fn transform_vec4(&self, v: &Vec4) -> Vec4 {
456 unsafe {
457 let mut res = Vec4::uninitialized();
458 ffi::graphene_matrix_transform_vec4(
459 self.to_glib_none().0,
460 v.to_glib_none().0,
461 res.to_glib_none_mut().0,
462 );
463 res
464 }
465 }
466
467 #[doc(alias = "graphene_matrix_translate")]
468 pub fn translate(&mut self, pos: &Point3D) {
469 unsafe {
470 ffi::graphene_matrix_translate(self.to_glib_none_mut().0, pos.to_glib_none().0);
471 }
472 }
473
474 #[doc(alias = "graphene_matrix_transpose")]
475 #[must_use]
476 pub fn transpose(&self) -> Matrix {
477 unsafe {
478 let mut res = Matrix::uninitialized();
479 ffi::graphene_matrix_transpose(self.to_glib_none().0, res.to_glib_none_mut().0);
480 res
481 }
482 }
483
484 #[doc(alias = "graphene_matrix_unproject_point3d")]
485 pub fn unproject_point3d(&self, modelview: &Matrix, point: &Point3D) -> Point3D {
486 unsafe {
487 let mut res = Point3D::uninitialized();
488 ffi::graphene_matrix_unproject_point3d(
489 self.to_glib_none().0,
490 modelview.to_glib_none().0,
491 point.to_glib_none().0,
492 res.to_glib_none_mut().0,
493 );
494 res
495 }
496 }
497
498 #[doc(alias = "graphene_matrix_untransform_bounds")]
499 pub fn untransform_bounds(&self, r: &Rect, bounds: &Rect) -> Rect {
500 unsafe {
501 let mut res = Rect::uninitialized();
502 ffi::graphene_matrix_untransform_bounds(
503 self.to_glib_none().0,
504 r.to_glib_none().0,
505 bounds.to_glib_none().0,
506 res.to_glib_none_mut().0,
507 );
508 res
509 }
510 }
511
512 #[doc(alias = "graphene_matrix_untransform_point")]
513 pub fn untransform_point(&self, p: &Point, bounds: &Rect) -> Option<Point> {
514 unsafe {
515 let mut res = Point::uninitialized();
516 let ret = ffi::graphene_matrix_untransform_point(
517 self.to_glib_none().0,
518 p.to_glib_none().0,
519 bounds.to_glib_none().0,
520 res.to_glib_none_mut().0,
521 );
522 if ret {
523 Some(res)
524 } else {
525 None
526 }
527 }
528 }
529}
530
531impl PartialEq for Matrix {
532 #[inline]
533 fn eq(&self, other: &Self) -> bool {
534 self.equal(other)
535 }
536}
537
538impl Eq for Matrix {}