1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
/*
Test case for collision/jerking issue.
*/
#include "test.h"
#include <vector>
#include <iostream>
class Skier : public Test
{
public:
Skier()
{
b2Body* ground = NULL;
{
b2BodyDef bd;
ground = m_world->CreateBody(&bd);
float const PlatformWidth = 8.0f;
/*
First angle is from the horizontal and should be negative for a downward slope.
Second angle is relative to the preceding slope, and should be positive, creating a kind of
loose 'Z'-shape from the 3 edges.
If A1 = -10, then A2 <= ~1.5 will result in the collision glitch.
If A1 = -30, then A2 <= ~10.0 will result in the glitch.
*/
float const Angle1Degrees = -30.0f;
float const Angle2Degrees = 10.0f;
/*
The larger the value of SlopeLength, the less likely the glitch will show up.
*/
float const SlopeLength = 2.0f;
float const SurfaceFriction = 0.2f;
// Convert to radians
float const Slope1Incline = -Angle1Degrees * b2_pi / 180.0f;
float const Slope2Incline = Slope1Incline - Angle2Degrees * b2_pi / 180.0f;
//
m_platform_width = PlatformWidth;
// Horizontal platform
b2Vec2 v1(-PlatformWidth, 0.0f);
b2Vec2 v2(0.0f, 0.0f);
b2Vec2 v3(SlopeLength * cosf(Slope1Incline), -SlopeLength * sinf(Slope1Incline));
b2Vec2 v4(v3.x + SlopeLength * cosf(Slope2Incline), v3.y - SlopeLength * sinf(Slope2Incline));
b2Vec2 v5(v4.x, v4.y - 1.0f);
b2Vec2 vertices[5] = { v5, v4, v3, v2, v1 };
b2ChainShape shape;
shape.CreateLoop(vertices, 5);
b2FixtureDef fd;
fd.shape = &shape;
fd.density = 0.0f;
fd.friction = SurfaceFriction;
ground->CreateFixture(&fd);
}
{
float const BodyWidth = 1.0f;
float const BodyHeight = 2.5f;
float const SkiLength = 3.0f;
/*
Larger values for this seem to alleviate the issue to some extent.
*/
float const SkiThickness = 0.3f;
float const SkiFriction = 0.0f;
float const SkiRestitution = 0.15f;
b2BodyDef bd;
bd.type = b2_dynamicBody;
float initial_y = BodyHeight / 2 + SkiThickness;
bd.position.Set(-m_platform_width / 2, initial_y);
b2Body* skier = m_world->CreateBody(&bd);
b2PolygonShape ski;
b2Vec2 verts[4];
verts[0].Set(-SkiLength / 2 - SkiThickness, -BodyHeight / 2);
verts[1].Set(-SkiLength / 2, -BodyHeight / 2 - SkiThickness);
verts[2].Set(SkiLength / 2, -BodyHeight / 2 - SkiThickness);
verts[3].Set(SkiLength / 2 + SkiThickness, -BodyHeight / 2);
ski.Set(verts, 4);
b2FixtureDef fd;
fd.density = 1.0f;
fd.friction = SkiFriction;
fd.restitution = SkiRestitution;
fd.shape = &ski;
skier->CreateFixture(&fd);
skier->SetLinearVelocity(b2Vec2(0.5f, 0.0f));
m_skier = skier;
}
g_camera.m_center = b2Vec2(m_platform_width / 2.0f, 0.0f);
g_camera.m_zoom = 0.4f;
m_fixed_camera = true;
}
void Keyboard(int key) override
{
switch (key)
{
case GLFW_KEY_C:
m_fixed_camera = !m_fixed_camera;
if(m_fixed_camera)
{
g_camera.m_center = b2Vec2(m_platform_width / 2.0f, 0.0f);
}
break;
}
}
void Step(Settings& settings) override
{
g_debugDraw.DrawString(5, m_textLine, "Keys: c = Camera fixed/tracking");
m_textLine += m_textIncrement;
if(!m_fixed_camera)
{
g_camera.m_center = m_skier->GetPosition();
}
Test::Step(settings);
}
static Test* Create()
{
return new Skier;
}
b2Body* m_skier;
float m_platform_width;
bool m_fixed_camera;
};
static int testIndex = RegisterTest("Bugs", "Skier", Skier::Create);
|