[ODE] collision detection optimalizations for humanoid

Piotr Obrzut piotr_obrzut at o2.pl
Fri Jan 7 00:40:15 MST 2005


Hi Jon,

JW> What does "slow" mean?

i'm sorry i don't have some fps rating for now (b/c i'm updating
engine which i'm using for mine app, and it will take some time to get
code working - i need to do some changes both in mine app and in
engine...), but when collision detection is on, then in several situations
app slows down even dozen times;

JW> I've had a stack of 100 boxes, and a pile of 40 spheres, laying 
JW> around in a system that also has ~200 static triangle mesh objects
JW> (and most of them do collide with the trimeshes). This system is 
JW> limited by the pixel shaders of the graphics part, not by ODE.



JW> 40 boxes shouldn't be a big deal. Are you running in release mode?
JW> Have you profiled it with VTune to figure out where you're spending
JW> your time? Are you using collision masks so that you don't have to
JW> collide against things you don't need to?


well the problems starts when 2 human models are going to collide
mutually. I need to know about every collided box, so the pesimistic
complexity is O(n^2) (which gives me 1600 collision checkings when
models have 40 box colliders) - i've tested that doing collision
detection so many times is VERY expensive.

I must say that i'm not using OPCODE or even ODE for
collision detection directly, i'm using Crystal Space engine
which uses OPCODE for me (perhaps I should do it by myself? - see
below);

Here is the function i'm using for col. det. :

bool csOPCODECollideSystem::Collide (
  iCollider* collider1, const csReversibleTransform* trans1,
  iCollider* collider2, const csReversibleTransform* trans2)
{
  // printf( " we are in Collide \n");
  csOPCODECollider* col1 = (csOPCODECollider*) collider1;
  csOPCODECollider* col2 = (csOPCODECollider*) collider2;
  if (col1 == col2) return false;

  ColCache.Model0 = col1->m_pCollisionModel;
  ColCache.Model1 = col2->m_pCollisionModel;

  csMatrix3 m1;
  if (trans1) m1 = trans1->GetT2O ();
  csMatrix3 m2;
  if (trans2) m2 = trans2->GetT2O ();
  csVector3 u;

  u = m1.Row1 ();
  col1->transform.m[0][0] = u.x;
  col1->transform.m[1][0] = u.y;
  col1->transform.m[2][0] = u.z;
  u = m2.Row1 ();
  col2->transform.m[0][0] = u.x;
  col2->transform.m[1][0] = u.y;
  col2->transform.m[2][0] = u.z;
  u = m1.Row2 ();
  col1->transform.m[0][1] = u.x;
  col1->transform.m[1][1] = u.y;
  col1->transform.m[2][1] = u.z;
  u = m2.Row2 ();
  col2->transform.m[0][1] = u.x;
  col2->transform.m[1][1] = u.y;
  col2->transform.m[2][1] = u.z;
  u = m1.Row3 ();
  col1->transform.m[0][2] = u.x;
  col1->transform.m[1][2] = u.y;
  col1->transform.m[2][2] = u.z;
  u = m2.Row3();
  col2->transform.m[0][2] = u.x;
  col2->transform.m[1][2] = u.y;
  col2->transform.m[2][2] = u.z;

  if (trans1) u = trans1->GetO2TTranslation ();
  else u.Set (0, 0, 0);
  col1->transform.m[3][0] = u.x;
  col1->transform.m[3][1] = u.y;
  col1->transform.m[3][2] = u.z;

  if (trans2) u = trans2->GetO2TTranslation ();
  else u.Set (0, 0, 0);
  col2->transform.m[3][0] = u.x;
  col2->transform.m[3][1] = u.y;
  col2->transform.m[3][2] = u.z;

  bool isOk = TreeCollider.Collide (ColCache, &col1->transform,
        &col2->transform);
  if (isOk)
  {
    bool status = TreeCollider.GetContactStatus ();
    if (status)
    {
      CopyCollisionPairs (col1, col2);
    }
    return status;
  }
  else
  {
    return false;
  }
}

-- 
greetings,
 Piotr Obrzut



More information about the ODE mailing list