Problem with capsule Autosize

I’m doing some tests and I’ve found a problem with the capsule collider Autosize property.

I’m using some Kenney 3D animated models (mini-characters and mini-dungeon packages, both from OpenGameArt.org). First I created a ground platform with a box collider and fixed its rigidbody position and rotation to prevent it to move. Then I put the human character from mini-dungeon, added a capsule collider and programmed a semi-complex control that allows to move and jump, with animations… It works.

Then I decided to change the model by another from the mini-characters (character-female-b) and suddenly the animations didn’t work as expected: the character shivers when walking, and sometimes it still plays the walking animation when it’s not walking.

Fortunately I do versioning/backup so I recovered the previous view design and compared both and i’ve found that, despite both models have same dimensions (approx), their capsule sizes are quite different. That makes my FindGround algorithm to fail hence the problems (i.e. it detects ground and air intermittently so it changes between “walk” and “fall” animations quickly).

For the one that works:

  • Height : 0.21
  • Radius : 0.27
  • translation: 0 0.38 0.02

For the one that doesn’t work:

  • Height : 0.11
  • Radius : 0.31
  • translation: 0 0.37 0

So, I set the AutoSize to false and manually changed the collider size and position and now it works.

I don’t know if the problem is the way the collider calculates its own size, or maybe because the models aren’t actually so similar as they look but I decided to tell you just to be sure.

Indeed, the AutoSize is sometimes not guessing what you want. We experimented (with Andrzej Kilijański) and found there’s no perfect algorithm here, all approaches to autosize seem to be just “guesses, that are sometimes wrong”.

Below is the TCastleCapsuleCollider.CalculateSizeCore current algorithm.

Any ideas to improve it are welcome :slight_smile: You can experiment with editing it (it’s here: castle-engine/src/transform/castletransform_physics.inc at master · castle-engine/castle-engine · GitHub ) .

procedure TCastleCapsuleCollider.CalculateSizeCore;
var
  LocalBoundingBox: TBox3D;
  MinThickness: Single;
begin
  inherited; // resets Translation, Rotation

  if Mode2D then
    MinThickness := AutoSizeMinThickness2D
  else
    MinThickness := AutoSizeMinThickness;

  if (Parent = nil) or (Parent.BoundingBox.IsEmptyOrZero) then
  begin
    Radius := MinThickness;
    Height := MinThickness;
    Exit;
  end;

  LocalBoundingBox := Parent.LocalBoundingBox;

  if Mode2D then
    Radius := LocalBoundingBox.SizeX * 0.50
  else
    Radius := ((LocalBoundingBox.SizeX * 0.50) + (LocalBoundingBox.SizeZ * 0.50)) / 2;

  { If radius * 2 is bigger than height make it smaller. }
  if Radius * 2 > LocalBoundingBox.SizeY then
    Radius := LocalBoundingBox.SizeY / 2 - 0.001;
  { Radius must be at least MinThickness }
  Radius := Max(Radius, MinThickness);

  Height := Max(LocalBoundingBox.SizeY - Radius * 2, 0.001);

  Translation := LocalBoundingBox.Center;
end;

I see, it does an approximation. I thought it calculates the maximum and minimum vertex coordinates and use them, but that would be time consuming if model has a high vertex count.

BTW, if I remember correctly, previous versions of CGE rendered the collision volumes, didn’t it? Is it planned to render them in the future?

Unity uses a method in its MonoBehaviour and a Gizmos API for this. Next code is from a project I did:

/* Draw a gizmo to show the attack area. */
  void OnDrawGizmosSelected ()
  {
    Vector3 lPoint = new Vector3 (this.Origin.x * this.transform.right.x, this.Origin.y);
    Gizmos.color = Color.red;
    Gizmos.DrawWireSphere (this.transform.position + lPoint , this.Radius);
  }      

We do calculate minimum and maximum vertex coordinates. That’s what the Parent.LocalBoundingBox in code above does :slight_smile:

We can show colliders, nothing changed in this regard I think. Use “Physics → Show Colliders”.

Hmmm, though testing on examples/platformer, I see that capsule collider can be not visible for some reason, until I toggle “Viewport → Wireframe Mode → Wireframe” (Alt + Z). TODO: I’ll look into it. For now, if you experience the same issue, switch to wireframe rendering in editor – you should see capsule collider then.

Oh, I didn’t remember that.

TODO: I think I’ll look for the Editor code that renders it and try to figure how to render a simpler capsule volume. I have an idea, maybe I can implement it.