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