codingben / box2d-netstandard

C# port of Box2D - Erin Catto's 2D Physics Engine
https://box2d.org
MIT License
263 stars 53 forks source link

[Bug] Prismatic Joint affected by Vector2.Normalize #47

Open BinarySpike opened 1 year ago

BinarySpike commented 1 year ago

Description

When applying a Prismatic Joint, the localAxisA is normalized. This causes {NaN, NaN} when the joint is new Vector2(0,0)

See https://github.com/codingben/box2d-netstandard/blob/b34d6238011a97a4f777e88dc41aa31f6b984c7b/src/box2dx/Box2D.NetStandard/Dynamics/Joints/Prismatic/PrismaticJoint.cs#L146

How To Reproduce

Create a new prismatic joint where the localAxisA is new Vector2(0,0)

You can work around the issue by using Reflection to update the private values:

var jdef = new PrismaticJointDef();
jdef.bodyA = body1;
jdef.bodyB = body2;
jdef.collideConnected = false;
jdef.localAxisA = new Vector2(0, 0);

var pJoint = world.CreateJoint(jdef);

var propX = pJoint.GetType().GetField("m_localXAxisA", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var propY = pJoint.GetType().GetField("m_localYAxisA", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
propX.SetValue(pJoint, new Vector2(0, 0));
propY.SetValue(pJoint, new Vector2(0, 0));

Expected Behavior

Something similar to:

https://github.com/erincatto/box2d/blob/c6cc3646d1701ab3c0750ef397d2d68fc6dbcff2/src/dynamics/b2_prismatic_joint.cpp#L88

HughPH commented 1 year ago

We have discussed Vector2.Normalize before: https://github.com/codingben/box2d-netstandard/pull/43 https://github.com/codingben/box2d-netstandard/pull/33 It's worth noting that OpenTK's Vector2 will also produce NaN with a zero length: https://github.com/opentk/opentk/blob/682ae61055aa7b606fe9a8510d6024b2220a22ac/src/OpenTK.Mathematics/Vector/Vector2.cs#L167

So if you can make a case for it being a common enough use case to create a prismatic joint with localAxisA of 0, I would suggest the fix should go into that contructor rather than into Vector2.Normalize