px3Collision.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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, const MatrixF &localXfm )
  60. {
  61. Px3CollisionDesc *desc = new Px3CollisionDesc;
  62. desc->pGeometry = new physx::PxSphereGeometry(radius);
  63. desc->pose = px3Cast<physx::PxTransform>(localXfm);
  64. mColShapes.push_back(desc);
  65. }
  66. void Px3Collision::addCapsule( F32 radius, F32 height, const MatrixF &localXfm )
  67. {
  68. Px3CollisionDesc *desc = new Px3CollisionDesc;
  69. desc->pGeometry = new physx::PxCapsuleGeometry(radius,height*0.5);//uses half height
  70. desc->pose = px3Cast<physx::PxTransform>(localXfm);
  71. mColShapes.push_back(desc);
  72. }
  73. bool Px3Collision::addConvex( const Point3F *points, U32 count, const MatrixF &localXfm )
  74. {
  75. physx::PxCooking *cooking = Px3World::getCooking();
  76. physx::PxConvexMeshDesc convexDesc;
  77. convexDesc.points.data = points;
  78. convexDesc.points.stride = sizeof(Point3F);
  79. convexDesc.points.count = count;
  80. convexDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX | physx::PxConvexFlag::eCHECK_ZERO_AREA_TRIANGLES;
  81. if(PhysicsWorld::isGpuEnabled())
  82. convexDesc.flags |= physx::PxConvexFlag::eGPU_COMPATIBLE;
  83. Px3MemOutStream stream;
  84. if(!cooking->cookConvexMesh(convexDesc,stream))
  85. return false;
  86. physx::PxConvexMesh* convexMesh;
  87. Px3MemInStream in(stream.getData(), stream.getSize());
  88. convexMesh = gPhysics3SDK->createConvexMesh(in);
  89. Px3CollisionDesc *desc = new Px3CollisionDesc;
  90. physx::PxVec3 scale = px3Cast<physx::PxVec3>(localXfm.getScale());
  91. physx::PxQuat rotation = px3Cast<physx::PxQuat>(QuatF(localXfm));
  92. physx::PxMeshScale meshScale(scale,rotation);
  93. desc->pGeometry = new physx::PxConvexMeshGeometry(convexMesh,meshScale);
  94. desc->pose = px3Cast<physx::PxTransform>(localXfm);
  95. mColShapes.push_back(desc);
  96. return true;
  97. }
  98. bool Px3Collision::addTriangleMesh( const Point3F *vert, U32 vertCount, const U32 *index, U32 triCount, const MatrixF &localXfm )
  99. {
  100. physx::PxCooking *cooking = Px3World::getCooking();
  101. physx::PxTriangleMeshDesc meshDesc;
  102. meshDesc.points.count = vertCount;
  103. meshDesc.points.data = vert;
  104. meshDesc.points.stride = sizeof(Point3F);
  105. meshDesc.triangles.count = triCount;
  106. meshDesc.triangles.data = index;
  107. meshDesc.triangles.stride = 3*sizeof(U32);
  108. meshDesc.flags = physx::PxMeshFlag::eFLIPNORMALS;
  109. Px3MemOutStream stream;
  110. if(!cooking->cookTriangleMesh(meshDesc,stream))
  111. return false;
  112. physx::PxTriangleMesh *mesh;
  113. Px3MemInStream in(stream.getData(), stream.getSize());
  114. mesh = gPhysics3SDK->createTriangleMesh(in);
  115. Px3CollisionDesc *desc = new Px3CollisionDesc;
  116. desc->pGeometry = new physx::PxTriangleMeshGeometry(mesh);
  117. desc->pose = px3Cast<physx::PxTransform>(localXfm);
  118. mColShapes.push_back(desc);
  119. return true;
  120. }
  121. bool Px3Collision::addHeightfield( const U16 *heights, const bool *holes, U32 blockSize, F32 metersPerSample, const MatrixF &localXfm )
  122. {
  123. const F32 heightScale = 0.03125f;
  124. physx::PxHeightFieldSample* samples = (physx::PxHeightFieldSample*) new physx::PxHeightFieldSample[blockSize*blockSize];
  125. memset(samples,0,blockSize*blockSize*sizeof(physx::PxHeightFieldSample));
  126. physx::PxHeightFieldDesc heightFieldDesc;
  127. heightFieldDesc.nbColumns = blockSize;
  128. heightFieldDesc.nbRows = blockSize;
  129. heightFieldDesc.thickness = -10.f;
  130. heightFieldDesc.convexEdgeThreshold = 0;
  131. heightFieldDesc.format = physx::PxHeightFieldFormat::eS16_TM;
  132. heightFieldDesc.samples.data = samples;
  133. heightFieldDesc.samples.stride = sizeof(physx::PxHeightFieldSample);
  134. physx::PxU8 *currentByte = (physx::PxU8*)heightFieldDesc.samples.data;
  135. for ( U32 row = 0; row < blockSize; row++ )
  136. {
  137. const U32 tess = ( row + 1 ) % 2;
  138. for ( U32 column = 0; column < blockSize; column++ )
  139. {
  140. physx::PxHeightFieldSample *currentSample = (physx::PxHeightFieldSample*)currentByte;
  141. U32 index = ( blockSize - row - 1 ) + ( column * blockSize );
  142. currentSample->height = (physx::PxI16)heights[ index ];
  143. if ( holes && holes[ getMax( (S32)index - 1, 0 ) ] ) // row index for holes adjusted so PhysX collision shape better matches rendered terrain
  144. {
  145. currentSample->materialIndex0 = physx::PxHeightFieldMaterial::eHOLE;
  146. currentSample->materialIndex1 = physx::PxHeightFieldMaterial::eHOLE;
  147. }
  148. else
  149. {
  150. currentSample->materialIndex0 = 0;
  151. currentSample->materialIndex1 = 0;
  152. }
  153. S32 flag = ( column + tess ) % 2;
  154. if(flag)
  155. currentSample->clearTessFlag();
  156. else
  157. currentSample->setTessFlag();
  158. currentByte += heightFieldDesc.samples.stride;
  159. }
  160. }
  161. physx::PxCooking *cooking = Px3World::getCooking();
  162. physx::PxHeightField * hf = cooking->createHeightField(heightFieldDesc,gPhysics3SDK->getPhysicsInsertionCallback());
  163. physx::PxHeightFieldGeometry *geom = new physx::PxHeightFieldGeometry(hf,physx::PxMeshGeometryFlags(),heightScale,metersPerSample,metersPerSample);
  164. physx::PxTransform pose= physx::PxTransform(physx::PxQuat(Float_HalfPi, physx::PxVec3(1, 0, 0 )));
  165. physx::PxTransform pose1= physx::PxTransform(physx::PxQuat(Float_Pi, physx::PxVec3(0, 0, 1 )));
  166. physx::PxTransform pose2 = pose1 * pose;
  167. pose2.p = physx::PxVec3(( blockSize - 1 ) * metersPerSample, 0, 0 );
  168. Px3CollisionDesc *desc = new Px3CollisionDesc;
  169. desc->pGeometry = geom;
  170. desc->pose = pose2;
  171. mColShapes.push_back(desc);
  172. SAFE_DELETE(samples);
  173. return true;
  174. }