Welding problems

Welding problems

On regular flat ground I am getting hops when I traverse over the edges of the triangles, so I set up my welding like so:

	hkpMoppCompilerInput mci;
hkpMoppCode *moppCode = hkpMoppUtility::buildCode( shape_mesh, mci );

hkpMoppBvTreeShape* moppShape = new hkpMoppBvTreeShape( shape_mesh, moppCode );
shape_mesh->computeWeldingInfo( moppShape, hkpWeldingUtility::WeldingType::WELDING_TYPE_ANTICLOCKWISE );


I have a few problems:

  • If I use SIMULATION_TYPE_DISCRETE the welding doesn't seem to work at all, my character pops up and looking at the contact planes in the visual debugger I see that the neighboring triangle is responsible. If I use SIMULATION_TYPE_CONTINUOUS it does work, and is probably preferable to discrete, but I'm curious why it's not working in discrete.
  • My second problem is that if I have geometry setup using exact coordinates, where the edge of two convex shapes is shared (not by actual vertices, but in physical location), I get errors in the compute welding information telling me that I cannot use one sided welding. I can imagine the technical challege this presents, since you're only given the triangles as input and you have to decide how they are connected (aparently by location of vertices), but couldn't you just reject welding the edge if the face of the triangles is not facing the same direction? Or just throw a warning instead of bailing out?
  • Also even when welding IS working, I have strange strange contact normals even with very small steps. I have my max slope set to 90, so I doubt that is the problem.
    • info.m_maxSlope = 90 * HK_REAL_DEG_TO_RAD;

I have attached a screenshot from the VDB of the welding not working (right), and the strange extra contact normals (left).


Descargar weldingIssues.GIF77.4 KB
publicaciones de 10 / 0 nuevos
Último envío
Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.

Oh yeah, and by the way, the m_enableDeprecatedWelding works much better (it doesn't have the above mentioned problems).

However, even with m_enableDeprecatedWelding, I get some issues. I've attached another file.

This one shows the player passing over the edge of a step from high to low (left), and climbing a stair (right).
The two frames on the left show the before and after going down the step, and the two frames on the right show the before and after climbing the step.

The issue climbing the stair is that the contact point is maintained with the edge of the step even after I've passed over it. This doesn't *normally* affect the movement, but if I reverse and head back down the stair I get feedback from this extra contact point.

The plane from the edge of the step gets steeper as I move away from it to the right (beyond the step after I have climbed it).



Descargar weldingIssues.GIF77.4 KB

Hey John,

The "new" welding works by finding adjacent triangles and saving the welding information out so at runtime it can calculate what the correct normals are. Because of this, non-shared edges aren't going to work with new welding. The first thing to try is making sure that you don't have non-shared edges in your geometry and if you're still seeing some bad behavior there are a few more things you could try.

Because the rigid body character controller uses the same collision tolerance as the rest of the world, you can sometimes get trouble when using it with the new welding. You could try setting hkpWorldCinfo.m_collisionTolerance to about 0.01 instead of 0.1 and see how this affects your behavior.

You could also try rejecting contact points that give bad normals too, by using a collision listener. In the listener you could check if the collision is at an edge, and if it is, either discard it or just use the triangle's normal instead of the normal provided by the welding. Of course this isn't going to do a lot for your performance, but it's something to play with.

Hope this helps you get around these problems! Let me know how you get on.



An example of what I meant about a shared edge that's reversed is if you have steps created from boxes:

I just think in this situation it should be solvable. The top face of the bottom box could be connected to the front face of the upper box (along the edge in question), and a similar pairing on the bottom OR the bottom box is welded separately from the upper box. Either way is acceptable, but failing completely for one-sided winding is not good.

I realize that the collision data should probably be modeled more carefully if one is to use the new welding, which is not obvious from my screen shots but in the testing scene there I have two sets of stairs side by side, ones that have a continuous mesh, and another made of boxes offset from each other (non-welded).

I'm pretty sure on my continuous mesh, that the vertices are shared in the modeling program, though I'll double check that they are in fact. I suppose it's possible if they aren't actually shared there could be floating-point discrepancies that prevent the havok welding from working properly.

The screenshots I've posted are all from the steps of the (supposedly) continuous mesh.

I have not yet tried to profile the difference between the deprecated welding method and the new welding method, but are there benefits other than performance?

I have played with my world collision tolerance trying to fix another issue I'm having with undesired feedback to the velocity (I'll post about that tonight), but I'll give it another shot and see if it helps eliminate the extra vertical collision surface.



Descargar sharedEdge.jpg2.16 KB

First of all, I examined my mesh closely and the continuous mesh is in fact continuous. I checked the vertices and they are welded in maya, thus the same index is used in the vertex array and I'm confident it's not like some slight floating point discrepency that's causing the anamalous contact points to be added.

Secondly I had a chance to play with the collision tollerance, and indeed turning it down seems to really help with the erroneous contact points. I am however curious how simply climbing over a very small ledge (even if the contact points are added within a radius of the capsule), that I could get a contact plane perpendicular with the ground plane.

I tested this very thoroughly by recoding the VDB data and stepping through the frames to see if there were any cases of the strange contact planes and it seems to have solved that particular issue, but in doing so has made the other issue I eluded to in my previous post even worse.

I'll discuss the other issue in a new thread:
Velocity feedback and bouncing with Character Rigid Body

Also, I tested two sets of sequentially larger steps. One which was a continuous welded mesh, and the other was a set of boxes (also individually welded), offset from each other in the same fashon. With the new collision tolerance they both seem to function fine. I couldn't really tell the difference between the two.

I'm curious about the method you described for checking the contact points and editing them as they are added. I'm hoping for steps I can snap the normal from the contact with the edge of the next step to world up, instead of pointing in towards my character proxy. However this means I need to be able to detect that it is a step, and not a ramp. I can probably come up with something if I can see what the two faces are that are connected to the edge. Is there a way to find this infomation?


Are we considering the collision tolerance the fix to this issue, or are there other things I can try to prevent the strange contact planes?
I don't think I want to try manual rejection of contact points.

Is this potentially a havok bug or is there a valid reason for the vertical contact plane? I can't see what is generating it.

If I can work with the small collision tolerance and it doesn't break other aspects of the dynamics I'll try to make it work. It seemed like you eluded that this is only a problem with the character rigid body, and by elimination do you mean this isn't a problem as much with the character proxy method? I went with the character rigid body because it seemed like it's the preferred approach now.



Right now I would suggest trying out two-sided welding if you haven't already and see how that works out. It's possible that you might get less of those irregular normals.

This issue has come up before with character rigid body but I don't believe it has with character proxy (though that's no guarantee that with your code and assets it will solve all your problems). The character proxy is a little slower than the character rigid body but neither is specifically preferred: feel free to try them both out and see which gives you the results you need.

There is a demo under Physics->UseCase->CharacterController->CharacterProxyVsRigidBody which shows how both of the controllers interact with the environment. Maybe you could load your asset into this demo and see how the two different controllers react to your environment?

Sorry for not having an exact answer for what's going wrong; this is something that has just come up recently but it's been logged and will be investigated to see whether or not it's a bug in Havok.


Hi John,

Can you verify that your normals for your triangular mesh are consistent, e.g. point in the same direction, in Maya. If the triangle winding is inconsistent, then the welding (new or deprecated) is not going to work.

David W.

I'm absolutely sure the normals are legit.

I literally just made a new test scene in maya I created two boxes, both unit length, one is created at the origin, the next is offset +1 in the x, and +1 in the y:

But I was wrong about the crashing. It was just an assert. Hopefully it properly skips the triangles it fails on, and it succeeds in a valid case. The assert is kind of annoying though, it could be made to check for other valid cases before throwing the assert. Here is the output of the two boxes you see above:

.UtilWeldinghkpMeshWeldingUtility.cpp(158): [0xfe98751e] Assert : 'orderedEdgeVerticesOnTriangle1[0] == ( orderedEdgeVerticesOnTriangle1[1] + 1 ) % 3
Inconsistant triangle winding between triangle 7and triangle 1048578.: One sided welding will not work.'
.UtilWeldinghkpMeshWeldingUtility.cpp(158): [0xfe98751e] Assert : 'orderedEdgeVerticesOnTriangle1[0] == ( orderedEdgeVerticesOnTriangle1[1] + 1 ) % 3
Inconsistant triangle winding between triangle 10and triangle 1048585.: One sided welding will not work.'
.UtilWeldinghkpMeshWeldingUtility.cpp(158): [0xfe98751e] Assert : 'orderedEdgeVerticesOnTriangle1[0] == ( orderedEdgeVerticesOnTriangle1[1] + 1 ) % 3
Inconsistant triangle winding between triangle 1048578and triangle 7.: One sided welding will not work.'
.UtilWeldinghkpMeshWeldingUtility.cpp(158): [0xfe98751e] Assert : 'orderedEdgeVerticesOnTriangle1[0] == ( orderedEdgeVerticesOnTriangle1[1] + 1 ) % 3
Inconsistant triangle winding between triangle 1048585and triangle 10.: One sided welding will not work.'

By the way, that triangle index is really scary. I hope I'm not misplacing the blame on this one. But it only does this when I have a shared edge like in this example. In maya these are two completely separate objects. Just the standard unit length box, which has face normals, and is really nothing special.

It's not hard to see what's happening. From the screenshot, the top face of the white selection is trying to weld with the bottom face of the green selection, it should be able to ignore that case and only weld with the right face of the white selection, OR the left face of the green selection.

I hope this helps.


Thanks a lot for all of the help.

Using a collision tolerance of 0.1f, and two sided welding I don't get those strange perpendicular extra contact points.

But for now I'll try the 0.01 collision tolerance and I'm going to see if I can solve the extra bouncyness by handling the velocity manually in the contact point callback.


Deje un comentario

Por favor inicie sesión para agregar un comentario. ¿No es socio? Únase ya