Cable Component and Sweep Collision Detection

I’m trying to integrate the cable component plugin in my project, but I’m having issue with collisions. I always get a tunnelling effect unless I use a very small substep time (e.g. 0.005), but then it does hundreds of sweep queries per frame. I’ve debugged it a little bit what happens with a bigger time step (e.g. 0.02) and it seems like there’s a recurring pattern for every particle:

- First frame of collision, using `FHitResult::Location`

- Second frame of collision, `FHitResult::bStartPenetrating` is `true`, but `FHitResult::PenetrationDepth` is very small, e.g. < 0.001

- Third frame of collision, `FHitResult::bStartPenetrating` is also `true`, but `FHitResult::Normal` is reversed and `FHitResult::PenetrationDepth` is big, e.g. > 1.0

- Fourth frame has no collision

From what I understand, the issue is with the second frame, where `FHitResult::PenetrationDepth` should be way bigger to get the shape out of penetration. When I look at particle positions, it looks like this:

- First frame, we’re setting particle’s position explicitly to `FHitResult::Location`

- Second frame, particle’s position has moved within the surface, but small depenetration doesn’t counteract this

- Third frame, particles’s position has moved further within the surface, past its center, depenetration is now reversed

- Fourth frame, particle’s position movement, coupled with reversed depenetration, has tunnelled the particle beyond the surface

Is this expected, or is there settings in chaos that can counteract this?

Steps to Reproduce

  1. Enable `CableComponent` plugin
  2. Create an `AActor` blueprint
  3. Attach a `UCableComponent` to the blueprint
  4. Set these properties:
    1. `UCableComponent::bAttachStart` to `true`
    2. `UCableComponent::CableLength` to `10000`
    3. `UCableComponent::NumSegments` to `50`
    4. `UCableComponent::EndLocation` to `[0, 0, 10000]`
    5. `UCableComponent::SubstepTime` to `0.02`
    6. `UCableComponent::bUseSubstepping` to `true`
    7. `UCableComponent::bEnableCollision` to `true`
  5. Move the actor towards the ground at low and high velocity to see how it collides with the surface
    1. At low velocity, it should collide and coil correctly
    2. At high velocity, it will tunnel through, but it shouldn’t
  6. Optionally, lower the value of `UCableComponent::SubstepTime` to `0.005`
    1. It now collides correctly at high velocity

For me, low velocity was 1m/s and high velocity was 10m/s at a substep of `0.02`.

Hi Simon,

As silly as it sounds, can you create a repro from a vanilla version of unreal and send it across to us please? It allows us to rule out any hidden engine config changes which the client may have and be unware of!

That being said, it does look like the setup will really struggle with convergence (due to the 50 segments primarily, but that is also a long cable to be simulating). A lot depends on what you are going to be using this for - can you let me know the use case for this?

All the best

Geoff Stacey

Developer Relations

Epic Games

I’ve wrote a small project that showcases the issue. In fact, in this project, I was unable to make collision work at all. I’ve modified the cable component on my side to show debug draws (replaced UWorld::SweepSingleByChannel with UKismetSystemLibrary::SphereTraceSingle) and we can see the collision occurring and the particles are slightly displaced for a brief moment, but the particle end up through the landscape.

The project is a single actor with a cube and a cable attached to it. The level blueprint moves the actor byt 2.5cm toward negative Z every frames. You should be able to press play and see the issue.

I’ve used 5.5.1-release.

I’ve updated the zip, it was missing a few assets.

Hi Simon,

Thank you for the repro project! - There are 2 immediate things that are worth a callout based on an initial look.

1) Based on hooking this up to the chaos visual debugger - there aren’t any bodies I can see which represent the cable which I’d assume is why there isn’t any collisions.

2) This actor is being moved outside of the physics engine (by the tick function of the world) - this could also be a reason for the tunneling. Generally setting a velocity on an actor is preferable because the physics system can use that to sweep out better volumes (and use CCD or MACD).

I’m taking a look into why the bodies aren’t being generated first, and then will see if altering the movement update will give a better result.

Geoff

Hi Simon,

I have finished investigating this, and ignore both points above. The quick answer is that this specific setup won’t work. (Ie something with a purely vertical cable attached to a kinematic or simulated body which is moving towards the floor when the distance is less than the cable). The longer answer is that the cable cannot push back on the kinematic or dynamic body, nor can it get out of the way - so it gets more and more compressed until something gives - in this case it punches through the ground.

This cable component system sits essentially outside of core physics - so it uses a different system which is faster, but less stable than the normal collision detection and solvers (where the constraints and contacts are solved together iteratively, as opposed to independently in this one).

If you can let me know a bit more about the specific use case I may be able to suggest something a bit different.

Best

Geoff