summaryrefslogtreecommitdiff
path: root/2d/rigidbody/rigidbody_1/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to '2d/rigidbody/rigidbody_1/main.cpp')
-rw-r--r--2d/rigidbody/rigidbody_1/main.cpp113
1 files changed, 109 insertions, 4 deletions
diff --git a/2d/rigidbody/rigidbody_1/main.cpp b/2d/rigidbody/rigidbody_1/main.cpp
index 26d24e2..8d4ab0e 100644
--- a/2d/rigidbody/rigidbody_1/main.cpp
+++ b/2d/rigidbody/rigidbody_1/main.cpp
@@ -43,6 +43,8 @@ struct Rigidbody {
struct Rectangle {
OrthographicShape shape;
Rigidbody body;
+ Vector2 originalPoints[4];
+ Vector2 transformedPoints[4];
void load(OrthographicRenderer* renderer, Vector4 color, float32 width, float32 height) {
color = color.toNormalizedColor();
@@ -62,6 +64,11 @@ struct Rectangle {
vertices[i].color = color;
}
+ originalPoints[0] = vertices[0].position;
+ originalPoints[1] = vertices[1].position;
+ originalPoints[2] = vertices[2].position;
+ originalPoints[3] = vertices[4].position;
+
shape.load(vertices, 6, renderer);
body.reset();
}
@@ -69,6 +76,54 @@ struct Rectangle {
void update(float32 dtSeconds) {
body.update(dtSeconds);
shape.model = Mat4x4().translateByVec2(body.position);
+
+ // Note: This helps us check if the cursor is within the bounds of the
+ // rectangle later on.
+ for (int idx = 0; idx < 4; idx++) {
+ transformedPoints[idx] = shape.model * originalPoints[idx];
+ }
+ }
+
+ void render(OrthographicRenderer* renderer) {
+ shape.render(renderer);
+ }
+
+ void unload() {
+ shape.unload();
+ }
+};
+
+struct Circle {
+ OrthographicShape shape;
+ Rigidbody body;
+
+ float32 radius = 5.f;
+
+ void load(OrthographicRenderer* renderer, Vector4 color) {
+ const int32 numSegments = 36;
+ const float32 radiansPerSegment = (2.f * PI) / static_cast<float>(numSegments);
+ const int32 numVertices = numSegments * 3;
+
+ color = color.toNormalizedColor();
+
+ OrthographicVertex vertices[numSegments * 3];
+ for (int idx = 0; idx < numSegments; idx++) {
+ int vIdx = idx * 3;
+
+ vertices[vIdx].color = color;
+ vertices[vIdx].position = Vector2 { radius * cosf(radiansPerSegment * idx), radius * sinf(radiansPerSegment * idx) };
+ vertices[vIdx + 1].color = color;
+ vertices[vIdx + 1].position = Vector2 { 0.f, 0.f };
+ vertices[vIdx + 2].color = color;
+ vertices[vIdx + 2].position = Vector2 { radius * cosf(radiansPerSegment * (idx + 1)), radius * sinf(radiansPerSegment * (idx + 1)) };
+ }
+
+ shape.load(vertices, numVertices, renderer);
+ body.reset();
+ }
+
+ void update(float32 dtSeconds) {
+ shape.model = Mat4x4().translateByVec2(body.position);
}
void render(OrthographicRenderer* renderer) {
@@ -82,6 +137,7 @@ struct Rectangle {
EM_BOOL onPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData);
EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData);
+EM_BOOL onMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
void load();
void update(float32 time, void* userData);
@@ -91,11 +147,15 @@ WebglContext context;
OrthographicRenderer renderer;
MainLoop mainLoop;
Rectangle rectangle;
+Circle pointer;
+bool isIntersectingPointer = false;
int main() {
context.init("#gl_canvas");
emscripten_set_click_callback("#gl_canvas_play", NULL, false, onPlayClicked);
emscripten_set_click_callback("#gl_canvas_stop", NULL, false, onStopClicked);
+ emscripten_set_mousemove_callback("#gl_canvas", NULL, false, onMouseMove);
+
return 0;
}
@@ -106,11 +166,40 @@ void load() {
rectangle.body.position = Vector2 { context.width / 3.f, context.height / 3.f };
rectangle.body.velocity = Vector2 { 100.f, 250.f };
+ pointer.load(&renderer, Vector4 { 25.f, 235.f, 235.f, 255.f });
+
mainLoop.run(update);
}
+bool isPointInRectangle(Vector2 p, Rectangle r) {
+ // https://math.stackexchange.com/a/190373
+ Vector2 A = r.transformedPoints[0];
+ Vector2 B = r.transformedPoints[1];
+ Vector2 D = r.transformedPoints[3];
+
+ float32 amDotAb = (p - A).dot(B - A);
+ float32 abDotAb = (B - A).dot(B - A);
+
+ float32 amDotAd = (p - A).dot(D - A);
+ float32 aDDotAd = (D - A).dot(D - A);
+
+ return amDotAb > 0 && amDotAb < abDotAb && amDotAd > 0 && amDotAd < aDDotAd;
+
+}
+
void update(float32 deltaTimeSeconds, void* userData) {
rectangle.update(deltaTimeSeconds);
+ pointer.update(deltaTimeSeconds);
+
+ if (isPointInRectangle(pointer.body.position, rectangle)) {
+ if (!isIntersectingPointer) {
+ isIntersectingPointer = true;
+ rectangle.body.force += pointer.body.force;
+ }
+ } else if (isIntersectingPointer) {
+ isIntersectingPointer = false;
+ }
+
// Check collisions with walls so we don't go out of the scene. Simply reflect here.
if (rectangle.body.position.x <= 0.f) {
@@ -121,24 +210,26 @@ void update(float32 deltaTimeSeconds, void* userData) {
rectangle.body.position.y = 0.f;
rectangle.body.velocity = rectangle.body.velocity - Vector2 { 0.f, 1.f } * (2 * (rectangle.body.velocity.dot(Vector2 { 0.f, 1.f })));
}
- if (rectangle.body.position.x >= 640.f) {
- rectangle.body.position.x = 640.f;
+ if (rectangle.body.position.x >= 800.f) {
+ rectangle.body.position.x = 800.f;
rectangle.body.velocity = rectangle.body.velocity - Vector2 { -1.f, 0.f } * (2 * (rectangle.body.velocity.dot(Vector2{ -1.f, 0.f })));
}
- if (rectangle.body.position.y >= 480.f) {
- rectangle.body.position.y = 480.f;
+ if (rectangle.body.position.y >= 600.f) {
+ rectangle.body.position.y = 600.f;
rectangle.body.velocity = rectangle.body.velocity - Vector2 { 0.f, -1.f } * (2 * (rectangle.body.velocity.dot(Vector2 { 0.f, -1.f }))) ;
}
// Renderer
renderer.render();
rectangle.render(&renderer);
+ pointer.render(&renderer);
}
void unload() {
mainLoop.stop();
renderer.unload();
rectangle.unload();
+ pointer.unload();
}
//
@@ -156,3 +247,17 @@ EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, voi
unload();
return true;
}
+
+EM_BOOL onMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) {
+ if (!mainLoop.isRunning) {
+ return true;
+ }
+
+ pointer.body.force.x = static_cast<float32>(mouseEvent->movementX) * 1000.f;
+ pointer.body.force.y = static_cast<float32>(-mouseEvent->movementY) * 1000.f;
+
+ pointer.body.position.x = static_cast<float32>(mouseEvent->targetX);
+ pointer.body.position.y = static_cast<float32>(600.f - mouseEvent->targetY);
+
+ return true;
+}