MathUtil.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /**
  2. Copyright 2013 BlackBerry Inc.
  3. Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
  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. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. Original file from GamePlay3D: http://gameplay3d.org
  14. This file was modified to fit the cocos2d-x project
  15. */
  16. #include "math/MathUtil.h"
  17. #include "base/ccMacros.h"
  18. #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
  19. #include <cpu-features.h>
  20. #endif
  21. //#define USE_NEON32 : neon 32 code will be used
  22. //#define USE_NEON64 : neon 64 code will be used
  23. //#define INCLUDE_NEON32 : neon 32 code included
  24. //#define INCLUDE_NEON64 : neon 64 code included
  25. //#define USE_SSE : SSE code used
  26. //#define INCLUDE_SSE : SSE code included
  27. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
  28. #if defined (__arm64__)
  29. #define USE_NEON64
  30. #define INCLUDE_NEON64
  31. #elif defined (__ARM_NEON__)
  32. #define USE_NEON32
  33. #define INCLUDE_NEON32
  34. #else
  35. #endif
  36. #elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
  37. #if defined (__arm64__) || defined (__aarch64__)
  38. #define USE_NEON64
  39. #define INCLUDE_NEON64
  40. #elif defined (__ARM_NEON__)
  41. #define INCLUDE_NEON32
  42. #else
  43. #endif
  44. #else
  45. #endif
  46. #if defined (__SSE__)
  47. #define USE_SSE
  48. #define INCLUDE_SSE
  49. #endif
  50. #ifdef INCLUDE_NEON32
  51. #include "math/MathUtilNeon.inl"
  52. #endif
  53. #ifdef INCLUDE_NEON64
  54. #include "math/MathUtilNeon64.inl"
  55. #endif
  56. #ifdef INCLUDE_SSE
  57. #include "math/MathUtilSSE.inl"
  58. #endif
  59. #include "math/MathUtil.inl"
  60. NS_CC_MATH_BEGIN
  61. void MathUtil::smooth(float* x, float target, float elapsedTime, float responseTime)
  62. {
  63. GP_ASSERT(x);
  64. if (elapsedTime > 0)
  65. {
  66. *x += (target - *x) * elapsedTime / (elapsedTime + responseTime);
  67. }
  68. }
  69. void MathUtil::smooth(float* x, float target, float elapsedTime, float riseTime, float fallTime)
  70. {
  71. GP_ASSERT(x);
  72. if (elapsedTime > 0)
  73. {
  74. float delta = target - *x;
  75. *x += delta * elapsedTime / (elapsedTime + (delta > 0 ? riseTime : fallTime));
  76. }
  77. }
  78. float MathUtil::lerp(float from, float to, float alpha)
  79. {
  80. return from * (1.0f - alpha) + to * alpha;
  81. }
  82. bool MathUtil::isNeon32Enabled()
  83. {
  84. #ifdef USE_NEON32
  85. return true;
  86. #elif (defined (INCLUDE_NEON32) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) )
  87. class AnrdoidNeonChecker
  88. {
  89. public:
  90. AnrdoidNeonChecker()
  91. {
  92. if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM && (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0)
  93. _isNeonEnabled = true;
  94. else
  95. _isNeonEnabled = false;
  96. }
  97. bool isNeonEnabled() const { return _isNeonEnabled; }
  98. private:
  99. bool _isNeonEnabled;
  100. };
  101. static AnrdoidNeonChecker checker;
  102. return checker.isNeonEnabled();
  103. #else
  104. return false;
  105. #endif
  106. }
  107. bool MathUtil::isNeon64Enabled()
  108. {
  109. #ifdef USE_NEON64
  110. return true;
  111. #else
  112. return false;
  113. #endif
  114. }
  115. void MathUtil::addMatrix(const float* m, float scalar, float* dst)
  116. {
  117. #ifdef USE_NEON32
  118. MathUtilNeon::addMatrix(m, scalar, dst);
  119. #elif defined (USE_NEON64)
  120. MathUtilNeon64::addMatrix(m, scalar, dst);
  121. #elif defined (INCLUDE_NEON32)
  122. if(isNeon32Enabled()) MathUtilNeon::addMatrix(m, scalar, dst);
  123. else MathUtilC::addMatrix(m, scalar, dst);
  124. #else
  125. MathUtilC::addMatrix(m, scalar, dst);
  126. #endif
  127. }
  128. void MathUtil::addMatrix(const float* m1, const float* m2, float* dst)
  129. {
  130. #ifdef USE_NEON32
  131. MathUtilNeon::addMatrix(m1, m2, dst);
  132. #elif defined (USE_NEON64)
  133. MathUtilNeon64::addMatrix(m1, m2, dst);
  134. #elif defined (INCLUDE_NEON32)
  135. if(isNeon32Enabled()) MathUtilNeon::addMatrix(m1, m2, dst);
  136. else MathUtilC::addMatrix(m1, m2, dst);
  137. #else
  138. MathUtilC::addMatrix(m1, m2, dst);
  139. #endif
  140. }
  141. void MathUtil::subtractMatrix(const float* m1, const float* m2, float* dst)
  142. {
  143. #ifdef USE_NEON32
  144. MathUtilNeon::subtractMatrix(m1, m2, dst);
  145. #elif defined (USE_NEON64)
  146. MathUtilNeon64::subtractMatrix(m1, m2, dst);
  147. #elif defined (INCLUDE_NEON32)
  148. if(isNeon32Enabled()) MathUtilNeon::subtractMatrix(m1, m2, dst);
  149. else MathUtilC::subtractMatrix(m1, m2, dst);
  150. #else
  151. MathUtilC::subtractMatrix(m1, m2, dst);
  152. #endif
  153. }
  154. void MathUtil::multiplyMatrix(const float* m, float scalar, float* dst)
  155. {
  156. #ifdef USE_NEON32
  157. MathUtilNeon::multiplyMatrix(m, scalar, dst);
  158. #elif defined (USE_NEON64)
  159. MathUtilNeon64::multiplyMatrix(m, scalar, dst);
  160. #elif defined (INCLUDE_NEON32)
  161. if(isNeon32Enabled()) MathUtilNeon::multiplyMatrix(m, scalar, dst);
  162. else MathUtilC::multiplyMatrix(m, scalar, dst);
  163. #else
  164. MathUtilC::multiplyMatrix(m, scalar, dst);
  165. #endif
  166. }
  167. void MathUtil::multiplyMatrix(const float* m1, const float* m2, float* dst)
  168. {
  169. #ifdef USE_NEON32
  170. MathUtilNeon::multiplyMatrix(m1, m2, dst);
  171. #elif defined (USE_NEON64)
  172. MathUtilNeon64::multiplyMatrix(m1, m2, dst);
  173. #elif defined (INCLUDE_NEON32)
  174. if(isNeon32Enabled()) MathUtilNeon::multiplyMatrix(m1, m2, dst);
  175. else MathUtilC::multiplyMatrix(m1, m2, dst);
  176. #else
  177. MathUtilC::multiplyMatrix(m1, m2, dst);
  178. #endif
  179. }
  180. void MathUtil::negateMatrix(const float* m, float* dst)
  181. {
  182. #ifdef USE_NEON32
  183. MathUtilNeon::negateMatrix(m, dst);
  184. #elif defined (USE_NEON64)
  185. MathUtilNeon64::negateMatrix(m, dst);
  186. #elif defined (INCLUDE_NEON32)
  187. if(isNeon32Enabled()) MathUtilNeon::negateMatrix(m, dst);
  188. else MathUtilC::negateMatrix(m, dst);
  189. #else
  190. MathUtilC::negateMatrix(m, dst);
  191. #endif
  192. }
  193. void MathUtil::transposeMatrix(const float* m, float* dst)
  194. {
  195. #ifdef USE_NEON32
  196. MathUtilNeon::transposeMatrix(m, dst);
  197. #elif defined (USE_NEON64)
  198. MathUtilNeon64::transposeMatrix(m, dst);
  199. #elif defined (INCLUDE_NEON32)
  200. if(isNeon32Enabled()) MathUtilNeon::transposeMatrix(m, dst);
  201. else MathUtilC::transposeMatrix(m, dst);
  202. #else
  203. MathUtilC::transposeMatrix(m, dst);
  204. #endif
  205. }
  206. void MathUtil::transformVec4(const float* m, float x, float y, float z, float w, float* dst)
  207. {
  208. #ifdef USE_NEON32
  209. MathUtilNeon::transformVec4(m, x, y, z, w, dst);
  210. #elif defined (USE_NEON64)
  211. MathUtilNeon64::transformVec4(m, x, y, z, w, dst);
  212. #elif defined (INCLUDE_NEON32)
  213. if(isNeon32Enabled()) MathUtilNeon::transformVec4(m, x, y, z, w, dst);
  214. else MathUtilC::transformVec4(m, x, y, z, w, dst);
  215. #else
  216. MathUtilC::transformVec4(m, x, y, z, w, dst);
  217. #endif
  218. }
  219. void MathUtil::transformVec4(const float* m, const float* v, float* dst)
  220. {
  221. #ifdef USE_NEON32
  222. MathUtilNeon::transformVec4(m, v, dst);
  223. #elif defined (USE_NEON64)
  224. MathUtilNeon64::transformVec4(m, v, dst);
  225. #elif defined (INCLUDE_NEON32)
  226. if(isNeon32Enabled()) MathUtilNeon::transformVec4(m, v, dst);
  227. else MathUtilC::transformVec4(m, v, dst);
  228. #else
  229. MathUtilC::transformVec4(m, v, dst);
  230. #endif
  231. }
  232. void MathUtil::crossVec3(const float* v1, const float* v2, float* dst)
  233. {
  234. #ifdef USE_NEON32
  235. MathUtilNeon::crossVec3(v1, v2, dst);
  236. #elif defined (USE_NEON64)
  237. MathUtilNeon64::crossVec3(v1, v2, dst);
  238. #elif defined (INCLUDE_NEON32)
  239. if(isNeon32Enabled()) MathUtilNeon::crossVec3(v1, v2, dst);
  240. else MathUtilC::crossVec3(v1, v2, dst);
  241. #else
  242. MathUtilC::crossVec3(v1, v2, dst);
  243. #endif
  244. }
  245. NS_CC_MATH_END