px3Collision.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "T3D/physics/physx3/px3Collision.h"
  24. #include "math/mPoint3.h"
  25. #include "math/mMatrix.h"
  26. #include "T3D/physics/physx3/px3.h"
  27. #include "T3D/physics/physx3/px3Casts.h"
  28. #include "T3D/physics/physx3/px3World.h"
  29. #include "T3D/physics/physx3/px3Stream.h"
  30. Px3Collision::Px3Collision()
  31. {
  32. }
  33. Px3Collision::~Px3Collision()
  34. {
  35. for ( U32 i=0; i < mColShapes.size(); i++ )
  36. {
  37. Px3CollisionDesc *desc = mColShapes[i];
  38. delete desc->pGeometry;
  39. // Delete the descriptor.
  40. delete desc;
  41. }
  42. mColShapes.clear();
  43. }
  44. void Px3Collision::addPlane( const PlaneF &plane )
  45. {
  46. physx::PxVec3 pos = px3Cast<physx::PxVec3>(plane.getPosition());
  47. Px3CollisionDesc *desc = new Px3CollisionDesc;
  48. desc->pGeometry = new physx::PxPlaneGeometry();
  49. desc->pose = physx::PxTransform(pos, physx::PxQuat(physx::PxHalfPi, physx::PxVec3(0.0f, -1.0f, 0.0f)));
  50. mColShapes.push_back(desc);
  51. }
  52. void Px3Collision::addBox( const Point3F &halfWidth,const MatrixF &localXfm )
  53. {
  54. Px3CollisionDesc *desc = new Px3CollisionDesc;
  55. desc->pGeometry = new physx::PxBoxGeometry(px3Cast<physx::PxVec3>(halfWidth));
  56. desc->pose = px3Cast<physx::PxTransform>(localXfm);
  57. mColShapes.push_back(desc);
  58. }
  59. void Px3Collision::addSphere( F32 radius,
  60. const MatrixF &localXfm )
  61. {
  62. Px3CollisionDesc *desc = new Px3CollisionDesc;
  63. desc->pGeometry = new physx::PxSphereGeometry(radius);
  64. desc->pose = px3Cast<physx::PxTransform>(localXfm);
  65. mColShapes.push_back(desc);
  66. }
  67. void Px3Collision::addCapsule( F32 radius,
  68. F32 height,
  69. const MatrixF &localXfm )
  70. {
  71. Px3CollisionDesc *desc = new Px3CollisionDesc;
  72. desc->pGeometry = new physx::PxCapsuleGeometry(radius,height*0.5);//uses half height
  73. desc->pose = px3Cast<physx::PxTransform>(localXfm);
  74. mColShapes.push_back(desc);
  75. }
  76. bool Px3Collision::addConvex( const Point3F *points,
  77. U32 count,
  78. const MatrixF &localXfm )
  79. {
  80. physx::PxCooking *cooking = Px3World::getCooking();
  81. physx::PxConvexMeshDesc convexDesc;
  82. convexDesc.points.data = points;
  83. convexDesc.points.stride = sizeof(Point3F);
  84. convexDesc.points.count = count;
  85. convexDesc.flags = physx::PxConvexFlag::eFLIPNORMALS|physx::PxConvexFlag::eCOMPUTE_CONVEX | physx::PxConvexFlag::eINFLATE_CONVEX;
  86. Px3MemOutStream stream;
  87. if(!cooking->cookConvexMesh(convexDesc,stream))
  88. return false;
  89. physx::PxConvexMesh* convexMesh;
  90. Px3MemInStream in(stream.getData(), stream.getSize());
  91. convexMesh = gPhysics3SDK->createConvexMesh(in);
  92. Px3CollisionDesc *desc = new Px3CollisionDesc;
  93. physx::PxVec3 scale = px3Cast<physx::PxVec3>(localXfm.getScale());
  94. physx::PxQuat rotation = px3Cast<physx::PxQuat>(QuatF(localXfm));
  95. physx::PxMeshScale meshScale(scale,rotation);
  96. desc->pGeometry = new physx::PxConvexMeshGeometry(convexMesh,meshScale);
  97. desc->pose = px3Cast<physx::PxTransform>(localXfm);
  98. mColShapes.push_back(desc);
  99. return true;
  100. }
  101. bool Px3Collision::addTriangleMesh( const Point3F *vert,
  102. U32 vertCount,
  103. const U32 *index,
  104. U32 triCount,
  105. const MatrixF &localXfm )
  106. {
  107. physx::PxCooking *cooking = Px3World::getCooking();
  108. physx::PxTriangleMeshDesc meshDesc;
  109. meshDesc.points.count = vertCount;
  110. meshDesc.points.data = vert;
  111. meshDesc.points.stride = sizeof(Point3F);
  112. meshDesc.triangles.count = triCount;
  113. meshDesc.triangles.data = index;
  114. meshDesc.triangles.stride = 3*sizeof(U32);
  115. meshDesc.flags = physx::PxMeshFlag::eFLIPNORMALS;
  116. Px3MemOutStream stream;
  117. if(!cooking->cookTriangleMesh(meshDesc,stream))
  118. return false;
  119. physx::PxTriangleMesh *mesh;
  120. Px3MemInStream in(stream.getData(), stream.getSize());
  121. mesh = gPhysics3SDK->createTriangleMesh(in);
  122. Px3CollisionDesc *desc = new Px3CollisionDesc;
  123. desc->pGeometry = new physx::PxTriangleMeshGeometry(mesh);
  124. desc->pose = px3Cast<physx::PxTransform>(localXfm);
  125. mColShapes.push_back(desc);
  126. return true;
  127. }
  128. bool Px3Collision::addHeightfield( const U16 *heights,
  129. const bool *holes,
  130. U32 blockSize,
  131. F32 metersPerSample,
  132. const MatrixF &localXfm )
  133. {
  134. const F32 heightScale = 0.03125f;
  135. physx::PxHeightFieldSample* samples = (physx::PxHeightFieldSample*) new physx::PxHeightFieldSample[blockSize*blockSize];
  136. memset(samples,0,blockSize*blockSize*sizeof(physx::PxHeightFieldSample));
  137. physx::PxHeightFieldDesc heightFieldDesc;
  138. heightFieldDesc.nbColumns = blockSize;
  139. heightFieldDesc.nbRows = blockSize;
  140. heightFieldDesc.thickness = -10.f;
  141. heightFieldDesc.convexEdgeThreshold = 0;
  142. heightFieldDesc.format = physx::PxHeightFieldFormat::eS16_TM;
  143. heightFieldDesc.samples.data = samples;
  144. heightFieldDesc.samples.stride = sizeof(physx::PxHeightFieldSample);
  145. physx::PxU8 *currentByte = (physx::PxU8*)heightFieldDesc.samples.data;
  146. for ( U32 row = 0; row < blockSize; row++ )
  147. {
  148. const U32 tess = ( row + 1 ) % 2;
  149. for ( U32 column = 0; column < blockSize; column++ )
  150. {
  151. physx::PxHeightFieldSample *currentSample = (physx::PxHeightFieldSample*)currentByte;
  152. U32 index = ( blockSize - row - 1 ) + ( column * blockSize );
  153. currentSample->height = (physx::PxI16)heights[ index ];
  154. if ( holes && holes[ getMax( (S32)index - 1, 0 ) ] ) // row index for holes adjusted so PhysX collision shape better matches rendered terrain
  155. {
  156. currentSample->materialIndex0 = physx::PxHeightFieldMaterial::eHOLE;
  157. currentSample->materialIndex1 = physx::PxHeightFieldMaterial::eHOLE;
  158. }
  159. else
  160. {
  161. currentSample->materialIndex0 = 0;
  162. currentSample->materialIndex1 = 0;
  163. }
  164. int flag = ( column + tess ) % 2;
  165. if(flag)
  166. currentSample->clearTessFlag();
  167. else
  168. currentSample->setTessFlag();
  169. currentByte += heightFieldDesc.samples.stride;
  170. }
  171. }
  172. physx::PxHeightField * hf = gPhysics3SDK->createHeightField(heightFieldDesc);
  173. physx::PxHeightFieldGeometry *geom = new physx::PxHeightFieldGeometry(hf,physx::PxMeshGeometryFlags(),heightScale,metersPerSample,metersPerSample);
  174. physx::PxTransform pose= physx::PxTransform(physx::PxQuat(Float_HalfPi, physx::PxVec3(1, 0, 0 )));
  175. physx::PxTransform pose1= physx::PxTransform(physx::PxQuat(Float_Pi, physx::PxVec3(0, 0, 1 )));
  176. physx::PxTransform pose2 = pose1 * pose;
  177. pose2.p = physx::PxVec3(( blockSize - 1 ) * metersPerSample, 0, 0 );
  178. Px3CollisionDesc *desc = new Px3CollisionDesc;
  179. desc->pGeometry = geom;
  180. desc->pose = pose2;
  181. mColShapes.push_back(desc);
  182. SAFE_DELETE(samples);
  183. return true;
  184. }