hkpSimpleMeshShape won't come to rest
Hey,
first of all thanks for Intel making Havok available like this. And this forum seems really great.
I've got a problem I hope you could help with. I've done a simple test project that creates two hkpSimpleMeshShapes (just boxes) from my mesh triangle data, and they appear to form correctly in the Visual Debugger, but when the box drops on the another one and is supposed to settle in to rest, it instead jumps away.

With worldInfo.m_contactRestingVelocity = 0.01f, it is even crazier.

This is what I have in worldInfo:
worldInfo.m_gravity.set(0.0f, -9.8f, 0.0f);
worldInfo.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_8ITERS_MEDIUM);
worldInfo.m_collisionTolerance = 0.01f;
//worldInfo.m_contactRestingVelocity = 0.01f;
This is how I create the boxes:
// Create the floor as a fixed box
{
hkpRigidBodyCinfo boxInfo;
hkpSimpleMeshShape* shape2 = new hkpSimpleMeshShape( 0.1f );
shape2->m_vertices.setSize( mesh2.numVertices );
for(int i=0; i<mesh2.numVertices; i++)
{
//sprintf(str, "vertex %i: %f, %f, %f", i, mesh2.vertexList[i].p.x, mesh2.vertexList[i].p.y, mesh2.vertexList[i].p.z); cprint(str);
shape2->m_vertices[i].set(
mesh2.vertexList[i].p.x,
mesh2.vertexList[i].p.y,
mesh2.vertexList[i].p.z,
0.0f );
}
//sprintf(str, "numfaces: %i", mesh.numFaces); cprint(str);
shape2->m_triangles.setSize( mesh.numFaces );
for(int i=0, k=0; k<mesh2.numFaces; i+=3, k++)
{
//sprintf(str, "faces %i: %i, %i, %i", k, mesh2.faceList[i], mesh2.faceList[i+1], mesh2.faceList[i+2]); cprint(str);
shape2->m_triangles[k].m_a = mesh2.faceList[i+2];
shape2->m_triangles[k].m_b = mesh2.faceList[i+1];
shape2->m_triangles[k].m_c = mesh2.faceList[i+0];
}
{
hkpMoppCompilerInput mci;
hkpMoppCode *moppCode = hkpMoppUtility::buildCode( shape2, mci );
hkpMoppBvTreeShape* moppShape = new hkpMoppBvTreeShape( shape2, moppCode );
shape2->computeWeldingInfo( moppShape, hkpWeldingUtility::WeldingType::WELDING_TYPE_ANTICLOCKWISE );
moppCode->removeReference();
}
boxInfo.m_shape = shape2;
boxInfo.m_motionType = hkpMotion::MOTION_FIXED;
boxInfo.m_position.set(0.0f, 0.0f, 0.0f);
boxInfo.m_restitution = 0.9f;
g_floor = new hkpRigidBody(boxInfo);
shape2->removeReference();
physicsWorld->addEntity(g_floor);
g_floor->removeReference();
}
// Create a moving box
hkpSimpleMeshShape* shape = new hkpSimpleMeshShape( 0.1f );
shape->m_vertices.setSize( mesh.numVertices );
for(int i=0; i<mesh.numVertices; i++)
{
shape->m_vertices[i].set(
mesh.vertexList[i].p.x,
mesh.vertexList[i].p.y,
mesh.vertexList[i].p.z,
0.0f );
}
shape->m_triangles.setSize( mesh.numFaces );
for(int i=0, k=0; k<mesh.numFaces; i+=3, k++)
{
shape->m_triangles[k].m_a = mesh.faceList[i+0];
shape->m_triangles[k].m_b = mesh.faceList[i+1];
shape->m_triangles[k].m_c = mesh.faceList[i+2];
}
{
hkpMoppCompilerInput mci;
hkpMoppCode *moppCode = hkpMoppUtility::buildCode( shape, mci );
hkpMoppBvTreeShape* moppShape = new hkpMoppBvTreeShape( shape, moppCode );
shape->computeWeldingInfo( moppShape, hkpWeldingUtility::WeldingType::WELDING_TYPE_ANTICLOCKWISE );
moppCode->removeReference();
}
const hkReal boxDim = 15.0f; // This is the size of the cubes
const hkReal extBoxDim = 1.1f * boxDim; // This is an extended size (used to shorten the pendulums)
hkVector4 boxRadii(boxDim *.5f, boxDim *.5f, boxDim *.5f);
hkpShape* boxShape = new hkpBoxShape( boxRadii , 0 );
hkpMassProperties massProperties;
hkpInertiaTensorComputer::computeBoxVolumeMassProperties(boxRadii, 110.0f, massProperties);
hkpRigidBodyCinfo boxInfo;
boxInfo.m_inertiaTensor = massProperties.m_inertiaTensor;
boxInfo.m_mass = massProperties.m_mass;
boxInfo.m_shape = shape;
//boxInfo.m_shape = boxShape;
boxInfo.m_qualityType = HK_COLLIDABLE_QUALITY_CRITICAL;
boxInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;
boxInfo.m_position.set(0.0f, 30.0f, -2.0f);
// Create RigidBody
hkpRigidBody* RigidBody = new hkpRigidBody(boxInfo);
shape->removeReference();
physicsWorld->addEntity(RigidBody);
g_ball = RigidBody;
RigidBody->removeReference();
Also I have another test project that creates a vehicle chassis with the same method, and the floor like this:
// Create the floor as a fixed box
{
hkpRigidBodyCinfo boxInfo;
hkVector4 boxSize(50.0f, 2.5f , 50.0f);
hkpBoxShape* boxShape = new hkpBoxShape(boxSize);
boxInfo.m_shape = boxShape;
boxInfo.m_motionType = hkpMotion::MOTION_FIXED;
boxInfo.m_position.set(0.0f, 0.0f, 0.0f);
boxInfo.m_restitution = 0.9f;
hkpRigidBody* floor = new hkpRigidBody(boxInfo);
boxShape->removeReference();
physicsWorld->addEntity(floor);
floor->removeReference();
}
The behaviour is again quite strange. Download this Visual Debugger movie file test.hkm to see.
If I create just a normal hkpBoxShape instead of hkpSimpleMeshShape, it settles on the ground nicely.
Sorry this was a lot of text, but hopefully you could provide some assistance.
Best Regards,
vfgdfg
| |
Re: hkpSimpleMeshShape won't come to rest
Hi vfgdfg,
This is a pretty cool post with the gifs and everything.
Just a few observations which might help you get past this.The hkpSimpleMeshShape is kind of on the outs. The hkpExtendedMeshShape is a better solution, but if you are doing convex shapes then the hkpConvexVerticesShape. The hkpBoxShape would be best, as you have mentioned.
We have seen a few things with the hkpSimpleMeshShape and welding. You can try turning this off and seeing if that gets you anywhere.
It is also not a great idea to have moving MOPPs. You are going to want to use a MOPP for your static geometry.
Give those a try and see if that gets it working. We'll go from there if you are still experiencing problems.
Thanks, Sean
Developer Support Engineer
Havok
www.havok.com | |
Re: hkpSimpleMeshShape won't come to rest
Hi,
thanks for the response. I commented out the welding code from both shapes and it fixed it! The box still does drop off though, but it does it quite naturally and because of the -2 Z-position of the box :)

If I set the Z to zero, it settles on the other box nicely after some sliding.
I actually copy pasted the welding code from this forum, hoping it would the missing piece to my original problem, which was when the boxes came to contact, the whole application crashed. But upgrading to Havok 6 fixed that, leaving only the bizzarre behaviour problem, which is now fixed, thanks.
The vehicle test acts still all weird after commenting the welding code, but I'll have to do further testing tomorrow and try that hkpExtendedMeshShape you suggested. I'll get back to you with the results.
Thanks a lot for the help.
Best Regards,
vfgdfg
| |
Re: hkpSimpleMeshShape won't come to rest
Hi,
I have now replaced the other shape in my code to hkpExtendedMeshShape. I'm creating just one test triangle to it for now. But something's wrong, it now crashes to physicsWorld->addEntity(g_floor);
hkpExtendedMeshShape* shape2 = new hkpExtendedMeshShape();
hkpExtendedMeshShape::TrianglesSubpart part;
float verts[9];
verts[0]=0; verts[1]=1; verts[2]=2;
verts[3]=3; verts[4]=4; verts[5]=5;
verts[6]=6; verts[7]=7; verts[8]=8;
part.m_vertexBase = verts;
part.m_vertexStriding = sizeof(float)*3;
part.m_numVertices = 3;
unsigned short faces[3];
faces[0]=0; faces[1]=3; faces[2]=6;
part.m_indexBase = faces;
part.m_indexStriding = sizeof( unsigned short)*3;
part.m_numTriangleShapes = 1;
part.m_stridingType = hkpExtendedMeshShape::INDICES_INT16;
shape2->addTrianglesSubpart( part );
boxInfo.m_shape = shape2;
boxInfo.m_motionType = hkpMotion::MOTION_FIXED;
boxInfo.m_position.set(0.0f, 0.0f, 0.0f);
boxInfo.m_restitution = 0.9f;
g_floor = new hkpRigidBody(boxInfo);
shape2->removeReference();
physicsWorld->addEntity(g_floor);
Would you have any ideas what could be wrong?
Best Regards,
vfgdfg
| |
Re: hkpSimpleMeshShape won't come to rest
Hey vfgdfg,
Are you running in debug or release? Which version of Havok are you running? Are you getting an assert or a crash? What is the callstack for this crash/assert? There is a lot of debug code in Havok that will throw asserts which are designed to help you when you might be doing something wrong or unsafe. I tried that code out real quick and I didn't get either. Maybe I reproed it incorrectly.
Thanks, Sean
Developer Support Engineer
Havok
www.havok.com | |
Re: hkpSimpleMeshShape won't come to rest
Hi,
to be honest I'm not good at debugging C++, most of the time I run outside the debugger and output text to my log file for debugging purposes. Having said that, the Havok version is hk600r1, I am on debug mode (tried quickly to switch to release and changed the libs but got some linking errors, didn't start fighting with that any further yet). I think it's a crash but not really sure, not very familiar with asserts. Here's a shot of the state I'm thrown into when it breaks:

Best Regards,
vfgdfg
| |
Re: hkpSimpleMeshShape won't come to rest
Hi vfgdfg,
Is the physicsWorld->addEntity(g_floor) the last line of your method? I am not liking those memory frees and I am not sure why they are being called before the Havok methods. Is it possible for you to post the entire callstack so I can see the whole progression. You should be able to copy and paste the callstack from Visual Studio to a text editor.
This looks like a crash and not an assert, asserts write out to the ouput window if you take a look there.
Thanks, Sean
Developer Support Engineer
Havok
www.havok.com | |
Re: hkpSimpleMeshShape won't come to rest
Hi,
there's this line:
g_floor->removeReference();
below the physicsWorld->addEntity(g_floor), but the g_floor->removeReference() is the one it seems to crash to, if I have debug outputs to the log before each call, this call is the last it outputs before. Yes I have more code after this but the bit I posted is in it's own { } block. Well actually the code continues exactly from row 50 in the code I posted above, I just replaced the hkpSimpleMeshShape creation with this piece of code.
Here comes the whole stack:
Test.exe!hkEntityAabbUtil::entityBatchRecalcAabb(const hkpCollisionInput * collisionInput=0x00fa8e80, hkpEntity * const * entityBatch=0x0012f368, int numEntities=1) Line 125 + 0xa3 bytes C++
ntdll.dll!7c9268ad()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c9268ad()
Test.exe!hkp3AxisSweep::addObject(hkpBroadPhaseHandle * object=, const hkAabbUint32 & aabbIn=, hkArray<hkpBroadPhaseHandlePair> & newPairs=) Line 1556 + 0x11 bytes C++
ntdll.dll!7c90e5e5()
ntdll.dll!7c90e9ff()
kernel32.dll!7c810e16()
kernel32.dll!7c810e36()
kernel32.dll!7c810e36()
> Test.exe!_write_nolock(int fh=7469004, const void * buf=0x00fa0000, unsigned int cnt=0) Line 301 + 0x3c bytes C
ntdll.dll!7c91056d()
Test.exe!_CrtIsValidHeapPointer(const void * pUserData=0x0071a904) Line 1963 C++
Test.exe!_free_dbg_nolock(void * pUserData=0x00000004, int nBlockUse=7360125) Line 1329 + 0x9 bytes C++
Test.exe!_free_dbg(void * pUserData=0x00fa3818, int nBlockUse=1) Line 1199 + 0x7 bytes C++
Test.exe!_Mtxunlock(_RTL_CRITICAL_SECTION * _Mtx=0x00fa3818) Line 54 C
Test.exe!free(void * pUserData=0x00fa3818) Line 1152 + 0xb bytes C++
Test.exe!std::_DebugHeapDelete<std::locale>() + 0x16 bytes C++
Test.exe!std::ios_base::_Ios_base_dtor(std::ios_base * _This=0x0012f7b4) Line 58 + 0xc bytes C++
Test.exe!cprint() + 0xc9 bytes C++
ntdll.dll!7c96e0d4()
ntdll.dll!7c926abe()
ntdll.dll!7c926abe()
ntdll.dll!7c926abe()
ntdll.dll!7c9268ad()
ntdll.dll!7c926abe()
ntdll.dll!7c9268ad()
wl_hook.dll!1000a548()
wl_hook.dll!1000a35f()
wl_hook.dll!10009d4d()
wl_hook.dll!10009f4d()
wl_hook.dll!10009f23()
wl_hook.dll!10009f01()
wl_hook.dll!10009a1b()
wl_hook.dll!10009868()
wl_hook.dll!1000727a()
wl_hook.dll!10020d26()
ntdll.dll!7c90e03c()
kernel32.dll!7c8213c0()
dinput8d.dll!6d31c636()
dinput8d.dll!6d31c6cf()
dinput8d.dll!6d31c6dd()
dinput8d.dll!6d315c86()
Test.exe!_openfile(const char * filename=0x00000078, const char * mode=0x003c5948, int shflag=3932160, _iobuf * str=0x7c926abe) Line 221 + 0x6d bytes C
ntdll.dll!7c96e0d4()
ntdll.dll!7c96e0d4()
ntdll.dll!7c94a5d0()
ntdll.dll!7c926abe()
kernel32.dll!7c809e80()
kernel32.dll!7c80bcfe()
dinput8d.dll!6d332b5f()
dinput8d.dll!6d30a9a0()
dinput8d.dll!6d30aa94()
dinput8d.dll!6d30a9a0()
dinput8d.dll!6d30aa94()
dinput8d.dll!6d30a9a0()
dinput8d.dll!6d30a9a0()
ntdll.dll!7c90fb6c()
ntdll.dll!7c90fb71()
ntdll.dll!7c90e20a()
kernel32.dll!7c80261a()
dinput8d.dll!6d30a9a0()
dinput8d.dll!6d30aa94()
dinput8d.dll!6d335ced()
dinput8d.dll!6d30a9a0()
dinput8d.dll!6d30aa94()
dinput8d.dll!6d30a9a0()
dinput8d.dll!6d30aa94()
dinput8d.dll!6d30a9a0()
dinput8d.dll!6d30aa94()
ntdll.dll!7c90d592()
advapi32.dll!77dd6bcc()
dinput8d.dll!6d30a9a0()
dinput8d.dll!6d30aa94()
dinput8d.dll!6d30c2c4()
dinput8d.dll!6d30c2e5()
dinput8d.dll!6d30f6e7()
dinput8d.dll!6d30e48e()
dinput8d.dll!6d30f713()
Test.exe!InitKeyb() + 0xab bytes C++
Test.exe!hkMatrix6::sub() + 0x10061c bytes C++
Test.exe!_WinMain@16() + 0x13c bytes C++
Test.exe!__tmainCRTStartup() Line 315 + 0x35 bytes C
Test.exe!WinMainCRTStartup() Line 187 C
kernel32.dll!7c816ff7()
Best Regards,
vfgdfg
| |
Re: hkpSimpleMeshShape won't come to rest
Hi vfgdfg,
I'm not quite sure what is causing this crash. My suggestion is to take this code out of your program and put it into the demo framework. It should be pretty easy to do that. Then, see if it still crashes. I haven't been able to reproduce the crash you are seeing. If you can get the crash in the demo framework, let me know the details.
Thanks for posting the call stack. Sorry I can't be more helpful at this time.
-Sean
Developer Support Engineer
Havok
www.havok.com | |
Re: hkpSimpleMeshShape won't come to rest
Hi,
I replaced the vehicle hull creation code in the vehicleapi demo and got kind of similiar result (entityBatchRecalcAabb):
Demos_win32-net_8-0_debug_multithreaded.exe!hkEntityAabbUtil::entityBatchRecalcAabb(const hkpCollisionInput * collisionInput=0x016739e0, hkpEntity * const * entityBatch=0x016747b4, int numEntities=1) Line 82 + 0x76 bytes C++
Demos_win32-net_8-0_debug_multithreaded.exe!hkpMotion::getNumInactiveFramesMt(int select=0, int worldDeactivationNumInactiveFramesSelectFlag=1065353216) Line 188 + 0x19 bytes C++
Demos_win32-net_8-0_debug_multithreaded.exe!hkpMotion::zeroNumInactiveFramesMt(int select=1030071700, int worldDeactivationNumInactiveFramesSelectFlag=1065353216) Line 215 + 0xe bytes C++
Demos_win32-net_8-0_debug_multithreaded.exe!hkRigidMotionUtilApplyForcesAndStep(const hkpSolverInfo & solverInfo={...}, const hkStepInfo & info={...}, const hkVector4 & deltaVel={...}, hkpMotion * const * motions=0x00000000, int numMotions=0, int motionOffset=0) Line 271 + 0x11 bytes C++
Demos_win32-net_8-0_debug_multithreaded.exe!hkMultiThreadCheck::accessCheck(hkMultiThreadCheck::AccessType type=48) Line 188 + 0xf bytes C++
d3d9.dll!4fe758f4()
[Frames below may be incorrect and/or missing, no symbols loaded for d3d9.dll]
Demos_win32-net_8-0_debug_multithreaded.exe!hkJobQueue::addJob(hkJob & job=, hkJobQueue::JobPriority priority=) Line 714 C++
Demos_win32-net_8-0_debug_multithreaded.exe!hkJobQueue::addJob(hkJob & job=, hkJobQueue::JobPriority priority=) Line 714 + 0xf bytes C++
Demos_win32-net_8-0_debug_multithreaded.exe!hkpMultiThreadedSimulation::processNextJob(hkJobQueue & jobQueue={...}, hkJobQueue::JobQueueEntry & job={...}) Line 126 + 0xb bytes C++
Demos_win32-net_8-0_debug_multithreaded.exe!hkJobQueue::processAllJobs() Line 434 C++
Demos_win32-net_8-0_debug_multithreaded.exe!hkpWorld::stepMultithreaded(hkJobQueue * jobQueue=0x028d7910, hkJobThreadPool * threadPool=0x028d7b20, float physicsDeltaTime=0.016000001) Line 2358 C++
> Demos_win32-net_8-0_debug_multithreaded.exe!hkDefaultPhysicsDemo::stepDemo() Line 372 C++
Demos_win32-net_8-0_debug_multithreaded.exe!VehicleApiDemo::stepDemo() Line 209 C++
Demos_win32-net_8-0_debug_multithreaded.exe!MenuDemo::stepCurrentDemo() Line 1118 + 0x14 bytes C++
d3d9.dll!4fe09994()
d3d9.dll!4fe6560f()
d3d9.dll!4fe6561d()
Demos_win32-net_8-0_debug_multithreaded.exe!hkgDisplayContextDX9S::setBlendState(bool on=true) Line 152 C++
d3d9.dll!4fe10780()
d3d9.dll!4fe10f79()
Demos_win32-net_8-0_debug_multithreaded.exe!hkgDisplayContext::unlock() Line 455 C++
Demos_win32-net_8-0_debug_multithreaded.exe!render(hkgWindow * window=0x00000000, const hkDemoEnvironment & env={...}, hkDemo * demo=) Line 878 C++
Demos_win32-net_8-0_debug_multithreaded.exe!render() Line 878 + 0x10 bytes C++
d3d9.dll!4fe51c64()
d3d9.dll!4fe55836()
d3d9.dll!4fdf5e25()
d3d9.dll!4fe55845()
d3d9.dll!4fe78933()
d3d9.dll!4fe5714f()
Demos_win32-net_8-0_debug_multithreaded.exe!hkgWindowDX9SPC::clearBuffers() Line 659 C++
Demos_win32-net_8-0_debug_multithreaded.exe!hkgDisplayContext::unlock() Line 455 C++
Demos_win32-net_8-0_debug_multithreaded.exe!hkFrameworkMain(hkDemoFrameworkOptions & options={...}, char * startUpDemo=0x00da7b10) Line 1333 C++
Demos_win32-net_8-0_debug_multithreaded.exe!main(int argc=1, char * * argvIn=0x01663b08) Line 35 + 0xf bytes C++
Demos_win32-net_8-0_debug_multithreaded.exe!__tmainCRTStartup() Line 318 + 0x19 bytes C
Demos_win32-net_8-0_debug_multithreaded.exe!mainCRTStartup() Line 187 C
kernel32.dll!7c816ff7()
You can download the new VehicleApiDemo.cpp here
Best regards,
vfgdfg
| |
Re: hkpSimpleMeshShape won't come to rest
Hi vfgdfg,
My advice is not to use a single triangle for you vehicle. Try using a convex vertices shape. I was experiencing problems with calculating the inertia tensor using your code. Did you not hit that problem? ExtendedMeshShapes are really good for fixed terrain. You are probably going to experience slow downs if you use it for dynamic collisions as a collision agent will be created for each triangle.
Thanks, Sean
Developer Support Engineer
Havok
www.havok.com | | |