Getting collision data

Getting collision data

Ritratto di Abhinav S.

Hello,

I just recently started working with Havok. I am approaching it from an scientific perspective. That is, I want data.

I modified the ConsoleExampleMt standalone demo and turned it into a simple ball bouncing demo and now, I need to get force data; I wish to know how much force the ball bounces with. I first looked into implementing a collision listener. The hkpContactPointEvent& event that acts as a parameter for the contactPointCallback method has a member m_contactPointProperties which (as the name implies) contains contact point properties. It in turn has a member m_impulseApplied. m_impulseApplied as I understand corresponds to the impulse applied by the solver at the last time step. I tried attaching the collision listener to both the world and ball but kept on getting an impulse of zero. I know for sure that the listener has been attached properly (I printed off the separating velocities from the contactPointCallback method and it gave me changing velocity values).

Could you please direct me on how to get this collision force or impulse data? (Dividing impulse by the timestep would give force)

Thanks.

11 post / 0 new
Ultimo contenuto
Per informazioni complete sulle ottimizzazioni del compilatore, consultare l'Avviso sull'ottimizzazione
Ritratto di Havok - Josh S.

Hi Abhinav,
The reason you're not getting the impulse applied in your contact point callback is that this callback is fired BEFORE the collision is resolved. It is designed this way so that the listener can make changes to the rigid body properties that could affect the way the collision will resolve. It sounds like you want access to the resulting values AFTER the collision is resolved. Havok is not designed to query the collision forces directly for individual contact points, so the solution will be a bit more involved. If your collision lasts more than a single frame, the impulse applied will correspond to the collision response for the previous frame. If your collision only lasts one frame, though, this will not work. In this case, you may have to recreate the forces by hand. You can capture the net force applied to a rigid body each frame capturing its linear and angular velocities and differentiating over the time step. If you need the force for a particular contact point, you can compute it using the separating velocity (if interested, please look at this article describing the mathematics involved). These approaches are mathematically complex, computationally expensive, and approximate, though. I'll keep looking for a serviceable workaround, and let you know what I find.

Josh S. Havok Developer Support Engineer www.havok.com
Ritratto di Abhinav S.

Hello,
Thank you very much for your reply. I had searched the user guide quite a bit but could not figure out how to get that data directly. I had my doubts about the time at which the callback was fired around last week, so I marked the ball's quality as HK_COLLIDABLE_QUALITY_DEBRIS_SIMPLE_TOI so as to make the callback fire at the time of impact. It did not change anything. I still got a value of zero for my impulse.
But I have a question though: what type of data can I get out ragdolls? Can I get forces being applied at the joints, torques etc? If the ragdoll falls on the ground, can I get the impact data on its joints or body?
Thank you for considering this post.

Ritratto di Havok - Josh S.

Hi Abhinav,

I recommend that you look at 1.3.1.8. Limiting Constraint Force in the Havok Physics help (Creating a Simulation -> Creating Physics Objects ->Constraints -> Introduction -> Limiting Constraint Forces). In particular, take a look at what it says about hkpContactImpulseLimitBreachedListener. For ragdoll constraints, you can specify a maximum impulse that each constraint can apply. Conceptually, this corresponds to the amount of force that a joint can safely withstand along a direction in which it doesn't move freely. When this limit is exceeded, you can use this callback to respond appropriately. In the case of a ragdoll constraint, this could mean notifying the gameplay logic that the character has sustained an injury. This won't give you the applied forces directly, but it may provide a useful substitute. Keep in mind that this will cap the constraint impulses, allowing the joints to break apart if this limit is exceeded.

Here's an example of how to set this up for a ragdoll constraint using the Physics -> Api -> Constraints -> Ragdoll demo:

add in Demos\Physics\Api\Constraints\Ragdoll\RagdollDemo.h:

> #include <Physics/Dynamics/Constraint/Contact/hkpContactImpulseLimitBreachedListener.h>

> class MyListener : public hkpContactImpulseLimitBreachedListener, public hkReferencedObject
> {
> public:
>     HK_DECLARE_CLASS_ALLOCATOR(HK_MEMORY_CLASS_DEMO);
>     virtual void contactImpulseLimitBreachedCallback( const hkpContactImpulseLimitBreachedListenerInfo* breachedContacts, int numBreachedContacts ) ;
> };

add in Demos\Physics\Api\Constraints\Ragdoll\RagdollDemo.cpp:

> void MyListener::contactImpulseLimitBreachedCallback( const hkpContactImpulseLimitBreachedListenerInfo* breachedContacts, int numBreachedContacts )
> {
>     hkprintf("ouch!");
> }

//...

RagdollDemo::RagdollDemo(hkDemoEnvironment* env)
{

    //...

    //
    // CREATE RAGDOLL CONSTRAINT
    //
    {
        hkReal planeMin = HK_REAL_PI * -0.2f;
        hkReal planeMax = HK_REAL_PI * 0.1f;
        hkReal twistMin = HK_REAL_PI * -0.1f;
        hkReal twistMax = HK_REAL_PI * 0.4f;
        hkReal coneMin = HK_REAL_PI * 0.3f;

        hkpRagdollConstraintData* rdc = new hkpRagdollConstraintData();

        rdc->setConeAngularLimit(coneMin);
        rdc->setPlaneMinAngularLimit(planeMin);
        rdc->setPlaneMaxAngularLimit(planeMax);
        rdc->setTwistMinAngularLimit(twistMin);
        rdc->setTwistMaxAngularLimit(twistMax);
>         rdc->setBreachImpulse(10.f); // this is the maximum impulse that can be applied per physics iteration

        hkVector4 twistAxis(1.0f, 0.0f, 0.0f);
        hkVector4 planeAxis(0.0f, 1.0f, 0.0f);
        pivot.set(0.0f, 0.0f, 0.0f);
        rdc->setInWorldSpace(moveableBody->getTransform(), fixedBody->getTransform(), pivot, twistAxis, planeAxis);
        
        //
        //    Create and add the constraint
        //
        {
            hkpConstraintInstance* constraint = new hkpConstraintInstance(moveableBody, fixedBody, rdc );
            m_world->addConstraint(constraint);
            constraint->removeReference();
        }    

        rdc->removeReference();

>         m_world->addContactImpulseLimitBreachedListener( &m_myListener );
    }
    

Josh S. Havok Developer Support Engineer www.havok.com
Ritratto di Abhinav S.

Thank you very much for your help. I looked at the ragdoll demo and it is not a whole ragdoll as per say (it just demonstrates how to setup the ragdoll constraint). I now wish implement that listener on an actual ragdoll. I could go ahead and create a ragdoll using code but I wish to use an Autodesk Maya character that I already have. I wish to export it in a format that can be accessible and modifiable through code. Basically this is what I am thinking of: transform the maya character into a Havok character (export the skeletal structure, mesh, skin weights) and be able to use Havok Physics SDK methods (such as implementing the above hkpContactImpulseLimitBreachedListener) on it. I have started looking into the Havok Content Tools for the export aspect of it. But I want to know: how feasible is this? If this is feasible, I wish to take this a step further and use the character (now a havok character) to create a really cool explosion demo. For this, here is what I am thinking of: my character walking up to a door, setting a bomb and a huge boom happens. Obviously, I would also want to get data out of this; like how strong the explosion was and so on.
Do you have any ideas on how this can be done?
Thank you very much for your help.

Ritratto di Havok - Josh S.

Hi Abhinav,
You can set up a rag doll for your character using the Havok Maya plugin. Please look at the Havok Content Tools help under Maya Tools -> Tutorial: Rag Doll Setup for more information on how to do this.

There are many ways to model a bomb using Havok Physics. Depending on how you choose to model it, you can apply explosion forces however you like. One way to do it would be to create a custom action to simulate a shockwave. For example, a simple shockwave action could have a position, energy, radius, and expansion velocity. Each frame, you would increase the radius by the expansion velocity and look for objects in the sphere formed around the explosion epicenter. Then you could apply impulses to these objects based on their mass, distance from the epicenter, and explosion energy. In building this, you could build in ways to track the forces applied by the shockwave. For more information on how to create a custom action, please look at Havok Physics Help under Creating a Simulation -> Simulating a Physics World -> Populating a World -> Actions -> Creating a Custom Action.

Josh S. Havok Developer Support Engineer www.havok.com
Ritratto di Abhinav S.

Thank you for your reply. I actually did look into the Rag Doll Setup and succeeded in creating a .hkt file. I tried testing it out with the simple Loader demo but I get an error pointing to the line that says there is no physics item in the world. To make sure the code itself worked, I created a sphere and ground (box) in maya and succeeded in uploading that in the simple loader. I am not really sure why the character isn't working as well.

Thank you for the suggestion on the creation of the explosion. I will definitely look into it.

Ritratto di Abhinav S.

Hello, let's say I want to go with the shockwave explosion. How exactly should I get started here? Should I start from scratch or can I modify some existing demo to create this? All of the work I have done so far with Havok has involved modifying some existing demo. Maybe it is too much asking but would it be possible for you to outline the steps I should take for the creation of this demo? I wish to create a room full of ragdolls (or just one ragdoll) and apply a bomb from the center of the room and get the the following data: whether or not the ragdoll joint limit max impulse was breached (using the listener you suggested me implementing) and the force being applied depending on the ragdoll by the explosion as it is moved around. I looked into the explosion demo in physics-> api -> dynamics -> explosion. and that seemed to be a good starting point to me at least. I have not yet succeeded in uploading the ragdoll either. I have to wrap up with this project soon. Thank you very much for considering this.

Ritratto di Abhinav S.

Hello, let's say I want to go with the shockwave explosion. How exactly should I get started here? Should I start from scratch or can I modify some existing demo to create this? All of the work I have done so far with Havok has involved modifying some existing demo. Maybe it is too much asking but would it be possible for you to outline the steps I should take for the creation of this demo? I wish to create a room full of ragdolls (or just one ragdoll) and apply a bomb from the center of the room and get the the following data: whether or not the ragdoll joint limit max impulse was breached (using the listener you suggested me implementing) and the force being applied depending on the ragdoll by the explosion as it is moved around. I looked into the explosion demo in physics-> api -> dynamics -> explosion. and that seemed to be a good starting point to me at least. I have not yet succeeded in uploading the ragdoll either. I have to wrap up with this project soon. Thank you very much for considering this.

Ritratto di Abhinav S.

I also noticed that many demos use ragdolls, can i just copy and paste them into the explosion demo?

Ritratto di Havok - Josh S.

Hi Abhinav,
It sounds like you're already using the physics -> api -> dynamics -> Actions -> WindAction -> Explosion demo, which is what I would recommend. The explosion demo does essentially everything you need already, though it uses hkpWind rather than an hkpAction. If you have extra time and are curious about the process, you can build the same functionality using an action instead of a wind. You would need to derive from hkpNullAction because this action isn't tied to a particular rigid body. You would then need to override getEntities to get all rigid bodies that intersect the shockwave. You would also need to override applyAction to get and apply the vector to each rigid body from getEntities. This calculation should look like Explosion::getWindVector, followed by a call to hkpRigidBody::applyForce(). There are no examples in the demos of hkpNullActions, but the action interface is shared between all action types. For an example, look at Demos\Physics\Api\Dynamics\Actions\GravityAction\GravityAction.h

Josh S. Havok Developer Support Engineer www.havok.com

Accedere per lasciare un commento.