Skip to content

Instantly share code, notes, and snippets.

@alanjfs
Last active March 31, 2021 17:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alanjfs/76416c401ca471d34da920190f6c43b2 to your computer and use it in GitHub Desktop.
Save alanjfs/76416c401ca471d34da920190f6c43b2 to your computer and use it in GitHub Desktop.
Reproducible Bug - PhysX 4.1
add_executable(Kinematics kinematicsSnippet.cpp)
set(PX_BUILDSNIPPETS FALSE CACHE BOOL "" FORCE)
set(PX_BUILDPUBLICSAMPLES FALSE CACHE BOOL "" FORCE)
set(PX_GENERATE_STATIC_LIBRARIES TRUE CACHE BOOL "" FORCE)
set(PX_FLOAT_POINT_PRECISE_MATH FALSE CACHE BOOL "" FORCE)
set(NV_USE_STATIC_WINCRT TRUE CACHE BOOL "" FORCE)
set(NV_USE_DEBUG_WINCRT TRUE CACHE BOOL "" FORCE)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(Kinematics PRIVATE -D_DEBUG)
if(MSVC)
target_compile_options(Kinematics PRIVATE "/Zi")
endif()
else()
target_compile_definitions(Kinematics PRIVATE -DNDEBUG)
endif()
if(MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "/MT")
set(CMAKE_CXX_FLAGS_DEBUG "/MTd")
endif()
# Convert our build type to something PhysX understands
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
message("-- PhysX BUILD TYPE: release")
set(CMAKE_BUILD_TYPE "release" CACHE STRING "Build type")
add_subdirectory(PhysX/physx EXCLUDE_FROM_ALL)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type")
elseif (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
message("-- PhysX BUILD TYPE: checked")
set(CMAKE_BUILD_TYPE "checked" CACHE STRING "Build type")
add_subdirectory(PhysX/physx EXCLUDE_FROM_ALL)
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type")
else()
message("Bad build type" FATAL)
endif()
target_link_libraries(
Kinematics
PRIVATE
PhysX
PhysXExtensions
PhysXFoundation
PhysXCommon
PhysXCooking
PhysXPvdSDK
)
#define PX_PHYSX_STATIC_LIB
#include <ctype.h>
#include <cmath>
#include <algorithm>
#include "PxPhysicsAPI.h"
#include "foundation/PxPreprocessor.h"
#define PVD_HOST "127.0.0.1"
#define PX_RELEASE(x) if(x) { x->release(); x = NULL; }
using namespace physx;
PxDefaultAllocator gAllocator;
PxDefaultErrorCallback gErrorCallback;
PxFoundation* gFoundation = NULL;
PxPhysics* gPhysics = NULL;
PxDefaultCpuDispatcher* gDispatcher = NULL;
PxScene* gScene = NULL;
PxMaterial* gMaterial = NULL;
PxPvd* gPvd = NULL;
// D6 joint with a spring maintaining its position
PxJoint* createD6(PxRigidActor* parent, const PxTransform& parentTm,
PxRigidActor* child, const PxTransform& childTm) {
PxD6Joint* joint = PxD6JointCreate(*gPhysics, parent, parentTm, child, childTm);
joint->setMotion(PxD6Axis::eX, PxD6Motion::eLIMITED);
joint->setMotion(PxD6Axis::eY, PxD6Motion::eLIMITED);
joint->setMotion(PxD6Axis::eZ, PxD6Motion::eLIMITED);
joint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE);
joint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);
joint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eFREE);
joint->setDrive(PxD6Drive::eSLERP, PxD6JointDrive(0, 1000, FLT_MAX, true));
const PxSpring linearSpring { 100.f, 100.f };
const PxJointLinearLimitPair linearLimit { -0.01f, 0.01f, linearSpring };
joint->setLinearLimit(PxD6Axis::eX, linearLimit);
joint->setLinearLimit(PxD6Axis::eY, linearLimit);
joint->setLinearLimit(PxD6Axis::eZ, linearLimit);
return joint;
}
PxRigidDynamic* initPhysics() {
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
gPvd = PxCreatePvd(*gFoundation);
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true, gPvd);
PxInitExtensions(*gPhysics, gPvd);
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
sceneDesc.gravity = PxVec3(0.0f, 0.0f, 0.0f);
gDispatcher = PxDefaultCpuDispatcherCreate(2);
sceneDesc.cpuDispatcher = gDispatcher;
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
sceneDesc.solverType = PxSolverType::eTGS;
gScene = gPhysics->createScene(sceneDesc);
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
if (pvdClient) {
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
}
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
gScene->addActor(*groundPlane);
PxReal separation { 2.0f };
PxVec3 offset(separation / 2, 0, 0);
PxTransform localTm(offset);
PxRigidDynamic* prev = NULL;
PxTransform tm { PxVec3(0.0f, 20.0f, -20.0f) };
PxBoxGeometry geo { separation / 2, 0.5f, 0.5f };
PxRigidDynamic* parent = PxCreateDynamic(*gPhysics, tm * localTm, geo, *gMaterial, separation);
localTm.p.x += separation;
PxRigidDynamic* child = PxCreateDynamic(*gPhysics, tm * localTm, geo, *gMaterial, separation);
createD6(parent, PxTransform(offset), child, PxTransform(-offset));
gScene->addActor(*parent);
gScene->addActor(*child);
// Let's animate this one
parent->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
return parent;
}
void stepPhysics(PxRigidDynamic* rigid, PxU32 frame) {
// "Animation"
const float x = std::min(std::max(std::sin(0.025f * frame + 0.5f), -0.5f), 0.5f) * 10.0f - 5.0f;
PxTransform tm { PxVec3(x, 20.0f, -20.0f) };
rigid->setKinematicTarget(tm);
gScene->simulate(1.0f/60.0f);
gScene->fetchResults(true);
}
void cleanupPhysics() {
PX_RELEASE(gScene);
PX_RELEASE(gDispatcher);
PxCloseExtensions();
PX_RELEASE(gPhysics);
if (gPvd) {
PxPvdTransport* transport = gPvd->getTransport();
gPvd->release(); gPvd = NULL;
PX_RELEASE(transport);
}
PX_RELEASE(gFoundation);
}
int main(int, const char* const*) {
static const PxU32 frameCount = 500;
PxRigidDynamic* rigid = initPhysics();
for(PxU32 i=0; i<frameCount; i++) {
stepPhysics(rigid, i);
}
cleanupPhysics();
printf("All done\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment