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

其他游戏

开发平台:

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. hkpRayCastQueryJob::hkpRayCastQueryJob( JobSubType subType,  hkUint16 size )
  9. : hkJob( HK_JOB_TYPE_RAYCAST_QUERY, subType, size, HK_JOB_SPU_TYPE_DISABLED ),
  10. m_semaphore(HK_NULL), m_jobDoneFlag(HK_NULL)
  11. {
  12. m_jobSpuType = HK_JOB_SPU_TYPE_ENABLED; // all kd tree jobs run on the SPU
  13. m_sharedJobHeaderOnPpu = HK_NULL;
  14. }
  15. inline void hkpRayCastQueryJob::atomicIncrementAndReleaseSemaphore() const
  16. {
  17. if (m_jobDoneFlag)
  18. {
  19. hkCriticalSection::atomicExchangeAdd(m_jobDoneFlag, 1);
  20. }
  21. if (m_semaphore)
  22. {
  23. hkSemaphoreBusyWait::release(m_semaphore);
  24. }
  25. }
  26. // ===============================================================================================================================================================================================
  27. //  SHAPE RAYCAST
  28. // ===============================================================================================================================================================================================
  29. hkpShapeRayCastJob::hkpShapeRayCastJob( const hkpProcessCollisionInput* input, hkpCollisionQueryJobHeader* jobHeader, const hkpShapeRayCastCommand* commandArray, int numCommands, hkSemaphoreBusyWait* semaphore, int numCommandsPerTask) 
  30. : hkpRayCastQueryJob(RAYCAST_QUERY_SHAPE_RAYCAST, sizeof(hkpShapeRayCastJob))
  31. {
  32. HK_ASSERT2( 0xaf236153, jobHeader, "jobHeader has to be set." );
  33. HK_ASSERT2( 0xaf3647f2, numCommands > 0, "numCommands has to be > 0." );
  34. HK_ASSERT2( 0xaf3647e3, commandArray, "commandArray has to be set." );
  35. HK_ASSERT2( 0xaf236158, ((hkUlong)jobHeader & 0xf) == 0, "jobHeader has to be 16 byte aligned." );
  36. HK_ASSERT2( 0xaf3647e9, ((hkUlong)commandArray & 0xf) == 0, "commandArray has to be 16 byte aligned." );
  37. HK_ASSERT2( 0xaf3647ff, numCommandsPerTask > 0 && numCommandsPerTask <= MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK, "numCommandsPerTask has to be > 0 and <= " << MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK << "." );
  38. #if defined(HK_DEBUG)
  39. {
  40. for (int i=0; i<numCommands; i++)
  41. {
  42. const hkpShapeRayCastCommand* command = &commandArray[i];
  43. HK_ASSERT2( 0xaf3647e4, command->m_collidables, "command[ " << i << " ]->m_collidables has to be set." );
  44. HK_ASSERT2( 0xaf3647e5, command->m_results, "command[ " << i << " ]->m_results has to be set." );
  45. HK_ASSERT2( 0xaf3647e6, ((hkUlong)command->m_collidables & 0xf) == 0, "command[ " << i << " ]->m_collidables (address 0x" << command->m_collidables << " has to be 16 byte aligned." );
  46. HK_ASSERT2( 0xaf3647e7, ((hkUlong)command->m_results     & 0xf) == 0, "command[ " << i << " ]->m_results (address 0x" << command->m_results << " has to be 16 byte aligned." );
  47. HK_ASSERT2( 0xaf3648e0, command->m_numCollidables > 0 && command->m_numCollidables <= hkpShapeRayCastCommand::MAXIMUM_NUM_COLLIDABLES, "hkpShapeRayCastCommand::m_numCollidables has to be > 0 and <= " << hkpShapeRayCastCommand::MAXIMUM_NUM_COLLIDABLES << "." );
  48. HK_ASSERT2( 0xaf3648e2, command->m_resultsCapacity > 0 && command->m_resultsCapacity <= hkpShapeRayCastCommand::MAXIMUM_RESULTS_CAPACITY, "hkpShapeRayCastCommand::m_resultsCapacity has to be > 0 and <= " << hkpShapeRayCastCommand::MAXIMUM_RESULTS_CAPACITY << "." );
  49. }
  50. }
  51. // This is a very simple and crude attempt to try to catch a common mistake where the user might
  52. // forget to actually advance the pointer to the results. Doing so could cause incorrect query results.
  53. // This check though will NOT catch trickier situations like e.g. partially overlapping results.
  54. if ( numCommands > 1 )
  55. {
  56. HK_ASSERT2(0xaf253411, commandArray[0].m_results != commandArray[1].m_results, "You are not allowed to re-use the same results buffer for two different query commands.");
  57. }
  58. #endif
  59. m_collisionInput = input;
  60. m_sharedJobHeaderOnPpu = jobHeader;
  61. m_numCommandsPerTask = numCommandsPerTask;
  62. m_semaphore = semaphore;
  63. m_commandArray = commandArray;
  64. m_numCommands = numCommands;
  65. // precalculate the total number of jobs that will be spawned from the original job (incl. the original)
  66. m_sharedJobHeaderOnPpu->m_openJobs = ((numCommands-1)/numCommandsPerTask) + 1;
  67. }
  68. hkJobQueue::JobPopFuncResult hkpShapeRayCastJob::popJobTask( hkpShapeRayCastJob& out )
  69. {
  70. //
  71. // split off a fully filled child job if there are more commands left than one job can handle
  72. //
  73. if ( m_numCommands > m_numCommandsPerTask )
  74. {
  75. out.m_numCommands  = m_numCommandsPerTask;
  76. m_numCommands -= m_numCommandsPerTask;
  77. m_commandArray  = hkAddByteOffsetConst(m_commandArray, m_numCommandsPerTask * sizeof(hkpShapeRayCastCommand));
  78. return hkJobQueue::DO_NOT_POP_QUEUE_ENTRY;
  79. }
  80. return hkJobQueue::POP_QUEUE_ENTRY;
  81. }
  82. // ===============================================================================================================================================================================================
  83. //  WORLD RAYCAST
  84. // ===============================================================================================================================================================================================
  85. hkpWorldRayCastJob::hkpWorldRayCastJob( const hkpProcessCollisionInput* input, hkpCollisionQueryJobHeader* jobHeader, const hkpWorldRayCastCommand* commandArray, int numCommands, const hkpBroadPhase* broadphase, hkSemaphoreBusyWait* semaphore, int numCommandsPerTask)
  86. : hkpRayCastQueryJob( RAYCAST_QUERY_WORLD_RAYCAST, sizeof(hkpWorldRayCastJob) )
  87. {
  88. HK_ASSERT2( 0xaf236152, jobHeader && ((hkUlong)jobHeader & 0xf) == 0, "jobHeader has to be set and be 16 byte aligned." );
  89. HK_ASSERT2( 0xaf3647f6, numCommands > 0, "numCommands has to be > 0." );
  90. HK_ASSERT2( 0xaf3647f7, commandArray && ((hkUlong)commandArray & 0xf) == 0, "commandArray has to be set and 16 byte aligned." );
  91. HK_ASSERT2( 0xaf3647fd, numCommandsPerTask > 0 && numCommandsPerTask <= MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK, "numCommandsPerTask has to be > 0 and <= " << MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK << "." );
  92. #if defined(HK_DEBUG)
  93. {
  94. for (int i=0; i<numCommands; i++)
  95. {
  96. const hkpWorldRayCastCommand* command = &commandArray[i];
  97. HK_ASSERT2( 0xaf3647fe, command->m_results && ((hkUlong)command->m_results & 0xf) == 0, "hkpWorldRayCastCommand::m_results has to be set and 16 byte aligned." );
  98. HK_ASSERT2( 0xaf3638e2, command->m_resultsCapacity > 0 && command->m_resultsCapacity <= hkpWorldRayCastCommand::MAXIMUM_RESULTS_CAPACITY, "hkpWorldRayCastCommand::m_resultsCapacity has to be > 0 and <= " << hkpWorldRayCastCommand::MAXIMUM_RESULTS_CAPACITY << "." );
  99. }
  100. }
  101. // This is a very simple and crude attempt to try to catch a common mistake where the user might
  102. // forget to actually advance the pointer to the results. Doing so could cause incorrect query results.
  103. // This check though will NOT catch trickier situations like e.g. partially overlapping results.
  104. if ( numCommands > 1 )
  105. {
  106. HK_ASSERT2(0xaf253412, commandArray[0].m_results != commandArray[1].m_results, "You are not allowed to re-use the same results buffer for two different query commands.");
  107. }
  108. #endif
  109. m_collisionInput = input;
  110. m_sharedJobHeaderOnPpu = jobHeader;
  111. m_numCommandsPerTask = numCommandsPerTask;
  112. m_semaphore = semaphore;
  113. m_commandArray = commandArray;
  114. m_numCommands = numCommands;
  115. m_broadphase = broadphase;
  116. // precalculate the total number of jobs that will be spawned from the original job (incl. the original)
  117. m_sharedJobHeaderOnPpu->m_openJobs = ((numCommands-1)/numCommandsPerTask) + 1;
  118. }
  119. hkJobQueue::JobPopFuncResult hkpWorldRayCastJob::popJobTask( hkpWorldRayCastJob& out )
  120. {
  121. //
  122. // split off a fully filled child job if there are more commands left than one job can handle
  123. //
  124. if ( m_numCommands > m_numCommandsPerTask )
  125. {
  126. out.m_numCommands  = m_numCommandsPerTask;
  127. m_numCommands -= m_numCommandsPerTask;
  128. m_commandArray  = hkAddByteOffsetConst(m_commandArray, m_numCommandsPerTask * sizeof(hkpWorldRayCastCommand));
  129. return hkJobQueue::DO_NOT_POP_QUEUE_ENTRY;
  130. }
  131. return hkJobQueue::POP_QUEUE_ENTRY;
  132. }
  133. // ===============================================================================================================================================================================================
  134. //  KD-TREE WORLD RAYCAST
  135. // ===============================================================================================================================================================================================
  136. hkpKdTreeRayCastJob::hkpKdTreeRayCastJob(hkpRayCastQueryJobHeader* jobHeader, const hkKdTreeRayCastCommand* commandArray, int numCommands, hkSemaphoreBusyWait* semaphore, int numCommandsPerTask) 
  137. :  hkpRayCastQueryJob(RAYCAST_QUERY_KD_TREE_RAYCAST, sizeof(hkpKdTreeRayCastJob) )
  138. {
  139. HK_ASSERT2( 0xaf236152, jobHeader && ((hkUlong)jobHeader & 0xf) == 0, "jobHeader has to be set and be 16 byte aligned." );
  140. HK_ASSERT2( 0xaf3647f6, numCommands > 0, "numCommands has to be > 0." );
  141. HK_ASSERT2( 0xaf3647f7, commandArray && ((hkUlong)commandArray & 0xf) == 0, "commandArray has to be set and 16 byte aligned." );
  142. HK_ASSERT2( 0xaf3647fd, numCommandsPerTask > 0 && numCommandsPerTask <= MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK, "numCommandsPerTask has to be > 0 and <= " << MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK << "." );
  143. #if defined(HK_DEBUG)
  144. {
  145. hkKdTreeCheckCommandPointers<hkKdTreeRayCastCommand>(commandArray, numCommands);
  146. hkKdTreeCheckCommandCapacity<hkKdTreeRayCastCommand>(commandArray, numCommands);
  147. }
  148. #endif
  149. m_sharedJobHeaderOnPpu = jobHeader;
  150. m_numCommandsPerTask = numCommandsPerTask;
  151. m_semaphore = semaphore;
  152. m_rayCastCommandArray = commandArray;
  153. m_numRayCastCommands = numCommands;
  154. m_rayCastBundleCommandArray = 0;
  155. m_numRayCastBundleCommands = HK_NULL;
  156. m_filter = HK_NULL;
  157. m_numTrees = 0;
  158. m_trees[0] = HK_NULL;
  159. // precalculate the total number of jobs that will be spawned from the original job (incl. the original)
  160. m_sharedJobHeaderOnPpu->m_openJobs = ((numCommands-1)/numCommandsPerTask) + 1;
  161. }
  162. hkJobQueue::JobPopFuncResult hkpKdTreeRayCastJob::popJobTask( hkpKdTreeRayCastJob& out )
  163. {
  164. //
  165. // split off a fully filled child job if there are more commands left than one job can handle
  166. //
  167. hkJobQueue::JobPopFuncResult retVal =  hkJobQueue::POP_QUEUE_ENTRY;
  168. if ( m_numRayCastCommands > m_numCommandsPerTask )
  169. {
  170. out.m_numRayCastCommands  = m_numCommandsPerTask;
  171. m_numRayCastCommands -= m_numCommandsPerTask;
  172. m_rayCastCommandArray  = hkAddByteOffsetConst( m_rayCastCommandArray, m_numCommandsPerTask * sizeof(hkKdTreeRayCastCommand) );
  173. retVal = hkJobQueue::DO_NOT_POP_QUEUE_ENTRY;
  174. }
  175. const int numBundleCommandsPerTask = m_numCommandsPerTask/4;
  176. if ( m_numRayCastBundleCommands > numBundleCommandsPerTask )
  177. {
  178. out.m_numRayCastBundleCommands  = numBundleCommandsPerTask;
  179. m_numRayCastBundleCommands -=  numBundleCommandsPerTask;
  180. m_rayCastBundleCommandArray  = hkAddByteOffsetConst( m_rayCastBundleCommandArray, numBundleCommandsPerTask * sizeof(hkKdTreeRayCastBundleCommand) );
  181. retVal = hkJobQueue::DO_NOT_POP_QUEUE_ENTRY;
  182. }
  183. return retVal;
  184. }
  185. hkpKdTreeBuildJobFast::hkpKdTreeBuildJobFast()
  186. : hkpRayCastQueryJob( RAYCAST_QUERY_KD_TREE_BUILD_FAST, sizeof(hkpKdTreeBuildJobFast) ), 
  187. m_treeDepthOut(HK_NULL)
  188. {
  189. }
  190. hkpKdTreeBuildJobFast::hkpKdTreeBuildJobFast(hkKdTree *tree)
  191. : hkpRayCastQueryJob( RAYCAST_QUERY_KD_TREE_BUILD_FAST, sizeof(hkpKdTreeBuildJobFast) )
  192. {
  193. m_numCollidables = tree->getNumPrimitives();
  194. m_treeOut = tree->getRoot();
  195. m_nodeArraySize = tree->getTotalNumNodes();
  196. m_projEntOut = tree->getProjectedEntries();
  197. m_numAvailableEmptyNodes = tree->getNumReservedEmptyNodes();
  198. m_treeDepthOut = &tree->m_maxDepth;
  199. }
  200. hkpKdTreeBuildDistributedJob::hkpKdTreeBuildDistributedJob(hkpRayCastQueryJobHeader* jobHeader)
  201. : hkpRayCastQueryJob(RAYCAST_QUERY_KD_TREE_BUILD_FAST_DISTRIBUTED_JOB, sizeof(hkpKdTreeBuildDistributedJob) ),
  202. m_branchDepthsOut(HK_NULL)
  203. {
  204. m_sharedJobHeaderOnPpu = jobHeader;
  205. }
  206. hkpKdTreeBuildDistributedJob::hkpKdTreeBuildDistributedJob(hkpRayCastQueryJobHeader* jobHeader, hkKdTree* tree)
  207. : hkpRayCastQueryJob(RAYCAST_QUERY_KD_TREE_BUILD_FAST_DISTRIBUTED_JOB, sizeof(hkpKdTreeBuildDistributedJob) ),
  208. m_branchDepthsOut(HK_NULL)
  209. {
  210. m_sharedJobHeaderOnPpu = jobHeader;
  211. m_numPrimitives = tree->getNumPrimitives();
  212. m_treeOut = tree->getRoot();
  213. m_nodeArraySize = tree->getTotalNumNodes();
  214. m_projEntOut = tree->getProjectedEntries();
  215. m_numAvailableEmptyNodes = tree->getNumReservedEmptyNodes();
  216. }
  217. hkpKdTreeBuildDistributedSubJob::hkpKdTreeBuildDistributedSubJob()
  218. : hkpRayCastQueryJob(RAYCAST_QUERY_KD_TREE_BUILD_FAST_DISTRIBUTED_SUBJOB, sizeof(hkpKdTreeBuildDistributedSubJob) ),
  219. m_branchDepthOut(HK_NULL)
  220. {
  221. }
  222. hkpKdTreeBuildCoordinatorJob::hkpKdTreeBuildCoordinatorJob(hkpRayCastQueryJobHeader* jobHeader, const class hkpWorld* world)
  223. : hkpKdTreeBuildDistributedJob(jobHeader) 
  224. {
  225. m_jobSubType = RAYCAST_QUERY_KD_TREE_BUILD_COORDINATOR_JOB;
  226. m_size = sizeof(hkpKdTreeBuildCoordinatorJob);
  227. m_collisionInput = world->getCollisionInput();
  228. }
  229. hkpKdTreeBuildSetupJob::hkpKdTreeBuildSetupJob()
  230. : hkpKdTreeBuildDistributedJob(HK_NULL), 
  231. m_spawnBuildDistributedJob(false)
  232. {
  233. m_jobSubType = RAYCAST_QUERY_KD_TREE_BUILD_SETUP_JOB;
  234. m_size = sizeof(hkpKdTreeBuildSetupJob);
  235. }
  236. /*
  237. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  238. * Confidential Information of Havok.  (C) Copyright 1999-2009
  239. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  240. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  241. * rights, and intellectual property rights in the Havok software remain in
  242. * Havok and/or its suppliers.
  243. * Use of this software for evaluation purposes is subject to and indicates
  244. * acceptance of the End User licence Agreement for this product. A copy of
  245. * the license is included with this software and is also available at www.havok.com/tryhavok.
  246. */