Problem - creating joint between two objects in collision

Hello,

When I create a PxFixedJoint between two PxRigidBodies A and B that are colliding, B moves to its new anchored position but with a crazy rotation.

I could upload a minimal code if you need. I already did it; and clearly separating A and B solves the issue.

My current solution is not… “sexy”: put both A and B in the same CollisionGroup, wait a cycle, do create the PxFixedJoint.

Do you have a better solution?

(I tried setLinearVelocity(null), setAngularVelocity(null), clearForce(), clearTorque(), …)

Lokfry

After testing my minimal code, it clearly seems a bug in PhysX’s code itself.

When I create my fixed joint, I also set the collision off between A and B.

“joint->setConstraintFlag( PxConstraintFlag::eCOLLISION_ENABLED, false );”

But it seems this function breaks something in simulation filter data; just re-assigning the same filter data does resolve the bug.

My workaround:

std::vector<PxFilterData>   getFilterData( PxRigidActor* actor )
      {
          std::vector<PxShape*>   shapes(actor->getNbShapes(), nullptr);
          std::vector<PxFilterData>   out(shapes.size());
  
          actor->getShapes(&shapes[0], shapes.size());
          for (int i = 0; i < shapes.size(); ++i)
              out[i] = shapes[i]->getSimulationFilterData();
  
          return out;
      }
  
      void                        setFilterData( PxRigidActor* actor,
             const std::vector<PxFilterData>& filterData )
      {
          std::vector<PxShape*>   shapes(actor->getNbShapes(), nullptr);
  
          actor->getShapes(&shapes[0], shapes.size());
          for (int i = 0; i < shapes.size(); ++i)
              shapes[i]->setSimulationFilterData(filterData[i]);
      }

When assigning:

std::vector<PxFilterData> fd = getFilterData(actor);
joint->setConstraintFlag( PxConstraintFlag::eCOLLISION_ENABLED, false );
setFilterData(actor, fd);

I could investigate, find, solve this bug (it seems the internal buffer in ScbShape is corrupted) instead of using my workaround, and send a pull request on your github project. However I am not sure you are active (many pull requests are still waiting)

Lokfry

This definitely doesn’t seem right. It also seems very strange because, what you’re suggesting is that a data member in the shape class is being stomped when you set a flag on the constraint, which should not have any influence on the shape.

Could you confirm which version of PhysX you are using? I can try to make a repro locally but I don’t have a lot of confidence that I’ll be able to repro this issue.

You mention “the internal buffer in ScbShape is corrupted”. Does that mean you are overlapping setting these values with simulation so that it’s hitting the buffering cases?

Hi, thanks for your reply!

First I am not sure at all about my “the internal buffer in ScbShape is corrupted”. I didn’t dig into physx’s code, I don’t know how it works.

Because the simulation filter data where exactly the same before and after the call to “setConstraintFlag” (I displayed each bit), I wanted to know where these data were stored and I found the mentioned buffer in ScbShape. And this buffer seems shared. So I did a quick supposition that someone was misreading/mis-writing into this buffer.

I just uploaded my minimal code project if you need:

(just have to change the link to PhysX in the CMakeLists.txt)
There are also two screenshots showing what happens when the workaround is on/off.

My version is: PhysX 3.3(.4)
It comes from the ‘master’ branch, last commit is:

commit 3aeffc35b32ce175b7d19b1bace53ad9d8f84242
Author: sschirm <sschirm@nvidia.com>
Date:   Thu Feb 11 18:09:48 2016 +0100

I did the following modifications in order to compile:

lokfry ~/Projects/echoes/extlibs/PhysX-3.3$ git diff
diff --git a/PhysXSDK/Include/foundation/unix/PxUnixIntrinsics.h b/PhysXSDK/Include/foundation/unix/PxUnixIntrinsics.h
index 5b95710..f3f0c0a 100644
--- a/PhysXSDK/Include/foundation/unix/PxUnixIntrinsics.h
+++ b/PhysXSDK/Include/foundation/unix/PxUnixIntrinsics.h
@@ -21,8 +21,10 @@
        #error "This file should only be included by Unix builds!!"
 #endif
 
-#include <math.h>
-#include <float.h>
+#include <cmath>
+#include <cfloat>
+//#include <math.h>
+//#include <float.h>
 
 namespace physx
 {
@@ -72,13 +74,13 @@ namespace physx
        //! \brief platform-specific finiteness check (not INF or NAN)
        PX_FORCE_INLINE bool isFinite(float a)
        {
-               return isfinite(a);
+               return std::isfinite(a);
        }
 
        //! \brief platform-specific finiteness check (not INF or NAN)
        PX_FORCE_INLINE bool isFinite(double a)
        {
-               return isfinite(a);
+               return std::isfinite(a);
        }
 
        /*!
diff --git a/PhysXSDK/Source/SimulationController/src/ScScene.cpp b/PhysXSDK/Source/SimulationController/src/ScScene.cpp
index b1cbf85..2063b5c 100644
--- a/PhysXSDK/Source/SimulationController/src/ScScene.cpp
+++ b/PhysXSDK/Source/SimulationController/src/ScScene.cpp
@@ -3419,7 +3419,7 @@ PX_FORCE_INLINE void buildActiveTransform(Sc::Actor*const PX_RESTRICT activeActo
        PX_ASSERT(activeActor->isDynamicRigid());
        
        Sc::BodySim* body = static_cast<Sc::BodySim*>(activeActor);
-       if(!body->getBodyCore().getCore().mInternalFlags & PxsRigidCore::eFROZEN)
+       if(!(body->getBodyCore().getCore().mInternalFlags & PxsRigidCore::eFROZEN))
        {
                PxRigidActor* ra = static_cast<PxRigidActor*>(body->getPxActor());
                PX_ASSERT(ra != NULL);

My compiler (clang++) was complaining about:

lokfry ~/Projects/echoes/extlibs/PhysX-3.3/PhysXSDK/Source/compiler/linux64$ make
SimulationController: compiling checked ./../../SimulationController/src/ScScene.cpp...
./../../SimulationController/src/ScScene.cpp: In function ‘void buildActiveTransform(physx::Sc::Actor*, physx::Sc::Client**, physx::PxU32)’:
./../../SimulationController/src/ScScene.cpp:3422:36: error: suggest parentheses around operand of ‘!’ or change ‘&’ to ‘&&’ or ‘!’ to ‘~’ [-Werror=parentheses]
  if(!body->getBodyCore().getCore().mInternalFlags & PxsRigidCore::eFROZEN)
                                    ^
cc1plus: all warnings being treated as errors
Makefile.SimulationController.mk:286: recipe for target 'build/SimulationController_checked/SimulationController/src/ScScene.cpp.o' failed
make: *** [build/SimulationController_checked/SimulationController/src/ScScene.cpp.o] Error 1

By the way,

lokfry ~/Projects/echoes/lab/bug_mcjointcoll/git/bug_mcjointcoll$ uname --all
Linux Farore 4.4.0-78-generic #99-Ubuntu SMP Thu Apr 27 15:29:09 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

 lokfry ~/Projects/echoes/lab/bug_mcjointcoll/git/bug_mcjointcoll$ clang++ -v
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/i686-linux-gnu/6.0.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/6.0.0
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/6.0.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.0.0
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0
Candidate multilib: .;@m64
Selected multilib: .;@m64

We tried to make a repro out of this and failed to reproduce the issue. We tried both PhysX 3.3 and 3.4 and, in both cases, there was no failure. We attempted to repro on Windows 10 64-bit using VS2015 x64. We didn’t include your rendering code but everything else was a straight copy.

What’s strange is that PxConstraintFlag::eCOLLISION_ENABLED is disabled by default so there should not have been a need to disable this flag to make the pair stop colliding.

Hi,
I see that you use clang to compile the PhysX SDK, is that correct?
Could you please try these clang flags for compilation to see if it fixes the issue you see:
-std=c++11 -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -Werror -ferror-limit=0 -Wall -Wextra -fstrict-aliasing -Wstrict-aliasing=2 -Weverything -Wno-documentation-deprecated-sync -Wno-documentation-unknown-command -Wno-float-equal -Wno-padded -Wno-weak-vtables -Wno-cast-align -Wno-conversion -Wno-missing-noreturn -Wno-missing-variable-declarations -Wno-shift-sign-overflow -Wno-covered-switch-default -Wno-exit-time-destructors -Wno-global-constructors -Wno-missing-prototypes -Wno-unreachable-code -Wno-unused-macros -Wno-unused-member-function -Wno-used-but-marked-unused -Wno-weak-template-vtables -Wno-deprecated -Wno-non-virtual-dtor -Wno-invalid-noreturn -Wno-return-type-c-linkage -Wno-reserved-id-macro -Wno-c++98-compat-pedantic -Wno-unused-local-typedef -Wno-old-style-cast -Wno-newline-eof -Wno-unused-private-field -Wno-undefined-func-template -Wno-format-nonliteral -Wno-implicit-fallthrough -Wno-undefined-reinterpret-cast -Wno-disabled-macro-expansion

These should work with clang 3.9 hopefully, except the compilation issue you see, that has been already fixed internally, but we did not release 3.3.5 yet unfortunately. We will try to release 3.3.5 asap.

Currently 3.3 does not support clang compilation, we have clang support with 3.4 and these settings seems to work for it. Please could you give it a try?
Thanks,
regards
Ales

Yes, I did use clang for the PhysXSDK too.
(EDIT: no PhysX SDK was compiled with g++, and my project with clang – my bad!)

Okay I will able to test this in approx 2 hours. If it doesn’t work I will test it also on Win 10 64-bit - VS2015 (just to confirm it’s clang).

Many thanks!

Hi,

Ok, true. I didn’t know it was the default behavior. Last time, when reducing the code, I ended up to surround this setConstraintFlag() with my getFilterData/setFilterData – it fixed my problem – I wrongly supposed it was because of this.

I commented this line and the behavior is the same: same problem without my dirty ‘fix’.

std::vector<PxFilterData> fd = getFilterData(actor);
//joint->setConstraintFlag( PxConstraintFlag::eCOLLISION_ENABLED, false );
setFilterData(actor, fd);

(Thus I still need these dirty get/setFilterData to make it work :s)

Then I did some tests:

  • Compiling PhysX SDK and my test project with clang (I installed version 3.9) and the mentioned flags.
    Result: Failed.
    Note: I am not 100% sure of what I did, not sure if it’s correct. I commented most of original flags (for all projects)…
#PhysX_release_common_cflags  += -m64
#PhysX_release_common_cflags  += -Werror -m64 -fPIC -msse2 -mfpmath=sse -ffast-math -fno-exceptions -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden
#PhysX_release_common_cflags  += -Wall -Wextra -Wstrict-aliasing=2 -fdiagnostics-show-option
#PhysX_release_common_cflags  += -Wno-long-long
#PhysX_release_common_cflags  += -Wno-unknown-pragmas -Wno-invalid-offsetof -Wno-uninitialized -Wno-attributes -Wno-unused-local-typedefs
#PhysX_release_common_cflags  += -Wno-unused-parameter -Wno-missing-field-initializers -Wno-ignored-qualifiers
#PhysX_release_common_cflags  += -O3 -fno-strict-aliasing

…so that they are not added to the mentioned ones (+ it seems this is mainly about optimisation flags)
and added the new ones as follow:
(MakeFile)

#default defines
[...]
CCLD      =  /usr/bin/clang++-3.9
CXX       =  /usr/bin/clang++-3.9
CC        =  /usr/bin/clang-3.9
[...]
PhysX_custom_cflags     = -std=c++11 -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -Werror -ferror-limit=0 -Wall -Wextra -fstrict-aliasing -Wstrict-aliasing=2 -Weverything -Wno-documentation-deprecated-sync -Wno-documentation-unknown-command -Wno-float-equal -Wno-padded -Wno-weak-vtables -Wno-cast-align -Wno-conversion -Wno-missing-noreturn -Wno-missing-variable-declarations -Wno-shift-sign-overflow -Wno-covered-switch-default -Wno-exit-time-destructors -Wno-global-constructors -Wno-missing-prototypes -Wno-unreachable-code -Wno-unused-macros -Wno-unused-member-function -Wno-used-but-marked-unused -Wno-weak-template-vtables -Wno-deprecated -Wno-non-virtual-dtor -Wno-invalid-noreturn -Wno-return-type-c-linkage -Wno-reserved-id-macro -Wno-c++98-compat-pedantic -Wno-unused-local-typedef -Wno-old-style-cast -Wno-newline-eof -Wno-unused-private-field -Wno-undefined-func-template -Wno-format-nonliteral -Wno-implicit-fallthrough -Wno-undefined-reinterpret-cast -Wno-disabled-macro-expansion

# !!! Note I had to add these flags to make it compile !!!
PhysX_custom_cflags     += -Wno-double-promotion -Wno-comma -Wno-documentation -Wno-unknown-pragmas -Wno-unused-parameter -Wno-undef -Wno-invalid-offsetof -Wno-extended-offsetof -Wno-header-hygiene -fPIC -Wno-expansion-to-defined -Wno-switch-enum -Wno-shadow-field-in-constructor

LowLevel_custom_cflags = ${PhysX_custom_cflags}
LowLevelCloth_custom_cflags = ${PhysX_custom_cflags}
PhysXCharacterKinematic_custom_cflags = ${PhysX_custom_cflags}
PhysXCommon_custom_cflags = ${PhysX_custom_cflags}
PhysXCooking_custom_cflags = ${PhysX_custom_cflags}
PhysXExtensions_custom_cflags = ${PhysX_custom_cflags}
PhysXProfileSDK_custom_cflags = ${PhysX_custom_cflags}
PhysXVehicle_custom_cflags = ${PhysX_custom_cflags}
PhysXVisualDebuggerSDK_custom_cflags = ${PhysX_custom_cflags}
PvdRuntime_custom_cflags = ${PhysX_custom_cflags}
PxTask_custom_cflags = ${PhysX_custom_cflags}
SceneQuery_custom_cflags = ${PhysX_custom_cflags}
SimulationController_custom_cflags = ${PhysX_custom_cflags}

But more interesting:

  • Compiling PhysX SDK and my test project with GCC
    Result: Failed.
  • Compiling PhysX SDK and my test project with MSVC 2015 - Win 10, 64-bit (both Debug)
    Result: Failed.
  • Compiling PhysX SDK and my test project with MSVC 2015 - Win 10, 64-bit (both Release)
    Result: Failed.
    (I used PhysX 3.3.4 from the github repository)

In all cases it failed (with the exact same behavior – see screenshots) and I need this little tricks get/setFilterData…

Since it’s working on your side, I am a bit lost. Now I tested it on MSVC 2015, I see only few differences with your test:

  • the graphics part
  • the object behavior itself (In my case, A falls down on B, bounces, and stabilizes itself until ‘sleep’)

For the graphics part, I need to check again. I already found some errors (the biggest one was default rotation quat(0, 0, 0, 1) instead of quat(1, 0, 0, 0)) but nothing has resolved the issue. I will be available again next week, if you want I test something.

Thanks,
Lokfry