Collisions only

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Collisions only

Postby anyone » Mon Apr 04, 2011 2:54 pm

Hi,

1) I'd like to use NGD for collisions only. Can I set the matrix of each body manually before calling NewtonUpdate() and check for collisions
with NewtonCollisionCollide() after that?

2) Do I have to call specific Newton functions to use NGD as a collision system only? Is AABB mandatory?


Thanks in advance for your answer,
anyone
anyone
 
Posts: 4
Joined: Mon Apr 04, 2011 2:32 pm

Re: Collisions only

Postby Julio Jerez » Mon Apr 04, 2011 3:47 pm

you can use the high level or a low level.
a high level you set everything like a physic world and to calculate collision you call collisionUpdate.
as a low level, you make collisions shapes and call collide, and to do all your high level management.
Julio Jerez
Moderator
Moderator
 
Posts: 12452
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Collisions only

Postby anyone » Mon Apr 04, 2011 11:05 pm

Hi Julio,

I want to use the low-level approach. Can I work with bodies to store the NewtonCollision and matrix?
For the moment, I don't detect any collision :(

Code: Select all
s32 E3D::createEntity(const f32 *origin, const f32 *size) const
{
    if (__g_E3D_iNbrEntities >= __g_E3D_iMaxEntities)
        return -1;

    s32 i = 0;
    for (; i < __g_E3D_iMaxEntities; ++i)
    {
        if (__g_E3D_aEntities[i] == 0)
        {
            __g_E3D_aEntities[i] = new Entity();
            break;
        }
    }

    dgMatrix offset(dgGetIdentityMatrix());
    offset.m_posit[0] = origin[0];
    offset.m_posit[1] = origin[1];
    offset.m_posit[2] = origin[2];

    NewtonCollision *collision = NewtonCreateBox(__g_E3D_pWorld, size[0], size[1], size[2], 0, &offset[0][0]);
    NewtonBody *body = NewtonCreateBody(_g_E3D_pWorld, collision, &offset[0][0]);
    NewtonReleaseCollision(__g_E3D_pWorld, collision);

    __g_E3D_aEntities[i]->body = body;

    __g_E3D_iNbrEntities++;

    return i;
}

// Called each frame to maintain the position up-to-date.
void E3D::entityPos(const s32& id, const f32 *pos) const
{
    dgVector front(0, 0, -1, 0), up(0, 1, 0, 0), right(1, 0, 0, 0);
    dgMatrix matrix(front, up, right, pos);
    NewtonBodySetMatrix(__g_E3D_aEntities[id]->body, &matrix[0][0]);
}

// Get the transformation matrix for display
void E3D::entityMatrix(const s32& id, f32 *m) const
{
    NewtonBodyGetMatrix(__g_E3D_aEntities[id]->body, m);
}

// Called to detect collisions between entitites
bool E3D::collide(const s32& id1, const s32& id2) const
{
    if (id1 < 0 || id2 < 0)
        return false;

    dgMatrix matrixA;
    dgMatrix matrixB;
    dFloat contact[3 * 4];
    dFloat normal[3 * 4];
    dFloat penetration[1 * 4];

    NewtonBodyGetMatrix(__g_E3D_aEntities[id1]->body, &matrixA[0][0]);
    NewtonBodyGetMatrix(__g_E3D_aEntities[id2]->body, &matrixB[0][0]);

    int collisions = NewtonCollisionCollide
    (
        __g_E3D_pWorld,
        4,
        NewtonBodyGetCollision(__g_E3D_aEntities[id1]->body),
        &matrixA[0][0],
        NewtonBodyGetCollision(__g_E3D_aEntities[id2]->body),
        &matrixB[0][0],
        contact,
        normal,
        penetration,
        0
    );

    if (collisions > 0)
        return true;

    return false;
}
anyone
 
Posts: 4
Joined: Mon Apr 04, 2011 2:32 pm

Re: Collisions only

Postby anyone » Tue Apr 05, 2011 1:23 am

Hi again,

It is working now!!! I've modified
NewtonCollision *collision = NewtonCreateBox(__g_E3D_pWorld, size[0], size[1], size[2], 0, &offset[0][0]);
by
NewtonCollision *collision = NewtonCreateBox(__g_E3D_pWorld, size[0], size[1], size[2], 0, 0);

But I'm still wondering about AABB. It is said in the documentation that I have to implement my own
trivial AABB function. My world is very small and the number of entities is not high (a few dozens).
Is it really needed?

Regards,
anyone
anyone
 
Posts: 4
Joined: Mon Apr 04, 2011 2:32 pm

Re: Collisions only

Postby Julio Jerez » Tue Apr 05, 2011 8:21 am

I you are going the low level approach ,you do not have to use the rigid bodies they are only goo for system when you will use physics to advance the world.
Instead you can save the pointer to the collision shape and the tow vector to represent the entity aabb in global space with your entity.

these function functions are useful

void NewtonCollisionCalculateAABB (const NewtonCollision* const collision, const dFloat* const matrix, dFloat* const p0, dFloat* const p1);
int NewtonCollisionCollide (const NewtonWorld* const newtonWorld, int maxSize, const NewtonCollision* const collisionA, const dFloat* const matrixA, const NewtonCollision* const collisionB, const dFloat* const matrixB,dFloat* const contacts, dFloat* const normals, dFloat* const penetration, int threadIndex);


When you are ready to implement the AABB test you the it is a very simple, you can use this functions
basically you will do something like this:

-after you move a body you calculate the AABB and same it with the body, that way the AABB calculation only happens the entity changes its matrix.

// Called each frame to maintain the position up-to-date.
Code: Select all
void E3D::entityPos(const s32& id, const f32 *pos) const
{
    dgVector front(0, 0, -1, 0), up(0, 1, 0, 0), right(1, 0, 0, 0);
    dgMatrix matrix(front, up, right, pos);
    //NewtonBodySetMatrix(__g_E3D_aEntities[id]->body, &matrix[0][0]);
 
   entMatrix = matrix;     
   NewtonCollisionCalculateAABB (entCollision, &matrix[0], &entAABB_p0[0], &entAABB_p1[0]);
}


-if your world is very small then a brute force will be fine. do not worry about aabb test for now.
Code: Select all
int OverlapTest (const dgVector& p0, const dgVector& p1, const dgVector& q0, const dgVector& q1)
{
         return ((p0.m_x < q1.m_x) && (p1.m_x > q0.m_x) && (p0.m_z < q1.m_z) && (p1.m_z > q0.m_z) && (p0.m_y < q1.m_y) && (p1.m_y > q0.m_y));
}

void MyWorld::BruteForceCollisionSystem ()
{
   for (i = 0; i <bodyCount; i ++) {
     E3D* ent0 = GetEnt(i);
    for (j = i + 1; j < bodyCount; j ++) {
       E3D* ent2 = GetEnt(j);
       if (OverlapTest (ent0->&entAABB_p0[0], ent0->&entAABB_p1[0], ent1->&entAABB_p0[0], ent1->&entAABB_p1[0]) {
         if (E3D::collide(const s32& id1, const s32& id2) {
              // do stuff whne body collide   
         }
   }
}
}


then when you have that working if you want to move to a move advance system, you can use a hirarchy or a mutigrid like Newton and 200 and 300
but liek a say if you work is small (less than 100 objects then you do not have to worry about that.
Julio Jerez
Moderator
Moderator
 
Posts: 12452
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Collisions only

Postby anyone » Tue Apr 05, 2011 12:12 pm

Hi Julio,

Thanks for the explanations. I'll remove the rigid bodies and implement the bruteforce method.
If I rotate the shapes, can I pass the OpenGL matrix to NGD instead of a simple position?

Regards
anyone
 
Posts: 4
Joined: Mon Apr 04, 2011 2:32 pm

Re: Collisions only

Postby Julio Jerez » Tue Apr 05, 2011 2:29 pm

yes you can pass the openGL matrix
Julio Jerez
Moderator
Moderator
 
Posts: 12452
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles


Return to General Discussion

Who is online

Users browsing this forum: Google Adsense [Bot] and 0 guests