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

其他游戏

开发平台:

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. #ifndef HK_COLLISION_JOBS_H
  9. #define HK_COLLISION_JOBS_H
  10. #include <Common/Base/hkBase.h>
  11. #include <Common/Base/Types/Geometry/Aabb/hkAabb.h>
  12. #include <Common/Base/Thread/Semaphore/hkSemaphoreBusyWait.h>
  13. #include <Common/Base/Thread/JobQueue/hkJobQueue.h>
  14. #include <Physics/Collide/Shape/Compound/Tree/hkpBvTreeShape.h>
  15. #include <Physics/Collide/hkpCollide.h>
  16. #include <Physics/Collide/Agent/Collidable/hkpCollidable.h>
  17. #include <Physics/Collide/Query/CastUtil/hkpWorldRayCastInput.h>
  18. #include <Physics/Collide/Query/CastUtil/hkpLinearCastInput.h>
  19. #include <Physics/Collide/Shape/Compound/Collection/List/hkpListShape.h>
  20. #include <Physics/Collide/Shape/Query/hkpShapeRayCastInput.h>
  21. #include <Physics/Collide/Shape/Query/hkpShapeRayCastOutput.h>
  22. #include <Physics/Internal/Collide/Mopp/Code/hkpMoppCode.h>
  23. #include <Common/Internal/KdTree/hkKdTree.h>
  24. #include <Common/Base/hkBase.h>
  25. struct hkpRootCdPoint;
  26. class hkpShapeCollectionFilter;
  27. class hkpBroadPhase;
  28. class hkpWorld;
  29. struct hkpShapeRayCastInput;
  30. struct hkpShapeRayCastOutput;
  31. struct hkpWorldRayCastOutput;
  32. class hkpCollisionFilter;
  33. /// Each collision query job needs an hkpCollisionQueryJobHeader. Usually this is passed in through the job's constructor.
  34. /// PLAYSTATION(R)3 note: this header will be dma'd back and forth between PPU and SPU and therefore must not be allocated on PPU stack.
  35. struct hkpCollisionQueryJobHeader
  36. {
  37. public:
  38. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpCollisionQueryJobHeader );
  39. // This member can only be accessed if the job queue is locked once its governing job has been added to the job queue.
  40. HK_ALIGN16( mutable int m_openJobs );
  41. };
  42. //
  43. // The base class for all collision query jobs
  44. // Important: the 16bit m_jobType HAS to be the first member of this class and it HAS to be 16byte aligned! See hkJob for more details.
  45. //
  46. struct hkpCollisionQueryJob : public hkJob
  47. {
  48. public:
  49. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpCollisionQueryJob );
  50. enum JobSubType
  51. {
  52. COLLISION_QUERY_MOPP_AABB,
  53. COLLISION_QUERY_PAIR_GET_CLOSEST_POINTS,
  54. COLLISION_QUERY_WORLD_GET_CLOSEST_POINTS,
  55. COLLISION_QUERY_PAIR_LINEAR_CAST,
  56. COLLISION_QUERY_WORLD_LINEAR_CAST,
  57. COLLISION_QUERY_KD_TREE_AABB_QUERY_JOB,
  58. COLLISION_QUERY_KD_TREE_LINEAR_CAST_JOB,
  59. COLLISION_QUERY_JOB_END
  60. };
  61. void atomicIncrementAndReleaseSemaphore() const;
  62. protected:
  63. HK_FORCE_INLINE hkpCollisionQueryJob( JobSubType subType, hkUint16 size );
  64. public:
  65. // This semaphore is released once the original job (and all its spawned children) has finished.
  66. hkSemaphoreBusyWait* m_semaphore;
  67. // this header must be set for all jobs that potentially spawn additional jobs or that have been spawned by other jobs
  68. hkpCollisionQueryJobHeader* m_sharedJobHeaderOnPpu;
  69. const hkpProcessCollisionInput* m_collisionInput;
  70. // The variable at this location will be incremented (atomically) when the job is done.
  71. hkUint32* m_jobDoneFlag;
  72. };
  73. // ===============================================================================================================================================================================================
  74. //   PAIR LINEAR CAST 
  75. // ===============================================================================================================================================================================================
  76. /// An hkpPairLinearCastCommand can be used to calculate the linear casts between two objects. 
  77. /// The first object is cast against the second one, with endpoints specified by the user.
  78. /// More than one collision result may return. 
  79. struct hkpPairLinearCastCommand
  80. {
  81. public:
  82. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpPairLinearCastCommand );
  83. enum { MAXIMUM_RESULTS_CAPACITY = 16 }; // the capacity has to be limited as we need to allocate this array on the SPU stack
  84. public:
  85. // ===================================================================
  86. // Input
  87. // ===================================================================
  88. /// The first collidable will be cast along a provided path against the second collidable.
  89. const hkpCollidable* m_collidableA;
  90. /// The second collidable remains fixed.
  91. const hkpCollidable* m_collidableB;
  92. /// The starting point of the linear cast path. The first collidable will move along this path.
  93. hkVector4 m_from;
  94. /// The endpoint of the linear cast path. The first collidable will move along this path.
  95. hkVector4 m_to;
  96. // ===================================================================
  97. // Output
  98. // ===================================================================
  99. /// Pointer to an hkpRootCdPoint array. The user has to pre-allocate this manually. Once the job has finished, this array will hold the results.
  100. /// Note that the results will be arbitrarily placed in the results array (i.e. without any specific order).
  101. /// PLAYSTATION(R)3 note: this array will be dma'd from SPU and therefore must not be allocated on PPU stack.
  102. hkpRootCdPoint* m_results;
  103. /// The maximum number of results pre-allocated in m_results.
  104. int m_resultsCapacity;
  105. /// The number of results.
  106. /// This value is only valid after the job's semaphore has been released.
  107. int m_numResultsOut;
  108. hkpRootCdPoint* m_startPointResults;
  109. int m_startPointResultsCapacity;
  110. int m_startPointNumResultsOut;
  111. };
  112. /// An hkpPairLinearCastJob will take an arbitrary number of hkpPairLinearCastCommand and calculate the linear casts between the specified pairs. The job is able
  113. /// to split itself into two jobs if it holds more commands than the maximum allowed number that can be executed in one go. Jobs will be processed multithreaded
  114. /// (i.e. in parallel by different PPU and/or SPU threads, if available).
  115. struct hkpPairLinearCastJob : public hkpCollisionQueryJob
  116. {
  117. public:
  118. friend struct hkpCollisionQueryJobQueueUtils;
  119. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpPairLinearCastJob );
  120. enum { MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK = 128 };
  121. public:
  122. /// When creating an hkpPairLinearCastJob you have to pass in an unique jobHeader as well as an array of commands.
  123. /// Only points closer than the supplied tolerance are reported.
  124. /// The supplied filter is used if any shape collections are queried.
  125. /// The supplied semaphore is released once all commands of this job have been completed and the job has been removed from the job queue.
  126. /// The number of commands that are grouped into one task is customizable.
  127. /// PLAYSTATION(R)3 note: the jobHeader and the commandArray will be dma'd to SPU and therefore must not be allocated on PPU stack.
  128. HK_FORCE_INLINE hkpPairLinearCastJob( const hkpProcessCollisionInput* input, hkpCollisionQueryJobHeader* jobHeader, const hkpPairLinearCastCommand* commandArray, int numCommands, const hkpShapeCollectionFilter* filter, hkReal tolerance, hkSemaphoreBusyWait* semaphore, int numCommandsPerTask = MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK);
  129. /// This constructor is for internal use only! Please use the other constructor.
  130. HK_FORCE_INLINE hkpPairLinearCastJob();
  131. /// Only necessary on PLAYSTATION(R)3. 
  132. /// Use this method to assign this job to be processed on the SPU or PPU. This is automatically set depending on what the job references.
  133. /// If it references objects which are not supported on the spu
  134. /// this function will produce a warning (in debug) and the job will be processed on PPU. 
  135. void setRunsOnSpuOrPpu();
  136. protected:
  137. HK_FORCE_INLINE hkJobQueue::JobPopFuncResult popJobTask( hkpPairLinearCastJob& out );
  138. public:
  139. hkReal m_tolerance; //
  140. const hkpShapeCollectionFilter* m_filter; // Filter to be used when searching for the closest point(s)
  141. // Linear cast tolerances
  142. hkReal m_maxExtraPenetration;
  143. hkReal m_iterativeLinearCastEarlyOutDistance; // For iterative linear cast only
  144. int m_iterativeLinearCastMaxIterations;
  145. int m_numCommandsPerTask; // maximum # of commands per task; once this limit is breached a subjob is spawned
  146. const hkpPairLinearCastCommand* m_commandArray;
  147. int m_numCommands;
  148. };
  149. // ===============================================================================================================================================================================================
  150. //  WORLD LINEAR CAST
  151. // ===============================================================================================================================================================================================
  152. /// An hkpWorldLinearCastCommand can be used to cast exactly one collidable through the broadphase. Depending on how many hits you want
  153. /// to be reported you have to supply a large enough m_results output array. Once this array has reached its capacity, the furthest
  154. /// hit will be dropped.
  155. /// Performance note: when supplying a m_results array-size of exactly 1, the broadphase will use an early-out algorithm to significantly
  156. /// speedup things. With an array-size > 1 this speedup will be lost.
  157. struct hkpWorldLinearCastCommand
  158. {
  159. public:
  160. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpWorldLinearCastCommand );
  161. enum { MAXIMUM_RESULTS_CAPACITY = 16 }; // the capacity has to be limited as we need to allocate this array on the SPU stack
  162. public:
  163. // ===================================================================
  164. // Input
  165. // ===================================================================
  166. /// The linear cast input data.
  167. hkpLinearCastInput m_input;
  168. /// This collidable will be cast along the provided path against.
  169. const hkpCollidable* m_collidable;
  170. // ===================================================================
  171. // Output
  172. // ===================================================================
  173. /// Pointer to an hkpRootCdPoint array. The user has to pre-allocate this manually. Once the job has finished, this array will hold the results.
  174. /// Note that the results in this array will be only grouped on an object-pair-basis, but for one object pair they are arbitrarily placed in the results array (i.e. without any specific order).
  175. /// PLAYSTATION(R)3 note: this array will be dma'd from SPU and therefore must not be allocated on PPU stack.
  176. hkpRootCdPoint* m_results;
  177. /// The maximum number of results pre-allocated in m_results.
  178. int m_resultsCapacity;
  179. /// The number of results.
  180. /// This value is only valid after the job's semaphore has been released.
  181. int m_numResultsOut;
  182. };
  183. /// An hkpWorldLinearCastJob will take an arbitrary number of hkWorldLinearCastCommands and perform the linear casts. The job is able
  184. /// to split itself into two jobs if it holds more commands than the maximum allowed number that can be executed in one go.
  185. /// Jobs will be processed multithreaded (i.e. in parallel by different PPU and/or SPU threads, if available).
  186. struct hkpWorldLinearCastJob : public hkpCollisionQueryJob
  187. {
  188. public:
  189. friend struct hkpCollisionQueryJobQueueUtils;
  190. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpWorldLinearCastJob );
  191. enum { MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK = 256 };
  192. public:
  193. /// When creating an hkpWorldLinearCastJob you have to pass in an unique jobHeader as well as an array of commands.
  194. /// The supplied broadphase is used to limit the number of possible object pairs and thus helps increasing performance.
  195. /// The supplied semaphore is released once all commands of this job have been completed and the job has been removed from the job queue.
  196. /// The number of commands that are grouped into one task is customizable.
  197. /// PLAYSTATION(R)3 note: the jobHeader and the commandArray will be dma'd to SPU and therefore must not be allocated on PPU stack.
  198. HK_FORCE_INLINE hkpWorldLinearCastJob( const hkpProcessCollisionInput* input, hkpCollisionQueryJobHeader* jobHeader, const hkpWorldLinearCastCommand* commandArray, int numCommands, const hkpBroadPhase* broadphase, hkSemaphoreBusyWait* semaphore, int numCommandsPerTask = MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK);
  199. /// Only necessary on PLAYSTATION(R)3. 
  200. /// Use this method to assign this job to be processed on the SPU or PPU. This is automatically set depending on what the job references.
  201. /// If it references objects which are not supported on the spu
  202. /// this function will produce a warning (in debug) and the job will be processed on PPU. 
  203. void setRunsOnSpuOrPpu();
  204. protected:
  205. HK_FORCE_INLINE hkJobQueue::JobPopFuncResult popJobTask( hkpWorldLinearCastJob& out );
  206. public:
  207. // Inputs
  208. int m_numCommandsPerTask; // maximum # of commands per task; once this limit is breached a subjob is spawned
  209. const hkpWorldLinearCastCommand* m_commandArray;
  210. int m_numCommands;
  211. const hkpBroadPhase* m_broadphase;
  212. };
  213. // ===============================================================================================================================================================================================
  214. //  MOPP AABB
  215. // ===============================================================================================================================================================================================
  216. /// An hkpMoppAabbCommand can be used to cast exactly one AABB cast against the job's global MOPP. It will return a maximum of MAX_OUTPUT_KEYS_PER_QUERY
  217. /// results. The last valid results in this array will be followed by an HK_INVALID_SHAPE_KEY.
  218. struct hkpMoppAabbCommand
  219. {
  220. public:
  221. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpMoppAabbCommand );
  222. enum { MAX_OUTPUT_KEYS_PER_QUERY = HK_MAX_NUM_HITS_PER_AABB_QUERY };
  223. typedef hkpShapeKey QueryOutput[MAX_OUTPUT_KEYS_PER_QUERY];
  224. public:
  225. // ===================================================================
  226. // Input
  227. // ===================================================================
  228. /// The AABB's input data.
  229. hkAabb m_aabbInput;
  230. // ===================================================================
  231. // Output
  232. // ===================================================================
  233. /// Pointer to an hkpShapeKey array.
  234. /// PLAYSTATION(R)3 note: this array will be dma'd from SPU and therefore must not be allocated on PPU stack.
  235. QueryOutput* m_results;
  236. };
  237. /// An hkpMoppAabbJob will take an arbitrary number of hkMoppAabbCommands and perform the AABB casts on the job's MOPP. The job is able
  238. /// to split itself into two jobs if it holds more commands than the maximum allowed number that can be executed in one go.
  239. /// Jobs will be processed multithreaded (i.e. in parallel by different PPU and/or SPU threads, if available).
  240. struct hkpMoppAabbJob : public hkpCollisionQueryJob
  241. {
  242. public:
  243. friend struct hkpCollisionQueryJobQueueUtils;
  244. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpMoppAabbJob );
  245. enum { MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK = 256 };
  246. public:
  247. /// When creating an hkpMoppAabbJob you have to pass in an unique jobHeader as well as an array of commands.
  248. /// All the job's commands are executed on the same MOPP code and info.
  249. /// The supplied semaphore is released once all commands of this job have been completed and the job has been removed from the job queue.
  250. /// The number of commands that are grouped into one task is customizable.
  251. /// PLAYSTATION(R)3 note: the jobHeader and the commandArray will be dma'd to SPU and therefore must not be allocated on PPU stack.
  252. HK_FORCE_INLINE hkpMoppAabbJob( const hkpProcessCollisionInput* input, hkpCollisionQueryJobHeader* jobHeader, const hkpMoppAabbCommand* commandArray, int numCommands, const hkUint8* moppCodeData, const hkpMoppCode::CodeInfo& moppCodeInfo, hkSemaphoreBusyWait* semaphore, int numCommandsPerTask = MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK);
  253. protected:
  254. HK_FORCE_INLINE hkJobQueue::JobPopFuncResult popJobTask( hkpMoppAabbJob& out );
  255. public:
  256. hkpMoppCode::CodeInfo m_moppCodeInfo; // MOPP code info
  257. const hkUint8* m_moppCodeData; // MOPP code data
  258. int m_numCommandsPerTask; // maximum # of commands per task; once this limit is breached a subjob is spawned
  259. const hkpMoppAabbCommand* m_commandArray;
  260. int m_numCommands;
  261. };
  262. // ===============================================================================================================================================================================================
  263. //  PAIR GET CLOSEST POINTS
  264. // ===============================================================================================================================================================================================
  265. /// An hkpPairGetClosestPointsCommand can be used to calculate the shortest distances (i.e. closest points) between two objects. Depending on the
  266. /// objects' shapes, more than 1 distance can exist. Depending on how many distances you want reported you have to supply a large
  267. /// enough m_results output array. Once this array is full, every time a closer point is added the currently longest distance will be dropped.
  268. HK_CLASSALIGN16(struct) hkpPairGetClosestPointsCommand
  269. {
  270. public:
  271. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpPairGetClosestPointsCommand );
  272. enum { MAXIMUM_RESULTS_CAPACITY = 16 }; // the capacity has to be limited as we need to allocate this array on the SPU stack
  273. public:
  274. // ===================================================================
  275. // Input
  276. // ===================================================================
  277. /// The first of the two collidables for which we would like to find the closest point between.
  278. const hkpCollidable* m_collidableA;
  279. /// The second of the two collidables for which we would like to find the closest point between.
  280. const hkpCollidable* m_collidableB;
  281. // ===================================================================
  282. // Output
  283. // ===================================================================
  284. /// Pointer to an hkpRootCdPoint array. The user has to pre-allocate this manually. Once the job has finished, this array will hold the results.
  285. /// Note that the results will be arbitrarily placed in the results array (i.e. without any specific order).
  286. /// PLAYSTATION(R)3 note: this array will be dma'd from SPU and therefore must not be allocated on PPU stack.
  287. hkpRootCdPoint* m_results;
  288. /// The maximum number of results pre-allocated in m_results.
  289. int m_resultsCapacity;
  290. /// The number of results.
  291. /// This value is only valid after the job's semaphore has been released.
  292. int m_numResultsOut;
  293. /// This variable is set automatically. Do not touch.
  294. // Automatically set to HK_NULL if m_results is private to this command.
  295. // If m_results is shared between multiple hkPairGetClosestPointsCommands this variable points to an index into m_results. Currently this is only the case for 
  296. // hkPairGetClosestPointsCommands that have been created by an hkpWorldGetClosestPointsJob and thus points to hkpWorldGetClosestPointsCommand::m_numResultsOut.
  297. hkUint32* m_indexIntoSharedResults;
  298. };
  299. /// An hkpPairGetClosestPointsJob will take an arbitrary number of hkpPairGetClosestPointsCommand and calculate the shortest distances between the specified pairs. The job is able
  300. /// to split itself into two jobs if it holds more commands than the maximum allowed number that can be executed in one go. Jobs will be processed multithreaded
  301. /// (i.e. in parallel by different PPU and/or SPU threads, if available).
  302. struct hkpPairGetClosestPointsJob : public hkpCollisionQueryJob
  303. {
  304. public:
  305. friend struct hkpCollisionQueryJobQueueUtils;
  306. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpPairGetClosestPointsJob );
  307. enum { MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK = 256 };
  308. public:
  309. /// When creating an hkpPairGetClosestPointsJob you have to pass in an unique jobHeader as well as an array of commands.
  310. /// Only closest points with a distance of the supplied tolerance (or smaller) are reported.
  311. /// The supplied semaphore is released once all commands of this job have been completed and the job has been removed from the job queue.
  312. /// The number of commands that are grouped into one task is customizable.
  313. /// PLAYSTATION(R)3 note: the jobHeader and the commandArray will be dma'd to SPU and therefore must not be allocated on PPU stack.
  314. HK_FORCE_INLINE hkpPairGetClosestPointsJob( const hkpProcessCollisionInput* input, hkpCollisionQueryJobHeader* jobHeader, const hkpPairGetClosestPointsCommand* commandArray, int numCommands, hkReal tolerance, hkSemaphoreBusyWait* semaphore, int numCommandsPerTask = MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK);
  315. /// This constructor is for internal use only! Please use the other constructor.
  316. HK_FORCE_INLINE hkpPairGetClosestPointsJob();
  317. /// Only necessary on PLAYSTATION(R)3. 
  318. /// Use this method to assign this job to be processed on the SPU or PPU. This is automatically set depending on what the job references.
  319. /// If it references objects which are not supported on the spu
  320. /// this function will produce a warning (in debug) and the job will be processed on PPU. 
  321. void setRunsOnSpuOrPpu();
  322. protected:
  323. HK_FORCE_INLINE hkJobQueue::JobPopFuncResult popJobTask( hkpPairGetClosestPointsJob& out );
  324. public:
  325. hkReal m_tolerance;
  326. int m_numCommandsPerTask; // maximum # of commands per task; once this limit is breached a subjob is spawned
  327. const hkpPairGetClosestPointsCommand* m_commandArray;
  328. int m_numCommands;
  329. };
  330. // ===============================================================================================================================================================================================
  331. //  WORLD GET CLOSEST POINTS
  332. // ===============================================================================================================================================================================================
  333. /// An hkpWorldGetClosestPointsCommand can be used to calculate the shortest distances (i.e. closest points) between the supplied object and all its surrounding objects.
  334. /// Processing this command will spawn hkPairGetClosestPointsJobs, so see hkpPairGetClosestPointsJob for more information.
  335. struct hkpWorldGetClosestPointsCommand
  336. {
  337. public:
  338. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpWorldGetClosestPointsCommand );
  339. public:
  340. // ===================================================================
  341. // Input
  342. // ===================================================================
  343. /// We want the closest points all around this particular collidable.
  344. const hkpCollidable* m_collidable;
  345. // ===================================================================
  346. // Output
  347. // ===================================================================
  348. /// Pointer to an hkpRootCdPoint array. The user has to pre-allocate this manually. Once the job has finished, this array will hold the results.
  349. /// Note that the results in this array will be only grouped on an object-pair-basis, but for one object pair they are arbitrarily placed in the results array (i.e. without any specific order).
  350. /// PLAYSTATION(R)3 note: this array will be dma'd from SPU and therefore must not be allocated on PPU stack.
  351. hkpRootCdPoint* m_results;
  352. /// The maximum number of results pre-allocated in m_results.
  353. int m_resultsCapacity;
  354. /// The number of results.
  355. /// This value is only valid after the job's semaphore has been released.
  356. hkUint32 m_numResultsOut;
  357. };
  358. /// An hkpWorldGetClosestPointsJob will take a limited number of hkWorldGetClosestPointsCommands and calculate the shortest distances between
  359. /// the specified objects and their surroundings.
  360. struct hkpWorldGetClosestPointsJob : public hkpCollisionQueryJob
  361. {
  362. public:
  363. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpWorldGetClosestPointsJob );
  364. // The maximum number of commands that can be processed by one single hkpWorldGetClosestPointsJob
  365. enum { MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK = 64 };
  366. // PRIVATE ENUM. DO NOT MODIFY! NO NEED TO UNDERSTAND ITS PURPOSE. :)
  367. // The job's m_openJobs variable will be preset with this value to assert that all spawned jobs finish first before releasing the job's semaphore.
  368. enum { OPEN_JOBS_PRESET = 1000000 };
  369. enum { MAXIMUM_RESULTS_CAPACITY = 16 }; // the capacity has to be limited as we need to allocate this array on the SPU stack
  370. public:
  371. /// When creating an hkpWorldGetClosestPointsJob you have to pass in an unique jobHeader as well as an array of commands.
  372. /// The supplied broadphase is used to limit the number of possible object pairs and thus helps increasing performance.
  373. /// Only closest points for object pairs with a distance of the supplied tolerance (or smaller) are reported.
  374. /// The supplied semaphore is released once all commands of this job have been completed and the job has been removed from the job queue.
  375. /// PLAYSTATION(R)3 note: the jobHeader and the commandArray will be dma'd to SPU and therefore must not be allocated on PPU stack.
  376. /// PLAYSTATION(R)3 note: the pairGetClosestPointsCommandBuffer will be dma'd from SPU and therefore must not be allocated on PPU stack.
  377. HK_FORCE_INLINE hkpWorldGetClosestPointsJob( const hkpProcessCollisionInput* input, hkpCollisionQueryJobHeader* jobHeader, const hkpWorldGetClosestPointsCommand* commandArray, int numCommands, hkpPairGetClosestPointsCommand* pairGetClosestPointsCommandBuffer, int pairGetClosestPointsCommandBufferCapacity, const hkpBroadPhase* broadphase, hkReal tolerance, hkSemaphoreBusyWait* semaphore);
  378. /// Only necessary on PLAYSTATION(R)3. 
  379. /// Use this method to assign this job to be processed on the SPU or PPU. This is automatically set depending on what the job references.
  380. /// If it references objects which are not supported on the spu
  381. /// this function will produce a warning (in debug) and the job will be processed on PPU. 
  382. void setRunsOnSpuOrPpu();
  383. public:
  384. const hkpBroadPhase* m_broadphase;
  385. hkReal m_tolerance;
  386. // This buffer on PPU is used to store hkPairGetClosestPointsCommands for jobs that are spawned on the spu/ppu.
  387. hkpPairGetClosestPointsCommand* m_pairGetClosestPointsCommandBuffer; // if this is != HK_NULL it will be used to create actual hkPairGetClosestPointsJobs on the queue; make sure to reasonably size it
  388. int m_pairGetClosestPointsCommandBufferCapacity; // the above buffer's capacity
  389. const hkpWorldGetClosestPointsCommand* m_commandArray;
  390. int m_numCommands;
  391. // PRIVATE MEMBER. DO NOT MODIFY! NO NEED TO UNDERSTAND ITS PURPOSE. :)
  392. // Some background info: hkpWorldGetClosestPointsJob can spawn hkpPairGetClosestPointsJob jobs. As there is no support for any addJobFunc in the job queue
  393. // we have no way of increasing m_openJobs when adding a new job to the queue. Doing this during popJobFunc can be too late, therefore we will preset m_openJobs
  394. // with a huge enough value to cover any reasonable amount of potentially spawned 'sub'jobs. To correct this exaggerated value during this job's finishJobFunc
  395. // we need to know how many 'sub'jobs were actually spawned.
  396. mutable int m_numJobsSpawned;
  397. };
  398. // ===============================================================================================================================================================================================
  399. //   KD-TREE AABB QUERY
  400. // ===============================================================================================================================================================================================
  401. struct hkpKdTreeAabbCommand
  402. {
  403. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpKdTreeAabbCommand );
  404. // Input
  405. hkAabb m_aabb;
  406. int m_resultsCapacity;
  407. // Ouput
  408. hkPrimitiveId* m_results;
  409. int m_numResultsOut;
  410. };
  411. struct hkpKdTreeAabbJob : public hkpCollisionQueryJob
  412. {
  413. public:
  414. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpKdTreeAabbJob );
  415. enum { MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK = 256 };
  416. public:
  417. HK_FORCE_INLINE hkpKdTreeAabbJob(hkpCollisionQueryJobHeader* jobHeader, hkpKdTreeAabbCommand* commandArray, int numCommands, hkSemaphoreBusyWait* semaphore, int numCommandsPerTask = MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK);
  418. HK_FORCE_INLINE hkJobQueue::JobPopFuncResult popJobTask( hkpKdTreeAabbJob& out );
  419. public:
  420. enum {MAX_NUM_TREES = 4};
  421. // Inputs
  422. int m_numCommandsPerTask; // maximum # of commands per task; once this limit is breached a subjob is spawned
  423. hkpKdTreeAabbCommand* m_aabbCommandArray;
  424. int m_numAabbCommands;
  425. int m_numTrees;
  426. const class hkKdTree* m_trees[MAX_NUM_TREES];
  427. };
  428. // ===============================================================================================================================================================================================
  429. //   KD-TREE WORLD LINEAR CAST QUERY
  430. // ===============================================================================================================================================================================================
  431. // No special command for kdtree linear casts; just reuse hkpWorldLinearCastCommand
  432. struct hkpWorldLinearCastCommand;
  433. struct hkpKdTreeLinearCastJob : public hkpCollisionQueryJob
  434. {
  435. public:
  436. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_COLLIDE, hkpKdTreeLinearCastJob );
  437. enum { MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK = 256 };
  438. public:
  439. HK_FORCE_INLINE hkpKdTreeLinearCastJob( const hkpProcessCollisionInput* input, hkpCollisionQueryJobHeader* jobHeader, hkpWorldLinearCastCommand* commandArray, int numCommands, hkSemaphoreBusyWait* semaphore, int numCommandsPerTask = MAXIMUM_NUMBER_OF_COMMANDS_PER_TASK);
  440. HK_FORCE_INLINE hkJobQueue::JobPopFuncResult popJobTask( hkpKdTreeAabbJob& out );
  441. /// Only necessary on PLAYSTATION(R)3. 
  442. /// Use this method to assign this job to be processed on the SPU or PPU. This is automatically set depending on what the job references.
  443. /// If it references objects which are not supported on the spu
  444. /// this function will produce a warning (in debug) and the job will be processed on PPU. 
  445. void setRunsOnSpuOrPpu();
  446. public:
  447. enum {MAX_NUM_TREES = 4};
  448. // Inputs
  449. int m_numCommandsPerTask; // maximum # of commands per task; once this limit is breached a subjob is spawned
  450. hkpWorldLinearCastCommand* m_commandArray;
  451. int m_numCommands;
  452. const hkpProcessCollisionInput* m_collisionInput;
  453. hkpCollisionFilter* m_filter;
  454. int m_numTrees;
  455. const class hkKdTree* m_trees[MAX_NUM_TREES];
  456. };
  457. #include <Physics/Collide/Query/Multithreaded/CollisionQuery/hkpCollisionQueryJobs.inl>
  458. #endif // HK_COLLISION_JOBS_H
  459. /*
  460. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  461. * Confidential Information of Havok.  (C) Copyright 1999-2009
  462. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  463. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  464. * rights, and intellectual property rights in the Havok software remain in
  465. * Havok and/or its suppliers.
  466. * Use of this software for evaluation purposes is subject to and indicates
  467. * acceptance of the End User licence Agreement for this product. A copy of
  468. * the license is included with this software and is also available at www.havok.com/tryhavok.
  469. */