-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathScene.cpp
135 lines (112 loc) · 4.02 KB
/
Scene.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
135
#define GLEW_STATIC
#include <GL/glew.h>
#include "Scene.h"
#include "CollisionDetector.h"
#include "Box2D.h"
void Scene::init() {
selectedRigidBody = -1;
physicalEngine.SetResolverAcivity(true);
AddBox(100, 150, 1e8, ObjectType::Internal);
}
void Scene::update(float dt) {
physicalEngine.SetRigidBodies(&this->rigidBodies);
physicalEngine.Update(dt);
}
void Scene::render() {
glPushAttrib(GL_LINE_BIT);
// Draw Origin
glColor3f(1, 0, 0);
glBegin(GL_LINES);
glVertex2f(-20, 0);
glVertex2f(20, 0);
glVertex2f(0, -20);
glVertex2f(0, 20);
glEnd();
// Draw Box
for (int i = 0; i < this->rigidBodies.size(); i++) {
if (dynamic_cast<Box2D *>(this->rigidBodies[i]) != nullptr) {
auto *box2D = dynamic_cast<Box2D *>(this->rigidBodies[i]);
if (box2D->GetShapeType() == ObjectType::Internal || this->selectedRigidBody == i)
glColor3f(0, 0, 1);
else
glColor3f(0, 1, 0);
glLineWidth(glm::min(2.f, box2D->GetMass()));
glBegin(GL_LINE_LOOP);
for (auto v : box2D->GetVertices())
glVertex2f(v.x, v.y);
glEnd();
} else if (dynamic_cast<Circle *>(this->rigidBodies[i]) != nullptr) {
auto *circle = dynamic_cast<Circle *>(this->rigidBodies[i]);
if (circle->GetShapeType() == ObjectType::Internal || this->selectedRigidBody == i)
glColor3f(0, 0, 1);
else
glColor3f(0, 1, 0);
glBegin(GL_LINE_LOOP);
for (int j = 0; j <= 300; j++) {
double angle = 2 * M_PI * j / 300;
glVertex2d(circle->GetCenter().x + circle->GetRadius() * cos(angle),
circle->GetCenter().y + circle->GetRadius() * sin(angle));
}
glEnd();
}
}
// Draw Collision info
auto collisionInfo = physicalEngine.CurrentCollisionInfo();
for (auto info : collisionInfo) {
glBegin(GL_LINES);
glColor3f(1, 0, 0);
glVertex2f(info.penetrationPoint.x, info.penetrationPoint.y);
glVertex2f(info.contactPoint.x, info.contactPoint.y);
glEnd();
}
glPopAttrib();
}
int Scene::AddBox(int h, int w, int mass, ObjectType type) {
Box2D *box2d = new Box2D(h, w, mass, type);
this->rigidBodies.push_back(box2d);
physicalEngine.SetChangedRigidBodies(true);
return this->rigidBodies.size() - 1;
}
int Scene::AddCircle(int r, int mass) {
this->rigidBodies.push_back(new Circle(r, mass));
physicalEngine.SetChangedRigidBodies(true);
return this->rigidBodies.size() - 1;
}
void Scene::Select(int x, int y) {
auto p = glm::vec2(x, y);
for (int i = 0; i < this->rigidBodies.size(); i++) {
auto box = this->rigidBodies[i];
if (box->GetShapeType() == ObjectType::Internal) continue;
if (CollisionDetector::ShapeContainsPoint(box, p)) {
selectedRigidBody = i;
return;
}
}
}
void Scene::Select(int index) {
selectedRigidBody = glm::min((int) this->rigidBodies.size() - 1, glm::max(0, index));
}
int Scene::GetSelectedRigidBody() {
return selectedRigidBody;
}
void Scene::ChangeMass(float mass, bool relative) {
if (selectedRigidBody >= 0) {
this->rigidBodies[selectedRigidBody]->ChangeMass(mass, relative);
physicalEngine.SetChangedRigidBodies(true);
}
}
void Scene::Rotate(float angle, bool relative) {
if (selectedRigidBody >= 0) {
this->rigidBodies[selectedRigidBody]->Rotate(angle, relative);
physicalEngine.SetChangedRigidBodies(true);
}
}
void Scene::Move(float x, float y, bool isRelative) {
if (selectedRigidBody >= 0) {
this->rigidBodies[selectedRigidBody]->MoveTo(x, y, isRelative);
physicalEngine.SetChangedRigidBodies(true);
}
}
std::vector<Object *> Scene::GetRigidBodies() {
return this->rigidBodies;
}