关于BOX2D刚体有时无法休眠的原因及处理方法
这段是b2Island.as的方法..
//if (minSleepTime >= b2Settings.b2_timeToSleep)
这个是BOX2D原来的判定...
b2Settings.b2_timeToSleep指向的值是0.5
minSleepTime 是根据时间步的值来增加的..
如果只有一个刚体..时间步是1/24的话..即使要休眠也达不到0.5的要求..
b2Settings.b2_timeToSleep的意思是最小休眠时间....
不过0.5一样还有问题...
于是我就把这段函数改了下..
增加了两句:
var needSleep:Boolean = true;
needSleep = contactsOkay && needSleep;
并把判定改为:
minSleepTime >= step.dt && needSleep
这样位置修正也没问题..也可以休眠了
1
Report(contactSolver.m_constraints);
2
3
4
5
if (allowSleep){
6
7
8
9
var minSleepTime:Number = Number.MAX_VALUE;
10
11
12
13
var linTolSqr:Number = b2Settings.b2_linearSleepTolerance * b2Settings.b2_linearSleepTolerance;
14
15
var angTolSqr:Number = b2Settings.b2_angularSleepTolerance * b2Settings.b2_angularSleepTolerance;
16
17
18
19
for (i = 0; i < m_bodyCount; ++i)
20
21
{
22
23
b = m_bodies[i];
24
25
if (b.m_invMass == 0.0)
26
27
{
28
29
continue;
30
31
}
32
33
34
35
if ((b.m_flags & b2Body.e_allowSleepFlag) == 0 ||
36
37
b.m_angularVelocity * b.m_angularVelocity > angTolSqr ||
38
39
b2Math.b2Dot(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr)
40
41
{
42
43
b.m_sleepTime = 0.0;
44
45
minSleepTime = 0.0;
46
47
}
48
49
else
50
51
{
52
53
b.m_sleepTime += step.dt;
54
55
minSleepTime = b2Math.b2Min(minSleepTime, b.m_sleepTime);
56
57
}
58
59
}
60
61
62
if (minSleepTime >= step.dt && needSleep)
63
64
{
65
66
for (i = 0; i < m_bodyCount; ++i)
67
68
{
69
70
b = m_bodies[i];
71
72
if ( b.m_sleepTime >= step.dt)
73
74
{
75
76
b.m_flags |= b2Body.e_sleepFlag;
77
78
b.m_linearVelocity.SetZero();
79
80
b.m_angularVelocity = 0.0;
81
82
}
83
84
}
85
86
}
Report(contactSolver.m_constraints);2

3
4

5
if (allowSleep){6

7
8

9
var minSleepTime:Number = Number.MAX_VALUE;10

11
12

13
var linTolSqr:Number = b2Settings.b2_linearSleepTolerance * b2Settings.b2_linearSleepTolerance;14

15
var angTolSqr:Number = b2Settings.b2_angularSleepTolerance * b2Settings.b2_angularSleepTolerance;16

17
18

19
for (i = 0; i < m_bodyCount; ++i)20

21
{22

23
b = m_bodies[i];24

25
if (b.m_invMass == 0.0)26

27
{28

29
continue;30

31
}32

33
34

35
if ((b.m_flags & b2Body.e_allowSleepFlag) == 0 ||36

37
b.m_angularVelocity * b.m_angularVelocity > angTolSqr ||38

39
b2Math.b2Dot(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr)40

41
{42

43
b.m_sleepTime = 0.0;44

45
minSleepTime = 0.0;46

47
}48

49
else50

51
{52

53
b.m_sleepTime += step.dt;54

55
minSleepTime = b2Math.b2Min(minSleepTime, b.m_sleepTime);56

57
}58

59
}60

61

62
if (minSleepTime >= step.dt && needSleep)63

64
{65

66
for (i = 0; i < m_bodyCount; ++i)67

68
{69

70
b = m_bodies[i];71

72
if ( b.m_sleepTime >= step.dt)73

74
{75

76
b.m_flags |= b2Body.e_sleepFlag;77

78
b.m_linearVelocity.SetZero();79

80
b.m_angularVelocity = 0.0;81

82
}83

84
}85

86
}
上面的代码还是有点问题,改了后.会无缘无故的漂浮..
但是可以增加是否有碰撞..就可以解决无缘无故的漂浮..
..我给BODY类加了一个碰撞属性..
碰撞时改为TRUE..
然后睡眠时再判定是不是有碰撞..
具体代码我就不贴了..
