Hello! I recently started trying PhysX, I need to simulate some cubes movements and collisions. Since I was not able to do that, I tried to reach a somewhat minimal example.
In the following example, I create two rigid dynamic actors. One of them is a kinematic cube, the other one is a non-kinematic sphere.
auto boxGeometry = physx::PxBoxGeometry(100.f, 100.f, 100.f);
auto boxMaterial = GPhysXSDK->createMaterial(0.5f, 0.5f, 0.1f);
boxMaterial->setFlag(PxMaterialFlag::eDISABLE_FRICTION, true);
auto boxShape = GPhysXSDK->createShape(boxGeometry, *boxMaterial, true);
boxShape->setFlag(physx::PxShapeFlag::Enum::eSIMULATION_SHAPE, true);
PxFilterData boxFilterData;
boxFilterData.word0 = FilterGroup::eBOX;
boxFilterData.word1 = FilterGroup::eSPHERE;
boxShape->setSimulationFilterData(boxFilterData);
boxMaterial->userData = boxShape;
auto sphereGeometry = physx::PxSphereGeometry(physx::PxReal(50.f));
auto sphereMaterial = GPhysXSDK->createMaterial(0.5f, 0.5f, 0.1f);
sphereMaterial->setFlag(PxMaterialFlag::eDISABLE_FRICTION, true);
auto sphereShape = GPhysXSDK->createShape(sphereGeometry, *sphereMaterial, true);
sphereShape->setFlag(physx::PxShapeFlag::Enum::eSIMULATION_SHAPE, true);
PxFilterData sphereFilterData;
sphereFilterData.word0 = FilterGroup::eSPHERE;
sphereFilterData.word1 = FilterGroup::eBOX;
sphereShape->setSimulationFilterData(sphereFilterData);
sphereMaterial->userData = sphereShape;
auto kinematicCube = GPhysXSDK->createRigidDynamic(physx::PxTransform(physx::PxVec3(0.f, 0.f, 0.f)));
kinematicCube->attachShape(*boxShape);
boxShape->release();
kinematicCube->putToSleep();
kinematicCube->setName("box");
kinematicCube->setMass(10.f);
kinematicCube->setMassSpaceInertiaTensor(PxVec3(1.f));
kinematicCube->setActorFlag(physx::PxActorFlag::eSEND_SLEEP_NOTIFIES, true);
kinematicCube->setActorFlag(physx::PxActorFlag::eDISABLE_SIMULATION, false);
kinematicCube->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, true);
kinematicCube->setRigidBodyFlag(physx::PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW, true);
auto dynamicSphere = GPhysXSDK->createRigidDynamic(physx::PxTransform(physx::PxVec3(0.f, 300.f, 0.f)));
dynamicSphere->attachShape(*sphereShape);
sphereShape->release();
dynamicSphere->putToSleep();
dynamicSphere->setName("sphere");
dynamicSphere->setMass(10.f);
dynamicSphere->setMassSpaceInertiaTensor(PxVec3(1.f));
dynamicSphere->setActorFlag(physx::PxActorFlag::eSEND_SLEEP_NOTIFIES, true);
dynamicSphere->setActorFlag(physx::PxActorFlag::eDISABLE_SIMULATION, false);
dynamicSphere->setRigidBodyFlag(physx::PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW, true);
dynamicSphere->setLinearVelocity(physx::PxVec3(PxReal(0.f), PxReal(-100.f), PxReal(0.f)));
auto pActors = TArray<PxActor*>{kinematicCube, dynamicSphere};
auto sceneDesc = physx::PxSceneDesc(physx::PxTolerancesScale());
sceneDesc.filterShader = CustomSimulationFilterShader;
sceneDesc.simulationEventCallback = new CustomSimulationEventCallback();
const auto physxScene = GPhysXSDK->createScene(sceneDesc);
physxScene->addActors(pActors.GetData(), pActors.Num());
kinematicCube->setKinematicTarget(physx::PxTransform(physx::PxVec3(0.f, 150.f, 0.f)));
physxScene->simulate(1.f);
auto errorState = physx::PxU32();
auto res = physxScene->fetchResults(true, &errorState);
auto actor1Pos = kinematicCube->getGlobalPose();
auto actor2Pos = dynamicSphere->getGlobalPose();
Here CustomSimulationEventCallback inherits from the pure-virtual PxSimulationEventCallback. The only callbacks I was able to get where the ones about sleeping/waking up. No advance nor collision callbacks are generated by the above code. I tried using two non-kinematic rigid bodies, and still I get no collision callbacks, even when they are in a starting overlapping position.
Moreover, the final getGlobalPose() on the two actors give me the actors start location. I was not able to make them move within the simulation… Any idea why?
Thanks for the help
Francesco