NVIDIA PhysX SDK

Overview

NVIDIA PhysX SDK 4.1

Copyright (c) 2021 NVIDIA Corporation. All rights reserved.

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.

Introduction

Welcome to the NVIDIA PhysX SDK source code repository. This depot includes the PhysX SDK and the Kapla Demo application.

The NVIDIA PhysX SDK is a scalable multi-platform physics solution supporting a wide range of devices, from smartphones to high-end multicore CPUs and GPUs. PhysX is already integrated into some of the most popular game engines, including Unreal Engine, and Unity3D. PhysX SDK on developer.nvidia.com.

Documentation

Please see Release Notes for updates pertaining to the latest version.

The full set of documentation can also be found in the repository under physx/documentation or online at http://gameworksdocs.nvidia.com/simulation.html

Platform specific information can be found here:

Quick Start Instructions

Requirements:

  • Python 2.7.6 or later
  • CMake 3.12 or later

To begin, clone this repository onto your local drive. Then change directory to physx/, run ./generate_projects.[bat|sh] and follow on-screen prompts. This will let you select a platform specific solution to build. You can then open the generated solution file with your IDE and kick off one or more configuration builds.

To build and run the Kapla Demo see kaplademo/README.md.

Acknowledgements

This depot contains external third party open source software copyright their respective owners. See kaplademo/README.md and externals/README.md for details.

Comments
  • Raycasts fail for articulations after a while

    Raycasts fail for articulations after a while

    I have set up a ragdoll using articulations and I am observing rather weird behavior with raycasts. Just after a while of activity, parts of an articulation stop being hit by raycasts. It still interacts with other actors and can be pushed by a character controller, but raycasts just don't hit those parts anymore, as if suddenly the collision filter changed.

    Here is a video (zipped because apparently I can upload larger zips than mp4s):

    Raycasts through Articulation.zip

    After a while the top beam stops hitting the articulation, for no apparent reason. Then the gun also doesn't hit those parts anymore, though it still hits the bottom half of the articulation.

    I'm also attaching the corresponding PVD recording, though since articulations aren't supported that well by it, I don't see any useful data in it.

    Articulation Raycasts.zip

    opened by jankrassnigg 40
  • drives failing to achieve maximum force

    drives failing to achieve maximum force

    I'm simulating a wheel loader. This link shows the basic layout of a wheel loader for illustration purposes though it's not this one that I'm simulating https://wastemanagementreview.com.au/wp-content/uploads/2018/11/wheel-loader-pic.jpg .

    Effectively there's a linear drive which pushes on the lever in the middle which in turn pulls on a link connected to the bucket which then rotates. Note that this is implemented using constrained ridid bodies rather than articulations with the PGS solver in physx 4.1.2. The drive itself is a force limited damper with target velocity dictated by user input. There are a few complications over that basic model which I'm glossing over which are hopefully unimportant.

    I have a requirement that when the bucket is on the ground and the hydraulic is contracted such that the bucket is rotated downwards the machine should lift off the ground. i.e. the hydraulic which rotates the bucket should be strong enough to lift the machine by rotating the bucket.

    What I am observing is that the machine is failing to lift and yet the force exerted by the drive is a fraction of the maximum force it is permitted to exert. I'd like to know:

    • why is this?
    • what are my options to fix it?

    Changing the damping coefficient has a minimal impact. Changing the target velocity makes a big difference. If I say I want to extend at 1m/s with 10^10N of force then I don't get enough force to move. If I say I want to extend at 2m/s then it moves just fine. These are of course just illustrative values.

    My suspicion is that it's to do with the relevant mass ratios in the system. In general the ratios of the various physical parts in the system maintain the 1:10 recommendation but they're not ideal. It's a little harder to tell for moments of inertia but I believe in my case the force pushing on the bucket is only about 9% of the force at the hydraulic (depending on the exact configuration of the system) due to the levers involved. The mass any individual part is certainly less than 10% of the mass of the whole machine which I'm trying to lift.

    I believe the TGS solver is intended to do a better job of this and indeed it has solved similar problems in the past for me but it has also caused unacceptable instability (read: explosions) so I conclude that it is inappropriate for my problem.

    I'm curious about whether articulations would do a better job of this. Unfortunately it would be quite difficult to restructure everything to use an articulation so I wouldn't want to attempt it unless there was a theoretical expectation it would solve my problem. I'm also concerned about the circular dependencies in the parts in the system and how that would work for an articulation.

    From reading the code and documentation, it appears that using the mass/inertia scales should solve my problem. However I've found that if I scale mass/inertia symmetrically across the two bodies then I achieve no effect. This surprises me as it seems like for damping to make so little difference, dt * damping * unitResponse must be must greater than 1 so reducing unitResponse should solve my problem but in (https://github.com/NVIDIAGameWorks/PhysX/blob/c3d5537bdebd6f5cd82fcaf87474b838fe6fd5fa/physx/source/lowleveldynamics/src/DyConstraintSetup.cpp#L478) it appears that unitResponse is directly proportional to the mass/inertia scales.

    Applying mass/inertia scales asymmetrically results in a net force on the system as a whole resulting in my machine accelerating faster and faster along the ground without any input.

    I could implement some sort of feedback loop where I artifically apply additional force or increase target speed when I observe that neither the target speed nor maximum force are reached. However I'd prefer to avoid this because of the weird side effects it might have in cases where things would otherwise work fine.

    opened by asdasdasdasdasdf 39
  • PhysX 5.0 - Available in 2020 ?

    PhysX 5.0 - Available in 2020 ?

    PhysX 5.0 is just around the corner, and we wanted to provide a look at all the new features! In this version, available in 2020, we’ll be introducing support for a unified constrained particle simulation frame。

    Tody is 2020.12.29!

    opened by swq0553 27
  • Bug with TGS + linear limit  or linear drive between Kinematic and Dynamic body

    Bug with TGS + linear limit or linear drive between Kinematic and Dynamic body

    Hi all,

    Re-posting this from within a longer thread for visibility and clarity, given the problem is now pretty clearly a bug.

    Original issue

    • https://github.com/NVIDIAGameWorks/PhysX/issues/356

    Problem

    With a PxD6Joint between a kinematic and dynamic rigid body, both limits and drives misbehave under TGS, but not PGS. The dynamic body appears to inherit too much velocity from the kinematic body.

    TGS

    | Case | Demo |:-----|:--- | TGS Linear Limit | bug | PGS Linear Limit | good | TGS Drive | bugdrives

    The problem is made much worse with a rotating kinematic body.

    | Case | Demo |:-----|:--- | PGS Linear Drive | kinematicrotating | TGS Linear Drive | tgsrotation


    Reproducible

    Lines of interest are..

    And the result as seen from PVD, where TGS appears to introduce additional velocity to the dynamic rigid when jointed to an animated kinematic rigid, whereas PGS does not.

    bugtgs pgsgood


    PxDistanceJoint

    The problem can also be seen with other joints, like the PxDistanceJoint

    PxJoint* createJoint(PxRigidActor* parent, const PxTransform& parentTm,
                         PxRigidActor* child, const PxTransform& childTm) {
    
        PxDistanceJoint* joint = PxDistanceJointCreate(*gPhysics, parent, parentTm, child, childTm);
        joint->setDistanceJointFlag(PxDistanceJointFlag::eMAX_DISTANCE_ENABLED, true);
        joint->setDistanceJointFlag(PxDistanceJointFlag::eSPRING_ENABLED, true);
        joint->setMaxDistance(0.0f);
        joint->setStiffness(100.f);
        joint->setDamping(100.f);
    
        return joint;
    }
    

    distancealsobad

    Any idea what a fellow like myself can do to fix this?

    Thanks

    opened by alanjfs 19
  • Odd behavior with linearLimit and PxD6Joint

    Odd behavior with linearLimit and PxD6Joint

    Hi all,

    I'm looking at an odd result I can't make sense out of.

    oddmuscle

    I've simplified the setup with a minimal amount of moving parts.

    Which, as you can see, there are a total of 3 rigid bodies and 2 constraints.

    1. Two kinematic rigids for the upper and lower arm
    2. One dynamic rigid for the "muscle"
    3. Two constraints pulling it in either direction, towards the muscle attachment points on both arm rigids

    I'll attach a PVD session file here as well, where you can inspect the attributes more closely.

    madmuscle.zip

    What I'm expecting to see, is for these two constraints to pull the muscle in a straight line towards the end points. But instead, it somehow gets mad amounts of angular force applied to it as the lower arm moves. Why? What's happening?

    opened by alanjfs 15
  • Crash in PxsNphaseImplementationContext::unregisterContactManager method.

    Crash in PxsNphaseImplementationContext::unregisterContactManager method.

    Visual studio debugger console output:

    "Exception thrown: read access violation. cm was nullptr."

    Autos output:

    •   cm	0x0000000000000000 <NULL>	physx::PxsContactManager *
      
    •   this	0x0000022da9505fa0 {mRemovedContactManagers={mData=0x0000000000000000 {???} mSize=0 mCapacity=0 } mNarrowPhasePairs=...}	physx::PxsNphaseImplementationContext *
      
    •   physx::PxvNphaseImplementationContextUsableAsFallback	{...}	physx::PxvNphaseImplementationContextUsableAsFallback
      
    •   mRemovedContactManagers	{mData=0x0000000000000000 {???} mSize=0 mCapacity=0 }	physx::shdfnd::Array<unsigned int,physx::shdfnd::NamedAllocator>
      
    •   mNarrowPhasePairs	{mOutputContactManagers={mData=0x0000022db38209a0 {contactPatches=0x0000022e2d271120 "" contactPoints=...} ...} ...}	physx::PxsContactManagers
      
    •   mNewNarrowPhasePairs	{mOutputContactManagers={mData=0x0000022e2ca80000 {contactPatches=0x0000000000000000 <NULL> contactPoints=...} ...} ...}	physx::PxsContactManagers
      
    •   mModifyCallback	0x0000000000000000 <NULL>	physx::PxContactModifyCallback *
      
    •   mIslandSim	0x0000022dc6042b40 {mIslandHandles={mFreeHandles={mData=0x0000022ee403ac80 {1162} mSize=1257 mCapacity=...} ...} ...}	physx::IG::IslandSim *
      

    Call Stack:

    PhysX_64.dll!physx::PxsNphaseImplementationContext::unregisterContactManager(physx::PxsContactManager * cm) Line 691 C++ PhysX_64.dll!physx::Sc::Scene::finishBroadPhaseStage2(const unsigned int ccdPass) Line 6074 C++ PhysX_64.dll!physx::Sc::Scene::updateCCDSinglePassStage3(physx::PxBaseTask * continuation) Line 3125 C++ PhysX_64.dll!physx::Cm::Task::run() Line 67 C++ CarbonEditor.exe!physx::Ext::CpuWorkerThread::execute() Line 97 C++ PhysXFoundation_64.dll!physx::shdfnd::`anonymous namespace'::PxThreadStart(void * arg) Line 101 C++ kernel32.dll!BaseThreadInitThunk() Unknown ntdll.dll!RtlUserThreadStart() Unknown

    opened by lbrysh 14
  • D6 joints jitter on ragdoll

    D6 joints jitter on ragdoll

    Hello.

    We have ragdoll implementation using D6 joints with soft limits [All linear limits are locked, some angular limits are locked others are limited to some degree]. It works fine on high fps, simulation rate. Sadly it doesn't work well on low fps(20-30) and low simulation rate(~30). Joints produce jitter. [We use PGS in the project but switching to TGS didn't help]

    On the other hand there is no such issues on fps and simulation rate around 100. Expamle: ezgif-4-a8254f77fc23

    So what I tried:

    1. enabled projection for joints (didn't help)
    2. tweaked max depenetration vel, contact/rest offset (didn't help)
    3. relaxes joints limits (didn't help)
    4. tweaked mass of the bodies. this helped in most cases but ragdoll was looking not physically/visually correct. Artists didn't agree to this solution.
    5. increased solver iteration count (didn't help)

    I tried to make use of PVD but wasn't able to collect all the necessary information about joint. What I was able to collect you can find in the link below(.pxd2): https://drive.google.com/file/d/1SC5bFUe-6WemCRKsqEG8vfZUbovOPZnb/view?usp=sharing

    Also I gave it a try to debug PhysX code but it appears to be pretty complicated part of code related to constraints/contacts, so I gave up on this for now. If you can point me to spots in code where I can start digging would be just awesome.

    Based on what I've tried and what I've seen, my guess that joint's limits can't be solved by a solver that's why bodies remains awaken for a while trying to solve the constraints. But for some reasons we can't observe such behavior on the higher simulation rate. maybe there is some clamping for say impulses that on higher simulation dt clamp necessary impulse to push other bodies and fulfill the constraint. Nevertheless I wasn't able to find anything like that.

    Any advice is highly appreciated!

    opened by Esentiel 13
  • TGS and gaps between PxD6Joints

    TGS and gaps between PxD6Joints

    Hello PhysX team!

    I've had a problem for many moons whereby any gap between two rigid bodies connected by a PxD6Joint (or any joint, it seems) would cause severe jitter in my simulations.

    https://user-images.githubusercontent.com/47274066/155728339-fb135657-2d32-4ef6-ba60-5ba95d6653fb.mp4

    The problem is worsened with thinner radii and greater differences in mass. Except when using PGS, at which point there seems to be no limit to how thin or short things can get.

    PGS

    https://user-images.githubusercontent.com/47274066/155728632-73b38d0c-7943-40a6-bc21-b3f2304d7d1c.mp4

    I've managed to reproduce the problem using only these capsule, but the problem is much worse in more complex setups and much less obvious that gaps are to blame. Here are a few PVDs to illustrate things.

    | PVD | Description |:-----|:----- | gaps_1_sphere.zip | Largest possible gap, a sphere |gaps_2_capsule.zip | Slightly less of a gap, with a short capsule | gaps_3_mass1.zip | Less gap, with with a constant mass of 1 for each rigid body | gaps_4_pgs.zip | PGS, works in any scenario.

    I really enjoy TGS for it's strong drives and would much prefer to keep using it, but these jitters make the choice less easy. :( It's taken a while to get it to happen on such a small scale, and next time it happens in a more complex scenario I'll try and upload the PVD for it as well. In case there are two separate issues hiding underneath.

    Any idea of what to do about this?

    opened by alanjfs 12
  • Sweep normals on edges

    Sweep normals on edges

    Hi. I have noticed, that if geometry (in my case a capsule) hits an edge during scene sweep, the blocking hit normal seems to be a product of some sort of interpolation between the normals of faces that form given edge. So my questions are:

    1. Is there a way to get actual normals of both surfaces without doing additional queries?
    2. If not is there a reliable way to get those normals with additional queries? I tried doing raycasts with small offsets from original hit point but this approach feels... shaky.

    Context: I perform a downwards sweep in order to detect floor surface. So when hitting edge, I would like to check both surfaces to see, which one is closer to horizontal plane. Basically I am looking for a way to reliably get floor normal (blue) instead of edge "normal" (red): image

    opened by nikita-one 12
  • License incompatibility of PhysX' BSD and FleX' Gameworks license

    License incompatibility of PhysX' BSD and FleX' Gameworks license

    To my understanding, we can't use PhysX-4.0 together with FleX because PhysX is now distributed under the 3-Clause BSD license which forbids the usage of the name NVIDIA without written consent. This is the exact opposite of the NVIDIA GAMEWORKS license as it requires detailed attribution to NVIDIA in section 6.

    Is there any recommendation on how to deal with that? I am quite certain you don't want to allow the usage of NVIDIA's name individually? Or ... can you tell if there are any plans for FleX becoming available under BSD license?

    opened by thebrandre 11
  • Pushing bodies at specific positions - torque vs velocity (extensions)

    Pushing bodies at specific positions - torque vs velocity (extensions)

    While looking at the extensions method to apply forces to a body at a specific position, it looks like the routine doesn't apply velocity the way one would expect. I'm the furthest thing you can imagine from a physics expert, but I believe the point at which you push an object determines how far it moves, right? For example, if I push an object into the air from the very edge, it will spin around, but won't go very high. Whereas if I push it up from its very center point, it won't spin much, and will travel much further up. The point of contact determines how much of the force is converted to torque, and how much remains velocity.

    It doesn't look like the dynamic body extension method applies velocity this way:

    const PxTransform globalPose = body.getGlobalPose();
    const PxVec3 centerOfMass = globalPose.transform(body.getCMassLocalPose().p);
    
    const PxVec3 torque = (pos - centerOfMass).cross(force);
    body.addForce(force, mode, wakeup);
    body.addTorque(torque, mode, wakeup);
    

    Unless I'm mistaken, it seems to convert force into torque correctly, but it leaves all of the force in the resulting velocity, which makes objects travel the same distance, regardless of the contact point.

    Am I misunderstanding the code? Or is there perhaps a more advanced version of this method? Am I correct in assuming that we can just measure how much torque is being applied, then dot-product-scale that from the force? Or does that have some strange side effect that is difficult to overcome, and it was simplified as a result?

    Thanks for any information!

    Edit: I've found source code for similar functions for three different projects, and all of them do it this same way. So either everyone is doing it wrong, or I'm missing something obvious, and I would sooner believe the latter. But if anyone can point me to what it is I'm missing, that would be great. Maybe this has something to do with the length of time the force is being applied? IE, if pushing an object from the very edge, the amount of time we push on it decreases as compared to pushing it in the center? I realize this question is turning more into a physics lesson, but I still appreciate any assistance understanding this.

    opened by RobertMtx 10
  • Cannot find procdeure entry point in VS2022 when call PxCreatePvd

    Cannot find procdeure entry point in VS2022 when call PxCreatePvd

    I used vc to build PhysX for vc17 by https://github.com/NVIDIAGameWorks/PhysX/issues/599#issue-1360999091 then I can build my own projects and include all headers and libraries. But I can't call PxCreatePvd() Fuction.

    Here're my codes

    PxDefaultAllocator		m_Allocator;
    PxDefaultErrorCallback	m_ErrorCallback;
    PxFoundation* m_pFoundation;
    m_pFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, m_Allocator, m_ErrorCallback);
    m_pPVD =  PxCreatePvd(*m_pFoundation);
    

    *it works well in release mode.

    opened by ChrisOyj 0
  • Discrepancy in SDK Guide and API reference about completion tasks

    Discrepancy in SDK Guide and API reference about completion tasks

    The SDK Guide says:

    A completion task is a task that executes immediately after PxScene::simulate has exited. If PhysX has been configured to use worker threads then PxScene::simulate will start simulation tasks on the worker threads and will likely exit before the worker threads have completed the work necessary to complete the scene update. […] As a consequence, a typical completion task would first need to call PxScene::fetchResults(true) to ensure that fetchResults blocks until all worker threads started during simulate() have completed their work.

    I.e. the completion task is submitted just before simulate returns. (This would also mean that completion tasks are a redundant feature, as the caller could just submit the task themselves after simulate returns.)


    The API reference says:

    if non-NULL, this task will have its refcount incremented in simulate(), then decremented when the scene is ready to have fetchResults called. So the task will not run until the application also calls removeReference().

    I.e. the completion task is not submitted before all the simulation tasks have finished. (This behavior seems actually useful, as it permits asynchronous use of the API without any blocking.)


    It seems to me that the SDK Guide and the API reference disagree about when completion tasks are submitted. I guess the API reference here is correct?

    opened by chloekek 2
  • PxRigidDynamic::setKinematicSurfaceVelocity() is missing

    PxRigidDynamic::setKinematicSurfaceVelocity() is missing

    PxRigidDynamic::setKinematicSurfaceVelocity() is described in the Physx 4.1 documentation but is missing in the sources.

    I would need the method to instant move a kinematic body and have correct velocities reported for that frame. (so PxRigidDynamic::setGlobalPose + PxRigidDynamic::setKinematicSurfaceVelocity()).

    I currently use PxRigidDynamic::setKinematicSurfaceVelocity but this introduces a one frame delay in comparison to PxRigidDynamic::setGlobalPose.

    opened by fredUmlaut 0
  • Incorrect sweep hit distance

    Incorrect sweep hit distance

    I'm using PhysX 4.1.2.29882248.

    When calling PxScene::sweep, the returned distance in PxSweepBuffer::distance seems to be systematically off by a small amount. That amount is deterministic, it seems to be related to the size of the objects at play.

    I'm passing PxHitFlag::eDEFAULT and a null inflation (the default value for the parameter). I have also tried setting contactOffset on all shapes to be 1e-10, but it did not change the result.

    Here is an example. Take a scene with two cubes, whose centers are located at (0, 10, 0) and (0, 15, 0). The two cubes have the same dimensions: between (-1, -1, -1) and (1, 1, 1), that is to say cubes centered on the origin and with a side length of 2.

    I'm sweeping the cube at (0, 15, 0) downwards, with the direction (0, -1, 0). I would thus expect a hit distance of exactly 3.

    However, the distance returned by PhysX is 2.9975. Consistently. It's not dramatically off, but since it's very consistent across scenes and parameters, I wonder if there is something to be done about it to be more precise.

    The code looks like that:

    const PxQueryFilterData filter( PxQueryFlag::eSTATIC );
    bool has_hit = scene->sweep( convex_mesh, shape_pose, direction, max_distance, hit, PxHitFlag::eDEFAULT, filter );
    if ( has_hit ) {
        max_distance = hit.getAnyHit( 0 ).distance;
    }
    

    The input to the sweep method is a dynamic convex mesh, while the rest of the scene is composed of static triangle meshes.

    When running the code above with the two cubes, the only contact is in (0, 11, 0.5). Could it possibly explain the distance?

    The doc does say that it should be between the centers that the distance is computed: image

    And the numbers don't match anyway. I'm just asking in case there's a lead to follow there.

    I have seen in PhysX's source code a parameter that could potentially explain that offset, though the numbers do not exactly match: SQ_PRUNER_INFLATION. It seems no matter the inflation parameter, there is a fixed amount of inflation being applied to the extents of the object. Could that be the source of the offset?

    Note: PxHitFlag::ePRECISE_SWEEP did not help. It does not change the resulting distance.

    Do you know if there is something to be done about that offset, in order to get more precise sweep results?

    opened by fkorsa 0
  • Shape insertion order affects contact target velocity

    Shape insertion order affects contact target velocity

    When trying to simulate a conveyor belt by using the contact modification callback and PxContactsSet::setTargetVelocity, under very specific circumstances it is possible that a dynamic actor that sits on top of the 'conveyor' moves in the opposite direction, specified in setTargetVelocity.

    A standalone code snippet is added below. I tried to make it as comprehensible as possible, yet it is still rather large. The example sets up contact modification for a kinematic actor (our 'conveyor') with a constant target velocity in the positive x direction. We then perform the following steps before the simulation runs:

    1. A simple dynamic actor A (consisting only of a single shape) and a conveyor C (in this order) get added to the scene.
    2. Run the simulation. A will begin moving in the positive x direction, as expected.
    3. After a short time, we remove A from the scene.
    4. Add a new dynamic actor B to the scene. This time however, the actor will consist of more than just one shape. It now moves into the negative x direction.

    Some details are important to reliably reproduce the bug:

    1. The first dynamic actor must only consist of a SINGLE shape while the second dynamic actor must consist of MORE THAN ONE shape.
    2. The first dynamic actor must be added to the scene BEFORE the conveyor.
    3. The first dynamic actor must be removed from the scene while it is still moving on the conveyor. If it drops off the conveyor before being removed, the bug will not happen.

    PhysX build settings: vc16win64.xml | build static lib | use dynamic WINCRT lib | Precise math: false PhysX 4.1 Commit: c3d5537bdebd6f5cd82fcaf87474b838fe6fd5fa Visual Studio 2019 v142 C++ 14

    The code snippet below has no dependencies other than PhysX. PVD must be running.

    #include "PxPhysicsAPI.h"
    
    using namespace physx;
    
    class PhysicsCallbacks : public PxContactModifyCallback
    {
      virtual void onContactModify(PxContactModifyPair* const pairs, PxU32 count)
      {
        for (PxU32 i = 0; i < count; i++) {
          PxContactModifyPair& pair = pairs[i];
          for (PxU32 j = 0; j < pair.contacts.size(); j++) {
            //We set a constant target velocity for every contact that requests contact modification
            pair.contacts.setTargetVelocity(j, PxVec3(0.5f, 0, 0));
          }
        }
      }
    };
    
    PxFilterFlags SimulationFilterShader(
      PxFilterObjectAttributes attributes0, PxFilterData filterData0,
      PxFilterObjectAttributes attributes1, PxFilterData filterData1,
      PxPairFlags& pairFlags, const void*, PxU32)
    {
      pairFlags |= PxPairFlag::eCONTACT_DEFAULT;
    
      //we store 'true' in word0 to indicate that this shape has a surface velocity
      if (filterData0.word0 || filterData1.word0)
        pairFlags |= PxPairFlag::eMODIFY_CONTACTS;
    
      return PxFilterFlag::eDEFAULT;
    }
    
    struct Shape
    {
      float HalfX = 0;
      float HalfY = 0;
      float HalfZ = 0;
    
      float PosX = 0;
      float PosY = 0;
      float PosZ = 0;
    };
    
    PxRigidDynamic* CreateActor(PxPhysics* ph, const PxMaterial* material, float yOffset, Shape* shapes, size_t numShapes, bool kinematic, bool surfaceVel)
    {
      PxRigidDynamic* dyn = ph->createRigidDynamic(PxTransform(PxVec3(0, yOffset, 0)));
      dyn->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, kinematic);
    
      for (size_t i = 0; i < numShapes; i++) {
        auto& shape = shapes[i];
    
        auto pxShape = ph->createShape(PxBoxGeometry(shape.HalfX, shape.HalfY, shape.HalfZ), *material, true);
        pxShape->setLocalPose(PxTransform(PxVec3(shape.PosX, shape.PosY, shape.PosZ)));
        PxFilterData filter{};
        filter.word0 = surfaceVel;
        pxShape->setSimulationFilterData(filter);
        dyn->attachShape(*pxShape);
        pxShape->release();
      }
    
      PxRigidBodyExt::setMassAndUpdateInertia(*dyn, 5.0f);
      return dyn;
    }
    
    int main()
    {
      //Initialize the SDK. Mostly default values, nothing fancy
      PxDefaultErrorCallback errCb;
      PxDefaultAllocator defaultAlloc;
      auto foundation = PxCreateFoundation(PX_PHYSICS_VERSION, defaultAlloc, errCb);
    
      auto pvd = PxCreatePvd(*foundation);
      auto transport = PxDefaultPvdSocketTransportCreate("127.0.0.1", 5425, 1500);
      pvd->connect(*transport, PxPvdInstrumentationFlag::eALL);
    
      auto physics = PxCreateBasePhysics(PX_PHYSICS_VERSION, *foundation, PxTolerancesScale(), false, pvd);
      auto pxMaterial = physics->createMaterial(0.4f, 0.4f, 0.8f);
    
      //Create a scene. Same as before, mostly default values.
      //Except for our FilterShader and contact modification callback
      PxSceneDesc sceneDesc = PxSceneDesc(physics->getTolerancesScale());
      sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
      sceneDesc.cpuDispatcher = PxDefaultCpuDispatcherCreate(0);
      sceneDesc.filterShader = SimulationFilterShader;
      sceneDesc.contactModifyCallback = new PhysicsCallbacks();
    
      auto scene = physics->createScene(sceneDesc);
    
      //Create some simple shapes to be used by CreateActor
      Shape conveyorShapes  [] = { { /*HalfSize*/ 2.5f, 0.5f, 0.5f, /*Pos*/ 0.0f, 0, 0 } };
      Shape simpleDynShapes [] = { { /*HalfSize*/ 0.5f, 0.5f, 0.5f, /*Pos*/ 0.0f, 0, 0 } };
      Shape complexDynShapes[] = 
      { 
        { /*HalfSize*/ 0.5f, 0.2f, 0.5f, /*Pos*/ 0,  0.3f, 0 },
        { /*HalfSize*/ 0.5f, 0.2f, 0.5f, /*Pos*/ 0, -0.3f, 0 },
      };
    
      auto conveyor   = CreateActor(physics, pxMaterial, 0.0f, conveyorShapes  , 1, true, true);
      auto simpleDyn  = CreateActor(physics, pxMaterial, 1.0f, simpleDynShapes , 1, false, false);
      auto complexDyn = CreateActor(physics, pxMaterial, 1.0f, complexDynShapes, 2, false, false);
    
      //Several conditions (X) must be true to reproduce the bug.
      //(1) A dynamic actor (simpleDyn) that only consists of a single shape (!) gets added to the scene BEFORE the conveyor.
      const bool SHOW_BUGGY_BEHAVIOUR = true;
      if (SHOW_BUGGY_BEHAVIOUR) {
        //The bug only happens if the dynamic actor gets added to the scene BEFORE the conveyor.
        //(Creation order aka the order of calls to CreateActor above does not seem to affect it).
        scene->addActor(*simpleDyn);
        scene->addActor(*conveyor);
      }
      else {
        //If the conveyor gets added before the dynamic, everything works as expected
        scene->addActor(*conveyor);
        scene->addActor(*simpleDyn);
    
        //In addition, if we replace simpleDyn with complexDyn, the bug also does not reproduce
        //scene->addActor(*conveyor);
        //scene->addActor(*complexDyn);
      }
    
      size_t frameCount = 0;
      while (true) {
        scene->simulate(0.033f);
        scene->fetchResults(true);
        
        //(2) The simple dynamic actor (single shape only) gets removed.
        //IMPORTANT: This has to happen before the actor falls off the conveyor!
        if (frameCount == 20) {
          simpleDyn->release();
        }
    
        //(3) After the simple dynamic actor got removed, a new actor that consists of MORE THAN ONE shape
        //gets added to the scene.
        //Despite a target velocity of +0.5 on the x axis, the actor will now move in the negative x direction
        if (frameCount == 21) {
          scene->addActor(*complexDyn);
        }
    
        if (frameCount > 60) {
          break;
        }
        frameCount++;
      }
    
      return 0;
    }
    

    My knowledge of physics engines is VERY limited. However I have been trying for a while to debug the PhysX SDK to find the issue. I obviously could not fix the issue but there are some things I have noticed. I will add them here, in case it might help.

    1. When solving the contacts for actor B, solveContactBlock gets chosen from gVTableSolveBlock but ONLY in the reproduction case. When e.g. using a multi shape actor for actor A AND B, other solver functions get used.
    2. solveContactBlock then calls solveContact where the 'flipping' of the velocity sign seems to take place. Specifically when linVel1 gets calculated. deltaF is a positive value, which (at least intuitively) makes sense. However the result of the calculation
    linVel1 = V3NegScaleSub(delLinVel1, deltaF, linVel1);
    

    causes linVel1 to become negative which seems to produce the negative velocity (?)

    opened by alektron 0
  • Merged / separated trimesh, which is better for collision detection?

    Merged / separated trimesh, which is better for collision detection?

    In game dev, visible trimeshes are often merged to reduce drawCall, which leads to huge AABBs for collision detection. We are wondering if those meshes are separated, the collision detection can be faster?

    I have done a test that 168 convexes move along a straight racing line, with merged / separated trimesh as roads and fences. The result shows that the performances have no difference. (But if the convexes are not aligned with roads and fences, the simulation consumption increases 0.22ms. since midphase has easier codes to transverse AABB rather than OBB).

    image

    opened by pkusilence 0
Releases(4.0.0)
Owner
NVIDIA GameWorks
NVIDIA Technologies for game and application developers
NVIDIA GameWorks
Gstreamer plugin that allows use of NVIDIA Maxine SDK in a generic pipeline.

GST-NVMAXINE Gstreamer plugin that allows use of NVIDIA MaxineTM sdk in a generic pipeline. This plugin is intended for use with NVIDIA hardware. Visi

Alex Pitrolo 15 Aug 30, 2022
NVIDIA Image Scaling SDK

NVIDIA Image Scaling SDK v1.0 The MIT License(MIT) Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. Permission is hereby grante

NVIDIA GameWorks 384 Nov 14, 2022
GPU Cloth TOP in TouchDesigner using CUDA-enabled NVIDIA Flex

This project demonstrates how to use NVIDIA FleX for GPU cloth simulation in a TouchDesigner Custom Operator. It also shows how to render dynamic meshes from the texture data using custom PBR GLSL material shaders inside TouchDesigner.

Vinícius Ginja 37 Jul 27, 2022
Forward - A library for high performance deep learning inference on NVIDIA GPUs

a library for high performance deep learning inference on NVIDIA GPUs.

Tencent 123 Mar 17, 2021
A library for high performance deep learning inference on NVIDIA GPUs.

Forward - A library for high performance deep learning inference on NVIDIA GPUs Forward - A library for high performance deep learning inference on NV

Tencent 508 Nov 15, 2022
GPU ray tracing framework using NVIDIA OptiX 7

GPU ray tracing framework using NVIDIA OptiX 7

Shunji Kiuchi 26 Oct 25, 2022
ROS2 packages based on NVIDIA libArgus library for hardware-accelerated CSI camera support.

Isaac ROS Argus Camera This repository provides monocular and stereo nodes that enable ROS developers to use cameras connected to Jetson platforms ove

NVIDIA Isaac ROS 34 Nov 21, 2022
Hardware-accelerated DNN model inference ROS2 packages using NVIDIA Triton/TensorRT for both Jetson and x86_64 with CUDA-capable GPU.

Isaac ROS DNN Inference Overview This repository provides two NVIDIA GPU-accelerated ROS2 nodes that perform deep learning inference using custom mode

NVIDIA Isaac ROS 52 Nov 24, 2022
Visual odometry package based on hardware-accelerated NVIDIA Elbrus library with world class quality and performance.

Isaac ROS Visual Odometry This repository provides a ROS2 package that estimates stereo visual inertial odometry using the Isaac Elbrus GPU-accelerate

NVIDIA Isaac ROS 296 Nov 16, 2022
The core engine forked from NVidia's Q2RTX. Heavily modified and extended to allow for a nicer experience all-round.

Nail & Crescent - Development Branch Scratchpad - Things to do or not forget: Items are obviously broken. Physics.cpp needs more work, revising. Proba

PalmliX Studio 19 Nov 22, 2022
Docker files and scripts to setup and run VINS-FUSION-gpu on NVIDIA jetson boards inside a docker container.

jetson_vins_fusion_docker This repository provides Docker files and scripts to easily setup and run VINS-FUSION-gpu on NVIDIA jetson boards inside a d

Mohamed Abdelkader Zahana 20 Oct 12, 2022
NVIDIA Texture Tools samples for compression, image processing, and decompression.

NVTT 3 Samples This repository contains a number of samples showing how to use NVTT 3, a GPU-accelerated texture compression and image processing libr

NVIDIA DesignWorks Samples 33 Nov 16, 2022
Golang bindings for Nvidia Datacenter GPU Manager (DCGM)

Bindings Golang bindings are provided for NVIDIA Data Center GPU Manager (DCGM). DCGM is a set of tools for managing and monitoring NVIDIA GPUs in clu

NVIDIA Corporation 37 Nov 8, 2022
Vendor and game agnostic latency reduction middleware. An alternative to NVIDIA Reflex.

LatencyFleX (LFX) Vendor and game agnostic latency reduction middleware. An alternative to NVIDIA Reflex. Why LatencyFleX? There is a phenomenon commo

Tatsuyuki Ishi 540 Nov 18, 2022
TensorRT is a C++ library for high performance inference on NVIDIA GPUs and deep learning accelerators.

TensorRT Open Source Software This repository contains the Open Source Software (OSS) components of NVIDIA TensorRT. Included are the sources for Tens

NVIDIA Corporation 6.2k Nov 23, 2022
Dataset Synthesizer - NVIDIA Deep learning Dataset Synthesizer (NDDS)

NVIDIA Deep learning Dataset Synthesizer (NDDS) Overview NDDS is a UE4 plugin from NVIDIA to empower computer vision researchers to export high-qualit

NVIDIA Corporation 508 Nov 22, 2022
waifu2x converter ncnn version, runs fast on intel / amd / nvidia GPU with vulkan

waifu2x ncnn Vulkan ncnn implementation of waifu2x converter. Runs fast on Intel / AMD / Nvidia with Vulkan API. waifu2x-ncnn-vulkan uses ncnn project

null 2.4k Nov 24, 2022
NVIDIA GPUs htop like monitoring tool

NVTOP What is NVTOP? Nvtop stands for NVidia TOP, a (h)top like task monitor for NVIDIA GPUs. It can handle multiple GPUs and print information about

Maxime Schmitt 4.4k Nov 18, 2022