Introduction
The c++ (cpp) hkpcontactpointaddedevent example is extracted from the most popular open source projects, you can refer to the following example for usage.
Programming language: C++ (Cpp)
Class/type: hkpContactPointAddedEvent
Example#1File:
CollisionEventsDemo.cppProject:
venkatarajasekhar/viper
void MyCollisionListener::contactPointAddedCallback( hkpContactPointAddedEvent& event )
{
//
// draw the contact point as a little red star
//
{
const hkVector4& start = event.m_contactPoint->getPosition();
for ( int i = 0; i < 20; i++ )
{
hkVector4 dir( hkMath::sin( i * 1.0f ), hkMath::cos( i * 1.0f ), hkMath::sin(i * 5.0f ) );
dir.setMul4(0.3f, dir);
hkVector4 end; end.setAdd4(start, dir);
HK_DISPLAY_LINE(start, end, hkColor::RED);
}
}
//
// collect all information in our own data structure
// as the havok memory manager is really really fast,
// allocating lots of small structures is acceptable
//
if ( event.m_contactPointProperties->getUserData() == HK_NULL )
{
ContactPointInfo* info = new ContactPointInfo;
info->m_uniqueId = m_uniqueIdCounter++;
event.m_contactPointProperties->setUserData( reinterpret_cast<hkUlong>(info) );
//
// printf some information
//
if (m_reportLevel >= hkDemoEnvironment::REPORT_INFO)
{
if ( event.isToi() )
{
hkprintf("Toi userId=%i created\n", info->m_uniqueId );
}
else
{
int cpId = event.asManifoldEvent().m_contactPointId;
hkprintf("Contact Point userId=%i created: contactId=%i\n", info->m_uniqueId, cpId );
}
}
}
// By setting the ProcessContactCallbackDelay to 0 we will receive callbacks for
// any collisions processed for this body every frame (simulation step), i.e. the delay between
// any such callbacks is 0 frames.
// If you wish to only be notified every N frames simply set the delay to be N-1.
// The default is 65536, i.e. (for practical purpose) once for the first collision only, until
// the bodies separate to outside the collision tolerance.
event.m_callbackFiredFrom->setProcessContactCallbackDelay(0);
}
Example#2
void MyExtendedUserDataListener::contactPointAddedCallback( hkpContactPointAddedEvent& event )
{
//
// Read the shape key hierarchy -- this is done identically for both Psi and Toi contact points.
//
hkpShapeKey shapeKey;
{
// This is the body to which the listener is attached.
hkpEntity* body = event.m_callbackFiredFrom;
// Extended user data only works when you use the default hkpSimpleConstraintContactMgr.
// The function below will assert otherwise.
// The atom caches information on how many extended user datas we store for each body.
// Each body stores its data independently.
const int numDatas = event.getNumExtendedUserDatas(event.m_callbackFiredFrom);
// Now we can read the data.
// The first user data stores the hkpShapeKey of the bottom most hkpCdBody in the shape hierarchy,
// the next one stores hkpShapeKey of its parent, and so on, till we store '-1' as the hkpShapeKey
// of the root collidable, or we run out of extended user data slots, in which case only a part
// of the hierarchy is stored.
//
// In this demo we expect to have:
// extendedUserDatas[0] in the [0,7] range -- this is the hkpShapeKey of one of the 8 transformed sphere shapes grouped under a hkpListShape
// extendedUserDatas[1] equal -1 -- this is the root hkpListShape, with no parent, and therefore no hkpShapeKey
//
// Note that we only have two levels of hierarchy, while our shape is composed of hkpListShape->hkpConvexTransformShape->hkpSphereShape.
// That's because hkpConvexTransform/TranslateShapes don't create a corresponding hkpCdBody during collision detection.
// Note that the above is not the case for the deprecated hkpTransformShape.
hkInplaceArray<hkpContactPointProperties::UserData,8> data; data.setSize(numDatas);
event.getExtendedUserDatas(body, data.begin(), numDatas);
// Let us store our custom contact point id. Let's store it in the last data slot to avoid overwriting the hkpShapeKey hierarchy.
// We know we have enough room, as we set entity->m_numUserDatasInContactPointProperties = 3 which is more that the max hierarchy depth for our shape.
data[numDatas-1] = m_uniqueIdCounter++;
// And write back all datas
event.setExtendedUserDatas(body, data.begin(), numDatas);
// Get the hkpShapeKey
shapeKey = data[0];
}
// Sample demo structure holding history about callbacks triggered for this contact point.
{
ContactPointInfo& info = m_contactInfos.expandOne();
new (&info) ContactPointInfo();
HK_ASSERT2(0xad7853aa, m_contactInfos.getSize() == m_uniqueIdCounter, "Unique ID is not in synch with m_contactInfos array.");
info.m_type = event.isToi() ? ContactPointInfo::TOI : ContactPointInfo::PSI;
info.m_added = true;
info.m_key = int(shapeKey);
}
// By setting the ProcessContactCallbackDelay to 0 we will receive callbacks for
// any collisions processed for this body every frame (simulation step), i.e. the delay between
// any such callbacks is 0 frames.
// If you wish to only be notified every N frames simply set the delay to be N-1.
// The default is 65536, i.e. (for practical purpose) once for the first collision only, until
// the bodies separate to outside the collision tolerance.
event.m_callbackFiredFrom->setProcessContactCallbackDelay(0);
}