Compound trigger volumes

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Compound trigger volumes

Postby hpesoj » Sat Aug 22, 2009 6:09 pm

I refer you to this post:

viewtopic.php?f=9&t=4912&p=35210&hilit=trigger+volume#p35210

I am trying to implement some sort of magnetic behaviour, much like in the black/white hole demos, and naturally I thought of using compound collision shapes composed of a solid body with trigger volume as a magnetic field. However, it seems that compound collision shapes and their components still cannot be used as trigger volumes. Would it be easy to implement such a feature, or did you previously decide against it?

EDIT

Also, I just tried removing contacts as suggested in the above post, but my body still reacts to collisions. How exactly is this meant to work :S?
hpesoj
 
Posts: 90
Joined: Sun Jan 09, 2005 4:36 pm
Location: Cambridge/Bristol, UK

Re: Compound trigger volumes

Postby Julio Jerez » Sat Aug 22, 2009 7:40 pm

Only convex shape can be trigger volumes.
you can not make a compound collision a trigger volume, but you can make some of the pieces of of a compound collision a trigger volumne.
Is that what you are trying to make?


hpesoj wrote:However, it seems that compound collision shapes and their components still cannot be used as trigger volumes. Would it be easy to implement such a feature, or did you previously decide against it?

Not I did not decided against that, Maybe I forget, My impresion was that this was working. However there is somithing you should know.
when you make a compoumd collision, the shape are fixed, so if the body is dynamics and moves or rotates, the triggers will move with it.
So this is the kind of feature that sound good on paper but that it is not that practical.
Of course Trigger volumes in compound shape can be used for defining irregular triggers regions, is that how you are trying to use them?

also on this
hpesoj wrote:Also, I just tried removing contacts as suggested in the above post, but my body still reacts to collisions. How exactly is this meant to work :S?

Removing contact is teh old way to simulate trigget volome,
I usually do not implement functionality in Newton that can be implemented from the client app. There is a reason for using trigger volumen.
First of all they do not calculate contacts at all, so you to not get contact slot from the Max contact count that is allow for colling pairs.
Secund they are much faster than letting the contact be calculated just to be rejected in the callback.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Compound trigger volumes

Postby hpesoj » Sat Aug 22, 2009 7:58 pm

Yep, that is what I am trying to do, but even if I set the pieces as trigger volumes, contacts are still generated.

It has also occured to me that even if I could set individual collisions as triggers within the compound collision, the only way to get the shapeID is through contacts, which aren't generated for trigger volumes, so how would I be able to tell which collisions have collided?

I usually do not implement functionality in Newton that can be implemented from the client app. There is a reason for using trigger volumen.
First of all they do not calculate contacts at all, so you to not get contact slot from the Max contact count that is allow for colling pairs.
Secund they are much faster than letting the contact be calculated just to be rejected in the callback.


Fair enough, but how then can I manually control the "collidable" property like friction or softness?
Last edited by hpesoj on Sat Aug 22, 2009 8:03 pm, edited 1 time in total.
hpesoj
 
Posts: 90
Joined: Sun Jan 09, 2005 4:36 pm
Location: Cambridge/Bristol, UK

Re: Compound trigger volumes

Postby hpesoj » Sat Aug 22, 2009 8:02 pm

when you make a compoumd collision, the shape are fixed, so if the body is dynamics and moves or rotates, the triggers will move with it.
So this is the kind of feature that sound good on paper but that it is not that practical.
Of course Trigger volumes in compound shape can be used for defining irregular triggers regions, is that how you are trying to use them?


Eh? What I am trying to do is have a dynamic body surrounded by a "field" in the form of a trigger volume. What I gather you are saying is that as the body moves, the trigger volume will move with it, which is definitely what I want (I can't imagine why I'd want it to not move with the body). My problem is that trigger volumes within compound collisions do not seem to act as trigger volumes, rather as regular collisions.
hpesoj
 
Posts: 90
Joined: Sun Jan 09, 2005 4:36 pm
Location: Cambridge/Bristol, UK

Re: Compound trigger volumes

Postby Julio Jerez » Sat Aug 22, 2009 8:05 pm

On the trigger moving with the body, Realsie that when teh body rotate teh trige will rotate with the body, as well.

anyway maybe there is a unfinish feature there.
Do you have a test demo I can run I can try rather me to making a set up?
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Compound trigger volumes

Postby hpesoj » Sat Aug 22, 2009 8:20 pm

Since I didn't have a proper demo at hand, I just modified my benchmark code again to demonstrate my problem.

Code: Select all
#include <iostream>
#include <windows.h>
#include <Newton.h>

// High precision timer for Windows.
class Timer
{
public:
    //-------------------------------------------------------------------------
    Timer() :
        mStartTime(),
        mTicksPerSecond()
   {
      QueryPerformanceFrequency(&mTicksPerSecond);
      QueryPerformanceCounter(&mStartTime);
   }

    //-------------------------------------------------------------------------
   float getSeconds(bool reset = false)
   {
      LARGE_INTEGER currentTime;
      QueryPerformanceCounter(&currentTime);
      
      float seconds = (float)(
            ((double)currentTime.QuadPart - (double)mStartTime.QuadPart) /
            (double)mTicksPerSecond.QuadPart);
      
        if (reset)
        {
          QueryPerformanceCounter(&mStartTime);
        }

      return seconds;
   }
   
private:
   LARGE_INTEGER mStartTime;
   LARGE_INTEGER mTicksPerSecond;

};


void gravityCallback(const NewtonBody* body, float timestep, int threadIndex)
{
    static float force[] = {0.0f, -9.8f * 0.01, 0.0f};
    NewtonBodySetForce(body, force);
}

float sumPosition[3];
int totalSum;

void transformCallback(const NewtonBody* body, const float* matrix, int threadIndex)
{
    sumPosition[0] += matrix[12];
    sumPosition[1] += matrix[13];
    sumPosition[2] += matrix[14];
    totalSum++;
}


int main(void)
{
    NewtonWorld* world = NewtonCreate(0, 0);
    NewtonSetPlatformArchitecture(world, 2);

    //--------------------------------------------------
    // CHANGE THIS VALUE TO TEST
    //--------------------------------------------------
    NewtonSetSolverModel(world, 0);


    // Create shapes.
    NewtonCollision* floorShape = NewtonCreateBox(world, 100.0f, 1.0f, 100.0f, 0, 0);

#if 1
    NewtonCollision* triggerShape = NewtonCreateBox(world, 1.0f, 1.0f, 1.0f, 0, 0);

    //--------------------------------------------------
    // The boxes still stack even after setting this!
    //--------------------------------------------------
    NewtonCollisionSetAsTriggerVolume(triggerShape, 1);
    //--------------------------------------------------

    NewtonCollision* shapes[1] = {triggerShape};
    NewtonCollision* boxShape = NewtonCreateCompoundCollision(world, 1, shapes, 0);
#else
    NewtonCollision* boxShape = NewtonCreateBox(world, 1.0f, 1.0f, 1.0f, 0, 0);

    //--------------------------------------------------
    // The boxes do not stack when not using compound collisions
    //--------------------------------------------------
    NewtonCollisionSetAsTriggerVolume(boxShape, 1);
    //--------------------------------------------------
#endif

    float boxMass = 1.0f;
    float boxInertia[3];
    float boxOrigin[3];
    NewtonConvexCollisionCalculateInertialMatrix(boxShape, boxInertia, boxOrigin);


    // Create floor.
    NewtonBody* floor = NewtonCreateBody(world, floorShape);

    float floorMatrix[] = {1.0f, 0.0f, 0.0f, 0.0f,
                           0.0f, 1.0f, 0.0f, 0.0f,
                           0.0f, 0.0f, 1.0f, 0.0f,
                           0.0f, -1.0f, 0.0f, 1.0f};
    NewtonBodySetMatrix(floor, floorMatrix);


    // Create 10x10x10 stacks of boxes.
    float boxMatrix[] = {1.0f, 0.0f, 0.0f, 0.0f,
                         0.0f, 1.0f, 0.0f, 0.0f,
                         0.0f, 0.0f, 1.0f, 0.0f,
                         0.0f, 0.0f, 0.0f, 1.0f};

    for (int y = 0; y < 10; y++)
    {
        for (int x = 0; x < 10; x++)
        {
            for (int z = 0; z < 10; z++)
            {
                NewtonBody* box = NewtonCreateBody(world, boxShape);
                NewtonBodySetMassMatrix(box, boxMass,
                    boxInertia[0] * boxMass, boxInertia[1] * boxMass, boxInertia[2] * boxMass);
                NewtonBodySetAutoSleep(box, 0);
                NewtonBodySetForceAndTorqueCallback(box, gravityCallback);
                NewtonBodySetTransformCallback(box, transformCallback);

                boxMatrix[12] = x * 2.0f;
                boxMatrix[13] = y * 1.0f;
                boxMatrix[14] = z * 2.0f;
                NewtonBodySetMatrix(box, boxMatrix);
            }
        }
    }

    Timer timer;
    int iterations = 0;

    // Count iterations per second.
    while (true)
    {
        sumPosition[0] = sumPosition[1] = sumPosition[2] = 0.0f;
        totalSum = 0;
        NewtonUpdate(world, 1.0f / 60.0f);
        iterations++;

        if (timer.getSeconds() > 1.0f)
        {
            std::cout << iterations << " iterations in " << timer.getSeconds(true) << std::endl;
            std::cout << "Average position: " <<
                sumPosition[0] / totalSum << ", " <<
                sumPosition[1] / totalSum << ", " <<
                sumPosition[2] / totalSum << std::endl;
            iterations = 0;
        }
    }

   return 0;
}

hpesoj
 
Posts: 90
Joined: Sun Jan 09, 2005 4:36 pm
Location: Cambridge/Bristol, UK

Re: Compound trigger volumes

Postby Julio Jerez » Sat Aug 22, 2009 8:27 pm

Oh I think I see what you mean.
The way It is now, thigger volumes can only work with a Material, but that makes then too hard to use.

Bacially what we need ot that trigger volumes insert and null entry in the contact array,
that would be is a contact that is just a NULL contact, just pointer to the two colliding shapes and the call back can check if the shape is a trigger volume and make decitions.
But this contact will not have any influence in the simulation.
Does that sound alright, to you?
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Compound trigger volumes

Postby hpesoj » Sat Aug 22, 2009 8:39 pm

The way It is now, thigger volumes can only work with a Material, but that makes then too hard to use.


I am not sure what you mean. Trigger volumes seem to work, but not when they are part of a compound collision: this is the problem demonstrated by my code.

Bacially what we need ot that trigger volumes insert and null entry in the contact array,
that would be is a contact that is just a NULL contact, just pointer to the two colliding shapes and the call back can check if the shape is a trigger volume and make decitions.
But this contact will not have any influence in the simulation.
Does tha sound alright, to you?


That sounds good, and it solves my other problem, but it's no use if the initial problem isn't fixed.

While we're on this topic, can I ask again how you would go about manually overriding the "collidable" setting? Or is the NewtonMaterialSetDefaultCollidable function misleading? Is collidability a per-body setting like continuous collision and surface thickness?
hpesoj
 
Posts: 90
Joined: Sun Jan 09, 2005 4:36 pm
Location: Cambridge/Bristol, UK

Re: Compound trigger volumes

Postby Julio Jerez » Sat Aug 22, 2009 8:53 pm

Yes they work because they create a NULL joint which means you need a materail callback to properly handle them.
you did not see it in the test you made becuase you did not add contact callback.
with the proposed solution Instead of adding a NULL Joint, a collision trigger will add NULL contact to a contact joint.
this way and the will generate a Joint with a NULL concat like they are doing now but of they are use in a compound collision then they will generate a contact joint that will have some NULL contacts.

What do you mean the Initial problem?

on this, NewtonMaterialSetDefaultCollidable
say you have and object like a ragdoll, and you do not wna some body part colliding, you can use a Material and make the collision betwen
that pair invisible by default and no time will be spent calculation contacts when those object overlap.
This is nio a trigger a triger still doe the inertstion test, thwy just do not calculates contacts.
NewtonMaterialSetDefaultCollidable reject the pair at the AABB level as if they never existed.
some time this is needed for complex objects for example an arm that hit the Neck ot the shoulder of a model, you do not want them colliding but you still want them to collide with other bodies
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Compound trigger volumes

Postby hpesoj » Sat Aug 22, 2009 9:13 pm

Yes they work because they create a NULL joint which means you need a materail callback to properly handle them.
you did not see it in the test you made becuase you did not add contact callback.


I'm confused. Exactly how should I be handling them in the contact callback? In my project code I am using contact callbacks and the trigger volumes still behave like regular collisions (with generated contacts and everything).

What do you mean the Initial problem?


The trigger volumes behaving like regular collisions when part of a compound collision.

on this, NewtonMaterialSetDefaultCollidable
say you have and object like a ragdoll, and you do not wna some body part colliding, you can use a Material and make the collision betwen
that pair invisible by default and no time will be spent calculation contacts when those object overlap.


I understand this, but with other "Default" properties you can override them in a contact callback, for example, by using NewtonMaterialSetContactSoftness. My question really is, why is there no NewtonMaterialSetContactCollidable? Or perhaps NewtonMaterialSetDefaultCollidable should really be called NewtonMaterialSetCollidable?

The way you have to process contacts is quite confusing IMO, it took me some time to figure it out. Something like this would make far more sense to me:

Code: Select all
void materialCollisionCallback(
    const NewtonJoint* joint, dFloat timestep, int threadIndex)
{
    NewtonBody* body0 = NewtonJointGetBody0(joint);
    NewtonBody* body1 = NewtonJointGetBody1(joint);
   
    for (NewtonContact* contact = NewtonContactJointGetFirstContact(joint);
        contact; contact = NewtonContactJointGetNextContact (joint, contact))
    {
        NewtonCollision* col0 = NewtonContactGetCollision(contact, body0);
        NewtonCollision* col1 = NewtonContactGetCollision(contact, body1);
       
        unsigned int id0 = NewtonCollisionGetUserID(col0);
        unsigned int id1 = NewtonCollisionGetUserID(col1);
       
        if (NewtonCollisionIsTriggerVolume(col0) ||
            NewtonCollisionIsTriggerVolume(col1))
        {
            // Do stuff related to trigger volumes
        }
        {
            NewtonContactSetSoftness(contact, whatever);
        }
    }
}


I.e. get rid of the concept of NewtonMaterials since NewtonMaterials and contacts seem to have a one-to-one correspondance, plus NewtonMaterials seem to represent a pair of material IDs, which is just confusing since usually you would just use the material IDs. Also, I'm not sure why contacts are void pointers, shouldn't they really have their own type? I'm probably just ranting now, the current system is usable, but not very intuitive :).
hpesoj
 
Posts: 90
Joined: Sun Jan 09, 2005 4:36 pm
Location: Cambridge/Bristol, UK

Re: Compound trigger volumes

Postby Julio Jerez » Sat Aug 22, 2009 9:30 pm

What I sai before mean exacth that

Code: Select all
void materialCollisionCallback(
    const NewtonJoint* joint, dFloat timestep, int threadIndex)
{
    NewtonBody* body0 = NewtonJointGetBody0(joint);
    NewtonBody* body1 = NewtonJointGetBody1(joint);
   
    for (NewtonContact* contact = NewtonContactJointGetFirstContact(joint);
        contact; contact = NewtonContactJointGetNextContact (joint, contact))
    {
        NewtonCollision* col0 = NewtonContactGetCollision(contact, body0);
        NewtonCollision* col1 = NewtonContactGetCollision(contact, body1);
       
        unsigned int id0 = NewtonCollisionGetUserID(col0);
        unsigned int id1 = NewtonCollisionGetUserID(col1);
       
        if (NewtonCollisionIsTriggerVolume(col0) ||
            NewtonCollisionIsTriggerVolume(col1))
        {
            // Do stuff related to trigger volumes
        }
        else
        {
            NewtonContactSetSoftness(contact, whatever);
        }
    }
}



teh part loop ove each conatc in the conat array the joint,
for (NewtonContact* contact = NewtonContactJointGetFirstContact(joint);
contact; contact = NewtonContactJointGetNextContact (joint, contact))

But Collision trigger do no add anthing the make the entire join NULL, and that is bad beacause tehn teh eis no way to get feeback for a trigger is call back.
The call back will never be called the way triggers are working now but after I made the fix then it will be ok.


get rid of the concept of NewtonMaterials since NewtonMaterials and contacts seem to have a one-to-one correspondance,

This is not true, you need two materials to have one kind of contact definition.
The Materials confuse you because you need to understand tha the material systemn is a Graph,
Material are nodes of the graph, the contacts properties are the edges of the graph.
This is being like that since Newton was first released. It is not changing.

you can check the wiki tutorial advance Material system, it is a simpler but very poweful implementation where a single callback can generate more than one tipy of contact
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Compound trigger volumes

Postby hpesoj » Sat Aug 22, 2009 9:39 pm

Thanks very much for the help. Hopefully I will understand fully when you make the fix!
hpesoj
 
Posts: 90
Joined: Sun Jan 09, 2005 4:36 pm
Location: Cambridge/Bristol, UK

Re: Compound trigger volumes

Postby JulBaxter » Fri Mar 19, 2010 11:26 am

I have the same problem. I make my best to find the answer into this post but i don't.

Context: A dynamic body with a compoundCollision with two convex collision.The tallest is set as Trigger.
When the body is falling and the tallest trigger shape "touch" another body the materialcontactcallback is called but the body is stopped (the trigger collision do not go throught the other body).

What can I do ?
JulBaxter
 
Posts: 23
Joined: Wed Mar 10, 2010 6:56 am


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest