pango 3.1.1-x64-mingw32 → 3.1.2-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (306) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +27 -5
  3. data/ext/pango/depend +2 -2
  4. data/ext/pango/extconf.rb +32 -28
  5. data/ext/pango/pango.def +0 -16
  6. data/ext/pango/rb-pango-attr-list.c +64 -0
  7. data/ext/pango/rb-pango-attribute.c +147 -0
  8. data/ext/pango/rb-pango-context.c +79 -0
  9. data/ext/pango/{rbpangoconversions.h → rb-pango-conversions.h} +4 -6
  10. data/ext/pango/rb-pango-private.h +27 -0
  11. data/ext/pango/rb-pango.c +32 -0
  12. data/ext/pango/rb-pango.h +29 -0
  13. data/extconf.rb +25 -9
  14. data/lib/2.2/pango.so +0 -0
  15. data/lib/2.3/pango.so +0 -0
  16. data/lib/2.4/pango.so +0 -0
  17. data/lib/pango.rb +24 -68
  18. data/lib/pango/cairo-loader.rb +63 -0
  19. data/lib/pango/color.rb +31 -0
  20. data/lib/pango/deprecated.rb +37 -0
  21. data/lib/pango/font-description.rb +29 -0
  22. data/lib/pango/language.rb +29 -0
  23. data/lib/pango/layout.rb +41 -0
  24. data/lib/pango/loader.rb +87 -0
  25. data/lib/pango/markup.rb +31 -0
  26. data/lib/pango/matrix.rb +64 -0
  27. data/lib/pango/rectangle.rb +28 -0
  28. data/lib/pango/version.rb +30 -0
  29. data/test/pango-test-utils.rb +7 -7
  30. data/test/run-test.rb +34 -8
  31. data/test/test-attr-list.rb +28 -0
  32. data/test/test-color.rb +1 -3
  33. data/test/test-context.rb +4 -4
  34. data/test/test-enum.rb +37 -0
  35. data/test/test-font-description.rb +31 -0
  36. data/test/test-language.rb +2 -1
  37. data/test/test-layout.rb +12 -0
  38. data/test/test-markup.rb +30 -0
  39. data/test/test-matrix.rb +131 -5
  40. data/test/test-rectangle.rb +16 -3
  41. data/vendor/local/bin/derb.exe +0 -0
  42. data/vendor/local/bin/genbrk.exe +0 -0
  43. data/vendor/local/bin/genccode.exe +0 -0
  44. data/vendor/local/bin/gencfu.exe +0 -0
  45. data/vendor/local/bin/gencmn.exe +0 -0
  46. data/vendor/local/bin/gencnval.exe +0 -0
  47. data/vendor/local/bin/gendict.exe +0 -0
  48. data/vendor/local/bin/gennorm2.exe +0 -0
  49. data/vendor/local/bin/genrb.exe +0 -0
  50. data/vendor/local/bin/gensprep.exe +0 -0
  51. data/vendor/local/bin/hb-ot-shape-closure.exe +0 -0
  52. data/vendor/local/bin/hb-shape.exe +0 -0
  53. data/vendor/local/bin/hb-view.exe +0 -0
  54. data/vendor/local/bin/icuinfo.exe +0 -0
  55. data/vendor/local/bin/icupkg.exe +0 -0
  56. data/vendor/local/bin/libgraphene-1.0-0.dll +0 -0
  57. data/vendor/local/bin/libharfbuzz-0.dll +0 -0
  58. data/vendor/local/bin/libpango-1.0-0.dll +0 -0
  59. data/vendor/local/bin/libpangocairo-1.0-0.dll +0 -0
  60. data/vendor/local/bin/libpangoft2-1.0-0.dll +0 -0
  61. data/vendor/local/bin/libpangowin32-1.0-0.dll +0 -0
  62. data/vendor/local/bin/makeconv.exe +0 -0
  63. data/vendor/local/bin/pango-view.exe +0 -0
  64. data/vendor/local/bin/pkgdata.exe +0 -0
  65. data/vendor/local/bin/uconv.exe +0 -0
  66. data/vendor/local/include/graphene-1.0/graphene-box.h +148 -0
  67. data/vendor/local/include/graphene-1.0/graphene-euler.h +140 -0
  68. data/vendor/local/include/graphene-1.0/graphene-frustum.h +93 -0
  69. data/vendor/local/include/graphene-1.0/graphene-gobject.h +119 -0
  70. data/vendor/local/include/graphene-1.0/graphene-macros.h +105 -0
  71. data/vendor/local/include/graphene-1.0/graphene-matrix.h +288 -0
  72. data/vendor/local/include/graphene-1.0/graphene-plane.h +99 -0
  73. data/vendor/local/include/graphene-1.0/graphene-point.h +120 -0
  74. data/vendor/local/include/graphene-1.0/graphene-point3d.h +140 -0
  75. data/vendor/local/include/graphene-1.0/graphene-quad.h +80 -0
  76. data/vendor/local/include/graphene-1.0/graphene-quaternion.h +136 -0
  77. data/vendor/local/include/graphene-1.0/graphene-ray.h +98 -0
  78. data/vendor/local/include/graphene-1.0/graphene-rect.h +180 -0
  79. data/vendor/local/include/graphene-1.0/graphene-simd4f.h +1870 -0
  80. data/vendor/local/include/graphene-1.0/graphene-simd4x4f.h +1045 -0
  81. data/vendor/local/include/graphene-1.0/graphene-size.h +105 -0
  82. data/vendor/local/include/graphene-1.0/graphene-sphere.h +97 -0
  83. data/vendor/local/include/graphene-1.0/graphene-triangle.h +105 -0
  84. data/vendor/local/include/graphene-1.0/graphene-types.h +88 -0
  85. data/vendor/local/include/graphene-1.0/graphene-vec2.h +130 -0
  86. data/vendor/local/include/graphene-1.0/graphene-vec3.h +155 -0
  87. data/vendor/local/include/graphene-1.0/graphene-vec4.h +156 -0
  88. data/vendor/local/include/graphene-1.0/graphene-version-macros.h +185 -0
  89. data/vendor/local/include/graphene-1.0/graphene-version.h +70 -0
  90. data/vendor/local/include/graphene-1.0/graphene.h +61 -0
  91. data/vendor/local/include/harfbuzz/hb-common.h +36 -0
  92. data/vendor/local/include/harfbuzz/hb-font.h +18 -1
  93. data/vendor/local/include/harfbuzz/hb-ot-var.h +105 -0
  94. data/vendor/local/include/harfbuzz/hb-ot.h +1 -0
  95. data/vendor/local/include/harfbuzz/hb-shape.h +0 -16
  96. data/vendor/local/include/harfbuzz/hb-version.h +2 -2
  97. data/vendor/local/include/pango-1.0/pango/pango-engine.h +6 -6
  98. data/vendor/local/include/pango-1.0/pango/pango-features.h +2 -2
  99. data/vendor/local/include/pango-1.0/pango/pango-layout.h +1 -1
  100. data/vendor/local/lib/girepository-1.0/Graphene-1.0.typelib +0 -0
  101. data/vendor/local/lib/girepository-1.0/Pango-1.0.typelib +0 -0
  102. data/vendor/local/lib/graphene-1.0/include/graphene-config.h +89 -0
  103. data/vendor/local/lib/icudt.dll +0 -0
  104. data/vendor/local/lib/icudt58.dll +0 -0
  105. data/vendor/local/lib/icuin.dll +0 -0
  106. data/vendor/local/lib/icuin58.dll +0 -0
  107. data/vendor/local/lib/icuio.dll +0 -0
  108. data/vendor/local/lib/icuio58.dll +0 -0
  109. data/vendor/local/lib/icutest.dll +0 -0
  110. data/vendor/local/lib/icutest58.dll +0 -0
  111. data/vendor/local/lib/icutu.dll +0 -0
  112. data/vendor/local/lib/icutu58.dll +0 -0
  113. data/vendor/local/lib/icuuc.dll +0 -0
  114. data/vendor/local/lib/icuuc58.dll +0 -0
  115. data/vendor/local/lib/libgraphene-1.0.dll.a +0 -0
  116. data/vendor/local/lib/libgraphene-1.0.la +41 -0
  117. data/vendor/local/lib/libharfbuzz-icu.a +0 -0
  118. data/vendor/local/lib/libharfbuzz-icu.la +1 -1
  119. data/vendor/local/lib/libharfbuzz.dll.a +0 -0
  120. data/vendor/local/lib/libharfbuzz.la +1 -1
  121. data/vendor/local/lib/libicudt.dll.a +0 -0
  122. data/vendor/local/lib/libicuin.dll.a +0 -0
  123. data/vendor/local/lib/libicuio.dll.a +0 -0
  124. data/vendor/local/lib/libicutest.dll.a +0 -0
  125. data/vendor/local/lib/libicutu.dll.a +0 -0
  126. data/vendor/local/lib/libicuuc.dll.a +0 -0
  127. data/vendor/local/lib/libpango-1.0.dll.a +0 -0
  128. data/vendor/local/lib/libpango-1.0.la +1 -1
  129. data/vendor/local/lib/libpangocairo-1.0.dll.a +0 -0
  130. data/vendor/local/lib/libpangocairo-1.0.la +1 -1
  131. data/vendor/local/lib/libpangoft2-1.0.dll.a +0 -0
  132. data/vendor/local/lib/libpangoft2-1.0.la +1 -1
  133. data/vendor/local/lib/libpangowin32-1.0.dll.a +0 -0
  134. data/vendor/local/lib/libpangowin32-1.0.la +1 -1
  135. data/vendor/local/lib/pkgconfig/graphene-1.0.pc +15 -0
  136. data/vendor/local/lib/pkgconfig/graphene-gobject-1.0.pc +15 -0
  137. data/vendor/local/lib/pkgconfig/harfbuzz-icu.pc +1 -1
  138. data/vendor/local/lib/pkgconfig/harfbuzz.pc +1 -1
  139. data/vendor/local/lib/pkgconfig/pango.pc +1 -1
  140. data/vendor/local/lib/pkgconfig/pangocairo.pc +1 -1
  141. data/vendor/local/lib/pkgconfig/pangoft2.pc +1 -1
  142. data/vendor/local/lib/pkgconfig/pangowin32.pc +1 -1
  143. data/vendor/local/share/gir-1.0/Graphene-1.0.gir +8180 -0
  144. data/vendor/local/share/gir-1.0/Pango-1.0.gir +12 -16
  145. data/vendor/local/share/gtk-doc/html/graphene/annotation-glossary.html +57 -0
  146. data/vendor/local/share/gtk-doc/html/graphene/api-index.html +1985 -0
  147. data/vendor/local/share/gtk-doc/html/graphene/ch01.html +97 -0
  148. data/vendor/local/share/gtk-doc/html/graphene/deprecated-api-index.html +34 -0
  149. data/vendor/local/share/gtk-doc/html/graphene/graphene-Box.html +1252 -0
  150. data/vendor/local/share/gtk-doc/html/graphene/graphene-Euler.html +886 -0
  151. data/vendor/local/share/gtk-doc/html/graphene/graphene-Frustum.html +527 -0
  152. data/vendor/local/share/gtk-doc/html/graphene/graphene-GObject-integration.html +147 -0
  153. data/vendor/local/share/gtk-doc/html/graphene/graphene-Matrix.html +2959 -0
  154. data/vendor/local/share/gtk-doc/html/graphene/graphene-Plane.html +641 -0
  155. data/vendor/local/share/gtk-doc/html/graphene/graphene-Point.html +689 -0
  156. data/vendor/local/share/gtk-doc/html/graphene/graphene-Point3D.html +916 -0
  157. data/vendor/local/share/gtk-doc/html/graphene/graphene-Quad.html +418 -0
  158. data/vendor/local/share/gtk-doc/html/graphene/graphene-Quaternion.html +1056 -0
  159. data/vendor/local/share/gtk-doc/html/graphene/graphene-Ray.html +596 -0
  160. data/vendor/local/share/gtk-doc/html/graphene/graphene-Rectangle.html +1483 -0
  161. data/vendor/local/share/gtk-doc/html/graphene/graphene-SIMD-matrix.html +1475 -0
  162. data/vendor/local/share/gtk-doc/html/graphene/graphene-SIMD-vector.html +3046 -0
  163. data/vendor/local/share/gtk-doc/html/graphene/graphene-Size.html +489 -0
  164. data/vendor/local/share/gtk-doc/html/graphene/graphene-Sphere.html +641 -0
  165. data/vendor/local/share/gtk-doc/html/graphene/graphene-Triangle.html +705 -0
  166. data/vendor/local/share/gtk-doc/html/graphene/graphene-Vectors.html +3715 -0
  167. data/vendor/local/share/gtk-doc/html/graphene/graphene-Versioning-information.html +104 -0
  168. data/vendor/local/share/gtk-doc/html/graphene/graphene.devhelp2 +534 -0
  169. data/vendor/local/share/gtk-doc/html/graphene/home.png +0 -0
  170. data/vendor/local/share/gtk-doc/html/graphene/index.html +107 -0
  171. data/vendor/local/share/gtk-doc/html/graphene/ix03.html +1313 -0
  172. data/vendor/local/share/gtk-doc/html/graphene/ix04.html +582 -0
  173. data/vendor/local/share/gtk-doc/html/graphene/ix05.html +151 -0
  174. data/vendor/local/share/gtk-doc/html/graphene/ix06.html +34 -0
  175. data/vendor/local/share/gtk-doc/html/graphene/left-insensitive.png +0 -0
  176. data/vendor/local/share/gtk-doc/html/graphene/left.png +0 -0
  177. data/vendor/local/share/gtk-doc/html/{pango/api-index-1-40.html → graphene/object-tree.html} +14 -11
  178. data/vendor/local/share/gtk-doc/html/graphene/rectangle-intersection.png +0 -0
  179. data/vendor/local/share/gtk-doc/html/graphene/rectangle-union.png +0 -0
  180. data/vendor/local/share/gtk-doc/html/graphene/rectangle.png +0 -0
  181. data/vendor/local/share/gtk-doc/html/graphene/right-insensitive.png +0 -0
  182. data/vendor/local/share/gtk-doc/html/graphene/right.png +0 -0
  183. data/vendor/local/share/gtk-doc/html/graphene/style.css +479 -0
  184. data/vendor/local/share/gtk-doc/html/graphene/triangle-barycentric.png +0 -0
  185. data/vendor/local/share/gtk-doc/html/graphene/up-insensitive.png +0 -0
  186. data/vendor/local/share/gtk-doc/html/graphene/up.png +0 -0
  187. data/vendor/local/share/gtk-doc/html/harfbuzz/api-index-1-2-3.html +2 -2
  188. data/vendor/local/share/gtk-doc/html/harfbuzz/{api-index-1-4-0.html → api-index-1-3-3.html} +2 -2
  189. data/vendor/local/share/gtk-doc/html/harfbuzz/api-index-full.html +104 -0
  190. data/vendor/local/share/gtk-doc/html/harfbuzz/deprecated-api-index.html +9 -2
  191. data/vendor/local/share/gtk-doc/html/harfbuzz/harfbuzz-Shaping.html +1 -1
  192. data/vendor/local/share/gtk-doc/html/harfbuzz/harfbuzz-hb-font.html +156 -40
  193. data/vendor/local/share/gtk-doc/html/harfbuzz/harfbuzz-hb-gobject.html +73 -0
  194. data/vendor/local/share/gtk-doc/html/harfbuzz/harfbuzz-hb-graphite2.html +1 -0
  195. data/vendor/local/share/gtk-doc/html/harfbuzz/harfbuzz-hb-ot-layout.html +49 -0
  196. data/vendor/local/share/gtk-doc/html/harfbuzz/harfbuzz-hb-ot-math.html +174 -177
  197. data/vendor/local/share/gtk-doc/html/harfbuzz/harfbuzz-hb-shape-plan.html +40 -0
  198. data/vendor/local/share/gtk-doc/html/harfbuzz/harfbuzz-hb-version.html +2 -2
  199. data/vendor/local/share/gtk-doc/html/harfbuzz/harfbuzz.devhelp2 +28 -10
  200. data/vendor/local/share/gtk-doc/html/harfbuzz/index.html +1 -1
  201. data/vendor/local/share/gtk-doc/html/harfbuzz/pt02.html +2 -2
  202. data/vendor/local/share/gtk-doc/html/pango/PangoEngineLang.html +2 -2
  203. data/vendor/local/share/gtk-doc/html/pango/PangoEngineShape.html +2 -2
  204. data/vendor/local/share/gtk-doc/html/pango/PangoFcDecoder.html +1 -1
  205. data/vendor/local/share/gtk-doc/html/pango/PangoFcFont.html +1 -1
  206. data/vendor/local/share/gtk-doc/html/pango/PangoFcFontMap.html +3 -3
  207. data/vendor/local/share/gtk-doc/html/pango/PangoMarkupFormat.html +1 -1
  208. data/vendor/local/share/gtk-doc/html/pango/PangoRenderer.html +2 -2
  209. data/vendor/local/share/gtk-doc/html/pango/annotation-glossary.html +1 -1
  210. data/vendor/local/share/gtk-doc/html/pango/api-index-full.html +1 -1
  211. data/vendor/local/share/gtk-doc/html/pango/index.html +2 -23
  212. data/vendor/local/share/gtk-doc/html/pango/lowlevel.html +1 -1
  213. data/vendor/local/share/gtk-doc/html/pango/pango-Bidirectional-Text.html +1 -1
  214. data/vendor/local/share/gtk-doc/html/pango/pango-Cairo-Rendering.html +69 -69
  215. data/vendor/local/share/gtk-doc/html/pango/pango-CoreText-Fonts.html +1 -1
  216. data/vendor/local/share/gtk-doc/html/pango/pango-Coverage-Maps.html +1 -1
  217. data/vendor/local/share/gtk-doc/html/pango/pango-Engines.html +5 -1
  218. data/vendor/local/share/gtk-doc/html/pango/pango-Fonts.html +5 -4
  219. data/vendor/local/share/gtk-doc/html/pango/pango-FreeType-Fonts-and-Rendering.html +8 -4
  220. data/vendor/local/share/gtk-doc/html/pango/pango-Glyph-Storage.html +3 -3
  221. data/vendor/local/share/gtk-doc/html/pango/pango-Layout-Objects.html +4 -4
  222. data/vendor/local/share/gtk-doc/html/pango/pango-Miscellaneous-Utilities.html +1 -1
  223. data/vendor/local/share/gtk-doc/html/pango/pango-Modules.html +3 -1
  224. data/vendor/local/share/gtk-doc/html/pango/pango-OpenType-Font-Handling.html +1 -1
  225. data/vendor/local/share/gtk-doc/html/pango/pango-Scripts-and-Languages.html +3 -3
  226. data/vendor/local/share/gtk-doc/html/pango/pango-Tab-Stops.html +1 -1
  227. data/vendor/local/share/gtk-doc/html/pango/pango-Text-Attributes.html +1 -1
  228. data/vendor/local/share/gtk-doc/html/pango/pango-Text-Processing.html +3 -3
  229. data/vendor/local/share/gtk-doc/html/pango/pango-Version-Checking.html +3 -3
  230. data/vendor/local/share/gtk-doc/html/pango/pango-Vertical-Text.html +1 -1
  231. data/vendor/local/share/gtk-doc/html/pango/pango-Win32-Fonts-and-Rendering.html +3 -3
  232. data/vendor/local/share/gtk-doc/html/pango/pango-Xft-Fonts-and-Rendering.html +1 -1
  233. data/vendor/local/share/gtk-doc/html/pango/pango-hierarchy.html +1 -1
  234. data/vendor/local/share/gtk-doc/html/pango/pango.html +1 -1
  235. data/vendor/local/share/gtk-doc/html/pango/rendering.html +1 -1
  236. data/vendor/local/share/man/man1/pango-view.1 +2 -2
  237. metadata +119 -78
  238. data/README +0 -32
  239. data/ext/pango/rbpango.c +0 -356
  240. data/ext/pango/rbpango.h +0 -95
  241. data/ext/pango/rbpangoanalysis.c +0 -218
  242. data/ext/pango/rbpangoattribute.c +0 -506
  243. data/ext/pango/rbpangoattriterator.c +0 -141
  244. data/ext/pango/rbpangoattrlist.c +0 -101
  245. data/ext/pango/rbpangocairo.c +0 -122
  246. data/ext/pango/rbpangocairocontext.c +0 -131
  247. data/ext/pango/rbpangocolor.c +0 -120
  248. data/ext/pango/rbpangocontext.c +0 -344
  249. data/ext/pango/rbpangocoverage.c +0 -106
  250. data/ext/pango/rbpangoengine.c +0 -73
  251. data/ext/pango/rbpangofont.c +0 -110
  252. data/ext/pango/rbpangofontdescription.c +0 -282
  253. data/ext/pango/rbpangofontface.c +0 -73
  254. data/ext/pango/rbpangofontfamily.c +0 -79
  255. data/ext/pango/rbpangofontmap.c +0 -102
  256. data/ext/pango/rbpangofontmetrics.c +0 -85
  257. data/ext/pango/rbpangofontset.c +0 -69
  258. data/ext/pango/rbpangofontsetsimple.c +0 -60
  259. data/ext/pango/rbpangoglyphinfo.c +0 -123
  260. data/ext/pango/rbpangoglyphitem.c +0 -125
  261. data/ext/pango/rbpangoglyphstring.c +0 -151
  262. data/ext/pango/rbpangogravity.c +0 -54
  263. data/ext/pango/rbpangoitem.c +0 -95
  264. data/ext/pango/rbpangolanguage.c +0 -94
  265. data/ext/pango/rbpangolayout.c +0 -583
  266. data/ext/pango/rbpangolayoutiter.c +0 -189
  267. data/ext/pango/rbpangolayoutline.c +0 -243
  268. data/ext/pango/rbpangologattr.c +0 -109
  269. data/ext/pango/rbpangomatrix.c +0 -143
  270. data/ext/pango/rbpangoprivate.h +0 -49
  271. data/ext/pango/rbpangorectangle.c +0 -170
  272. data/ext/pango/rbpangorenderer.c +0 -193
  273. data/ext/pango/rbpangoscript.c +0 -84
  274. data/ext/pango/rbpangoscriptiter.c +0 -92
  275. data/ext/pango/rbpangotabarray.c +0 -128
  276. data/sample/attribute.rb +0 -82
  277. data/sample/break.rb +0 -28
  278. data/sample/gdk_layout.rb +0 -27
  279. data/sample/glyphstring.rb +0 -61
  280. data/sample/item.rb +0 -37
  281. data/sample/label.rb +0 -23
  282. data/sample/layout.rb +0 -102
  283. data/sample/pango_cairo.rb +0 -66
  284. data/sample/parse.rb +0 -33
  285. data/sample/sample.txt +0 -10
  286. data/sample/script.rb +0 -23
  287. data/vendor/local/share/gtk-doc/html/pango/api-index-1-10.html +0 -134
  288. data/vendor/local/share/gtk-doc/html/pango/api-index-1-12.html +0 -48
  289. data/vendor/local/share/gtk-doc/html/pango/api-index-1-14.html +0 -63
  290. data/vendor/local/share/gtk-doc/html/pango/api-index-1-16.html +0 -227
  291. data/vendor/local/share/gtk-doc/html/pango/api-index-1-18.html +0 -151
  292. data/vendor/local/share/gtk-doc/html/pango/api-index-1-2.html +0 -121
  293. data/vendor/local/share/gtk-doc/html/pango/api-index-1-20.html +0 -86
  294. data/vendor/local/share/gtk-doc/html/pango/api-index-1-22.html +0 -123
  295. data/vendor/local/share/gtk-doc/html/pango/api-index-1-24.html +0 -96
  296. data/vendor/local/share/gtk-doc/html/pango/api-index-1-26.html +0 -45
  297. data/vendor/local/share/gtk-doc/html/pango/api-index-1-30.html +0 -38
  298. data/vendor/local/share/gtk-doc/html/pango/api-index-1-31-0.html +0 -38
  299. data/vendor/local/share/gtk-doc/html/pango/api-index-1-32-4.html +0 -52
  300. data/vendor/local/share/gtk-doc/html/pango/api-index-1-32.html +0 -41
  301. data/vendor/local/share/gtk-doc/html/pango/api-index-1-34.html +0 -38
  302. data/vendor/local/share/gtk-doc/html/pango/api-index-1-38.html +0 -79
  303. data/vendor/local/share/gtk-doc/html/pango/api-index-1-4.html +0 -200
  304. data/vendor/local/share/gtk-doc/html/pango/api-index-1-6.html +0 -164
  305. data/vendor/local/share/gtk-doc/html/pango/api-index-1-8.html +0 -170
  306. data/vendor/local/share/gtk-doc/html/pango/api-index-deprecated.html +0 -441
@@ -0,0 +1,1045 @@
1
+ /* graphene-simd4x4f.h: 4x4 float vector operations
2
+ *
3
+ * Copyright 2014 Emmanuele Bassi
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in
13
+ * all copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ * THE SOFTWARE.
22
+ */
23
+
24
+ #ifndef __GRAPHENE_SIMD4X4F_H__
25
+ #define __GRAPHENE_SIMD4X4F_H__
26
+
27
+ #include "graphene-simd4f.h"
28
+
29
+ #include <math.h>
30
+ #include <float.h>
31
+
32
+ GRAPHENE_BEGIN_DECLS
33
+
34
+ /**
35
+ * graphene_simd4x4f_t:
36
+ *
37
+ * A SIMD-based matrix type that uses four #graphene_simd4f_t vectors.
38
+ *
39
+ * The matrix is treated as row-major, i.e. the x, y, z, and w vectors
40
+ * are rows, and elements of each vector are a column:
41
+ *
42
+ * |[<!-- language="C" -->
43
+ * graphene_simd4x4f_t = {
44
+ * x.x, x.y, x.z, x.w,
45
+ * y.x, y.y, y.z, y.w,
46
+ * z.x, z.y, z.z, z.w,
47
+ * w.x, w.y, w.z, w.w
48
+ * }
49
+ * ]|
50
+ *
51
+ * The contents of the #graphene_simd4x4f_t type are private and
52
+ * cannot be accessed directly; use the provided API instead.
53
+ *
54
+ * Since: 1.0
55
+ */
56
+
57
+ /**
58
+ * graphene_simd4x4f_init:
59
+ * @x: a #graphene_simd4f_t for the first row
60
+ * @y: a #graphene_simd4f_t for the second row
61
+ * @z: a #graphene_simd4f_t for the third row
62
+ * @w: a #graphene_simd4f_t for the fourth row
63
+ *
64
+ * Creates a new #graphene_simd4x4f_t using the given row vectors
65
+ * to initialize it.
66
+ *
67
+ * Returns: the newly created #graphene_simd4x4f_t
68
+ *
69
+ * Since: 1.0
70
+ */
71
+ static inline graphene_simd4x4f_t GRAPHENE_VECTORCALL
72
+ graphene_simd4x4f_init (graphene_simd4f_t x,
73
+ graphene_simd4f_t y,
74
+ graphene_simd4f_t z,
75
+ graphene_simd4f_t w)
76
+ {
77
+ graphene_simd4x4f_t s;
78
+
79
+ s.x = x;
80
+ s.y = y;
81
+ s.z = z;
82
+ s.w = w;
83
+
84
+ return s;
85
+ }
86
+
87
+ /**
88
+ * graphene_simd4x4f_init_identity:
89
+ * @m: a #graphene_simd4x4f_t
90
+ *
91
+ * Initializes @m to be the identity matrix.
92
+ *
93
+ * Since: 1.0
94
+ */
95
+ static inline void
96
+ graphene_simd4x4f_init_identity (graphene_simd4x4f_t *m)
97
+ {
98
+ *m = graphene_simd4x4f_init (graphene_simd4f_init (1.0f, 0.0f, 0.0f, 0.0f),
99
+ graphene_simd4f_init (0.0f, 1.0f, 0.0f, 0.0f),
100
+ graphene_simd4f_init (0.0f, 0.0f, 1.0f, 0.0f),
101
+ graphene_simd4f_init (0.0f, 0.0f, 0.0f, 1.0f));
102
+ }
103
+
104
+ /**
105
+ * graphene_simd4x4f_init_from_float:
106
+ * @m: a #graphene_simd4x4f_t
107
+ * @f: (array fixed-size=16): an array of 16 floating point values
108
+ *
109
+ * Initializes a #graphene_simd4x4f_t with the given array
110
+ * of floating point values.
111
+ *
112
+ * Since: 1.0
113
+ */
114
+ static inline void
115
+ graphene_simd4x4f_init_from_float (graphene_simd4x4f_t *m,
116
+ const float *f)
117
+ {
118
+ m->x = graphene_simd4f_init_4f (f + 0);
119
+ m->y = graphene_simd4f_init_4f (f + 4);
120
+ m->z = graphene_simd4f_init_4f (f + 8);
121
+ m->w = graphene_simd4f_init_4f (f + 12);
122
+ }
123
+
124
+ /**
125
+ * graphene_simd4x4f_to_float:
126
+ * @m: a #graphene_sidm4x4f_t
127
+ * @v: (out caller-allocates) (array fixed-size=16): a floating
128
+ * point values vector capable of holding at least 16 values
129
+ *
130
+ * Copies the content of @m in a float array.
131
+ *
132
+ * Since: 1.0
133
+ */
134
+ static inline void
135
+ graphene_simd4x4f_to_float (const graphene_simd4x4f_t *m,
136
+ float *v)
137
+ {
138
+ graphene_simd4f_dup_4f (m->x, v + 0);
139
+ graphene_simd4f_dup_4f (m->y, v + 4);
140
+ graphene_simd4f_dup_4f (m->z, v + 8);
141
+ graphene_simd4f_dup_4f (m->w, v + 12);
142
+ }
143
+
144
+ GRAPHENE_AVAILABLE_IN_1_0
145
+ void graphene_simd4x4f_transpose_in_place (graphene_simd4x4f_t *s);
146
+
147
+ #if defined(GRAPHENE_USE_SSE)
148
+
149
+ #ifdef __GNUC__
150
+ #define graphene_simd4x4f_transpose_in_place(s) \
151
+ (__extension__ ({ \
152
+ _MM_TRANSPOSE4_PS ((s)->x, (s)->y, (s)->z, (s)->w); \
153
+ }))
154
+ #elif defined (_MSC_VER)
155
+ #define graphene_simd4x4f_transpose_in_place(s) \
156
+ _MM_TRANSPOSE4_PS ((s)->x, (s)->y, (s)->z, (s)->w)
157
+ #endif
158
+
159
+ #elif defined(GRAPHENE_USE_GCC)
160
+
161
+ #define graphene_simd4x4f_transpose_in_place(s) \
162
+ (__extension__ ({ \
163
+ const graphene_simd4f_t sx = (s)->x; \
164
+ const graphene_simd4f_t sy = (s)->y; \
165
+ const graphene_simd4f_t sz = (s)->z; \
166
+ const graphene_simd4f_t sw = (s)->w; \
167
+ (s)->x = graphene_simd4f_init (sx[0], sy[0], sz[0], sw[0]); \
168
+ (s)->y = graphene_simd4f_init (sx[1], sy[1], sz[1], sw[1]); \
169
+ (s)->z = graphene_simd4f_init (sx[2], sy[2], sz[2], sw[2]); \
170
+ (s)->w = graphene_simd4f_init (sx[3], sy[3], sz[3], sw[3]); \
171
+ }))
172
+
173
+ #elif defined(GRAPHENE_USE_ARM_NEON)
174
+
175
+ #define graphene_simd4x4f_transpose_in_place(s) \
176
+ (__extension__ ({ \
177
+ const graphene_simd4f_union_t sx = { (s)->x }; \
178
+ const graphene_simd4f_union_t sy = { (s)->y }; \
179
+ const graphene_simd4f_union_t sz = { (s)->z }; \
180
+ const graphene_simd4f_union_t sw = { (s)->w }; \
181
+ (s)->x = graphene_simd4f_init (sx.f[0], sy.f[0], sz.f[0], sw.f[0]); \
182
+ (s)->y = graphene_simd4f_init (sx.f[1], sy.f[1], sz.f[1], sw.f[1]); \
183
+ (s)->z = graphene_simd4f_init (sx.f[2], sy.f[2], sz.f[2], sw.f[2]); \
184
+ (s)->w = graphene_simd4f_init (sx.f[3], sy.f[3], sz.f[3], sw.f[3]); \
185
+ }))
186
+
187
+ #elif defined(GRAPHENE_USE_SCALAR)
188
+
189
+ #define graphene_simd4x4f_transpose_in_place(s) \
190
+ (graphene_simd4x4f_transpose_in_place ((graphene_simd4x4f_t *) (s)))
191
+
192
+ #else
193
+ # error "No implementation for graphene_simd4x4f_t defined."
194
+ #endif
195
+
196
+ /**
197
+ * graphene_simd4x4f_sum:
198
+ * @a: a #graphene_simd4f_t
199
+ * @res: (out): return location for the sum vector
200
+ *
201
+ * Adds all the row vectors of @a.
202
+ *
203
+ * Since: 1.0
204
+ */
205
+ static inline void
206
+ graphene_simd4x4f_sum (const graphene_simd4x4f_t *a,
207
+ graphene_simd4f_t *res)
208
+ {
209
+ graphene_simd4f_t s = graphene_simd4f_add (a->x, a->y);
210
+ s = graphene_simd4f_add (s, a->z);
211
+ s = graphene_simd4f_add (s, a->w);
212
+ *res = s;
213
+ }
214
+
215
+ /**
216
+ * graphene_simd4x4f_vec4_mul:
217
+ * @a: a #graphene_simd4x4f_t
218
+ * @b: a #graphene_simd4f_t
219
+ * @res: (out): return location for a #graphene_simd4f_t
220
+ *
221
+ * Multiplies the given #graphene_simd4x4f_t with the given
222
+ * #graphene_simd4f_t using a dot product.
223
+ *
224
+ * Since: 1.0
225
+ */
226
+ static inline void
227
+ graphene_simd4x4f_vec4_mul (const graphene_simd4x4f_t *a,
228
+ const graphene_simd4f_t *b,
229
+ graphene_simd4f_t *res)
230
+ {
231
+ const graphene_simd4f_t v = *b;
232
+ const graphene_simd4f_t v_x = graphene_simd4f_splat_x (v);
233
+ const graphene_simd4f_t v_y = graphene_simd4f_splat_y (v);
234
+ const graphene_simd4f_t v_z = graphene_simd4f_splat_z (v);
235
+ const graphene_simd4f_t v_w = graphene_simd4f_splat_w (v);
236
+
237
+ *res = graphene_simd4f_add (graphene_simd4f_add (graphene_simd4f_mul (a->x, v_x),
238
+ graphene_simd4f_mul (a->y, v_y)),
239
+ graphene_simd4f_add (graphene_simd4f_mul (a->z, v_z),
240
+ graphene_simd4f_mul (a->w, v_w)));
241
+ }
242
+
243
+ /**
244
+ * graphene_simd4x4f_vec3_mul:
245
+ * @m: a #graphene_simd4x4f_t
246
+ * @v: a #graphene_simd4f_t
247
+ * @res: (out): return location for a #graphene_simd4f_t
248
+ *
249
+ * Multiplies the given #graphene_simd4x4f_t with the given
250
+ * #graphene_simd4f_t, using only the first three row vectors
251
+ * of the matrix, and the first three components of the vector.
252
+ *
253
+ * Since: 1.0
254
+ */
255
+ static inline void
256
+ graphene_simd4x4f_vec3_mul (const graphene_simd4x4f_t *m,
257
+ const graphene_simd4f_t *v,
258
+ graphene_simd4f_t *res)
259
+ {
260
+ const graphene_simd4f_t v_x = graphene_simd4f_splat_x (*v);
261
+ const graphene_simd4f_t v_y = graphene_simd4f_splat_y (*v);
262
+ const graphene_simd4f_t v_z = graphene_simd4f_splat_z (*v);
263
+
264
+ *res = graphene_simd4f_add (graphene_simd4f_add (graphene_simd4f_mul (m->x, v_x),
265
+ graphene_simd4f_mul (m->y, v_y)),
266
+ graphene_simd4f_mul (m->z, v_z));
267
+ }
268
+
269
+ /**
270
+ * graphene_simd4x4f_point3_mul:
271
+ * @m: a #graphene_simd4x4f_t
272
+ * @p: a #graphene_simd4f_t
273
+ * @res: (out): return location for a #graphene_simd4f_t
274
+ *
275
+ * Multiplies the given #graphene_simd4x4f_t with the given
276
+ * #graphene_simd4f_t.
277
+ *
278
+ * Unlike graphene_simd4x4f_vec3_mul(), this function will
279
+ * also use the fourth row vector of the matrix.
280
+ *
281
+ * Since: 1.0
282
+ */
283
+ static inline void
284
+ graphene_simd4x4f_point3_mul (const graphene_simd4x4f_t *m,
285
+ const graphene_simd4f_t *p,
286
+ graphene_simd4f_t *res)
287
+ {
288
+ const graphene_simd4f_t v = *p;
289
+ const graphene_simd4f_t v_x = graphene_simd4f_splat_x (v);
290
+ const graphene_simd4f_t v_y = graphene_simd4f_splat_y (v);
291
+ const graphene_simd4f_t v_z = graphene_simd4f_splat_z (v);
292
+
293
+ *res = graphene_simd4f_add (graphene_simd4f_add (graphene_simd4f_mul (m->x, v_x),
294
+ graphene_simd4f_mul (m->y, v_y)),
295
+ graphene_simd4f_add (graphene_simd4f_mul (m->z, v_z),
296
+ m->w));
297
+ }
298
+
299
+ /**
300
+ * graphene_simd4x4f_transpose:
301
+ * @s: a #graphene_simd4x4f_t
302
+ * @res: (out): return location for the transposed matrix
303
+ *
304
+ * Transposes the given #graphene_simd4x4f_t.
305
+ *
306
+ * Since: 1.0
307
+ */
308
+ static inline void
309
+ graphene_simd4x4f_transpose (const graphene_simd4x4f_t *s,
310
+ graphene_simd4x4f_t *res)
311
+ {
312
+ *res = *s;
313
+ graphene_simd4x4f_transpose_in_place (res);
314
+ }
315
+
316
+ /**
317
+ * graphene_simd4x4f_inv_ortho_vec3_mul:
318
+ * @a: a #graphene_simd4x4f_t
319
+ * @b: a #graphene_simd4f_t
320
+ * @res: (out): return location for the transformed vector
321
+ *
322
+ * Performs the inverse orthographic transformation of the first
323
+ * three components in the given vector, using the first three
324
+ * row vectors of the given SIMD matrix.
325
+ *
326
+ * Since: 1.0
327
+ */
328
+ static inline void
329
+ graphene_simd4x4f_inv_ortho_vec3_mul (const graphene_simd4x4f_t *a,
330
+ const graphene_simd4f_t *b,
331
+ graphene_simd4f_t *res)
332
+ {
333
+ graphene_simd4x4f_t transpose = *a;
334
+ graphene_simd4f_t translation = *b;
335
+
336
+ transpose.w = graphene_simd4f_init (0.f, 0.f, 0.f, 0.f);
337
+ graphene_simd4x4f_transpose_in_place (&transpose);
338
+
339
+ graphene_simd4x4f_vec3_mul (&transpose, &translation, res);
340
+ }
341
+
342
+ /**
343
+ * graphene_simd4x4f_inv_ortho_point3_mul:
344
+ * @a: a #graphene_simd4x4f_t
345
+ * @b: a #graphene_simd4x4f_t
346
+ * @res: (out): return location for the result vector
347
+ *
348
+ * Performs the inverse orthographic transformation of the first
349
+ * three components in the given vector, using the given SIMD
350
+ * matrix.
351
+ *
352
+ * Unlike graphene_simd4x4f_inv_ortho_vec3_mul(), this function
353
+ * will also use the fourth row vector of the SIMD matrix.
354
+ *
355
+ * Since: 1.0
356
+ */
357
+ static inline void
358
+ graphene_simd4x4f_inv_ortho_point3_mul (const graphene_simd4x4f_t *a,
359
+ const graphene_simd4f_t *b,
360
+ graphene_simd4f_t *res)
361
+ {
362
+ graphene_simd4f_t translation = graphene_simd4f_sub (*b, a->w);
363
+ graphene_simd4x4f_t transpose = *a;
364
+
365
+ transpose.w = graphene_simd4f_init (0.f, 0.f, 0.f, 0.f);
366
+ graphene_simd4x4f_transpose_in_place (&transpose);
367
+
368
+ graphene_simd4x4f_point3_mul (&transpose, &translation, res);
369
+ }
370
+
371
+ /**
372
+ * graphene_simd4x4f_matrix_mul:
373
+ * @a: a #graphene_simd4x4f_t
374
+ * @b: a #graphene_simd4x4f_t
375
+ * @res: (out): return location for the result
376
+ *
377
+ * Multiplies the two matrices.
378
+ *
379
+ * Since: 1.0
380
+ */
381
+ static inline void
382
+ graphene_simd4x4f_matrix_mul (const graphene_simd4x4f_t *a,
383
+ const graphene_simd4x4f_t *b,
384
+ graphene_simd4x4f_t *res)
385
+ {
386
+ #if 0
387
+ /* this is the classic naive A*B implementation of the row * column
388
+ * matrix product. using a SIMD scalar implementation, it's fairly
389
+ * slow at 329ns per multiplication; the SSE implementation makes it
390
+ * about 10x faster, at 32ns; the GCC vector implementation is only
391
+ * 5x faster, at 66ns. the biggest culprits are the transpose operation
392
+ * and the multiple, one lane reads to compute the scalar sum.
393
+ */
394
+ graphene_simd4x4f_t t;
395
+
396
+ graphene_simd4x4f_transpose (b, &t);
397
+
398
+ res->x =
399
+ graphene_simd4f_init (graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->x, t.x)),
400
+ graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->x, t.y)),
401
+ graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->x, t.z)),
402
+ graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->x, t.w)));
403
+
404
+ res->y =
405
+ graphene_simd4f_init (graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->y, t.x)),
406
+ graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->y, t.y)),
407
+ graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->y, t.z)),
408
+ graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->y, t.w)));
409
+
410
+ res->z =
411
+ graphene_simd4f_init (graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->z, t.x)),
412
+ graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->z, t.y)),
413
+ graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->z, t.z)),
414
+ graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->z, t.w)));
415
+
416
+ res->w =
417
+ graphene_simd4f_init (graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->w, t.x)),
418
+ graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->w, t.y)),
419
+ graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->w, t.z)),
420
+ graphene_simd4f_sum_scalar (graphene_simd4f_mul (a->w, t.w)));
421
+ #else
422
+ /* this is an optimized version of the matrix multiplication, using
423
+ * four dot products for each row vector. this yields drastically
424
+ * better numbers while retaining the same correct results as above:
425
+ * the scalar implementation now clocks at 91ns; the GCC vector
426
+ * implementation is 19ns; and the SSE implementation is 16ns.
427
+ *
428
+ * the order is correct if we want to multiply A with B; remember
429
+ * that matrix multiplication is non-commutative.
430
+ */
431
+ graphene_simd4x4f_vec4_mul (b, &a->x, &res->x);
432
+ graphene_simd4x4f_vec4_mul (b, &a->y, &res->y);
433
+ graphene_simd4x4f_vec4_mul (b, &a->z, &res->z);
434
+ graphene_simd4x4f_vec4_mul (b, &a->w, &res->w);
435
+ #endif
436
+ }
437
+
438
+ /**
439
+ * graphene_simd4x4f_init_perspective:
440
+ * @m: a #graphene_simd4x4f_t
441
+ * @fovy_rad: the angle of the field of vision, in radians
442
+ * @aspect: the aspect value
443
+ * @z_near: the depth of the near clipping plane
444
+ * @z_far: the depth of the far clipping plane
445
+ *
446
+ * Initializes a #graphene_simd4x4f_t with a perspective projection.
447
+ *
448
+ * Since: 1.0
449
+ */
450
+ static inline void
451
+ graphene_simd4x4f_init_perspective (graphene_simd4x4f_t *m,
452
+ float fovy_rad,
453
+ float aspect,
454
+ float z_near,
455
+ float z_far)
456
+ {
457
+ float delta_z = z_far - z_near;
458
+ float cotangent = tanf (GRAPHENE_PI_2 - fovy_rad * 0.5f);
459
+
460
+ float a = cotangent / aspect;
461
+ float b = cotangent;
462
+ float c = -(z_far + z_near) / delta_z;
463
+ float d = -2 * z_near * z_far / delta_z;
464
+
465
+ m->x = graphene_simd4f_init ( a, 0.0f, 0.0f, 0.0f);
466
+ m->y = graphene_simd4f_init (0.0f, b, 0.0f, 0.0f);
467
+ m->z = graphene_simd4f_init (0.0f, 0.0f, c, -1.0f);
468
+ m->w = graphene_simd4f_init (0.0f, 0.0f, d, 0.0f);
469
+ }
470
+
471
+ /**
472
+ * graphene_simd4x4f_init_ortho:
473
+ * @m: a #graphene_simd4x4f_t
474
+ * @left: edge of the left clipping plane
475
+ * @right: edge of the right clipping plane
476
+ * @bottom: edge of the bottom clipping plane
477
+ * @top: edge of the top clipping plane
478
+ * @z_near: depth of the near clipping plane
479
+ * @z_far: depth of the far clipping plane
480
+ *
481
+ * Initializes the given SIMD matrix with an orthographic projection.
482
+ *
483
+ * Since: 1.0
484
+ */
485
+ static inline void
486
+ graphene_simd4x4f_init_ortho (graphene_simd4x4f_t *m,
487
+ float left,
488
+ float right,
489
+ float bottom,
490
+ float top,
491
+ float z_near,
492
+ float z_far)
493
+ {
494
+ float delta_x = right - left;
495
+ float delta_y = top - bottom;
496
+ float delta_z = z_far - z_near;
497
+
498
+ float a = 2.0f / delta_x;
499
+ float b = -(right + left) / delta_x;
500
+ float c = 2.0f / delta_y;
501
+ float d = -(top + bottom) / delta_y;
502
+ float e = -2.0f / delta_z;
503
+ float f = -(z_far + z_near) / delta_z;
504
+
505
+ m->x = graphene_simd4f_init ( a, 0.0f, 0.0f, 0.0f);
506
+ m->y = graphene_simd4f_init (0.0f, c, 0.0f, 0.0f);
507
+ m->z = graphene_simd4f_init (0.0f, 0.0f, e, 0.0f);
508
+ m->w = graphene_simd4f_init ( b, d, f, 1.0f);
509
+ }
510
+
511
+ /**
512
+ * graphene_simd4x4f_init_look_at:
513
+ * @m: a #graphene_simd4x4f_t
514
+ * @eye: vector for the camera coordinates
515
+ * @center: vector for the object coordinates
516
+ * @up: vector for the upwards direction
517
+ *
518
+ * Initializes a SIMD matrix with the projection necessary for
519
+ * the camera at the @eye coordinates to look at the object at
520
+ * the @center coordinates. The top of the camera is aligned to
521
+ * the @up vector.
522
+ *
523
+ * Since: 1.0
524
+ */
525
+ static inline void
526
+ graphene_simd4x4f_init_look_at (graphene_simd4x4f_t *m,
527
+ graphene_simd4f_t eye,
528
+ graphene_simd4f_t center,
529
+ graphene_simd4f_t up)
530
+ {
531
+ const graphene_simd4f_t z_axis = graphene_simd4f_normalize3 (graphene_simd4f_sub (center, eye));
532
+ const graphene_simd4f_t x_axis = graphene_simd4f_normalize3 (graphene_simd4f_cross3 (z_axis, up));
533
+ const graphene_simd4f_t y_axis = graphene_simd4f_cross3 (x_axis, z_axis);
534
+ float eye_v[4];
535
+
536
+ graphene_simd4f_dup_4f (eye, eye_v);
537
+
538
+ m->x = x_axis;
539
+ m->y = y_axis;
540
+ m->z = graphene_simd4f_neg (z_axis);
541
+ m->w = graphene_simd4f_init (-eye_v[0], -eye_v[1], -eye_v[2], 1.f);
542
+ }
543
+
544
+ /**
545
+ * graphene_simd4x4f_init_frustum:
546
+ * @m: a #graphene_simd4x4f_t
547
+ * @left: distance of the left clipping plane
548
+ * @right: distance of the right clipping plane
549
+ * @bottom: distance of the bottom clipping plane
550
+ * @top: distance of the top clipping plane
551
+ * @z_near: distance of the near clipping plane
552
+ * @z_far: distance of the far clipping plane
553
+ *
554
+ * Initializes a SIMD matrix with a frustum described by the distances
555
+ * of six clipping planes.
556
+ *
557
+ * Since: 1.2
558
+ */
559
+ static inline void
560
+ graphene_simd4x4f_init_frustum (graphene_simd4x4f_t *m,
561
+ float left,
562
+ float right,
563
+ float bottom,
564
+ float top,
565
+ float z_near,
566
+ float z_far)
567
+ {
568
+ float x = 2.f * z_near / (right - left);
569
+ float y = 2.f * z_near / (top - bottom);
570
+
571
+ float a = (right + left) / (right - left);
572
+ float b = (top + bottom) / (top - bottom);
573
+ float c = -1.f * (z_far + z_near) / (z_far - z_near);
574
+ float d = -2.f * z_far * z_near / (z_far - z_near);
575
+
576
+ m->x = graphene_simd4f_init ( x, 0.f, 0.f, 0.f);
577
+ m->y = graphene_simd4f_init (0.f, y, 0.f, 0.f);
578
+ m->z = graphene_simd4f_init ( a, b, c, -1.f);
579
+ m->w = graphene_simd4f_init (0.f, 0.f, d, 0.f);
580
+ }
581
+
582
+ /**
583
+ * graphene_simd4x4f_perspective:
584
+ * @m: a #graphene_simd4x4f_t
585
+ * @depth: depth of the perspective
586
+ *
587
+ * Adds a perspective transformation for the given @depth.
588
+ *
589
+ * Since: 1.0
590
+ */
591
+ static inline void
592
+ graphene_simd4x4f_perspective (graphene_simd4x4f_t *m,
593
+ float depth)
594
+ {
595
+ #if 1
596
+ const float m_xw = graphene_simd4f_get_w (m->x);
597
+ const float m_yw = graphene_simd4f_get_w (m->y);
598
+ const float m_zw = graphene_simd4f_get_w (m->z);
599
+ const float m_ww = graphene_simd4f_get_w (m->w);
600
+
601
+ const float p0 = graphene_simd4f_get_z (m->x) + -1.0f / depth * m_xw;
602
+ const float p1 = graphene_simd4f_get_z (m->y) + -1.0f / depth * m_yw;
603
+ const float p2 = graphene_simd4f_get_z (m->z) + -1.0f / depth * m_zw;
604
+ const float p3 = graphene_simd4f_get_z (m->w) + -1.0f / depth * m_ww;
605
+
606
+ const graphene_simd4f_t p_x = graphene_simd4f_merge_w (m->x, m_xw + p0);
607
+ const graphene_simd4f_t p_y = graphene_simd4f_merge_w (m->y, m_yw + p1);
608
+ const graphene_simd4f_t p_z = graphene_simd4f_merge_w (m->z, m_zw + p2);
609
+ const graphene_simd4f_t p_w = graphene_simd4f_merge_w (m->w, m_ww + p3);
610
+ #else
611
+ /* this is equivalent to the operations above, but trying to inline
612
+ * them into SIMD registers as much as possible by transposing the
613
+ * original matrix and operating on the resulting column vectors. it
614
+ * should warrant a micro benchmark, because while the above code is
615
+ * dominated by single channel reads, the code below has a transpose
616
+ * operation.
617
+ */
618
+ graphene_simd4x4f_t t;
619
+ const graphene_simd4f_t f, p;
620
+ const graphene_simd4f_t p_x, p_y, p_z, p_w;
621
+
622
+ graphene_simd4x4f_transpose (m, &t);
623
+
624
+ f = graphene_simd4f_neg (graphene_simd4f_reciprocal (graphene_simd4f_splat (depth)));
625
+ p = graphene_simd4f_sum (t.w, graphene_simd4f_sum (t.z, graphene_simd4f_mul (f, t.w)));
626
+ p_x = graphene_simd4f_merge_w (m->x, graphene_simd4f_get_x (p));
627
+ p_y = graphene_simd4f_merge_w (m->y, graphene_simd4f_get_y (p));
628
+ p_z = graphene_simd4f_merge_w (m->z, graphene_simd4f_get_z (p));
629
+ p_w = graphene_simd4f_merge_w (m->w, graphene_simd4f_get_w (p));
630
+ #endif
631
+
632
+ *m = graphene_simd4x4f_init (p_x, p_y, p_z, p_w);
633
+ }
634
+
635
+ /**
636
+ * graphene_simd4x4f_translation:
637
+ * @m: a #graphene_simd4x4f_t
638
+ * @x: coordinate of the X translation
639
+ * @y: coordinate of the Y translation
640
+ * @z: coordinate of the Z translation
641
+ *
642
+ * Initializes @m to contain a translation to the given coordinates.
643
+ *
644
+ * Since: 1.0
645
+ */
646
+ static inline void
647
+ graphene_simd4x4f_translation (graphene_simd4x4f_t *m,
648
+ float x,
649
+ float y,
650
+ float z)
651
+ {
652
+ *m = graphene_simd4x4f_init (graphene_simd4f_init (1.0f, 0.0f, 0.0f, 0.0f),
653
+ graphene_simd4f_init (0.0f, 1.0f, 0.0f, 0.0f),
654
+ graphene_simd4f_init (0.0f, 0.0f, 1.0f, 0.0f),
655
+ graphene_simd4f_init ( x, y, z, 1.0f));
656
+ }
657
+
658
+ /**
659
+ * graphene_simd4x4f_scale:
660
+ * @m: a #graphene_simd4x4f_t
661
+ * @x: scaling factor on the X axis
662
+ * @y: scaling factor on the Y axis
663
+ * @z: scaling factor on the Z axis
664
+ *
665
+ * Initializes @m to contain a scaling transformation with the
666
+ * given factors.
667
+ *
668
+ * Since: 1.0
669
+ */
670
+ static inline void
671
+ graphene_simd4x4f_scale (graphene_simd4x4f_t *m,
672
+ float x,
673
+ float y,
674
+ float z)
675
+ {
676
+ *m = graphene_simd4x4f_init (graphene_simd4f_init ( x, 0.0f, 0.0f, 0.0f),
677
+ graphene_simd4f_init (0.0f, y, 0.0f, 0.0f),
678
+ graphene_simd4f_init (0.0f, 0.0f, z, 0.0f),
679
+ graphene_simd4f_init (0.0f, 0.0f, 0.0f, 1.0f));
680
+
681
+ }
682
+
683
+ /**
684
+ * graphene_simd4x4f_rotation:
685
+ * @m: a #graphene_simd4x4f_t
686
+ * @rad: the rotation, in radians
687
+ * @axis: the vector of the axis of rotation
688
+ *
689
+ * Initializes @m to contain a rotation of the given angle
690
+ * along the given axis.
691
+ *
692
+ * Since: 1.0
693
+ */
694
+ static inline void
695
+ graphene_simd4x4f_rotation (graphene_simd4x4f_t *m,
696
+ float rad,
697
+ graphene_simd4f_t axis)
698
+ {
699
+ float sine, cosine;
700
+ float x, y, z;
701
+ float ab, bc, ca;
702
+ float tx, ty, tz;
703
+ graphene_simd4f_t i, j, k;
704
+
705
+ rad = -rad;
706
+ axis = graphene_simd4f_normalize3 (axis);
707
+
708
+ /* We cannot use graphene_sincos() because it's a private function, whereas
709
+ * graphene-simd4x4f.h is a public header
710
+ */
711
+ sine = sinf (rad);
712
+ cosine = cosf (rad);
713
+
714
+ x = graphene_simd4f_get_x (axis);
715
+ y = graphene_simd4f_get_y (axis);
716
+ z = graphene_simd4f_get_z (axis);
717
+
718
+ ab = x * y * (1.0f - cosine);
719
+ bc = y * z * (1.0f - cosine);
720
+ ca = z * x * (1.0f - cosine);
721
+
722
+ tx = x * x;
723
+ ty = y * y;
724
+ tz = z * z;
725
+
726
+ i = graphene_simd4f_init (tx + cosine * (1.0f - tx), ab - z * sine, ca + y * sine, 0.f);
727
+ j = graphene_simd4f_init (ab + z * sine, ty + cosine * (1.0f - ty), bc - x * sine, 0.f);
728
+ k = graphene_simd4f_init (ca - y * sine, bc + x * sine, tz + cosine * (1.0f - tz), 0.f);
729
+
730
+ *m = graphene_simd4x4f_init (i, j, k, graphene_simd4f_init (0.0f, 0.0f, 0.0f, 1.0f));
731
+ }
732
+
733
+ /**
734
+ * graphene_simd4x4f_add:
735
+ * @a: a #graphene_simd4x4f_t
736
+ * @b: a #graphene_simd4x4f_t
737
+ * @res: (out caller-allocates): return location for a #graphene_simd4x4f_t
738
+ *
739
+ * Adds each row vector of @a and @b and places the results in @res.
740
+ *
741
+ * Since: 1.0
742
+ */
743
+ static inline void
744
+ graphene_simd4x4f_add (const graphene_simd4x4f_t *a,
745
+ const graphene_simd4x4f_t *b,
746
+ graphene_simd4x4f_t *res)
747
+ {
748
+ res->x = graphene_simd4f_add (a->x, b->x);
749
+ res->y = graphene_simd4f_add (a->y, b->y);
750
+ res->z = graphene_simd4f_add (a->z, b->z);
751
+ res->w = graphene_simd4f_add (a->w, b->w);
752
+ }
753
+
754
+ /**
755
+ * graphene_simd4x4f_sub:
756
+ * @a: a #graphene_simd4x4f_t
757
+ * @b: a #graphene_simd4x4f_t
758
+ * @res: (out caller-allocates): return location for a #graphene_simd4x4f_t
759
+ *
760
+ * Subtracts each row vector of @a and @b and places the results in @res.
761
+ *
762
+ * Since: 1.0
763
+ */
764
+ static inline void
765
+ graphene_simd4x4f_sub (const graphene_simd4x4f_t *a,
766
+ const graphene_simd4x4f_t *b,
767
+ graphene_simd4x4f_t *res)
768
+ {
769
+ res->x = graphene_simd4f_sub (a->x, b->x);
770
+ res->y = graphene_simd4f_sub (a->y, b->y);
771
+ res->z = graphene_simd4f_sub (a->z, b->z);
772
+ res->w = graphene_simd4f_sub (a->w, b->w);
773
+ }
774
+
775
+ /**
776
+ * graphene_simd4x4f_mul:
777
+ * @a: a #graphene_simd4x4f_t
778
+ * @b: a #graphene_simd4x4f_t
779
+ * @res: (out caller-allocates): return location for a #graphene_simd4x4f_t
780
+ *
781
+ * Multiplies each row vector of @a and @b and places the results in @res.
782
+ *
783
+ * You most likely want graphene_simd4x4f_matrix_mul() instead.
784
+ *
785
+ * Since: 1.0
786
+ */
787
+ static inline void
788
+ graphene_simd4x4f_mul (const graphene_simd4x4f_t *a,
789
+ const graphene_simd4x4f_t *b,
790
+ graphene_simd4x4f_t *res)
791
+ {
792
+ res->x = graphene_simd4f_mul (a->x, b->x);
793
+ res->y = graphene_simd4f_mul (a->y, b->y);
794
+ res->z = graphene_simd4f_mul (a->z, b->z);
795
+ res->w = graphene_simd4f_mul (a->w, b->w);
796
+ }
797
+
798
+ /**
799
+ * graphene_simd4x4f_div:
800
+ * @a: a #graphene_simd4x4f_t
801
+ * @b: a #graphene_simd4x4f_t
802
+ * @res: (out caller-allocates): return location for a #graphene_simd4x4f_t
803
+ *
804
+ * Divides each row vector of @a and @b and places the results in @res.
805
+ *
806
+ * Since: 1.0
807
+ */
808
+ static inline void
809
+ graphene_simd4x4f_div (const graphene_simd4x4f_t *a,
810
+ const graphene_simd4x4f_t *b,
811
+ graphene_simd4x4f_t *res)
812
+ {
813
+ res->x = graphene_simd4f_div (a->x, b->x);
814
+ res->y = graphene_simd4f_div (a->y, b->y);
815
+ res->z = graphene_simd4f_div (a->z, b->z);
816
+ res->w = graphene_simd4f_div (a->w, b->w);
817
+ }
818
+
819
+ /**
820
+ * graphene_simd4x4f_inverse:
821
+ * @m: a #graphene_simd4x4f_t
822
+ * @res: (out): return location for the inverse matrix
823
+ *
824
+ * Inverts the given #graphene_simd4x4f_t.
825
+ *
826
+ * Returns: `true` if the matrix was invertible
827
+ *
828
+ * Since: 1.0
829
+ */
830
+ static inline bool
831
+ graphene_simd4x4f_inverse (const graphene_simd4x4f_t *m,
832
+ graphene_simd4x4f_t *res)
833
+ {
834
+ /* split rows */
835
+ const graphene_simd4f_t r0 = m->x;
836
+ const graphene_simd4f_t r1 = m->y;
837
+ const graphene_simd4f_t r2 = m->z;
838
+ const graphene_simd4f_t r3 = m->w;
839
+
840
+ /* cofactors */
841
+ const graphene_simd4f_t r0_wxyz = graphene_simd4f_shuffle_wxyz (r0);
842
+ const graphene_simd4f_t r0_zwxy = graphene_simd4f_shuffle_zwxy (r0);
843
+ const graphene_simd4f_t r0_yzwx = graphene_simd4f_shuffle_yzwx (r0);
844
+
845
+ const graphene_simd4f_t r1_wxyz = graphene_simd4f_shuffle_wxyz (r1);
846
+ const graphene_simd4f_t r1_zwxy = graphene_simd4f_shuffle_zwxy (r1);
847
+ const graphene_simd4f_t r1_yzwx = graphene_simd4f_shuffle_yzwx (r1);
848
+
849
+ const graphene_simd4f_t r2_wxyz = graphene_simd4f_shuffle_wxyz (r2);
850
+ const graphene_simd4f_t r2_zwxy = graphene_simd4f_shuffle_zwxy (r2);
851
+ const graphene_simd4f_t r2_yzwx = graphene_simd4f_shuffle_yzwx (r2);
852
+
853
+ const graphene_simd4f_t r3_wxyz = graphene_simd4f_shuffle_wxyz (r3);
854
+ const graphene_simd4f_t r3_zwxy = graphene_simd4f_shuffle_zwxy (r3);
855
+ const graphene_simd4f_t r3_yzwx = graphene_simd4f_shuffle_yzwx (r3);
856
+
857
+ const graphene_simd4f_t r0_wxyz_x_r1 = graphene_simd4f_mul (r0_wxyz, r1);
858
+ const graphene_simd4f_t r0_wxyz_x_r1_yzwx = graphene_simd4f_mul (r0_wxyz, r1_yzwx);
859
+ const graphene_simd4f_t r0_wxyz_x_r1_zwxy = graphene_simd4f_mul (r0_wxyz, r1_zwxy);
860
+
861
+ const graphene_simd4f_t r2_wxyz_x_r3 = graphene_simd4f_mul (r2_wxyz, r3);
862
+ const graphene_simd4f_t r2_wxyz_x_r3_yzwx = graphene_simd4f_mul (r2_wxyz, r3_yzwx);
863
+ const graphene_simd4f_t r2_wxyz_x_r3_zwxy = graphene_simd4f_mul (r2_wxyz, r3_zwxy);
864
+
865
+ const graphene_simd4f_t ar1 = graphene_simd4f_sub (graphene_simd4f_shuffle_wxyz (r2_wxyz_x_r3_zwxy),
866
+ graphene_simd4f_shuffle_zwxy (r2_wxyz_x_r3));
867
+ const graphene_simd4f_t ar2 = graphene_simd4f_sub (graphene_simd4f_shuffle_zwxy (r2_wxyz_x_r3_yzwx),
868
+ r2_wxyz_x_r3_yzwx);
869
+ const graphene_simd4f_t ar3 = graphene_simd4f_sub (r2_wxyz_x_r3_zwxy,
870
+ graphene_simd4f_shuffle_wxyz (r2_wxyz_x_r3));
871
+
872
+ const graphene_simd4f_t br1 = graphene_simd4f_sub (graphene_simd4f_shuffle_wxyz (r0_wxyz_x_r1_zwxy),
873
+ graphene_simd4f_shuffle_zwxy (r0_wxyz_x_r1));
874
+ const graphene_simd4f_t br2 = graphene_simd4f_sub (graphene_simd4f_shuffle_zwxy (r0_wxyz_x_r1_yzwx),
875
+ r0_wxyz_x_r1_yzwx);
876
+ const graphene_simd4f_t br3 = graphene_simd4f_sub (r0_wxyz_x_r1_zwxy,
877
+ graphene_simd4f_shuffle_wxyz (r0_wxyz_x_r1));
878
+
879
+ const graphene_simd4f_t r0_sum =
880
+ graphene_simd4f_madd (r0_yzwx, ar3,
881
+ graphene_simd4f_madd (r0_zwxy, ar2,
882
+ graphene_simd4f_mul (r0_wxyz, ar1)));
883
+ const graphene_simd4f_t r1_sum =
884
+ graphene_simd4f_madd (r1_wxyz, ar1,
885
+ graphene_simd4f_madd (r1_zwxy, ar2,
886
+ graphene_simd4f_mul (r1_yzwx, ar3)));
887
+ const graphene_simd4f_t r2_sum =
888
+ graphene_simd4f_madd (r2_yzwx, br3,
889
+ graphene_simd4f_madd (r2_zwxy, br2,
890
+ graphene_simd4f_mul (r2_wxyz, br1)));
891
+ const graphene_simd4f_t r3_sum =
892
+ graphene_simd4f_madd (r3_yzwx, br3,
893
+ graphene_simd4f_madd (r3_zwxy, br2,
894
+ graphene_simd4f_mul (r3_wxyz, br1)));
895
+
896
+ /* determinant and its inverse */
897
+ const graphene_simd4f_t d0 = graphene_simd4f_mul (r1_sum, r0);
898
+ const graphene_simd4f_t d1 = graphene_simd4f_add (d0, graphene_simd4f_merge_high (d0, d0));
899
+ const graphene_simd4f_t det = graphene_simd4f_sub (d1, graphene_simd4f_splat_y (d1));
900
+ if (graphene_simd4f_get_x (det) != 0.f)
901
+ {
902
+ const graphene_simd4f_t invdet = graphene_simd4f_splat_x (graphene_simd4f_div (graphene_simd4f_splat (1.0f), det));
903
+
904
+ const graphene_simd4f_t o0 = graphene_simd4f_mul (graphene_simd4f_flip_sign_0101 (r1_sum), invdet);
905
+ const graphene_simd4f_t o1 = graphene_simd4f_mul (graphene_simd4f_flip_sign_1010 (r0_sum), invdet);
906
+ const graphene_simd4f_t o2 = graphene_simd4f_mul (graphene_simd4f_flip_sign_0101 (r3_sum), invdet);
907
+ const graphene_simd4f_t o3 = graphene_simd4f_mul (graphene_simd4f_flip_sign_1010 (r2_sum), invdet);
908
+
909
+ graphene_simd4x4f_t mt = graphene_simd4x4f_init (o0, o1, o2, o3);
910
+
911
+ /* transpose the resulting matrix */
912
+ graphene_simd4x4f_transpose (&mt, res);
913
+
914
+ return true;
915
+ }
916
+
917
+ return false;
918
+ }
919
+
920
+ /**
921
+ * graphene_simd4x4f_determinant:
922
+ * @m: a #graphene_simd4x4f_t
923
+ * @det_r: (out): return location for the matrix determinant
924
+ * @invdet_r: (out): return location for the inverse of the matrix
925
+ * determinant
926
+ *
927
+ * Computes the determinant (and its inverse) of the given matrix
928
+ *
929
+ * Since: 1.0
930
+ */
931
+ static inline void
932
+ graphene_simd4x4f_determinant (const graphene_simd4x4f_t *m,
933
+ graphene_simd4f_t *det_r,
934
+ graphene_simd4f_t *invdet_r)
935
+ {
936
+ /* split rows */
937
+ const graphene_simd4f_t r0 = m->x;
938
+ const graphene_simd4f_t r1 = m->y;
939
+ const graphene_simd4f_t r2 = m->z;
940
+ const graphene_simd4f_t r3 = m->w;
941
+
942
+ /* cofactors */
943
+ const graphene_simd4f_t r1_wxyz = graphene_simd4f_shuffle_wxyz (r1);
944
+ const graphene_simd4f_t r1_zwxy = graphene_simd4f_shuffle_zwxy (r1);
945
+ const graphene_simd4f_t r1_yzwx = graphene_simd4f_shuffle_yzwx (r1);
946
+
947
+ const graphene_simd4f_t r2_wxyz = graphene_simd4f_shuffle_wxyz (r2);
948
+
949
+ const graphene_simd4f_t r3_zwxy = graphene_simd4f_shuffle_zwxy (r3);
950
+ const graphene_simd4f_t r3_yzwx = graphene_simd4f_shuffle_yzwx (r3);
951
+
952
+ const graphene_simd4f_t r2_wxyz_x_r3 = graphene_simd4f_mul (r2_wxyz, r3);
953
+ const graphene_simd4f_t r2_wxyz_x_r3_yzwx = graphene_simd4f_mul (r2_wxyz, r3_yzwx);
954
+ const graphene_simd4f_t r2_wxyz_x_r3_zwxy = graphene_simd4f_mul (r2_wxyz, r3_zwxy);
955
+
956
+ const graphene_simd4f_t ar1 = graphene_simd4f_sub (graphene_simd4f_shuffle_wxyz (r2_wxyz_x_r3_zwxy),
957
+ graphene_simd4f_shuffle_zwxy (r2_wxyz_x_r3));
958
+ const graphene_simd4f_t ar2 = graphene_simd4f_sub (graphene_simd4f_shuffle_zwxy (r2_wxyz_x_r3_yzwx),
959
+ r2_wxyz_x_r3_yzwx);
960
+ const graphene_simd4f_t ar3 = graphene_simd4f_sub (r2_wxyz_x_r3_zwxy,
961
+ graphene_simd4f_shuffle_wxyz (r2_wxyz_x_r3));
962
+
963
+ const graphene_simd4f_t r1_sum =
964
+ graphene_simd4f_madd (r1_wxyz, ar1,
965
+ graphene_simd4f_madd (r1_zwxy, ar2,
966
+ graphene_simd4f_mul (r1_yzwx, ar3)));
967
+
968
+ /* determinant and its inverse */
969
+ const graphene_simd4f_t d0 = graphene_simd4f_mul (r1_sum, r0);
970
+ const graphene_simd4f_t d1 = graphene_simd4f_add (d0, graphene_simd4f_merge_high (d0, d0));
971
+
972
+ const graphene_simd4f_t det = graphene_simd4f_sub (d1, graphene_simd4f_splat_y (d1));
973
+
974
+ const graphene_simd4f_t invdet = graphene_simd4f_splat_x (graphene_simd4f_div (graphene_simd4f_splat (1.0f), det));
975
+
976
+ if (det_r != NULL)
977
+ *det_r = det;
978
+
979
+ if (invdet_r != NULL)
980
+ *invdet_r = invdet;
981
+ }
982
+
983
+ /**
984
+ * graphene_simd4x4f_is_identity:
985
+ * @m: a #graphene_simd4x4f_t
986
+ *
987
+ * Checks whether the given matrix is the identity matrix.
988
+ *
989
+ * Returns: `true` if the matrix is the identity matrix
990
+ *
991
+ * Since: 1.0
992
+ */
993
+ static inline bool
994
+ graphene_simd4x4f_is_identity (const graphene_simd4x4f_t *m)
995
+ {
996
+ const graphene_simd4f_t r0 = graphene_simd4f_init (1.0f, 0.0f, 0.0f, 0.0f);
997
+ const graphene_simd4f_t r1 = graphene_simd4f_init (0.0f, 1.0f, 0.0f, 0.0f);
998
+ const graphene_simd4f_t r2 = graphene_simd4f_init (0.0f, 0.0f, 1.0f, 0.0f);
999
+ const graphene_simd4f_t r3 = graphene_simd4f_init (0.0f, 0.0f, 0.0f, 1.0f);
1000
+
1001
+ return graphene_simd4f_cmp_eq (m->x, r0) &&
1002
+ graphene_simd4f_cmp_eq (m->y, r1) &&
1003
+ graphene_simd4f_cmp_eq (m->z, r2) &&
1004
+ graphene_simd4f_cmp_eq (m->w, r3);
1005
+ }
1006
+
1007
+ /**
1008
+ * graphene_simd4x4f_is_2d:
1009
+ * @m: a #graphene_simd4x4f_t
1010
+ *
1011
+ * Checks whether the given matrix is compatible with an affine
1012
+ * transformation matrix.
1013
+ *
1014
+ * Returns: `true` if the matrix is compatible with an affine
1015
+ * transformation matrix
1016
+ *
1017
+ * Since: 1.0
1018
+ */
1019
+ static inline bool
1020
+ graphene_simd4x4f_is_2d (const graphene_simd4x4f_t *m)
1021
+ {
1022
+ float f[4];
1023
+
1024
+ if (!(fabsf (graphene_simd4f_get_z (m->x)) < FLT_EPSILON && fabsf (graphene_simd4f_get_w (m->x)) < FLT_EPSILON))
1025
+ return false;
1026
+
1027
+ if (!(fabsf (graphene_simd4f_get_z (m->y)) < FLT_EPSILON && fabsf (graphene_simd4f_get_w (m->y)) < FLT_EPSILON))
1028
+ return false;
1029
+
1030
+ graphene_simd4f_dup_4f (m->z, f);
1031
+ if (!(fabsf (f[0]) < FLT_EPSILON &&
1032
+ fabsf (f[1]) < FLT_EPSILON &&
1033
+ 1.f - fabsf (f[2]) < FLT_EPSILON &&
1034
+ fabsf (f[3]) < FLT_EPSILON))
1035
+ return false;
1036
+
1037
+ if (!(fabsf (graphene_simd4f_get_z (m->w)) < FLT_EPSILON && 1.f - fabsf (graphene_simd4f_get_w (m->w)) < FLT_EPSILON))
1038
+ return false;
1039
+
1040
+ return true;
1041
+ }
1042
+
1043
+ GRAPHENE_END_DECLS
1044
+
1045
+ #endif /* __GRAPHENE_SIMD4X4F_H__ */