summaryrefslogtreecommitdiff
path: root/frontend/2d/_collisions/pill_line/main.cpp
blob: 41874351876465f5b1ce534a0271e9fa40fffe4b (plain)
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
151
#include "../../../shared_cpp/OrthographicRenderer.h"
#include "../../../shared_cpp/types.h"
#include "../../../shared_cpp/WebglContext.h"
#include "../../../shared_cpp/mathlib.h"
#include "../../../shared_cpp/MainLoop.h"
#include <cstdio>
#include <emscripten/html5.h>
#include <unistd.h>
#include <pthread.h>
#include <cmath>

// Side note: It is Eastertime, so I chose this easter color palette. Enjoy: https://htmlcolors.com/palette/144/easter

//
// Pill object 
//
struct Pill {
	OrthographicShape shape;
	float32 width = 1.f;
	float32 height = 1.f;

	void load(OrthographicRenderer* renderer, float32 numSegments) {
		// Note that a so-called "pill" is simply an ellipse.
		// Equation of an ellipse is:
		//
		//	x^2 / a^2 + y^2 / b^2 = 1
		//
		// or, in parametric form:
		//
		// x = a * cos(t), y = b * sin(t)
		//
		float32 angleIncrements = (2.f * PI) / numSegments;
		uint32 numVertices = static_cast<uint32>(numSegments * 3.f);
		OrthographicVertex* vertices = new OrthographicVertex[numVertices];

		float32 a = width / 2.f;
		float32 b = height / 2.f;

		Vector4 color = Vector4().fromColor(243,166,207, 255);

		for (uint32 vertexIndex = 0; vertexIndex < numVertices; vertexIndex += 3) {
			// Create a single "slice" of the ellipse (like a pizza)
			float32 currAngle = (vertexIndex / 3.f) * angleIncrements;
			float32 nextAngle = (vertexIndex / 3.f + 1.f) * angleIncrements;

			vertices[vertexIndex].position = Vector2 { 0.f, 0.f };
			vertices[vertexIndex].color = color;

			vertices[vertexIndex + 1].position = Vector2 { a * cosf(currAngle), b * sinf(currAngle) };
			vertices[vertexIndex + 1].color = color;

			vertices[vertexIndex + 2].position = Vector2 { a * cosf(nextAngle), b * sinf(nextAngle) };
			vertices[vertexIndex + 2].color = color;
		}

		shape.load(vertices, numVertices, renderer);
		delete[] vertices;
	}

	void render(OrthographicRenderer* renderer) {
		shape.render(renderer);
	}

	void unload() {
		shape.unload();
	}

	float32 getArea() {
		return 0.f;
	}
};

struct LineSegment {
	OrthographicShape shape;
	Vector2 start;
	Vector2 end;
	OrthographicVertex vertices[2];

	void load(OrthographicRenderer* renderer, Vector4 color, Vector2 start, Vector2 end) {
		vertices[0].position = start;
		vertices[0].color = color;
		vertices[1].position = end;
		vertices[1].color = color;
		shape.load(vertices, 2, renderer);
	}

	void render(OrthographicRenderer* renderer) {
		shape.render(renderer, GL_LINES);
	}
};

EM_BOOL onPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData);
EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData);
EM_BOOL update(float time, void* userData);

// Global Variables
WebglContext context;
OrthographicRenderer renderer;
Pill pill;
MainLoop mainLoop;
LineSegment segmentList[4];

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);
	return 0;
}

EM_BOOL update(float deltaTimeSeconds, void* userData) {
	renderer.render();
	pill.shape.render(&renderer);

	for (int segmentIndex = 0; segmentIndex < 4; segmentIndex++) {
		segmentList[segmentIndex].render(&renderer);
	}

	return true;
}

//
// Interactions with DOM handled below
//
EM_BOOL onPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData) {
	printf("Play clicked\n");
	
	renderer.load(&context);

	// Add the pill
	pill.width = 100.f;
	pill.height = 50.f;
	pill.shape.model = Mat4x4().translateByVec2(Vector2 { context.width / 2.f, context.height / 2.f });
	pill.load(&renderer, 64);

	// Add the lines
	segmentList[0].load(&renderer, Vector4().fromColor(191, 251, 146, 255.f), Vector2 { 50.f, 0.f }, Vector2 { 50.f, static_cast<float>(context.height) });
	segmentList[1].load(&renderer, Vector4().fromColor(159, 224, 210, 255.f), Vector2 { context.width - 50.f, 0.f }, Vector2 { context.width - 50.f, static_cast<float>(context.height) });
	segmentList[2].load(&renderer, Vector4().fromColor(248, 255, 156, 255.f), Vector2 { 50.f, 50.f }, Vector2 { context.width - 50.f, 150.f });
	segmentList[3].load(&renderer, Vector4().fromColor(205, 178, 214, 255.f), Vector2 { 50.f, 150.f }, Vector2 { context.width - 50.f, 50.f });

	mainLoop.run(update);
	return true;
}

EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData) {
	printf("Stop clicked\n");
	mainLoop.stop();
	pill.unload();
	renderer.unload();
	return true;
}