MathUtil.cpp 7.5 KB

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