如何在Farseer中创建一个非常特殊的关节?

编辑

问题解决了(见Drackir的答案)。 下面是我试图通过这个联合实现的演示 。 更多关于这个问题的情况 。


问题

我试图在Farseer中创建一个非常特定的关节types,其行为如下所示:

  • 对象在X轴和Y轴上应始终保持相同的距离。
  • 翻译 – 与其中一个物体发生碰撞应将整个组移动到一起,但组不能旋转 – 只有单个物体可能因扭矩而围绕其中心旋转。
  • 旋转 – 对象应始终具有相同的旋转。 与其中一个物体的碰撞应该使所有其他物体旋转完全相同的量。

这是一张图片:

在这里输入图像描述

如果Farseer没有办法实现这个function,那我怎么去扩展它来创建一个这样的新型连接呢? 基本上我希望每个人都像其他人的“克隆”一样,但是他们之间有一个固定的偏移。

好吧,经过大约两个小时的修补,我设法做到了这一点,但它需要添加一些额外的机构。 你可能想要将这些东西提取到方法/类中,但是其基本思想是这样的:

  1. 创建我所谓的“持有人”的身体为您的对象。 这些机构分享你的“对象”的大小和位置,但不参与碰撞。 基本上,它们是克隆。

    //Create "Main" (center) body _bodyMain = BodyFactory.CreateRectangle(World, 5f, 5f, 1f); _bodyMain.BodyType = BodyType.Dynamic; _bodyMain.Position = new Vector2(2, 2); //Create "MainHolder" _bodyMainHolder = BodyFactory.CreateRectangle(World, 5f, 5f, 1f); _bodyMainHolder.BodyType = BodyType.Dynamic; _bodyMainHolder.CollisionCategories = Category.None; //Prevents collisions _bodyMainHolder.Position = new Vector2(2, 2); _bodyMainHolder.IsSensor = true; //See http://farseerphysics.codeplex.com/discussions/222524 for why they're sensors _bodyMainHolder.FixedRotation = true; //Note: Only add FixedRotation for the main one, leave it off of the other // holders. I'll explain later. 
  2. 使用WeldJoint将每个夹持器连接到“mainHolder”。 这将防止他们彼此离开。 FixedRotation上的FixedRotation阻止它们旋转。 我不知道是否有一个错误,但如果你添加一个WeldJoint并且两个主体都有FixedRotation == true ,这个关节就不能正常工作。 这就是为什么只有.FixedRotation = true

     //Weld the holders together so they don't move. Assumes another holder is defined // for the object on the right side (bodyRightHolder). JointFactory.CreateWeldJoint(World, _bodyMainHolder, _bodyRightHolder, _bodyRightHolder.Position - _bodyMainHolder.Position, Vector2.Zero); 
  3. 使用RevoluteJoint将您的“对象”物体附着到它们各自的持有者RevoluteJoint 。 这将您的物体locking到持有人,但允许他们自由旋转。

     //Lock the actual bodies to the holders JointFactory.CreateRevoluteJoint(World, _bodyMainHolder, _bodyMain, Vector2.Zero); JointFactory.CreateRevoluteJoint(World, _bodyRightHolder, _bodyRight, Vector2.Zero); 
  4. 通过附加一个角度关节来使你的真实物体旋转相互匹配。 注意:您不必为每个对象附加角度关节。 只要在主体和另一个身体上加一个角度关节,旋转就可以在所有的物体上转换。

     //Make them rotate the same as each other JointFactory.CreateAngleJoint(World, _bodyMain, _bodyRight); 

而已! 只需为每个其他对象/对象持有者添加额外的代码,就可以处理剩余的代码。 这是一个图像来说明我的testing: 测试机构的示例图像。

在这里你会看到绿色的身体是持有人。 它们不旋转或碰撞并焊接在一起。 黄色和红色的身体是你的“物体”(黄色是主要的)。 你可以看到他们被旋转了相同的数量,并围绕着他们各自的持有人旋转。 此外,只有红色和黄色的身体参与碰撞。 我相信这符合上述所有三个条件。

工作示例

如果你加载了Farseer“Samples XNA”解决scheme,并findSimpleDemo1.cs(“Samples XNA”project>“Samples”文件夹),我重写了它( 代码在这里 )来testing。

希望这可以帮助。 如果您有任何问题,请告诉我。

不幸的是我不能检查这个答案,因为我现在正在打电话,所以如果它不工作,我期望的道歉。

我想你可以使用几个现有的关节来实现你想要的。 在三角形的角落创建一个没有碰撞几何的物体,然后可以使用三个距离关节来实现所需的翻译。 那么如果你把两个可以碰撞的物体连接在一起,它们将会一起旋转。