feat(physics): wire physx sdk into build
This commit is contained in:
402
engine/third_party/physx/snippets/snippetfrustumquery/SnippetFrustumQuery.cpp
vendored
Normal file
402
engine/third_party/physx/snippets/snippetfrustumquery/SnippetFrustumQuery.cpp
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2025 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates how to use a PxBVH to implement view-frustum culling.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include "foundation/PxArray.h"
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
#ifdef RENDER_SNIPPET
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#endif
|
||||
|
||||
//#define BENCHMARK_MODE
|
||||
|
||||
using namespace physx;
|
||||
|
||||
static PxDefaultAllocator gAllocator;
|
||||
static PxDefaultErrorCallback gErrorCallback;
|
||||
static PxFoundation* gFoundation = NULL;
|
||||
|
||||
namespace
|
||||
{
|
||||
class CustomScene
|
||||
{
|
||||
public:
|
||||
CustomScene();
|
||||
~CustomScene();
|
||||
|
||||
void release();
|
||||
void addGeom(const PxGeometry& geom, const PxTransform& pose);
|
||||
void createBVH();
|
||||
void render() const;
|
||||
|
||||
struct Object
|
||||
{
|
||||
PxGeometryHolder mGeom;
|
||||
PxTransform mPose;
|
||||
};
|
||||
|
||||
PxArray<Object> mObjects;
|
||||
PxBVH* mBVH;
|
||||
};
|
||||
|
||||
CustomScene::CustomScene() : mBVH(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CustomScene::~CustomScene()
|
||||
{
|
||||
}
|
||||
|
||||
void CustomScene::release()
|
||||
{
|
||||
PX_RELEASE(mBVH);
|
||||
mObjects.reset();
|
||||
PX_DELETE_THIS;
|
||||
}
|
||||
|
||||
void CustomScene::addGeom(const PxGeometry& geom, const PxTransform& pose)
|
||||
{
|
||||
Object obj;
|
||||
obj.mGeom.storeAny(geom);
|
||||
obj.mPose = pose;
|
||||
mObjects.pushBack(obj);
|
||||
}
|
||||
|
||||
void CustomScene::createBVH()
|
||||
{
|
||||
const PxU32 nbObjects = mObjects.size();
|
||||
PxBounds3* bounds = new PxBounds3[nbObjects];
|
||||
for(PxU32 i=0;i<nbObjects;i++)
|
||||
{
|
||||
Object& obj = mObjects[i];
|
||||
PxGeometryQuery::computeGeomBounds(bounds[i], obj.mGeom.any(), obj.mPose);
|
||||
}
|
||||
|
||||
PxBVHDesc bvhDesc;
|
||||
bvhDesc.bounds.count = nbObjects;
|
||||
bvhDesc.bounds.data = bounds;
|
||||
bvhDesc.bounds.stride = sizeof(PxBounds3);
|
||||
bvhDesc.enlargement = 0.0f;
|
||||
mBVH = PxCreateBVH(bvhDesc);
|
||||
delete [] bounds;
|
||||
}
|
||||
|
||||
enum FrustumPlaneIndex
|
||||
{
|
||||
FRUSTUM_PLANE_LEFT = 0,
|
||||
FRUSTUM_PLANE_RIGHT = 1,
|
||||
FRUSTUM_PLANE_TOP = 2,
|
||||
FRUSTUM_PLANE_BOTTOM = 3,
|
||||
FRUSTUM_PLANE_NEAR = 4,
|
||||
FRUSTUM_PLANE_FAR = 5,
|
||||
};
|
||||
|
||||
void CustomScene::render() const
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
if(0)
|
||||
{
|
||||
// This codepath to draw all objects without culling
|
||||
const PxVec3 color(1.0f, 0.5f, 0.25f);
|
||||
for(PxU32 i=0;i<mObjects.size();i++)
|
||||
{
|
||||
const CustomScene::Object& obj = mObjects[i];
|
||||
Snippets::renderGeoms(1, &obj.mGeom, &obj.mPose, false, color);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract planes from the view/proj matrices. You could also build them from the frustum's vertices.
|
||||
PxPlane planes[6];
|
||||
{
|
||||
float VM[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, VM);
|
||||
const PxMat44 ViewMatrix(VM);
|
||||
|
||||
float PM[16];
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, PM);
|
||||
const PxMat44 ProjMatrix(PM);
|
||||
|
||||
const PxMat44 combo = ProjMatrix * ViewMatrix;
|
||||
|
||||
planes[FRUSTUM_PLANE_LEFT].n.x = -(combo.column0[3] + combo.column0[0]);
|
||||
planes[FRUSTUM_PLANE_LEFT].n.y = -(combo.column1[3] + combo.column1[0]);
|
||||
planes[FRUSTUM_PLANE_LEFT].n.z = -(combo.column2[3] + combo.column2[0]);
|
||||
planes[FRUSTUM_PLANE_LEFT].d = -(combo.column3[3] + combo.column3[0]);
|
||||
|
||||
planes[FRUSTUM_PLANE_RIGHT].n.x = -(combo.column0[3] - combo.column0[0]);
|
||||
planes[FRUSTUM_PLANE_RIGHT].n.y = -(combo.column1[3] - combo.column1[0]);
|
||||
planes[FRUSTUM_PLANE_RIGHT].n.z = -(combo.column2[3] - combo.column2[0]);
|
||||
planes[FRUSTUM_PLANE_RIGHT].d = -(combo.column3[3] - combo.column3[0]);
|
||||
|
||||
planes[FRUSTUM_PLANE_TOP].n.x = -(combo.column0[3] - combo.column0[1]);
|
||||
planes[FRUSTUM_PLANE_TOP].n.y = -(combo.column1[3] - combo.column1[1]);
|
||||
planes[FRUSTUM_PLANE_TOP].n.z = -(combo.column2[3] - combo.column2[1]);
|
||||
planes[FRUSTUM_PLANE_TOP].d = -(combo.column3[3] - combo.column3[1]);
|
||||
|
||||
planes[FRUSTUM_PLANE_BOTTOM].n.x = -(combo.column0[3] + combo.column0[1]);
|
||||
planes[FRUSTUM_PLANE_BOTTOM].n.y = -(combo.column1[3] + combo.column1[1]);
|
||||
planes[FRUSTUM_PLANE_BOTTOM].n.z = -(combo.column2[3] + combo.column2[1]);
|
||||
planes[FRUSTUM_PLANE_BOTTOM].d = -(combo.column3[3] + combo.column3[1]);
|
||||
|
||||
planes[FRUSTUM_PLANE_NEAR].n.x = -(combo.column0[3] + combo.column0[2]);
|
||||
planes[FRUSTUM_PLANE_NEAR].n.y = -(combo.column1[3] + combo.column1[2]);
|
||||
planes[FRUSTUM_PLANE_NEAR].n.z = -(combo.column2[3] + combo.column2[2]);
|
||||
planes[FRUSTUM_PLANE_NEAR].d = -(combo.column3[3] + combo.column3[2]);
|
||||
|
||||
planes[FRUSTUM_PLANE_FAR].n.x = -(combo.column0[3] - combo.column0[2]);
|
||||
planes[FRUSTUM_PLANE_FAR].n.y = -(combo.column1[3] - combo.column1[2]);
|
||||
planes[FRUSTUM_PLANE_FAR].n.z = -(combo.column2[3] - combo.column2[2]);
|
||||
planes[FRUSTUM_PLANE_FAR].d = -(combo.column3[3] - combo.column3[2]);
|
||||
|
||||
for(PxU32 i=0;i<6;i++)
|
||||
planes[i].normalize();
|
||||
}
|
||||
|
||||
if(mBVH)
|
||||
{
|
||||
struct LocalCB : PxBVH::OverlapCallback
|
||||
{
|
||||
LocalCB(const CustomScene& scene) : mScene(scene)
|
||||
{
|
||||
mVisibles.reserve(10000);
|
||||
}
|
||||
|
||||
virtual bool reportHit(PxU32 boundsIndex)
|
||||
{
|
||||
mVisibles.pushBack(boundsIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
const CustomScene& mScene;
|
||||
PxArray<PxU32> mVisibles;
|
||||
LocalCB& operator=(const LocalCB&){return *this;}
|
||||
};
|
||||
|
||||
LocalCB cb(*this);
|
||||
|
||||
#ifdef BENCHMARK_MODE
|
||||
unsigned long long time = __rdtsc();
|
||||
#endif
|
||||
mBVH->cull(6, planes, cb);
|
||||
|
||||
char buffer[256];
|
||||
#ifdef BENCHMARK_MODE
|
||||
time = __rdtsc() - time;
|
||||
sprintf(buffer, "%d visible objects (%d)\n", cb.mVisibles.size(), int(time/1024));
|
||||
#else
|
||||
sprintf(buffer, "%d visible objects\n", cb.mVisibles.size());
|
||||
#endif
|
||||
const PxVec3 color(1.0f, 0.5f, 0.25f);
|
||||
for(PxU32 i=0;i<cb.mVisibles.size();i++)
|
||||
{
|
||||
const CustomScene::Object& obj = mObjects[cb.mVisibles[i]];
|
||||
Snippets::renderGeoms(1, &obj.mGeom, &obj.mPose, false, color);
|
||||
}
|
||||
|
||||
if(1)
|
||||
{
|
||||
const PxU32 nbObjects = mBVH->getNbBounds();
|
||||
for(PxU32 i=0;i<nbObjects;i++)
|
||||
Snippets::DrawBounds(mBVH->getBounds()[i]);
|
||||
}
|
||||
|
||||
Snippets::print(buffer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static PxConvexMesh* createConvexMesh(const PxVec3* verts, const PxU32 numVerts, const PxCookingParams& params)
|
||||
{
|
||||
PxConvexMeshDesc convexDesc;
|
||||
convexDesc.points.count = numVerts;
|
||||
convexDesc.points.stride = sizeof(PxVec3);
|
||||
convexDesc.points.data = verts;
|
||||
convexDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;
|
||||
return PxCreateConvexMesh(params, convexDesc);
|
||||
}
|
||||
|
||||
static PxConvexMesh* createCylinderMesh(const PxF32 width, const PxF32 radius, const PxCookingParams& params)
|
||||
{
|
||||
PxVec3 points[2*16];
|
||||
for(PxU32 i = 0; i < 16; i++)
|
||||
{
|
||||
const PxF32 cosTheta = PxCos(i*PxPi*2.0f/16.0f);
|
||||
const PxF32 sinTheta = PxSin(i*PxPi*2.0f/16.0f);
|
||||
const PxF32 y = radius*cosTheta;
|
||||
const PxF32 z = radius*sinTheta;
|
||||
points[2*i+0] = PxVec3(-width/2.0f, y, z);
|
||||
points[2*i+1] = PxVec3(+width/2.0f, y, z);
|
||||
}
|
||||
return createConvexMesh(points, 32, params);
|
||||
}
|
||||
|
||||
static void initScene()
|
||||
{
|
||||
}
|
||||
|
||||
static void releaseScene()
|
||||
{
|
||||
}
|
||||
|
||||
static PxConvexMesh* gConvexMesh = NULL;
|
||||
static PxTriangleMesh* gTriangleMesh = NULL;
|
||||
|
||||
static CustomScene* gScene = NULL;
|
||||
|
||||
void renderScene()
|
||||
{
|
||||
if(gScene)
|
||||
gScene->render();
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
const PxTolerancesScale scale;
|
||||
PxCookingParams params(scale);
|
||||
params.midphaseDesc.setToDefault(PxMeshMidPhase::eBVH34);
|
||||
// params.midphaseDesc.mBVH34Desc.quantized = false;
|
||||
params.meshPreprocessParams |= PxMeshPreprocessingFlag::eDISABLE_ACTIVE_EDGES_PRECOMPUTE;
|
||||
params.meshPreprocessParams |= PxMeshPreprocessingFlag::eDISABLE_CLEAN_MESH;
|
||||
|
||||
gConvexMesh = createCylinderMesh(3.0f, 1.0f, params);
|
||||
|
||||
{
|
||||
PxTriangleMeshDesc meshDesc;
|
||||
meshDesc.points.count = SnippetUtils::Bunny_getNbVerts();
|
||||
meshDesc.points.stride = sizeof(PxVec3);
|
||||
meshDesc.points.data = SnippetUtils::Bunny_getVerts();
|
||||
meshDesc.triangles.count = SnippetUtils::Bunny_getNbFaces();
|
||||
meshDesc.triangles.stride = sizeof(int)*3;
|
||||
meshDesc.triangles.data = SnippetUtils::Bunny_getFaces();
|
||||
|
||||
gTriangleMesh = PxCreateTriangleMesh(params, meshDesc);
|
||||
}
|
||||
|
||||
gScene = new CustomScene;
|
||||
|
||||
#ifdef BENCHMARK_MODE
|
||||
{
|
||||
SnippetUtils::BasicRandom rnd(42);
|
||||
|
||||
PxVec3 v;
|
||||
const float coeff = 30.0f;
|
||||
for(int i=0;i<1000;i++)
|
||||
{
|
||||
rnd.unitRandomPt(v); v*=coeff;
|
||||
gScene->addGeom(PxBoxGeometry(PxVec3(1.0f, 2.0f, 0.5f)), PxTransform(v+PxVec3(0.0f, 0.0f, 0.0f)));
|
||||
rnd.unitRandomPt(v); v*=coeff;
|
||||
gScene->addGeom(PxSphereGeometry(1.5f), PxTransform(v+PxVec3(4.0f, 0.0f, 0.0f)));
|
||||
rnd.unitRandomPt(v); v*=coeff;
|
||||
gScene->addGeom(PxCapsuleGeometry(1.0f, 1.0f), PxTransform(v+PxVec3(-4.0f, 0.0f, 0.0f)));
|
||||
rnd.unitRandomPt(v); v*=coeff;
|
||||
gScene->addGeom(PxConvexMeshGeometry(gConvexMesh), PxTransform(v+PxVec3(0.0f, 0.0f, 4.0f)));
|
||||
rnd.unitRandomPt(v); v*=coeff;
|
||||
gScene->addGeom(PxTriangleMeshGeometry(gTriangleMesh), PxTransform(v+PxVec3(0.0f, 0.0f, -4.0f)));
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
gScene->addGeom(PxBoxGeometry(PxVec3(1.0f, 2.0f, 0.5f)), PxTransform(PxVec3(0.0f, 0.0f, 0.0f)));
|
||||
gScene->addGeom(PxSphereGeometry(1.5f), PxTransform(PxVec3(4.0f, 0.0f, 0.0f)));
|
||||
gScene->addGeom(PxCapsuleGeometry(1.0f, 1.0f), PxTransform(PxVec3(-4.0f, 0.0f, 0.0f)));
|
||||
gScene->addGeom(PxConvexMeshGeometry(gConvexMesh), PxTransform(PxVec3(0.0f, 0.0f, 4.0f)));
|
||||
gScene->addGeom(PxTriangleMeshGeometry(gTriangleMesh), PxTransform(PxVec3(0.0f, 0.0f, -4.0f)));
|
||||
}
|
||||
#endif
|
||||
gScene->createBVH();
|
||||
|
||||
initScene();
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
releaseScene();
|
||||
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gConvexMesh);
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetFrustumQuery done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char /*key*/, const PxTransform& /*camera*/)
|
||||
{
|
||||
/* if(key >= 1 && key <= gScenarioCount)
|
||||
{
|
||||
gScenario = key - 1;
|
||||
releaseScene();
|
||||
initScene();
|
||||
}
|
||||
|
||||
if(key == 'r' || key == 'R')
|
||||
{
|
||||
releaseScene();
|
||||
initScene();
|
||||
}*/
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
printf("Frustum query snippet.\n");
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user