NaNs in hkpMeshWeldingUtility::computeWeldingInfo

NaNs in hkpMeshWeldingUtility::computeWeldingInfo

Hi!

I'm using Havok 7.1 R1

I'm setting the FP control word to raise exceptions on NaNs & denormals.
And I'm getting QNaNs inside hkpMeshWeldingUtility::computeWeldingInfo
Is this normal? Havok full debug isn't warning anything other than advising I should do this offline.

The full stack trace is:

>	Distant Souls.exe!hkAreTrianglesEqual(const hkpTriangleShape * triangle0=0x033ff4d0, const hkpTriangleShape * triangle1=0x033ff6d0)  Line 140	C++

 	Distant Souls.exe!hkpMeshWeldingUtility::computeWeldingInfoMultiShape(const hkTransform & meshTransform={...}, hkpShapeCollection * mesh=0x0928f660, hkpWeldingUtility::WeldingType weldingType=WELDING_TYPE_ANTICLOCKWISE, hkArray & allShapes={...}, bool weldOpenEdges=true)  Line 361 + 0x13 bytes	C++

 	Distant Souls.exe!hkpMeshWeldingUtility::computeWeldingInfo(hkpShapeCollection * collection=0x0928f660, const hkpBvTreeShape * bvTree=0x092865c0, hkpWeldingUtility::WeldingType weldingType=WELDING_TYPE_ANTICLOCKWISE, bool weldOpenEdges=true)  Line 258	C++

 	Distant Souls.exe!TLW::GameObjectType::createMeshShape(const TLW::BasicShapesParam & shapeParam={...})  Line 227 + 0x14 bytes	C++

It's happening with some (not all) of my meshes, so I wanted to know if this is expected behavior or not (i.e. Havok expects a few NaNs and handles them gracefully, except this time the HW is raising an exception first)

May be I'm doing something wrong (I doubt it since the sample code is very clear and simple) or if there are certain requirements about the vertex/index data I'm not aware of (i.e. no degenerate triangles, memory padding after a few vertices, memory alignment, etc).
The simulation runs as expected, shall I note. But it's troublesome to have QNaN exceptions in that place when I enable them while trying to catch potential bugs overall in the app.

Just in case, the code I use to build up the MOPP is:

#include "UnDeclareDebugNew.h"

hkpExtendedMeshShape *meshShape = new hkpExtendedMeshShape( /*shapeParam.fRadius*/ );

#include "DeclareDebugNew.h"
for( size_t i=0; iaddTrianglesSubpart( part );

}
hkpMoppCode* moppCode = hkpMoppUtility::buildCode( meshShape, hkpMoppCompilerInput() );
#include "UnDeclareDebugNew.h"

hkpMoppBvTreeShape *retVal = new hkpMoppBvTreeShape( meshShape, moppCode );

#include "DeclareDebugNew.h"

hkpMeshWeldingUtility::computeWeldingInfo( meshShape, retVal,

											hkpWeldingUtility::WELDING_TYPE_ANTICLOCKWISE );

moppCode->removeReference();

meshShape->removeReference();

Where shapeParam.vertices[i] is of type std::vector, and shapeParam.indices[i] is of type std::vector
There are no special considerations in the memory alignment of those containers (afaik std::vector should make them 4-byte aligned in an x86; but haven't checked yet).
The vertex data is copied first from an Ogre mesh file, which is rendered correctly.

So, I would like to know if this is expected behavior, a fixed bug from Havok, or an error on my end I should start worrying about.

Thanks in advance.
Cheers
Matias

Matias N. Goldberg
Intel Havok Physics Innovation Contest Winner
* Most Innovative Use of Physics in a Game (2nd Place)
* Best Physics Knowledge Base Entry (2nd Place)
5 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.
Best Reply

HiMatias,

I just looked in to this and I can confirm that NaNs are generated in normal use-cases but are safely ignored. The technical details here are we use a 4-component vector for simd operations, but since we only use the XYZ here, the W component commonly gets NaN'd in certain operations.

Under windows you can wrap your calls to computeWeldingInfo() in calls to _controlfp() to set and clear the fpu exception flags so that you still get them for your code, but don't hit benignHavok ones.

Cheers,
Tyler

Thanks for the promptly answer. I tried to wrap between _controlfp but somehow it crashed when I restored the FPU flags. May be I forgot to clear the exception flag correctly. I was too tired when I tried that last part.

Cheers
Matias

Matias N. Goldberg
Intel Havok Physics Innovation Contest Winner
* Most Innovative Use of Physics in a Game (2nd Place)
* Best Physics Knowledge Base Entry (2nd Place)

I'm no expert on the windows fpu control settings, but IIRC something like this should work:

_clearfp();

_controlfp( exceptionUnMaskParams );
// code that throws on fpu
_controlfp( _CW_DEFAULT, ~0u ); // restore all defaults

I think you can also do something to store the current state in a bitmask, and then re-set that instead of restoring defaults but I'd have to look that up.

-Tyler

Oh I see, I forgot the _clearfp call. Thanks, you saved me a google ;)

Matias N. Goldberg
Intel Havok Physics Innovation Contest Winner
* Most Innovative Use of Physics in a Game (2nd Place)
* Best Physics Knowledge Base Entry (2nd Place)

Kommentar hinterlassen

Bitte anmelden, um einen Kommentar hinzuzufügen. Sie sind noch nicht Mitglied? Jetzt teilnehmen