Box2D的AS3接触监听器问题 [英] Box2d As3 contact listener problem

查看:159
本文介绍了Box2D的AS3接触监听器问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在与Box2D的AS3 b2ContactListener类的问题。我有一类名为ContactListener扩展b2ContactListener和覆盖PostSolve方法。 PostSolve需要两个参数,联系方式持有约2个对象有联系的信息,和冲动持有有关联系人的信息。我使用的冲动参数来决定两个对象如何努力打,然后我据此适用损害。

I'm having a problem with the box2d as3 b2ContactListener class. I have a class named ContactListener that extends b2ContactListener and overrides the PostSolve method. PostSolve takes 2 parameters, contact which holds the info about the 2 objects that have contact, and impulse which holds info about the contact. I'm using the impulse parameter to decide how hard 2 objects hit and then I apply damage accordingly.

下面的问题: 如果我做什么,是圆形的,并且让它慢慢滚上静态的身体我作为地面,然后随地丢弃一个相当大的物体在地面上,圆而运动将获得接触会重复的冲动是办法大,只是滚滚。这使得滚动圆形物体打破时,他们不应该。

Here is the problem: If I make anything that is circular, and let it slowly roll on the static body I have as the ground, then drop a fairly large object anywhere on the ground, the circle while in motion will get contacts will a repeating impulse that is way to large for just rolling. It causes the rolling circular objects to break when they shouldn't.

它几乎一样,如果它摇晃静体,造成巨大的破坏对象几百米的距离,但它不仅影响圈。

Its almost as if its shaking the static body and causing massive damage to objects hundreds of meters away, but it only affects circles.

任何人都可以摆脱的情况一些轻?这是一个已知的问题?解决方法?

Can anyone shed some light on the situation? Is this a known issue? Workarounds?

我使用Box2DAs3版本2.1A。

I am using Box2DAs3 version 2.1a.

更新:一旦身体进入这个奇怪的状态,适用于多大的伤害,任何一个圆触及它得到吨的大型冲动。一旦一些非圆形进来与身体接触,它不再有问题。另外这个问题不仅是静态对象,但动力学和运动学为好。

Update: Once the body enters this weird state of applying to much damage, any circle that touches it gets tons of large impulses. Once something non circular come in contact with the body, it no longer has the problem. Also this problem is not only on static objects but dynamic and kinematic as well.

更新:我已经缩小问题进一步下降。接触监听器怪胎和应用的大规模的冲动,当一个大对象的平边打我的地面目标。任何对象,而不仅仅是圈子,那是清醒和接触地​​面会得到吨PostSolve方法调用。我试图通过11个像素丢弃一箱为11像素的大小到地面,而一个圆是在地上打滚。这个错误并没有发生。但是,如果盒子是12 12的错误确实发生。另外,如果我旋转框12的由12至0.1度的大小​​,错误不会发生。需要有足够大的接触面积为它REPRO。还盒子的密度不影响任何东西。另外,如果盒子是用宽度为10和100的高度和错误将REPRO矩形。这几乎就像只是对象的大小导致了错误,接触尺寸的可能不是区域。

Update: I have narrowed the problem down further. The contact listener freaks out and apply's mass impulses when the flat edge of a large object hits my ground object. Any object, not just circles, that is awake and touches the ground will get tons of PostSolve method calls. I tried dropping a box with a size of 11 pixels by 11 pixels onto the ground while a circle was rolling on the ground. The bug did not happen. However if the box is 12 by 12 the bug does occur. Also if i rotate a box with a size of 12 by 12 to 0.1 degrees, the bug does not occur. There needs to be a large enough contact area for it to repro. Also density of the box does not effect anything. Also if the box is a rectangle with a width of 10 and height of 100 and the bug will repro. It's almost like just the size of the object is causing the bug, possibly not the area of contact size.

更新:这里是一个链接到一个Box2D的论坛后我做了有一个例子SWF与源

Update: Here is a link to a Box2D forum post I made that has an example swf with source.

链接

推荐答案

WOW。所以,我终于发现了问题所在。

WOW. So I've finally found out what the problem is.

在在试图找出是否有解决方法做一些花哨的ContactListener小时时间,我决定去看看,看看那里的PostSolve方法正在从调用。它来自一个名为类b2Island,它来自于该类报告功能。乍一看,我很容易发现问题。她的功能是:

After hours upon hours of trying to figure out if there is a workaround by doing something fancy in the ContactListener, I decided to look and see where the PostSolve method was being called from. It comes from a class named b2Island and it comes from the Report function in that class. At first glance I spotted the problem easily. Her is the function:

private static var s_impulse:b2ContactImpulse = new b2ContactImpulse();
public function Report(constraints:Vector.<b2ContactConstraint>) : void
{
    if (m_listener == null)
    {
        return;
    }

    for (var i:int = 0; i < m_contactCount; ++i)
    {
        var c:b2Contact = m_contacts[i];
        var cc:b2ContactConstraint = constraints[ i ];

        for (var j:int = 0; j < cc.pointCount; ++j)
        {
            s_impulse.normalImpulses[j] = cc.points[j].normalImpulse;
            s_impulse.tangentImpulses[j] = cc.points[j].tangentImpulse;
        }
        m_listener.PostSolve(c, s_impulse);
    }
}

所以是明显的s_impulse变种是静态的,所以这将是相同的b2Island类的每个实例(如果有一个以上的),并且还它没有得到复位在任何点。所有引用的s_impulse VAR上面可以看出,所以没有别的没发生过吧。但这里的点,一个圆只与一个多边形这意味着它将只设置冲动一个接触被报道当一个人接触。另一接触,如果不是被复位将具有最后一个对象的最后脉冲进行报告。

So yeah obviously the s_impulse var is static so it will be the same for every instance of the b2Island class ( if there is more then one ) and also it's not getting reset at any point. All the references to the s_impulse var can be seen above, so nothing else ever happens to it. But here's the point, a circle only has one contact with a polygon meaning it will only set the impulse for one contact when being reported. The other contact, if not being reset will have the last impulse of the last object to be reported.

基本上看到了一圈的冲动实际上是遗留下来的冲动无论从那个刚刚报道。要修复它做到这一点:

Basically the impulses seen on the circle is actually left over impulse from whatever just got reported. To fix it do this:

private static var s_impulse:b2ContactImpulse = new b2ContactImpulse();
public function Report(constraints:Vector.<b2ContactConstraint>) : void
{
    if (m_listener == null)
    {
        return;
    }

    for (var i:int = 0; i < m_contactCount; ++i)
    {
        s_impulse = new b2ContactImpulse();

        var c:b2Contact = m_contacts[i];
        var cc:b2ContactConstraint = constraints[ i ];

        for (var j:int = 0; j < cc.pointCount; ++j)
        {
            s_impulse.normalImpulses[j] = cc.points[j].normalImpulse;
            s_impulse.tangentImpulses[j] = cc.points[j].tangentImpulse;
        }
        m_listener.PostSolve(c, s_impulse);
    }
}

就这么简单。

It's as simple as that.

这篇关于Box2D的AS3接触监听器问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆