Comments (9)
Ah, that makes perfect sense now. You're telling the system that you're ok with reporting a collision if objects are actually separated by 0.01 (this is quite a high number). In this case we should have mY[0].Length() < 0.01 instead of 1.0e-4. I'll see if I can patch this up (unfortunately a different tolerance is passed to that function)
from joltphysics.
Should be fixed now!
from joltphysics.
The assert handler passes the filename and line number, so in principle you could use that to ignore certain asserts (albeit with extra work if the line numbers change).
I'd be interested in seeing why this particular assert triggers. The value is nearly 8 mm from the origin which is quite a lot. Would it be possible to isolate an example when this assert triggers? What I usually do is to go a few levels up in the call stack and copy the values from the debugger in a unit test like here:
JoltPhysics/UnitTests/Physics/CollideShapeTests.cpp
Lines 280 to 432 in 4deaf12
from joltphysics.
That's going to be a bit of work, I'll have to see when I can find the time for that.
from joltphysics.
If you paste the debugger values here then I can also create the example. I don't know your callstack so it's hard to tell you exactly which values I need, but it probably comes from CollideConvexVsTriangles::Collide in which case I need the values passed to the constructor of that class (should be a bit higher up in the callstack) + all the parameters to the Collide function and I'm going to need all the internal members of inShape1 passed to the constructor. The classes should all be opened up fully so that I can copy paste the float values with their significant digits.
from joltphysics.
Finally had some time to investigate.
So in my character code I call NarrowPhaseQuery::CollideShape()
directly to detect contacts with the surroundings. See here.
Arguments to NarrowPhaseQuery::CollideShape()
are:
inShape
is a CapsuleShape
with half height 0.00999999978
and radius 0.300000012
.
inShapeScale
is just all 1, inBaseOffset
is all 0.
inCenterOfMassTransform
is
[Row 0] 1.00000000, 0.00000000, 0.00000000, 7.33719635
[Row 1] 0.00000000, -1.19209290e-07, -1.00000012, 16.2943859
[Row 2] 0.00000000, 1.00000012, -1.19209290e-07, 0.0854607671
[Row 3] 0.00000000, 0.00000000, 0.00000000, 1.00000000
inCenterOfMassTransform
was built from a quaternion {x=0.707106829 y=0.00000000 z=0.00000000 w=0.707106829}
and position { x=7.33719635, y=16.2943859, z=0.0854607671 }
.
The callstack looks like this:
Jolt.dll!JPH::EPAPenetrationDepth::GetPenetrationDepthStepEPA<JPH::AddConvexRadius<JPH::ConvexShape::Support>,JPH::TriangleConvexSupport>(const JPH::AddConvexRadius<JPH::ConvexShape::Support> & inAIncludingConvexRadius, const JPH::TriangleConvexSupport & inBIncludingConvexRadius, float inTolerance, JPH::Vec3 & outV, JPH::Vec3 & outPointA, JPH::Vec3 & outPointB) Line 157 C++
Jolt.dll!JPH::CollideConvexVsTriangles::Collide(const JPH::Vec3 inV0, const JPH::Vec3 inV1, const JPH::Vec3 inV2, unsigned char inActiveEdges, const JPH::SubShapeID & inSubShapeID2) Line 99 C++
Jolt.dll!JPH::MeshShape::sCollideConvexVsMesh(const JPH::Shape * inShape1, const JPH::Shape * inShape2, const JPH::Vec3 inScale1, const JPH::Vec3 inScale2, const JPH::Mat44 & inCenterOfMassTransform1, const JPH::Mat44 & inCenterOfMassTransform2, const JPH::SubShapeIDCreator & inSubShapeIDCreator1, const JPH::SubShapeIDCreator & inSubShapeIDCreator2, const JPH::CollideShapeSettings & inCollideShapeSettings, JPH::CollisionCollector<JPH::CollideShapeResult,JPH::CollisionCollectorTraitsCollideShape> & ioCollector, const JPH::ShapeFilter & inShapeFilter) Line 1116 C++
Jolt.dll!JPH::CollisionDispatch::sCollideShapeVsShape(const JPH::Shape * inShape1, const JPH::Shape * inShape2, const JPH::Vec3 inScale1, const JPH::Vec3 inScale2, const JPH::Mat44 & inCenterOfMassTransform1, const JPH::Mat44 & inCenterOfMassTransform2, const JPH::SubShapeIDCreator & inSubShapeIDCreator1, const JPH::SubShapeIDCreator & inSubShapeIDCreator2, const JPH::CollideShapeSettings & inCollideShapeSettings, JPH::CollisionCollector<JPH::CollideShapeResult,JPH::CollisionCollectorTraitsCollideShape> & ioCollector, const JPH::ShapeFilter & inShapeFilter) Line 40 C++
ezJoltPlugin.dll!ezJoltCustomShapeInfo::sCollideShapeVsUser1(const JPH::Shape * inShape1, const JPH::Shape * inShape2, const JPH::Vec3 inScale1, const JPH::Vec3 inScale2, const JPH::Mat44 & inCenterOfMassTransform1, const JPH::Mat44 & inCenterOfMassTransform2, const JPH::SubShapeIDCreator & inSubShapeIDCreator1, const JPH::SubShapeIDCreator & inSubShapeIDCreator2, const JPH::CollideShapeSettings & inCollideShapeSettings, JPH::CollisionCollector<JPH::CollideShapeResult,JPH::CollisionCollectorTraitsCollideShape> & ioCollector, const JPH::ShapeFilter & inShapeFilter) Line 154 C++
Jolt.dll!JPH::CollisionDispatch::sCollideShapeVsShape(const JPH::Shape * inShape1, const JPH::Shape * inShape2, const JPH::Vec3 inScale1, const JPH::Vec3 inScale2, const JPH::Mat44 & inCenterOfMassTransform1, const JPH::Mat44 & inCenterOfMassTransform2, const JPH::SubShapeIDCreator & inSubShapeIDCreator1, const JPH::SubShapeIDCreator & inSubShapeIDCreator2, const JPH::CollideShapeSettings & inCollideShapeSettings, JPH::CollisionCollector<JPH::CollideShapeResult,JPH::CollisionCollectorTraitsCollideShape> & ioCollector, const JPH::ShapeFilter & inShapeFilter) Line 40 C++
Jolt.dll!JPH::TransformedShape::CollideShape(const JPH::Shape * inShape, const JPH::Vec3 inShapeScale, const JPH::Mat44 & inCenterOfMassTransform, const JPH::CollideShapeSettings & inCollideShapeSettings, const JPH::Vec3 inBaseOffset, JPH::CollisionCollector<JPH::CollideShapeResult,JPH::CollisionCollectorTraitsCollideShape> & ioCollector, const JPH::ShapeFilter & inShapeFilter) Line 95 C++
Jolt.dll!`JPH::NarrowPhaseQuery::CollideShape'::`2'::MyCollector::AddHit(const JPH::BodyID & inResult) Line 258 C++
Jolt.dll!JPH::QuadTree::CollideAABox(const JPH::AABox & inBox, JPH::CollisionCollector<JPH::BodyID,JPH::CollisionCollectorTraitsCollideShape> & ioCollector, const JPH::ObjectLayerFilter & inObjectLayerFilter, const std::vector<JPH::QuadTree::Tracking,JPH::STLAllocator<JPH::QuadTree::Tracking>> & inTracking) Line 1149 C++
Jolt.dll!JPH::BroadPhaseQuadTree::CollideAABox(const JPH::AABox & inBox, JPH::CollisionCollector<JPH::BodyID,JPH::CollisionCollectorTraitsCollideShape> & ioCollector, const JPH::BroadPhaseLayerFilter & inBroadPhaseLayerFilter, const JPH::ObjectLayerFilter & inObjectLayerFilter) Line 440 C++
Jolt.dll!JPH::NarrowPhaseQuery::CollideShape(const JPH::Shape * inShape, const JPH::Vec3 inShapeScale, const JPH::Mat44 & inCenterOfMassTransform, const JPH::CollideShapeSettings & inCollideShapeSettings, const JPH::Vec3 inBaseOffset, JPH::CollisionCollector<JPH::CollideShapeResult,JPH::CollisionCollectorTraitsCollideShape> & ioCollector, const JPH::BroadPhaseLayerFilter & inBroadPhaseLayerFilter, const JPH::ObjectLayerFilter & inObjectLayerFilter, const JPH::BodyFilter & inBodyFilter, const JPH::ShapeFilter & inShapeFilter) Line 281 C++
> ezJoltPlugin.dll!ezJoltCharacterControllerComponent::CollectContacts(ezDynamicArray<ezJoltCharacterControllerComponent::ContactPoint,ezDefaultAllocatorWrapper> & out_Contacts, const JPH::Shape * pShape, const ezVec3Template<float> & vQueryPosition, const ezQuatTemplate<float> & qQueryRotation, float fCollisionTolerance) Line 314 C++
ezJoltPlugin.dll!ezJoltDefaultCharacterComponent::CheckFeet() Line 463 C++
ezJoltPlugin.dll!ezJoltDefaultCharacterComponent::UpdateCharacter() Line 587 C++
ezJoltPlugin.dll!ezJoltCharacterControllerComponent::Update(ezTime deltaTime) Line 402 C++
ezJoltPlugin.dll!ezJoltWorldModule::FetchResults(const ezWorldModule::UpdateContext & context) Line 672 C++
Now when we reach CollideConvexVsTriangles::Collide()
the arguments are as follows:
inV0
is 7.02168655, 15.9783554, 0.0718481541, L^2=304.617096
inV1
is 7.64038849, 15.9783554, 0.0336148739, L^2=313.684509
inV2
is 7.33101273, 16.2876892, 0.0787103176, L^2=319.038757
inActiveEdges
is 0
inSubShapeID2
is {mValue=4293976543 }
One step up in the callstack Visitor
is initialized with these values:
shape1
is the CapsuleShape
with {mRadius=0.300000012 mHalfHeightOfCylinder=0.00999999978 }
inScale
is 1.00000000, 1.00000000, 1.00000000, L^2=3.00000000
inScale2
is 1.00000000, 1.00000000, 1.00000000, L^2=3.00000000
inCenterOfMassTransform1
is 1.00000000, 0.00000000, 0.00000000, 7.33719635 | 0.00000000, -1.19209290e-07, -1.00000012, 16.2943859 | 0.00000000, 1.00000012, -1.19209290e-07, 0.0854607671
inCenterOfMassTransform2
is 1.00000000, 0.00000000, 0.00000000, 0.00000000 | 0.00000000, 1.00000000, 0.00000000, 0.00000000 | 0.00000000, 0.00000000, 1.00000000, 0.00000000
If you are wondering that in the callstack there is a custum shape type ezJoltCustomShapeInfo::sCollideShapeVsUser1() which is just passing things through.
Finally in GetPenetrationDepthStepEPA()
where it asserts, support_points.mY.size()
is 1
and the first array item is 0.00618362427, -0.00324955024, -0.00669670105, L^2=9.36425931e-05
.
mGJK
is this:
- mGJK {mY=0x00000037e59efa60 {0.00618362427, -0.00324955024, -0.00669670105, L^2=9.36425931e-05, 0.00618362427, -0.00324955024, -0.00669670105, L^2=9.36425931e-05, ...} ...} JPH::GJKClosestPoint
JPH::NonCopyable {...} JPH::NonCopyable
- mY 0x00000037e59efa60 {0.00618362427, -0.00324955024, -0.00669670105, L^2=9.36425931e-05, 0.00618362427, -0.00324955024, -0.00669670105, L^2=9.36425931e-05, ...} JPH::Vec3[4]
+ [0] 0.00618362427, -0.00324955024, -0.00669670105, L^2=9.36425931e-05 JPH::Vec3
+ [1] 0.00618362427, -0.00324955024, -0.00669670105, L^2=9.36425931e-05 JPH::Vec3
+ [2] -107374176., -107374176., -107374176., L^2=3.45876422e+16 JPH::Vec3
+ [3] -107374176., -107374176., -107374176., L^2=3.45876422e+16 JPH::Vec3
- mP 0x00000037e59efaa0 {0.00000000, -0.00999999978, 0.00000000, L^2=9.99999975e-05, 0.00000000, -0.00999999978, 0.00000000, L^2=9.99999975e-05, ...} JPH::Vec3[4]
+ [0] 0.00000000, -0.00999999978, 0.00000000, L^2=9.99999975e-05 JPH::Vec3
+ [1] 0.00000000, -0.00999999978, 0.00000000, L^2=9.99999975e-05 JPH::Vec3
+ [2] -107374176., -107374176., -107374176., L^2=3.45876422e+16 JPH::Vec3
+ [3] -107374176., -107374176., -107374176., L^2=3.45876422e+16 JPH::Vec3
- mQ 0x00000037e59efae0 {-0.00618362427, -0.00675044954, 0.00669670105, L^2=0.000128651576, -0.00618362427, -0.00675044954, 0.00669670105, L^2=0.000128651576, ...} JPH::Vec3[4]
+ [0] -0.00618362427, -0.00675044954, 0.00669670105, L^2=0.000128651576 JPH::Vec3
+ [1] -0.00618362427, -0.00675044954, 0.00669670105, L^2=0.000128651576 JPH::Vec3
+ [2] -107374176., -107374176., -107374176., L^2=3.45876422e+16 JPH::Vec3
+ [3] -107374176., -107374176., -107374176., L^2=3.45876422e+16 JPH::Vec3
mNumPoints 1 int
As far as I can tell, there is no badly normalized rotation that I pass in (I only have one quaternion that rotates the shape by 90 degree and it looks fine to me). The triangle also seems to not be degenerate (it shouldn't be, it is basically a heightmap, so just a grid of quads, don't see how those can deform too badly). It does seem to only happen with this capsule, I have used capsules with a different radius before and never encountered the issue with them.
This is in a Debug build, and I don't use the Jolt CMake file, so maybe some code generation option is different.
I hope that's all the data you need. Thanks for the help!
from joltphysics.
I hijacked CapsuleVsBoxTest.cpp
:
#include <TestFramework.h>
#include <Tests/ConvexCollision/CapsuleVsBoxTest.h>
#include <Jolt/Physics/Collision/Shape/CapsuleShape.h>
#include <Jolt/Physics/Collision/CollideShape.h>
#include <Jolt/Physics/Collision/CollisionCollectorImpl.h>
#include <Jolt/Physics/Collision/CollideConvexVsTriangles.h>
#include <Jolt/Renderer/DebugRenderer.h>
JPH_IMPLEMENT_RTTI_VIRTUAL(CapsuleVsBoxTest)
{
JPH_ADD_BASE_CLASS(CapsuleVsBoxTest, Test)
}
void CapsuleVsBoxTest::PrePhysicsUpdate(const PreUpdateParams &inParams)
{
Ref<CapsuleShape> shape = new CapsuleShape(0.00999999978f, 0.300000012f);
Mat44 com1 = Mat44(Vec4(1.00000000f, 0.00000000f, 0.00000000f, 7.33719635f), Vec4(0.00000000f, -1.19209290e-07f, -1.00000012f, 16.2943859f), Vec4(0.00000000f, 1.00000012f, -1.19209290e-07f, 0.0854607671f), Vec4(0, 0, 0, 1)).Transposed();
Mat44 com2 = Mat44(Vec4(1.00000000f, 0.00000000f, 0.00000000f, 0.00000000f), Vec4(0.00000000f, 1.00000000f, 0.00000000f, 0.00000000f), Vec4(0.00000000f, 0.00000000f, 1.00000000f, 0.00000000f), Vec4(0, 0, 0, 1)).Transposed();
CollideShapeSettings settings; // <--- What are these?
AllHitCollisionCollector<CollideShapeCollector> collector;
CollideConvexVsTriangles collider(shape, Vec3::sReplicate(1.0f), Vec3::sReplicate(1.0f), com1, com2, SubShapeID(), settings, collector);
Vec3 v0(7.02168655f, 15.9783554f, 0.0718481541f);
Vec3 v1(7.64038849f, 15.9783554f, 0.0336148739f);
Vec3 v2(7.33101273f, 16.2876892f, 0.0787103176f);
collider.Collide(v0, v1, v2, 0, SubShapeID());
shape->Draw(DebugRenderer::sInstance, RMat44(com1), Vec3::sReplicate(1.0f), Color::sGreen, false, true);
DebugRenderer::sInstance->DrawWireTriangle(RVec3(com2 * v0), RVec3(com2 * v1), RVec3(com2 * v2), Color::sGreen);
DebugRenderer::sInstance->DrawMarker(RVec3(collector.mHits[0].mContactPointOn1), Color::sRed, 0.1f);
DebugRenderer::sInstance->DrawMarker(RVec3(collector.mHits[0].mContactPointOn2), Color::sRed, 0.1f);
}
I tried in Debug mode under MSVC 2022 17.9.6 and in Clang 17.0.3 (both under Windows) with the following defines:
JPH_DOUBLE_PRECISION;JPH_DEBUG_RENDERER;JPH_PROFILE_ENABLED;JPH_USE_AVX2;JPH_USE_AVX;JPH_USE_SSE4_1;JPH_USE_SSE4_2;JPH_USE_LZCNT;JPH_USE_TZCNT;JPH_USE_F16C;JPH_USE_FMADD
I don't get any asserts (b.t.w. JPH_DOUBLE_PRECISION didn't matter) and it does produce a collision:
but it doesn't even go through the EPA path (GJK already finds a valid contact between the 2 shapes, so it earlies out) and if I modify the code so that the early out doesn't exist then it finds support_points.mY.size() == 2
and also doesn't assert.
The only values that I didn't have are those from the CollideShapeSettings
object. Perhaps you can provide these? (although I don't think it will make much difference).
Another thing I'd like you to try is if you copy paste the contents of PrePhysicsUpdate
in your own codebase, will it then trigger the assert? (just to make sure that I got all the values right and to see if it could indeed be compiler config specific)
from joltphysics.
The CollideShapeSettings
are indeed the key to making it crash!
I pasted your code into mine and it worked just fine. I then copied the settings from the failing code path, which are like this:
JPH::CollideShapeSettings settings;
settings.mCollisionTolerance = 0.00999999978f;
settings.mBackFaceMode = JPH::EBackFaceMode::CollideWithBackFaces;
Now it crashes reproducably. I hardcoded the collision tolerance to 0.01f, I assume that's the problem. Though frankly it's a value that I don't understand well, anyway.
from joltphysics.
Awesome! Thank you so much!
from joltphysics.
Related Issues (20)
- Avoid setting CMake configuration types as a subproject HOT 9
- `CylinderShape` vs `MeshShape` yields odd collision data HOT 4
- Placement new with Jolt allocators HOT 2
- GCC 13.2: warning: ISO C++ prohibits anonymous structs [-Wpedantic] HOT 2
- Some userdata variables are still uint32_t HOT 2
- Support multiple collisions per vertex for a soft body
- CharacterContactListener: add OnContactPersisted and OnContactRemoved HOT 3
- Should DecoratedShapeSettings allow for raw pointers in its constructor? HOT 3
- Automatic transmission HOT 2
- Crash in SkeletonMapperTest sample HOT 3
- [MSVC] Internal compiler error
- Slightly incorrect documentation HOT 1
- Box can rotate while sliding due to friction being applied asymmetrically
- About override new object (不能通过内存的方式创建对象,对于重写了new的class) HOT 2
- Linker Failure: GetSubmergedVolume HOT 2
- DirectX Error HOT 5
- btMotionState equivalent? HOT 4
- Documentation: Syntax is not valid for JPH::ConvexHullShapeSettings HOT 2
- Weird issue with virtual character controller not hitting the ground in Firefox Emscripten HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from joltphysics.