-
Notifications
You must be signed in to change notification settings - Fork 1
/
rigidbody.cpp
134 lines (110 loc) · 3.82 KB
/
rigidbody.cpp
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
#include "rigidbody.h"
namespace
{
float sign(float value)
{
if (value >= 0.0f)
return 1.0f;
return -1.0;
}
b2FixtureDef GetPolygonFixtureDef(const std::vector<glm::vec2>& points)
{
static b2PolygonShape shape;
std::vector<b2Vec2> b2Points;
for (auto& point : points)
{
b2Points.push_back(
{point.x - sign(point.x) * b2_polygonRadius, point.y - sign(point.y) * b2_polygonRadius});
}
shape.Set(b2Points.data(), static_cast<int>(b2Points.size()));
static b2FixtureDef fixtureDef;
fixtureDef.shape = &shape;
return fixtureDef;
}
b2FixtureDef GetCircleFixtureDef(float radius)
{
static b2CircleShape shape;
shape.m_radius = radius;
static b2FixtureDef fixtureDef;
fixtureDef.shape = &shape;
return fixtureDef;
}
b2Body* CreateBody(b2World& world, b2FixtureDef fixtureDef, b2BodyType type, float density)
{
b2BodyDef def;
def.type = type;
auto* body = world.CreateBody(&def);
fixtureDef.density = density;
body->CreateFixture(&fixtureDef);
return body;
}
} // namespace
Box2DSolver::Box2DSolver(b2World& world) : mWorld(world) {}
void Box2DSolver::Step(float delta)
{
const int velocityStep = 8;
const int positionStep = 3;
mWorld.Step(delta, velocityStep, positionStep);
}
Box2DRigidbody::Box2DRigidbody(const Vortex2D::Renderer::Device& device,
const glm::ivec2& size,
Vortex2D::Renderer::Drawable& drawable,
Vortex2D::Fluid::RigidBody::Type type,
b2Body* body)
: Vortex2D::Fluid::RigidBody(device, size, drawable, type), mBody(body)
{
}
void Box2DRigidbody::ApplyForces()
{
if (GetType() & Vortex2D::Fluid::RigidBody::Type::eWeak)
{
auto force = GetForces();
b2Vec2 b2Force = {force.velocity.x, force.velocity.y};
mBody->ApplyForceToCenter(b2Force, true);
mBody->ApplyTorque(force.angular_velocity, true);
}
}
void Box2DRigidbody::ApplyVelocities()
{
auto pos = mBody->GetPosition();
Position = {pos.x, pos.y};
Rotation = glm::degrees(mBody->GetAngle());
if (GetType() & Vortex2D::Fluid::RigidBody::Type::eStatic)
{
glm::vec2 vel = {mBody->GetLinearVelocity().x, mBody->GetLinearVelocity().y};
float angularVelocity = mBody->GetAngularVelocity();
SetVelocities(vel, angularVelocity);
}
}
void Rigidbody::SetTransform(const glm::vec2& pos, float angle)
{
mRigidbody->Position = pos;
mRigidbody->Rotation = angle;
mBody->SetTransform({pos.x, pos.y}, glm::radians(angle));
}
PolygonRigidbody::PolygonRigidbody(const Vortex2D::Renderer::Device& device,
const glm::ivec2& size,
b2World& rWorld,
b2BodyType rType,
Vortex2D::Fluid::RigidBody::Type type,
const std::vector<glm::vec2>& points,
float density)
: mPolygon(device, points)
{
mBody = CreateBody(rWorld, GetPolygonFixtureDef(points), rType, density);
mRigidbody = std::make_unique<Box2DRigidbody>(device, size, mPolygon, type, mBody);
mRigidbody->SetMassData(mBody->GetMass(), mBody->GetInertia());
}
CircleRigidbody::CircleRigidbody(const Vortex2D::Renderer::Device& device,
const glm::ivec2& size,
b2World& rWorld,
b2BodyType rType,
Vortex2D::Fluid::RigidBody::Type type,
const float radius,
float density)
: mCircle(device, radius)
{
mBody = CreateBody(rWorld, GetCircleFixtureDef(radius), rType, density);
mRigidbody = std::make_unique<Box2DRigidbody>(device, size, mCircle, type, mBody);
mRigidbody->SetMassData(mBody->GetMass(), mBody->GetInertia());
}