hkKdTreeMath.inl
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:10k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* 
  2.  * 
  3.  * Confidential Information of Telekinesys Research Limited (t/a Havok). Not for disclosure or distribution without Havok's
  4.  * prior written consent. This software contains code, techniques and know-how which is confidential and proprietary to Havok.
  5.  * Level 2 and Level 3 source code contains trade secrets of Havok. Havok Software (C) Copyright 1999-2009 Telekinesys Research Limited t/a Havok. All Rights Reserved. Use of this software is subject to the terms of an end user license agreement.
  6.  * 
  7.  */
  8. inline hkBool32 hkKdTreeMath::isComponentEqZero(hkVector4Parameter v, int component)
  9. {
  10. hkVector4 zero; zero.setZero4();
  11. hkVector4Comparison compMask = v.compareEqual4(zero);
  12. return compMask.allAreSet(hkVector4Comparison::s_components[component]);
  13. }
  14. inline hkBool32 hkKdTreeMath::isComponentGtZero(hkVector4Parameter v, int component)
  15. {
  16. hkVector4 zero; zero.setZero4();
  17. hkVector4Comparison compMask = v.compareGreaterThan4(zero);
  18. return compMask.allAreSet(hkVector4Comparison::s_components[component]);
  19. }
  20. // sets v to its minimum component
  21. inline void hkKdTreeMath::vectorBroadcastMin3(hkVector4& v)
  22. {
  23. hkVector4 temp0, temp1, temp2, temp;
  24. temp0.setBroadcast(v, 0);
  25. temp1.setBroadcast(v, 1);
  26. temp.setMin4(temp0, temp1);
  27. temp2.setBroadcast(v, 2);
  28. v.setMin4(temp, temp2);
  29. }
  30. inline void hkKdTreeMath::vectorBroadcastMin3(hkVector4& v, hkVector4ComparisonParameter ignoreMask)
  31. {
  32. hkQuadReal allMax = HK_QUADREAL_CONSTANT(HK_REAL_MAX, HK_REAL_MAX, HK_REAL_MAX, HK_REAL_MAX);
  33. HK_ASSERT(0x2dc51fe7, !ignoreMask.allAreSet(hkVector4Comparison::MASK_XYZ)); // trying to ignore all 3 components
  34. hkVector4 temp0, temp1, temp2, temp;
  35. hkVector4 allMaxV; allMaxV.getQuad() = allMax;
  36. v.select32(v, allMaxV, ignoreMask); 
  37. temp0.setBroadcast(v, 0);
  38. temp1.setBroadcast(v, 1);
  39. temp.setMin4(temp0, temp1);
  40. temp2.setBroadcast(v, 2);
  41. v.setMin4(temp, temp2);
  42. }
  43. // sets v to its maximum component
  44. inline void hkKdTreeMath::vectorBroadcastMax3(hkVector4& v)
  45. {
  46. hkVector4 temp0, temp1, temp2, temp;
  47. temp0.setBroadcast(v, 0);
  48. temp1.setBroadcast(v, 1);
  49. temp.setMax4(temp0, temp1);
  50. temp2.setBroadcast(v, 2);
  51. v.setMax4(temp, temp2);
  52. }
  53. inline void hkKdTreeMath::vectorBroadcastMax3(hkVector4& v, hkVector4ComparisonParameter ignoreMask)
  54. {
  55. hkQuadReal allMin = HK_QUADREAL_CONSTANT(-HK_REAL_MAX, -HK_REAL_MAX, -HK_REAL_MAX, -HK_REAL_MAX);
  56. HK_ASSERT(0x2dc51fe7, !ignoreMask.allAreSet(hkVector4Comparison::MASK_XYZ)); // trying to ignore all 3 components
  57. hkVector4 temp0, temp1, temp2, temp;
  58. hkVector4 allMinV; allMinV.getQuad() = allMin;
  59. v.select32(v, allMinV, ignoreMask); 
  60. temp0.setBroadcast(v, 0);
  61. temp1.setBroadcast(v, 1);
  62. temp.setMax4(temp0, temp1);
  63. temp2.setBroadcast(v, 2);
  64. v.setMax4(temp, temp2);
  65. }
  66. inline hkBool hkKdTreeMath::rayAabbCheckSlow(hkVector4Parameter orig, hkVector4Parameter invDir, hkReal tNear, hkReal tFar, const hkAabb& aabb)
  67. {
  68. for (int i=0; i<3; i++)
  69. {
  70. if (invDir(i) == 0.0f) // Ray is flat in this direction; can't exclude
  71. {
  72. // check that origin is within the bounds of the other planes
  73. if (orig(i) > aabb.m_max(i) || orig(i) < aabb.m_min(i))
  74. {
  75. return false;
  76. }
  77. continue;
  78. }
  79. hkReal splitMin = aabb.m_min(i);
  80. hkReal splitMax = aabb.m_max(i);
  81. hkReal dNear = ( splitMin - orig( i ) ) * invDir( i );
  82. hkReal dFar  = ( splitMax - orig( i ) ) * invDir( i );
  83. if (invDir(i) < 0.0f)
  84. {
  85. hkReal temp = dFar;
  86. dFar = dNear;
  87. dNear = temp;
  88. }
  89. tNear = hkMath::max2(dNear, tNear);
  90. tFar =  hkMath::min2(dFar, tFar);
  91. }
  92. return (tNear < tFar);
  93. }
  94. inline hkBool32 hkKdTreeMath::rayAabbCheck(hkVector4Parameter orig, hkVector4Parameter invDir, hkReal _tNear, hkReal _tFar, const hkAabb& aabb)
  95. {
  96. hkVector4 dNearTemp;
  97. dNearTemp = aabb.m_min;
  98. hkVector4 dFarTemp;
  99. dFarTemp = aabb.m_max;
  100. dNearTemp.sub4(orig);
  101. dFarTemp.sub4( orig);
  102. dNearTemp.mul4(invDir);
  103. dFarTemp.mul4( invDir);
  104. hkVector4 zero; zero.setZero4();
  105. hkVector4Comparison invDirLtZero = invDir.compareGreaterThanEqual4(zero);
  106. hkVector4 dNear, dFar;
  107. dNear.select32(dFarTemp, dNearTemp, invDirLtZero);
  108. dFar.select32( dNearTemp, dFarTemp, invDirLtZero);
  109. hkVector4 tNear, tFar;
  110. tNear.setAll(_tNear);
  111. tFar.setAll( _tFar );
  112. hkVector4Comparison invDirEqZero;
  113. invDirEqZero = invDir.compareEqual4(zero);
  114. hkVector4Comparison origInAabb = orig.compareGreaterThanEqual4(aabb.m_min);
  115. origInAabb.setAnd(origInAabb, orig.compareLessThanEqual4(aabb.m_max));
  116. vectorBroadcastMax3(dNear, invDirEqZero);
  117. vectorBroadcastMin3(dFar,  invDirEqZero);
  118. tNear.setMax4(tNear, dNear);
  119. tFar.setMin4(tFar, dFar);
  120. hkVector4Comparison nearLtFar = tNear.compareLessThan4(tFar);
  121. hkVector4Comparison isOk; isOk.setSelect(nearLtFar, origInAabb, invDirEqZero);
  122. //return nearLtFar.allAreSet();
  123. return isOk.allAreSet(hkVector4Comparison::MASK_XYZ);
  124. }
  125. inline hkVector4Comparison hkKdTreeMath::rayBundleAabbCheck(const struct hkKdTreeUtils::RayBundle& orig, const struct hkKdTreeUtils::RayBundle& invDir, hkVector4Parameter _tNear, hkVector4Parameter _tFar, const hkVector4* aabbData)
  126. {
  127. hkVector4 tNear = _tNear;
  128. hkVector4 tFar = _tFar;
  129. hkVector4Comparison flatOrigOK; flatOrigOK.set(hkVector4Comparison::MASK_XYZW);
  130. for (int i=0; i<3; i++)
  131. {
  132. hkVector4 aabbMin, aabbMax;
  133. aabbMin = *aabbData++;
  134. aabbMax = *aabbData++;
  135. hkVector4 dNear, dFar, dNearTemp, dFarTemp;
  136. dNearTemp.setSub4(aabbMin, orig.m_vec[i]);
  137. dFarTemp.setSub4( aabbMax, orig.m_vec[i]);
  138. dNearTemp.mul4(invDir.m_vec[i]);
  139. dFarTemp.mul4( invDir.m_vec[i]);
  140. hkVector4 zero; zero.setZero4();
  141. hkVector4Comparison dirLtZero = invDir.m_vec[ i ].compareGreaterThanEqual4(zero);
  142. hkVector4Comparison dirEqZero = invDir.m_vec[ i ].compareEqual4(zero);
  143. // Check that the origins in flat directions (dir=0) are within the AABB in that direction
  144. // OK = OK && ( (!flat) || (flat && inRange) )
  145. //    = OK && select(true, inRange, flat)
  146. //    = OK && select(OK, inRange, flat)
  147. hkVector4Comparison inRange;
  148. inRange = orig.m_vec[i].compareLessThanEqual4(aabbMax);
  149. inRange.setAnd(inRange, orig.m_vec[i].compareGreaterThanEqual4(aabbMin) );
  150. hkVector4Comparison thisComponentIsOk; thisComponentIsOk.setSelect(flatOrigOK, inRange, dirEqZero);
  151. flatOrigOK.setAnd(flatOrigOK, thisComponentIsOk);
  152. dNear.select32(dFarTemp, dNearTemp, dirLtZero);
  153. dFar.select32( dNearTemp, dFarTemp, dirLtZero);
  154. // If the ray is flat in this direction, effectively skip the direction
  155. dNear.select32(dNear, tNear, dirEqZero);
  156. dFar.select32( dFar, tFar, dirEqZero);
  157. tNear.setMax4(dNear, tNear);
  158. tFar.setMin4(dFar, tFar);
  159. }
  160. //return tNear.compareLessThan4(tFar);
  161. // The ray hits if tNear<tFar and the origins are within the proper ranges
  162. hkVector4Comparison tOk = tNear.compareLessThan4(tFar);
  163. tOk.setAnd(tOk, flatOrigOK);
  164. return tOk;
  165. }
  166. //static const hkQuadReal oneOver65K = HK_QUADREAL_CONSTANT(1.0f/65535.0f, 1.0f/65535.0f, 1.0f/65535.0f, 1.0f/65535.0f);
  167. #ifndef HK_PLATFORM_PS3_SPU
  168. static HK_FORCE_INLINE hkQuadReal hkGetOneOver65K()
  169. {
  170. static hkQuadReal x = HK_QUADREAL_CONSTANT(1.0f / 65535.0f, 1.0f / 65535.0f, 1.0f / 65535.0f, 1.0f / 65535.0f);
  171. return x;
  172. }
  173. #else
  174. static HK_FORCE_INLINE hkQuadReal hkGetOneOver65K()
  175. {
  176. // 0x37800080
  177. vector signed char upper = si_ilhu(0x3780);
  178. return (hkQuadReal) si_iohl(upper, 0x0080);
  179. }
  180. #endif
  181. void inline hkKdTreeMath::getAabbFromProjectedEntry(const hkKdTreeBuildInput::ProjectedEntry* aabbData, hkAabb& aabb, hkVector4Parameter offset, hkVector4Parameter _scale)
  182. {
  183. hkVector4 scale; scale.getQuad() = hkGetOneOver65K();
  184. scale.mul4(_scale); 
  185. hkVector4 min, max;
  186. convertProjectedEntryToHkVector4(aabbData, min, max);
  187. aabb.m_min.setAddMul4(offset, scale, min); // offset + (scale*min)
  188. aabb.m_max.setAddMul4(offset, scale, max);
  189. // isEmpty means that max < min, which happens when the primitive is invalidated
  190. HK_ASSERT(0x781378a0, aabb.isValid() || aabb.isEmpty() );
  191. }
  192. // Vectors are output in the order minX, maxX, minY, maxY, minZ, maxZ
  193. void inline hkKdTreeMath::getAabbVecsFromProjectedEntry(const hkKdTreeBuildInput::ProjectedEntry* aabbData, hkVector4* HK_RESTRICT vecsOut, hkVector4Parameter offset, hkVector4Parameter scaleIn)
  194. {
  195. hkVector4 scale; scale.getQuad() = hkGetOneOver65K();
  196. scale.mul4(scaleIn);
  197. hkVector4 min, max;
  198. convertProjectedEntryToHkVector4(aabbData, min, max);
  199. min.setAddMul4(offset, scale, min); // offset + (scale*min)
  200. max.setAddMul4(offset, scale, max);
  201. vecsOut[0].setBroadcast(min, 0);
  202. vecsOut[1].setBroadcast(max, 0);
  203. vecsOut[2].setBroadcast(min, 1);
  204. vecsOut[3].setBroadcast(max, 1);
  205. vecsOut[4].setBroadcast(min, 2);
  206. vecsOut[5].setBroadcast(max, 2);
  207. }
  208. inline void hkKdTreeMath::convertProjectedEntryToHkVector4(const hkKdTreeBuildInput::ProjectedEntry* splits, hkVector4& v1, hkVector4& v2)
  209. {
  210. #if (HK_CONFIG_SIMD == HK_CONFIG_SIMD_ENABLED) && (HK_POINTER_SIZE == 4)
  211. // The compressed AABBs are always 16-byte aligned
  212. HK_ASSERT( 0x0, ((hkUlong)splits & 0xf) == 0);
  213. hkIntVector b = *(hkIntVector*)splits; // b = xxyy zz00 XXYY ZZ00
  214. hkIntVector zero; zero.setZero();
  215. hkIntVector minUint, maxUint;
  216. if(HK_ENDIAN_BIG) 
  217. {
  218. minUint.setMergeHigh16(zero, b); // minUint = 00xx 00yy 00zz 0000
  219. maxUint.setMergeLow16(zero, b);  // maxUint = 00XX 00YY 00ZZ 0000
  220. }
  221. else
  222. {
  223. minUint.setMergeHigh16(b, zero); 
  224. maxUint.setMergeLow16(b, zero); 
  225. }
  226. minUint.convertToF32fromU32(v1);
  227. maxUint.convertToF32fromU32(v2);
  228. #else
  229. v1.set(hkReal(splits->m_min[0]), hkReal(splits->m_min[1]), hkReal(splits->m_min[2]), 0.0f);
  230. v2.set(hkReal(splits->m_max[0]), hkReal(splits->m_max[1]), hkReal(splits->m_max[2]), 0.0f);
  231. #endif
  232. }
  233. // Leave an extra line at the EOF
  234. /*
  235. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  236. * Confidential Information of Havok.  (C) Copyright 1999-2009
  237. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  238. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  239. * rights, and intellectual property rights in the Havok software remain in
  240. * Havok and/or its suppliers.
  241. * Use of this software for evaluation purposes is subject to and indicates
  242. * acceptance of the End User licence Agreement for this product. A copy of
  243. * the license is included with this software and is also available at www.havok.com/tryhavok.
  244. */