@quicktvui/ai 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/package.json +1 -1
  2. package/rules/.clinerules +27 -4
  3. package/rules/.cursorrules +27 -4
  4. package/rules/.github/copilot-instructions.md +27 -4
  5. package/rules/.source/hippy/extend_views/CoverFlowHorizontalView.java +203 -0
  6. package/rules/.source/hippy/extend_views/CoverFlowVerticalView.java +203 -0
  7. package/rules/.source/hippy/extend_views/CoverFlowViewController.java +195 -0
  8. package/rules/.source/hippy/extend_views/EngineRootView.java +125 -0
  9. package/rules/.source/hippy/extend_views/ExtendTag.java +83 -0
  10. package/rules/.source/hippy/extend_views/FocusSearchHelper.java +124 -0
  11. package/rules/.source/hippy/extend_views/IRecyclerItemView.java +12 -0
  12. package/rules/.source/hippy/extend_views/JSEventHandleView.java +5 -0
  13. package/rules/.source/hippy/extend_views/MarqueeRelayManager.java +133 -0
  14. package/rules/.source/hippy/extend_views/MarqueeRelayTextView.java +211 -0
  15. package/rules/.source/hippy/extend_views/ProgressBarView.java +83 -0
  16. package/rules/.source/hippy/extend_views/ProgressBarViewController.java +145 -0
  17. package/rules/.source/hippy/extend_views/SeekBarView.java +104 -0
  18. package/rules/.source/hippy/extend_views/SeekBarViewController.java +218 -0
  19. package/rules/.source/hippy/extend_views/StateImageView.java +149 -0
  20. package/rules/.source/hippy/extend_views/StateImageViewController.java +34 -0
  21. package/rules/.source/hippy/extend_views/TVButtonView.java +314 -0
  22. package/rules/.source/hippy/extend_views/TVButtonViewController.java +89 -0
  23. package/rules/.source/hippy/extend_views/TVTextView.java +684 -0
  24. package/rules/.source/hippy/extend_views/TVViewActor.java +811 -0
  25. package/rules/.source/hippy/extend_views/TVViewActorHost.java +6 -0
  26. package/rules/.source/hippy/extend_views/TVViewActor/346/216/245/345/205/245.md +66 -0
  27. package/rules/.source/hippy/extend_views/TemplateUtil.java +336 -0
  28. package/rules/.source/hippy/extend_views/TextButtonNode.java +47 -0
  29. package/rules/.source/hippy/extend_views/TextViewController.java +377 -0
  30. package/rules/.source/hippy/extend_views/fastlist/CenterFlyInAnimator.java +96 -0
  31. package/rules/.source/hippy/extend_views/fastlist/ChildOnScreenScroller.java +548 -0
  32. package/rules/.source/hippy/extend_views/fastlist/ClonedViewTag.java +17 -0
  33. package/rules/.source/hippy/extend_views/fastlist/EventDeliverer.java +55 -0
  34. package/rules/.source/hippy/extend_views/fastlist/FastAdapter.java +4683 -0
  35. package/rules/.source/hippy/extend_views/fastlist/FastAdapterUtil.java +982 -0
  36. package/rules/.source/hippy/extend_views/fastlist/FastFlexNode.java +48 -0
  37. package/rules/.source/hippy/extend_views/fastlist/FastFlexView.java +873 -0
  38. package/rules/.source/hippy/extend_views/fastlist/FastFlexViewController.java +130 -0
  39. package/rules/.source/hippy/extend_views/fastlist/FastItemNode.java +67 -0
  40. package/rules/.source/hippy/extend_views/fastlist/FastItemView.java +306 -0
  41. package/rules/.source/hippy/extend_views/fastlist/FastItemViewController.java +106 -0
  42. package/rules/.source/hippy/extend_views/fastlist/FastListModule.java +95 -0
  43. package/rules/.source/hippy/extend_views/fastlist/FastListNode.java +90 -0
  44. package/rules/.source/hippy/extend_views/fastlist/FastListView.java +2466 -0
  45. package/rules/.source/hippy/extend_views/fastlist/FastListViewController.java +1038 -0
  46. package/rules/.source/hippy/extend_views/fastlist/FastListView/346/270/262/346/237/223/346/265/201/347/250/213/345/233/276.graffle +0 -0
  47. package/rules/.source/hippy/extend_views/fastlist/FastPendingView.java +47 -0
  48. package/rules/.source/hippy/extend_views/fastlist/ItemDecorations.java +71 -0
  49. package/rules/.source/hippy/extend_views/fastlist/ItemStoreNode.java +64 -0
  50. package/rules/.source/hippy/extend_views/fastlist/ItemStoreView.java +13 -0
  51. package/rules/.source/hippy/extend_views/fastlist/ItemStoreViewController.java +45 -0
  52. package/rules/.source/hippy/extend_views/fastlist/ListItemHolder.java +7 -0
  53. package/rules/.source/hippy/extend_views/fastlist/ListViewControlProp.java +41 -0
  54. package/rules/.source/hippy/extend_views/fastlist/MouseRecycleView.java +509 -0
  55. package/rules/.source/hippy/extend_views/fastlist/OnFastItemClickListener.java +12 -0
  56. package/rules/.source/hippy/extend_views/fastlist/OnFastItemFocusChangeListener.java +9 -0
  57. package/rules/.source/hippy/extend_views/fastlist/OnFastScrollStateChangedListener.java +7 -0
  58. package/rules/.source/hippy/extend_views/fastlist/PendingListNode.java +18 -0
  59. package/rules/.source/hippy/extend_views/fastlist/PendingViewController.java +13 -0
  60. package/rules/.source/hippy/extend_views/fastlist/PostHandlerView.java +6 -0
  61. package/rules/.source/hippy/extend_views/fastlist/PostTaskHolder.java +20 -0
  62. package/rules/.source/hippy/extend_views/fastlist/ReplaceChildController.java +105 -0
  63. package/rules/.source/hippy/extend_views/fastlist/ReplaceChildView.java +312 -0
  64. package/rules/.source/hippy/extend_views/fastlist/TVListView.java +3692 -0
  65. package/rules/.source/hippy/extend_views/fastlist/TemplateCodeParser.java +247 -0
  66. package/rules/.source/hippy/extend_views/fastlist/Utils.java +572 -0
  67. package/rules/.source/hippy/extend_views/fastlist/ViewTag.java +317 -0
  68. package/rules/.source/hippy/extend_views/fastlist/VirtualListView.java +8 -0
  69. package/rules/.source/hippy/extend_views/fastlist/diff/FastListDataBindingHelper.java +320 -0
  70. package/rules/.source/hippy/extend_views/fastlist/diff/KeyDiffHelper.java +289 -0
  71. package/rules/.source/hippy/extend_views/fastlist/diff/NoKeyDiffHelper.java +278 -0
  72. package/rules/.source/hippy/extend_views/tag/FontTag.java +53 -0
  73. package/rules/.source/hippy/extend_views/tag/HtmlTag.java +191 -0
  74. package/rules/.source/hippy/extend_views/tag/HtmlTagHandler.java +185 -0
  75. package/rules/.source/hippy/extend_views/tag/SpanTag.java +160 -0
  76. package/rules/.source/hippy/extend_views/tag/TextFontSpan.java +102 -0
  77. package/rules/.source/hippy/extend_views/waterfall/Chunk.java +10 -0
  78. package/rules/.source/hippy/extend_views/waterfall/ChunkGroup.java +5 -0
  79. package/rules/.source/hippy/extend_views/waterfall/Section.java +4 -0
  80. package/rules/.source/hippy/extend_views/waterfall/Tabs.java +5 -0
  81. package/rules/.source/hippy/extend_views/waterfall/WaterfallUtils.java +26 -0
  82. package/rules/.source/hippy/hippy_uimanager/ControllerHolder.java +30 -0
  83. package/rules/.source/hippy/hippy_uimanager/ControllerManager.java +651 -0
  84. package/rules/.source/hippy/hippy_uimanager/ControllerRegistry.java +102 -0
  85. package/rules/.source/hippy/hippy_uimanager/ControllerUpdateManger.java +252 -0
  86. package/rules/.source/hippy/hippy_uimanager/CustomControllerHelper.java +425 -0
  87. package/rules/.source/hippy/hippy_uimanager/DiffUtils.java +526 -0
  88. package/rules/.source/hippy/hippy_uimanager/ExtendViewGroup.java +36 -0
  89. package/rules/.source/hippy/hippy_uimanager/HippyCustomViewCreator.java +29 -0
  90. package/rules/.source/hippy/hippy_uimanager/HippyGroupController.java +83 -0
  91. package/rules/.source/hippy/hippy_uimanager/HippyViewBase.java +27 -0
  92. package/rules/.source/hippy/hippy_uimanager/HippyViewController.java +2189 -0
  93. package/rules/.source/hippy/hippy_uimanager/HippyViewEvent.java +52 -0
  94. package/rules/.source/hippy/hippy_uimanager/IHippyZIndexViewGroup.java +24 -0
  95. package/rules/.source/hippy/hippy_uimanager/InternalExtendViewUtil.java +395 -0
  96. package/rules/.source/hippy/hippy_uimanager/ListItemRenderNode.java +143 -0
  97. package/rules/.source/hippy/hippy_uimanager/ListViewRenderNode.java +44 -0
  98. package/rules/.source/hippy/hippy_uimanager/MatrixUtil.java +470 -0
  99. package/rules/.source/hippy/hippy_uimanager/NativeGestureDispatcher.java +349 -0
  100. package/rules/.source/hippy/hippy_uimanager/NativeGestureProcessor.java +188 -0
  101. package/rules/.source/hippy/hippy_uimanager/PullFooterRenderNode.java +43 -0
  102. package/rules/.source/hippy/hippy_uimanager/PullHeaderRenderNode.java +43 -0
  103. package/rules/.source/hippy/hippy_uimanager/RenderManager.java +304 -0
  104. package/rules/.source/hippy/hippy_uimanager/RenderNode.java +533 -0
  105. package/rules/.source/hippy/hippy_uimanager/StateView.java +17 -0
  106. package/rules/.source/hippy/hippy_uimanager/TransformUtil.java +125 -0
  107. package/rules/.source/hippy/hippy_uimanager/ViewGroupDrawingOrderHelper.java +108 -0
  108. package/rules/.source/hippy/hippy_uimanager/ViewStateProvider.java +10 -0
  109. package/rules/.source/hippy/hippy_views/audioview/AudioPlayManager.java +457 -0
  110. package/rules/.source/hippy/hippy_views/audioview/AudioView.java +225 -0
  111. package/rules/.source/hippy/hippy_views/audioview/AudioViewController.java +135 -0
  112. package/rules/.source/hippy/hippy_views/common/CommonBackgroundDrawable.java +58 -0
  113. package/rules/.source/hippy/hippy_views/common/CommonBorder.java +37 -0
  114. package/rules/.source/hippy/hippy_views/custom/HippyCustomPropsController.java +61 -0
  115. package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerListAdapter.java +399 -0
  116. package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerView.java +378 -0
  117. package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerViewController.java +187 -0
  118. package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerViewHolder.java +39 -0
  119. package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerViewWrapper.java +134 -0
  120. package/rules/.source/hippy/hippy_views/hippylist/NodePositionHelper.java +55 -0
  121. package/rules/.source/hippy/hippy_views/hippylist/PreloadHelper.java +54 -0
  122. package/rules/.source/hippy/hippy_views/hippylist/PullFooterEventHelper.java +61 -0
  123. package/rules/.source/hippy/hippy_views/hippylist/PullHeaderEventHelper.java +127 -0
  124. package/rules/.source/hippy/hippy_views/hippylist/RecyclerViewEventHelper.java +394 -0
  125. package/rules/.source/hippy/hippy_views/image/HippyContentDrawable.java +113 -0
  126. package/rules/.source/hippy/hippy_views/image/HippyImageView.java +1608 -0
  127. package/rules/.source/hippy/hippy_views/image/HippyImageViewController.java +382 -0
  128. package/rules/.source/hippy/hippy_views/image/IImageStateListener.java +7 -0
  129. package/rules/.source/hippy/hippy_views/list/ChildOnScreenScroller.java +255 -0
  130. package/rules/.source/hippy/hippy_views/list/HippyListAdapter.java +647 -0
  131. package/rules/.source/hippy/hippy_views/list/HippyListItemView.java +162 -0
  132. package/rules/.source/hippy/hippy_views/list/HippyListItemViewController.java +45 -0
  133. package/rules/.source/hippy/hippy_views/list/HippyListView.java +915 -0
  134. package/rules/.source/hippy/hippy_views/list/HippyListViewController.java +622 -0
  135. package/rules/.source/hippy/hippy_views/list/HippyRecycler.java +31 -0
  136. package/rules/.source/hippy/hippy_views/list/IRecycleItemTypeChange.java +23 -0
  137. package/rules/.source/hippy/hippy_views/list/ItemDecorations.java +70 -0
  138. package/rules/.source/hippy/hippy_views/list/NegativeLongKeyFlinger.java +156 -0
  139. package/rules/.source/hippy/hippy_views/list/NodeHolder.java +34 -0
  140. package/rules/.source/hippy/hippy_views/list/RecycleViewFlinger.java +126 -0
  141. package/rules/.source/hippy/hippy_views/list/TVRecyclerView.java +2070 -0
  142. package/rules/.source/hippy/hippy_views/list/TVSingleLineListView.java +15 -0
  143. package/rules/.source/hippy/hippy_views/modal/HippyModalHostManager.java +102 -0
  144. package/rules/.source/hippy/hippy_views/modal/HippyModalHostView.java +597 -0
  145. package/rules/.source/hippy/hippy_views/modal/ModalHostHelper.java +46 -0
  146. package/rules/.source/hippy/hippy_views/modal/ModalStyleNode.java +34 -0
  147. package/rules/.source/hippy/hippy_views/modal/RequestCloseEvent.java +32 -0
  148. package/rules/.source/hippy/hippy_views/modal/ShowEvent.java +31 -0
  149. package/rules/.source/hippy/hippy_views/navigator/Navigator.java +126 -0
  150. package/rules/.source/hippy/hippy_views/navigator/NavigatorController.java +120 -0
  151. package/rules/.source/hippy/hippy_views/refresh/HippyPullFooterView.java +47 -0
  152. package/rules/.source/hippy/hippy_views/refresh/HippyPullFooterViewController.java +65 -0
  153. package/rules/.source/hippy/hippy_views/refresh/HippyPullHeaderView.java +39 -0
  154. package/rules/.source/hippy/hippy_views/refresh/HippyPullHeaderViewController.java +104 -0
  155. package/rules/.source/hippy/hippy_views/refresh/RefreshWrapper.java +237 -0
  156. package/rules/.source/hippy/hippy_views/refresh/RefreshWrapperController.java +62 -0
  157. package/rules/.source/hippy/hippy_views/refresh/RefreshWrapperItemController.java +39 -0
  158. package/rules/.source/hippy/hippy_views/refresh/RefreshWrapperItemView.java +26 -0
  159. package/rules/.source/hippy/hippy_views/scroll/HippyHorizontalScrollView.java +500 -0
  160. package/rules/.source/hippy/hippy_views/scroll/HippyOnScrollHelper.java +39 -0
  161. package/rules/.source/hippy/hippy_views/scroll/HippyScrollView.java +46 -0
  162. package/rules/.source/hippy/hippy_views/scroll/HippyScrollViewController.java +178 -0
  163. package/rules/.source/hippy/hippy_views/scroll/HippyScrollViewEventHelper.java +92 -0
  164. package/rules/.source/hippy/hippy_views/scroll/HippyVerticalScrollView.java +522 -0
  165. package/rules/.source/hippy/hippy_views/text/HippyTextView.java +512 -0
  166. package/rules/.source/hippy/hippy_views/text/HippyTextViewController.java +77 -0
  167. package/rules/.source/hippy/hippy_views/textinput/HippyTextInput.java +668 -0
  168. package/rules/.source/hippy/hippy_views/textinput/HippyTextInputController.java +528 -0
  169. package/rules/.source/hippy/hippy_views/textinput/TextInputNode.java +115 -0
  170. package/rules/.source/hippy/hippy_views/videoview/APEZProvider.java +287 -0
  171. package/rules/.source/hippy/hippy_views/videoview/APKExpansionSupport.java +82 -0
  172. package/rules/.source/hippy/hippy_views/videoview/PivotPoint.java +13 -0
  173. package/rules/.source/hippy/hippy_views/videoview/ScalableType.java +34 -0
  174. package/rules/.source/hippy/hippy_views/videoview/ScalableVideoView.java +265 -0
  175. package/rules/.source/hippy/hippy_views/videoview/ScaleManager.java +191 -0
  176. package/rules/.source/hippy/hippy_views/videoview/Size.java +19 -0
  177. package/rules/.source/hippy/hippy_views/videoview/VideoHippyView.java +917 -0
  178. package/rules/.source/hippy/hippy_views/videoview/VideoHippyViewController.java +236 -0
  179. package/rules/.source/hippy/hippy_views/videoview/ZipResourceFile.java +427 -0
  180. package/rules/.source/hippy/hippy_views/view/CardRootView.java +28 -0
  181. package/rules/.source/hippy/hippy_views/view/CustomLayoutView.java +10 -0
  182. package/rules/.source/hippy/hippy_views/view/CustomNodeView.java +5 -0
  183. package/rules/.source/hippy/hippy_views/view/DialogViewGroup.java +113 -0
  184. package/rules/.source/hippy/hippy_views/view/HippyViewGroup.java +2042 -0
  185. package/rules/.source/hippy/hippy_views/view/HippyViewGroupController.java +583 -0
  186. package/rules/.source/hippy/hippy_views/view/WindowRoot.java +5 -0
  187. package/rules/.source/hippy/hippy_views/viewpager/HippyViewPager.java +308 -0
  188. package/rules/.source/hippy/hippy_views/viewpager/HippyViewPagerAdapter.java +148 -0
  189. package/rules/.source/hippy/hippy_views/viewpager/HippyViewPagerController.java +246 -0
  190. package/rules/.source/hippy/hippy_views/viewpager/HippyViewPagerItem.java +27 -0
  191. package/rules/.source/hippy/hippy_views/viewpager/HippyViewPagerItemController.java +42 -0
  192. package/rules/.source/hippy/hippy_views/viewpager/ViewPagerPageChangeListener.java +114 -0
  193. package/rules/.source/hippy/hippy_views/viewpager/event/HippyPageItemExposureEvent.java +40 -0
  194. package/rules/.source/hippy/hippy_views/viewpager/event/HippyPageScrollEvent.java +43 -0
  195. package/rules/.source/hippy/hippy_views/viewpager/event/HippyPageScrollStateChangedEvent.java +42 -0
  196. package/rules/.source/hippy/hippy_views/viewpager/event/HippyPageSelectedEvent.java +42 -0
  197. package/rules/.source/hippy/hippy_views/webview/HippyWebView.java +160 -0
  198. package/rules/.source/hippy/hippy_views/webview/HippyWebViewBridge.java +20 -0
  199. package/rules/.source/hippy/hippy_views/webview/HippyWebViewController.java +103 -0
  200. package/rules/.source/hippy/hippy_views/webview/HippyWebViewInner.java +77 -0
  201. package/rules/.windsurfrules +27 -4
  202. package/rules/AGENTS.md +27 -4
  203. package/rules/CLAUDE.md +27 -3
  204. package/rules/GEMINI.md +25 -3
@@ -0,0 +1,470 @@
1
+ /* Tencent is pleased to support the open source community by making Hippy available.
2
+ * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ package com.tencent.mtt.hippy.uimanager;
17
+
18
+ public class MatrixUtil {
19
+
20
+ private static final double EPSILON = .00001d;
21
+
22
+ public static class MatrixDecompositionContext {
23
+
24
+ final double[] perspective = new double[4];
25
+ final double[] quaternion = new double[4];
26
+ final double[] scale = new double[3];
27
+ final double[] skew = new double[3];
28
+ final double[] translation = new double[3];
29
+ final double[] rotationDegrees = new double[3];
30
+
31
+ public void reset() {
32
+ perspective[0] = 0;
33
+ perspective[1] = 0;
34
+ perspective[2] = 0;
35
+ perspective[3] = 0;
36
+
37
+ quaternion[0] = 0;
38
+ quaternion[1] = 0;
39
+ quaternion[2] = 0;
40
+ quaternion[3] = 0;
41
+
42
+ scale[0] = 0;
43
+ scale[1] = 0;
44
+ scale[2] = 0;
45
+
46
+ skew[0] = 0;
47
+ skew[1] = 0;
48
+ skew[2] = 0;
49
+
50
+ translation[0] = 0;
51
+ translation[1] = 0;
52
+ translation[2] = 0;
53
+
54
+ rotationDegrees[0] = 0;
55
+ rotationDegrees[1] = 0;
56
+ rotationDegrees[2] = 0;
57
+ }
58
+ }
59
+
60
+ private static boolean isZero(double d) {
61
+ if (Double.isNaN(d)) {
62
+ return false;
63
+ }
64
+ return Math.abs(d) < EPSILON;
65
+ }
66
+
67
+ // 四维矩阵运算:out = matrixA * matrixB
68
+ // 输入:matrixA,长度16的一维数组,代表四维矩阵
69
+ // 输入:matrixB,长度16的一维数组,代表四维矩阵
70
+ public static void multiplyInto(double[] out, double[] matrixA, double[] matrixB) {
71
+ double b00 = matrixB[0], b01 = matrixB[1], b02 = matrixB[2], b03 = matrixB[3],
72
+ b10 = matrixB[4], b11 = matrixB[5], b12 = matrixB[6], b13 = matrixB[7],
73
+ b20 = matrixB[8], b21 = matrixB[9], b22 = matrixB[10], b23 = matrixB[11],
74
+ b30 = matrixB[12], b31 = matrixB[13], b32 = matrixB[14], b33 = matrixB[15];
75
+
76
+ double a0 = matrixA[0], a1 = matrixA[1], a2 = matrixA[2], a3 = matrixA[3];
77
+ out[0] = a0 * b00 + a1 * b10 + a2 * b20 + a3 * b30;
78
+ out[1] = a0 * b01 + a1 * b11 + a2 * b21 + a3 * b31;
79
+ out[2] = a0 * b02 + a1 * b12 + a2 * b22 + a3 * b32;
80
+ out[3] = a0 * b03 + a1 * b13 + a2 * b23 + a3 * b33;
81
+
82
+ a0 = matrixA[4];
83
+ a1 = matrixA[5];
84
+ a2 = matrixA[6];
85
+ a3 = matrixA[7];
86
+ out[4] = a0 * b00 + a1 * b10 + a2 * b20 + a3 * b30;
87
+ out[5] = a0 * b01 + a1 * b11 + a2 * b21 + a3 * b31;
88
+ out[6] = a0 * b02 + a1 * b12 + a2 * b22 + a3 * b32;
89
+ out[7] = a0 * b03 + a1 * b13 + a2 * b23 + a3 * b33;
90
+
91
+ a0 = matrixA[8];
92
+ a1 = matrixA[9];
93
+ a2 = matrixA[10];
94
+ a3 = matrixA[11];
95
+ out[8] = a0 * b00 + a1 * b10 + a2 * b20 + a3 * b30;
96
+ out[9] = a0 * b01 + a1 * b11 + a2 * b21 + a3 * b31;
97
+ out[10] = a0 * b02 + a1 * b12 + a2 * b22 + a3 * b32;
98
+ out[11] = a0 * b03 + a1 * b13 + a2 * b23 + a3 * b33;
99
+
100
+ a0 = matrixA[12];
101
+ a1 = matrixA[13];
102
+ a2 = matrixA[14];
103
+ a3 = matrixA[15];
104
+ out[12] = a0 * b00 + a1 * b10 + a2 * b20 + a3 * b30;
105
+ out[13] = a0 * b01 + a1 * b11 + a2 * b21 + a3 * b31;
106
+ out[14] = a0 * b02 + a1 * b12 + a2 * b22 + a3 * b32;
107
+ out[15] = a0 * b03 + a1 * b13 + a2 * b23 + a3 * b33;
108
+ }
109
+
110
+ /**
111
+ * @param transformMatrix 16-element array of numbers representing 4x4 transform matrix
112
+ */
113
+ public static void decomposeMatrix(double[] transformMatrix, MatrixDecompositionContext ctx) {
114
+ // output values
115
+ final double[] perspective = ctx.perspective;
116
+ final double[] quaternion = ctx.quaternion;
117
+ final double[] scale = ctx.scale;
118
+ final double[] skew = ctx.skew;
119
+ final double[] translation = ctx.translation;
120
+ final double[] rotationDegrees = ctx.rotationDegrees;
121
+
122
+ // create normalized, 2d array matrix
123
+ // and normalized 1d array perspectiveMatrix with redefined 4th column
124
+ if (isZero(transformMatrix[15])) {
125
+ return;
126
+ }
127
+ double[][] matrix = new double[4][4];
128
+ double[] perspectiveMatrix = new double[16];
129
+ for (int i = 0; i < 4; i++) {
130
+ for (int j = 0; j < 4; j++) {
131
+ double value = transformMatrix[(i * 4) + j] / transformMatrix[15];
132
+ matrix[i][j] = value;
133
+ perspectiveMatrix[(i * 4) + j] = j == 3 ? 0 : value;
134
+ }
135
+ }
136
+ perspectiveMatrix[15] = 1;
137
+
138
+ // test for singularity of upper 3x3 part of the perspective matrix
139
+ if (isZero(determinant(perspectiveMatrix))) {
140
+ return;
141
+ }
142
+
143
+ // isolate perspective
144
+ if (!isZero(matrix[0][3]) || !isZero(matrix[1][3]) || !isZero(matrix[2][3])) {
145
+ // rightHandSide is the right hand side of the equation.
146
+ // rightHandSide is a vector, or point in 3d space relative to the origin.
147
+ double[] rightHandSide = {matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]};
148
+
149
+ // Solve the equation by inverting perspectiveMatrix and multiplying
150
+ // rightHandSide by the inverse.
151
+ double[] inversePerspectiveMatrix = inverse(perspectiveMatrix);
152
+ double[] transposedInversePerspectiveMatrix = transpose(inversePerspectiveMatrix);
153
+ multiplyVectorByMatrix(rightHandSide, transposedInversePerspectiveMatrix, perspective);
154
+ } else {
155
+ // no perspective
156
+ perspective[0] = perspective[1] = perspective[2] = 0d;
157
+ perspective[3] = 1d;
158
+ }
159
+
160
+ // translation is simple
161
+ System.arraycopy(matrix[3], 0, translation, 0, 3);
162
+
163
+ // Now get scale and shear.
164
+ // 'row' is a 3 element array of 3 component vectors
165
+ double[][] row = new double[3][3];
166
+ for (int i = 0; i < 3; i++) {
167
+ row[i][0] = matrix[i][0];
168
+ row[i][1] = matrix[i][1];
169
+ row[i][2] = matrix[i][2];
170
+ }
171
+
172
+ // Compute X scale factor and normalize first row.
173
+ scale[0] = v3Length(row[0]);
174
+ row[0] = v3Normalize(row[0], scale[0]);
175
+
176
+ // Compute XY shear factor and make 2nd row orthogonal to 1st.
177
+ skew[0] = v3Dot(row[0], row[1]);
178
+ row[1] = v3Combine(row[1], row[0], 1.0, -skew[0]);
179
+
180
+ // Compute XY shear factor and make 2nd row orthogonal to 1st.
181
+ skew[0] = v3Dot(row[0], row[1]);
182
+ row[1] = v3Combine(row[1], row[0], 1.0, -skew[0]);
183
+
184
+ // Now, compute Y scale and normalize 2nd row.
185
+ scale[1] = v3Length(row[1]);
186
+ row[1] = v3Normalize(row[1], scale[1]);
187
+ skew[0] /= scale[1];
188
+
189
+ // Compute XZ and YZ shears, orthogonalize 3rd row
190
+ skew[1] = v3Dot(row[0], row[2]);
191
+ row[2] = v3Combine(row[2], row[0], 1.0, -skew[1]);
192
+ skew[2] = v3Dot(row[1], row[2]);
193
+ row[2] = v3Combine(row[2], row[1], 1.0, -skew[2]);
194
+
195
+ // Next, get Z scale and normalize 3rd row.
196
+ scale[2] = v3Length(row[2]);
197
+ row[2] = v3Normalize(row[2], scale[2]);
198
+ skew[1] /= scale[2];
199
+ skew[2] /= scale[2];
200
+
201
+ // At this point, the matrix (in rows) is orthonormal.
202
+ // Check for a coordinate system flip. If the determinant
203
+ // is -1, then negate the matrix and the scaling factors.
204
+ double[] pdum3 = v3Cross(row[1], row[2]);
205
+ if (v3Dot(row[0], pdum3) < 0) {
206
+ for (int i = 0; i < 3; i++) {
207
+ scale[i] *= -1;
208
+ row[i][0] *= -1;
209
+ row[i][1] *= -1;
210
+ row[i][2] *= -1;
211
+ }
212
+ }
213
+
214
+ // Now, get the rotations out
215
+ quaternion[0] = 0.5 * Math.sqrt(Math.max(1 + row[0][0] - row[1][1] - row[2][2], 0));
216
+ quaternion[1] = 0.5 * Math.sqrt(Math.max(1 - row[0][0] + row[1][1] - row[2][2], 0));
217
+ quaternion[2] = 0.5 * Math.sqrt(Math.max(1 - row[0][0] - row[1][1] + row[2][2], 0));
218
+ quaternion[3] = 0.5 * Math.sqrt(Math.max(1 + row[0][0] + row[1][1] + row[2][2], 0));
219
+
220
+ if (row[2][1] > row[1][2]) {
221
+ quaternion[0] = -quaternion[0];
222
+ }
223
+ if (row[0][2] > row[2][0]) {
224
+ quaternion[1] = -quaternion[1];
225
+ }
226
+ if (row[1][0] > row[0][1]) {
227
+ quaternion[2] = -quaternion[2];
228
+ }
229
+
230
+ // correct for occasional, weird Euler synonyms for 2d rotation
231
+
232
+ if (quaternion[0] < 0.001 && quaternion[0] >= 0 && quaternion[1] < 0.001
233
+ && quaternion[1] >= 0) {
234
+ // this is a 2d rotation on the z-axis
235
+ rotationDegrees[0] = rotationDegrees[1] = 0d;
236
+ rotationDegrees[2] = roundTo3Places(Math.atan2(row[0][1], row[0][0]) * 180 / Math.PI);
237
+ } else {
238
+ quaternionToDegreesXYZ(quaternion, rotationDegrees);
239
+ }
240
+ }
241
+
242
+ public static double determinant(double[] matrix) {
243
+ double m00 = matrix[0], m01 = matrix[1], m02 = matrix[2], m03 = matrix[3], m10 = matrix[4], m11 = matrix[5], m12 = matrix[6], m13 = matrix[7],
244
+ m20 = matrix[8], m21 = matrix[9], m22 = matrix[10], m23 = matrix[11], m30 = matrix[12], m31 = matrix[13], m32 = matrix[14],
245
+ m33 = matrix[15];
246
+ return (m03 * m12 * m21 * m30 - m02 * m13 * m21 * m30 - m03 * m11 * m22 * m30
247
+ + m01 * m13 * m22 * m30 + m02 * m11 * m23 * m30
248
+ - m01 * m12 * m23 * m30 - m03 * m12 * m20 * m31 + m02 * m13 * m20 * m31
249
+ + m03 * m10 * m22 * m31 - m00 * m13 * m22 * m31
250
+ - m02 * m10 * m23 * m31 + m00 * m12 * m23 * m31 + m03 * m11 * m20 * m32
251
+ - m01 * m13 * m20 * m32 - m03 * m10 * m21 * m32
252
+ + m00 * m13 * m21 * m32 + m01 * m10 * m23 * m32 - m00 * m11 * m23 * m32
253
+ - m02 * m11 * m20 * m33 + m01 * m12 * m20 * m33
254
+ + m02 * m10 * m21 * m33 - m00 * m12 * m21 * m33 - m01 * m10 * m22 * m33
255
+ + m00 * m11 * m22 * m33);
256
+ }
257
+
258
+ /**
259
+ * Inverse of a matrix. Multiplying by the inverse is used in matrix math instead of division.
260
+ * <p>
261
+ * Formula from: http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
262
+ */
263
+ public static double[] inverse(double[] matrix) {
264
+ double det = determinant(matrix);
265
+ if (isZero(det)) {
266
+ return matrix;
267
+ }
268
+ double m00 = matrix[0], m01 = matrix[1], m02 = matrix[2], m03 = matrix[3], m10 = matrix[4], m11 = matrix[5], m12 = matrix[6], m13 = matrix[7],
269
+ m20 = matrix[8], m21 = matrix[9], m22 = matrix[10], m23 = matrix[11], m30 = matrix[12], m31 = matrix[13], m32 = matrix[14],
270
+ m33 = matrix[15];
271
+ return new double[]{
272
+ (m12 * m23 * m31 - m13 * m22 * m31 + m13 * m21 * m32 - m11 * m23 * m32 - m12 * m21 * m33
273
+ + m11 * m22 * m33) / det,
274
+ (m03 * m22 * m31 - m02 * m23 * m31 - m03 * m21 * m32 + m01 * m23 * m32 + m02 * m21 * m33
275
+ - m01 * m22 * m33) / det,
276
+ (m02 * m13 * m31 - m03 * m12 * m31 + m03 * m11 * m32 - m01 * m13 * m32 - m02 * m11 * m33
277
+ + m01 * m12 * m33) / det,
278
+ (m03 * m12 * m21 - m02 * m13 * m21 - m03 * m11 * m22 + m01 * m13 * m22 + m02 * m11 * m23
279
+ - m01 * m12 * m23) / det,
280
+ (m13 * m22 * m30 - m12 * m23 * m30 - m13 * m20 * m32 + m10 * m23 * m32 + m12 * m20 * m33
281
+ - m10 * m22 * m33) / det,
282
+ (m02 * m23 * m30 - m03 * m22 * m30 + m03 * m20 * m32 - m00 * m23 * m32 - m02 * m20 * m33
283
+ + m00 * m22 * m33) / det,
284
+ (m03 * m12 * m30 - m02 * m13 * m30 - m03 * m10 * m32 + m00 * m13 * m32 + m02 * m10 * m33
285
+ - m00 * m12 * m33) / det,
286
+ (m02 * m13 * m20 - m03 * m12 * m20 + m03 * m10 * m22 - m00 * m13 * m22 - m02 * m10 * m23
287
+ + m00 * m12 * m23) / det,
288
+ (m11 * m23 * m30 - m13 * m21 * m30 + m13 * m20 * m31 - m10 * m23 * m31 - m11 * m20 * m33
289
+ + m10 * m21 * m33) / det,
290
+ (m03 * m21 * m30 - m01 * m23 * m30 - m03 * m20 * m31 + m00 * m23 * m31 + m01 * m20 * m33
291
+ - m00 * m21 * m33) / det,
292
+ (m01 * m13 * m30 - m03 * m11 * m30 + m03 * m10 * m31 - m00 * m13 * m31 - m01 * m10 * m33
293
+ + m00 * m11 * m33) / det,
294
+ (m03 * m11 * m20 - m01 * m13 * m20 - m03 * m10 * m21 + m00 * m13 * m21 + m01 * m10 * m23
295
+ - m00 * m11 * m23) / det,
296
+ (m12 * m21 * m30 - m11 * m22 * m30 - m12 * m20 * m31 + m10 * m22 * m31 + m11 * m20 * m32
297
+ - m10 * m21 * m32) / det,
298
+ (m01 * m22 * m30 - m02 * m21 * m30 + m02 * m20 * m31 - m00 * m22 * m31 - m01 * m20 * m32
299
+ + m00 * m21 * m32) / det,
300
+ (m02 * m11 * m30 - m01 * m12 * m30 - m02 * m10 * m31 + m00 * m12 * m31 + m01 * m10 * m32
301
+ - m00 * m11 * m32) / det,
302
+ (m01 * m12 * m20 - m02 * m11 * m20 + m02 * m10 * m21 - m00 * m12 * m21 - m01 * m10 * m22
303
+ + m00 * m11 * m22) / det};
304
+ }
305
+
306
+ /**
307
+ * Turns columns into rows and rows into columns.
308
+ */
309
+ public static double[] transpose(double[] m) {
310
+ return new double[]{m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14],
311
+ m[3], m[7], m[11], m[15]};
312
+ }
313
+
314
+ /**
315
+ * Based on: http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c
316
+ */
317
+ public static void multiplyVectorByMatrix(double[] v, double[] m, double[] result) {
318
+ double vx = v[0], vy = v[1], vz = v[2], vw = v[3];
319
+ result[0] = vx * m[0] + vy * m[4] + vz * m[8] + vw * m[12];
320
+ result[1] = vx * m[1] + vy * m[5] + vz * m[9] + vw * m[13];
321
+ result[2] = vx * m[2] + vy * m[6] + vz * m[10] + vw * m[14];
322
+ result[3] = vx * m[3] + vy * m[7] + vz * m[11] + vw * m[15];
323
+ }
324
+
325
+ /**
326
+ * From: https://code.google.com/p/webgl-mjs/source/browse/mjs.js
327
+ */
328
+ public static double v3Length(double[] a) {
329
+ return Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
330
+ }
331
+
332
+ /**
333
+ * Based on: https://code.google.com/p/webgl-mjs/source/browse/mjs.js
334
+ */
335
+ public static double[] v3Normalize(double[] vector, double norm) {
336
+ double im = 1 / (isZero(norm) ? v3Length(vector) : norm);
337
+ return new double[]{vector[0] * im, vector[1] * im, vector[2] * im};
338
+ }
339
+
340
+ /**
341
+ * The dot product of a and b, two 3-element vectors. From: https://code.google.com/p/webgl-mjs/source/browse/mjs.js
342
+ */
343
+ public static double v3Dot(double[] a, double[] b) {
344
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
345
+ }
346
+
347
+ /**
348
+ * From: http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp
349
+ */
350
+ public static double[] v3Combine(double[] a, double[] b, double aScale, double bScale) {
351
+ return new double[]{aScale * a[0] + bScale * b[0], aScale * a[1] + bScale * b[1],
352
+ aScale * a[2] + bScale * b[2]};
353
+ }
354
+
355
+ /**
356
+ * From: http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp
357
+ */
358
+ public static double[] v3Cross(double[] a, double[] b) {
359
+ return new double[]{a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2],
360
+ a[0] * b[1] - a[1] * b[0]};
361
+ }
362
+
363
+ /**
364
+ * Based on: http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
365
+ * and: http://quat.zachbennett.com/
366
+ * <p>
367
+ * Note that this rounds degrees to the thousandth of a degree, due to floating point errors in
368
+ * the creation of the quaternion.
369
+ * <p>
370
+ * Also note that this expects the qw value to be last, not first.
371
+ * <p>
372
+ * Also, when researching this, remember that: yaw === heading === z-axis pitch ===
373
+ * elevation/attitude === y-axis roll === bank === x-axis
374
+ */
375
+ public static void quaternionToDegreesXYZ(double[] q, double[] result) {
376
+ double qx = q[0], qy = q[1], qz = q[2], qw = q[3];
377
+ double qw2 = qw * qw;
378
+ double qx2 = qx * qx;
379
+ double qy2 = qy * qy;
380
+ double qz2 = qz * qz;
381
+ double test = qx * qy + qz * qw;
382
+ double unit = qw2 + qx2 + qy2 + qz2;
383
+ double conv = 180 / Math.PI;
384
+
385
+ if (test > 0.49999 * unit) {
386
+ result[0] = 0;
387
+ result[1] = 2 * Math.atan2(qx, qw) * conv;
388
+ result[2] = 90;
389
+ return;
390
+ }
391
+ if (test < -0.49999 * unit) {
392
+ result[0] = 0;
393
+ result[1] = -2 * Math.atan2(qx, qw) * conv;
394
+ result[2] = -90;
395
+ return;
396
+ }
397
+
398
+ result[0] = roundTo3Places(Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx2 - 2 * qz2) * conv);
399
+ result[1] = roundTo3Places(Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy2 - 2 * qz2) * conv);
400
+ result[2] = roundTo3Places(Math.asin(2 * qx * qy + 2 * qz * qw) * conv);
401
+ }
402
+
403
+ public static double roundTo3Places(double n) {
404
+ return Math.round(n * 1000d) * 0.001;
405
+ }
406
+
407
+ public static double degreesToRadians(double degrees) {
408
+ return degrees * Math.PI / 180;
409
+ }
410
+
411
+ public static void resetIdentityMatrix(double[] matrix) {
412
+ matrix[1] = matrix[2] = matrix[3] = matrix[4] = matrix[6] = matrix[7] = matrix[8] = matrix[9] = matrix[11] = matrix[12] = matrix[13] = matrix[14] = 0;
413
+ matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1;
414
+ }
415
+
416
+ public static void applyPerspective(double[] m, double perspective) {
417
+ m[11] = -1 / perspective;
418
+ }
419
+
420
+ public static void applyScaleX(double[] m, double factor) {
421
+ m[0] = factor;
422
+ }
423
+
424
+ public static void applyScaleY(double[] m, double factor) {
425
+ m[5] = factor;
426
+ }
427
+
428
+ public static void applyTranslate2D(double[] m, double x, double y) {
429
+ m[12] = x;
430
+ m[13] = y;
431
+ }
432
+
433
+ public static void applyTranslate3D(double[] m, double x, double y, double z) {
434
+ m[12] = x;
435
+ m[13] = y;
436
+ m[14] = z;
437
+ }
438
+
439
+ public static void applySkewX(double[] m, double radians) {
440
+ m[4] = Math.sin(radians);
441
+ m[5] = Math.cos(radians);
442
+ }
443
+
444
+ public static void applySkewY(double[] m, double radians) {
445
+ m[0] = Math.cos(radians);
446
+ m[1] = Math.sin(radians);
447
+ }
448
+
449
+ public static void applyRotateX(double[] m, double radians) {
450
+ m[5] = Math.cos(radians);
451
+ m[6] = Math.sin(radians);
452
+ m[9] = -Math.sin(radians);
453
+ m[10] = Math.cos(radians);
454
+ }
455
+
456
+ public static void applyRotateY(double[] m, double radians) {
457
+ m[0] = Math.cos(radians);
458
+ m[2] = -Math.sin(radians);
459
+ m[8] = Math.sin(radians);
460
+ m[10] = Math.cos(radians);
461
+ }
462
+
463
+ // http://www.w3.org/TR/css3-transforms/#recomposing-to-a-2d-matrix
464
+ public static void applyRotateZ(double[] m, double radians) {
465
+ m[0] = Math.cos(radians);
466
+ m[1] = Math.sin(radians);
467
+ m[4] = -Math.sin(radians);
468
+ m[5] = Math.cos(radians);
469
+ }
470
+ }